The relation between .load and .ready - javascript

I'm loading a part of a page into another page using the .load function in jQuery
$("#loadingDockShotPg").load("include/shot_comments.php?id="+get['id']);
In my file that's being loaded into the div with the id "loadingDockShotPg" there are elements in there in which I would like to be effected by my jQuery commands.
The HTML that's being placed into another page using .load
<textarea id='newNoteTextarea' class='width100 hidden' placement='Write a comment...'></textarea>
The jQuery that's placed in the parent file that the HTML above is being placed in
$(document).ready(function(){
$("input[placement], textarea[placement]").each(function(){
var orAttr = $(this).attr("placement");
$(this).val(orAttr);
$(this).focus(function(){
if($(this).val() == orAttr)
{
$(this).val("");
}
});
$(this).blur(function(){
if($(this).val() == "")
{
$(this).val(orAttr);
}
});
});
});
The problem is that my textarea isn't being affected by the jQuery that's supposed to put the placement attribute in the textarea's value. What do I have to do in order to have this work?

Your .load() is a "live function". You are adding content to the DOM after it has been loaded. Your .each() function have already been executed before your content is added with the .load(). To fix this you can run your .each() function when .load() is complete as a callback.
This is how I should have done it:
$(function(){
var inputElements = $("input[placement], textarea[placement]");
function setInputValue() {
var self = $(this),
orAttr = self.attr("placement");
self
.val(orAttr)
.focus(function(){
if(self.val() == orAttr)
{
self.val("");
}
})
.blur(function(){
if(self.val() == "")
{
self.val(orAttr);
}
});
}
inputElements.each(setInputValue);
$("#loadingDockShotPg").load("include/shot_comments.php?id="+get['id'], function(){
inputElements = $("input[placement], textarea[placement]");
inputElements.each(setInputValue);
});
});

You may want to look at using .live(), (which is technically depreciated) or .on() to attach/bind to events on selected elements when using .load()
http://api.jquery.com/live/
http://api.jquery.com/on/

Related

How can I observe changes to my DOM and react to them with jQuery?

I have this function where I toggle a class on click, but also append HTML to an element, still based on that click.
The problem is that now, I'm not listening to any DOM changes at all, so, once I do my first click, yup, my content will be added, but if I click once again - the content gets added again, because as far as this instance of jQuery is aware, the element is not there.
Here's my code:
(function($) {
"use strict";
var closePluginsList = $('#go-back-to-setup-all');
var wrapper = $('.dynamic-container');
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
wrapper.append(markup);
} else {
$('.plugins-container').hide();
}
});
//Below here, there's a lot of code that gets put into the markup variable. It's just generating the HTML I'm adding.
})(jQuery);
Someone suggested using data attributes, but I've no idea how to make them work in this situation.
Any ideas?
You could just do something like adding a flag and check for it before adding your markup.
var flag = 0;
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
if(flag == 0){
wrapper.append(markup);
flag = 1;
}
} else {
$('.plugins-container').hide();
}
});
If you want to add element once only on click then you should make use of .one() and put logic you want to execute once only in that handler.
Example :
$(document).ready(function(){
$("p").one("click", function(){
//this will get execute once only
$(this).animate({fontSize: "+=6px"});
});
$("p").on("click", function(){
//this get execute multiple times
alert('test');
});
});
html
<p>Click any p element to increase its text size. The event will only trigger once for each p element.</p>

jQuery not executing code for new element with new id

