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;
}
}
}
});
Related
I am trying here to add a class and an id to the elements that will be created (div or section) ,
the problem is when I tried to make a variable that contains the elements that will be created but the code didn't work
let numberOfElements = document.getElementsByTagName("input")[0].value;
document.getElementsByTagName("input")[0].onchange = function () {
numberOfElements = document.getElementsByTagName("input")[0].value;
}
///
let theTextInput = document.getElementsByTagName("input")[1].value;
document.getElementsByTagName("input")[1].onchange = function () {
theTextInput = document.getElementsByTagName("input")[1].value
}
let theSubmit = document.getElementsByName("create")[0];
document.forms[0].onsubmit = function (e) {
// stop submitting
e.preventDefault();
};
theSubmit.onclick = function () {
if (document.getElementsByTagName("select")[0].value === "Div") {
for (let i = 1; i <= numberOfElements; i++) {
return document.body.appendChild(document.createElement("div")).innerHTML = theTextInput;;
}
} else if (document.getElementsByTagName("select")[0].value !== "Div"){
for (let i = 1; i <= numberOfElements; i++) {
return document.body.appendChild(document.createElement("section")).innerHTML = theTextInput;;
}
}
};
<body>
<form action="">
<input type="number" name="elements" class="input" placeholder="Number Of Elements" value="1"/>
<input type="text" name="texts" class="input" placeholder="Elements Text" />
<select name="type" class="input" >
<option value="Div">Div</option>
<option value="Section">Section</option>
</select>
<input type="submit" name="create" value="Create" />
<div class="results"></div>
</form>
<!-- /////////// -->
<script src="DOM.js"></script>
</body>
First of all, you can use variable for created element and update whatever property/attribute required on that variable. At the same time remove the return on creating elements to continue create the rest. The return will stop once first element created:
const divElm = document.createElement('div');
Now, you can modify that element as required then add to the DOM:
divElm.innerHTML = theTextInput;
divElm.classList.add('new-class');
document.body.append(divElm);
Your code can be simplified by getting the required number and text values from inputs only when you need to create the elements. The inputs change events aren't required. Just merge the submit and click events into a single one, then add the get required values inside it:
document.forms[0].onsubmit = function (e) {
// stop submitting
e.preventDefault();
const numberOfElements = document.getElementsByTagName("input")[0].value;
const theTextInput = document.getElementsByTagName("input")[1].value;
if (document.getElementsByTagName("select")[0].value === "Div") {
for (let i = 1; i <= numberOfElements; i++) {
const divElm = document.createElement('div');
divElm.innerHTML = theTextInput;
divElm.classList.add('new');
document.body.append(divElm);
}
} else if (document.getElementsByTagName("select")[0].value !== "Div") {
for (let i = 1; i <= numberOfElements; i++) {
// Same code as above but with section
...
}
}
};
Even with that, there's still room for improvement. So, try to split your statements into multiple lines. First, store queried elements into variables/arrays then use them to manipulate the element. That will also reduce the number of times you query/get those elements from the DOM
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/
please be nice. I'm trying to create a page which sets limit and cut the excess (from the specified limit). Example: Limit is 3. then, I'll input abc if I input d it must say that its limit is reached and the abc will remain. My problem is that it just delete my previous input and make new inputs. Hoping for your great cooperation. Thanks.
<html>
<script type="text/javascript">
function disable_btn_limit(btn_name)
{
/* this function is used to disable and enable buttons and textbox*/
if(btn_name == "btn_limit")
{
document.getElementById("btn_limit").disabled = true;
document.getElementById("ctr_limit_txt").disabled = true;
document.getElementById("btn_edit_limit").disabled = false;
}
if(btn_name == "btn_edit_limit")
{
document.getElementById("btn_limit").disabled = false;
document.getElementById("ctr_limit_txt").disabled = false;
document.getElementById("btn_edit_limit").disabled = true;
}
}
function check_content(txtarea_content)
{
/*This function is used to check the content*/
// initialize an array
var txtArr = new Array();
//array assignment
//.split(delimiter) function of JS is used to separate
//values according to groups; delimiter can be ;,| and etc
txtArr = txtarea_content.split("");
var newcontent = "";
var momo = new Array();
var trimmedcontent = "";
var re = 0;
var etoits;
var etoits2;
//for..in is a looping statement for Arrays in JS. This is similar to foreach in C#
//Syntax: for(index in arr_containter) {}
for(ind_val in txtArr)
{
var bool_check = check_if_Number(txtArr[ind_val])
if(bool_check == true)
{
//DO NOTHING
}
else
{
//trim_content(newcontent);
newcontent += txtArr[ind_val];
momo[ind_val] = txtArr[ind_val];
}
}
var isapa = new Array();
var s;
re = trim_content(newcontent);
for(var x = 0; x < re - 1; x++){
document.getElementById("txtarea_content").value += momo[x];
document.getElementById("txtarea_content").value = "";
}
}
function trim_content(ContentVal)
{
//This function is used to determine length of content
//parseInt(value) is used to change String values to Integer data types.
//Please note that all value coming from diplay are all in String data Type
var limit_char =parseInt(document.getElementById("ctr_limit_txt").value);
var eto;
if(ContentVal.length > (limit_char-1))
{
alert("Length is greater than the value specified above: " +limit_char);
eto = limit_char ;
etoits = document.getElementById("txtarea_content").value;
//document.getElementById("txtarea_content").value = "etoits";
return eto;
//for(var me = 0; me < limit_char; me++)
//{document.getElementById("txtarea_content").value = "";}
}
return 0;
}
function check_if_Number(ContentVal)
{
//This function is used to check if a value is a number or not
//isNaN, case sensitive, JS function used to determine if the values are
//numbers or not. TRUE = not a number, FALSE = number
if(isNaN(ContentVal))
{
return false;
}
else
{ alert("Input characters only!");
return true;
}
}
</script>
<table>
<tr>
<td>
<input type="text" name="ctr_limit_txt" id="ctr_limit_txt"/>
</td>
<td>
<input type="button" name="btn_limit" id="btn_limit" value="Set Limit" onClick="javascript:disable_btn_limit('btn_limit');"/>
</td>
<td>
<input type="button" name="btn_edit_limit" id="btn_edit_limit" value="Edit Limit" disabled="true" onClick="javascript:disable_btn_limit('btn_edit_limit');"/>
</td>
</tr>
<tr>
<td colspan="2">
<textarea name="txtarea_content" id="txtarea_content" onKeyPress="javascript:check_content(this.value);"></textarea>
<br>
*Please note that you cannot include <br>numbers inside the text area
</td>
</tr>
</html>
Try this. If the condition is satisfied return true, otherwise return false.
<html>
<head>
<script type="text/javascript">
function check_content(){
var text = document.getElementById("txtarea_content").value;
if(text.length >= 3){
alert('Length should not be greater than 3');
return false;
} else {
return true;
}
}
</script>
</head>
<body>
<div>
<textarea name="txtarea_content" id="txtarea_content" onkeypress=" return check_content();"></textarea>
</div>
</body>
</html>
Instead of removing the extra character from the text area, you can prevent the character from being written in the first place
function check_content(event) { //PARAMETER is the event NOT the content
txtarea_content = document.getElementById("txtarea_content").value; //Get the content
[...]
re = trim_content(newcontent);
if (re > 0) {
event.preventDefault(); // in case the content exceeds the limit, prevent defaultaction ie write the extra character
}
/*for (var x = 0; x < re - 1; x++) {
document.getElementById("txtarea_content").value += momo[x];
document.getElementById("txtarea_content").value = "";
}*/
}
And in the HTML (parameter is the event):
<textarea ... onKeyPress="javascript:check_content(event);"></textarea>
Try replacing with this:
for(var x = 0; x < re - 6; x++){
document.getElementById("txtarea_content").value += momo[x];
document.getElementById("txtarea_content").value = "";
}
Any reason why the maxlength attribute on a text input wouldn't work for so few characters? In your case, you would have:
<input type="text" maxlength="3" />
or if HTML5, you could still use a textarea:
<textarea maxlength="3"> ...
And then just have a label that indicates a three-character limit on any input.
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;
}
};
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]);
}
}
}