How to excute Jquery plugin on an object added at runtime - javascript

I have a JQuery plugin that count the character in the textarea .
But if I added the textarea at run time using append("<textarea></textarea>") for example,.
How to execute this plugin on the appended textarea ?
$("textarea").charCount({
allowed: 200,
warning: 30,
counterText: 'Characters left: '
});
adding textarea at runtime ..
$("#btnAddStep").click(function () {
var text = "" +
" <div class='row-fluid'>" +
" <div class='span10'>" +
" <input type='text' class='span12' placeholder='Type something…'>" +
" </div>" +
" <div class='span2'>" +
" <div class='btn-group'>" +
" <button class='btn btn-mini' id='btnAddStep'><i class='icon icon-plus'></i></button>" +
" <button class='btn btn-mini'><i class='icon icon-minus'></i></button>" +
" </div>" +
" </div>" +
" </div>" ;
$("#response>#steps").append(text);
});

Inside your click event handler for the button that you use to add the textarea to the div, add a call to your plugin's method.
As I cannot see the entire code, I am going to assume that the plugin is automatically called at runtime as well, inside a $(document).ready() or something similar. If you add the textarea after this is called you will need to re-run the plugin.
All you will have to do is add the code you posted again to your click event code, but in the interest of efficiency, rather than running the plugin on every text area all over again, I suggest that you add another option to search for textareas with a particular class and then remove that class after the plugin is run on them. This way, you can give all your new text areas this class and after the plugin runs on them it will never look at them again.
Good luck!
EDIT: A friend of mine is looking over my shoulder and suggested that I clarify a bit: you will not have to modify your plugin in any way (granted, I cannot see the full code so I cannot be 100% sure of this, but let's just say that I'm 95% sure). What you would do is change the event handler (and also any call made in the document.ready - which, technically, is an event handler) like so:
$("#buttonID").click(function() {
...your code...
$("#placeToAddNewTextArea").append("<textarea class="newTA"></textarea>");
$("textarea.newTA").charCount({ ......... });
$("textarea.newTA").removeClass("newTA");
});
In other words, you can use CSS as flags and create, use, and remove them all outside of the plugin code.

Look into jQuery SuperLive.
According to the authors:
jQuery SuperLive is my favorite new plugin. Allen Mackley and I created this to solve a ton of applicate JS problems. We needed plugins to work no matter when elements existed on the page, AND, if attributes were ever added, the plugins should re-enable.
SuperLive does all this.
THIS DOES NOT WORK IN IE. ie doesn't support mutation events.
Also requires jQuery 1.7
Demo video: http://www.youtube.com/watch?v=mh5mGR2GyLY
Download: http://code.google.com/p/jquery-superlive/downloads/list

Related

JS eventListener click disappearing

I created simple fidlle
var cnt = 1;
function add() {
var root = document.getElementById('root')
root.innerHTML += '<br /><a id= "a_' +cnt + '" href="#">click</a>'
var a = document.getElementById("a_"+cnt)
a.addEventListener('click', function(event) {
alert('click:a_'+cnt)
})
cnt++
}
When Add button is clicked once new link is added and after clicking on this link alert appears.
When more links are added with Add button only the last link works(others does not have click event listener according to devel tools).
Why does only the last link work and how can I make all links working?
Because you are reinserting the anchor tags in the html.
The question is similar to Appending HTML string to the DOM.
You can use
root.insertAdjacentHTML( 'beforeend', '<br /><a id= "a_' +cnt + '" href="#">click</a>');
instead of
root.innerHTML += '<br /><a id= "a_' +cnt + '" href="#">click</a>'
Working fiddle https://jsfiddle.net/0nm4uLvd/
Just to improve answer, here is another reference why event listeners are removed when dom element is removed => If a DOM Element is removed, are its listeners also removed from memory?
thanks to these guys :)
You're modifying the innerHTML of your root element. This will cause the complete 'root' to be destroyed en recreated, so only the new event will work.
See Manipulating innerHTML removes the event handler of a child element?.
You can set a class to your links: class="some-class".
Then you can use jquery to listen to click event on elements of this class.
$(document).on('click', '.some-class', function(event) {
alert('click:'+$(this).attr('id'));
});
Runnable example https://jsfiddle.net/2d99hq1h/1/
Check in the console your variable cnt.
You did not post the whole context where the function add is called, but I have a strong guess that this variable stays always 1.
And write a semicolon after your cnt++
For the possible benefit of anyone who finds this page many years after the initial question was asked:
The culprit that destroys existing event listeners seems to be
.innerHTML +=
so use a different technique.
For example:
HTML Insertion Technique 1 (which inserts the HTML but also inadvertently seems to erase any existing event listeners on other unrelated elements, so is NOT recommended):
document.body.innerHTML += '<div id="something"</div>';
Technique 2 (which works and does not affect existing event listeners):
document.body.insertAdjacentHTML( 'beforeend','<div id="something"</div>');
...or any other way (such as with append and so on).