I have an image, and when I click on it I want it to change to a different image and change its ID as well. Then when I click on this new image, it reverts back.
$(document).ready(function(){
$("#name_edit").click(function(){
$(this).attr("src", "img/tick.png");
$(this).attr("id","name_confirm");
});
$("#name_confirm").click(function(){
$(this).attr("src", "img/edit.png");
$(this).attr("id","name_edit");
});
});
I have successfully done the first step, going from #name_edit to #name_confirm. However, not the reverse.
How do I go about solving this?
My suspicion is that since I'm using (document).ready, jQuery is preparing itself for elements already on the page. However, the element with the ID name_confirm does not exist until the image is clicked on.
Thanks.
The element that you are working on is always the same...
$(document).ready(function(){
// use just the first id value to find it in the DOM
$("#name_edit").click(function(){
var item = $(this);
var id = item.attr('id');
if(id === 'name_edit') {
return item
.attr("src", "img/tick.png")
.attr("id","name_confirm")
;
}
return item
.attr("src", "img/edit.png")
.attr("id","name_edit")
;
})
;
});
I think you have chosen bad solution for your problem.
1) Why your code doesn't work:
You bind 2 events only 1 time, whne your document loaded. So, jquery finds #name_edit element and bind onclick event on it. But jquery cannot find #name_confirm element, because it doesn't exists on document ready)
In your code you should bind 1 onclick event, but have some attr (for example class for checking your state).
Something like:
<img id="main_image" class="name_edit"/>
<script>
var img_paths = ["img/tick.png", "img/edit.png"]
var img_index = 0;
$("#main_image").click(function(){
if($(this).attr("class") == "name_edit"){
$(this).attr("src", "img/tick.png");
$(this).attr("class","name_confirm");
}
else{
$(this).attr("src", "img/edit.png");
$(this).attr("class","name_edit");
}
});
</script>
Other solutions: You can create 2 images and show/hide them.
Or use styles with background attr. With pseudoclasses or classes.
Also you can store image pathes in array and tick array index on click.
Something like:
var img_paths = ["/content/img1.png", "/content/img2.png"]
var img_index = 0;
$("#main_image").click(function(){
$(this).src = img_paths[img_index];
img_index = !img_index;
})
It is not working because you are referencing the same elements, try this:
(function(window, document, $, undefined){
$("#name_edit").on("click", function(){
var self = $(this);
if(self.attr("id") === "name_edit") {
self.attr("src", "img/tick.png");
self.attr("id", "name_confirm");
} else {
self.attr("src", "img/edit.png");
self.attr("id", "name_edit");
}
});
})(this, this.document, jQuery);
Also for easier to understand code you could use classes like this:
(function(window, document, $, undefined){
$(".name_edit").on("click", function(){
var self = $(this);
if(self.hasClass("name_edit")) {
self.attr("src", "img/tick.png");
self.removeClass("name_edit").addClass("name_confirm");
} else {
self.attr("src", "img/edit.png");
self.removeClass("name_confirm").addClass("name_edit");
}
});
})(this, this.document, jQuery);
To simplify replacing classes you could even add your own $.fn.replaceClass(); like this:
jQuery.fn.replaceClass = function(classA, classB) {
this.removeClass(classA).addClass(classB);
return this;
};
Then use it like this:
(function(window, document, $, undefined){
$(".name_edit").on("click", function(){
var self = $(this);
if(self.hasClass("name_edit")) {
self.attr("src", "img/tick.png");
self.replaceClass("name_edit", "name_confirm");
} else {
self.attr("src", "img/edit.png");
self.replaceClass("name_confirm", "name_edit");
}
});
})(this, this.document, jQuery);
I can confirm what the others said.. the jquery gets run on document ready, but doesn't get updated subsequently - so it basically gets the correct element from the dom, and assigns the click event. It has no event for the name_confirm.
so this code does nothing...
$("#name_confirm").click(function(){
$(this).attr("src", "img/edit.png");
$(this).attr("id","name_edit");
});
See it not work in this instructive jsfiddle
Of course does the id need to change? is it possible to use for example a specific class for the img? then you could make the second click bind on the class instead... for example see this working example, which still changes the src and id...
Try On method:
$(document).on('click', '#name_edit', function(){
$(this).attr("src", "img/tick.png");
$(this).attr("id","name_confirm");
});
$(document).on('click', '#name_confirm', function(){
$(this).attr("src", "img/edit.png");
$(this).attr("id","name_edit");
});

How to edit an event trigged by an anchor from inside of a $.get() function?

