Filter a collection by multiple attributes - javascript

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;

Related

jQuery - Populate dropdown and remove or merge duplicates

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.

Remove an object from an from an array by it's id (angular)

I'm trying to remove an object from an array by it's key/value of ID. I would normally just splice by index, however the index might be changing quite a bit because multiple users will be manipulating and updating the object so I want to hook onto something more concrete - aka the id. So I have a bit of logic to check if it still exists and if so remove it by it's ID. However I can't seem to get the syntax quite correct. I Am using underscore.js, I don't know if it's easier with/without it but it's worth mentioning.
Here's what I have -
$scope.toggleSelection = function(typeId,name,index){
//check if exists in array
check = $scope.multipleTypes.some( function( el ) {
return el.name === name;
});
//checked on/off actions
if($scope.items[index].checked == false || $scope.items[index].checked == undefined ){
//IS cecked
if(check){
//already exists, do nothing
}else{
$scope.multipleTypes.push({id:typeId, name:name, checked: true});
}
}else{
//IS not checked
if(check){
var list = _.filter($scope.multipleTypes, function(element){
return element.id != typeId;
}
$scope.multipleTypes = list;
}else{
//is not there, do nothing
}
}
};
So if it does exist and is checked off, it gets pushed. If it does exist and is unchecked, I want to remove it from $scope.multipleTypes by it's ID. I think I Am doing this wrong, all I want to do is remove that one object that has the matching ID from $scope.multipleTypes. Would appreciate any help. Thanks for reading!
If you can use UnderScore Js, You can do it very easily.
Here is an Example:
var someArray= [{Employee:'ved',id:20},
{Employee:"ved",age:25},
{Employee:"p",age:2}];
var a = _.findWhere(someArray,{id:25});//searching Element in Array
var b= _.indexOf(someArray,a);// getting index.
someArray.splice(b,1);// removing.
I normally find the object by id, then splice it out. Note that angularjs adds other properties to the object .
e.g
$scope.items = [......]
var findItemByID = function(id, items){
angular.forEach(items, function(item){
if(item.id === id){
return item;
}
})
return null;
}
var removeItemByID = function(id, items){
var item = findItemByID(id);
if(item){
items.splice(items.indexOf(item), 1);
}
}
//you can now do removeItemByID(id, $scope.items);
//I have not tested this code and it may have syntax errors. hope you get the idea.
Josh

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 deserialize form

I am using jQuery Serialize to serialize my form elements and would like to deserialize them back. Unfortunately can't find any working jQuery deserializer, any suggestions?
I wrote a version of jQuery.deserialize that supports serialized data generated from the serialize, serializeArray and serializeObject functions. It also supports all form element types, including checkboxes and radio buttons.
Try this:
function deparam(query) {
var pairs, i, keyValuePair, key, value, map = {};
// remove leading question mark if its there
if (query.slice(0, 1) === '?') {
query = query.slice(1);
}
if (query !== '') {
pairs = query.split('&');
for (i = 0; i < pairs.length; i += 1) {
keyValuePair = pairs[i].split('=');
key = decodeURIComponent(keyValuePair[0]);
value = (keyValuePair.length > 1) ? decodeURIComponent(keyValuePair[1]) : undefined;
map[key] = value;
}
}
return map;
}
I was very interested in trying JQuery.deserialize, but it didn't seem to handle checkboxes at all, so it didn't serve my purposes. So I wrote my own. It turned out to be easier than I thought, because the jQuery val() function does most of the work:
jQuery.fn.deserialize = function (data) {
var f = this,
map = {},
find = function (selector) { return f.is("form") ? f.find(selector) : f.filter(selector); };
//Get map of values
jQuery.each(data.split("&"), function () {
var nv = this.split("="),
n = decodeURIComponent(nv[0]),
v = nv.length > 1 ? decodeURIComponent(nv[1]) : null;
if (!(n in map)) {
map[n] = [];
}
map[n].push(v);
})
//Set values for all form elements in the data
jQuery.each(map, function (n, v) {
find("[name='" + n + "']").val(v);
})
//Clear all form elements not in form data
find("input:text,select,textarea").each(function () {
if (!(jQuery(this).attr("name") in map)) {
jQuery(this).val("");
}
})
find("input:checkbox:checked,input:radio:checked").each(function () {
if (!(jQuery(this).attr("name") in map)) {
this.checked = false;
}
})
return this;
};
You should be able to use this like this:
$("#myform").deserialize(data);
Where data is a parameter list such as what $("#myform").serialize() would produce.
It affects all fields in the form, and it will clear the values of fields that are not contained in the data. But you can also pass any selector to affect only specific fields, as you can with the serialize function. E.g.:
$("select").deserialize(data);
Half of jQuery Serialize is param(), so half of something that deserializes a query string is going to be a deparam. Unfortunately I haven't been able to find a good standalone deparam. For now I recommend getting the jQuery BBQ library and using that. If you don't need the other stuff you can remove them. I read somewhere that Ben Alman (cowboy) planned to extract deparam into its own module.
For the rest of deserializing, you'll just need to loop through the object that deparam returns and for each key and value pair in the object, select the form element based on the key, and set the form elements value to the value.
Bit late on this one, but somebody might find this useful.
function fetchInput(identifier) {
var form_data = identifier.serialize().split('&');
var input = {};
$.each(form_data, function(key, value) {
var data = value.split('=');
input[data[0]] = decodeURIComponent(data[1]);
});
return input;
}
I'm not now answering your question but my guess is that you want to serialize it and send back to server and then use the serialized data which is why you have to deserialize it?
If that's the case you should consider using .serializeArray(). You can send it as POST data in ajax, and then access later as well because you will have object.
May be a bit late, but perhaps you are looking for something like JQuery.deserialize. Problems: no support for checkboxes or radio buttons.
Using Jack Allan's deparam function with jQuery, you can change this line:
map[key] = value;
to
$('input[name=' + key + ']').val(value);
Which will load the data back into your form fields.
this code returns an array when same key is spotted multiple times in the serialized string
chaine="single=Single1&multiple=Multiple&multiple=Multiple1&multiple=Multiple2&multiple=Multiple3&check=check2&radio=radio1"
function deserialize(txt){
myjson={}
tabparams=chaine.split('&')
var i=-1;
while (tabparams[++i]){
tabitems=tabparams[i].split('=')
if( myjson[decodeURIComponent(tabitems[0])] !== undefined ){
if( myjson[decodeURIComponent(tabitems[0])] instanceof Array ){
myjson[decodeURIComponent(tabitems[0])].push(decodeURIComponent(tabitems[1]))
}
else{
myjson[decodeURIComponent(tabitems[0])]= [myjson[decodeURIComponent(tabitems[0])],decodeURIComponent(tabitems[1])]
}
}
else{
myjson[decodeURIComponent(tabitems[0])]=decodeURIComponent(tabitems[1]);
}
}
return myjson;
}
Needed all in a single string, which can be stored in maybe COOKIE, and later read and fill the same form with input values.
Input elements seperator: ~ (use any seperator)
Input attributes seperator: | (use any seperator)
input type | input name | input value ~ input2 type | input2 name | input2 value
var formData = '';
$('#form_id').find('input, textarea, select').each(function(i, field) {
formData += field.type+'|'+field.name+'|'+field.value+'~';
});
Example:
hidden|vote_id|10~radio|option_id|~radio|option_id|427~radio|option_id|428~
If what you want is to remove the standard URL-encoded notation, you can use JavaScript's decodeURIComponent(), which will give you a regular string, just like this:
var decodedString = decodeURIComponent("Http%3A%2F%2FHello%3AWorld");
alert(decodedString);
In this case, decodedString will look like Http://Hello:World, here's a working fiddle.
Got all of this searching for this same issue, and found the answer here: How can I decode a URL with jQuery?
I know this is an old question, but doing some searches for jQuery deserialize got me here, so I might as well try to give a different approach on the issue for people with the same problem.

Categories