Webpage not working in IE9 (insertAdjacentHTML)

IE is giving me an error (Error: Invalid target element for this operation.) when trying to execute this code:
var d1 = document.getElementById( name + '-body');
d1.insertAdjacentHTML('beforeend', html );
Without having to put the entire function in here, the point of it is to add some text inputs dynamically when a user clicks a button. I did a bit of searching and found many statements that insertAdjacentHTML doesn't work right within tables, which is what I need it to do.
Is there a workaround for this?
Edit: Here is the html I am trying to insert. If you want I can post the generated html from Chrome also.
"<tr id=\"node-" + counter + "\">
<td>
<textarea onclick=\"Common.removeInstructions(id)\" name=\"on\" id=\"action-" + counter + "\" wrap=\"soft\" cols=\"35\" rows=\"4\" style=\"resize: none; overflow: hidden;\">
Please limit responses to 150 characters. Blank fields will be ignored.
</textarea>
</td>
<td>
<input classname=\"TextInput\" id=\"actionDate-" + counter + "\" newline=\"1\" style=\"width: 100px;\" class=\"TextInput\" assemblers=\"jaba.ui.input.TextInput\" jaba-pagerowindex=\"1\"/>
</td>
</tr>"
IE often doesn't allow you to dynamically add table rows/cells.
Pre-creating the rows/cells which you want added with display:none, then changing their innerHTML and display when needed is an useful workaround for that.
Adding Fabrício Matté as an answer so I can accept it.
If you'd show us the generated HTML and what you're trying to do, it'd be much easier to reply. Anyway, I've had a problem inserting rows/cells in a table on IE before, my solution was pre-creating the rows/cells with display:none when the table is created, then changing the 's innerHTML together with their display.

Javascript within HTML form tag in the javascript function

Is it possible to put a JavaScript code within the HTML Form tags. I am trying to achieve something like this:
function abc(abcd) {
document.getElementById("context").innerHTML += "<br> 1:";
document.getElementById("context").innerHTML += "***<form METHOD=POST ACTION=\"/InformationRetrieval/home\">***<input type=\"checkbox\" name=\" GoogleRelevance\" value=\"1\"> Relevant <br><br>";
document.getElementById("context").innerHTML += "<br> 2:";
document.getElementById("context").innerHTML += "<input type=\"checkbox\" name=\" GoogleRelevance1\" value=\"1\"> Relevant <br><br>";
document.getElementById("context").innerHTML += "<br> 3:";
document.getElementById("context").innerHTML += "<input type=\"checkbox\" name=\" GoogleRelevance3\" value=\"1\"> Relevant <br>***<input type=\"submit\" value=\"Submit\"></form>***<br><br>";
}
Here what I am trying to ask in this example is:
I have started the tag initially in my starting 2-3 lines, but I am not closing it there and rather inserting some more javascript lines and in the end I am closing the tag with another <input type="submit">, but when I click this button it does not work.
I tried using the OnClick property too but that didn't work either.
I am badly stuck with it. Any help will be greatly appreciated.
I think you really should use some good ajax library (jQuery, YUI, dojo, goog, ...) for something like this, stuffing all the code into form attributes doesn't feel right. As nickf pointed out modifying a dom property in this way is really not a good idea. As I'm used to jQuery here is a snippet to what I understand from your post is the problem:
// Caching the stuff that you used to += on the innerHTML
var newStuff = ' /* your form code here */ ';
jQuery
.ajax({
url: /* your request to google */,
context: jQuery('#context') // Caching the context dom node
})
.done(function() {
// The request was successful
jQuery(this) // The cached context node is the context of this callback
.append(newStuff); // You only have to append new stuff here, if you want something
// more dynamic insert the logic in this function
})
.fail(function() { /* alert("error"); */ })
.always(function() { /* alert("complete"); */ });
I didn't test this one though, it's only a recommendation. To me it is cleaner and it has the advantage if you get it to work in one browser this way you can count on jQuery to make sure it's working in most other browsers too.
And by the way: you can use single ' around the whole html string so that you don't need to escape the " thingys.
Hope this helps, good luck!

