Appending div from another html file - javascript

I have 2 menu buttons which supposed to append divs from an external html.
Now I have this:
<ul>
<li><a href="#" onclick="javascript:test2();" value="#CS" >CS</a></li>
<li><a href="#" onclick="javascript:test2();" value="#PS" >PS</a></li>
</ul>
And 2 divs on the external html, that just have simple text in them saying "text1" and "text2".
I use this code to append the data:
$.get('external/list.html', function (data) {
$(data).filter('#PS').appendTo('#content')
});
How can I "upgrade" it to take for example an attribute like value, and use it to choose what div to append? Because I prefer to have it as 1 function instead of making 2.
Also this code appends a div, but it doesn't reset it. It just keeps spamming the same div over and over and over. How can I stop it?

Option 1
Keep a single call to your $.get, as you are doing now, but pass reference of your clicked element through your function as below:
<ul>
<li><a href="#" onclick="javascript:test2(this);" value="#CS" >CS</a></li>
<li><a href="#" onclick="javascript:test2(this);" value="#PS" >PS</a></li>
</ul>
JS
function test2(ctrl)
{
var element=$(ctrl).attr('value');
$.get('external/list.html', function (data) {
$(data).filter(element).appendTo('#content');
//element will have value either #PS or #CS
});
}
Note - .appendTo will keep on appending the data to your DOM, instead use .html which replaces contents everytime
Ex:
$(data).filter(element).html('#content');
Option 2
You can also attach click event to your a tags with a common class given for both thus removing inline function call as below:
<ul>
<li>CS</li>
<li>PS</li>
</ul>
JS
$(".menu").on('click',function(){
var element=$(this).attr('value'); //this refers to clicked element
$.get('external/list.html', function (data) {
$(data).filter(element).appendTo('#content');
//element will have value either #PS or #CS
});
});
Update
Ideally html should work but I imposed it in wrong way. You just need to change one thing as below:
$("#content").html($(data).filter(element));

Related

Applying an onclick event to an element that doesn't exist on page load

