jQuery replace DIV to INPUT and vice versa

10,157

You can do that better swapping with 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);
        }
    })

});

Updated Demo

Also, I suggest, you hide/show the elements, which would be better in this case, instead of creating and swapping elements every time.

Share:
10,157
copenndthagen
Author by

copenndthagen

Buy some cool JavaScript related merchandise from; https://teespring.com/stores/technical-guru-2

Updated on June 22, 2022

Comments

  • copenndthagen
    copenndthagen almost 2 years

    I am implementing an inline edit kind of functionality.

    So initially a date label (say 05/01/1999) will be displayed and on click of it, it would be replaced with an input box with the same value (05/01/1999). Now user can select any date using the jQuery UI date picker and on select of any date (say 05/01/2005), I would again show a label (05/01/2005)

    Currently I am using the below code;

    $(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();
    });
    

    What is the best way to implement the same?

    Now here is the crucial point: I am using jQuery UI datepicker, which uses the jQuery data() internally. So I do not want to loose it while jumping from div > input and vice versa.

    How can I modify the above code to consider that the jQuery data() info stays?

    Updated code

     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);
    
        });
    
    });
    
    }
    
  • copenndthagen
    copenndthagen almost 10 years
    and i think i'll not have onSelect: function (date) {} inside click of editableDateTxt ....would have that replace handled in change of .datePicker
  • copenndthagen
    copenndthagen almost 10 years
    so what is the correct way? can u post on fiddle something which works with click, change, blur
  • Shaunak D
    Shaunak D almost 10 years
    You have to use onselect, on change and on blur wont work on '.datepicker` wait i'm working on a solution.
  • copenndthagen
    copenndthagen almost 10 years
    Thx....butit would be really great and appeciated if u can update the fiddle so that i get a clear working picture...i'll accept the answer and close...coz i need that on blur, the date picker should hide and show back as label text
  • copenndthagen
    copenndthagen almost 10 years
    or are u saying it is not possible to have all at once (click,change blur) ?
  • Shaunak D
    Shaunak D almost 10 years
    See, the Datepicker plugin gives datepicker value to input after the blur in fired. So the blur,change event won't get the changed date
  • copenndthagen
    copenndthagen almost 10 years
    ok..but how do I hide the picker input on blur and show back the date as label ?
  • copenndthagen
    copenndthagen almost 10 years
    i m getting TypeError: e is undefined (when i select any date and also when i click out i.e. blur)
  • copenndthagen
    copenndthagen almost 10 years
    Actually i don't know why...but when i select any date..it has the div element in $this , but after it fires input.replaceWith($this); ...nothing is visible in the div
  • Shaunak D
    Shaunak D almost 10 years
    is the $this global? Settimeout is just for getting values. Post a fiddle which is giving error
  • copenndthagen
    copenndthagen almost 10 years
    I have defined it outsde $(document).on("click", ".editableDateTxt", ...) so it does seem to be global
  • copenndthagen
    copenndthagen almost 10 years
    Hmm...I know the fiddle is working...but not sure why it is not working for me....Actually i cannot post the exact thing i m working on...since it is a complete Backbone View inside of which i have this code....
  • Shaunak D
    Shaunak D almost 10 years
    Have you removed all the other events? Your previous blur and change?
  • ebiv
    ebiv almost 10 years
    The best way to do this is to use a readonly input field with the date picker. Is there any reason behind using the div and replacing with input field?
  • copenndthagen
    copenndthagen almost 10 years
    when i debug i get $this as the div element with correct values....but then the div itself disappears from the DOM completely..like gets deleted...not sure somthing inside setTimeout or what ?
  • copenndthagen
    copenndthagen almost 10 years
    I have updated the code in my original question to include more of the view code...pls ignore any braces issues...i have just copied it at random to give a more detailed picture...
  • copenndthagen
    copenndthagen almost 10 years
    In that case, it gives me an error...uncaught exception: Missing instance data for this datepicker (on date select)...
  • copenndthagen
    copenndthagen almost 10 years
    Here is what...i increased the setTimeout delay to 1000...then i select a date...the selected date appears as label after 1 sec and then just disappears....