What is the return order of the Javascript "find" function?

Asked

Viewed 85 times

0

I have an application in Django that uses this widget: https://github.com/ExoticObjects/django-better-filter-widget/

dj

In line 6 of the Better-filter-widget.js file the plugin executes the following:

orig_input.find('option:selected').each(function(i, opt)

I needed the elements to be inserted in the "Selected Children" column exactly in the selection order and not in the alphabetical order.

The "find" function returns the elements in the order they appear in document?

  • 1

    find takes the order of the elements. It does not rearrange by any criteria. The plugin you are using recreates a list of elements each time you select an item, and since the first list is in alphabetical order, the second dynamic list tb will be.

1 answer

1

The .find returns the elements in the order they are in the DOM. The plugin you are using recreates a list of div's (Selected Children) each time you select an element from the first list (Available Children). As the names in the first list are in alphabetical order, consequently the second list will also be in the same order, because the .find so he finds them in the DOM.

What you can do is add some codes in the plugin to get the result you want. For this you need to add an attribute to the added item so that we can then rearrange the second list. This attribute would be a dataset with a numeric value representing the order in which the item was added, for example:

var ordem = 1;
// adiciona ao item o atributo data-add = ordem;
ordem++; // incrementa +1 para o próximo item

Thus, the last item added will always have a higher value than the previous one. These values will be used so that we can rearrange the Divs from the second list.

Change the function selectItem() and declare the variable ordem with the value 1:

var ordem = 1;
function selectItem(){
   // BFWTimer.start(arguments.callee.name);
   var selected_item = $(this);
   var selected_id = selected_item.data('id');
   selected_item.addClass('selected');
   // if (had_focus) filter_input.focus(); // to bring keyboard back on mobile
   // select item in the hidden input
   orig_input.find('option[value='+selected_id+']').attr(
   {
      'selected':'selected',
      'data-add': ordem
   });
   ordem++;
   updateSelectedDisplay();
   toast('Added '+ selected_item.text());
   // BFWTimer.report(arguments.callee.name);
}

Now change the function updateSelectedDisplay() inserting a code that will rearrange the Divs by the attribute value data-add added:

function updateSelectedDisplay(){
   // BFWTimer.start(arguments.callee.name);
   selected_items.html('');
   orig_input.find('option[selected]').each(function(i, opt){
      opt = $(opt);
      var item = $('<div class="item item-selected" data-add="'+ opt.data("add") +'" data-id="'+opt.attr('value')+'"><span class="action-icon action-icon-minus">-</span>'+opt.text()+'</div>');
      selected_items.append( item );
      item.click(deselectItem);
   });

   // reorganiza divs pelo data-add crescente
   selected_items.find('div.item').detach().sort(function(a, b) {
      return a.dataset.add - b.dataset.add;
   }).appendTo(selected_items);


   // BFWTimer.report(arguments.callee.name);
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.