Search code examples
jquerynested-sortable

jQuery Sortable update output on input


We're using the jQuery Sortable library for dynamic menu management similar to WordPress. And it has multi level management.

<ol id="my-nav">
    <li data-id="unique-id-here" data-label="">
        <span>My Label</span>
        <input type="text" class="label-change">
        <ol><!-- PLACEHOLDER FOR SUBMENU --></ol>
    </li>
</ol>

<textarea id="output"></textarea>

We want to update the Menu Label using the inherited input field. So we did something like below:

$('body').on('keyup change', '.label-change', function () {
    var this_menu_label_field = $(this);
    var this_field_val        = this_menu_label_field.val();
    var this_menu_nav         = this_menu_label_field.parents('li');

    // Update the text string inside the <li>
    this_menu_nav.find('span').html(this_field_val);

    // Update the data-label attribute
    this_menu_nav.attr('data-label', this_field_val).sortable('refresh');

    var serialized_data = menu_container.sortable('serialize').get();
    $('#output').val(JSON.stringify(serialized_data));
});

The code is updating the string inside the <span> inside the respective <li> and also changing the data-label. But unfortunately it's updating only the first keystroke into the #output textarea.

For example: if we type "Whatever", it might take "W" or "Wha". And no further keystrokes are updated into the #output. But at always the update inside the <span> and data-label is working fine.

We need this kind of feature critically. But how can we achieve this?

DEMO Fiddle

https://jsfiddle.net/mayeenulislam/Lsrgu0qy/38/

  • Do nothing, see the value in the <textarea>
  • Do nothing, just type in the textbox
  • Now see the value in the <textarea> again

Solution

  • I fiddled around with this and was able to make it work. Check my forked fiddle here: jsfiddle.net/qf7n89oe.

    The only change I made was to replace

    this_menu_nav.attr('data-label', this_field_val).sortable('refresh');
    

    with

    this_menu_nav.data('label', this_field_val).sortable('refresh');
    

    It seems using attr() causes some caching issues so I replaced it with data() which doesn't seem to have this problem.