Hi I have a script which parses a local JSON object (at the moment just to display a list).
function generateFamilySelect() {
var implantData = JSON.parse(localStorage.getItem("implantData"));
var implantFamilies = "";
$.each(implantData.implantFamilies, function( index, value ) {
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
});
$("#holderForFamilySelect").html(implantFamilies);
}
and the JSON object:
{"implantFamilies":[
{"id":"1","familySelector":"aa","familyDisplay":"One","loadInitially":"1"},
{"id":"2","familySelector":"bb","familyDisplay":"Two","loadInitially":"1"},
{"id":"3","familySelector":"cc","familyDisplay":"Three","loadInitially":"1"},
{"id":"4","familySelector":"dd","familyDisplay":"Four","loadInitially":"0"},
{"id":"5","familySelector":"ee","familyDisplay":"Five","loadInitially":"0"},
{"id":"6","famiā¦
At the moment, the list shows all of the elements. How can I modify this script to only show those with "loadInitially":"1"?
Also, a quick syntax question, I feel like the line
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
could be written something like
implantFamilies += this[index].familyDisplay + "<br />";
but I can't get that to work...
The easiest is to use the Javascript Array.filter() method
// (or in your case, you get it from localstorage, but here's the data)
var myJson = {"implantFamilies":[
{"id":"1","familySelector":"aa","familyDisplay":"One","loadInitially":"1"},
{"id":"2","familySelector":"bb","familyDisplay":"Two","loadInitially":"1"},
{"id":"3","familySelector":"cc","familyDisplay":"Three","loadInitially":"1"},
{"id":"4","familySelector":"dd","familyDisplay":"Four","loadInitially":"0"},
{"id":"5","familySelector":"ee","familyDisplay":"Five","loadInitially":"0"}] };
//the array of implant families
var implantFamilies = myJson.implantFamilies;
//the filtering function. This is preferable to $.each
function implantFamiliesThatLoadInitially(implantFamily){
return implantFamily.loadInitially === '1';
}
//this is only the ones you want, (filtered by loadInitially property)
var loadInitiallyImplantFamilies = implantFamilies.filter(implantFamiliesThatLoadInitially);
The goal of the second part of your code is to build some html based on the data in the json, stored in teh variable implantFamilies. I will recommend Array.map() as an easier solution, than dealing with this. like before I am breaking this into multiple steps with comments so it is clear what is happening.
//your map function. You can make any html you want, like li's
function toImplantFamilyHtml(family){
return family.familyDisplay + '<br />'
}
//returns a plain string of html
var implantFamilyHtml = loadInitiallyImplantFamilies.map(toImplantFamilyHtml);
//jquery object you can use, or append to the DOM or whatever
var $implantFamilyHtml = $(implantFamilyHtml);
//append to DOM
$("#holderForFamilySelect").html($implantFamilyHtml);
working Fiddle: https://jsfiddle.net/mv850pxo/2/
the_5imian has provided a good answer to your first question, and you have determined the obvious alternate solution, given your current code.
As to your second question (this within jQuery.each()):
Within jQuery.each(), this is the value wrapped as an Object. value is the value of the array element at the current index, not the entire array. In other words, you don't use [index] on value or this within this context to get the current array element. For this code, value and this are the same because value is already an Object.
For what you want, you could just use value (Given that all elements of the array are already Objects, you could use this instead, but using value is a better habit to be in.):
$.each(implantData.implantFamilies, function( index, value ) {
if (value.loadInitially == "1") {
implantFamilies += value.familyDisplay + "<br />";
} else {
//do nothing
}
});
this is the value wrapped as an Object:
The following should show you what the values of value and this are within $.each(array,function(index,value){...});:
var myArray = ['zero','one','two','three','four','five'];
$.each(myArray, function(index,value){
console.log(index + ' value =',value);
console.log(index + ' this =',this); //this is the value wrapped as an Object.
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Well that just seems obvious now.
$.each(implantData.implantFamilies, function( index, value ) {
if (implantData.implantFamilies[index].loadInitially == "1") {
implantFamilies += implantData.implantFamilies[index].familyDisplay + "<br />";
} else {
//do nothing
}
});
How about the second part of my question?
Related
After hours of hit and trial this code has finally worked after looking at various posts for help. But i want someone to help me understand the function(i,dat) , what does this means ? Here is my full code below -
function get_assignedtasks_first_time(){
var jdata=$.getJSON( "http://45.114.246.107/quicktask/webservice/admtask.php?entdt=&entusr=SAURABH&company=&taskno=&status=&priority=&primary=", function( data ) {
db.transaction(function (tx) {
$.each(data, function(i, dat) {
tx.executeSql('INSERT INTO tasks (sno, taskdesc) VALUES("'+data[i]['SNO']+'", "'+data[i]['TASKDESC']+'")');
});
alert("completed");
});
});
}
The function $.each takes in two parameters. The first is the array being iterated over, and the second is a callback function to execute for each element in the array.
For each element in the array, $.each will execute this callback function with two arguments. The first argument (which you defined as i) is the index of the current element, and the second argument (dat) is the actual element you are looking at for each iteration.
For the function you defined, you are extracting the 'SNO' and 'TASKDESC' properties from each of the elements in the array. However, it looks like instead of using the dat parameter, which contains the current entry, you are using the original array (making your code a little bit more complicated to read).
Another way to implement the function might look like this:
function(index, element) {
// put these variables in quotes
var sno = "'" + element.SNO + "'";
var taskdesc = "'" + element.TASKDESC + "'";
// join these strings with commas
var values = [sno, taskdesc].join(',');
tx.executeSql("INSERT INTO TASKS (sno, taskdesk) VALUES(" + values + ")")
alert("inserted " + values);
}
In this case, we didn't need to use index at all since we are using the second parameter (the element being iterated over).
Take a look at my code :
// is_array function
function is_array(input){ return typeof(input)=='object'&&(input instanceof Array); }
// Check if cos_in is an array. If is not, create him
if(!is_array(cos_in))
{
var cos_in = new Array();
}
// Onclick function
function cos(pret,box,configuratie)
{
// Create a value (is different on every click; using different box)
cos_in[box] = box + '|||' + pret + '|||' + configuratie + '||||';
// Insert values from array in some div with #cos id
$("#cos").html(cos_in.join('||||'));
}
My problem is that the div with id #cos has from start value "test-empty", and for each time onclick function is executed, the div should have value from function. But is returns an empty div.
Some help please?
Although this code can be improved a lot I tried to fix your first immediate problem here.
Do you want to append the result every time you click? Where is the join for?
Are you trying to join the keys or the values? I assume for now you want the value and not the key.
window.cos_in = window.cos_in && window.cos_in instanceof Array ? window.cos_in : []
// Onclick function
function cos(pret,box,configuratie)
{
// Create a value (is different on every click; using different box)
cos_in.push(box + '|||' + pret + '|||' + configuratie + '||||');
// Insert values from array in some div with #cos id
$("#cos").html(cos_in.join('||||'));
}
Let me iterate a bit to get to something readable/understandable.
Here is a cleaner example of what you're doing. To improve it more I need to know where you're going with your links and parameters.
var cos = (function (cos_in) {
return function cos(pret, box, configuratie) {
// Create a value (is different on every click; using different box)
cos_in.push(box + '|||' + pret + '|||' + configuratie + '||||');
// Insert values from array in some div with #cos id
$("#cos").text(cos_in.join('||||'));
};
}([]));
Here is an example of an object version instead of an array...
var cos = (function (cos_in) {
return function cos(pret, box, configuratie) {
// Create a value (is different on every click; using different box)
cos_in[box] = (box + '|||' + pret + '|||' + configuratie + '||||');
// Insert values from array in some div with #cos id
$("#cos").text(Object.keys(cos_in).join('||||'));
};
}({}));
This is a simple wrapper you could use:
function join(input, str) {
if(typeof(input) === 'object') {
if(input instanceof Array) {
return input.join(str);
} else {
var tmp = [];
for(var x in input) {
if(input.hasOwnProperty(x)) {
tmp.push(input[x]);
}
}
return tmp.join(str);
}
}
return input;
}
/* ... */
$("#cos").html( join(cos_in, '||||') );
However, you really need to differ between languages. JavaScript might not work as you expect it, at least in comparison with PHP.
this is my first post in stackoverflow.. I am trying to iterate over an object(my implementation is an associative array) which in turn has some properties. Now I wish to construct another array out of it in order to use it as a localsource in jquery autocomplete widget for seach operations. Now the problem is that i am using for in loop to that according to the documenations available... However the output is always one less than the original object. The itearation involving the last element is not performed at all. Below is the sample object that I am using as input.
SubTeachPair = object{"5CS1":{SubAbbrev:"CA-L",SubCode:"5CS1",SubName:"Computer Architecture",TeacherId:"1",TeacherName:"Ayush Pandey",label:"Computer Architecture",value:"5CS1"},"5CS2":{SubAbbrev:"CA-P",SubCode:"5CS2",SubName:"Computer Engg",TeacherId:"10",TeacherName:"MAyush Pandey",label:"Computer Engg",value:"5CS2"}}
It has this kind of elements and is dynamically generated so the property names are variable. The loop construct that I have written is
var SubSource = [];
console.log(SubTeachPair);
var count = 0;
for(sub in SubTeachPair){
console.log(count);
SubSource[count] = {};
SubSource[count]['label']=SubTeachPair[sub]['label'];
SubSource[count]['value']=SubTeachPair[sub]['value'];
count++;
}
However, the result for the given input is only:
object{{ label: "Computer Architecture", value: "5CS1"}}
Am I missing something here?
edit-- The function that produces the input object is as follows(It is triggered onclick by the next button).
$('#' + $(this).attr("id")).autocomplete({
source : 'search',
minLength : 1,
change : function(event, ui) {
if( typeof ui.item != 'undefined') {
SubTeachPair[$(this).attr("id")] = {};
// console.log(ui.item);
SubTeachPair[$(this).attr("id")]['value'] = $(this).attr("id");
SubTeachPair[$(this).attr("id")]['label'] = $('label[for="' + this.id + '"]').html();
SubTeachPair[$(this).attr("id")]['SubCode'] = $(this).attr("id");
SubTeachPair[$(this).attr("id")]['SubName'] =$('label[for="' + this.id + '"]').html();
SubTeachPair[$(this).attr("id")]['SubAbbrev'] =$('label[for="' + this.id + '"]').attr('id');
SubTeachPair[$(this).attr("id")]['TeacherId'] = ui.item.id;
SubTeachPair[$(this).attr("id")]['TeacherName'] = ui.item.value;
// console.log(SubTeachPair);
//window.SubTeachPair = SubTeachPair;
}
}
});
I think I have found the cause of the error -- the object that is the input is actually the out put of another form that uses jquery autocomplete . Now when I enter something in the input and then click on the suggestion, the suggestion is filled in the text input, however if i do not click outside the input text and directly click the button which triggers my script, I get that error. Otherwise its fine. Is there any way to avoid that?
In your code, the array SubSource and count are not defined, You have to declare:
var SubSource = [];
var count = 0`
before for(sub in SubTeachPair) {...}
See http://jsfiddle.net/abu5C/
Try this:
SubSource[count] = {};
for(sub in SubTeachPair) {
console.log(count);
SubSource[count]['label']=SubTeachPair[sub]['label'];
SubSource[count]['value']=SubTeachPair[sub]['value'];
count++;
}
I wish to iterate over an object's properties and change them all to include "" around the value stored in them.
This object is passed to a REST call and the above format must be enforced. I prefer to handle the addition of "" in a central location, rather when assigning the actual values (the code is very complex and long).
I know that you can iterate through the object's properties easily:
$.each(queryOptions, function(obj){console.log(obj)})
However, can I somehow get reference to the actual property and set it from within the iteration?
Input:
queryOptions.value1 = 1234;
queryOptions.value2 = "testing";
queryOptions.value3 = 555;
Desired output:
queryOptions.value1 = "1234";
queryOptions.value2 = ""testing"";
queryOptions.value3 = "555";
Thanks
I agree with Pointy that this seems an odd requirement. But if it's really a requirement:
Using $.each:
$.each(queryOptions, function(key) {
queryOptions[key] = '"' + queryOptions[key] + '"';
});
Or just using JavaScript without any library stuff:
var key;
for (key in queryOptions) {
if (queryOptions.hasOwnProperty(key)) {
queryOptions[key] = '"' + queryOptions[key] + '"';
}
}
I'm likely missing something with json and javascript.
[{"commentText":"Testing 123","userPosted":"maxfridbe"},
{"commentText":"Testing 23","userPosted":"maxfridbe"}]
Sometimes I get multiple responses which works with this code:
function(data)
{
var sel = this;
jQuery.each(data,
function()
{
sel.append("<li>"+ this.userPosted+ "-" + this.commentText + "</li>");
});
};
Sometimes I only get one response which breaks the above code:
[{"commentText":"another test again welcom","userPosted":"maxfridbe"}]
I know this is because the response is being treated differently than a list.
Looking for the answer to this I get a bit of a runaround. Any solution would be greatly appreciated.
In the second example you provide, it seems to be an array with only one item, if it's like that, it should work, but I think that you're getting only a single object like:
{"commentText":"another test again welcom","userPosted":"maxfridbe"}
If it's a single object $.each iterates over the object properties.
You could check if your data variable is not an array using $.isArray, and if is not, you can wrap it into a single element array, so the $.each function will still work as expected:
//..
if (!jQuery.isArray(data)) data = [data]; // if isn't an array, wrap it
jQuery.each(data, function() {
sel.append("<li>"+ this.userPosted+ "-" + this.commentText + "</li>");
});
//..
I think you should user some optional parameters in your each() function:
function(data)
{
var sel = this;
jQuery.each(data,
function(i, item)
{
sel.append("<li>"+ item.userPosted+ "-" + item.commentText + "</li>");
});
};
using THIS keyword creates confusion in your case
Hope this helps
Playing around with CMS's solution made me realize that data was just a string somehow so:
if (!jQuery.isArray(data)) data = eval(data);
worked because then the data was an object. Not sure why when there are multiple results it does an eval for you.