How to get Events associated with DOM elements? - javascript

I have an HTML document.
It is possible to get the events associated with every Element in a particular FORM element in the document using JavaScript.
var element = document.forms[i].elements[j];
This way I can get jth element in ith form, But can I get the event associated with the element.
There can be any number of elements in a form. I am using IE 8.
**EDIT :**
Actually I was trying to serialize HTML DOM into XML.
what I did to do this was :
createXML : function() {
objSerializeDOM.msg += "";
objSerializeDOM.msg += "<?xml version='1.0' encoding='UTF-8'?>\n\n";
// Get all the forms in a document.
var forms = document.forms;
for ( var i = 0; i < forms.length; i++) {
// Get all the elements on per form basis.
elements = document.forms[i].elements;
objSerializeDOM.msg += "<FORM name=\"" + forms[i].name + "\" method=\""
+ forms[i].method + "\" action=\"" + forms[i].action + "\">\n\n";
for ( var j = 0; j < elements.length; j++) {
objSerializeDOM.msg += " <" + elements[j].tagName + " type=\""
+ elements[j].type + "\"" + " name=\""
+ elements[j].name + "\"" + " Value =\""
+ elements[j].value + "\" />\n";
}
alert(document.forms[i].elements[1].event);
}
objSerializeDOM.msg += "\n\n</FORM>\n\n";
alert(objSerializeDOM.msg);
objSerializeDOM.writeToFile(objSerializeDOM.msg);
}
What I am getting from this is an XML :
<?xml version='1.0' encoding='UTF-8'?>
<FORM name="loginForm" method="post" action="/sigma/login.do;jsessionid=E6509E7BA55573AA5386274ABB93F718">
<INPUT type="hidden" name="message" Value ="" />
<INPUT type="hidden" name="userAction" Value ="" />
<INPUT type="text" name="userId" Value ="" />
<INPUT type="password" name="passwd" Value ="" />
<INPUT type="button" name="button" Value ="Continue" />
</FORM>
Now suppose I have:
<input tabindex="7" name="button" type="button" class="button"
style="width:100;height:30" Value="Continue" onclick='login()' />
All I want to do now is to get onClick in my XML or any event associated like onBlur() etc.

As Felix said in his comment, there are several ways to register an event on an object. So how you can get the events attached to an object and serialize them somehow to your xml depends on how they are registered. I will list some thoughts of how you can get them for serialisation.
1 Handlers registered inline
1.1 Completely inline code:
<INPUT type="hidden" name="message" Value ="" onclick="alert('hello')"/>
When the code is completely inline, you can just get the attribute in your xml and save it.
2.1 Inline function call
In this case you would have to export the declaration of the function. In JavaScript Functions are objects itsself so you could actually get the declaration text of your function by invoking myFunc.toString(). The hard part on this would be to figure out, if this is a function call where the declaration hast to be exported or not.
2 Handlers registered through attributes
If you have added all your element Handlers through i.e. :
function myFunc(num){
alert("Your number is: " + num);
}
document.getElementById('myElement').onclick = myFunc;
you could just iterate your form elements like you already do and get the onlick, onmouseover, onblur, on.... properties all one by one and save them to xml. Also in this case the content of this propertys will be Function Objects as well so to save their actual content you have to do .toString() on the Function object.
In addition there are some other ways to register Event handlers depending on the different Browsers. So if you definetly know how your events are registered, you can actually serialize them. If you don't that's going to be very difficult.
I hope that helps to get you a bit further.

This probably isn't what you're looking for but may help you atleast see which part of the DOM you need to be looking at - you can get a plugin for firebug which shows any jQuery events bound to DOM elements called firequery, and I think firebug on its own can show attached events in normal JS.
Considering that firebug is written in JS, there obviously must be a way to do it.
Unfortunately I don't have time to go through the source myself (I'd like to :D ) but you can find the repo here: http://code.google.com/p/fbug/source/browse/branches/firebug1.8/content/firebug/
Sorry I can't be of more help and good luck

Though It looks weird to answer my own question but may be it will help some one :
I did some research and found that:
document.forms[i].elements[j].onclick will return
function onclick()
{
login()
}
Here is the method which I was calling onClick of the button
similarly we can check many others like:
document.forms[i].elements[j].onblur
document.forms[i].elements[j].onfocus etc. etc.
Many thanks to all for taking interest in this question.

There is a very good tool visual event that would display all the events associated with element visually.
Add the following code at the end of each page that you want to monitor.
This will make the page disable and highlight all the events with icons and also show what they are doing by taking the cursor on that icon.
(function()
{
if(typeof VisualEvent!='undefined')
{
if(document.getElementById('Event_display'))
{
VisualEvent.fnClose();
}else{
VisualEvent.fnInit();
}
}else
{
var n=document.createElement('script');
n.setAttribute('language','JavaScript');
n.setAttribute('src','http://www.sprymedia.co.uk/design/event/media/js/event-loader.js');
document.body.appendChild(n);
}
})();
Please read visual event for detail.

