How to prevent javascript/jquery execution on specific HTML element? - javascript

What is the possibility of the $subject?
Just imagine I have a foo html element
e.g.
<div data-toggle="loader">...</div>
and have a jquery function binded to it by default,
e.g.
$(document).ready(function(){
$('[data-toggle=loader]').loader();
});
So this will change the DOM element to something like,
e.g.
<div data-toggle="loader" class="active" style="height:800px">...</div>
So what I want to do is prevent applying the changes to the foo element, if it has a class name .example. So the catch is, I cannot touch the default execution code. But I can write another function to handle it. That is the problem I'm facing right now. Any possibility of achieving this?

Easiest would be to either change the DOM structure, i.e. so the JS no longer finds the element, or overwrite the jQuery plugin with something innocuous. Do this in a script after the plugin script itself has loaded.
jQuery.fn.loader = jQuery.noop; //$.noop is an empty, pointless function
[EDIT]
In light of the OP's comment, the best bet may be to store a clone of the element then replace the original element with it after the plugin has fired.
var
el = $('.some-element'),
clone = el.clone(1, 1);
//some time passes... plugin is called... does nothing to element
el.replaceWith(clone);

Related

Javascript call function when html inject finished onclick

I've got this situation:
There is a calendar script to pick a date. When the date is picked a function called onclick to make a select box available for time pick. Now its not like its display:none-->display:block, the select being generated by JS. My goal is to customize this select. For that I got a jquery script "custom.select" which just turns the select to spans. The problem is that if I add the call for this script to the onclick right after the calendar call it does not take. I am pretty sure its because at that stage the html for the select is not injected yet. If I call the custom.select function from the firebug console after the select is visible - it works just fine.
So the question is: how do I call it so it will do its magic on select box?
Thanks
Use delegation with .on():
$(function(){
$(document).on('click','.classdynamic',function(){
//do stuff here
});
});
You should delegate event to the closest static container of your target element. This means changing $(document).on('click','.classdynamic',function(){...});
by something like: $('#staticContainer').on('click','.classdynamic',function(){...});
Figuring out when elements are added is not an easy task. I answered a similar question here.
The best way would be to have some control on the script that creates the select, and append your code to it. One way to achieve this is with Aspect Oriented Programming (AOP) - not easy either.
With current browsers, the most straightforward way is to use setTimeout in a loop and poll the page until the element exists.
Ok I got this thanks to Christophe! I used the Selector Listeners script from here: http://www.backalleycoder.com/2012/08/06/css-selector-listeners/
It was even more complicated coz the parent was not present either )). So what I did was that I attached the listener to the onclick just after the calendar call lol. I needed to make another function though to make it work with the script, here is the code:
var doSelect = function(){
jQuery('#timeslots').customSelect();
};
jQuery(document).ready(function(){
jQuery('.td_calendar').on('click','#anchor1',function(){
cal.select(document.forms['frmRequest'].startdate,'anchor1','yyyy-MM-dd');
document.getElementById('slots').addSelectorListener('#timeslots', doSelect);
});
});

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/

How can I dynamically change css for html that is generated by javascript at runtime?

I have some html that is generated programmatically using javascript at runtime.
I want to be able to dynamically change the css properties of this html
e.g.
$(".pointsbox").css("background-color","green");
but it appears to not work as those html elements are not available at the time that the css change is called.
I am pretty sure I have managed to do this before but I've forgotten what the function is called.
Any help much appreciated!
You haven't posted code on how exactly you create your HTML elements, but it can be something as simple as this:
You can create an HTML element by passing HTML into the jQuery function right?
var new_element = $('<div>');
Well, you can treat that like any other jQuery object, and just manipulate its CSS right then and there.
var new_element = $('<div>').css('background-color', 'green');
Heck, you can even chain the create, the css change and the DOM insert in one call.
var new_element = $('<div>')
.css('background-color', 'green')
.appendTo('#container')
;
There are the Mutation events - specifically the DOMNodeInserted event - that you could bind an event handler to. However, as the page I linked states, it's recommended that you don't because it has a serious negative effect on the performance of your page and the cross-browser support isn't particularly good.
An alternative is to simulate your own DOMNodeInserted event using a custom event. Essentially you bind a handler for a custom event (say nodeinserted) on the document, then trigger that event whenever you have code that dynamically modifies the structure of your page. Code might look something like the following:
$(document).on('nodeinserted', function() {
$('.pointsbox').css('background-color', 'green');
});
function modifyPage() {
// code to modify your page here
$(document).trigger('nodeinserted');
}
Note that, with this approach, you'll need to modify all functions that add elements to the page to trigger that nodeinserted custom event.
I use this. It ensures the DOM has loaded.
$(document).ready(function(){
//code here
$(".pointsbox").css("background-color","green");
});

