jQuery - Populate dropdown and remove or merge duplicates - javascript

Trying to populate a drowpdown box based on a json object. So data holds items returned from a table, where item_number. The below function works, but if there are duplicate item_number entries, so the options end up like this: 1,2,3,3,3. How do I group the 3 item_numbers ?
//populate #number dropdown
function numbers(data,n) {
$("#number option:not(:first)").remove();
var options = $("#number");
$.each(data, function() {
if(this.item_number != 0)
{
options.append($("<option />").val(this.item_number).text(this.item_number));
}
});
var dropVal = (n != "" ? n : "Issue nr.");
$("#number").val( dropVal );
}
And for bonus points ... how do I order them in ASC order? At the moment, they are mixed up. Can jquery order them?

You can first create an array with non-repeating values and use that array to build options. Or can be in use in other places as well once you filter and create an array of non-repeating values
var myArray = new Array();
$.each(data, function() {
if(this.item_number != 0){
if( $.inArray(this.item_number, myArray) == -1 ){
myArray.push(this.item_number);
}
}

You can create an object with item_number as key and value.
This will remove duplicate.
Now create an array out of this object and sort it.

Related

Add values from one array to object with specified key & index

Im using the following code,
jQuery.each(aDataSel, function(index, oData) {
oPushedObject = {};
aSelectedDataSet.push(fnCreateEnt(aProp, oData, oPushedObject));
});
This is aSelectedDataSet values
and this is the values of OData
What I need is that before I do the push is to fill the listTypeGroup & listTypeGroupDescription (with the red arrow ) with values that Are inside the oData -> ListTypeGroupAssigment -> result (listTypeGroup & listTypeGroupDescription) , The index is relevant since I want to add just the value of the index in each iteration (since this code is called inside outer loop and the index determine the current step of the loop) ,How it can be done nicely?
The result contain 100 entries (always) and the a selected data will have 100 entries at the end...
Update :)
Just to be clear In the pic I show the values which is hardcoded for this run but the values can be any values, we just need to find the match between the both objects values...
I mean to find a match between to_ListTypeGroupAssigment in both object (which in this case exist ) and if in oData there is result bigger then one entry start with the matching ...
UPDATE2 - when I try Dave code the following happen for each entry,
This happen in the Jquery.extend line...any idea how to overcome this?
The following hard-coded of Dave:-) work perfect but I need generic code which doesnt refer to specific field name
jQuery.each(aDataSet, function(index, oData) {
oPushedObject = {};
fnCreatePushedEntry(aProperties, oData, oPushedObject);
var result = oData.to_ListTypeGroupAssignment.results[index];
oPushedObject.to_ListTypeGroupAssignment = {
ListTypeGroup: result.ListTypeGroup,
ListTypeGroupDescription: result.ListTypeGroupDescription
};
aSelectedDataSet.push(oPushedObject);
});
Im stuck :(any idea how to proceed here ?what can be wrong with the extend ?
should I use something else ? Im new to jQuery...:)
I think that this happen(in Dave answer) because the oData[key] is contain the results and not the specified key (the keyValue = to_ListTypeGroupAssignment ) which is correct but we need the value inside the object result per index...
var needValuesForMatch = {
ListTypeGroup: 'undefined',
ListTypeGroupDescription: 'undefined',
}
//Just to show that oPushedObject can contain additional values just for simulation
var temp = {
test: 1
};
//------------------This object to_ListTypeGroupAssigment should be filled (in generic way :) ------
var oPushedObject = {
temp: temp,
to_ListTypeGroupAssignment: needValuesForMatch
};
oPushedObject is one instance in aSelectedDataSet
and after the matching I need to do the follwing:
aSelectedDataSet.push(oPushedObject);
Is this what you're after:
OPTION ONE - DEEP CLONE FROM oData TO aSelectedDataSet
aSelectedDataSet.forEach(function(currentObject,index){
for (var childObject in currentObject) {
if (! currentObject.hasOwnProperty(childObject))
continue;
var objectToClone = oData[childObject]['results'][index];
if(objectToClone)
$.extend(true,currentObject[childObject],objectToClone);
}
});
Here is your data in a fiddle with the function applied: https://jsfiddle.net/hyz0s5fe/
OPTION TWO - DEEP CLONE FROM oData ONLY WHERE PROPERTY EXISTS IN aSelectedDataSet
aSelectedDataSet.forEach(function(currentObject,index){
for (var childObject in currentObject) {
if (! currentObject.hasOwnProperty(childObject))
continue;
if(typeof currentObject[childObject] !== 'object')
continue;
for(var grandChildObject in currentObject[childObject]) {
var objectToClone = oData[childObject]['results'][index][grandChildObject];
if(typeof objectToClone === 'object') {
$.extend(true,currentObject[childObject][grandChildObject],objectToClone);
} else {
currentObject[childObject][grandChildObject] = objectToClone;
}
}
}
Fiddle for option 2: https://jsfiddle.net/4rh6tt25/
If I am understanding you correctly this should just be a small change:
jQuery.each(aDataSel, function(index, oData) {
oPushedObject = {};
fnCreateEnt(aProp, oData, oPushObj);
//get all the properties of oData and clone into matching properties of oPushObj
Object.getOwnPropertyNames(oData).forEach(function(key) {
if (oPushObj.hasOwnProperty(key)) {
//oPushObj has a matching property, start creating destination object
oPushObj[key] = {};
var source = oData[key];
var destination = oPushObj[key];
//can safely assume we are copying an object. iterate through source properties
Object.getOwnPropertyNames(source).forEach(function(sourceKey) {
var sourceItem = source[sourceKey];
//handle property differently for arrays
if (Array.isArray(sourceItem)) {
//just copy the array item from the appropriate index
destination[sourceKey] = sourceItem.slice(index, index + 1);
} else {
//use jQuery to make a full clone of sourceItem
destination[sourceKey] = $.extend(true, {}, sourceItem);
}
});
}
});
aSelectedDataSet.push(oPushedObject);
});
It is unclear what exactly your fnCreateEnt() function returns though. I am assuming it is the populated oPushObj but it's not entirely clear from your question.

Filter a collection by multiple attributes

I'm using underscore's filter method to retrieve the models I need within a collection. Here's my code so far:
search = {'name':'Jordan', 'country':'Brazil'};
var people = this.filter(function(person){
return person.get('name') == search['name']
&& person.get('country') == search['country'];
});
My problem is, I don't know how many key/value pairs I will receive in the search object. A simple solution would be something like this:
search = {'name':'Jordan', 'country':'Brazil'};
var people = this.filter(function(person){
for(var key in search)
{
if(search.hasOwnProperty(key)) return person.get(key) == search[key];
}
});
But of course it does not work. What can I do?
Edit:
The keys I get in the search object are not necessarily attributes of the models I am filtering. I might receive search = {'name':'Jordan', 'country':'Brazil', 'parentName': 'Steve'};
So one of the filter conditions would be Parents.byID(person.get('parentID')).get('name') == search['parentName'];
Worked it out:
var select = true;
for(var key in search)
{
if(search.hasOwnProperty(key))
{
select = (person.get(key) == search[key]) ? true : false ;
}
if(select == false) break;
}
return select;

sort javascript populated select list by alphabetical order

I'm trying to sort my javascript popuplated select list and ive searched through all the other posts on this site but i cant get it to work...
here is my javascript that auto populates the select list from an data in an SQL db:
for (clientKey in clientProjectsHash) {
//alert("client:" + clientKey + ", name: " + clientProjectsHash[clientKey].name);
clientSelect.options[clientSelect.options.length] = new Option(clientProjectsHash[clientKey].name, clientKey);
if(selectedClientId == undefined || selectedClientId == 0) {
if(clientKey > 0) {
selectedClientId=clientKey;
}
}
ive tried to add:
clientProjectsHash.sort(); to the top but it doesn't work... anyone help is appreciated!
this is my other function to get the first client ID from database:
function getInitialClient() {
for (clientKey in clientProjectsHash) {
if(clientKey > 0) {
return clientKey;
}
}
}
Here we go.
You want to sort an object's enumerable keys by their values.
You can use Object.keys to get the enumerable properties of an object.
Then, you can use Array.map to convert each key, to its value in the object.
(That link has a shim for older browsers in both of those)
Then you can call the normal sort function on them.
Example
Let's say your object is something like
var obj = {
"a":"Hello",
"b":"World",
"c":"AAAA",
"d":"ZZZZ",
};
var a = Object.keys(obj).map(function(elem){ // Get the keys, and map them
return obj[elem]; // to their value
}).sort(); // then sort
Here is a working fiddle
Your case:
In your case, this would be something like
var sortedValues = Object.keys(clientProjectsHash).map(function(elem){ // Get the keys, and map them
return clientProjectsHash[elem]; // to their value
}).sort();
Try something like this:
var list = [];
for(key in clientProjectsHash)
list.push(key);
list.sort();
for(var i=0; i<list.length; i++)
{
clientSelect.options[clientSelect.options.length] = new Option(clientProjectsHash[list[i]].name, clientKey);
if(selectedClientId == undefined || selectedClientId == 0) {
if(clientKey > 0) {
selectedClientId=clientKey;
}
}
}

get options' value list of a select in an array or JSON without using loop or jQuery each

I need options' value list in an array or JSON.
I have used following code.
var compArray=[];
jQuery("#myCombo option").each(function(){
compArray.push(jQuery(this).val());
});
But i dont want to iterate the options in a loop because my options list can grow.
I have used as
JSON.stringify(document.getElementById("myCombo").options)
But on stringify it shows empty JSON objects, though I can get value from
document.getElementById("myCombo").options[0].value
I have to pass these value in request parameter to server and I do not want to go through the looping.
Please suggest the optimized solution.
You can use custom serializer like this:
var options = Array.prototype.slice.call(document.getElementById("sel").options),
str = JSON.stringify(options, function(key, value){
if(key === ""){
return value;
}
if(!isNaN(parseInt(key))) {
return value.value;
}
};
http://jsfiddle.net/Vh9qD/
Or use iteration without creating jQuery instance for every option
var options = Array.prototype.slice.call(document.getElementById("sel").options),
str = JSON.stringify(options.map(function(item){return item.value;}));
Check this perf test: http://jsperf.com/get-options
But i dont want to iterate the options in a loop because my options list can grow.
This does not have anything to do with the combo.
Whenever you add/delete a option to the combo, just call a function, which will subsequently add/delete that option from your array.
function addDeleteListInArray( oVal, addDelete ) {
if( addDelete ) {
// add to array
compArray.push( oVal );
} else {
// delete from array
for( var i=0; i< compArray.length; i++ ) {
if( compArray[ i ] == oVal ) {
compArray.splice( i, 1 );
break;
}
}
}
}
Hope this helps.

jQuery $.inArray() always return -1 with an array of object

I have an array of object, that contain key value pair of columnNames.
when i check if a particular columnName exists it alwayz returns -1
Here is an sample http://jsfiddle.net/trLkt/6/, Help will b appriciated
You're searching for string values in the columnModel array, but you're storing objects in it (columnModel.push({'colName': $(this).text()});). $.inArray() cannot decide by itself to compare against the colName property of each array element, it simply compares the value you're searching for against each array element.
Two things you can do:
Add strings to the array instead of objects using .push (as suggested by #lanzz), then $.inArray will work as you expect.
Alternatively, if you do need to store objects within the array (if for example you need to have multiple properties within each object) you would need to iterate over each object and see if the colName already exists:
var colExists = false;
var text = $(this).text();
$.each(columnModel, function(k, v) {
if(text == v['colName']) {
colExists = true;
}
});
Then change your check from if(colExists === -1) to if(!colExists).
Example
$(function () {
$('#ddlMain').change(function (event) {
$('option:selected', $(this)).each(function () {
var colExists = false;
var text = $(this).text();
$.each(columnModel, function(k, v) {
if(text == v['colName']) {
colExists = true;
}
});
if(!colExists) {
columnModel.push({'colName': $(this).text()});
alert($(this).text() + ' added to columnModel');
}
});
});
});

Categories