2

How can I re-order the comma delimited value of a select multiple element based on the order in which the options were selected by the user instead of the order of the options in the html?

For example:

<select multiple>
    <option>1</option>
    <option>2</option>
    <option>3</option>
</select>

... If the user selects "3", then "1", then "2", the returned value of the select will be "1,2,3". How can I make it return "3,1,2"?

Note, I am using jQuery and HTML5, so I can use those tools if needed.

Thanks!

p1xelarchitect
  • 289
  • 1
  • 6
  • 19
  • Something similar. http://stackoverflow.com/questions/30372235/html-select-multiple-get-all-values-at-onchange-event – rajesh Apr 06 '16 at 05:41
  • https://jsfiddle.net/nbh72tc5/ can you try this? – Sam Teng Wong Apr 06 '16 at 05:41
  • @SamTengWong Thanks, your example shows the default setting. If you select 3, then 1, then 2, it will alert "1,2,3". I need some function that will alert the value as "3,1,2", because that's the order in which I selected the options. – p1xelarchitect Apr 06 '16 at 05:44
  • @rajesh Yes I saw that post before I asked my question. That question is just asking to return the value onchange but that poster isn't concerned with the order of selection. – p1xelarchitect Apr 06 '16 at 05:46
  • You have to follow this way only to get the value in the order you have selected. By default it will always give you in top to bottom order. So what you can do is on change event you can store the values in an array. – rajesh Apr 06 '16 at 05:51
  • The idea I have in my head is to assign an attribute to each option when they're selected with some kind of counter. For example, – p1xelarchitect Apr 06 '16 at 06:12

4 Answers4

1

This records the click of each elements add saves it to an array. When an item is deselected it is removed from the array.

var vals = [];
$(document).ready(function(e) {
  $('#selector').change(function(e) {
    for(var i=0; i <$('#selector option').length; i++) {
      if ($($('#selector option')[i]).prop('selected') ) {
        if (!vals.includes(i)) {
          vals.push(i);
        }
      } else {
        if (vals.includes(i)) {
          vals.splice(vals.indexOf(i), 1);
        }
      }
    }

  })

  $("#final").click(function(e) {
    var order = '';
    vals.forEach(function(ele) {
      order += $($('#selector option')[ele]).val() + ',';
    })

    console.log(order);
  })
})

Codepen: http://codepen.io/nobrien/pen/pydQjZ

NOBrien
  • 459
  • 3
  • 7
  • noice. you don't need the `if (vals.includes(i))` condition, however since the fact that we get to the `else` block already means that `vals.includes(i)` is true. nothing wrong, just redundant, namean? – digglemister Apr 06 '16 at 06:21
1

None of the proposed solutions floated my boat, so I came up with this:

My solution is to add an html5 attribute to the multiselect element, data-sorted-values, to which I append new values, and remove un-selected values, based on the latest change.

The effect in the end is that data-sorted-values can be queried at anytime to get the current list of user-ordered values. Also, all selected options hold an attribute of "selected".

I hope this can help someone else out there...

https://jsfiddle.net/p1xelarchitect/3c5qt4a1/

HTML:

<select onChange="update(this)" data-sorted-values="" multiple>
    <option>A</option>
    <option>B</option>
    <option>C</option> 
</select>

Javasript:

function update(menu) {

    // nothing selected
    if ($(menu).val() == null) 
    {
        $.each($(menu).find('option'), function(i) 
        {
            $(this).removeAttr('selected');
            $(menu).attr('data-sorted-values', '');
        });
    } 
    // at least 1 item selected
    else 
    {
        $.each($(menu).find('option'), function(i) 
        {
            var vals = $(menu).val().join(' ');
            var opt = $(this).text();

            if (vals.indexOf(opt) > -1) 
            {
                // most recent selection
                if ($(this).attr('selected') != 'selected') 
                {
                    $(menu).attr('data-sorted-values', $(menu).attr('data-sorted-values') + $(this).text() + ' ');
                    $(this).attr('selected', 'selected');
                }
            } 
            else 
            {
                // most recent deletion
                if ($(this).attr('selected') == 'selected') 
                {
                    var string = $(menu).attr('data-sorted-values').replace(new RegExp(opt, 'g'), '');
                    $(menu).attr('data-sorted-values', string);
                    $(this).removeAttr('selected');
                }
            }
        });
    }
}
p1xelarchitect
  • 289
  • 1
  • 6
  • 19
0

try this https://jsfiddle.net/ksojitra00023/76Luf1zs/

  <select multiple>
        <option>1</option>
        <option>2</option>
        <option>3</option>
    </select>
    <div id="output"></div>

$('select').click(function(){
  $("#output").append($(this).val());
});
krunal sojitra
  • 385
  • 1
  • 5
0
var data = '3,1,2';
var dataarray=data.split(",");
var length =dataarray.length;
for(i=0;i<length;i++){
    // Set the value
    $('#select').multiSelect('select',dataarray[i]);
}
  • 4
    please add a description and tell how this will solve the problem – janith1024 Jun 09 '20 at 05:30
  • 5
    While this code may resolve the OP's issue, it is best to include an explanation as to how your code addresses the OP's issue. In this way, future visitors can learn from your post, and apply it to their own code. SO is not a coding service, but a resource for knowledge. Also, high quality, complete answers are more likely to be upvoted. These features, along with the requirement that all posts are self-contained, are some of the strengths of SO as a platform, that differentiates it from forums. You can edit to add additional info &/or to supplement your explanations with source documentation – ysf Jun 09 '20 at 21:37