JS input validation submit disabled for separate instances - javascript

I need each instance of input and submit to operate independently. What is the best way to handle multiple instances where each submit is connected to it's own set of inputs?
Since they are unrelated, would data-attributes be the best solution?
$(document).ready(function() {
validate();
$('input').on('keyup', validate);
});
function validate() {
var inputsWithValues = 0;
var myInputs = $("input:not([type='submit'])");
myInputs.each(function(e) {
if ($(this).val()) {
inputsWithValues += 1;
}
});
if (inputsWithValues == myInputs.length) {
$("input[type=submit]").prop("disabled", false);
} else {
$("input[type=submit]").prop("disabled", true);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item1">
<div><input type="text" name="name" autocomplete="off" required/></div>
<input type="submit" value="Submit 1" />
</div>
<div class="item2">
<div><input type="text" name="name" autocomplete="off" required/></div>
<div><input type="text" name="name" autocomplete="off" required/></div>
<input type="submit" value="Submit 2" />
</div>

I think your intuition about using data attributes works great here.
var allButtons = document.querySelectorAll("input[type=submit]");
allButtons.forEach(button => {
button.addEventListener("click", () => {
var inputSet = button.getAttribute("data-input-set");
var inputs = document.querySelectorAll("input[type='text'][data-input-set='" + inputSet + "']");
});
});
In the following code, when an input button is pressed, it will fetch all the inputs with the corresponding "input-set" tag.

Preferred way
I think best solution would be use form -tag as it is created for just this use case HTML Forms.
<form id="form-1">
<input type="text"/>
<input type="submit>
</form>
<form id="form-2">
<input type="text"/>
<input type="submit>
</form>
You can also bind custom Form on submit event handlers and collect form data this way.
$('#form-1').on('submit', function(event){
event.preventDefault(); // Prevent sending form as defaulted by browser
/* Do something with form */
});
Possible but more bolt on method
Alternative methods to this would be to create your own function's for collecting all relevant data from inputs and merge some resonable data object.
I would most likely do this with giving desired class -attribute all inputs I would like to collect at once eg. <input type="text" class="submit-1" /> and so on. Get all elements with given class, loop through all them and save values into object.
This requires much more work tho and form -tag gives you some nice validation out of the box which you this way have to do yourself.

Related

Why's my form action still being triggered when validating the form despite using e.preventDefault()?

I'd like to display a message above the name field if the user submits a name with a length greater than 20. This means the form will not get submitted - in other words, the form's action won't be triggered.
I've tried almost every suggestion I could find to prevent the form action from being triggered upon form validation but nothing seems to be working.
I've hit a wall with this and can't figure out what I'm doing wrong. How can rectify this?
html:
<form method="POST" id="form" action="/post.php">
<span class="nameError"></span>
<input type="text" class="name" name="name" placeholder="Name" required/>
<input class="button" type="submit" value="Submit"/>
</form>
Here's my jquery:
let name = $('.name');
let nameError= $('.nameError');
$(document).ready(function() {
$('input[type=submit]').on('click', function(e) {
if (name.length > 20) {
e.preventDefault();
nameError.val("Too many characters!");
return false;
}
});
});
I have modified the logic for validation. Basically we need to capture the submit event for the form and use the correct jquery methods to retreive data based upon the selectors.
$(document).ready(function() {
$("#form").submit(function( event ) {
let name = $('.name').val();
let nameError= $('.nameError');
if (name.length > 20) {
nameError.text("Too many characters!");
event.preventDefault();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<form method="POST" id="form" action="/post.php">
<input type="text" class="name" name="name" placeholder="Name" required/>
<label class="nameError"></label> <br/>
<input class="button" type="submit" value="Submit"/>
</form>

Pass the specific submitted form to a function with jQuery/Javascript

I want to intercept a form submission, then pass the form as a variable to a Javascript function, then grab form element values within that specific form. In my example, there could be more than one form with class "formtype". I don't think what I have here is quite correct, but maybe close? How do I reference the specific form that has been submitted, in case of multiple "formtype" class forms?
$('.formtype').on('submit', function(e){
var $submittedform=$(this);
e.preventDefault();
processForm($submittedform);
});
function processForm($submittedform){
var email=$($submittedform+' .email').val();
}
You are pretty close, but use find() instead of the string concatenation
$('.formtype').on('submit', function(e) {
var $submittedform = $(this);
e.preventDefault();
processForm($submittedform);
});
function processForm($submittedform) {
console.log($submittedform.find('input.email').val())
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="formtype">
<input class="email" value="foo">
<input type="submit">
</form>
<form class="formtype">
<input class="email" value="bar">
<input type="submit">
</form>

How do I clear the previous text field value after submitting the form with out refreshing the entire page?

I am doing a web application using javascript and html that has a form containing a text field, button. When I enter a number in that text field and submit by clicking on that button, text areas are generated dynamically. Once my form is submitted some text areas are created but if I am not satisfied with existing text areas then again I enter some value with out refreshing page. But the text field value entered previously prevails showing the new text areas below the existing text areas on the page.
So, how do I clear the value with out refreshing the page.
<div>
<html>
<input type="text" name = "numquest" id ="numquest" value="" size="5" style="" disabled>
<input type="button" value="submit" onclick="getFields();">
</div>
</html>
<javascript>
var num_q=document.getElementById('numquest').value;
//code for dynamic creation
</javascript>
try this:
Using jQuery:
You can reset the entire form with:
$("#myform")[0].reset();
Or just the specific field with:
$('#form-id').children('input').val('')
Using JavaScript Without jQuery
<input type="button" value="Submit" id="btnsubmit" onclick="submitForm()">
function submitForm() {
// Get the first form with the name
// Hopefully there is only one, but there are more, select the correct index
var frm = document.getElementsByName('contact-form')[0];
frm.submit(); // Submit
frm.reset(); // Reset
return false; // Prevent page refresh
}
You can set the value of the element to blank
document.getElementById('elementId').value='';
Assign empty value:
document.getElementById('numquest').value=null;
or, if want to clear all form fields. Just call form reset method as:
document.forms['form_name'].reset()
you can just do as you get that elements value
document.getElementById('numquest').value='';
<form>
<input type="text" placeholder="user-name" /><br>
<input type=submit value="submit" id="submit" /> <br>
</form>
<script>
$(window).load(function() {
$('form').children('input:not(#submit)').val('')
}
</script>
You can use this script where every you want.
It will clear all the fields.
let inputs = document.querySelectorAll("input");
inputs.forEach((input) => (input.value = ""));
HTML
<form id="some_form">
<!-- some form elements -->
</form>
and jquery
$("#some_form").reset();
I believe it's better to use
$('#form-id').find('input').val('');
instead of
$('#form-id').children('input').val('');
incase you have checkboxes in your form use this to rest it:
$('#form-id').find('input:checkbox').removeAttr('checked');
.val() or .value is IMHO the best solution because it's useful with Ajax. And .reset() only works after page reload and APIs using Ajax never refresh pages unless it's triggered by a different script.
I had that issue and I solved by doing this:
.done(function() {
$(this).find("input").val("");
$("#feedback").trigger("reset");
});
I added this code after my script as I used jQuery. Try same)
<script type="text/JavaScript">
$(document).ready(function() {
$("#feedback").submit(function(event) {
event.preventDefault();
$.ajax({
url: "feedback_lib.php",
type: "post",
data: $("#feedback").serialize()
}).done(function() {
$(this).find("input").val("");
$("#feedback").trigger("reset");
});
});
});
</script>
<form id="feedback" action="" name="feedback" method="post">
<input id="name" name="name" placeholder="name" />
<br />
<input id="surname" name="surname" placeholder="surname" />
<br />
<input id="enquiry" name="enquiry" placeholder="enquiry" />
<br />
<input id="organisation" name="organisation" placeholder="organisation" />
<br />
<input id="email" name="email" placeholder="email" />
<br />
<textarea id="message" name="message" rows="7" cols="40" placeholder="сообщение"></textarea>
<br />
<button id="send" name="send">send</button>
</form>
You can assign to the onsubmit property:
document.querySelector('form').onsubmit = e => {
e.target.submit();
e.target.reset();
return false;
};
https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onsubmit

Putting specific element into variable

how can i get a specific element of a text input into a variable via javascript, in other words take the example below
<form id="123">
<input type="text" id="supply_qty" />
<input type="submit" name="submit" id="123" />
</form>
How do i get the element within the text input into a variable when the submit button is clicked, the problem i have is that i have multiple instances of the code above, with lots of text inputs, so i only want to get the element specific to the submit button clicked. Hopefully you will get what i mean. The reason i need this done via JavaScript and not php etc... is that i later want to use ajax with it, but for the moment i just need the variable.
Thanks
The most easiest way is to give and id to the element and user getElementById() method to grab the element on variable. Just like what you are doing right now
Simple Example:
var button = document.getElementyById("123");
button.onclick = function() {
var text = document.getElementById('supply_qty'); //now you got your element in varaiblle
};
Using jQuery make a slight change to your markup. I am just going to add some classes.
<form>
<input type="text" class="textbox" />
<input type="submit" class="submit" name="submit" />
</form>
then
$(".submit").click(function() {
var txtbox = $(this).parent("form").children(".textbox")[0];
});
Or, it might be better to bind to the submit handler of the form, on that case, give a common class to the form.
<form class="tinyforms">
<input type="text" class="textbox" />
<input type="submit" class="submit" name="submit" />
</form>
Then
$('.tinyforms').submit(function() {
var txtbox = $(this).children(".textbox")[0];
});
If you accept using jQuery you can do this:
DOM
<form class="form" action="false">
<input type="text" value="some input" name="textInput" />
<input type="text" value="some text" name="textInput2" />
<input type="submit" class="sumbit" value="Send" />
<div id="results"></div>
</form>​​​​​​​​​​​​​​​​​​​
And JavaScript
$(".form").submit( function(){
var inputs = $(this).serializeArray();
$.each(inputs , function(i, input){
$("#results").append(input.value + "<br />");
});
return false;
} );​
EDIT: Updated code and Fiddle: http://jsfiddle.net/65Xtp/4/

Can I determine which Submit button was used in javascript?

I have a very simple form with a name field and two submit buttons: 'change' and 'delete'. I need to do some form validation in javascript when the form is submitted so I need to know which button was clicked. If the user hits the enter key, the 'change' value is the one that makes it to the server. So really, I just need to know if the 'delete' button was clicked or not.
Can I determine which button was clicked? Or do I need to change the 'delete' button from a submit to a regular button and catch its onclick event to submit the form?
The form looks like this:
<form action="update.php" method="post" onsubmit="return checkForm(this);">
<input type="text" name="tagName" size="30" value="name goes here" />
<input type="hidden" name="tagID" value="1" />
<input type="submit" name="submit" value="Change" />
<input type="submit" name="submit" value="Delete" />
</form>
In the checkForm() function, form["submit"] is a node list, not a single element I can grab the value of.
Here's an unobtrusive approach using jQuery...
$(function ()
{
// for each form on the page...
$("form").each(function ()
{
var that = $(this); // define context and reference
/* for each of the submit-inputs - in each of the forms on
the page - assign click and keypress event */
$("input:submit", that).bind("click keypress", function ()
{
// store the id of the submit-input on it's enclosing form
that.data("callerid", this.id);
});
});
// assign submit-event to all forms on the page
$("form").submit(function ()
{
/* retrieve the id of the input that was clicked, stored on
it's enclosing form */
var callerId = $(this).data("callerid");
// determine appropriate action(s)
if (callerId == "delete") // do stuff...
if (callerId == "change") // do stuff...
/* note: you can return false to prevent the default behavior
of the form--that is; stop the page from submitting */
});
});
Note: this code is using the id-property to reference elements, so you have to update your markup. If you want me to update the code in my answer to make use of the name-attribute to determine appropriate actions, let me know.
You could also use the onclick event in a number of different ways to address the problem.
For instance:
<input type="submit" name="submit" value="Delete"
onclick="return TryingToDelete();" />
In the TryingToDelete() function in JavaScript, do what you want, then return false if do not want the delete to proceed.
Some browsers (at least Firefox, Opera and IE) support this:
<script type="text/javascript">
function checkForm(form, event) {
// Firefox || Opera || IE || unsupported
var target = event.explicitOriginalTarget || event.relatedTarget ||
document.activeElement || {};
alert(target.type + ' ' + target.value);
return false;
}
</script>
<form action="update.php" method="post" onsubmit="return checkForm(this, event);">
<input type="text" name="tagName" size="30" value="name goes here" />
<input type="hidden" name="tagID" value="1" />
<input type="submit" name="submit" value="Change" />
<input type="submit" name="submit" value="Delete" />
</form>
For an inherently cross-browser solution, you'll have to add onclick handlers to the buttons themselves.
<html>
<script type="text/javascript">
var submit;
function checkForm(form)
{
alert(submit.value);
return false;
}
function Clicked(button)
{
submit= button ;
}
</script>
<body>
<form method="post" onsubmit="return checkForm(this);">
<input type="text" name="tagName" size="30" value="name goes here" />
<input type="hidden" name="tagID" value="1" />
<input onclick="Clicked(this);" type="submit" name="submit" value="Change" />
<input onclick="Clicked(this);" type="submit" name="submit" value="Delete" />
</form>
</body>
</html>
You could use the SubmitEvent.submitter property.
form.addEventListener('submit', event => console.log(event.submitter))
Give each of the buttons a unique ID such as
<input type="submit" id="submitButton" name="submit" value="Change" />
<input type="submit" id="deleteButton" name="submit" value="Delete" />
I'm not sure how to do this in raw javascript but in jquery you can then do
$('#submitButton').click(function() {
//do something
});
$('#deleteButton').click(function() {
//do something
});
This says that if submitButton is clicked, do whatever is inside it.
if deleteButton is clicked, do whatever is inside it
In jQuery you can use $.data() to keep data in scope - no need for global variables in that case.
First you click submit button, then (depending on it's action) you assign data to form. I'm not preventing default action in click event, so form is submitted right after click event ends.
HTML:
<form action="update.php" method="post"">
<input type="text" name="tagName" size="30" value="name goes here" />
<input type="hidden" name="tagID" value="1" />
<input type="submit" name="submit" value="Change" />
<input type="submit" name="submit" value="Delete" />
</form>
JavaScript:
(function ($) {
"use strict";
$(document).ready(function () {
// click on submit button with action "Change"
$('input[value="Change"]').on("click", function () {
var $form = $(this).parents('form');
$form.data("action", "Change");
});
// click on submit button with action "Delete"
$('input[value="Delete"]').on("click", function () {
var $form = $(this).parents('form');
$form.data("action", "Delete");
});
// on form submit
$('form').on("submit", function () {
var $self = $(this);
// retrieve action type from form
// If there is none assigned, go for the default one
var action = $self.data("action") || "deafult";
// remove data so next time you won't trigger wrong action
$self.removeData("action");
// do sth depending on action type
if (action === "change") {
}
});
});
})(jQuery);
Right now you've got the same problem as you would a normal text input. You've got the same name on two different elements. Change the names to "Change" and "Delete" and then determine if either one of them were clicked by applying an event handler on both submits and providing different methods. I'm assuming you're using pure JavaScript, but if you want it to be quick, take a look at jQuery.
What you need is as simple as following what's on w3schools
Since you didn't mention using any framework, this is the cleanest way to do it with straight Javascript. With this code what you're doing is passing the button object itself into the go() function. You then have access to all of the button's properties. You don't have to do anything with setTimeout(0) or any other wacky functions.
<script type="text/javascript">
function go(button) {
if (button.id = 'submit1')
//do something
else if (button.id = 'submit2')
//do something else
}
</script>
<form action="update.php" method="post">
<input type="text" name="tagName" size="30" value="name goes here" />
<input type="hidden" name="tagID" value="1" />
<input id="submit1" type="submit" name="submit" value="Change" onclick="go(this);"/>
<input id="submit2" type="submit" name="submit" value="Delete" onclick="go(this);"/>
</form>
A click event anywhere in a form will be caught by a form's click handler (as long as the element clicked on allows it to propagate). It will be processed before the form's submit event.
Therefore, one can test whether the click target was an input (or button) tag of the submit type, and save the value of it (say, to a data-button attribute on the form) for processing in the form's submit handler.
The submit buttons themselves do not then need any event handlers.
I needed to do this to change a form's action and target attributes, depending upon which submit button is clicked.
// TO CAPTURE THE BUTTON CLICKED
function get_button(){
var oElement=event.target;
var oForm=oElement.form;
// IF SUBMIT INPUT BUTTON (CHANGE 'INPUT' TO 'BUTTON' IF USING THAT TAG)
if((oElement.tagName=='INPUT')&&(oElement.type=='submit')){
// SAVE THE ACTION
oForm.setAttribute('data-button',oElement.value);
}
}
// TO DO THE SUBMIT PROCESSING
function submit_form(){
var oForm=event.target;
// RETRIEVE THE BUTTON CLICKED, IF ONE WAS USED
var sAction='';
if(oForm.hasAttribute('data-button')){
// SAVE THE BUTTON, THEN DELETE THE ATTRIBUTE (SO NOT USED ON ANOTHER SUBMIT)
sAction=oForm.getAttribute('data-button');
oForm.removeAttribute('data-button');
}
// PROCESS BY THE BUTTON USED
switch(sAction){
case'Change':
// WHATEVER
alert('Change');
break;
case'Delete':
// WHATEVER
alert('Delete');
break;
default:
// WHATEVER FOR ENTER PRESSED
alert('submit: By other means');
break;
}
}
<form action="update.php" method="post" onsubmit="submit_form();" onclick="get_button();">
<input type="text" name="tagName" size="30" value="name goes here" />
<input type="hidden" name="tagID" value="1" />
<input type="submit" name="submit" value="Change" />
<input type="submit" name="submit" value="Delete" />
</form>
<p id="result"></p>
Here is my solution:
Just add dataset in submit button like this:
<form action="update.php" method="post" onsubmit="return checkForm(this);">
<input type="text" name="tagName" size="30" value="name goes here" />
<input type="hidden" name="tagID" value="1" />
<input type="submit" name="submit" value="Change" data-clicked="change" />
<input type="submit" name="submit" value="Delete" data-clicked="delete" />
</form>
In JS access it by:
$('body').on("submit", function(event){
var target = event.explicitOriginalTarget || event.relatedTarget || document.activeElement || {};
var buttonClicked = target.dataset['clicked'];
console.log(buttonClicked);
});
Name the delete button something else. Perhaps name one SubmitChange and name the other SubmitDelete.
I've been dealing with this problem myself. There's no built-in way to tell which button's submitting a form, but it's a feature which might show up in the future.
The workaround I use in production is to store the button somewhere for one event loop on click. The JavaScript could look something like this:
function grabSubmitter(input){
input.form.submitter = input;
setTimeout(function(){
input.form.submitter = null;
}, 0);
}
... and you'd set an onclick on each button:
<input type="submit" name="name" value="value" onclick="grabSubmitter(this)">
click fires before submit, so in your submit event, if there's a submitter on your form, a button was clicked.
I'm using jQuery, so I use $.fn.data() instead of expando to store the submitter. I have a tiny plugin to handle temporarily setting data on an element that looks like this:
$.fn.briefData = function(key, value){
var $el = this;
$el.data(key, value);
setTimeout(function(){
$el.removeData(key);
}, 0);
};
and I attach it to buttons like this:
$(':button, :submit').live('click', function () {
var $form = $(this.form);
if ($form.length) {
$form.briefData('submitter', this);
}
});

Categories