Using JQuery to get string value of an onclick() event

Wondered if there was good way to do this, thought I would post to the SO community...
There is a 3rd party web page that I have no control over how it renders, but they allow me to add JQuery.
Using the JQuery, I am creating a nav menu on the side of the page, it will be a list of links. The onclick event of these links I get from existing onclick events already on the page, but when I do a:
var linkLoc = $('#theLink').attr("onclick");
linkLoc returns:
function onclick(event) {
handleJumpTo("com.webridge.entity.Entity[OID[E471CB74A9857542804C7AC56B1F41FB]]", "smartform");
}
instead of what I would expect:
handleJumpTo("com.webridge.entity.Entity[OID[E471CB74A9857542804C7AC56B1F41FB]]", smartform");
I think JQuery is trying to get the event for binding, but I need the actual Javascript markup since I'm creating the HTML dynamically. I guess I could substring the "function onclick(event) {" out, but seems kind of hacky.
Any ideas of an elegant way I could get the onclick markup?
$("#theLink") would return a jQuery object whereas $("#theLink")[0] would give a DOM object. This is a resson that $("#thelink")[0].getAttributeNode('onclick').value would work.
The type of $('#theLink').attr("onclick") is a function, so you can just use that when you bind events to the links.
var linkLoc = $('#theLink').attr("onclick");
$('a#link1').live('click', linkLoc);
Example: http://jsfiddle.net/BdU6f/
You can also run other code in the click handler too, if you need:
var linkLoc = $('#theLink').attr("onclick");
$('a#link1').live('click', function(e){
// Code...
linkLoc(e);
});
Example: http://jsfiddle.net/BdU6f/1/
The "onfoo" attributes have values that are functions, not strings. The semantics of:
<whatever onclick='code code code'>
are that the browser constructs a function object as if you had code that did this:
document.getElementById('whatever').onclick = new Function("event", "code code code");
Thus you don't really need the raw string, since you've got something better: the function itself, ready to be called. You can then bind it as a handler to other elements via JavaScript code, not HTML (which is really a better way to do things anyway). You're using jQuery, you say, so you can use the jQuery ".bind()" API to bind those functions to whatever elements you need.
You should also be aware that there are other ways of binding event handlers to elements, ways that will leave the "onfoo" attributes completely unset.
If I understand where you're going with this, you should be able to assign the returned onclick function straight through to the onclick of your new nav element...
$('#NewNavElement').click($('#theLink').attr('onclick'));
If you need to add additional code to the handler, you can just bind another click handler.
try this;
$('#theLink').getAttributeNode('onclick').value
Revised as per comment:
$('#theLink').get().getAttributeNode('onclick').value

How to work with dynamically created fields?

I have web layout, which can contains several links on it. Those links are dynamically created, using AJAX functions. And it works ok.
But, I don't know how can I work with those "dynamically created links" (ie. how to call some JS or jQuery function if I click on them). I guess that browser can not recognize them, since there are created after page is loaded.
Is there some function, that can "re-render" my page and elements on it?
Tnx in adv on your help!
You can use the 2 following methods jQuery provides:
The first one, is the .live() method, and the other is the .delegate() method.
The usage of the first one is very simple:
$(document).ready(function() {
$("#dynamicElement").live("click", function() {
//do something
});
}
As you can see, the first argument is the event you want to bind, and the second is a function which handles the event. The way this works is not exactly like a "re-rendering". The common way to do this ( $("#dynamicElement").click(...) or $("#dynamicElement").bind("click", ...) ) works by attaching the event handler of a determinate event to the DOM Element when the DOM has properly loaded ($(document).ready(...) ). Now, obviously, this won't work with dynamically generated elements, because they're not present when the DOM first loads.
The way .live() works is, instead of attaching the vent handler to the DOM Element itself, it attaches it with the document element, taking advantage of the bubbling-up property of JS & DOM (When you click the dynamically generated element and no event handler is attached, it keeps looking to the top until it finds one).
Sounds pretty neat, right? But there's a little technical issue with this method, as I said, it attaches the event handler to the top of the DOM, so when you click the element, your browser has to transverse all over the DOM tree, until it finds the proper event handler. Process which is very inefficient, by the way. And here's where appears the .delegate() method.
Let's assume the following HTML estructure:
<html>
<head>
...
</head>
<body>
<div id="links-container">
<!-- Here's where the dynamically generated content will be -->
</div>
</body>
</html>
So, with the .delegate() method, instead of binding the event handler to the top of the DOM, you just could attach it to a parent DOM Element. A DOM Element you're sure it's going to be somewhere up of the dynamically generated content in the DOM Tree. The closer to them, the better this will work. So, this should do the magic:
$(document).ready(function() {
$("#links-container").delegate("#dynamicElement", "click", function() {
//do something
});
}
This was kind of a long answer, but I like to explain the theory behind it haha.
EDIT: You should correct your markup, it's invalid because: 1) The anchors does not allow the use of a value attribute, and 2) You can't have 2 or more tags with the same ID. Try this:
<a class="removeLineItem" id="delete-1">Delete</a>
<a class="removeLineItem" id="delete-2">Delete</a>
<a class="removeLineItem" id="delete-3">Delete</a>
And to determine which one of the anchors was clicked
$(document).ready(function() {
$("#links-container").delegate(".removeLineItem", "click", function() {
var anchorClicked = $(this).attr("id"),
valueClicked = anchorClicked.split("-")[1];
});
}
With that code, you will have stored in the anchorClicked variable the id of the link clicked, and in the valueClicked the number associated to the anchor.
In your page initialization code, you can set up handlers like this:
$(function() {
$('#myForm input.needsHandler').live('click', function(ev) {
// .. handle the click event
});
});
You just need to be able to identify the input elements by class or something.
How are these links dynamically created? You can use use the correct selector, given that they are using the same class name or resides in the same tag, etc.
consider the html form
<form>
<input type="text" id="id" name="id"/>
<input type="button" id="check" name="check value="check"/>
</form>
jquery script
$('#check).click(function() {
if($('#id).val() == '') {
alert('load the data!!!!);
}
});
here on clicking the button the script check the value of the textbox id to be null. if its null it will return an alert message....
i thin this is the solution you are looking for.....
have a nice day..
Noramlly , the browser process response HTML and add it to DOM tree , but sometimes , current defined events just not work , simply reinitialize the event when u call the ajax request ..
All you need to do to work with dynamically created elements is create identifiers you can locate them with. Try the following code in console of Firebug or the developer tools for Chrome or IE.
$(".everyonelovesstackoverflow").html('<a id="l1" href="http://www.google.com">google</a> <a id="l2" href="http://www.yahoo.com">yahoo</a>');
$("#l1").click(function(){alert("google");});
$("#l2").click(function(){alert("yahoo");});
You should now have two links where the ad normally is that were dynamically created, and than had an onclick handler added to bring up an alert (I didn't block default behaviour, so it will cause you to leave the page.)
jQuery's .live will allow you to automatically add handlers to newly created element.
If your links are coming in via AJAX, you can set the onclick attributes on the server. Just output the links into the AJAX like this:
Holy crap I'm a link
The return false makes sure the link doesn't reload the page.
Hope this helps!

Categories