I have styled a list to look like a select box and I want to fire a function when the user clicks an element in the list however the element is loaded via AJAX and hence isn't there when the page loads and I can't bind an onclick event to it onDomReady.
If I had it as a normal select list I could just tag on an onChange event to the <select> field, but I obviously can't do that in my case.
My HTML:
<div id="main_category_field" class="fields">
<div class="cat_list">
<ul>
<li class=""><a rel="1866" href="#1866">Sports Cards ></a></li>
<li class=""><a rel="1867" href="#1867">Gaming Cards ></a></li>
<li class=""><a rel="1868" href="#1868">Non-Sport Cards ></a></li>
<li class=""><a rel="1869" href="#1869">Supplies & Storage ></a></li>
<li class=""><a rel="1940" href="#1940">Video Games </a></li>
</ul>
</div>
<div class="contentClear"></div>
</div>
How can I run a function whenever the user clicks any of these options? Also would be great if you could also advise how to pass the respective value of the rel back when they click an option.
Using jQuery so options in that would be preferred.
Edit: Meant to say that the main element main_category_field is a static element. The elements inside are loaded via AJAX.
you need to delegate your elements to static parent , if the element is added dynamically using on()
try this
$(document).on('click','li a',function(e){
e.preventDefault();
var rel = this.rel;
//or using attr()
var rel=$(this).attr('rel');
alert(rel);
});
however delegating it to its closest static parent(present at a time of insertion) is better than document itself.. so if you are adding the list inside main_category_field div.. then you can use
$('#main_category_field').on('click','li a',function(e){
//same stuff
The key word is event delegation. If you want to assign event handlers to dynamically added elements for which you know their "future" selectors, you should use the .on() method on an (already existing) parent element of those dynamic elements.
The second parameter to .on() is then the selector of the dynamically added elements
$(document).on('click', '.cat_list li a', function(e) {
alert(this.rel); // show the "rel" attribute of the clicked a element
e.preventDefault(); // to prevent the default action of anchor elements
});
To bind an event handler to an element that does not yet exist on the page use on.
$(document).on("click", "#main_category_field", function(e){
e.preventDefault();
var rel = e.target.rel;
});
JS Fiddle: http://jsfiddle.net/82bAb/
Use .on for listen dynamically created dom elements as follows
$(document).on('click','div.cat_list ul li a',function(){
var rel=$(this).attr('rel');//to get value of rel attribute
alert(rel);
//other operations
});

About jquery append behavior

I have the following code:
$.getJSON('/api/video/',
function (resp) {
$("body").append("<ul/>");
$.each(resp, function (key, value) {
$("ul").append("<li/>").append(
$("<a/>", {
href: value.url,
html: value.title
}));
});
});
It produces:
...
<ul>
<li></li>
How to Connect a Mobile Broadband Antenna to Data Card
<li></li>
40000mW Laser vs. Line of Balloons!!
</ul>
...
As you can see the <a/> are not inside <li/> and my question is why (is there a good reason for the behavior or does it just work that way)? In my world $("ul").append("<li/>").append($("<a/>", ...)) adds the <a/> inside a <li/>. I see it as $("ul").append("<li/>") creates an <li/> inside the unorderd list and that the next append operates on the <li/> item and thus should add the link inside of it. However that is not the case and I wonder if there is a reason for that?
I am very grateful that you have taken time for my question!
The .append() function doesn't update the element(s) referenced by the jQuery object, so when you call the second .append() it's still being called against the <ul> element.
You could restructure it like so:
$('<li/>').append('<a/>', {
href: value.url,
title: value.title
}).appendTo('ul');
$.append() returns the item that was appended to, not the item being appended.

how do you hide a li when click on the hyerplink inside it using jQuery?

I'm trying to hide a li list item when the link inside is clicked i.s
<ul>
<li id="list_1" class="list">hide
</li>
<li id="list_2" class="list">hide</li>
<li id="list_3" class="list">hide</li>
<li id="list_4" class="list">hide</li>
</ul>
<span class="updateNumber">0</span>​
and everytime a li item is hidden, increase the number of updateNumber text by 1. thanks
This should do the trick:
$('li a').on('click', function(e) {
e.preventDefault();
$(this).parent().hide();
});
The selector li a finds all <a> tags inside any <li> (I've kept it simple here so it'll be greedy). We then use $.on() to bind an event handler to the click event.
Now we use an anonymous function (a function without a name) to do our stuff in. Here, we pass e into the function as an argument. e contains the event object so we can do e.preventDefault() on the next line. This line stops the browser doing it's default behaviour on the link, which is to navigate to the URL in the href attribute in the <a> tag.
The line $(this).parent().hide() is the important one. Here, $(this) references the link that was clicked, so doing $(this).parent() we can access the parent node (tag) of the <a> which is an <li> in this case. Adding .hide() to the end of it hides the <li> and you're done.
To update your .updateNumber span, add this code to your click handler function:
var currentNumber = parseInt($('.updateNumber').text());
currentNumber++;
$('.updateNumber').text(currentNumber);
The first line gets an integer from the text within your span and assigns it to a variable called currentNumber. parseInt() will attempt to turn whatever is inside the span into an integer.
The second line currentNumber++; takes the current value we got from the span and increments it by one (the ++) bit.
We then want to replace the text displayed in the span with the new, updated value, so we put the new value back into the span by using $.text() again:
$('.updateNumber').text(currentNumber);
Note that using $.text() without passing it a string to use will retrieve the element's text, whereas supplying $.text() with an argument such as "Hello world, I'm a string" will put that string into the target element.
Here is a working demo proudly produced and sponsored by #Reigel from the comments.

Jquery select all children within children

I'm sure this will be a simple question but I still struggle with DOM selectors in Jquery so here is a model of my html code:
<fieldset class="product-options" id="product-options-wrapper">
<ul class="options-list">
<li><a href>Item1.1</a></li>
<li><a href>Item1.2</a></li>
<li><a href>Item1.3</a></li>
</ul>
...other html items here
<ul class="options-list">
<li><a href>Item2.1</a></li>
<li><a href>Item2.2</a></li>
<li><a href>Item2.3</a></li>
</ul>
</fieldset>
Now how do I select all of the 'li a' items in both lists (or X number of lists) with class name .options-list and bind them with a click function.
Currently I have:
$('fieldset#product-options-wrapper ul.options-list > li a').bind('click', function(e) {
//code here
});
And it only gets the first options-list.
Thanks, greatly appreciated!
EDIT: If i click on a Item2.X list item first, then it will grab that options list. But as soon as I click on the Item1.x list items it disregards the second .options-list
If you are going to bind to each li element, you should bind it to the ul element instead (helps greatly with performance when there are a lot of events).
$('.options-list', '#product-options-wrapper').bind('click', function(e)
{
e.preventDefault();//In case you don't want to go to a different page
var clicked = e.target;//The href that was clicked
/* If you only want this to happen if the a tag was clicked, add the following line
if(clicked.tagName == 'A')*/
//Rest here
});
How about $('.options-list a').bind('click', function(e) { });?
You can use delegate in this case to make it even simpler. Try this
$('#product-options-wrapper ul.options-list').delegate('li > a', 'click', function(e) {
//code here
});
Your method seems sound to me. I created a test fiddle using your HTML (and an extra anchor to prove that it won't get the click added) and your JS (with minor modifications).
http://jsfiddle.net/chrisvenus/esZxH/1/
The selector you had did work but since you said you wanted the a to be a direct child of the li (or at least I read it that way) I slightly tweaked it in my version above. ARe you sure its not just your function is not doing quite what you want while executing or can you confirm that your click function isn't being run at all?

addEventListener gone after appending innerHTML

Okay, so i have the following html added to a site using javascript/greasemonkey.
(just sample)
<ul>
<li><a id='abc'>HEllo</a></li>
<li><a id='xyz'>Hello</a></li>
</ul>
and i've also added a click event listener for the elements.
All works fine up to this point, the click event gets fired when i click the element.
But... i have another function in the script, which upon a certain condition, modifies that html,
ie it appends it, so it looks like:
<ul>
<li><a id='abc'>Hello</a></li>
<li><a id='xyz'>Hello</a></li>
<li><a id='123'>Hello</a></li>
</ul>
but when this is done, it breaks the listeners i added for the first two elements...
nothing happens when i click them.
if i comment out the call to the function which does the appending, it all starts working again!
help please...
Any time you set the innerHTML property you are overwriting any previous HTML that was set there. This includes concatenation assignment, because
element.innerHTML += '<b>Hello</b>';
is the same as writing
element.innerHTML = element.innerHTML + '<b>Hello</b>';
This means all handlers not attached via HTML attributes will be "detached", since the elements they were attached to no longer exist, and a new set of elements has taken their place. To keep all your previous event handlers, you have to append elements without overwriting any previous HTML. The best way to do this is to use DOM creation functions such as createElement and appendChild:
var menu = pmgroot.getElementsByTagName("ul")[0];
var aEl = document.createElement("a");
aEl.innerHTML = "Hello";
aEl.id "123";
menu.appendChild(aEl);
As an variant, you can add such html, which will work without addEventListener:
<ul>
<li><a id='abc' onclick='myFunc()'>Hello</a></li>
<li><a id='xyz' onclick='myFunc()'>Hello</a></li>
// The following add dynamically
<li><a id='123' onclick='myFunc()'>Hello</a></li>
</ul>
U can also use jQuery's 'live' function

Categories