I'm trying to make a script that, when you click on an anchor, a $.get function will get the anchor's href and then the href will be removed, but I cannot edit anything about the anchor from inside de get element. Example:
// make anchor disappear for example (doesn't work)
$('.belovedanchor').click(function(e) {
$.get($(this).attr('href')).done(function() {
$(this).hide();
});
});
// make an anchor disappear using a function (doesn't work too)
$('.belovedanchor').click(function(e) {
function do() { $(this).hide(); };
$.get($(this).attr('href')).done(function() {
do();
});
});
I don't understand why $(this) change to work with the $.get function istead of the .click event.
How would you guys do it?
You have a couple problems. Edit: Only one problem -- I now see from your comment below that belovedanchor is not the actual selector in your code.
First, your jQuery selector for the click event handler is most likely incorrect. Change $('belovedanchor') to $('.belovedanchor') or $('#belovedanchor') depending if the anchor is identifiable by either class or element ID respectively.
Second, this in the do callback function does not refer to the anchor. In JavaScript, scope is set at the function level, so anytime you declare a new function, this will refer to that new scope.
Do this instead:
$('belovedanchor').click(function(e) {
var anchor = $(this);
function do() { anchor.hide(); };
$.get($(this).attr('href')).done(function() {
do();
});
});
Simplified:
$('belovedanchor').click(function(e) {
var anchor = $(this);
$.get(anchor.attr('href')).done(function() {
anchor.hide();
});
});
This may work properly
$('.belovedanchor').click(function() {
var selectedancor = $(this);
var myurl = $(this).attr('href');
$.get(myurl, function() {
selectedanchor.hide();
});
});

How to hide a div on document ready, and then call it dynamically from Javascript?

I'm using this code to hide a div container where I'm placing text dynamically.
$(document).ready(function(){
$(".slidingDiv").hide();
$(".show_hide").show();
$('.show_hide').click(function(){
$(".slidingDiv").slideToggle();
});
});
The problem I have is that I want to trigger the show div from a javascript function instead of a predefined click event. I've found this example which mateches the function I want, but I'm not sure how to trigger it from javascript instead of a click function.
JSFiddle Here
just hide the div using css
display:none;
.slidingDiv{
display:none;
}
and show it when ever you want using
.show()
$(".slidingDiv").show();
edit:
after you question edit, you can always trigger the click event programatically like
function yourFunction(){
$(".show_hide").click();
}
At any point in your script you can call the jQuery object with your div's id/class and run the show() function. i.e.
var javascript = "cool";
var foo = "I'm doing stuff";
var bar = "And some more stuff";
if (javascript === "cool")
jQuery(".slidingDiv").show();
else
$(".slidingDiv").show();
<script>
$(document).ready(function(){
$("input[type='file']").on("change", function () {
if(this.files[0].size > 1000000) //file size less than 1MB {
{
$("#fileAlert").show(); //calling a bootstrap 4 alert
}
$(this).val('');
}
});
});
</script>

Jquery Event onChange for Div

I have a page with the following two divs:
<div id="searchResults">
</div>
<div class="postSearchOptions" style="display: none;">
</div>
Is there any way that I can make the "postSearchOptions" div appear when the "searchResults" div is updated by an AJAX call? I don't control the AJAX calls and I want to detect any change in the "searchResults" div.
I tried writing the following JQuery code, but then realized that it requires Jquery 1.4 and I only have 1.3:
$("#searchResults").live("change", function() {
$(".postSearchOptions").css("display", "inline");
});
Is there any way to catch the event of the searchResults div changing using either standard JavaScript or Jquery 1.3? Thanks!
If the AJAX calls are made using jQuery, you could call handle the global ajaxComplete event and run your code there.
I don't think the onchange event will fire if you are programatically changing the innerHTML. Why don't you just show the Post Search options upon receiving those change i.e. why don't you include it as the last line in your ajax success method.
HTH
You could use setInterval to watch it, but as others have said it would be nicer to detect the change in the ajax callback. Here's an sketch of what a plugin would look like to "watch" a node, like you're trying to do with live:
jQuery.fn.watch = function() {
this.each(function() {
var original = $(this).html();
setInterval(function() {
var newHtml = $(this).html();
if (newHtml != original) {
$(this).trigger('change');
original = newHtml;
}
}, 500);
} );
}
to working, do....
jQuery.fn.watch = function() {
this.each(function() {
var obj = $(this);
var original = $(this).html();
setInterval(function() {
var newHtml = $(obj).html();
if (newHtml != original) {
$(obj).trigger('change');
original = newHtml;
}
}, 500);
} );
}

Categories