If a field is empty on form submission, I want to display a div by changing its display or visibility. I am doing this from php so this code is in and echo statement.
Great question. I’m familiar with calling Javascript functions from html events like onclick etc. However I’m calling the function after the form is submitted from PHP, so that is new to me. My initial misunderstanding was to try and call a function like any other php function, wrong, then I saw a post where Javascript is called using echo, so if isset() is false, echo ‘javascript’; I can execute an alert() this way, but hitting a wall trying to change css. Where do I call the function?
so that it executes right away when the page is loaded. But wouldn’t it be simpler to just set a style attribute on the element in question? Something like
echo '<div' . (isset($_POST['something']) ? '' : ' style="visibility: visible;"') . '>This field is required</div>';
Or actually, only add this element when the condition is met in the first place? ^^
I have an empty div which is hidden, however the echo seems to be overriding that because the div is visible on page load, not what I want. You don’t have an id or class associated with the div, how is it supposed to know which div to show once the condition is met?
if (!isset(/* something */)) {
echo '<script>/* ... */</script>';
}
Right? So why not simply include the div only when that condition is met, rather than including a script to show the otherwise hidden div? Maybe I misunderstood what you’re trying to achieve though… in this case I’d say best would be to give us more code for some context. :-)
Sorry I’m a bit confused. Is this div supposed to be shown after client-side or server-side validation? I.e. before submitting the form, or after the (incomplete) form has been sent to the server? Or is there some AJAX involved?
Ah ok sorry I really misunderstood you… was a bit late for me yesterday. ^^ Then you’d indeed have to add your script (unconditionally) to your page; you’ll have to add an event listener to the form, and on submit check if all fields are valid. If they are not, show that error field. Here’s a minimal form validation, maybe it will give you a starting point:
// Get a reference to the form and the error field
var form = document.getElementById('my-form')
var error = document.querySelector('.error')
// When the form is about to get submitted,
// do the validation
form.addEventListener('submit', function (event) {
// Iterate over the input elements
Array.from(form.elements).forEach(function(element) {
// Check if the current input element is required
// and has no value
if (element.required && element.value.trim() === '') {
// If so, prevent the default event (which would be
// submitting the form)
event.preventDefault()
// And show the error message
error.style.visibility = 'visible'
}
})
})
You might also show specific error messages for each field like so:
HTML
<form id="my-form" novalidate>
<label>First name:
<input type="text" name="firstname" required>
<div class="error">Please enter your first name!</div>
</label>
<label>Last name:
<input type="text" name="lastname" required>
<div class="error">Please enter your last name!</div>
</label>
<input type="submit" value="Submit">
</form>
// Get a reference to the form
var form = document.getElementById('my-form')
// When the form is about to get submitted,
// do some validation
form.addEventListener('submit', function (event) {
// Iterate over the input elements
Array.from(form.elements).forEach(function(element) {
// Check if it is required and not filled
if (element.required && element.value.trim() === '') {
// Prevent the form submission
event.preventDefault()
// Show the error message (which is just the adjacent
// sibling here to keep it simple)
element.nextElementSibling.style.visibility = 'visible'
} else {
// Otherwise hide it (in case it was previously shown)
element.nextElementSibling.style.display = 'hidden'
}
})
})
Note the novalidate attributes on the <form> tags; it tells the browser that you’re going to perform your own validation, rather than relying on native error messages. Of course, the browser validation is also quite capable by itself, and you can do a lot with just CSS pseudo-classes like :required and :invalid… alternatively, you can even directly access the validation API with your own JS. Here’s a very thorough article on that topic on the MDN:
All my validation is post submission in php. Going to change it to pre-submission with js. One of my forms has two radio buttons and a text field. I want to target both, that they are filled in, but I also want to do format checking on the text field. I can’t do the format checking with forEach(). The required attribute won’t work on the radio buttons, they both can’t be selected. I need to check that one or the other is selected.
The problem is that radios always have a value, so you need a different approach here (you’d still have to add a required attribute to at least one of them though). One possibility would be to go by the corresponding name property of the form, and see if this has a value:
you’d still have to add a required attribute to at least one of them though
Not necessarily. If neither are selected, show error msg. With radio buttons its either or, a choice. Not with text inputs. It just occurred to me that since a radio button is required and to me it makes no sense to require one of them and it won’t always the the one selected, I could use a hidden checkbox, and check it when one of the radio buttons is selected. I can make the checkbox required. Would that not solve the issue?
If you have a required attribute on a radio button, it just means you have to select one of the radios with the same name. You can also mark all of them required, that makes no difference; both the built-in HTML5 validation and my snippet above will handle this correctly. ;-) No need for checkbox-hacks here…
Since require takes care of ensuring fields are filled out before submission, for the event handler, is there a way of focusing on one field to do input format validation, leaving out forEach()?
You can get references to specific elements with usual CSS selectors using .querySelector(); form input elements specifically can also be accessed like myForm.elements['nameOfInput'] (or just myForm['nameOfInput']), as used above for the radio value.