Basic javascript loop/validation question - javascript

So im trying to perform a basic validation to check if a field is empty. I want to do it in a loop..
<input type="text" size="25" name="q170_Name" class="text" value="" id="q170" maxlength="100" maxsize="100" />
function validateMe() {
var dropdowns = ["q170","q172","q173","q174","q175","q176","q177"];
var totalz = (dropdowns.length);
//loop through the array
for ( var i in dropdowns ) {
if (document.getElementById(dropdowns[i]) == "") {
alert('missed one!');
}}}
I appreciate the help

if (document.getElementById(dropdowns[i]).value == "") {
alert('missed one!');
--edit
but probably there is a better way to do this:
for (var i = 0; i < document.myFormName.length; ++i) {
if( document.myFormName.elements[i].type == "text" &&
document.myFormName.elements[i].value == "") {
alert('missed one!');
}
}

I recommend you to do a simple for loop since for..in is meant to iterate over object properties, also note that you need to check the value attribute of the fields:
function validateMe() {
var dropdowns = ["q170","q172","q173","q174","q175","q176","q177"],
totalz = dropdowns.length,
i;
for (i = 0; i < totalz; i++) {
if (document.getElementById(dropdowns[i]).value == "") {
alert('Check the value of ' + dropdowns[i]);
}
}
}

Related

JS class not applying on datapicker

Good morning,
I've got some javascript to check if inputs are empty before printing and if so, cancel the print.
I have added jquery datepicker to one of the fields as a class and now it only applies one class or the other. (I have tried the datepicker as an ID instead) but doesn't work.
Javascript:
function checkForm(thisForm) {
var len = thisForm.elements.length ;
var cnt = 0 ;
for ( var i=0; i < len; i++) {
var elem = thisForm.elements[i] ;
if (elem.className == "formFieldRequired") {
if ((elem.value == "" || elem.value == -1)) {
alert("WARNING:\n You must supply information for the " + elem.name + " field");
elem.focus();
return false;
}
}
}
window.print();return true;
}
Input:
<input name="Effective Date" type="text" style="width:12%;" class="formFieldRequired datepicker" placeholder="DD/MM/YYYY" onkeyup="javascript:return mask(this.value,this,'2,5','/');" maxlength="10">
Any ideas on why this is happening and any fixes? - I may be missing something completely obvious!
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.4/jquery.datetimepicker.js"></script>
<form id="myform">
<input name="Effective Date" type="text" style="width:12%;" class="formFieldRequired datepicker" placeholder="DD/MM/YYYY" onkeyup="javascript:return mask(this.value,this,'2,5','/');" maxlength="10">
</form>
<script>
function checkForm(thisForm) {
var len = thisForm.elements.length;
var cnt = 0 ;
for ( var i=0; i < len; i++) {
var elem = thisForm.elements[i] ;
console.log(elem.className)
if (elem.className.indexOf("formFieldRequired") != -1) {
if ((elem.value == "" || elem.value == -1)) {
alert("WARNING:\n You must supply information for the " + elem.name + " field");
elem.focus();
return false;
}
}
}
window.print();return true;
}
checkForm(document.getElementById("myform"));
</script>

Can I select a multi-dimensional HTML array in JavaScript as a multi-dimensional array?

If I have the following HTML on a page:
<input type="hidden" name=item[0][id]>
<input type="text" name=item[0][title]>
<input type="text" name=item[0][description]>
<input type="hidden" name=item[1][id]>
<input type="text" name=item[1][title]>
<input type="text" name=item[1][description]>
<input type="hidden" name=item[2][id]>
<input type="text" name=item[2][title]>
<input type="text" name=item[2][description]>
I would like to select the items using JavaScript (or JQuery) in such a way that I can loop over the items using the outer array.
Currently I have the following JQuery/JavaScript to handle the items:
var items = ($('[name*="item["]'));
var i = 0;
while (i < items.length) {
if (items[i++].value === '') {
// No ID set.
}
else if (items[i++].value === '') {
// No title set.
}
else if (items[i++].value === '') {
// No description set.
}
}
Is there a way to select the elements so that I can loop over them using notation more like the following (Where items.length is 3)?
for (var i = 0; i < items.length; i++) {
if (items[i][0].value === '') {
// No ID set.
}
else if (items[i][1].value === '') {
// No title set.
}
else if (items[i][2].value === '') {
// No description set.
}
}
Or even more like this?
for (var i = 0; i < items.length; i++) {
if (items[i].id.value === '') {
// No ID set.
}
else if (items[i].title.value === '') {
// No title set.
}
else if (items[i].description.value === '') {
// No description set.
}
}
Or would this require more manipulation and processing to go from selecting from the DOM to creating the data structure to loop over?
I think this is exactly what you are looking for (which is not really related to selectors):
function serialize () {
var serialized = {};
$("[name]").each(function () {
var name = $(this).attr('name');
var value = $(this).val();
var nameBits = name.split('[');
var previousRef = serialized;
for(var i = 0, l = nameBits.length; i < l; i++) {
var nameBit = nameBits[i].replace(']', '');
if(!previousRef[nameBit]) {
previousRef[nameBit] = {};
}
if(i != nameBits.length - 1) {
previousRef = previousRef[nameBit];
} else if(i == nameBits.length - 1) {
previousRef[nameBit] = value;
}
}
});
return serialized;
}
console.log(serialize());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="hidden" name=item[0][id]>
<input type="text" name=item[0][title]>
<input type="text" name=item[0][description]>
<input type="hidden" name=item[1][id]>
<input type="text" name=item[1][title]>
<input type="text" name=item[1][description]>
<input type="hidden" name=item[2][id]>
<input type="text" name=item[2][title]>
<input type="text" name=item[2][description]>
See the related JSFiddle sample.
Here's a way to add a custom function into JQuery to get the data structure you're looking for.
$.fn.getMultiArray = function() {
var $items = [];
var index = 0;
$(this).each(function() {
var $this = $(this);
if ($this.attr('name').indexOf('item[' + index + ']') !== 0)
index++;
if (!$items[index])
$items[index] = {};
var key = $this.attr('name').replace('item[' + index + '][', '').replace(']', '');
$items[index][key] = $this;
});
return $items;
};
var $items = $('input[name^="item["]').getMultiArray();
This allows you to have the references in your "ideal" example.
var $items = $('input[name^="item["]').getMultiArray();
$items[0].id;
JS Fiddle: https://jsfiddle.net/apphffus/

Allow to select only predifened combination from available values

let us say we have parameter with A,B,C and D values. Now we want to force the user to choose only A,B,C or A,C,D or A or B or C.
Instead of Allowing all possible 16 combination, we want to allow only 5 predefined combination. I tried it but for this i have to put condition for each and every selection.
If we assume this values are bind with checkbox and we need to check whether selected values are as per our predifined combination or not.
I need to achieve this in javascript or either angular.js. Please help me with proper algorithm for such operation.
I tried below logic to achieve this but this will not infor user instantly, alert only after final submission
// multi-dimentional array of defined combinations
var preDefinedCombinations = [['a','b','c'], ['a','c','d'], ['a'], ['b'], ['c']];
// Combination user select
var selectedvalues = [];
// Function called on selection or removing value (i.e a,b,c,d)
function selectOption(value){
var checkIndex = selectedvalues.indexof(value);
if(checkIndex == -1){
selectedvalues.push(value);
}else{
selectedvalues.splice(checkIndex, 1);
}
}
// function called on submition of combination
function checkVaildCombination(){
if(preDefinedCombinations.indexOf(selectedvalues) == -1){
alert('Invalid Combination');
}else{
alert('Valid Combination');
}
}
This code gives information only about combination is valid or not, not about which may be possible combinations as per selections.
stolen from https://stackoverflow.com/a/1885660/1029988 :
function intersect_safe(a, b)
{
var ai=0, bi=0;
var result = new Array();
while( ai < a.length && bi < b.length )
{
if (a[ai] < b[bi] ){ ai++; }
else if (a[ai] > b[bi] ){ bi++; }
else /* they're equal */
{
result.push(a[ai]);
ai++;
bi++;
}
}
return result;
}
then in your code:
function checkVaildCombination(){
function get_diff(superset, subset) {
var diff = [];
for (var j = 0; j < superset.length; j++) {
if (subset.indexOf(superset[j]) == -1) { // actual missing bit
diff.push(superset[j]);
}
}
return diff;
}
if(preDefinedCombinations.indexOf(selectedvalues) == -1){
missing_bits = [];
diffed_bits = [];
for (var i = 0; i < preDefinedCombinations.length; i++) {
var intersection = intersect_safe(preDefinedCombinations[i], selectedvalues);
if (intersection.length == selectedvalues.length) { // candidate for valid answer
missing_bits.push(get_diff(preDefinedCombinations[i], intersection));
} else {
var excess_bits = get_diff(selectedvalues, intersection),
missing_bit = get_diff(preDefinedCombinations[i], intersection);
diffed_bits.push({
excess: excess_bits,
missing: missing_bit
});
}
}
var message = 'Invalid Combination, if you select any of these you`ll get a valid combination:\n\n' + missing_bits.toString();
message += '\n\n Alternatively, you can reach a valid combination by deselected some bits and select others:\n';
for (var j = 0; j < diffed_bits.length; j++) {
message += '\ndeselect: ' + diffed_bits[j].excess.toString() + ', select: ' + diffed_bits[j].missing.toString();
}
alert(message);
} else {
alert('Valid Combination');
}
}
you will of course want to format the output string, but that code will (hopefully, it is napkin code after all) give you the missing bits to make valid combos with what you've got selected already
May be following code could help you to solve ur problem
<script>
function validateForm(){
var checkBoxValues = this.a.checked.toString() + this.b.checked.toString() + this.c.checked.toString() + this.d.checked.toString();
if( checkBoxValues == 'truetruetruefalse' || // abc
checkBoxValues == 'truefalsetruetrue' || // acd
checkBoxValues == 'truefalsefalsefalse' || // a
checkBoxValues == 'falsetruefalsefalse' || // b
checkBoxValues == 'falsefalsetruefalse' ){ // c
return true;
}
return false;
}
</script>
<form onsubmit="return validateForm()" action="javascript:alert('valid')">
<input type="checkbox" name="mygroup" id="a">
<input type="checkbox" name="mygroup" id="b">
<input type="checkbox" name="mygroup" id="c">
<input type="checkbox" name="mygroup" id="d">
<input type="submit">
</form>

Loop Over Input Fields; Stop After Two Iterations

I have five form fields that will initially NOT be pre-populated with any values.
If a user fills out one of the fields, the next time they visit the form that field will be pre-populated with the value from the previous visit.
Here's what I'm trying: I'd like to create a loop that iterates through the fields. It will always check to see if there are empty fields. After finding 2 empty fields, the loop will stop and only show those 2 empty fields, while the other fields are hidden.
Here's what I have so far...I just can't figure how to stop after iterating through two fields,
HTML:
<form action="">
<input id="first" type="text" value="" />
<input id="second" type="text" value="" />
<input id="third" type="text" value="" />
<input id="fourth" type="text" value="" />
<input id="fifth" type="text" value="" />
</form>
JS:
$(document).ready(function() {
$('input').hide();
var firstValue = $('input[id="first"]').val(),
secondValue = $('input[id="second"]').val(),
thirdValue = $('input[id="third"]').val(),
fourthValue = $('input[id="fourth"]').val(),
fifthValue = $('input[id="fifth"]').val();
var firstField = $('input[id="first"]'),
secondField = $('input[id="second"]'),
thirdField = $('input[id="third"]'),
fourthField = $('input[id="fourth"]'),
fifthField = $('input[id="fifth"]');
var formValues = [firstValue, secondValue, thirdValue, fourthValue, fifthValue];
var fieldIds = [firstField, secondField, thirdField, fourthField, fifthField];
for (var i = 0; i < fieldIds.length; i++) {
for (var i = 0; i < formValues.length; i++) {
if ( formValues[i] === '' ) {
fieldIds[i].show();
return false;
}
}
}
});
Take all input fields, take the first two empty fields and show them; finally, take the complement of that to hide the rest:
var $inputFields = $('form input:text'),
$emptyFields = $inputFields
.filter(function() { return this.value == ''; })
.slice(0, 2)
.show();
$inputFields
.not($emptyFields)
.hide();
Demo
$(document).ready(function() {
$('input').hide().each( function(){
var index=0; //initilialize the counter
if( $(this).val().length ){ //check for input's length
if(index < 2) {
$(this).show();
index=index+1 //or index++ if you like
}
else {
break;
}
}
}
)};
If you want to include select and textarea fields in your eligible input population, use $(':input').hide().each(...). If you have multiple forms on your page, you would want to include that in your selector, too: $('#intended_form').find(':input').hide().each(...).
http://api.jquery.com/each/
I think that Jack provides the best answer, but this should work too. here, i use a second counter j and break the loop when j % 2 == 0, so at this time its found two empty fields. this is known as a modulus or the modulo operator.
$(document).ready(function() {
$('input').hide();
var firstValue = $('input[id="first"]').val(),
secondValue = $('input[id="second"]').val(),
thirdValue = $('input[id="third"]').val(),
fourthValue = $('input[id="fourth"]').val(),
fifthValue = $('input[id="fifth"]').val();
var firstField = $('input[id="first"]'),
secondField = $('input[id="second"]'),
thirdField = $('input[id="third"]'),
fourthField = $('input[id="fourth"]'),
fifthField = $('input[id="fifth"]');
var formValues = [firstValue, secondValue, thirdValue, fourthValue, fifthValue];
var fieldIds = [firstField, secondField, thirdField, fourthField, fifthField];
var j = 0;
for (var i = 1; i < fieldIds.length; i++) {
if ( formValues[i] === '' ) {
fieldIds[i].show();
j++;//we found an empty field
if (j % 2 == 0)
{
break;
}
}
}
});

Javascript Internet Explorer Issue - what am I doing wrong?

I've looked through many posts to no avail. I have the following in a simple form where one of the products changes based on the number of checkboxes checked. It works in every browser except IE. What am I doing wrong?
<body>
<script type="text/javascript">
function check(){
"use strict";
var count = 0, x=0, checkboxes=document.signup.getElementsByClassName("styled");
for(;x<checkboxes.length; x++){
if(checkboxes[x].checked){
count++;
}
}
if(count<3) {
document.getElementById("variable").value = "1";
}
else if (count == 3){
document.getElementById("variable").value = "74";
}
else if (count == 4){
document.getElementById("variable").value = "75";
}
else if (count == 5){
document.getElementById("variable").value = "76";
}
}
</script>
<form name="signup" id="signup" method="post" action="/subscribers/signup.php">
<input type="checkbox" id="variable" name="product_id[]" value="" class="styled"></input>product 1 - variable</div>
<input type="checkbox" id="same" name="product_id[]" value="3" class="styled"></input>product 2
<input type="checkbox" id="same2" name="product_id[]" value="2" class="styled"></input>product 3
<input type="checkbox" id="same3" name="product_id[]" value="4" class="styled"></input><div class="check-title">product 4
<input type="checkbox" id="same4" name="product_id[]" value="44" class="styled"></input><div class="check-title">product 5
Continue</td></tr>
</form>
</body>
All versions of IE prior to IE9 do not support getElementsByClassName(). You will need to use some sort of substitute.
Instead of this piece of your code:
checkboxes = document.signup.getElementsByClassName("styled");
I would suggest using this:
checkboxes = document.getElementById("signup").getElementsByTagName("input")
getElementsByTagName() is widely support in all versions of IE. This will obviously get all input tags, but only the checkboxes will have checked set so you should be OK.
If you need to filter by class, then you could do the whole thing this way:
function check() {
"use strict";
// initialize checkbox count to 0
var count = 0, item;
// get all input tags in the form
var inputs = document.getElementById("signup").getElementsByTagName("input");
// loop through all input tags in the form
for (var i = 0; i < inputs.length; i++) {
// get this one into the local variable item
item = inputs[i];
// if this input tag has the right classname and is checked, increment the count
if ((item.className.indexOf("styled") != -1) && item.checked) {
count++;
}
}
// get object for result
var obj = document.getElementById("variable");
// check count and set result based on the count
if(count < 3) {
obj.value = "1";
} else if (count == 3) {
obj.value = "74";
} else if (count == 4) {
obj.value = "75";
} else if (count == 5) {
obj.value = "76";
}
}
IE doesnt have method getElementsByClassName... you can try to define it:
if(document.getElementsByClassName == undefined) {
document.getElementsByClassName = function(cl) {
var retnode = [];
var myclass = new RegExp('\\b'+cl+'\\b');
var elem = this.getElementsByTagName('*');
for (var i = 0; i < elem.length; i++) {
var classes = elem[i].className;
if (myclass.test(classes)) {
retnode.push(elem[i]);
}
}
return retnode;
}
};

Categories