Jquery nested elements created dynamically have css styles and js events broken - javascript

I'm need to create the following form structure:
<div class="lg-pnl" id="logP">
<form id="form">
<div class="fields" id="fields1">
<div class="txt">
<label for="user" class="ent-u"></label>
<input id="user" type="text" name="user" class="validate[required] text-input" placeholder="user"/>
</div>
<div class="txt">
<label for="pw" class="ent-l"></label>
<input id="pw" type="password" name="password" class="validate[required] pw-input" placeholder="pwd"/>
</div>
<div class="btn">
<input type="submit" value="GO" id="subGO"/>
</div>
</div>
</form>
</div>
And for archieve this I'm using the very very very ugly code bellow:
$("#logP").append('<form id="form">');
$("#logP form").append('<div class="fields"></div>');
$("#logP form .fields").append('<div class="txt"></div>');
$("#logP form .fields .txt").append('<label for="user" class="ent-u"/>');
$("#logP form .fields .txt").append('<input id="user" type="text" name="user" class="validate[required] text-input" placeholder="user"/>');
$("#logP form .fields .txt").append('<label for="pw" class="ent-l"/>');
$("#logP form .fields .txt").append('<input id="pw" type="password" name="password" class="validate[required] pw-input" placeholder="pwd"/>');
$("#logP form .fields").append('<div class="btn"></div>');
$("#logP form .fields .buttons").append('<input type="submit" value="GO" id="subGO"/>');
I really need to preserve this DOM tree because the CSS style works on it.
But the styles isn't work properly neither the js events bind with form and input elements,
I have lost all behaviour for these functions, for example the piece of code bellow doesn't work anymore.
div.lg-pnl div.txt input[type="text"],
div.lg-pnl div.txt input[type="password"]
$('.subGO').click(function() {
$('#form').validation('validate');
});
$(function() {
$('input').keyup(function() {
this.value = this.value.toUpperCase();
});
});
So I'm trying to find out some better way to create this entire form and its own elements
dynamically without losing the styles and the id/class references in the javascript already
defined.
I'll really appreciate your suggestions
Thanks.

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the event binding call.
You need to use Event Delegation. You have to use .on() using delegated-events approach.
Use
$(document).on('click', '.subGO',function() {
$('#form').validation('validate');
});
Replace document with nearest static container. i.e. "#logP"
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.

Related

Why does my javascript function result in a rangeError?

