Access Elements After Append - javascript

I need to access DOM elements after JQuery append. Let's say I have this:
<ul id="items">
<li class="item">one</li>
<li class="item">two</li>
</ul>
Then is Javascript:
var addItems = function(html) {
$('#items').append(html);
//How do I access the new items here?
}
Let's say that html is:
<li class="item">three</li>
<li class="item">four</li>
I need to do something to the two new items. This something includes binding events to them. So I cannot simply use $('.item') because that will add double events to the existing items. Once the new items are part of the DOM, there is nothing about them that distinguishes them from the existing items.
What's the best way to do this?

Make a jQuery collection of the html before appending it:
var addItems = function(html) {
var $items = $(html);
$('#items').append($items);
$items.foo();
}

Here's a working example: http://jsfiddle.net/hunter/7UTA2/
var addItems = function(html) {
var $html = $(html);
$('#items').append($html);
$html.text("test");
}
This showcases that you still can manipulate the text (or whatever attribute) of the items since you still have a reference to the collection.

Related

Animating new additions to a generated list with CSS

I have a <ul> of elements like this:
<ul id="task-list">
<li class="task"></li>
<li class="task"></li>
<li class="task"></li>
<li class="task"></li>
</ul>
Every time a .task is changed, added, or removed, I generate the entire <ul> again through a Handlebars template and display it with .html():
function addHTML(allTasks) {
var tasks = compileTemplate(allTasks);
return $('#task-list').html(tasks);
}
function compileTemplate(allTasks) {
var source = $('#task-template').html();
var template = Handlebars.compile(source);
return template({
tasks: allTasks
});
}
The list uses Slip.js for reordering, and new items are added at the top of the list. The height of each item could be anything.
Is it possible to have a CSS animation for new additions where the list "slides down" to pop in the new task, or will I need to change my logic to add each task to an existing list, instead of generating the whole <ul> each time?
You can solve this with some simple jquery functions, although AngularJS would look much cleaner. A little example for adding and removing elements with JSFiddle example.
HTML
<ul id="task-list">
<li class="task"><button class="remove">remove</button>Lorem</li>
<li class="task"><button class="remove">remove</button>Ipsum</li>
<li class="task"><button class="remove">remove</button>Dilor</li>
<li class="task"><button class="remove">remove</button>Test</li>
</ul>
<li class="task" id="hidden-task"><button class="remove">remove</button>Test</li>
<button class="add">add last Child</button>
jQuery
//.remove is class of your remove button, task is the list element
$('.remove', '.task').on('click', function(){
var li = $(this).parent();
li.slideToggle({
'complete':function(){
li.remove()
}
});
})
//use hidden element as dummy
var element = $('#hidden-task');
//cache tasklist
var taskList = $('#task-list');
$('.add').on('click', function(){
//create a deep clone
var clone = element.clone(1,1);
taskList.append(clone);
setTimeout(function(){
clone.slideToggle()
}, 200);
});
var nth = 2;
$('.c2th').on('click', function(){
var clone = element.clone(1,1);
$('li').eq(nth-1).after(clone);
setTimeout(function(){
clone.slideToggle()
}, 200);
});

How to get the items inserted in the DOM using DOMNodeInserted

I want to get the values of items in a Dynamically generated DOM using DOMNodeInserted.
Here is my code.The items #I want to get the values are li eg
<div id="demo">
<ul>
<li class="req">Chemistry</li>
<li class="req">English</li>
<li class="req">Maths</li>
</ul>
</div>
Here is the code
$('#demo').on('DOMNodeInserted', function(e) {
var that = $(this);
if ($(e.target).is('.req')) {
alert(oneoftheitemsintheli);
}
});
I want to get on of the items in the li eg Maths, Chemistry etc. I need to know how to get the items.
Thanks
Given that each li has the class req, you can use each to iterate over them and get the text value - or any other property you need.
$('#demo').on('DOMNodeInserted', function(e) {
$('.req').each(function() {
alert($(this).text());
});
});
Example fiddle

Adding a Space when using addClass and variables using jQuery

I have jQuery read some text then add a class based on the value of this text. (The text read is rendered by my CMS).
The HTML Looks like this:
<ul class="zoneSubscriptions">
<li>
<ul>
<li class="zoneName">Professional</li>
<li>Never</li>
</ul>
</li>
<li>
<ul>
<li class="zoneName">RTTM</li>
<li>Never</li>
</ul>
</li>
</ul>
I want to read the text of class="zoneName"and add a class based on this.
JS to do this:
$(function() {
var zone = $( ".zoneName" ).text();
$( "#zones" ).addClass( zone );
});
This works without issue, however, I need it to add two classes, Professional and RTTM. What it adds is ProfessionalRTTM.
My question is how would I add the classes while keeping a space between the words?
In other words it should render like this: class="Professional RTTM" not class="ProfessionalRTTM"
Note: In my example there are two "zoneName"s. There could be anywhere from 1 to 5 or more when used live.
Try iterating the tags:
var $zones = $("#zones");
$(".zoneName").each(function () {
$zones.addClass( $(this).text() );
});
Also possible (if you want to reuse the list of class names)
var classes = [];
$(".zoneName").each(function () {
classes.push($(this).text());
});
$("#zones").addClass(classes.join(" "));
You're calling .text() on multiple results which is joining them together.
Why not do something like this instead:
var zone = $( ".zoneName" ).each(function(){
$("#zones").addClass($(this).text());
});
Find all your .zoneNames and then call addClass for each one.
jsFiddle example
You need to iterate across the .zoneNames, otherwise your .text() will be a one undivided string (unless you have whitespace in there)
$(".zoneName").each(function() {
$("#zones").addClass($(this).text());
});
You can use the callback function of addClass(), and use map() to get an array of the text, then simply join with a space:
$('#zones').addClass(function() {
return $('.zoneName').map(function() {
return $(this).text();
}).get().join(' ');
});
Here's a fiddle