Jquery detect id/class by overlapping

I've searched a lot for this on google, but without luck...
Basically I need some js, that can find the id/class of the element, that I'm hovering (So I can use "this"-property).
Because I have a lot of divs (Some have to be auto generated, with random names [Or maybe not, if I can use the "this"-property]) on my page, and I don't want to type in all there names (Such as I have to do in _hittest, with just gives me a true/false value)
Hope you guys can help me :D
I've really search for this, for a loooongtime
*EDIT:
Not a mouse hover, that I'm looking for, but when hover a div with another div
You could do this, although it's bad practice to select all the divs:
$('div').mouseover(function(){
console.log(this);
});
Put in a convenient textarea to copy from:
<textarea id="A"></textarea>
JS:
$('div').mouseover(function() {
$('#A').html($('#A').html() + "\nID: " + $(this).attr('id') + " CLS:" + $(this).attr('class') + " Name:" + $(this).attr('name') )
})
Something like this? It will look for all the elements on the page which have id or name attribute and attach a hover event handler.
$("*[id], *[name]").hover(function(){
alert(this.id || this.name);
});
Just did some calculating with offset

JQuery html() vs. innerHTML

Can I completely rely upon jQuery's html() method behaving identical to innerHTML? Is there any difference between innerHTML and jQuery's html() method? If these methods both do the same, can I use jQuery's html() method in place of innerHTML?
My problem is: I am working on already designed pages, the pages contains tables and in JavaScript the innerHTML property is being used to populate them dynamically.
The application is working fine on Firefox but Internet Explorer fires an error: unknown runtime exception. I used jQuery's html() method and IE's error has disappeared. But I'm not sure it will work for all browsers and I'm not sure whether to replace all innerHTML properties with jQuery's html() method.
Thanks a lot.
To answer your question:
.html() will just call .innerHTML after doing some checks for nodeTypes and stuff. It also uses a try/catch block where it tries to use innerHTML first and if that fails, it'll fallback gracefully to jQuery's .empty() + append()
Specifically regarding "Can I rely completely upon jquery html() method that it'll perform like innerHTML" my answer is NO!
Run this in internet explorer 7 or 8 and you'll see.
jQuery produces bad HTML when setting HTML containing a <FORM> tag nested within a <P> tag where the beginning of the string is a newline!
There are several test cases here and the comments when run should be self explanatory enough. This is quite obscure, but not understanding what's going on is a little disconcerting. I'm going to file a bug report.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script>
$(function() {
// the following two blocks of HTML are identical except the P tag is outside the form in the first case
var html1 = "<p><form id='form1'><input type='text' name='field1' value='111' /><div class='foo' /><input type='text' name='field2' value='222' /></form></p>";
var html2 = "<form id='form1'><p><input type='text' name='field1' value='111' /><div class='foo' /><input type='text' name='field2' value='222' /></p></form>";
// <FORM> tag nested within <P>
RunTest("<FORM> tag nested within <P> tag", html1); // succeeds in Internet Explorer
RunTest("<FORM> tag nested within <P> tag with leading newline", "\n" + html1); // fails with added new line in Internet Explorer
// <P> tag nested within <HTML>
RunTest("<P> tag nested within <FORM> tag", html2); // succeeds in Internet Explorer
RunTest("<P> tag nested within <FORM> tag with leading newline", "\n" + html2); // succeeds in Internet Explorer even with \n
});
function RunTest(testName, html) {
// run with jQuery
$("#placeholder").html(html);
var jqueryDOM = $('#placeholder').html();
var jqueryFormSerialize = $("#placeholder form").serialize();
// run with innerHTML
$("#placeholder")[0].innerHTML = html;
var innerHTMLDOM = $('#placeholder').html();
var innerHTMLFormSerialize = $("#placeholder form").serialize();
var expectedSerializedValue = "field1=111&field2=222";
alert( 'TEST NAME: ' + testName + '\n\n' +
'The HTML :\n"' + html + '"\n\n' +
'looks like this in the DOM when assigned with jQuery.html() :\n"' + jqueryDOM + '"\n\n' +
'and looks like this in the DOM when assigned with innerHTML :\n"' + innerHTMLDOM + '"\n\n' +
'We expect the form to serialize with jQuery.serialize() to be "' + expectedSerializedValue + '"\n\n' +
'When using jQuery to initially set the DOM the serialized value is :\n"' + jqueryFormSerialize + '\n' +
'When using innerHTML to initially set the DOM the serialized value is :\n"' + innerHTMLFormSerialize + '\n\n' +
'jQuery test : ' + (jqueryFormSerialize == expectedSerializedValue ? "SUCCEEDED" : "FAILED") + '\n' +
'InnerHTML test : ' + (innerHTMLFormSerialize == expectedSerializedValue ? "SUCCEEDED" : "FAILED")
);
}
</script>
</head>
<div id="placeholder">
This is #placeholder text will
</div>
</html>
If you're wondering about functionality, then jQuery's .html() performs the same intended functionality as .innerHTML, but it also performs checks for cross-browser compatibility.
For this reason, you can always use jQuery's .html() instead of .innerHTML where possible.
innerHTML is not standard and may not work in some browsers. I have used html() in all browsers with no problem.
Given the general support of .innerHTML these days, the only effective difference now is that .html() will execute code in any <script> tags if there are any in the html you give it. .innerHTML, under HTML5, will not.
From the jQuery docs:
By design, any jQuery constructor or method that accepts an HTML string — jQuery(), .append(), .after(), etc. — can potentially execute code. This can occur by injection of script tags or use of HTML attributes that execute code (for example, <img onload="">). Do not use these methods to insert strings obtained from untrusted sources such as URL query parameters, cookies, or form inputs. Doing so can introduce cross-site-scripting (XSS) vulnerabilities. Remove or escape any user input before adding content to the document.
Note: both .innerHTML and .html() can execute js other ways (e.g the onerror attribute).
"This method uses the browser's innerHTML property." - jQuery API
http://api.jquery.com/html/
Here is some code to get you started. You can modify the behavior of .innerHTML -- you could even create your own complete .innerHTML shim. (P.S.: redefining .innerHTML will also work in Firefox, but not Chrome -- they're working on it.)
if (/(msie|trident)/i.test(navigator.userAgent)) {
var innerhtml_get = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").get
var innerhtml_set = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").set
Object.defineProperty(HTMLElement.prototype, "innerHTML", {
get: function () {return innerhtml_get.call (this)},
set: function(new_html) {
var childNodes = this.childNodes
for (var curlen = childNodes.length, i = curlen; i > 0; i--) {
this.removeChild (childNodes[0])
}
innerhtml_set.call (this, new_html)
}
})
}
var mydiv = document.createElement ('div')
mydiv.innerHTML = "test"
document.body.appendChild (mydiv)
document.body.innerHTML = ""
console.log (mydiv.innerHTML)
http://jsfiddle.net/DLLbc/9/

Categories