jquery class selector only registering events on first element of class - javascript

im currently working on a form field highlighter in jquery and so far it works except it only works on the first line of the form and the rest of the fields do not register my focus events so that i may apply focus formatting
i am currently using the following jquery code
var debug = false;
$(function(){
$(".email-form tbody:last").AddFormLineToTable();
$("#do-add-row").click(function () {
if(debug)
{
alert("serialize click eventhandler fired");
}
$(".email-form tbody:last").AddFormLineToTable();
});
$(".does-focus-highlight").focusin(function(e){
$(e.target).addClass("focus-highlight");
if(debug){alert('field did focus');}
});
$(".does-focus-highlight").focusout(function(e){
$(e.target).removeClass("focus-highlight");
if(debug){alert('field did blur');}
});
$("#do-serialize").click(function(){
if(debug)
{
alert("serialize click eventhandler fired");
}
var jsn = $("#contact-form").serializeArray();
$("#serialize-target").val(JSON.stringify(jsn,null,2));
});
});
is there something im missing to catch these additional events
the form fields that are not firing are being generated dunamically as well if that makes a difference as well
which are being generated as follows
var lineCount = 0;
jQuery.fn.AddFormLineToTable = function() {
var o = $(this[0]);
o.append('<tr id="contact-'+lineCount+'">' +
'<td>Name: <input class="does-focus-highlight" id="contact-name-'+lineCount+'" name="contact-name-'+lineCount+'" type="text" required="required" /></td>' +
'<td>Email: <input class="does-focus-highlight" id="contact-email-'+lineCount+'" name="contact-email-'+lineCount+'" type="email" required="required" /></td>' +
'</tr>');
lineCount++;
};

.click() binds events only to elements that are existing at the time of calling .click(). If you want the events to be handled for elements that are created later on, use .on() or .live(), depending on the version of jQuery you are using. Read the very helpful info here.

Related

DOM equivalent to jQuery `.detach()`?

I’m trying to remove an input field by clicking an “X button”. After it is removed it will not post its value when the form is submitted. A “+ button” appears that allows the user to add said input again. The input has an onclick event that opens a calendar and after reattaching, the calendar does not open on click anymore. I can’t use jQuery.
adderBtn.onclick = function (e) {
var elem = that.hiddenElems.shift();
that.collectionItemContainer.append(elem);
}
removerBtn.onclick = function (e) {
collectionItemElem.remove();
that.hiddenElems.push(collectionItemElem);
}
The question is how do I remove and reattach DOM nodes without losing the Events.
When you remove an element, as long as you keep a reference to it, you can put it back. So:
var input = /*...code to get the input element*/;
input.parentNode.removeChild(input); // Or on modern browsers: `input.remove();`
later if you want to put it back
someParentElement.appendChild(input);
Unlike jQuery, the DOM doesn't distinguish between "remove" and "detach" — the DOM operation is always the equivalent of "detach," meaning if you add the element back, it still has its handlers:
Live Example:
var input = document.querySelector("input[type=text]");
input.addEventListener("input", function() {
console.log("input event: " + this.value);
});
input.focus();
var parent = input.parentNode;
document.querySelector("input[type=button]").addEventListener("click", function() {
if (input.parentNode) {
// Remove it
parent.removeChild(input);
} else {
// Put it back
parent.appendChild(input);
}
});
<form>
<div>
Type in the input to see events from it
</div>
<label>
Input:
<input type="text">
</label>
<div>
<input type="button" value="Toggle Field">
</div>
</form>
If you remove the element without keeping any reference to it, it is eligible for garbage collection, as are any handlers attached to it (provided nothing else refers to them, and ignoring some historic IE bugs in that regard...).
To detach an element in function form:
function detatch(elem) {
return elem.parentElement.removeChild(elem);
}
This will return the 'detached' element

How to apply validation to cloned elements in Jquery?

There is a textbox with label; having validation of isnumeric.
Money: <input type="text" id="dollar" name="dollar" data-require-numeric="true" value="">
//Textbox with id dollar0
At run time, I have created clone of above; by clicking on button named add; and this created another textbox with different id and other attributes same; say.
Money: <input type="text" id="dollar1" name="dollar1" data-require-numeric="true" value="">
//Cloned textbox; cloned by clicking on a button named clone
On both textboxes data-require-numeric is true.
Issue: For default textbox the JQuery validation is getting executed. But for new clone; JQuery is not running.
Following is jquery:
var economy= {
init: function () {
$('input[type="text"][data-require-numeric]').on("change keyup paste", function () {
check isnumeric; if yes then border red
});
}};
$(economy.init);
How to resolve this?
Try this : You need to register click event handler using .on() in following way where registering the click handler for document which will delegate the event to 'input[type="text"][data-require-numeric]'. This way you can handle events for dynamically added elements.
var economy= {
init: function () {
$(document).on("change keyup paste",'input[type="text"][data-require-numeric]',
function () {
check isnumeric; if yes then border red
});
}};
$(economy.init);
to bind change event on dynamic dom elements . use class reference instead of id . And bind the event to its parent like,
$(document).ready(function(){
$(".parent").on("keyup",".dynamicdom",function(e){
value = $(e.target).val()
//then do your validation here. and you can attach multiple events to it
})
})
<div class="parent">
<input type="text" class="dynamicdom" >
<input type="text" class="dynamicdom" >
</div>

Document not detecting input value

