jquery $(this).attr(…) returns undefined - javascript

I'm trying to get the title of an option element, but it keeps returning undefined. This also happens for $(this).attr("name")…and $(this).attr("value"), but curiously $(this).val() works (as expected). Yet, I'm able to set the value with $(this).attr("value", "baz").
Fiddle: http://jsfiddle.net/jshado1/JgAJC/1/

this points to the <select> element. For the selected option, use:
this.options[this.selectedIndex]
Full code (you can safely unwrap $opt's jquery wrapper, and use $opt.title and $opt.name, these are safe across all browsers):
$('select').change(function() {
var $opt = $(this.options[this.selectedIndex]),
t = $opt.attr("title"),
n = $opt.attr("name"),
v = this.value;
$("#name").text("name: "+n);
$("#title").text("title: "+n);
$("#value").text("value: "+v);
});
Another method, the jQuery-way is:
$('select').change(function() {
var $opt = $(this).children(':selected'),
t = $opt.attr("title"),
n = $opt.attr("name"),
v = this.value;
$("#name").text("name: "+n);
$("#title").text("title: "+n);
$("#value").text("value: "+v);
});

This is because you have mistaken what this represents in your code. The this represents the select element that has changed. Because the select node doesnt have a title attribute, it is undefined. What you would need to do is enumerate over the options list of the select and find the item that is selected. Then, you can operate on that item to find information like so:
var element = $(this.options[this.selectedIndex]);
element.attr('title');

Related

exchanging values in a select list with jQuery

I'm trying to swap select option values with jQuery when a links clicked, at the moment its just resetting the select when the links clicked, not sure what's going wrong?:
jQuery:
$(function () {
$("#swapCurrency").click(function (e) {
var selectOne = $("#currency-from").html();
var selectTwo = $("#currency-to").html();
$("#currency-from").html(selectTwo);
$("#currency-to").html(selectOne);
return false;
});
});
JS Fiddle here: http://jsfiddle.net/tchh2/
I wrote it in a step-by-step way so it is easier to understand:
$("#swapCurrency").click(function (e) {
//get the DOM elements for the selects, store them into variables
var selectOne = $("#currency-from");
var selectTwo = $("#currency-to");
//get all the direct children of the selects (option or optgroup elements)
//and remove them from the DOM but keep events and data (detach)
//and store them into variables
//after this, both selects will be empty
var childrenOne = selectOne.children().detach();
var childrenTwo = selectTwo.children().detach();
//put the children into their new home
childrenOne.appendTo(selectTwo);
childrenTwo.appendTo(selectOne);
return false;
});
jsFiddle Demo
Your approach works with transforming DOM elements to HTML and back. The problem is you lose important information this way, like which element was selected (it is stored in a DOM property, not an HTML attribute, it just gives the starting point).
children()
detach()
appendTo()
That happens because you remove all elements from both <select> fields and put them as new again. To make it working as expected you'd better move the actual elements as follows:
$("#swapCurrency").click(function(e) {
var options = $("#currency-from > option").detach();
$("#currency-to > option").appendTo("#currency-from");
$("#currency-to").append(options);
return false;
});
DEMO: http://jsfiddle.net/tchh2/2/
You are replacing the whole HTML (every option) within the <select>. As long as each select has the same amount of options and they correspond to each other, you can use the selected index property to swap them:
$("#swapCurrency").click(function (e) {
var selOne = document.getElementById('currency-from'),
selTwo = document.getElementById('currency-to');
var selectOne = selOne.selectedIndex;
var selectTwo = selTwo.selectedIndex;
selOne.selectedIndex = selectTwo;
selTwo.selectedIndex = selectOne;
return false;
});
JSFiddle

changing text for a selected option only when its in selected mode

I am not sure if I confused everyone with the above title. My problem is as follows.
I am using standard javascript (no jQuery) and HTML for my code. The requirement is that for the <select>...</select> menu, I have a dynamic list of varying length.
Now if the length of the option[selectedIndex].text > 43 characters, I want to change the option[selectecIndex] to a new text.
I am able to do this by calling
this.options[this.selectedIndex].text = "changed text";
in the onChange event which works fine. The issue here is once the user decides to change the selection, the dropdownlist is showing the pervious-selected-text with changed text. This needs to show the original list.
I am stumped! is there a simpler way to do this?
Any help would be great.
Thanks
You can store previous text value in some data attribute and use it to reset text back when necessary:
document.getElementById('test').onchange = function() {
var option = this.options[this.selectedIndex];
option.setAttribute('data-text', option.text);
option.text = "changed text";
// Reset texts for all other options but current
for (var i = this.options.length; i--; ) {
if (i == this.selectedIndex) continue;
var text = this.options[i].getAttribute('data-text');
if (text) this.options[i].text = text;
}
};
http://jsfiddle.net/kb7CW/
You can do it pretty simply with jquery. Here is a working fiddle: http://jsfiddle.net/kb7CW/1/
Here is the script for it also:
//check if the changed text option exists, if so, hide it
$("select").on('click', function(){
if($('option#changed').length > 0)
{
$("#changed").hide()
}
});
//bind on change
$("select").on('change', function(){
var val = $(":selected").val(); //get the value of the selected item
var text = $(':selected').html(); //get the text inside the option tag
$(":selected").removeAttr('selected'); //remove the selected item from the selectedIndex
if($("#changed").length <1) //if the changed option doesn't exist, create a new option with the text you want it to have (perhaps substring 43 would be right
$(this).append('<option id="changed" value =' + val + ' selected="selected">Changed Text</option>');
else
$('#changed').val(val) //if it already exists, change its value
$(this).prop('selectedIndex', $("#changed").prop('index')); //set the changed text option to selected;
});

Access a label's attribute using jquery

I have some data coming from the server in which I fill A Div in the Html page with.
The way I write the div is as follows:
<div class="BigDiv"><label class = "AttList" Std_Id="' + Std_Id + '">' + Std_Name +'</label></div>
Now, I want the data inside this div.
There are some other labels inside the div so I use this.children to access this label.
var labels = $(this).children('div');
var StdName = this.children[0].childNodes[0].nodeValue;
I want to access the Std_Id inside the Std_Id attribute, but I don't know how to do it ... Do you have any ideas?
Thanks.
Assuming that $(this) is a reference to the .BigDiv element:
var StdName = $(this).find('label').attr('Std_Id');
Or, similarly, and with the assumption that this is the .BigDiv element:
var children = this.childNodes;
for (var i=0,len=children.length; i<len; i++){
if (children[i].nodeType == 1 && children[i].tagName.toLowerCase() == 'label'){
var StdName = this.getAttribute('Std_Id');
}
}
References:
jQuery:
attr().
find().
JavaScript
element.getAttribute().
node.nodeType.
tagName.
toLowerCase().
Use getAttribute:
var labels = $(this).children('div');
var StdId = this.children[0].getAttribute("Std_Id");
Note that, according to the HTML5 spec, custom attributes should start with data-, though most browsers can tolerate it.
To save elements, which were selected using a jQuery-Selector, do this:
$labels = $('.BigDiv').find('label');
Now you can loop through each label with jQuery's foreach loop:
$.each($labels, function() {
var std_id = $(this).attr('Std_Id');
// do something with std_id
});
You could use the attr method as such,
var value = $('.AttList').attr('Std_Id');
EDIT
OK, so you for your implementation, you need to do this...
var value = $(this).find('.AttList').attr('Std_Id');
Assuming that this is the div or the parent of that div

Is it possible to make an option of a select dropdown appear as optgroup via css

I am actually populating options from xml for my dropdown and Now adding an optgroup to select is a challenge. Can I add them manually and change the behaviour via css
You can add options and optgroups to the select box manually after the fact with jQuery. Assuming your HTML is already available, you could do something like this:
$("select").append("<optgroup label='Example'><option>Test1 </option> <option>Test 2</option></optgroup>")
If you already have options in the select element, then it would just be a matter of finding all of those options that you would like to group up (via a class name or value attribute, perhaps), then pushing them into a newly create optgroup, then appending the optgroup into the select. Example:
var optionsToGroup = $("option.groupthis");
var optGroup = $("<optgroup></optgroup>").append(optionsToGroup);
$('select').append(optGroup);
Edit: Based on the Fiddle you've provided, I modified your jQuery code to build the optgroup before the options. This isn't the most efficient way, but it should get you started based on what you've provided. See http://jsfiddle.net/xUJZj
var title = $(this).find('title').text();
var optgrouping = "<optgroup label='"+title+"'></optgroup>";
var options = [];
$(this).find('value').each(function(){
var value = $(this).text();
options.push("<option class='ddindent' value='"+ value +"'>"+value+"</option>");
});
var grouping = $(optgroupting).html(options.join(''));
select.append(grouping);
Edit 2: I've modified the JSFiddle to use an actual XML doc (similar to what you provided). See it here: http://jsfiddle.net/xUJZj/13/
Or, the relevant modified code is here below:
function createSelect(xml)
{
var select = $('#mySelect');
$(xml).find('menuitem').each(function(){
var title = $(this).find('title').text();
var optgrouping = "<optgroup label='"+title+"'></optgroup>";
var options = [];
$(this).find('value').each(function(){
var value = $(this).text();
options.push("<option class='ddindent' value='"+ value +"'>"+value+"</option>");
});
var group = $(optgroupting).html(options.join(''));
select.append(group);
});
select.children(":first").text("please make a selection").prop("selected",true);
}
});
}

