So I am working on a conditional Shopify form which I inherited from another dev. Basically, it is using JavaScript/Jquery to validate fields and ensure that all required fields are filled out before going onto the next step. With a little doctoring, I got the validation working as intended but am having one problem. The issue is, because of the way the form is being setup to render conditionally, there are inputs set to style="display:none;" with JavaScript that get submitted blank. This is confusing, so I set up the following function:
$("body").on("click", "submit_button", function(){
var elements = document.getElementsByTagName("input")
for (var i = 0; i <= elements.length; i++) {
if(elements[i].value == "" ) {
elements[i].remove()
}
}
})
This works fine and dandy, but there is always one input left that is submitted blank which is fine, but not ideal.
I have double checked to make sure that the element that is submitting blank is indeed an input element (it is). I also originally set the loop up so that the for statement is as follows and saw the same result:
for (var i = 0; i < elements.length; i++) {
Any ideas on why I’m left with one blank field on submission? Thanks for the help!
2
Answers
You have jQuery. You should use it.
You may have a form field in there that isn’t an
input
– the three main types of form elements areinput
,select
andtextarea
. In your selector, you are only looking forinput
fields, so my guess is that the blank is coming from either aselect
ortextarea
that’s also in the form.Alternatively, your code may be breaking because you are
.remove()
‘ing elements from an array as you are iterating over it. This causes the array to change length as you are looping through it, which may cause you to skip over elements as their indices change.Assuming that you only care about input fields that are actually in the form being submitted, there are some interesting features of forms and form elements that you can take advantage of here without using any additional selectors (jQuery or otherwise) for a bit of a performance boost.
Every form element knows about the form it belongs to (
<Element>.form
) and every form knows about all of the form elements it contains. In fact,<Form>.length
returns the number of such form elements (inputs, selects and textareas, as well as fieldsets, etc.), and<Form>[i]
will give you the form element in thei
th position (ifi
is an integer – so an array lookup) or all elements that have the namei
(ifi
is a string – like accessing properties in an object)Secondly, you can prevent sending data by either removing an element completely or by simply clearing the
name
property from the field. If we create a loop over the form’s elements we can avoid problems with changing array indices by setting blank elements to have a blankname
attribute. (If we really want to axe the element though, we could also iterate through the array starting at index(length - 1)
and finishing on index0
– that way the changing indices only affect elements we’ve already checked)Which is a bit of a long way to say that you can do something like this: