Jquery, Targeting New Elements - javascript

I am quite new to the realm of Javascript and the Jquery Library, so bear with me please.
I am manipulating the DOM by adding new divs within a parent div like so:
var newdiv = document.createElement('div');
var addTst = document.getElementById("tst");
addTst.appendChild(newdiv)
<div id ="tst">
//new divs will appear here
</div>
$("#tst div").draggable(); *//things I need to be draggable*
#tst div{
height:50px;
width:50px;
background:red;
margin:20px;
display:inline-block;
}
However I am attempting to use Jquery UI, to target these new elements and make them draggable. (The new divs are added by the user after the initial document loading, without refreshing the Jquery/page).
Of course Jquery only loads once so anything added after remains undraggable.
I already have some AJAX in there, which is loading data fine, but it is quite long and I dont want to re-run the entire AJAX function just to refresh the parent divs contents (Assuming AJAX can update a div with new contents).
To help illustrate I have added a Fiddle:
http://jsfiddle.net/YuGhj/2/
As you can see, the first red box drags fine, but if you add a new child using the button, they are not draggable.
I am most likely totally misunderstanding how jquery/AJAX works.
TL;DR
To put it shortly, I need a way to target elements added dynamically after the first page load, and apply a drag function to them. I assume I need to refresh the div somehow, without losing any contents.
Thanks!

Manipulating the DOM is much easier with jQuery. Here's code to create a div, append it, and call draggable on it:
$('<div/>').appendTo('#tst').draggable();
Demo: http://jsfiddle.net/MvXR3/
A lot of people seem to misunderstand how selecting and binding work. When you do this:
$("#tst div").draggable();
That finds all elements that match "#tst div" at the time the line executes and calls draggable() on those elements. When you add a new element, you need to call draggable() on the new element. The previous call doesn't apply.

Related

JQuery not working on inserted/inject DOM element

I am still a bit new to JS & JQuery, so please excuse what may be a simple and stupid question.
Background:
I have a div on my page that holds several divs (#idle-variable). On click of the top level div, it basically shows the other divs (#addvariable). Nothing more than display: none; and .show(). Easy. On another action within that div (change of drop down), I essentially want to inject/insert that top level div (#idle-variable) underneath the first instance.
Issue:
Essentially, the .click function is not working on my newly inserted div. This may be because the two div's share the same ID, BUT I have a sneaky suspicion that it's not recognized in the DOM. A friend of mine said something about I have to "re-run" my jquery in order for it to be readable in the DOM.
Question:
How can i make this work properly? I want to be able to add a dynamic number of these idle-variables to the page and I need to make sure my .click function works for all added DIVS.
$(function(){
$('#idle-variable').click(function(event) {
$("#addvariable").show(400);
});
});
//create variable in db & show value entry
$("#variabletype").change(function() {
$("#varholder").css("display", "inline-block");
$.ajax({
type: "POST",
url: "/myphpfile.php",
data: {"variabletype": $("#variabletype").val()},
success: function(){
$( "#idle-variable" ).after("<div id="#idle-variable>content</div>");
}
});
});
Well to make the code work it would need to use on and ids are only supposed to be on one element. If it can be on the page multiple times you need to use classes.
$(document).on("click,'#idle-variable', function(event) {
$("#addvariable").show(400);
});
you should be using classes
$(document).on("click,'.idle-variable', function(event) {
//$("#addvariable").show(400); //not sure how this relates to the clicked element.
$(this).find(".addvariable").show(400); //if it is a child
});
You also have a typo in your code with quotes.
The ID based selector will be applied to the first element only.
See the example here http://jsfiddle.net/9GN2P/2/
If you are looking to bind same event handler to multiple elements, definitely go with the class based approach, instead of ID based approach.
And, you are expecting event handler to work with dynamically created elements as well. If you are using older versions of jquery, use the live method like
$('yourselector').live('click',function(){
});
Since live is deprecated and if you are in a new version, use the 'on' method
$('containerselector').on('click','yourselector',function(){
});
Editing to answer your comment:
To create dynamic element and append to DOM, you can follow the bellow pattern. Here, I will create a DIV with id "newID", class "newClass", content "NEW DIV!!" and a click event handler for it. And it will be pushed into another div with id 'containerID'
$('<div />',{
id:'newID',
'class':'newClass',
text:'NEW DIV!!',
click:function(){alert('hi');}
})
.appendTo('div#containerID');
This is just a demo.

using jQuery to change, only the elements that were loaded via ajax

