Looping through generated HTML with jQuery - javascript

I know if I wanted to bind events to generated HTML, I'd need to use something like .on(), but I've only used it when binding events like .click().
I'm creating a web app that applys a list of colors. Colors are generated from a JSON file. Once fetched, I add it to the page, with certain information contained in attributes. I'd like to do something with the new generated HTML, which is list-elements. But what console.log() is showing me is there is nothing in the parent ul. Even though on the page I see the newly added content.
Here's the entire code based around it.
var setColors = function(){
getColors = function(){
$.getJSON('js/colors.json', function(colors) {
$.each(colors, function(i, colors) {
//console.log(colors);
$('<li>', {
text: colors['color'],
'name' : colors['color'],
'data-hex' : colors['hex'],
'data-var' : colors['var']
}).appendTo('#picker');
})
});
addColors();
}
addColors = function(){
var el = $('#picker').children;
$(el).each(function(){
console.log($(this));
});
}
return getColors();
}
$(function(){
setColors();
});
addColors() is where I'm having trouble with. The error says 'Uncaught TypeError: Cannot read property 'firstChild' of null. How can I work with the newly generated HTML?

You are missing parentheses on the children method:
var el = $('#picker').children();
Also, if you want the addColor method to be executed on the newly generated html, then you must add a call to it after the html is generated, from within the getJSON callback method.

addColors = function(){
var el = $('#picker').children;
$(el).each(function(){
console.log($(this));
});
}
A few issues:
missing end semi-color
missing parentheses on .children()
children() returns a jQuery object, no need for $(el)
Updated:
window.addColors = function(){
var $el = $('#picker').children();
$el.each(function(){
// do stuff here, but could attach each() to above, after children()
});
};

Related

jquery storing dynamic innerhtml into usable jquery variable

var = cooldynamicelement
How could I store the inner html I grab with jQuery from my div ie. <div class="username"> </div> to store as an accessible variable in jQuery eg. cooldynamicelement so I can grab and use at different areas of my site by just calling ie. $cooldynamicelement and updates with the dynamic .username element value.
1. Store HTML into localStorage
var dynamicElementHTML = localstorage.dynamicElementHTML || $(".username").html() || "";
localstorage["dynamicElementHTML"] = dynamicElementHTML;
To make it available to other pages a way would be to use the power of localstorage
https://developer.mozilla.org/en/docs/Web/API/Window/localStorage
If you're actually interested in the whole element (not only it's inner HTML) than instead of .html() use .prop("outerHTML")
2. Binding using jQuery (essential idea)
If you only want a way to reflect some variable HTML as actual html and make it alive you could do like:
var $myElement = $("<div />", {
class : "userData",
append : $someDynamicElements,
appendTo : $someParentElement,
on : {
contentUpdate : function() {
$(this).html( $someDynamicElements );
}
}
});
than whenever your $someDynamicElements changes you can trigger a contentUpdate
$myElement.trigger("contentUpdate")
3. Binding using jQuery (concept)
Here's the same elements binding concept gone wild:
// Here we will store our elements
var EL = {};
// Create desired HTML elements like this:
var LIST = {
username: $("<b/>", {
html : "UNKNOWN",
click : function() {
alert( $(this).text() );
}
}),
email: $("<a/>", {
html : "test#test.test",
href : "mailto:"+ "test#test.test"
}),
// add more here, you got the idea.
// don't forget that you can assign any JS / jQuery propery to your element.
// You can go insane using .on() and later .trigger()
};
// Our small "program" that replaces data-bind elements
// with dynamic elements from our list
$("[data-bind]").replaceWith(function(i){
var bind = this.dataset.bind;
if(!LIST[bind]) return;
if(!EL.hasOwnProperty(bind)) EL[bind] = [];
var klon = LIST[bind].clone(true)[0];
EL[bind].push(klon);
return klon;
});
// That's it. Now goes your code ///////////////
$(EL.username).css({color:"red"}); // just to test if it works :D
$("[data-target]").on("input", function(){
var target = this.dataset.target;
$(EL[target]).html( this.value );
});
// P.S: Even having thousands of elements inside EL
// say you have "EL.tableRows" you can do fabulously
// quick stuff like i.e: sorting, cause you iterate over a plain JS array.
// After the sorting of EL.tableRows is done and you need a jQuery
// representation simply use $(EL.tableRows).
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Dynamic element Binding in jQuery</h2>
Enter some text and see the update trigger in different places<br>
<input data-target="username"><br>
Welcome <span data-bind="username"></span> !!<br>
You name is <span data-bind="username"></span> Click the red text!<br>
<span data-bind="email"></span>
Well if you want to have the jqueryObject in a variable, just do this:
$(function(){
window.$cooldynamicelement = $("div.username");
})
that way you're able to use $cooldynamicelement in a global context. If is that what you want. This way you're saving a reference to your .username element and thus every time you use it will be updated.
NOTE: If you decide to do this, be careful with polluting your global context.:

My javascript script for changing css don't seem to be working

