finding value in nested jquery array - javascript

I cant get that to work:
My json
[{"myicons":[{"icon":[{"rel":"1","id":"icon1","class":"bookmark desktop-icon ui-draggable","title":"bookmark1"}]},{"icon":[{"rel":"2","id":"icon2","class":"bookmark desktop-icon ui-draggable","title":"bookmark2"}]}]}]
My jquery each function finds the 2 icons but i cant seem to get the values... it keeps saying undefined.
var myicons = data[0].myicons;
$.each(myicons, function() {
var iconid = this.id;
alert(iconid);
});

Your JSON is full of array. i,e. data, myicons and even icon
$.each(data, function () {
var myicons = this.myicons;
$.each(myicons, function () {
var iconid = this.icon[0].id;
alert(iconid);
});
});
DEMO
I strongly suggest you to simplify yous JSON object

Related

JavaScript console.dir and runtime

I'm trying to use an object for javascript to hold my main elements etc. And my object will grab contents from the HTML elements. And I'm trying to use console.dir to see if my data is grabbed correctly.
The issue is, console.dir shows all values at once instead adding each element one by one. I'm using jQuery's each function.
Here is the fiddle ;
https://jsfiddle.net/365dzdhh/9/
Here is the code ;
(function(jQuery) {
'use strict';
window.DOER = {
saver:function(e){
e.preventDefault();
var sel = jQuery('.sel');
var data = {};
sel.find('.sell-me').each(function(){
//Shouldn't this show values one by one instead of all in one at once?
console.dir(data);
data = window.DOER.grabber(jQuery(this), data);
});
console.dir(data);
},
grabber:function(el,data){
data[jQuery(el).attr('id')] = jQuery(el).val();
return data;
},
init:function(){
jQuery(document).on('click', '.save-it', this.saver);
}
};
}($));
$(document).ready(function(){
window.DOER.init();
});
If you check the console, you'll see the log in the line "15" shows every details each time. Shouldn't it add each value by looping one by one? Am I missing something here?
I think this will give you the console info you want. console.dir(this) on line 15.
(function(jQuery) {
'use strict';
window.DOER = {
saver:function(e){
e.preventDefault();
var sel = jQuery('.sel');
var data = {};
sel.find('.sell-me').each(function(dataForEach){
//Shouldn't this show values one by one instead of all in one at once?
console.dir(this);
data = window.DOER.grabber(jQuery(this), data);
});
console.dir(data);
},
grabber:function(el,data){
data[jQuery(el).attr('id')] = jQuery(el).val();
return data;
},
init:function(){
jQuery(document).on('click', '.save-it', this.saver);
}
};
}($));
$(document).ready(function(){
window.DOER.init();
});

Javascript return variables from each function

