Criando um campo editável com JQuery

Você já viu em sistemas ou em sites campos que aparentemente estão como não editáveis e ao clicar no campo ele permite você alterar o valor e salvar?

Tive a necessidade de fazer algo semelhante em um projeto e gostaria de compartilhar com vocês.
Nesse exemplo que vamos trabalhar, tive que permitir que o usuário pudesse alterar o valor de um <span>. Para isso desenvolvi uma lógica para no inicio do carregamento da página o jQuery alterasse a estrutura inicial do texto em tela, no caso o <span>, para um container que possui ícones para edição, <input> e assim por diante.

Situação inicial do Sistema

Inicialmente no sistema temos a seguinte tag:

 <span id="teste123" class="left">Texto que será alterado</span

Imagino que isso é um simples campo de texto preenchido pelo sistema através de uma pesquisa ou carregamento inicial das informações.

Desenvolvimento

Para chegar no resultado esperado é necessário configurar um CSS e javascript.

Javascript

var visible = function(element){
    $(element).removeClass("invisible");
    $(element).addClass("visible");
}

var invisible = function(element){
    $(element).removeClass("visible");
    $(element).addClass("invisible");
}

var createEditableField = function (fieldId){

    createEditableHTML(fieldId);

    $('#editImg-' + fieldId).live('click', function(){
        var val = $("#" + fieldId).html();
        $("#old-" + fieldId + "-value").val(val);
        $("#" + fieldId)
            .replaceWith("<input id='" + fieldId + "-text' class='left' value='" + val +"'/>");
        invisible(this);
        visible("#saveImg-" + fieldId);
        visible("#closeImg-" + fieldId);
        $("#" + fieldId + "-text").focus();
    });

    $('#saveImg-' + fieldId).live('click', function(){
        var val = $("#" + fieldId + "-text").val();
        $("#" + fieldId + "-text")
            .replaceWith("<span id='" + fieldId + "' class='left'>" + val +"</span>");
        visible(this);
        visible("#editImg-" + fieldId);
        invisible("#saveImg-" + fieldId);
        invisible("#closeImg-" + fieldId);    
    });

    $('#closeImg-' + fieldId).live('click', function(){
        var val = $("#old-" + fieldId + "-value").val();
        $("#" + fieldId + "-text")
            .replaceWith("<span id='" + fieldId +"' class='left'>" + val +"</span>");
        visible(this);
        visible("#editImg-" + fieldId);
        invisible("#saveImg-" + fieldId);
        invisible("#closeImg-" + fieldId);
    });
}

var createEditableHTML = function(fieldId){
    var divFieldContainer = $('<div>').attr({id: 'fieldcontainer-' + fieldId});
    var divValueContainer = $('<div>').attr({id: 'valuecontainer-' + fieldId, class: 'left'});;
    var inputOldValue = $('<input>').attr({type: 'hidden', id:'old-' + fieldId + '-value'});
    var spanValue = $('<span>').attr({id:fieldId + '-value', class: 'left'});
    spanValue.html($("#" + fieldId).html());

    var divActionButtons = $('<div>').attr({id: 'actionButtons-' + fieldId, class: 'left'});
    var imgEdit = $('<img>').attr({id:'editImg-' + fieldId, class: 'visible left', src: 'http://cdn1.iconfinder.com/data/icons/stuttgart/16/edit.png'});
    var imgSave = $('<img>').attr({id:'saveImg-' + fieldId, class: 'invisible left', src: 'http://cdn1.iconfinder.com/data/icons/musthave/16/Save.png'});
    var imgClose = $('<img>').attr({id:'closeImg-' + fieldId, class: 'invisible left', src: 'http://cdn1.iconfinder.com/data/icons/woothemesiconset/16/close.png'});

    inputOldValue.appendTo(divValueContainer);
    spanValue.appendTo(divValueContainer);
    imgEdit.appendTo(divActionButtons);
    imgSave.appendTo(divActionButtons);
    imgClose.appendTo(divActionButtons);
    divValueContainer.appendTo(divFieldContainer);
    divActionButtons.appendTo(divFieldContainer);
    $("#" + fieldId).replaceWith(divFieldContainer);

    spanValue.attr({id:fieldId});
}

$(function () {
    createEditableField("teste123");
});

Veja que código acima temos as seguintes funções:

  • visible()
    • O método visible() é utilizado simplesmente para mostrar um elemento em tela.
  • invisible()
    • Assim como o visible, o invisible simplesmente some com o elemento de tela.
  • createEditableField()
    • Esse método inicialmente chama o método createEditableField e injeta os eventos de click no ícones de salvar, fechar e editar.
  • createEditableHtml()
    • Esse método é responsável pela criação do container de edição do campo, criando toda a estrutura de <div>. Veremos o resultado na sequência.

CSS

.invisible {
    display: none;
}

.visible {
    display:block;
}

.left{
    float: left;
    margin-right: 3px;
}

Resultado

campo-padrao
campo-editavel

HTML

<div id="fieldcontainer-teste123">
    <div id="valuecontainer-teste123">
        <input value="Texto que será alterado" id="old-teste123-value" type="hidden">
        <span id="teste123">Texto que será alterado</span>
    </div><div id="actionButtons-teste123">
        <img src="http://cdn1.iconfinder.com/data/icons/stuttgart/16/edit.png" id="editImg-teste123">
        <img src="http://cdn1.iconfinder.com/data/icons/musthave/16/Save.png" id="saveImg-teste123">
        <img src="http://cdn1.iconfinder.com/data/icons/woothemesiconset/16/close.png" id="closeImg-teste123">
    </div>
</div>

Perceba que o id do <span> não mudou. Isso foi feito para que não prejudique o que já estava funcionando no sistema.

Bom… Caso você queira ver esse exemplo na prática, acesse esse link:

http://jsfiddle.net/RUwtt/244/

Espero que esse exemplo seja útil para você. Grande abraço!

4 responses to “Criando um campo editável com JQuery

  1. Muito bom Willian, parabéns!

    Vou ver pra utilizar aqui em um projeto da empresa.

    Abraços!

  2. @Anderson… para fazer um upload de imagem já é um pouco mais complicado. Se você quiser fazer um upload para o servidor toda vez, é necessário ter um submit de form para isso. Dai começa o problema, porque você não pode ter um form dentro de outro. Bom… lamento não ter um exemplo para fazer isso aqui comigo. :/

Leave a Reply

Your email address will not be published. Required fields are marked *