Search key in json object based on value - javascript

I populate the options of a select input field based on json data I get from a php-script.
This works fine, but I want to show some extra info, based on the selected option.
Basically, I'm looking for a way to find the key that goes with the selected option:
$("#code").html(result[whichkey]["uniquecode"]);
This fiddle hopefully makes my question a bit more clearer.
Any help is much appreciated!

Given that the option element is created with the uniquecode of the object as its value, why do you even need to access the object again? You can just retrieve the value property of the selected option...?
Assuming this is just because you've oversimplified your example, and the objects within the array do hold other useful data which is not held in the option element itself, then you can use $.grep to filter the array of objects by the selected uniquecode, like this:
var json = '[{"uniquecode":"b32dez2","name":"John Doe","foo":"bar"},{"uniquecode":"a2df32","name":"Adam Smith","foo":"buzz"}]';
var result = JSON.parse(json);
var $sel = $('#names').change(function() {
var value = this.value;
var obj = $.grep(result, function(e) {
return e.uniquecode == value;
});
$("#code").html(obj[0].uniquecode + ' / ' + obj[0].foo)
});;
result.forEach(function(obj) {
$('<option value="' + obj.uniquecode + '">' + obj.name + '</option>').appendTo($sel)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="names"></select>
<div id="code"></div>
Note that I added the foo property to the object to show you how to access properties of the object outside of those placed directly on the option element.
Also note that I simplified the code that generates the option elements as well. If you're going to use jQuery once in your project, you may as well use it everywhere.

Related

Select2 v4 .val() does not maintain order of elements in data object

I have a select2 (v4) select box where people are choosing codes, and the order must be maintained. This works great when they originally add the elements:
However, this is a popup that is used for many different elements on the page. That means I must clear this array and load it with stored data objects on the fly.
My data object preserves the order as var codeArray = ['7990', '268'].
But when I use:
$(element).val(codeArray).trigger("change")
I get the following:
How can I maintain the order on load? Is there a sneaky workaround?
Okay, the fix was pretty hacky, but I'll post what I have:
function rebuildForm(codeArray) {
clearFormContents();
$.each(codeArray, function(j,obj){
var found = false;
code_list.some(function(el){
if (el.value == obj) {
var str = (el.text).split(")");
$("element option[value=" + el.value + "]").remove();
$(element).append(new Option("(" + el.value + ")" + str[1] , obj));
found = true;
}
})
if (!found) {
$(element).append(new Option("(" + obj + ") Custom Tag" , obj));
}
$(element).val(codeArray).trigger("change");
}
Sorry if the above code doesn't work perfectly, I had to clean it up to remove some fluff and hide the client/project identity.
Basically, on the rebuild of the form, I clear the old form contents then loop through the array grabbing each value/object. Then, if the value exists in the original code list of options in the select2 element I delete the option and rebuild it. This appends it to the bottom of the element list so that the order is maintained in the box. I also add any free form text tags using the 'found' boolean.
Once the new list of options are created in the "correct" order, then I am able to add the values back into the select input DOM element and trigger the select2 change to build the tags.
This thread posted by #RohitS in the comments showed the concept: https://github.com/select2/select2/issues/3106
I just adapted it to my needs.

How do I retrieve the actual string selector

Given a select tag with options:
<div id='mydiv'>0</div>
<select id="mysel">
<option id="opt1">a</option>
<option id="opt2">b</option>
</select>...
How do I retrieve the actual string selection? Ie. How do I retrieve the actual "select#mysel" from the var mysel?
example of how this might be used?
var mysel = $("select#mysel");
var myopt = $(mysel.actualstringselection + " option");
var myoptcount = myopt.length;
alert("my option count:" + myoptcount );
$("#mydiv").html(myoptcount);
Answer for updated question:
How do I retrieve the actual "select#mysel" from the var mysel?
example of how this might be used?
var mysel = $("select#mysel");
var myopt = $(mysel.actualstringselection + " option");
So basically, you want the original selector string that you passed into $() in order to get mysel.
You can't get that. jQuery never offered an official way to do it. For a long time, there was an undocumented property on jQuery instances that contained it (mostly, most of the time), but it was always undocumented because it wasn't entirely reliable, and it doesn't even exist in current versions.
So instead, you can do it yourself:
var selector = "select#mysel";
var mysel = $(selector).data("selector", selector);
// Presumably somewhere else where you no longer have the `selector` variable:
var myopt = $(mysel.data("selector") + " option");
But, you wouldn't want to use that for the above. (You'd use find, as described originally [below]). The only reason I can think of for such a thing is if you've changed the DOM and want to repeat the original query. E.g.:
mysel = $(mysel.data("selector")); // Goes looking for the elements again
Original answer:
If after this line:
var mysel = $("select#mysel");
...you're trying to use mysel to find something within the descendant elements of any DOM elements in that jQuery object, you use find:
var optionElements = mysel.find("option");

Why do you have to re-select a JQuery element from a collection?

I have a number of check-boxes on my page, each has a name attribute for its useful value.
I want to get a list of values for the checked items only. I can get a collection of elements like so...
var checkedItems = $(".checkbox:checked");
Now I want to create the list (string) so I create a loop...
var list = "";
for (var i = 0; i < checkedItems.length; i++) {
list += $(checkedItems[i]).attr("name") + "\n";
}
This works and gives me my list. But the question is, why do I have to apply the JQuery object thingy i.e. $(...) to use the attr property?
if I had the following instead it would not work...
list += checkedItems[i].attr("name") + "\n";
But surely the array should be a collection of JQuery elements already? Why re-cast?
Here is a JSFiddle of the working example if anybody wants to try it
EDIT: Why does this work...
var item = $("#item");
var name = item.attr("name");
checkedItems[i] is a raw DOM element, not a jQuery object.
To get a jQuery object for a given element in the set, call checkedItems.eq(i).
You can do this more nicely by writing
var list = $(".checkbox:checked")
.map(function() { return this.name; })
.get()
.join('\n');
The code in your question is wrong, because
$(checkedItems[i].attr("name"))
should really be
$(checkedItems[i]).attr("name")
Besides that, you should really do it like this
var list = "";
checkedItems.each(function(){ list += this.name + '\n'; });
Demo at http://jsfiddle.net/dGeNR/2/
The reason it would not work, is that when you access the elements in the jQuery object with [] you get back a direct reference to the DOM element, and not another jQuery object.
I presume that what you actually do is this:
list += $(checkedItems[i]).attr("name") + "\n";
checkedItems is a jQuery selection. It contains references to the elements that it contains. These elements can be manipulated by jQuery methods, or accessed directly with checkedItems[n], where n is a 0-based index.
Those properties are not jQuery selections: they are the native DOM elements. If you want to use a jQuery method like attr, you need to create a new jQuery object, wrapping that native object.
In this case, you can avoid that by using the eq method, which gets a jQuery selection from an original selection by using a numeric key:
list += checkedItems.eq(i).attr('name') + "\n";
Even better in your case would be to use a combination of map and get and Array.prototype.join:
var list = checkedItems.map(function() {
return this.name;
}).get().join('\n');
Well the list-building code in your question doesn't work; it should be:
for (var i = 0; i < checkedItems.length; i++)
list += $(checkedItems[i]).attr("name") + "\n"; // or just checkedItems[i].name
The ".attr()" function is just defined to return the attribute value for the first element in the list of matched elements. It could have been designed to return an array (like the ".pluck()" function in the Prototype library), but it just doesn't work that way.
The ".css()" jQuery method is similar in that regard, as is ".val()".
Another way to do what you want is:
var list = checkedItems.map(function() {
return this.name;
}).get().join('\n'); // thanks SLaks :-)
To be able to call jQuery functions, you need to wrap the content in $() or jQuery().
I have fixed the example at http://jsfiddle.net/dGeNR/1/
You need to use list += $(checkedItems[i]).attr("name") + "\n";

Javascript dropdownlist

How can I get the previous selected index on change event of dropdown list using Javascript.
No, it is not possible, but you can use a variable inside onchange event that tracks the previous selection
Example:
var previousSelected;
function track(d){
if(typeof previousSelected != 'undefined'){
alert("Previous selected value " + previousSelected );
}
previousSelected = d.selectedIndex;
alert("selected value " + d.selectedIndex);
}
Place a meta variable in the ul or ol object that is the index of the last selected item so that when you goto the item again you can just ask for that property again and, presto, you know the index of the last selected item.
A common way of placing a meta variable inside an object is by adding a class to the last item that was selected with javascript and then finding the list item with that class when you want to see which one was selected. I see JQuery users doing this alot (btw you should be using JQuery to help with all of your javascript).
For example, to mark the last item as selected:
$('ul li:last').addClass('selected');
Then to find it again:
$('ul li.selected')
Its actually a pretty easy way of tracking this kind of code.
You could have a javascript global variable which will track this value. So when the change event is trigerred you would have the new value and the old one. Then you would update the global variable with the new value.
Here's an example pseudo code:
var selectedValue = '';
document.getElementById('someId').onchange = function() {
var newValue = this.value;
// TODO: compare with the old value
selectedValue = newValue;
};

Using a html dropdown list to get the correct display text by value

I have some html that creates a dropdown list. The list has text values and text that is displayed to the user. I save some XML based on the “values” the user selects. At some other point in time I need to parse the XML and display the original text but not in the original list. At this point I only have the “value” from the list and not its display text. At first I was going to use a switch statement to get the display text but then had the idea of using the information that is held in the list. Is it possible to use a bit of javascript to use the value I have to look-up the display version on the list? If so, can someone supply a code snippet? I’ve tried different ways but so far drawn a blank. Shown below is a sample of the html that makes up the list.
'<select id="ifmgr_tr_Field">' +
'<option value="DeviceId">Device ID</option>' +
'<option value="DeviceMac">Device MAC</option>' +
'<option value="DeviceType">Device Type</option' +
'</select>';
Let’s say I have a value of “DeviceMac”, what I want from this list is “Device MAC”. Remember that I don’t want to use the list to display the value at this point.
EDIT
I could do this but it feels a bit dirty.
var item = $('#ifmgr_tr_Field')[0] ;
item.value = field; // field would be the value I have, EG “DeviceMac”
var text = item.options[item.selectedIndex].text; // This will give me “Device MAC” which is what I want.
I hope this might help. Well it still has a if condition. But as you said the value in the ListBox does not change. It uses list as a look-up and finds the option where the Text of option is "Device MAC" for example. emm... well i used jQuery cause it have a better loop(each) function than traditional javascript.
$('#ifmgr_tr_Field option').each(function () {
var option = this;
if(option.text == 'Device MAC')
alert(option.text + " Value : " + option.value);
});
I'm not sure EXACTLY what you want to do in the JS function, but you'll need to add the onchange attribute to your select item. It will need to point to your JS function, and pass the value when changed.
'<select onchange="doTheFunction(this.value);" id="ifmgr_tr_Field">' + ...
Then in your JS Code:
function doTheFunction(val){
//val will hold the newly selcted value
if (val=="DeviceId"){
//do something for DeviceId
} else if (val=="DeviceMac"){
//do something for DeviceMac
} else if (val=="DeviceType"){
//do something for DeviceType
}
}

Categories