I am just practicing some javascript and i used to use JQuery a lot! I have had no major experience with raw javascript and i want to learn it just as i did JQuery. I have a simple form and a javascript function to go with it onsubmit and i want to get the name and value of each input in the form with my function but it doesnt seem to work can someone help me out?
<!DOCTYPE html>
<html>
<head>
<title>Foreach Practice</title>
<script type="text/javascript">
function Get() {
var Form = document.getElementById('Form');
for(I = 0; I < Form.length; I++) {
var Value = this.attribute('name').value;
alert(Value);
}
}
</script>
</head>
<body>
<form id="Form" onsubmit="return false;">
<input type="text" name="User" placeholder="Username" />
<input type="password" name="User" placeholder="Password" />
<input type="submit" name="Submit" onclick="javascript:Get();" />
</form>
</body>
</html>
This question is probably better suited to code review, but whatever.
> function Get() {
Variable names starting with a capital letter are, by convention, reserved for constructors. Also, names should indicate what the function does, a generic "get" function doesn't give much of a hint. A better name might be getFormValues.
> var Form = document.getElementById('Form');
There is a document.forms collection available that can be used as an alternative to calling a method:
var form = document.forms('Form');
> for(I = 0; I < Form.length; I++) {
You should always declare variables in an appropriate scope (noting that ECMAScript only has global, function and eval scope, there is no block scope), especially counters. Also, the form's length attribute is the number of controls in the form. Since it's a live collection, getting the length every time when you don't need to is potentially a performance hit, so cache the value:
for (var i = 0, iLen = form.length; i < iLen; i++) {
> var Value = this.attribute('name').value;
The value of this is set by how you call a function. If the function is called by a handler, then depending on the browser and method attachment, this will reference the element whose listener called the function. In this case, because the function is called by an inline listener, this has not been set so will default to the global object.
You can easily pass a reference to the element from the listener if you do:
<input ... onclick="getFormValues(this);" ... >
Now your function will receive a reference to the element and can conveniently get a reference to the form and iterate over the controls. Finally, it is rare to need to access a form control's attribute values, you nearly always want to access properties. So here's the re-written function:
function getFormValues(element) {
var form = element.form;
var controls = form.controls;
for (var i=0, iLen=controls.length; i<iLen; i++) {
alert(controls[i].name + ': ' + controls[i].value);
}
// Prevent form submission
return false;
}
Lastly, you are better to call the listener from the form rather than the submit button, since forms can be submitted by means other than clicking a submit button. Oh, and don't call any form control "submit" or use any name that is the same as a form method as it will overwrite the same–named method. You get away with it here due to capitalisation, but that is not much defense.
The related HTML can be (note that the form now doesn't need either a name or id):
<form onsubmit="return getFormValues();">
<input type="text" name="userName" placeholder="Username">
<input type="password" name="userPassword" placeholder="Password">
<input type="submit" name="submitButton">
</form>
You should iterate to form's children and use getAttribute function to get attribute value.
Try this:
function Get() {
var Form = document.getElementById('Form');
var childs = Form.children;
for(I = 0; I < childs.length; I++) {
var Value = childs[I].getAttribute('name');
alert(Value);
}
}
Anyone looking for the answer to this i figured it ou just by using random attempts of rearranging my code but here it is.
<!DOCTYPE html>
<html>
<head>
<title>Foreach Tutorial</title>
<script type="text/javascript">
function Get() {
var Form = document.getElementById('Form');
for(I = 0; I < Form.length; I++) {
var Name = Form[I].getAttribute('name');
var Value = Form[I].value;
alert(Name + ' : ' + Value);
}
}
</script>
</head>
<body>
<form id="Form" onsubmit="return false;">
<input type="text" name="User" placeholder="Username" />
<input type="password" name="Pass" placeholder="Password" />
<input type="submit" name="Submit" onclick="Get();" />
</form>
</body>
</html>
Related
I'm retrieving forms from my page, using:
DOMS = {
form: '[data-form]',
}
document.querySelectorAll(DOMS.fom).forEach(function (form, index) {
arr[index] = {};
arr[index]['DOMRef'] = form;
}
and adding them to an object. I add an event:
addEventListener('submit', function (event) {
send(event, form);
});
Later on form submit, I retrieve the form, and loop thru it:
form = arr[1];
for (i = 0; i < form.elements.length; i++) {
if (form.elements[i].type !== 'submit') {
data = data + form.elements[i].name + '=' + form.elements[i].value;
}
}
Above, I'm creating an Ajax request data. The problem is that I always retrieve the first value(without refresh).
If I change the value of a form field, is ignored, I presume because I call it from the object, and not again from DOM. Something like refresh form.
But also I don't want if is possible to call the form DOM everytime.
You are making copies of your forms somewhere, being called from object shouldn't affect.
document.addEventListener('submit', function (e) {
collectFormData(e);
});
let formsArr = document.querySelectorAll("form");
let formsObj = {fArr: formsArr};
function collectFormData(e){
e.preventDefault();
//event.target
var currForm = e.target;
for(i=0; i<currForm.elements.length; i++){
if(currForm.elements[i].type !== 'submit')
console.log(currForm.elements[i].value);
}
//array
for(j=0; j<formsArr[0].elements.length; j++){
console.log(formsArr[0].elements[j].value);
}
//object
for(k=0; k<formsObj.fArr[0].elements.length; k++){
console.log(formsObj.fArr[0].elements[k].value);
}
}
<form name="myForm" id="myform" action="" method="POST" enctype="multipart/form-datam">
<input type="text" class="val1" name="val1" id="val1" />
<input type="text" class="val2" name="val2" id="val2" />
<input type="text" class="val3" name="val3" id="val3" />
<button type="submit">submit</button>
</form>
PS. But also I don't want if is possible to call the form DOM everytime The value of the input field is in(side) the DOM. You can't get the gift without touching the package.
I was thinking, can i stop the alerts after the first?
I'll explain it better, every time I confirm the form, start an aler for every input that has oninvalid.
so if i have 10 inputs, i'll have 10 alarms. Is it possible to interrupt them after the first one?
<form>
<input type="text" oninvalid="alert('test1')" required />
<input type="text" oninvalid="alert('test2')" required />
<button>Send</button>
</form>
Fiddle: https://jsfiddle.net/9d1L5pxd/1/
You can consider doing something like I demonstrate below. Basically just add an event handler to the send button, which will call a validation function on your form each time it's clicked.
The validation function checks all the text type field values. If a text field with an invalid value is encountered, the function will return false (stop immediately).
If the function doesn't find any problems with the user input then it will return true. You can use the return value to determine if the form should be submitted or whatever if you need to.
var btnSend = document.getElementById('btnSend');
btnSend.addEventListener('click', function() {
var isValid = validateForm();
if (isValid)
console.log('Form is ready to submit.');
});
function validateForm() {
var formToValidate = document.getElementById('dataForm');
var elements = formToValidate.elements;
var i;
for (i = 0; i < elements.length; i++) {
if (elements[i].type == 'text') {
//replace this with your actual validation
var invalid = elements[i].value.length == 0;
if (invalid) {
alert(elements[i].id + ' is invalid.');
return false;
}
}
}
return true;
}
<form id="dataForm">
<input id="field1" type="text" required />
<input id="field2" type="text" required />
<input id="btnSend" type="button" value="Send">
</form>
I am trying to update two input fields in a form when clicking one button. I actually had all the code right when using document.getElementById, but the form that I'm using strips the ID's I set away, so I can't use getbyid. If I know the form field name, how could I change my function to do the same thing? Please note that my form has more than two fields, including a submit button, so I don't want to update those.
This is what I used before (with the ID selector)
Html:
<input type="text" name="field-1" id="info1">
<input type="text" name="field" id="info2">
Populate
JS:
function addTxt(val, id,no)
{
var id = id;
for(var i=1;i<=no;i++){
document.getElementById(id+i).value = val[i-1];
}
}
Fiddle:
http://jsfiddle.net/qwz47phx/3/
Edited with a much simpler and readable approach
function addVal(obj) {
event.preventDefault(); // Prevent page scrolltop on anchor click
$.each(obj, function(k, v) {
$("input[name='"+ k +"']").val( v );
})
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="foo">
<input type="text" name="bar">
<a href="#" onclick='addVal({foo:"Hello", "bar-baz":"World"})'>Populate</a>
Or with native JS (ES5+):
function addVal(obj) {
Object.keys(obj).forEach(function(name) {
document.querySelector('input[name="' + name + '"]').value = obj[name];
});
}
<input type="text" name="foo">
<input type="text" name="bar">
<input type="text" name="name-with-dashes">
<a href="#" onclick='addVal({foo:"Hello", bar:"World", "name-with-dashes": "Works !"})'>Populate</a>
If you have problems with IDs you can use querySelector to select inputs by name like this:
JS:
function addTxt(val, id, no) {
for (var i = 1; i <= no; i++) {
document.querySelector('input[name="' + id + i + '"]').value = val[i - 1];
}
}
HTML:
<input type="text" name="info1" id="info1">
<input type="text" name="info2" id="info2">
Populate
Demo: http://jsfiddle.net/iRbouh/qwz47phx/6/
I hope this will help you.
You can use a jQuery attribute= selector to grab by name instead of ID.
function addTxt(val, id,no)
{
for(var i=1;i<=no;i++){
var name = id+i;
$("input[name='"+name+"']").val(val[i-1]);
}
}
Please note that this function will be looking for names of info1, info2, info3, etc, just as your original script did. However, in the HTML, you have names of info and info-1. Either the names will have to be changed to fit the function, or the function can be slightly more intricate.
Fiddle: http://jsfiddle.net/qwz47phx/8/
I am trying to make an e-commerce-like webpage (for practice) wherein a click on any of the buttons would update the cart value by the number (quantity) specified on the input element.
So far, I was only able to update the cart from the first form because when I try to assign the function on every form using a loop, the cart updates for a millisecond then returns to zero. I assume its because of the scope.
I know there's an easier way to do this without manually assigning the function for every document.forms[n]
JS
window.onload = function()
{
var getForm = document.forms[0];
var numItems = 0;
getForm.onsubmit = function(event)
{
event.preventDefault();
var getInput = getForm.elements["num-item"].value;
if(parseInt(getInput))
{
numItems = numItems + parseInt(getInput);
var getCart = document.getElementById("item-count");
getCart.innerHTML = numItems;
getForm.reset();
}
else
{
alert("Please enter a valid number");
}
}
HTML
Cart:
<div class="basket">
<p><i class="fa fa-shopping-basket"></i></p>
<p id="item-count">0</p>
</div>
HTML Form: For brevity, I'm only posting 1 form example, but in reality, I have 6 other forms that are exactly the same.
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="text" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
Loop through all of the forms by querying the selector (using whatever method you prefer, depending on performance requirements and markup flexibility -- I've used getElementsByClassName) and executing a for loop.
Inside the loop, bind a function to the "submit" event using addEventListener. You can define the function in-line (as I've done), or define the function elsewhere, assign it to a variable, and reference the variable when binding to the event.
Within the event listener function, you will refer to the form that was submitted as this.
On top of the changes described above, I've made some minor changes to your code:
Your previous version was overwriting the contents of the cart each time. This may have been on purpose, depending on whether you have one "basket" for each item or one overall (this wasn't clear in the question). So, rather than initialize numItems to zero, I've initialized it to the current number of items in the cart.
Consider using input type="number" HTML form elements. They're supported by nearly every browser and only accept digits -- they also have up/down arrows and can be set with the scroll wheel. On browsers that don't support them, they fall back to a basic text input.
var forms = document.getElementsByClassName("buy-form");
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener("submit", function(event) {
event.preventDefault();
var numItems = parseInt(document.getElementById("item-count").innerHTML);
var getInput = this.getElementsByClassName("num-item")[0].value;
if (parseInt(getInput)) {
numItems = numItems + parseInt(getInput);
var getCart = document.getElementById("item-count");
getCart.innerHTML = numItems;
this.reset();
} else {
alert("Please enter a valid number");
}
});
}
<div class="basket">
<p><i class="fa fa-shopping-basket"></i></p>
<p id="item-count">0</p>
</div>
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="number" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="number" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="number" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
You can use the jQuery selector.
<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
$(document).ready(function() {
$('.buy-btn').click(function(){
$(this).parent('form').submit();
});
});
</script>
<form class="buy-form">
<label>Quantity:</label>
<input type="text" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
The code above will setup a function for each HTML elements that has the css class buy-btn.
You can select anything using parent, children, prev, next or find function from jQuery.
Of course this is just a basic exemple I'm showing here, and again some simple example could be :
$('.buy-btn').click(function(){
$(this).parent('form').submit();
//var itemCount = $('#item-count').html();
//itemCount++;
//$('#item-count').html(itemCount);
var numItem = $(this).prev('.num-item').val();
$('#item-count').html(numItem);
});
Unfortunately, you're going to have to loop through the elements in your JavaScript and assign the function to each, however you can do it a bit simpler with some querySelector methods thrown in:
window.onload = function() {
var getCart = document.getElementById('item-count');
var forms = document.querySelectorAll('.buy-form');
var numItems = 0;
var isNum = function(n) {
return(!isNaN(parseFloat(n)) && isFinite(n));
};
var handler = function(e) {
(e || event).preventDefault();
var getInput = this.querySelector('.num-item').value;
if(isNum(getInput)) {
numItems += parseInt(getInput);
getCart.innerHTML = numItems;
this.reset();
} else {
alert("Please enter a valid number");
}
};
for(var i = 0, len = forms.length; i < len; i++) {
forms[i].addEventListener('submit', handler);
}
};
I have a code javascript:
<form onsubmit="return false;" action="">
<input type="radio" name="type" id="type0" value="0" onclick="toggleSet(this)" checked />type 0
<input type="radio" name="type" id="type1" value="1" onclick="toggleSet(this)" />Type 1
</form>
<script>
function toggleSet() {
for(var i=0; i<document.form.type.length; i++) {
if(document.form.type[i].checked) {
var type = document.form.type[i].value;
}
}
alert(type);
}
</script>
ouput error: document.form is undefined, how to fix it ?
The form property of document does not exist. You're probably confused with the document.forms HTML collection:
document.forms[0]; //First <form> element
document.forms['name_of_form']; //Points to <form name="name_of_form">
Fixed code:
function toggleSet() {
var form = document.forms[0];
var type; //Declare variable here, to prevent a ReferenceError at the end
for(var i=0; i<form.type.length; i++) {
if(form.type[i].checked) {
type = form.type[i].value;
break; // After finding an occurrence, break the loop:
// You expect only one value
}
}
alert(type);
}
Just define the name parameter in the form tag like < form name="form1" ...> and call it through array value as below.
e.g var type = document.form1.type[i].value;
There is no property document.form.
document has a property forms which is an array of the forms the document contains. You access the desired form this way:
document.forms[0] // first form
document.forms['theForm'] // form with name="theForm"
document.form is not standard as far as I know. document.forms (note the 's') is. Documents can have multiple forms.