1

Okay so please read on before marking it as duplicate:

First Part: I have a select list. I need to set dynamically whenever I select that particular option.

Second Part: Once this is done, whenever I select another option from the same select list, I want the previous option's selected attribute to be removed and set to the current one.

Note: I dont care about getting the value. I just want to set "selected" attribute since I will be using that for another purpose.

Eg. Currently I selected option- Jquery

<select>
    <option selected="selected">Jquery</option>
    <option>Java</option>
    <option>JS</option>
</select>

So the next time I select- Java, the following should occur:

<select>
    <option>Jquery</option>
    <option>Java</option>
    <option selected="selected">JS</option>
</select>

So I have tried the following which doesn't seem to work:

//First remove the previous set attribute
$('select').click(function() {
    $(this).find('option:selected').removeAttr('selected');
});

//Set the newly selected option's attribute to selected
$('select').on('change', function() {
    $("option:selected").attr('selected','selected');
});

How can I make this happen? Javascript/Jquery solution that can be used for any similar select and not specific to this one.

gireesh_bh
  • 75
  • 1
  • 1
  • 5
  • 1
    this is exactly the native way of working of the select. Once you choose one option it will gain the selected attribute. Then if you select a new one the attribute will be moved to the new selected. – Lelio Faieta Sep 11 '18 at 11:47
  • What have you tried? Stackoverflow is not a free code writing service. The objective is to help you improve your code when it's not working as expected. Also not sure why you would really need to worry about the attribute...unless you must store rendered html somewhere – charlietfl Sep 11 '18 at 11:47
  • @LelioFaieta no it won't. There is a difference between *selected attribute* and *selected property*. The attribute is not updated by user interaction, only the property is – charlietfl Sep 11 '18 at 11:48
  • @charlietfl I have added what I have tried. You don't have to be rude, you can ask if I can add what I have tried. I just forgot to add it. Sorry about that. – gireesh_bh Sep 11 '18 at 11:54
  • @gireesh_bh was not being rude. Many people come here expecting others to simply write code for them and show no attempts of their own to solve their own problem. Now that you added your code we can see that is not the case here...but is very common and requires prompts for people to show their code – charlietfl Sep 11 '18 at 12:03

2 Answers2

1

Use an attribute selector to remove the attribute

The :selected selector works based on selected property, not the attribute

$('select').change(function(e){
   $(this).find('[selected]').removeAttr('selected')
   $(this).find(':selected').attr('selected','selected')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
    <option selected="selected">Jquery</option>
    <option>Java</option>
    <option>JS</option>
</select>
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • Well explained. This is exactly what should be done, you beat me to it. – cнŝdk Sep 11 '18 at 12:00
  • This works like a charm. Thanks a ton @charlietfl ! And I am sorry to not have added my code the first time. I will make sure to not miss out the next time. Thanks again. :) – gireesh_bh Sep 11 '18 at 12:06
0

Wrong Assumption

Attribute/Properties as Defaults

At first I thought this question was trivial because I naturally assumed that any attribute/property bestowed on a tag would show up easily since its just something that confirms a "state" to which an element is obviously in (ex. a checkbox is checked by a user, so there's no need to use .setAttribute() on it so it has the checked attribute because it should already have it by default.)

My assumption was wrong, attributes like checked, selected, disabled, etc are on a tag to set an initial "state" by default. So these attributes/properties do not magically manifest when a user checks a checkbox or selects on <option> from a <select> element. The two most effective ways to handle these attribute/properties is to:

Plain JavaScript

Use set/get/remove/hasAttribute() method family.

jQuery

Use .prop()/.removeProp() method, do not use .attr()


Solution

The following section discusses important parts of the Demo that follows:

var s = sel.options[sel.selectedIndex];

There's two parts to this assignment:
This s a HTMLOptionsCollection which is similar to a NodeList of an array-like Object.

.options

The second half is a property that is unique to <select> and <option> tags:

.selectedIndex

On its own it returns an index number of the first selected <option> of a given <select>, but in combination with the formerly mentioned .options Object, we have a very formidable tool to access a <select>, locate the selected <option>, and retrieve it as a useful DOM Object instead of an index number.

The rest of the demo uses a for() loop, Array.prototype.push(), .setAttribute(), .removeAttribute(). Almost forgot that the jQuery function listened for a "change" event occuring on the <select>:

   $('select').on('change', function(e) {...

Demo

Details are commented in the demo on every line

// Listen for change events on a <select>
var s = $('select').on('change', function(sel) {

  // Empty array
  var sArr = [];

  // Dereferenced jQuery Object
  var sel = $('select')[0];

  // options HTMLCollection with a selectedIndex property
  var s = sel.options[sel.selectedIndex];

  // Total number of loops
  var sL = sel.length;

  // for() loop
  for (let S = 0; S < sL; S++) {

    // On each loop a selected attr is removed from each option
    sel[S].removeAttribute('selected');

    // The empty array is loaded with only the first 3 loops
    if (S < 3) {
      sArr.push(sel[S]);
    }
  }
  // One option from the 3 in the short array gets a selected attr
  s.setAttribute('selected', 'selected');

  // Clear console
  console.clear();

  // Display selected option
  console.log(s);

  // Display all 3 options from the short array
  console.log(sArr);
});
.as-console-row-code {
  color: gold;
  background: #000;
  font-size: 21px;
}

.as-console-row {
  color: gold;
  background: #000;
  max-width: 15px;
}
<select>
  <option> jQuery </option>
  <option> JavaScript </option>
  <option> CSS </option>
</select>




<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
zer00ne
  • 41,936
  • 6
  • 41
  • 68