Reputation: 55
Knowing HTML well, I'm trying to learn JQuery. I found the .change function on a JQuery site that does exactly what I want.
Ideally I'd like test1 and test2 to only affect each other and test3 and test4 only each other and so on.
Right now test2 and test4 affect both test1 and test3
Here is my code:
<select id="test1" name="sweets" multiple="multiple">
<option>Chocolate</option>
<option selected="selected">Candy</option>
<option>Taffy</option>
<option selected="selected">Caramel</option>
<option>Fudge</option>
<option>Cookie</option>
</select>
<div id="test2"></div>
<script>
$("select#test1").change(function () {
var str = "";
$("select option:selected").each(function () {
str += $(this).text() + " ";
});
$("div#test2").text(str);
})
.change();
</script>
<select id="test3" name="sweets" multiple="multiple">
<option>Chocolate</option>
<option selected="selected">Candy</option>
<option>Taffy</option>
<option selected="selected">Caramel</option>
<option>Fudge</option>
<option>Cookie</option>
</select>
<div id="test4"></div>
<script>
$("select#test3").change(function () {
var str = "";
$("select option:selected").each(function () {
str += $(this).text() + " ";
});
$("div#test4").text(str);
})
.change();
</script>
I tried separating it with ID's, but it's not quite there yet. How would I get this to work right?
Upvotes: 4
Views: 139
Reputation: 37997
It seems like what you actually want is a generic control that relates a select box to its sibling div tag. For that you want something a bit different:
http://jsfiddle.net/b9chris/KpUWP/
(function() {
function update() {
var str = $.map($('option:selected', this), function(option) {
return $(option).text();
}).join(' ');
$(this).next().text(str);
};
$("select").change(update)
.each(update);
})();
So first you define the update function separately, instead of assigning it directly to the change() handler and then firing the change() event. Although doing so is a pretty good hack, it introduces weird problems if anything else needs to listen for the change event.
Then to get the div you want to assign your string to, since you know it's always the next sibling, you just use .next()
.
To build the space-delimited string you were building, instead of an each loop you can just use a map function which simply takes each element in the selected list (selected option tags in this case) and returns their text value. The result is a simple array of what you wanted, which the JS built-in .join() method then builds your final string from.
It appears you already noticed the this object in the update function is the select tag; you can use this as the context of searches like the call to $('option:selected', this)
to get just the options for that tag, rather than having to resort to IDs and trying to work back what select is being referred to in a given handler.
Upvotes: 0
Reputation: 14385
$("select#test1").change(function () {
var str=$("#test1 :selected").text();
$("div#test2").text(str);
});
js fiddle http://jsfiddle.net/xdJ3H/
Upvotes: 0
Reputation: 1527
That's because you are selecting all selected options on your page.
Instead of $("select option:selected").each(..)
use $(this).find("select option:selected").each(..)
. This way it will only display the selected options of the select that was changed in the test2-div, and not the options from the other select.
Upvotes: 0
Reputation: 1026
This line:
$("select option:selected").each(function () {
Should be written like this:
$("#test1 option:selected").each(function() {
By using the generic "select" in that line, you are selecting every "select" element on the page, by using its id instead, it will only target the desired select tag.
Upvotes: 2