javascript - jQuery byta DIV till INPUT och vice versa


Jag implementerar en slags funktionalitet för inline-redigering.

Så initialt kommer en datumetikett (till exempel 05/01/1999) att visas och vid ett klick på den skulle den ersättas med en inmatningsruta med samma värde (05/01/1999). Nu kan användaren välja ett datum med jQuery UI-datumpickern och vid val av ett datum (till exempel 05/01/2005) kommer jag igen att visa en etikett (05/01/2005).

För närvarande använder jag koden nedan;

$(document).on("click",".editableDateTxt", function () {
    var currElmModelAttr = $(this).attr('data-model-attr');
    var input = $('<input />', {'type': 'text','name':currElmModelAttr, 'style':'width:100px','class':'datePicker', 'value': $(this).html()});
    var parent = $(this).parent();
    parent.append(input);
    $(this).remove();
    input.datepicker().focus();
});

Vad är det bästa sättet att implementera samma?

Nu är här den avgörande punkten: Jag använder jQuery UI datepicker, som använder jQuery data() internt. Så jag vill inte förlora det när jag hoppar från div > input och vice versa.

Hur kan jag ändra koden ovan för att ta hänsyn till att jQuery data()-informationen behålls?

Uppdaterad kod

 var MyView = BaseModalView.extend({
            el: "#myModalContainer",
            initialize: function() {
                var self = this;
            
            },

render: function() {
                var self = this,
                    $el = $(self.el);
                
                $el.find(".datePicker").datepicker();
                self.initEventListeners();
            },

initEventListeners: function() {
                var self = this, 
                    $el = $(self.el);

        var $this;
$(document).on("click", ".editableDateTxt", function () {
    var currElmModelId = $(this).attr('data-model-id');
    var currElmModelAttr = $(this).attr('data-model-attr');
    $this = $(this);
    var input = $('<input />', {
            'type': 'text',
            'name': currElmModelAttr,
            'data-model-id': currElmModelId, 
            'data-model-attr': currElmModelAttr,
            'style': 'width:100px',
            'class': 'datePicker',
            'value': $(this).text()
    });
    $(this).replaceWith(input);
    input.datepicker({
        onSelect: function (date) {
            $this.text(date);
            input.replaceWith($this);
            // input.blur();
        }
    }).focus();
    $(document).on("blur change", "input", function () {
        setTimeout(function () {
            var value = input.val();
            $this.text(value);
            input.replaceWith($this);
        }, 100);

    });

});

}

Svar #1

Du kan göra det bättre genom att byta med replaceWith()

$(document).on("click", ".editableDateTxt", function () {
    var currElmModelAttr = $(this).attr('data-model-attr');
    var $this = $(this);
    var input = $('<input />', {
        'type': 'text',
        'name': currElmModelAttr,
        'style': 'width:100px',
        'class': 'datePicker',
        'value': $(this).text()
    });
    $(this).replaceWith(input);
    input.datepicker({
        onSelect: function (date) {
            $this.text(date);
            input.replaceWith($this);
            console.log(date);
        }
    })

});

Uppdaterad demo

Jag föreslår också att du döljer/visar elementen, vilket skulle vara bättre i det här fallet, istället för att skapa och byta element varje gång.

Svar #2

Här är en enklare version, som föreslagits av @Shaunak D, med användning av grundläggande hide() och show().

^_^jsfiddle-exempel

Html-kod:

<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>

<div id="lbl"></div>
<input type='text' id="date-picker" />

Js-koder:

$('#lbl').html('2014-01-01');
$('#date-picker').hide();
$('#date-picker').datepicker({
   onSelect: function(date) {
        $('#lbl').html(date);
        $(this).hide();
        $('#lbl').show();
    }
});

$('#lbl').click(function(){
  //alert();
  $(this).hide();
  $('#date-picker').show();

});