Related

Javascript Escape Character Replacement

I'm using a button to dynamically generate a new table row in my form and the lines include calling functions with parameters. I tried using JQuery on the added lines to trigger the .blur() event, as was successfully done with the hardcoded first table row, but the page completely ignored it. So I'm trying another route of triggering the onblur() event from within the row HTML. I'm getting stuck on the function parameter, as I'm either messing up the escape character order or messing up the translation. I've already spent a few hours on this and tried doing research on Stack Overflow, so I'm hoping a second set of eyes would be able to help.
Here are the relevant pieces of code. The stored html is appended to my table row, which already works.
var strVar = 'myString';
var rowCount = $("#tbodyID td").closest("tr").length;
var rowNum = rowCount + 1;
var line17 = "<td><input type='number' class='form-control' name='named_qty' onblur='function(" + strVar + ")' id='row_R" + rowNum.toString() + "' /></td> ";
There are approximately 25 lines with varying html to be inserted. I was able to get it to work previously, but realized that a value was hardcoded and I needed it to be dynamic. The function it calls is accepting a string.
When inserted into the HTML document, this line should generally read:
<td><input type="number" class="form-control" name="named_qty" onblur="function('myString')" id="row_R2" /></td>
I did some more research and realized that I was using the JQuery blur() method as :
$('#id').blur( function() { }); and trying to call those functions, not realizing that the method only works for HTML elements that had been written to the DOM on page load.
Apparently the solution is to use the JQuery on() method as follows:
$(document).on("blur", '#id', function() { <insert code> });
From W3Schools,
Note: Event handlers attached using the on() method will work for both current and FUTURE elements (like a new element created by a script).
This removes the necessity to include the event function call in the HTML line to be appended to the DOM.

Why jquery validation is not working on appended elements?

I have a form and I want to add new elements as you can see in this fiddle I used append $('#cvfields').append(campos); to add this elements but the jquery validation plugin started to giving me problems. I found this in some answers related whith this question
$('#titulo_'+campo).rules('add', {'required': true});
$('#tipo_'+campo).rules('add', {'required': true});
But when I added .rules code I received this error
Uncaught TypeError: Cannot read property 'form' of undefined
$.extend.rules
(anonymous function)
x.event.dispatch
v.handle
Hope you can help!
You have some issues with your code:
1) When you use the .rules('add') method on a selector of multiple elements, you must nest it inside a jQuery .each() or it won't be applied to all the matching elements.
$('.newinput').each(function() {
$(this).rules('add', {
'required': true
});
});
However, you can probably skip .rules() entirely. See item #2 below.
2) You can totally forget about item #1 above since you're only trying to make these new fields required. Simply add a required="required" attribute (which I see you've already done) when you create them and you will not need to worry about the .rules('add') method at all. Alternatively, you could use class="required" instead, which is the method I chose for the demo below.
3) This is why nothing was working: Your newly added elements must also contain unique names. It's a requirement of the plugin that all form inputs need a name atribute. It's how the plugin keeps track of the elements, so they all need to be unique. However, as per your code, they do not. Your newly created elements all have the same exact name assigned to them as your existing elements. Fix it by adding a counter and incrementing it to the name each time you append to the form.
$(function () {
validar();
cvFields();
});
function validar() {
$(".validate").validate({
....
});
}
function cvFields() {
var count = 0;
$('#addcvfields').click(function (e) {
e.preventDefault();
count++;
var total = $()
var campos = '' +
....
'<input name="profesorcv_titulo[' + count + ']" type="text" class="form-control required" placeholder="Titulo de Estudio o Experiencia">' +
....
'<select name="profesorcv_tipo[' + count + ']" class="form-control required">' +
....
'<textarea rows="3" name="profesorcv_descripcion[' + count + ']" class="form-control" id="profesorcv_descripcion" placeholder="Describe Brevemente"></textarea>' +
....;
$('#cvfields').append(campos);
});
}
you get these problems because the added form elements where not in the DOM when your form validation plugin get initialized. you have to call your validation plugin again, after you've added new elements to the DOM.
EDIT: I just had a look at your fiddle code. your problem can be solved by first calling cvFields() and then validar();
$(function(){
cvFields();
validar();
});
If you first call validar(), the function will look in the DOM (document) if there are elements with the class ".validate". If there are elements with this class they'll get processed by the function. However all the elements that are added to the DOM after the validar() function won't get processed because they were not present in the DOM when the validar() function was called.
If you want to get the validating work after you added more items to validate you simply have to do validar(); again.