Altering the value of an option (select) element?

I'm attempting to select the selected value of a <select> form element, and append the value with -R. (This will be for regex matching later on). Anyway, so far I've tried the following:
Attempt 1:
var country = $('select[name=g_country\\['+value+'\\]]').val();
$('select[name=g_country\\['+value+'\\]]').find('option[value=' + value +']').val(country + '-R');
Attempt 2:
var country = $('select[name=g_country\\['+value+'\\]]').val();
$('select[name=g_country\\['+value+'\\]]').val(country + '-R');
I can tell that the selection of the correct form element (using delete_x, where x is a number) works fine, as the form elements to disable when .select-delete is clicked, however the value setting doesn't. The commented portion down the bottom is what I've been using to check the value of the <select> element post-value change (or what should be post-value change).
Here's a link to my jsFiddle: http://jsfiddle.net/gPF8X/11/
Any help/edits/answers will be greatly appreciated!
Try this:
$('.select-delete').click( function() {
var value = $(this).attr('id');
value = value.replace('delete_', '');
var country = $('select[name=g_country\\['+value+'\\]] option:selected').val() + '-R';
alert(country);
$('select[name=g_country\\['+value+'\\]] option:selected').val(country);
$('select[name=g_country\\['+value+'\\]]').attr('disabled','1');
$('input[name=g_url\\['+value+'\\]]').attr('disabled','1');
$(this).css('display', 'none');
var check = $('select[name=g_country\\['+value+'\\]]').val();
$('#test').append(check);
});
There is an issue with your HTML as well.
Finally came up with the right selector, props to #gjohn for the idea.
Here's my final working code, that appropriately adds -R to the end of g_country[x]:
$('.select-delete').click( function() {
var value = $(this).attr('id');
value = value.replace('delete_', '');
var country = $('select[name=g_country\\['+value+'\\]]').val();
$('select[name=g_country\\['+value+'\\]] > option:selected').val(country + '-R');
$('select[name=g_country\\['+value+'\\]]').attr('disabled','1');
$('input[name=g_url\\['+value+'\\]]').attr('disabled','1');
$(this).css('display', 'none');
});

Categories