Looping through children elements using each.
var divHeights = [];
$('#parent').children('div').each(function () {
divHeights.push(this.clientHeight);
});
alert(divHeights); // fails
How can I return the divHeights variable?
I've tried
var hts = ('#parent').children('div').each(function () { ...
but obviously that won't work.
You can do this in better way using .map() like:-
var divHeights = $('#parent').children('div').map(function () {
return this.clientHeight || 0;
}).get();
DEMO FIDDLE
The divHeights variable is available all the time. You can just assign it to a variable whenever you want:
var hts = divHeights;
This will just be another reference to the array, so you can do that any time after the array is created, even before you have put any values into it:
var divHeights = [];
var hts = divHeights;
$('#parent').children('div').each(function () {
divHeights.push(this.clientHeight);
});
You can of couse just use the variable divHeights instead of the variable hts when you want to use the result, or just use the variable hts instead of divHeights from start.
You could make it into a function like this:
function getHeights() {
return $('#parent div').map(function() {
return this.clientHeight;
});
}
Then you can just call the function wherever you like to get the array contents.

Adding the results of a function to an array

I have numerous input boxes that I'm trying to store the names of into an array. I'm using this currently to get the names:
var getImplementedNames = function (selector){
$(selector).each(function() {
console.log($( this ).attr('name').replace('imp-', ''));
});
}
console.log(getImplementedNames('[id^=imp]'));
This works, but now I'd like to add all the reslts to an array. I've tried;
var array = [getImplementedNames('[id^=imp]')];
console.log(array);
Which returns an undefined array.
I'm not sure of how this is supposed to be properly handled.
Use .map()
var getImplementedNames = function (selector) {
return $(selector).map(function () {
return $(this).attr('name').replace('imp-', '');
}).get();
}
usage
console.log(getImplementedNames('[id^=imp]'));
Read Return Value from function in JavaScript
Your function isn't currently returning anything. Try:
var getImplementedNames = function (selector){
return $(selector).map(function() {
return $( this ).attr('name').replace('imp-', '');
});
}
console.log(getImplementedNames('[id^=imp]'));

How to clone jQuery element with its data

How can we clone jQuery elements with them data?
Using .data("dummy", "test") I set "test" data to "dummy" key of selected elements. Using .data("dummy") it returns "test". After cloning .data("dummy") returns undefined.
How can I avoid this?
$(".save").on("click", function () {
var dummy = $(this).data("dummy");
if (dummy) {
return alert(dummy);
}
$(this).data("dummy", "I am a button");
var $clone = $(this).clone();
$(this).after($clone);
});
JSFIDDLE
You were just missing 1 parameter...
http://jsfiddle.net/DEKFn/2/
Notice the use of true in the clone(). That determines whether to copy data and events when cloning the element, as per the docs..
http://api.jquery.com/clone/
$(".save").on("click", function () {
var dummy = $(this).data("dummy");
if (dummy) {
return alert(dummy);
}
$(this).data("dummy", "I am a button");
var $clone = $(this).clone(true);
$(this).after($clone);
});
You've also asked how to copy just the data - not the events. This isn't possible, but you can remove all the event handlers like this...
var $clone = $(this).clone(true);
var $clone.off();
clone takes an argument withDataAndEvents so do:
var $clone = $(this).clone(true);
to get only data just turn off the events.
var $clone = $(this).clone(true).off();
Fiddle
The data is attached to the element as a simple javascript object. Simply duplicate the data and assign it to the clone.
$(".save").on("click", function () {
var dummy = $(this).data("dummy");
if (dummy) {
return alert(dummy);
}
var $this = $(this);
$this.data("dummy", "I am a button");
var $clone = $this.clone();
var $data = $.extend(true,{},$this.data());
$clone.data($data);
$(this).after($clone);
});
More on .extend() http://api.jquery.com/jQuery.extend/
Fiddle here
http://jsfiddle.net/9Q7EM/
EDIT:
Not sure why this was downvoted. You incur some overhead copying both the data and the events as the original answer suggested. Both are valid.

Replacing specific items within observable arrays in knockout.js

I am quite new to knockout.js, and I am enjoying learning how to make interfaces with it. But I have a bit of a wall while trying to make my interface more efficient. What I am trying to achieve is remove only the elements selected by $('.document_checkbox').serializeArray(), which contains the revision_id. I will then re-add the entries to the view model with a modified call to self.getDocument(), passing only the modified records which will be re-added. Can anyone help me how to remove the entries from the arrays based on the 'revision_id' values of $('.document_checkbox').serializeArray()
?
function Document(data) {
this.line_id = data.line_id
this.revision_id = ko.observable(data.revision_id);
this.status_id = ko.observable(data.status_id);
}
function DocumentViewModel() {
var self = this;
self.documents = ko.observableArray([]);
self.getDocument = function(){
//Reset arrays
self.documents.removeAll();
//Dynamically build section arrays
$.getJSON("/Documentation/Get-Section", function(allData) {
$.map(allData, function(item) {
var section = { name: item.array_name, display_name: item.display_name, documents: ko.observableArray([])};
self.documents.push(section);
})
//Add document objects to the arrays
$.getJSON("/Documentation/Get-Document", function(allData){
$.map(allData, function(item) {
var section = ko.utils.arrayFirst(self.documents(), function(documentSection) {
return documentSection.name === item.array_name;
});
section.documents.push(new Document(item));
});
});
});
}
self.updateStatusBatch = function(data,event){
$.post('/Documentation/Update-Status-Batch',
{
revision_id : $('.document_checkbox').serializeArray(),
status_id : event.currentTarget.value
}).done(
function(){
//This is where I get confused.
});
}
}
You should modify the /Documentation/Update-Status-Batch in order that it returns the deleted item id. So you will be able to remove it on the client side.
Try this "done" function:
function(removedItemId) {
self.documents.remove(function(doc){
return doc.status_id == removedItemId;
})
}
Take a look at the remove function.
I hope it helps.

Categories