get element by id returns null for elements that were dynamically added using javascript

function createInput(id){
count++;
var name = "name" + count;
var text = "#" + id.id;
var newInput = "<input type='text' id='" + name + "' placeholder='' />";
var myTextArea = document.getElementById(id.id);
myTextArea.innerHTML += newInput;
return false;
}
The above function adds an input type to a textarea in a div in my code. Once the input type is displayed dynamically, i try to get it's element id using getElementById but it returns null. May I know what is going wrong here? It seems that the new input type is added but somehow the input type is null.
Also, when i refresh the page, i realize the newly added input type disappears. Any way to force the new dynamic input type to remain in the page?
A dynamically created content is only temporary on the page. When page is refreshed it is again without it. You should recreate it again on a page onload Event or .ready() (store the information in a cookie or HTML5 storage).
I tried to create working example of your code: http://jsfiddle.net/G2PKF/1/.
<div id="area1" onclick="createInput(this)" ></div>
<br/>
<div id="area2" onclick="createInput(this)"></div>
<input type="button" onclick="alert(document.getElementById('name' + count));alert(document.getElementById('name' + count).outerHTML)" value="Access Last Element" />
When a rectangle is clicked an input is added to it. The button allows to display last element added.
Everything works as expected. I don't see any problem with your function.

JQuery: convert var's html contents to string

I have a var that gets the HTML of a div. I want to use that var in a hidden form field so I can save the HTML to a database.
I am just having difficulty converting the HTML or the var to a string. Currently, adding the var to my input as is disrupts the code.
I have tried using .wrap('<pre />'); in a few different ways but it doesnt help and I dont think it is right.
Can anyone point me in the right direction? Thanks!
var code = $('#container').html();
code = code.wrap('<pre />')
document.write('<input type="hidden" name="html" value="' + code + '">');
You're better off using the helper methods over a direct document.write as (because it's HTML) you'll need to escape it (ensure no quotation marks are witin the code). Long story short, maybe use something like:
$('<input>',{
'type':'hidden',
'name':'html'
}) // create element
.val(code) // use helper to insert HTML (auto-excapes)
.appendTo('body'); // insert it where ever you need it
Further explanation: Say, for example, code had the following:
<div class="foo">bar</div>
By using a document write (and not escaping it) you're writing:
<input type="hidden" name="html" value="<div class="foo">bar</div>">
The class="foo" (and its quotes) interfere with the original hidden element's value="" attribute. using .val() avoids this because it makes sure the value is safely inserted in to the element.
Using jQuery, this is probably the best way to do it...
jQuery(document).ready(
function (){
var code = jQuery.trim(jQuery('#container').html());
jQuery("form").append('<input type="hidden" name="html" value="' + code + '">');
});

Count Dynamically created html elements with jquery

I am counting the number of inputs on the current document that have value. It works fine, except for when I have dynamically added more inputs. I can't get there values.
For example I may have
<input id="participant-1"/>
<input id="participant-2"/>
...
Dynamically created after button click
<input id="participant-15" />
I'll get the value of each one in a for loop like
for(var i =1 ; i <25; i++)
{
...$('input#participant-' + i).val();
}
Now when I run a for loop to check the value of each one of these inputs it only gets the values of the inputs that weren't dynamically created. I have looked at the other questions on here and I still can't see how to apply something like .on() to what I am trying to accomplish.
NEW FOLLOW UP QUESTION
ok, now I think this is where I need more clarification concerning how to use the .on.
I have a jsfiddle here: JsFiddle example
where I create new elements and on blur of all text boxes I would like to calculate how many of the elements have value and log it. Now it currently will respond from blur event with elements who were static. It doesn't work for dynamically created elements
Give it a common class:
<input class="textbox" id="participant-1"/>
<input class="textbox" id="participant-2"/>
And get it like:
var values = [];
$('.textbox').each(function(){
values.push($(this).val());
});
console.log(values)
And to answer the edit:
The Syntax should be : $(container_selector).on(event_type, target_selector, callback)
JSFiddle Demo
$('.name').on('blur', 'input', calculate_total);
Could also consider the use of the CSS attribute selector.
http://www.w3.org/TR/CSS2/selector.html#attribute-selectors
$("input[id|=participant]").each(function(){
// something
});
Using a class selector will save time here.
<input id="participant-1" class="participant"/>
<input id="participant-2" class="participant"/>
Then use a simple count call...
var count = $('.participant').length
alert ('You have ' + count + ' Counted Inputs');
//result is 2
Hope you find this useful

Categories

Resources