Simple form validation help "Cannot read property 'elements' of undefined" - javascript

newbie here, im trying to figure out why i get "Cannot read property 'elements' of undefined ".
javascript:
function conf()
{
for (i=0; i<5; i++)
{
box = document.project.elements[i];
if (!box.value)
{
alert('You haven\'t filled in ' + box.name + '!');
return false
}
}
return true;
}
html:
<form id="project" onsubmit="return conf()" action="#">
<fieldset>
<legend>Contact Details</legend>
<label for="txtname">Your Name:</label> <input type="text" class="text" name="txtname" id="1" /><br/>
<label for="txtemail">Email:</label> <input type="text" class="text" name="txtemail" id="2"/><br/>
<label for="txtartist">Artist:</label> <input type="text" class="text" name="txtartist" id="3"/><br/>
<label for="txtalbum">Song / Album:</label> <input type="text" class="text" name="txtalbum" id="4"/><br/>
<label for="txtcomments">Comments:</label> <textarea class="ta" name="txtcomments" id="txtcomments" cols="30" rows="20"></textarea><br/>
<input type="submit" class="buttons" id="btnSubmit" name="btnsubmit" value="Send Enquiry"/>
</fieldset>
</form>

To get at the form elements you need to use the form id,
document.getElementById('project').elements[i];
a better approach would be use the document.querySelectorAll() and get the elements you are interested in, which would be in this case,
document.querySelectorAll('#project input[type="text"], textarea')
which gives you an array of elements that you could loop through and perform the checks.
BTW, you will probably sooner or later start needing individual checks for each of the inputs. One approach to this would be use the new HTML5 input types.

