JavaScript Form Submit Value - javascript

I have a legacy HTML form (that i dont control) that looks like this:
<form action="submit_action" method="get">
<textarea rows="4" cols="40" name="textarea1"></textarea>
<input type="submit" value="Submit" name="result" />
<input type="submit" value="Cancel" name="result" />
</form>
I need to read the values out of this form and do a HTTP POST to a REST API service. I wrote a function that would read out the input elements from the form and create a object from them like this:
const form = this._elementRef.nativeElement.querySelector('form');
form.onsubmit = (event) => this.onFormSubmit(event);
function onFormSubmit() {
event.preventDefault();
const action = form.attributes['action'].value;
let result = Object.keys(form.elements).reduce((acc, k) => {
const element = form.elements[k];
acc[element.name] = element.value;
return acc;
}, {});
console.log('Form Result', action, result);
}
In a classical form submit, the button that triggered the submission is passed a parameter. In this example: https://www.w3schools.com/tags/att_button_name.asp you see when you click the FORM it passes the button that was clicked in the post.
Is there a better way to do this so that I can read that out?

Related

Set associated form for custom element like form attribute for the input element?

Due to the layout of my page I would like to place a custom element outside of a form.
Can I make something like <my-custom-element form="foo"> work?
Presuming you want the submit button to return the value of your element even though it is outside the form. This is one way, there are many more (including using the function here called addExtras() to dynamically append your external name/value pair(s) to the form).
<my-custom-element> <input name="custom" id="custom" value="foo"></my-custom-element>
<form id="myForm" onsubmit="return addExtras()" method="post">
<input type="hidden"" name="customItem" id="customItem" />
<input name="anotherField" value="india" />
<button type="submit">submit</button>
</form>
<script>
function addExtras() {
document.getElementById("customItem").value = document.getElementById("custom").value;
return true;
}
// ==========================================================
//Code to display the submitted items, and prevent submission for test purposes
//Not needed for production
document.getElementById("myForm").addEventListener('submit', function (e) {
//prevent the normal submission of the form
e.preventDefault();
for (var i = 0; i < document.getElementById("myForm").elements.length; i++) {
var e = document.getElementById("myForm").elements[i];
console.log(e.name, e.value)
}
});
</script>

Why does my .innerhtml only works for a second?

I am using a form to get a word from a user then displaying it on a web page, here is my js code:
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('form').onsubmit = function() {
const word = document.querySelector('#wrd').value;
const header = document.querySelector('h1');
document.querySelector('h1').innerHTML = word;
}
});
the word flickers for a second then disappears,can you help me?
You must be submitting more than once while cleaning document.querySelector('#wrd').value if that's the only way to fill document.querySelector('h1'). Also, you might be reloading the page, without looking into your code I can't say for sure. The default behaviour of html submit is to reload the page, which would make it empty and appear to "flick"
When you submit a form it's synchronous by default. It takes the action attribute on the form and tries to post data to it. So in order to prevent that you have to capture the event and prevent its default action.
Take an example below for the different forms.
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#form1').onsubmit = function() {
const word = document.querySelector('#wrd').value;
document.querySelector('h1#first').innerHTML = word;
}
document.querySelector('#form2').onsubmit = function(e) {
e.preventDefault();
const word = document.querySelector('#wrd2').value;
document.querySelector('h1#second').innerHTML = word;
}
});
<form id="form1">
<input type="text" id="wrd" name="content" />
<button type="submit">Regular Submit</button>
</form>
<h1 id="first"></h1>
<hr>
<form id="form2">
<input type="text" id="wrd2" name="content" />
<button type="submit">Submit w/ Default Action Prevented</button>
</form>
<h1 id="second"></h1>

How to alter the attributes of a form's fields without clearing the field values?