Javascript Add Div on the fly which ul list link is clicked

I am trying to replace having to create a sub list and instead I want to add the div's via javascript / jquery.
Here is what I have:
<script>
function makepage() {
var myvariable1="myTitle";
var newPage = $("<div>'+myvariable1+'</div");
//appendTo here?
</script>
...
Then the list:
<ul>
<li>
Click Here
</li>
</ul>
The reason code creating it dynamically is that I want to pass some variables to it internally and I don't want to use a form / post etc...
How can I make newPage appear when I click myid link?
Simply make sure you use the quotes you started with and append to body or what element do you want:
<script>
function makepage() {
var myvariable1="myTitle";
var newPage = $("<div>"+myvariable1+"</div>");
$("body").append(newPage);
}
</script>
Instead of making a specific function and using in-line delegations, try the following:
<ul>
<li>
Click Here
</li>
</ul>
$('#myid').click(function() {
var myvariable1 = "myTitle";
var newPage = $("<div>"+myvariable1+"</div>");
$('body').append(newPage);
});​
DEMO

How to get inner HTML of element inside a list item, within a delegate?

I have this bit of HTML :
<li eventId="123">
<img src="image.jpeg"/>
<h3 id="eventName">Event Name</h3>
<p id="eventDescription"></p>
</li>
I want to be able to pull out the <h3> and <p> via jQuery so that I can update their values.
I have a delegate bound to the list items, and on click I'm trying to grab hold of <h3> and <p> using :
function eventIdClicked()
{
// This gets hold of "123" OK
theEvent.id = $(this).get(0).getAttribute('eventId');
// How to get the other 2 inner html?
var existingEventName = $(this).get(1).getAttribute('eventName');
var existingEventDesc = $(this).get(2).getAttribute('eventDescription');
$.mobile.changePage("home.html");
}
Am I able to do this?
Maybe something like $(this).find("h3").text() and $(this).find("p").text()?
Very simple jquery.
Also, while it isn't affecting the code in this case, ID's must be unique.
If the ID's aren't unique the elements might as well not have id's.
First off, in your case you should use classes instead of Id's if there are going to be multiple eventnames and eventdescriptions. As for the event handling try passing the event object into the function like so:
function eventIdClicked(evt){
// Now you get get the event target.
// In your case this is the li element.
var target = $(evt.target);
// Now you can pull out the children that you want.
var eventName = target.children(".eventName").text();
var eventDescription = target.children(".eventDescription").text();
// Do more stuff...
}
First, I take for granted that there are several of these <li> so you shouldn't use the id attribute as id have to be unique. I replaced these with a class name.
<li eventId="123">
<img src="image.jpeg"/>
<h3 class="name">Event Name</h3>
<p class="description"></p>
</li>
I cleaned up your syntax using cleaner jQuery methods. I also add the values to the object your are already referencing.
function eventIdClicked()
{
theEvent.id = $(this).attr('eventId');
theEvent.name = $('.name', this).text();
theEvent.description= $('.description', this).text();
$.mobile.changePage("home.html");
}
If you are using HTML5 this would be cleaner:
Replace <li eventId="123">
with <li data-event="{'id':123,'name':Event Name','description':'Event Description'}">
Replace
theEvent.id = $(this).attr('eventId');
theEvent.name = $('.name', this).text();
theEvent.description= $('.description', this).text();
with theEvent = $(this).data('event');
function eventIdClicked()
{
// This gets hold of "123" OK
theEvent.id = $(this).get(0).getAttribute('eventId');
// since you used an id for both tags, you could even ommit the context
var existingEventName = $("#eventName", this);
var existingEventDesc = $("#eventDescription", this);
existingEventName.text("a new event name");
existingEventDesc.text("a new description");
$.mobile.changePage("home.html");
}
Use children function:
var existingEventName = $(this).children('h3')
var existingEventDesc = $(this).children('p');
Now you can use text to grab or modify values. On the other hand those elements also have ids so you can access them using id selector.
If you want to change the innerHTML of the <h3> and <p>, you could use
$('#eventName').html(/*NEW HTML HERE*/);
$('#eventDescription').html(/*NEW HTML HERE*/);
This is assuming the ids are unique in your document

Categories

Resources