Changing css with javascript

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.

echo '<script>function DisplayError(){document.getElementById("divID").style.visibility="visible";} </script>';

What am I missing?

Hi @richarddunnebsc, so where does that function actually get called?

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?

Ah, no you can’t execute browser JS from PHP. You might just include that line w/o the wrapping function at the end of the page, like e.g.

  ...
  <?php if(!isset($_POST['something'])): ?>
    <script>document.getElementById("divID").style.visibility="visible";</script>
  <?php endif; ?>
</body>

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?

But it’s a condition within your PHP code, like

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. :-)

That would work. Doesn’t matter when the div is introduced, the css is already there. How would that be implemented?

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?

Its client-side error reporting. Display error if form field not filled out before submission

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:

HTML

<form id="my-form" novalidate>
  <label>First name: 
    <input type="text" name="firstname" required>
  </label>
  <label>Last name: 
    <input type="text" name="lastname" required>
  </label>
  <div class="error">Please fill the required fields!</div>
  <input type="submit" value="Submit">
</form>

CSS



.error {
  visibility: hidden;
  color: red;
}

JS

// 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:

Wow, there is lot to digest there. Will give it a go. cheers.

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.

Please don’t remove the PHP validation. JavaScript validation cannot be guaranteed to occur, for a wide variety of reasons.

Best practice is to:

  • Rely on PHP validation for protection
  • Use JavaScript validation to improve the user experience by providing feedback before it gets to the server.
1 Like

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:

// ...
if (element.required && form[element.name].value === '') {
  event.preventDefault()
  error.style.visibility = 'visible'
}

PS: What @Paul_Wilkins said.

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.

What am I doing wrong here?

var error = document.querySelector(‘.error’);
var form = document.getElementById(‘formname’);
form.addEventListener(‘Submit’,function(event)
{
if(form[‘fieldname’].value.length != 8)
{
alert();
error.style.visibility = ‘visible’;
}
})

is confusing, should it not be form[elementName].value