function normToggle(){
document.getElementById('normToggle').onclick = function(){
if(document.getElementById('normToggle').checked){
document.getElementsByTagName('add').style.verticalAlign= 'baseline';
}else{
document.getElementsByTagName('add').style.verticalAlign= 'super';
}
};
document.getElementsByTagName('add').style.verticalAlign= 'super';
document.getElementById('normToggle').checked = false;
}
So I try to use a checkbox to change the style of the 'add' tags. Their vertical align are super first, then i wnat them to change normal, but they didnt respond. Another javascript from the smae file working just fine.
getElementsByTagName returns a HTML Collection - you'll need to iterate through the collection to change the style of each element in the collection
something like this:
function normToggle() {
var setAlign = function (align) {
[].forEach.call(document.getElementsByTagName('add'), function(tag) {
tag.style.verticalAlign = align;
});
}
document.getElementById('normToggle').addEventListener('click', function() {
setAlign(this.checked ? 'baseline' : 'super');
});
setAlign('super');
document.getElementById('normToggle').checked = false;
}
Looking at the code now, you're unlikely to have elements called <add> !!! Is that some sort of mistake in your HTML?

jQuery read data from event

Here I have a problem:
I created one div and passed some data into it:
var div = $("<div />");
$.data(div, "a", 1);
div.on("click", function(event) {
console.log($.data(event.target, "a")); // print undefined
});
It looks like I could not retrieve data bound with an UI element this way. I would like to know why and whether there is any alternative for this - get a piece of data associated with an UI element within an event.
Thanks!
Try this ;-)
var div = $("<div>clic</div>").appendTo('body');
div.data("a", 1);
div.on("click", function() {
console.log($(this).data("a"));
});
JsFiddle : http://jsfiddle.net/t3n8y2xz/

Using jQuery to retrieve IDs of several DIVs and store in an array

I'm currently working on a "template" creation system with html, jQuery and PHP. So the interface is very basic, buttons that currently add divs, these divs are to have content such as buttons, textareas, checkboxes and such.
When I click a button, the div is added; now i also want to store this new div ID into an array with jQuery and at the same time output this array into a separate div with the ID of overview.
My current script looks like this:
function getSteps() {
$("#template").children().each(function(){
var kid = $(this);
//console.log(kid.attr('id'));
$('div.overview').append(kid.attr('id'))
});
}
$('button').on('click', function() {
var btnID = $(this).attr('id');
$('<div></div>', {
text: btnID,
id: btnID,
class: item,
}).appendTo('div.template');
});
$(document).ready(function() {
getSteps();
});
Now, the function getSteps is where I want to retrieve the ID's of all my divs and store them into an array. When I click one of my buttons, I want them to add a div with an ID into my #template div.
I get an error in my console in chrome:
Uncaught ReferenceError: item is not defined
(anonymous function)createtemplate.php:111
f.event.dispatchjquery.min.js:3
f.event.add.h.handle.i
I'm a bit lost and would love a push into the right direction. Thank you.
You could do (to retrieve the ID's of all the divs and store them into an array. )
function getSteps() {
var ids = [];
$("#template").children().each(function(){
ids.push(this.id);
});
return ids;
}
$(document).ready(function() {
var arrayOfIds = getSteps();
});
You get that error because you're trying to use a variable called item that doesn't exist. I guess you want to give a class called item, in which case you should write
class:"item",
Also, you're appending the new divs to a element with class "template", and your getSteps function is searching for an element with id "template".
Think that with your code, the getSteps function executes once, when the DOM is ready. If you want to refresh the list of id's every time you add a div, you should do it inside your code for click event:
function getSteps() {
$('div.overview').empty();
$(".template").children().each(function(){
var kid = $(this);
//console.log(kid.attr('id'));
$('div.overview').append(kid.attr('id'))
});
}
$(document).ready(function() {
$('button').on('click', function() {
var btnID = $(this).attr('id');
$('<div></div>', {
text: btnID,
id: btnID,
class: 'item',
}).appendTo('div.template');
getSteps();
});
});

jQuery create select list options from JSON, not happening as advertised?

How come this doesn't work (operating on an empty select list <select id="requestTypes"></select>
$(function() {
$.getJSON("/RequestX/GetRequestTypes/", showRequestTypes);
}
);
function showRequestTypes(data, textStatus) {
$.each(data,
function() {
var option = new Option(this.RequestTypeName, this.RequestTypeID);
// Use Jquery to get select list element
var dropdownList = $("#requestTypes");
if ($.browser.msie) {
dropdownList.add(option);
}
else {
dropdownList.add(option, null);
}
}
);
}
But this does:
Replace:
var dropdownList = $("#requestTypes");
With plain old javascript:
var dropdownList = document.getElementById("requestTypes");
$("#requestTypes") returns a jQuery object that contains all the selected elements. You are attempting to call the add() method of an individual element, but instead you are calling the add() method of the jQuery object, which does something very different.
In order to access the DOM element itself, you need to treat the jQuery object as an array and get the first item out of it, by using $("#requestTypes")[0].
By default, jQuery selectors return the jQuery object. Add this to get the DOM element returned:
var dropdownList = $("#requestTypes")[0];
For stuff like this, I use texotela's select box plugin with its simple ajaxAddOption function.

Categories