For each checkbox on the web page, I replace it with a slider that I borrowed from jsfiddle.net/gnQUe/170/
This is done by going through the elements when the document is loaded.
Now the problem is that when more content is loaded via ajax, the new checkboxes are not transformed.
To solve the problem, I used AjaxComplete event to go through all the elements again and replace the checkboxes with sliders.
Now the problem happens that elements that were already replaced, get two sliders. To avoid that I check if the checkbox is hidden and next element is div of class "slider-frame", then don't process the re-process the element.
But I have a lot of other such controls as well, and I am presume I am not the only one that has this problem. Is there another easy way around it?
There exists jQuery live/on( http://api.jquery.com/on/ ) event but it requires an event as an argument? whereas I would like to change the look of my controls when they are rendered.
Another example of the same problem is to extend some controls that are loaded via ajax with jQuerys autocomplete plugin.
Is there a better way to accomplish this other than changing some attributes on the element.
To summarize, on document load I would like to process every element in DOM, but when more elements are loaded via ajax then I want to change only the new elements.
I would assume that when the element's are transformed into a slider, a class is added to them. So just add a not clause.
$(".MySelector").not(".SomeClassThatSliderAddsToElement").slider({});
So in the case of your code do something like this
$('.slider-button').not(".sliderloaded").addClass("sliderloaded").toggle(function(){
$(this).addClass('on').html('YES');
$('#slider').val(true);
},function(){
$(this).removeClass('on').html('NO');
$('#slider').val(false);
});
Since you said you do not want to add anything else, how about you change the toggle function to click.
$(document).on("click", ".slider-button", function(){
var elem = $(this);
elem.toggleClass("on");
var state = elem.hasClass("on");
elem.text(state?"YES":"NO");
elem.parent().next().val(state);
});
Running fiddle: http://jsfiddle.net/d9uFs/

Adding a class to a .click function

new to StackOverflow and relatively new to JavaScript/jQuery. I've been trying to develop a website that contains a vector map (using the Raphael plugin), and when a particular area of the map is clicked, I want it to open a Lightbox using the Colorbox plugin. I have the Raphael and Colorbox plugins working individually (I've got the hover function working for Raphael, and I've got the Colorbox to work when a normal link is clicked). However, I'm not sure how to get the Colorbox to work when it is a Raphael element that is clicked.
This is because I think I need to add the "inline" class to the Raphael element, however my .click function can only get a url (I can't add a class).
Apologies if this question doesn't make much sense, I've been going round in circles for hours now.
Current .click function. locs is an array of the Raphael objects in a separate document. locarr is an array containing these objects for a for-loop. id and url are elements of the Raphael object.
.click(function(){
location.href = locs[locarr[this.id]].url
})
The Colorbox works with a normal link, like below. But I can't figure out a way to add the class to my .click function. I've tried various versions of .addClass and similar with no success.
LINK
I think my problem is because the Raphael objects do not exist in the HTML (the url is taken straight from the JavaScript document.
Sorry again if this doesn't make sense. Thanks.
Not going to pretend to try and understand full well what you want, so I am going off the current title. If thats the case and you want to add a class to an element for styling purposes of one sort or another and you want it to do this when the link is clicked on you can try..
$('.inline').click(function(e)
{
e.preventDefault();//stops the mouse click from triggering a normal click event
$(this).addClass('className');//adds a defined class from your stylesheet
//$(this).css({"color":"#FF0"});//changes the style properties without a class
});
Since your saying in the comments your JS is generating the link. You can try..
$('body').delegate('click', '.inline', function(e)
{
e.preventDefault();//stops the mouse click from triggering a normal click event
$(this).addClass('className');//adds a defined class from your stylesheet
//$(this).css({"color":"#FF0"});//changes the style properties without a class
});
or you can try
$('.inline').live('click', function(e)
{
e.preventDefault();//stops the mouse click from triggering a normal click event
$(this).addClass('className');//adds a defined class from your stylesheet
//$(this).css({"color":"#FF0"});//changes the style properties without a class
});

basic scripting question... dynamically modify div content?

I'm wondering what might be the simplest approach to dynamically changing the contents of a "caption" div to reflect the info corresponding to a specific thumbnail/link in an image gallery.
To be more specific, if you visit this link-- which shows off the awesome Seadragon zoom script btw-- I would like to have a small caption under the image that changes (text) content when a user clicks the different links above; perhaps pulling text from an alt or title attribute and placing in an empty div?
In my case, I'll be using thumbnails instead of text links, so upon clicking these images the user will both initiate the "switchTo" Seadragon event and fill the empty div with corresponding content.
thanks for any guidance here.
If you have the id of the div, the simplest way would be to use innerHTML:
document.getElementById(id).innerHTML = "text";
This is fine for simpler cases, like replacing all of the text in a div. If you want to do something more complicated, like having other html elements inside the div, this method is not the best choice.
If you want to add an html element to the div tag, then you should avoid innerHTML. If you have, say, a variable img that is an img tag, then use this to add it to the div:
document.getElementById(id).appendChild(img);
If you want to do anything more complicated than this, you should probably consider using a nice framework like jQuery--it might be too much for something like this, but if you plan to do anything else, then a framework would be worth using.
If you want to do this with jQuery, it can be done using some of the following functions:
var div = $("#id");// jQuery uses CSS selectors to get elements.
div.append("New content");// Puts the new content at the end.
div.empty();// Gets rid of everything inside the div.
div.append(element);// You can also append elements.
// For example, you can create and append an image to the div:
var img = $("<img>");
img.attr("src", "images/something.png");
div.append(img);

How do I "refresh" element in DOM?

I've got an empty DIV element in which I append images by using function createElement("img") and append them with appendChild. So now I've got DIV element full of images.
I would like to use one button to clean this DIV and add new images in it simultaneously.
Thanks for your help
Are you just looking for method replaceChild? Or you could remove all child elements before adding new images:
// assuming yor div is in variable divelement
while (divelement.firstChild)
divelement.removeChild(divelement.firstChild);
what do you mean by clean? If you just want to empty it, you can do
document.getElementById('mydiv').innerHTML = '';
And then add on whatever new images you want.
While both setting innerHTML and calling removeChild() in a loop will clear the contents out of the DIV, the innerHTML method is going to be much faster due to the nature of browsers today.

Categories