form input element arrays with mootools - javascript

I tried searching for the answer to this, but did not find the specific answer I was looking for. In mootools, how do I access a form input element like below that has an array name using the "double dollar" ($$) function to be able to iterate through for form validation.
<input name="field[inventory_id]" type="text" />
<input name="field[asset_tag]" type="text" />
<input name="field[idea_tag] type="text" />
<input name="field[equip_make]" type="text" />
<input name="field[equip_model]" type="text" />
etc...
Thanks
Dan B

In MooTools you can use for example:
$$('input[name^="field"]')
This will get you all the input elements that have a name attribute starting with "field".
You could combine with that a .filter() with a funcion for validating and check in the end `the length property of this elements collection. Something like:
$$('button').addEvent('click', function () {
var inputs = $$('[name^="field"]');
var notValidating = inputs.filter(function (input) {
return !input.value;
})
alert('There are ' + notValidating.length + ' inputs not validating.');
});
jsFiddle: http://jsfiddle.net/kthaqmL2/

So I worked on this for a bit and came to the conclusion that giving all of the input elements a classname was the best method. I then used mootools double dollar function to iterate over all of the items with that classname.

Related

Selecting all textbox at once with javascript

In my work we have to fill a lot of textboxes to do some validations. After all, we need to erase all - one by one - to restart the process.
Has some way to erase all textbox content with javascript (the only one method we can use now)? A for loop maybe?
You should put all the input fields in a form and then reset the form by the .reset() method.
document.getElementById("reset").onclick= ()=>{
document.getElementById("form").reset()
}
<form id="form">
<input/>
<input/>
</form>
<button id="reset">Reset</button>
See an example on W3Schools or the docs on MDN
If you want to restore the fields to their initial value, reset the form as suggested by #dota2pro's answer.
OTOH, if you want to clear the elements regardless of their initial value, you can query the elements using a type (aka "tag") CSS selector via Document​.query​SelectorAll()
and iterate through the elements as below:
function go() {
let inputs = document.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
}
<input type="text" value="a"><br>
<input type="text" value="b"><br>
<input type="text" value="c"><br>
<br>
<button onclick="go()">click to clear</button>
Note that:
document.querySelectorAll('input') fetches all <input>s regardless of their type attribute.
document.querySelectorAll('input[type="text"]') fetches all <input type="text">.
document.querySelectorAll('textarea') fetches all <textarea>.
If you want to combine, you can use the comma combinator:
document.querySelectorAll('input[type="text"],textarea')
You can get in different ways in javascript:
By ID : document.getElementById("id")
By class: document.getElementsByClassName("class")
By tag:
document.querySelectorAll("input")
or Jquery
By ID : $("#id")
By class: $(".class")
By tag: $("input")
Read documentation about that here
tru
[...document.querySelectorAll('input')].map(x=>x.value='')
var clean = () => [...document.querySelectorAll('input')].map(x=>x.value='');
<button onclick="clean()">Clear</button><br>
<input type="text" value="some"><br>
<input type="text" value="short"><br>
<input type="text" value="text"><br>
Bellow code will select all editable text-boxes
document.querySelectorAll('input[type="text"]:not(:disabled):not([readonly]))')
If you have JQuery available, you can do:
$('input[type="text"]').val('');
Or, if you prefer native:
for(var i = 0; i < document.getElementsByTagName('input').length; i++){
document.getElementsByTagName('input')[i].value = '';
}

Javascript set value for Form obeject Array

I am looking to add data to a form object which is an array.
This works fine:
<input type="text" name="object" value="">
<script>document.form.object.value = "value";</script>
But when the object is an array it's not working:
<input type="text" name="object[]" value="">
<script>document.form.object[0].value = "value";</script>
The value of the object is not changing.... Any idea?
I would like to loop the script so I need to create an array. Didn't find any solution...
Per example, I would utilize document.form.elements['object[]'].value = "value". Otherwise, if you intended on having multiple form elements with the same name (multiple inputs with object[], and iterate via the collection, can use the following:
var myForm = document.form;
var myControls = myForm.elements['object[]'];
for (var i = 0; i < myControls.length; i++) {
var aControl = myControls[i];
}
The example provided, in your code, the name provided is not perceived as an array.
The attribute value "object[]" is just a string to JavaScript -- it does not interpret that as an array. However, when brackets appear in a name, you cannot use it any more in the dot-notation, but must write:
document.form["object[]"].value = "value";
<form name="form">
<input type="text" name="object[]" value="">
</form>
If you have more than one element with name="object[]", then the above will only target the first one of these. To set the value of all those elements, you must loop. This you can (for instance) do with the elements property and Array.from to iterate over those elements:
Array.from(document.form.elements["object[]"], function(elem) {
elem.value = "value";
});
<form name="form">
<input type="text" name="object[]" value="">
<input type="text" name="object[]" value="">
</form>
For those using IE: replace Array.from with [].map.call

How to get all labels and its input elements in javascript

I would like to get all labels and its input elements using Javascript.
I have also radio, checkboxes and textarea elements.
Then I want to put it in an array of objects.
This is what I have done,
var html = data;
var array = [];
for(var i=0;i<$("input").length;i++){
array[i] = {label:"",val:$("input").eq(i).val()};
}
console.log(array);
By the way, doesn't have for attributes and also their next sibling is not always the input/radio/checkbox/textarea element. Sometimes,the structures are,
<label>Something:</label><Br/ ><input type="text" />
How can I do what I want in this situation?
You can use map() method to generate the array and use prevAll() method with jQuery :first pseudo-class selector to get the label(you can't use prev() method since there is a br tag in between).
var array = $("input").map(function(){
return {
label : $(this).prevAll('label:first').text(),
val:$(this).val()
};
}).get();
console.log(array);
FYI : If the input is wrapped by label in some case then you can use closest() method to get the wrapped element. Although you can use :input to select all form elements.
var array = $(":input").map(function() {
return {
label: $(this).prevAll('label:first').text(),
val: $(this).val()
};
}).get();
console.log(array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Some</label>
<Br/>
<input type="text" value="1" />
<label>Some1</label>
<Br/>
<input type="text" value="11" />
<label>Some2</label>
<Br/>
<input type="text" value="2" />
<label>Some3</label>
<Br/>
<input type="text" value="4" />
<label>Some4</label>
<Br/>
<input type="text" value="3" />
<label>Some422</label>
<Br/>
<select><option value="1"></option><select>
You're using labels wrong so I'm going to assume what you really want is just some identifying attribute of the text field checkbox etc to associate with the value.
Here is my go
https://jsfiddle.net/1akh5qg9/
HTML
<form id="test-form">
<label>Label1:</label>
<input class="get-value" name="input1" type="text" />
<br>
<label>Label2:</label>
<input class="get-value" name="input2" type="text" />
<br>
<label>Label3:</label>
<input class="get-value" type="checkbox" name="checkbox1">I have a bike
<br>
<br>
<button id="submit-button">Get Values</button>
</form>
Javascript
let btn = document.getElementById('submit-button');
let form = document.forms['test-form'].getElementsByClassName('get-value');
let valueArr = [];
// attach onclick handler
btn.onclick = function(e) {
e.preventDefault();
getFormValues();
}
// getFormValues
function getFormValues() {
for (var x of form){
valueArr.push({label:x.name ,value:x.value})
}
console.log(valueArr);
}
Results
[
{label:"input1", value:"test1"},
{label:"input2", value:"test1"},
{label:"checkbox1", value:"on"}
]
For you to get the label tags in your HTML form you first have to get the label tag from the DOM and follow up with the code below:
// get array of label tags in the DOM
const label = document.getElementsByTagName("label")
for (k = 0; k < label.length; k++){
const labelText = Array.prototype.filter
.call(label[k].childNodes, x => x.nodeName === "#text")
.map(x => x.textContent)
console.log(labelText)
}
If you want to select all elements (labels, inputs) into a single array, try using a custom attribute and use a selector like this $('*[data-all-labels-inputs]');
I would recommend doing something up-front in the HTML to mark the items you want to get.
You could put the label and input pairs in a DIV to indicate that they go together and then give the DIV a class that you could filter and loop on.
You could also use data-tag attributes to name the pairs. Say give all the labels and inputs the attribute data-LabelInp="NameA". Then you can select all labels with attribute data-LabelInp, get the value of the attribute and find the matching input with data-LabelInp === that value.

How do I use two .siblings with the same input type?

I want to get "The walking dead" also but it only gets the first hidden. Can i put a class on .this or how should I do?
$(".articel input[type='button']").click(function(){
var price = $(this).siblings("input[type='hidden']").attr("value");
var quantity = $(this).siblings("input[type='number']").attr("value");
var name = $(this).siblings("input[type='hidden']").attr("value");
var ul = document.getElementById("buylist");
var prod = name + " x " + quantity + " " + price + "$";
var el = document.createElement("li");
el.innerHTML = prod;
ul.appendChild(el);
<form class="articel">
Quantity: <input type="number" style="width:25px;"><br>
Add to cart: <input type="button" class="btn">
<input type="hidden" value="30">
<input type="hidden" value="The walking dead">
</form>
The conventional way to identify form fields is by the name property.
HTML:
<input type="hidden" name="title" value="The walking dead">
jQuery:
var name = $(this).siblings('input[name=title]').val();
Your current selector, siblings("input[type='hidden']"), selects all hidden field siblings, but since you have no way to discern them, attr will always just yield the value of the first match.
You could also have iterated over your collection of elements, or accessed them by index siblings('input[type=hidden]:eq(1)') or siblings('input[type=hidden]').eq(1), for instance, but it is a poor design that will break your code if you add another hidden field for something else. You really should prefer to name your elements so that you can access them in a meaningful way and know your data. That way you'll be free to move around and modify your markup according to new requirements, without breaking your script.
By the way, I'm using .val() above, which is shorthand for .attr('value').
One option is to use special selectors, e.g. :first and :last:
var price = $(this).siblings("input[type='hidden']:first").attr("value");
var name = $(this).siblings("input[type='hidden']:last").attr("value");
However, you always can set a class name to the elements:
<input type="hidden" class="price" value="30">
<input type="hidden" class="name" value="The walking dead">
var price = $(this).siblings(".price").attr("value");
var name = $(this).siblings(".name").attr("value");
I would add an class name to your hidden inputs (price, name). This way the html source code is more readable and also the js code will be more readable.

Clone form and increment ID

Consider the following form:
<form>
<input type="button" value="Input Button"/>
<input type="checkbox" />
<input type="file" id="file"/>
<input type="hidden" id="hidden"/>
<input type="image" id="image" />
<input type="password" id="password" />
<input type="radio" id="radio" />
<input type="reset" id="reset" />
</form>
Utilizing Javascript (and jQuery), what would be the easiest way to clone the entire form and increment each individual id within, to ensure uniqueness.
Using jQuery I would assume you would clone the form initially via clone() and iterate through the cloned objects id and add the new id fieldname1, fieldname2 etc. However, my knowledge of jQuery isn't too great and this project is almost killing me.
Any help would be great!
You would clone() it, and before attaching the cloned element to the DOM, you'd run through and add the number to each id attribute.
(function() {
var count = 0;
window.duplicateForm = function()
var source = $('form:first'),
clone = source.clone();
clone.find(':input').attr('id', function(i, val) {
return val + count;
});
clone.appendTo('body');
count++;
};
})();
jsFiddle.
This one starts with 0, but you could easily start count with 1.
You could also use a closure if you wanted, i.e.
var cloneForm = function(form, start) {
start = start || 0;
return function() {
var clone = form.clone();
clone.find(':input').attr('id', function(i, val) {
return val + start;
});
start++;
return clone;
};
};
Then you would do...
var cloneContactForm = cloneForm($('#contact-form'), 5);
// Now I want to clone it and put it somewhere.
$(cloneContactForm()).appendTo('body');
jsFiddle.
Here's a solution without updating any ids:
Give all forms the same class
Give all fields a name
Refer to cloned forms relative to all the forms with the class
Refer to fields with their name
Example:
How about giving each cloned form a different id, and then using names for each input element?
<form class="theForm">
<input type="password" name="password" />
</form>
Then Clone it with
container.append($('.theForm:first').clone());
(or cache the first form in a variable).
Finally, access the input fields with:
$('form.theForm:eq(0) [name=password]') // password from first form
$('form.theForm:eq(1) [name=password]') // password from second form
...
If the selector lookup efficiency is a factor here then there are several trivial ways to speed it up, such as caching variables with the different forms, caching $('.theForm') and using the eq() method, etc.
Sample jsFiddle is here: http://jsfiddle.net/orip/dX4sY

Categories