I've had this problem for awhile now and I can't seem to fix it no matter what I do.
Basically, my input is not retrieving the value that the user types in the input for some reason..
Here is my code:
$('#aid').one('click', function () {
$('.prompt').prepend('<tr class="task"><td class="cell-icon"></td>' +
'<td class="cell-title"><div>User\'s Object: <input id="inputObject" type="text" style="margin-top: 2px;margin-left:2px"></input> Amount: <input id="inputAmount"' +
'type="text" style="margin-top:2px;margin-left:2px; padding-right: 0px"></input></div></td>' +
'<td class="cell-status hidden-phone hidden-tablet"><a class="btn btn-success" style="margin-top:3px">Submit</a></td>' +
'<td class="cell-time align-right">Just Now</td></div>' +
'</tr>');
});
$('.btn').click(function () {
console.log("click");
var input = document.getElementById('inputObject').value;
console.log(input);
});
Everything works fine including both clicks, but for some reason it just won't display the input value to the console.
I've also tried: $('#inputObject').val(); but that didn't work either.
I really hope that someone can help me here!
Another method: use delegate.
$('body').delegate('.btn', "click", function() {
var inp = document.getElementById("inputObject").value;
console.log(inp);
});
Explanation from http://www.w3schools.com/jquery/event_delegate.asp:
The delegate() method attaches one or more event handlers for specified elements that are children of selected elements, and specifies a function to run when the events occur.
Event handlers attached using the delegate() method will work for both current and FUTURE elements (like a new element created by a script).
You are creating your HTML code dynamically so try using:
$(document).on("click",".btn", function(){
do stuff here...
});

Why is click event handler for a submit button in a colorbox defined in a jQuery prototype method not invoked

I have added a function to jQuery prototype as below. What I want to do is when this method is invoked, generate an html form based on the arguments passed to the method and show it in a colorbox.
(function($) {
$.fn.myFunction = function(data){
var form = $('<form name="people"></form>');
var index;
for (index = 0; index < data.length; index++) {
var match = data[index];
$('<input type="radio" name="person">' + match['name'] + ' [' + match['uri'] + ']<br> ')
.attr("value", match['uri'])
.appendTo(form);
}
$('<input type="button" id="a_button" value="Add"/><br>')
.appendTo(form);
var list = $('<div>').append(form).html();
$('#a_button').click(
function(){
console.log('message from event handler');
}
);
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
};
})(jQuery);
As you can see, form has a button called Add using which I hope to make an ajax request. But unfortunately click event handler attached to this button doesn't seem to be invoked.
Does anyone have any idea about what's wrong here? myFunction is actually invoked by a drupal ajax command in case if that's helpful.
You are appending the form to the DOM after attaching the event handler.
$('#a_button') searches the DOM at that specific point in time, but the form is not added to the DOM until after your call to colorbox with list as a parameter.
Try a permanent delegated event handler instead (or simply add the click handler after the colorbox line).
e.g.
$(document).on("click", "#a_button", function(){
console.log('message from event handler');
});
or
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
$('#a_button').click(
function(){
console.log('message from event handler');
}
);

Using an undeclared attribute for jquery event

This code is used to pop up a set of checkboxes that is generated when the radiobox with the value of Up is selected.
// Experiment
$("input[name='production-level']").on('change', function() {
var production = $(this).val();
var result = '';
if(production == 'Up') {
result = '<p class="question">Reasons why it is '+ production +'. Click as many as apply.</p>'
+ '<input type="checkbox" name="production-rsn[]" value="Increase in demand" required>Increase in demand <br/>'
+ '<input type="checkbox" name="production-rsn[]" value="Expected increase in demand">Expected increase in demand <br/>'
+ '<input type="checkbox" name="production-rsn[]" value="Fullfillment of past orders">Fulfillment of past orders <br/>'
+ '<input type="checkbox" name="production-rsn[]" value="Increased marketing activity">Increased marketing activity <br/>'
+ '<input type="checkbox" name="production-rsn[]" value="other" />Other';
}
$('#production').html(result);
});
And this code is used to pop up a textbox when the checkbox included in the generated code by the above function with value="other" is checked/ticked. The problem is it won't append!
$("input[name='production-rsn[]']").on('change', function () {
var result = '';
//check if the selected option is others
if (this.value === "other") {
result = '<input id="productionOther" maxlength="30" minlength="3" name="production-other" type="text"/>';
}
$('#production').append(result);
});
The problem is the textbox won't append! Any ideas?
As you are creating elements dynamically you need to use Event Delegation. You have to use .on() using delegated-events approach.
i.e.
$(document).on(event, selector, callback_function)
Example
$('#production').on('change', "input[name='production-rsn[]']", function(){
//Your code
});
In place of document you should use closest static container. In your case its '#production'
The delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, we can use delegated events to bind the click event to dynamically created elements and also to avoid the need to frequently attach and remove event handlers.
Since your input elements have been added dynamically to the DOM, all the events will not be available for these newly created input until you attach those events to them, you can achieve it using event delegation:
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all children matching a selector,
whether those children exist now or are added in the future.
$('#production').on('change', "input[name='production-rsn[]']", function () {
var result = '';
//check if the selected option is others
if (this.value === "other") {
result = '<input id="productionOther" maxlength="30" minlength="3" name="production-other" type="text"/>';
}
$('#production').append(result);
});

Categories

Resources