2

I have a list of n selects containing values from 1 to n. Whenever I change a value in a select, the other select containing the same value should be swapped to what was previously selected in the first select.

For example, initially listA is set to 1 and listE is set to 5. If listA is changed to 5 then listE should become 1, and the other lists remain unchanged.

This is different from questions such as How to swap values in select lists with jquery? because the values are swapped between multiple dynamic lists instead of between two static lists.

EDIT: Every value should only appear once in the group of lists. They initially all have distinct values.

Here is the code I have so far, needless to say, it does not work :

http://jsfiddle.net/yye3U/

HTML:

<div class="parentdiv">
  <select class="ranking">
    <option value="1" selected>1</option>
    <option value="2">2</option>
    <option value="3">3</option>
  </select>
  <select class="ranking">
    <option value="1">1</option>
    <option value="2" selected>2</option>
    <option value="3">3</option>
  </select>
  <select class="ranking">
    <option value="1">1</option>
    <option value="2">2<option>
    <option value="3" selected>3</option>
  </select>
</div>

JS:

var previous;
$( ".ranking" ).on( "focus", function() {
    previous = $( this ).val();
}).change(function() {
    var value = $( this ).val();
    var parent = $( this ).closest( ".parentdiv" );

    $( ".ranking option[value='" + value + "']", parent ).not( this ).parent().prop( 'selectedIndex', parseInt(previous) - 1 );
});
Community
  • 1
  • 1
Digzol
  • 323
  • 1
  • 12
  • Not sure to understand, you mean like this ? http://jsfiddle.net/yye3U/2/ – Karl-André Gagnon May 15 '14 at 13:43
  • So will it always initially start as Select0[0], Select1[1], Select2[2],...,SelectN[N]? – em_ May 15 '14 at 13:43
  • @Karl-AndréGagnon Changing the first list to 2 then back to 1 won't update the second list when changing back to 1. Each value should only appear once in the list. – Digzol May 15 '14 at 13:49
  • @Karl-AndréGagnon's answer seems to be exactly what I thought you were asking for as well, I've just updated with 5 options. http://jsfiddle.net/yye3U/3/ – dcclassics May 15 '14 at 13:49
  • So if you have three selects, with the order 1,2,3, and then change the third to 1, the order should be 3,2,1? If so, then what should the order be after than if the second select is changed to 1? – j08691 May 15 '14 at 13:51
  • @j08691 That should be 3,1,2 – Digzol May 15 '14 at 13:53
  • @Karl-AndréGagnon Ah! I just realized that is because the previous value is only changed on focus... is there a way to fix this? – Digzol May 15 '14 at 13:55
  • @Digzol i just fast coded to see if that was what you wanted, if that's a yes, ill post a good code. – Karl-André Gagnon May 15 '14 at 13:56
  • @Karl-AndréGagnon With an alternative way to the focus method this is exactly what is needed. – Digzol May 15 '14 at 13:58

2 Answers2

5

By storing the previous value in the data of the DOM element, you can easily do what you want with that simple code :

$(".ranking").each(function(){
    $(this).data('__old', this.value);
}).change(function() {
    var $this = $(this), value = $this.val(), oldValue = $this.data('__old');

    $(".ranking").not(this).filter(function(){
        return this.value == value;
    }).val(oldValue).data('__old', oldValue);

    $this.data('__old', value)
});

Here's a fiddle

Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75
1

Just add ':selected' to your selector in the last line of your JS:

$(".ranking option[value='" + value + "']:selected", parent).parent().not(this).prop('selectedIndex', parseInt(previous) - 1);
a1ee9b
  • 31
  • 6