So I have this html form:
<form action="">
<input type="text" name="form-0-product_name" id="id-form-0-product_name">
<input type="text" name="form-0-product_price" id="id-form-0-product_price">
<button>Change form</button>
</form>
Please note the name and id attributes and how they contain "form-0". For a reason that doesn't really matter too much, I want the user to be able to click the "Change form" button and have all the instances of "form-0" change to "form-1". I came up with this javascript function that does that:
let button = document.querySelector("button");
let form = document.querySelector("form");
button.addEventListener("click", e => {
e.preventDefault();
const replacedForm = "form-0";
form.innerHTML = form.innerHTML.replaceAll(replacedForm, "form-1");
})
This does the trick of replacing the "form-0" strings with "form-1" ; however, it seems as though this completely resets the form. In other words, if the client has already typed some data into the text fields and then presses the change form button, the fields are cleared of their values. What I want to know is if there's a really efficient way to change the form's fields' attributes (mainly id and name) without clearing the values of the fields if their are values in them. Thanks and please let me know if I need to clarify.
You'll have to iterate over the elements and attributes individually.
let button = document.querySelector("button");
let form = document.querySelector("form");
button.addEventListener("click", e => {
e.preventDefault();
const replacedForm = "form-0";
// Select all elements with a name or id
for (const elm of form.querySelectorAll('[name], [id]')) {
for (const attrib of ['name', 'id']) {
elm[attrib] = elm[attrib].replaceAll(replacedForm, "form-1");
}
}
})
<form action="">
<input type="text" name="form-0-product_name" id="id-form-0-product_name">
<input type="text" name="form-0-product_price" id="id-form-0-product_price">
<button>Change form</button>
</form>
But this is a really strange thing to want to do in most cases. IDs in particular should not be dynamic. Strongly consider if there's an alternative way to approach the problem you're trying to solve.
You can also iterate over form.elements and modify the attribute's value property
const form = document.querySelector('form');
Array.from(form.elements).forEach(el => {
Array.from(el.attributes).forEach(att => {
att.value = att.value.replaceAll('form-0', 'form-1')
console.log(att.value)
});
})
<form action="">
<input type="text" name="form-0-product_name" id="id-form-0-product_name">
<input type="text" name="form-0-product_price" id="id-form-0-product_price">
<button>Change form</button>
</form>

submit button does not post when its attributes were changed

I am using a form and a submit button in it to call a post request to server in html
In submit button, I use onclick event to change something in UI before posting request. Everything is fine when I do not change anything to the submit button, it posts request successfully.
But if I change anything in submit button such as value, disable attribute,... then it does not post request
Here is my code
<form action="url"method="post">
<input type="submit" onclick="return onClick(event)">
</form>
js code that does not post request
function onClick(e) {
const submit = e.target // or = this
submit.value = "Clicked"
submit.disabled = true
return true
}
js code that posts request successfully
function onClick(e) {
alert("Clicked")
return true
}
Could somebody tell me the reason why it does not post successfully and how to post with UI change like above?
You need to use submit method to achieve the result.
-> Assign id to the button and form element then get the element like,
const btn = document.getElementById('btn');
const form = document.getElementById('form');
It is always recommended to use addEventListener() method in javascript instead of making it in HTML template.
form.addEventListener('submit', onSubmit)
-> Now you can change the value of an attribute in submit method like,
function onSubmit(){
btn.value = "Clicked";
btn.disabled = true;
return true
}
Working snippet as follows,
const btn = document.getElementById('btn');
const form = document.getElementById('form');
function onSubmit(){
btn.value = "Clicked";
btn.disabled = true;
return true
}
form.addEventListener('submit', onSubmit)
<form id="form" action="url" method="post">
<input type="submit" id="btn">
</form>
Whether a form sends a POST or GET request is based on its method attribute. Try changing your form to
<form action="url" method="post">
<input type="submit" onclick="return onClick(event)">
</form>
another solution from me, I found it myself and many thanks to #Maniraj Murugan for your help above: use input type="button" instead, and in onclick event, use form.submit() to submit manually
<form action="url"method="post">
<input type="button" onclick="return onClick(event)">
</form>
and in onClick event
function onSubmit(e){
const btn = e.target
btn.value = "Clicked"
btn.disabled = true
const form = document.getElementById('form')
form.submit()
}

How to create html5 custom validation?