The approach you have tried should work, since forms with an ID are made named properties of the document object. Perhaps you have another element with a name or id of project.
If the form is the only element with a name or ID of project, you write, formally:
document.forms.project.elements...
or shorter:
document.project.elements...
But that issue can be avoided. Since you have a submit listener on the form, you can pass a reference to the form directly by passing this:
<form id="project" onsubmit="return conf(this)" action="#">
And within the function (don't forget to declare variables!!):
function conf(form)
{
var box;
for (var i=0; i<5; i++) {
box = form.elements[i];
if (!box.value) {
alert('You haven\'t filled in ' + box.name + '!');
return false
}
}
return true;
}
Now you can change the form ID to anything (or remove it) and the function still works.
Also, the label element is associated with a form control by ID, not by name so:
<label for="txtalbum">Song / Album:</label> <input ... name="txtalbum" id="4">
should be:
<label for="4">Song / Album:</label> <input ... name="txtalbum" id="4">
Otherwise the label will not be associated with the element (and therefore may as well be a span or similar and not have a for attribute).
Lastly, please don't use XML syntax in an HTML document. In an HTML document, the / in <br /> and <input ... /> is simply ignored.

Related

JS input validation submit disabled for separate instances

I need each instance of input and submit to operate independently. What is the best way to handle multiple instances where each submit is connected to it's own set of inputs?
Since they are unrelated, would data-attributes be the best solution?
$(document).ready(function() {
validate();
$('input').on('keyup', validate);
});
function validate() {
var inputsWithValues = 0;
var myInputs = $("input:not([type='submit'])");
myInputs.each(function(e) {
if ($(this).val()) {
inputsWithValues += 1;
}
});
if (inputsWithValues == myInputs.length) {
$("input[type=submit]").prop("disabled", false);
} else {
$("input[type=submit]").prop("disabled", true);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item1">
<div><input type="text" name="name" autocomplete="off" required/></div>
<input type="submit" value="Submit 1" />
</div>
<div class="item2">
<div><input type="text" name="name" autocomplete="off" required/></div>
<div><input type="text" name="name" autocomplete="off" required/></div>
<input type="submit" value="Submit 2" />
</div>
I think your intuition about using data attributes works great here.
var allButtons = document.querySelectorAll("input[type=submit]");
allButtons.forEach(button => {
button.addEventListener("click", () => {
var inputSet = button.getAttribute("data-input-set");
var inputs = document.querySelectorAll("input[type='text'][data-input-set='" + inputSet + "']");
});
});
In the following code, when an input button is pressed, it will fetch all the inputs with the corresponding "input-set" tag.
Preferred way
I think best solution would be use form -tag as it is created for just this use case HTML Forms.
<form id="form-1">
<input type="text"/>
<input type="submit>
</form>
<form id="form-2">
<input type="text"/>
<input type="submit>
</form>
You can also bind custom Form on submit event handlers and collect form data this way.
$('#form-1').on('submit', function(event){
event.preventDefault(); // Prevent sending form as defaulted by browser
/* Do something with form */
});
Possible but more bolt on method
Alternative methods to this would be to create your own function's for collecting all relevant data from inputs and merge some resonable data object.
I would most likely do this with giving desired class -attribute all inputs I would like to collect at once eg. <input type="text" class="submit-1" /> and so on. Get all elements with given class, loop through all them and save values into object.
This requires much more work tho and form -tag gives you some nice validation out of the box which you this way have to do yourself.

Set form names with javascript loop

I have a form with which a user can dynamically add text inputs. This generates a form with multiple text inputs that have the same name. If this form is submitted they overwrite each other. To solve this I need change the names so that they are appended with an incremented prefix when the form is submitted. Can anyone help?
Example of form (once three inputs have been added):
<form action="" method="post">
<td class="recipe-table__cell">
<input id="answer" name="the_answer" type="text" value="" >
<input id="answer" name="the_answer" type="text" value="" >
<input id="answer" name="the_answer" type="text" value="" >
</td>
<input type="submit" value="Submit">
</form>
Desired Post output on submission:
Array ( [1-answer] => test [2-answer] => ok [3-answer] => nice)
rather than Array ( [answer] => test )
First, select all of the elements that you want to add the attribute for. This can be done with .querySelectorAll().
Second, loop over those elements.
Third, use .setAttribute() to change the name attribute to append the index from the loop.
Note that you'll also want to increment the ID attribute, as you can't have duplicate IDs on the same page. You'll also want to swap your <td> elements for <div> elements to both allow .querySelectAll() to work correctly, and ensure valid markup.
This can be seen in the following example:
var inputs = document.querySelectorAll("form div input");
for (var i = 0; i < inputs.length; i++) {
inputs[i].setAttribute("id", "answer" + i);
inputs[i].setAttribute("name", "the_answer" + i);
console.log(inputs[i]); // Added purely to show the change
}
<form action="" method="post">
<div class="recipe-table__cell">
<input id="answer" name="the_answer" type="text" value="">
<input id="answer" name="the_answer" type="text" value="">
<input id="answer" name="the_answer" type="text" value="">
</div>
<input type="submit" value="Submit">
</form>
Hope this helps! :)

Using isset from a name of an input

I am not sure if I am going about this correctly. I have a set of checkbox inputs. If someone selects the last check box all_users_check, I want a new form to appear where I will be listing all of the users in a drop down (haven't added the drop down yet). I thought I could do this by using the name of the input, but I am mistaken apparently as I am getting this error..
How else could I structure what I am doing so that if someone checks that option the new form displays?
<div class="user_dropdown">
<form action="">
<input type="checkbox" name="spectator_check" value=""> Spectators<br>
<input type="checkbox" name="member_check" value="" checked> Team Members<br>
<input type="checkbox" name="commissioner_check" value="" checked> Commissioner(s)<br>
<label for="all_users_check">
<input type="checkbox" name="all_users_check" value="" checked> Individual User<br>
</label>
</form>
</div>
<script>
$(".user_dropdown").hide();
$(".all_users_check").click(function() {
if($(this).is(":checked")) {
$(".user_dropdown").show();
} else {
$(".user_dropdown").hide();
}
});
</script>
This is how the page looks on load. Those fields are already checked for some reason.
Issues in your code.
.all_users_check that is looking for a class. Your element doesn't have a class so this isn't found. You can use a different selector to use the name attribute, https://api.jquery.com/attribute-equals-selector/.
This $(".user_dropdown").hide(); hides your whole form. You might want to move around your divs, or remove that altogether.
The checked attribute checks the field it is on. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
Use the checked attribute to indicate whether this item is selected
<div class="user_dropdown">
<form>
<input type="checkbox" name="spectator_check" value=""> Spectators<br>
<input type="checkbox" name="member_check" value=""> Team Members<br>
<input type="checkbox" name="commissioner_check" value=""> Commissioner(s)<br>
<label for="all_users_check">
<input type="checkbox" name="all_users_check" value=""> Individual User<br>
</label>
</form>
</div>
<script>
//$(".user_dropdown").hide();
$("input[name='all_users_check']").click(function() {
if($(this).is(":checked")) {
$(".user_dropdown").show();
} else {
$(".user_dropdown").hide();
}
});
</script>
isset is a language construct and can't accept anything other than a variable as indicated by this warning on the linked to manual page:
Warning isset() only works with variables as passing anything else will result in a parse error.
You are not passing in a variable to the isset function, you are passing in a constant value, basically an array with a single string all_users_check. This is not a variable because you are not assigning it to a variable name. Try this instead:
if(isset($_POST['all_users_check']))
Here the variable being passed in is the superglobal $_POST, and you are checking to see if the index all_users_check is set inside of that array.
Update
To check if an input is empty or not via javascript, take a look at this question.
Try using this script, you have set the state of check boxes as checked by default.
<div class="user_dropdown">
<form action="">
<input type="checkbox" name="spectator_check" value=""> Spectators<br>
<input type="checkbox" name="member_check" value=""> Team Members<br><!-- removed 'checked' from this line -->
<input type="checkbox" name="commissioner_check" value=""> Commissioner(s)<br><!-- removed 'checked' from this line -->
<label for="all_users_check">
<input type="checkbox" name="all_users_check" value="" > Individual User<br> <!-- removed 'checked' from this line -->
</label>
</form>
</div>
<script>
$(".user_dropdown").hide();
$(".all_users_check").click(function() {
if($(this).is(":checked")) {
$(".user_dropdown").show();
} else {
$(".user_dropdown").hide();
}
});
</script>
For the other issue of showing the hidden section again, try whether class all_users_check is visible to click.

Text field to Hidden field value - value not being set

I'm having an issue with passing hidden values. I have a search field that onclick calls my javascript function with the intention of setting a hidden fields value further down the page.
<div class="search">
<input type="text" name="username" class="mySearch" value="">
<input type="button" class="myButton" value="" onclick="setSearch();">
</div>
My javascript, i is set outside of the function.
setSearch(){
if(i == 0){
$('input:hidden[name="search1"]').val($(".mySearch").val());
}
else if(i == 1)
{
$('input:hidden[name="search2"]').val($(".mySearch").val());
}
i++;
}
and then the field I'm try to set
<div class="sendallHolder">
<form method="post" action="getTweets.php">
<input type="hidden" name="fromTest" id="fromTest"/>
<input type="hidden" name="untilTest" id="untilTest"/>
<input type="hidden" name="latTest" id="latTest"/>
<input type="hidden" name="longTest" id="longTest"/>
<input type="hidden" name="search1" id="search1" />
<input type="hidden" name="search2" id="search2" />
<input type="submit" class="sendAll" value="Gather News!">
</form>
</div>
It runs through the loop twice but each time its not setting the values properly in my hidden fields. the dev tools in chrome tell me that the 'value' is popping up but no value is being set. I'm not entirely sure what I'm doing wrong.
Any ideas?
The :hidden selector doesn't do what you think. It matches elements that have been hidden using CSS, it doesn't match type="hidden" inputs. Just use
$("#search1")
since you have an id on the elements.
Use hidden input ID like this :
$('#search1').val($(".mySearch").val())
$(".mySearch").keyup(addhjc);
function addhjc(){
$('#search2').val($(".mySearch").val());
}
or
$('.myButton').click(function(){
$('#search2').val($(".mySearch").val());
});
also
function setSearch(){
if(i === 0){........
and define i var

How to validate form fields on its default values using serializeArray().?

Have a basic registration form, trying to validate it.
I am using form serializeArray() method and loop trough the form and find if the values are null.
HTML CODE
<form name="reg" id="regform">
<fieldset>
<label for="firstname">First Name</label>
<input type="text" name="firstname" value="First Name"/>
</fieldset>
<fieldset>
<label for="lastname">Last name</label>
<input type="text" name="lastname" value="Last Name"/>
</fieldset>
<fieldset>
<label for="date">Age</label>
<input type="text" name="age"/>
</fieldset>
</form>
JQUERY Code
var formElements = $("#regform").serializeArray();
$(formElements).each(function(x)
{
if(formElements[x]["value"] == "")
{
$("[name='" + formElements[x]['name'] +"']").addClass('error');
}
});
From the above code i am able to add the class ".error" when the value is null.
Now i want the code to check the text fields values are not the default values like in my case the default values are "First Name" "Last Name"..
So i want to check even for the default values and add error class to respective element and even focus back the cursor on the first null value text field
Thanks in advance
I highly suggest using http://docs.jquery.com/Plugins/Validation. You can test for various things, such as blank values, and even extend it to detect default values.
For example:
$.validator.addMethod("name", function(value) {
return value != "First Name";
}, 'Please enter your first name.');
Alternatively you can just test against a default value with jQuery's data() function:
Working Demo: http://jsfiddle.net/WpQ2n/2/
var input = $(".name"),
defaultval = input.data("default", input.val());
// Can't submit forms in jsfid, so i just used a click event.
// Change to .submit()
$("input[type='submit']").on("click",function(e){
if(input.val()== input.data("default")){
input.addClass("error");
}
else{
// Yay it validated...
input.removeClass("error");
}
e.preventDefault();
});

Categories