Fairly new to this. I read a bunch of answers with people having a similar problem. I tried all the solutions offered (using e.stopPropagation, using e.stopImmediatePropagation, using id instead of tag...) but nothing worked. I deployed a single html page through firebase.
I wrote the script directly in the html. Here's my code:
function onclick(e) {
/*e.stopPropagation() and e.preventDefault() --YIELDD SAME RESULT*/
e.stopImmediatePropagation()
console.log("hello")
}
<h3>Please update your information below</h3>
<form id="login-form" class="reset-form">
<label>Email:</label>
<input name="email" type="email" placeholder="#">
<label>New Password:</label>
<input name="password" type="password">
<label>Confirm Password:</label>
<input name="second-password" type="password">
<button id="submit-button" type="button" onclick="onclick()">Update</button>
</form>
</div>
</body>
Desired behavior: on click, button with id logs a message in the devtools console.
p.s. I'm sure there's a basic mistake I'm making but I am not able to find which one. Please help!
onclick is the name of a common DOM property. When a function with this name exists in the Global scope (as yours does), it essentially becomes a property of the window object and can overwrite the Global one. Call your callback function something else or move it out of the Global scope and it will work.
Also, e.stopImmediatePropagation() is most likely not required for your use case.
Finally, nothing can come after </body> except </html>. <script> elements are allowed in the head and body, but no where else.
<h3>Please update your information below</h3>
<form id="login-form" class="reset-form">
<label>Email:</label>
<input name="email" type="email" placeholder="#">
<label>New Password:</label>
<input name="password" type="password">
<label>Confirm Password:</label>
<input name="second-password" type="password">
<button id="submit-button" type="button" onclick="onclick1()">Update</button>
</form>
<script>
function onclick1(e) {
console.log("hello")
}
</script>
Now, since you are just learning all this, let's make sure you get off on the right foot. There is soooo much bad HTML and JavaScript floating around and bad habits are still used today because most people don't know any better so they just copy/paste someone else's code that seems to work.
Don't use inline HTML event handlers (onclick, onmouseover, etc.) in the first place. Separate your JavaScript from your HTML and follow modern, standards based code. There are many reasons to not use inline HTML event handlers. Instead, use the .addEventListener() method.
Next, the <label> element is a semantic element that works in one of two ways:
It has a for attribute that has a value that is identical to the
form field that it is the label "for":
<label for="txtFirstName">First Name:</label>
<input id="txtFirstName">
It contains the form field element that is is a label for:
<label>First Name: <input id="txtFirstName"></label>
In either case, you are telling the client that there is a relationship between the label and the form field it is a label for. This allows a user to click or touch the label and activate the form field. It is also very helpful to those who rely on assistive technologies (like screen readers) to use the web.
So, putting all this together, your code reworked would look like this (I've added just a little CSS to make the page a little cleaner to look at, but none of that is required):
label { display:block; width:200px; margin-bottom:.5em; }
button { margin-top: 1em; font-size:1.2em; padding:5px; }
<h3>Please update your information below</h3>
<form id="login-form" class="reset-form">
<label>Email: <input name="email" type="email" placeholder="#"></label>
<label>New Password: <input name="password" type="password"></label>
<label>Confirm Password: <input name="second-password" type="password"></label>
<button id="submit-button" type="button">Update</button>
</form>
<script>
// get a reference to the DOM element you want to work with
let btn = document.getElementById("submit-button");
// configure the event handler in JavaScript, not in HTML
btn.addEventListener("click", logToConsole);
// give your functions meaningful names
function logToConsole(e) {
console.log("hello")
}
</script>
<button id="submit-button" type="button"
onclick="onclick()">Update</button> causes an infinite loop. You're overriding the onclick method which basically makes your code say "When I'm clicked, click me" ad infinitum.
Change the name of function onclick() to anything else, like function hello() and it'll work.
Here's a working codepen you can play with. https://codepen.io/anon/pen/mzajGd
I think it's best to change which event your stopping, which seems to be the form submit. Unsure why you're getting the range issue, but this should work.
<!DOCTYPE html>
<html>
<body>
<form id="login-form" class="reset-form" >
<label>Email:</label>
<input name="email" type="email" placeholder="#">
<label>New Password:</label>
<input name="password" type="password">
<label>Confirm Password:</label>
<input name="second-password" type="password">
<input type="submit">Update</button>
</form>
<script>
document.getElementById("login-form").addEventListener("submit", function(event){
event.preventDefault();
alert('boogy');
});
</script>
</body>
</html>
Hi Steve and welcome to Stack Overflow.
First place your Button, there are several ways to acomplish this:
<button class="ui-btn" id="cmdHello">Push Me</button>
Yet another Button
Now react to it's Click event:
<script type="application/javascript">
$(document).bind("pageinit", function() {
$(document).on("click", "#cmdHello", function(evt) {
console.log("Hello World");
});
});
</script>
That should do the trick.

How to Disable button until required fields are filled without using javascript, just HTML5 and CSS

I have the following form
<form action="" method="post">
<fieldset>
<legend>Booking Details</legend>
<div>
<label for="name">Name:</label>
<input id="name" name="name" value="" required pattern="[A-Za-z-0-9]+\s[A-Za-z-'0-9]+" title="firstname lastname" aria-required="true" aria-describedby="name-format">
<span id="name-format" class="help">Format: firstname lastname</span>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="" required aria-required="true">
</div>
<div>
<label for="website">Website:</label>
<input type="url" id="website" name="website" value="">
</div>
<div>
<label for="numTickets"><abbr title="Number">No.</abbr> of Tickets:</label>
<input type="number" id="numTickets" name="numTickets" value="" required aria-required="true" min="1" max="4">
</div>
<div class="submit">
<input type="submit" value="Submit" onclick="alert('martharfarkar')">
</div>
</fieldset>
</form>
JS Fiddle FROM EXAMPLE
I want to send an email using a webservice on the onclick event of a button, but noticed that the event is triggered regardless the form validation, so the question is, is there a way to trigger the onclick event only if the form is valid without using javascript? perhaps HTML5 has something new to offer
I think the problem is that you are attaching an action to the button click not the form submit. So, two things are happening here:
You are atually using javascript in onclick="alert('whatever')"
You are binding this script to the button click not the form submit
Your validation is working fine for the submit action. Consider use the action parameter in form not the onclick param in the input button.
EDIT:
To be more precise the <input type="submit" value="Submit"> default click action is submitting the form.
Hope it helps!
When I need some extra validation I change submit input to an element 'a' with an 'id' that I can check on a jquery click function. So I validate and I fire a submit manually. Example: $('#formId').submit ().
The best possible way is to bind the action to onsubmit event of the form rather than onclick event of button as user onepopcorn mentioned. It can be done by using
<form action="" method="post" onsubmit=alert('whatever')>
instead of using onclick for the submit button.

HTML5 required attribute trigger action with jQuery

I'm working on a prototype and I want to trigger an action after a submit but only if the required fields were filled.
I have this code
<button type="submit" onclick="doSomething()" class="btn btn-primary">Register</button>
And also an input on my form using the 'required' attribute from HTML 5, like this
<input type="text" class="form-control" placeholder="Name" required>
I want to trigger the action onclick only if the input was filled.
I suppose I could do this by checking if the input was filled using jQuery, I was wondering if there is a simpler way
Well, I have actually found a solution, if anyone is going through the same problem, this is how I did it.
Instead of using "onclick" on the button tag I added an "onsubmit" (I had no clue this existed) event inside my form tag with my doSomething function, like this:
<form onsubmit="doSomething()">
The function will only be called if the required inputs are filled, easy as that.
Thanks for the ones who tried to help anyway
Try using oninput event
function doSomething() {
console.log("do stuff")
}
document.querySelector("input").oninput = function() {
this.nextElementSibling.click()
}
<input type="text" class="form-control" placeholder="Name" required>
<button type="submit" onclick="doSomething()" class="btn btn-primary">Register</button>
Well you can always use this https://jsfiddle.net/2Lzo9vfc/26/
HTML
<button type="submit" class="btn btn-primary">Register</button>
<input type="text" class="form-control" placeholder="Name" required>
JS
$('button').click(function() {
var content = $('input').val();
if(content != '') {
alert(content);
}
});

Manually highlight all invalid inputs of Angular Form

The task is kinda primitive.
I got a simple Angular form with various inputs and I'd like to highlight invalid inputs manually (e.g. on submit action).
I tried to loop over invalid inputs, assuming that they must have some method to highlight an error, but unfortunately they don't.
Same with form. $setDirty() didn't work as well.
I'm using ng-form directive to get access to both form and input.
AngularJS version is 1.2.x.
You form markup should look like, so that when you click on submit ng-class will add submitted class on form that will give you idea that whenever you have submitted class on form and field has ng-invalid class, you can highlight those element
Markup
<ng-form name="form" ng-class="{submitted: submitted}" ng-submit="submitted=true; submit();">
<input type="text" name="firstname" ng-model="formData.firstname">
<input type="text" name="lastname" ng-model="formData.lastname">
<input type="submit" value="submit">
</ng-form>
CSS
.submitted input.ng-invalid {
border: solid 1px red;
}
Use ng-pattern and required it will check you validation. and onSubmiy you can customized your validation also
Example: http://jsfiddle.net/kevalbhatt18/dmo1jg02/
<div ng-app ng-controller="formCtrl">
<form name="myForm" ng-submit="onSubmit()">
<input type="number" ng-model="price" name="price_field" ng-pattern="/^[0-9]{1,7}$/" required>
<span ng-show="myForm.price_field.$error.pattern">Not a valid number!</span>
<input type="submit" value="submit"/>
</form>
</div>
Js
function formCtrl($scope){
$scope.onSubmit = function(){
alert("form submitted");
}
}

Accordion + Appended Content Jquery

So I have an accordion menu that I created with Jquery:
<script>
$(document).ready(function() {
/*Accordian Script for the Request New Appraisal Panel*/
$('.accordian_item').hide();
$('.accordian_item').first().slideDown();
$('.accordian_trigger').click(function(event) {
event.preventDefault();
$(this).parent().find('.accordian_item').slideToggle();
});
});
</script>
Now, I want to be able to dynamically append extra accordion items to the accordion box, which I have done like this:
<script>
$('#add_contact_btn').click(function(event) {
event.preventDefault();
var large = '<div class="accordian_container"><h4>Co-Borrower Information</h4><hr/><div class="accordian_item"><label> First Name</label><br/><input type="text"/><br/><label>Middle Name</label><br/><input type="text"/><br/><label>Last Name</label><br/><input type="text" /><br/><label>Home Number</label><br/><input type="text"/><br><label>Work Number</label><br/><input type="text"/><br><label>Cell Number</label><br/><input type="text"/><br></div></div>';
$('#accordion_container_box').append(large);
});
</script>
This works perfect, except the dynamically generated items don't collaps when you click on the collapse button. The existing accordion items still work. For some reason it seems like Jquery wont trigger for dynamically created links. Any ideas how I can correct this?
BTW, here is the basic HTML structure:
<div id="accordion_container_box">
<div class="accordian_container">
<h4>Borrower's Information</h4>
<hr/>
<div class="accordian_item">
<label> First Name</label><br/>
<input type="text"/><br/>
<label>Middle Name</label><br/>
<input type="text"/><br/>
<label>Last Name</label><br/>
<input type="text" /><br/>
<label>Home Number</label><br/>
<input type="text"/><br>
<label>Work Number</label><br/>
<input type="text"/><br>
<label>Cell Number</label><br/>
<input type="text"/><br>
</div>
</div>
<div class="accordian_container">
<h4>Co-Borrower's Information</h4>
<hr/>
<div class="accordian_item">
<label> First Name</label><br/>
<input type="text"/><br/>
<label>Middle Name</label><br/>
<input type="text"/><br/>
<label>Last Name</label><br/>
<input type="text" /><br/>
<label>Home Number</label><br/>
<input type="text"/><br>
<label>Work Number</label><br/>
<input type="text"/><br>
<label>Cell Number</label><br/>
<input type="text"/><br>
</div>
</div>
</div>
+ Additional Contact
You have to use .live('click'... on dynamically created content.
By default binding events to elements will only affect nodes that exist at the time that the bind runs. By using event delegation you can make use of the built in way that events bubble. jQuery < 1.7 did this with the delegate and live methods, jQuery 1.7 added the on method to consolidate all the event handlers in a single API.
For example you could use the following to handle all clicks on nodes with a class of accordian_trigger regardless of when they were created.
​$(document).on('click', '.accordian_trigger', function() {
//whatever you need to do
});​​​​​​​​​​​
What this will do is attach an onclick event handler to the document itself. When any click occurs in the DOM it will bubble up from the node that the event occurred on to its parent and its parent until it reaches the document. jQuery will then check whether the event occurred on a node that matches the selector passed in as the second parameter of on, in this case it will check whether the node has a class of accordian_trigger. If it does it will run the function passed in as the third parameter.
For efficiency's sake you'll likely want to replace document with a parent node that you know will contain all accordian_trigger nodes. Otherwise all clicks bubble all the way up to the document and check whether the node that was clicked on has the accordian_trigger class, which is potentially expensive, especially if you have a large DOM.

Categories