I am using html 5 form validation for validate my form before submit, if is valid, submit, but I need validate my User Register form, so it need validate if Password Confirm value is equal camp Password, below is my form example:
<form>
<label>Login:</label>
<input type="text" name="login" id="login"/><br/>
<label>Password:</label>
<input type="password" name="pass" id="pass"/><br/>
<label>Password Confirm:</label>
<input type="password" name="pass_conf" id="pass_conf"/><br/>
<input type="submit"/>
</form>
or in jsfiddle
How to can I create my custom validation for work like default validations?
Well you can use JQuery and attach an attribute to be selected for the passwords to validate each other via input event. Use setCustomValidity() to set the message of the input affected to override the default message when the form is submitted.
See the updated fiddle.
As you can see in the fiddle, all you have to do is add an attribute data-equal-id wherein the attribute value must be the ID of password input element to be tested.
HTML
<h1>How to create html5 validation for password confirm?</h1>
<hr>
<form>
<label>Login:</label>
<input type="text" name="login" id="login"/><br/>
<label>Password:</label>
<input type="password" name="pass" id="pass"/><br/>
<label>Password Confirm:</label>
<input type="password" name="pass_conf" id="pass_conf" data-equal-id="pass" /><br/>
<input type="submit"/>
</form>
Javascript
$('[data-equal-id]').bind('input', function() {
var to_confirm = $(this);
var to_equal = $('#' + to_confirm.data('equalId'));
if(to_confirm.val() != to_equal.val())
this.setCustomValidity('Password must be equal');
else
this.setCustomValidity('');
});
you could try putting this code in your header:
<script>
document.getElementById('myform').onsubmit = function() {
if(!validateForm()){ // call your validation function
alert('fail!'); // remove this
return false; // prevent the form to submit
}
}
// your validation function
// compares that the passwords are equal
function validateForm(){
var pass = document.getElementById('pass').value;
var pass_conf = document.getElementById('pass_conf').value;
if(pass == pass_conf){
return true;
}else{
return false;
}
}
</script>
also put the id 'myform' to your form (or the name you want, but change it in the first line)
How about something fun like this using jQuery?
$('input[type="password"]').keyup(function() {
var pass=$('#pass').val();
var conf=$('#pass_conf').val();
if (pass == conf)
$('input[type="submit"]').removeAttr('disabled');
else
$('input[type="submit"]').attr('disabled', 'disabled');
});
The breakdown...
I am keying off of the keyup, so every time a key is pressed in the
password fields the function will fire.
I'm grabbing the value of both password fields, and comparing them.
If the values are the same, I'm enabling the submit button.
If the values are different, I'm disabling the submit button.
Pretty simple, but it works. Here is a demo: http://codepen.io/anon/pen/GxAyC/
(note - I added a couple of other visual enhancements to the demo to show what can be done)
You're using HTML5 for client-side form validation and wish to validate your form prior to form submission. Your form consists of three inputs and your only validation criteria is that both password fields match.
The most simple way to do this is to write a custom submit handler script:
const handleFormSubmit = (event) => {
event.preventDefault();
form = event.target;
if (form.pass === form.pass_conf) {
form.submit();
}
}
Above preventDefault() stops the default form submission behavior so you can execute your check. Then check if the value of the two password fields are equal. And if they are, continue form submission.
To use, attach the custom handler to your form by listening to the submit event:
const form = document.querySelector('form');
form.addEventListener('submit', handleFormSubmit);
Applied in context to example form provided:
<form>
<label>Login:</label>
<input type="text" name="login" id="login"/><br/>
<label>Password:</label>
<input type="password" name="pass" id="pass"/><br/>
<label>Password Confirm:</label>
<input type="password" name="pass_conf" id="pass_conf"/><br/>
<input type="submit"/>
</form>
<script>
const form = document.querySelector('form');
form.addEventListener('submit', handleFormSubmit);
const handleFormSubmit = (event) => {
event.preventDefault();
form = event.target;
if (form.pass.value === form.pass_conf.value) {
form.submit();
}
}
</script>

Categories

Resources