vicb/bsmSelect

pre-selecting items during page load and cannot control order

macwizard2 opened this issue · 10 comments

I have the following javascript in-place to preselect items when a page loads. I'm using web2py and {{=fill_messages_saved}} returns an array [4, 144, 142, 143], which all correspond to values of the options I'd like to select. Unfortunately, the order is always displayed in the order generated in the portion of the html. Is there a way to load each item according to the array of values {{=fill_messages_saved}} as preselected options when a page loads? I can watch each item load individually with the alert() below, but they don't load top down.. they retain the order designated in the html. When I manually select the options, they show up correctly. jQuery(document).ready(function(){ jQuery(function($) { $("#fill_messages").bsmSelect({ animate: true, highlight: true, plugins: [$.bsmSelect.plugins.sortable(), $.bsmSelect.plugins.compatibility()] }); }); $(window).load(function(){ $.each({{=fill_messages_saved}}.toString().split(","), function(i,e){ alert() $("#fill_messages option[value='" + e + "']").prop('selected', true).trigger('change'); }); }); </script>

vicb commented

Could you try to come up with a simple repro case that do not depend on a server side fmwk ?

Here's a repro case without the server side info and the html. I'm hoping to have it pre-populate the list with "Chicken", "Sheep,", "Cow", and "Pig" in that order [4,3,2,1], but it shows up "Pig", "Cow", "Sheep", "Chicken" [1,2,3,4]. Thanks for such a fast response!

jQuery(document).ready(function(){
   jQuery(function($) {
   $("#fill_messages").bsmSelect({
        animate: true,
        highlight: true,
        plugins: [$.bsmSelect.plugins.sortable(), $.bsmSelect.plugins.compatibility()]
      });
});
$(window).load(function(){
$.each([4,3,2,1].toString().split(","), function(i,e){
        alert()
        $("#fill_messages option[value='" + e + "']").prop('selected', true).trigger('change');
    });
});

<select name="fill_messages" id="fill_messages" multiple="multiple" title="Select a fill message">
  <option value=1>"Pig"</option>
  <option value=2>"Cow"</option>
  <option value=3>"Sheep"</option>
  <option value=4>"Chicken"</option>
</select>

I'm hoping to build the order saved [4,3,2,1] instead of [1,2,3,4]. Would this be possible?

vicb commented

I've started to look at this. This is because you use the change event and the previous order is not taken into account in this case.
The solution is probably to select the option (by using attr rather than prop) and then generate a click event (should use triggerOriginalEvent or whatever it's called)

You should give it a try. I won't be able to look before tomorrow

Thank you so much for offering to help. The line $("#fill_messages option[value='" + e + "']").prop('selected', true).trigger('change'); generates the click event, but unfortunately does not add the selected item to the bsmselect list in the order specified in the javascript portion. The order seems to be bound to something in jquery itself.. hmmmmm.

I'll keep working, but could still use some more help.

vicb commented

You should try triggering a click event rather than a change event. On clicks we know that the option has been (un)selected an can deal with the diff. On change we can not know the diff (I mean not easily and not done by bsmSelect) so the code walks all the options adding selected options in the order they appear there.

Yeah, I agree with you, but I can't get .trigger('click') to work w/ bsmselect. Once bsmselect is initialized, the only way I can simulate a click is through .trigger('change').

Bsmselect seems to rebuild when the 'change' event is triggered on the original select. Any way to have it rebuild based on the most recently selected items? Any luck finding a way to trigger a click event instead?

Any luck adding selected options by click? I haven't had any :-(

Hello @macwizard2

I use web2py, here what I do to workaround, I think, a pretty similar problem:

ordered_fieldname_list_query = db[request.args(0)](request.args(1)).ordered_max_to_minus_5_ordered_fieldname_list
controller_view_js = controller_view_js + 'var ordered_fieldname_list = ''%s''; $(document).ready(function() { if(ordered_fieldname_list != "None") { $.each(ordered_fieldname_list, function(i, val) { $("select[name=ordered_max_to_minus_5_ordered_fieldname_list]").append("<option value=\'"+ordered_fieldname_list[i]+"\'>"+$("select[name=ordered_max_to_minus_5_ordered_fieldname_list] option[value="+ordered_fieldname_list[i]+"]").text()+"</option>"); }); $("select[name=ordered_max_to_minus_5_ordered_fieldname_list] option:selected").remove(); $.each(ordered_fieldname_list, function(i, val) { $("select[name=ordered_max_to_minus_5_ordered_fieldname_list] option[value="+ordered_fieldname_list[i]+"]").attr("selected", "selected"); }); }; });' % [int(ID) for ID in ordered_fieldname_list_query]

I am doing that in the update view of the form to get the proper stored order...

Hope this help...