Search code examples
htmlcssmaterialize

How can I make a MaterializeCSS Select required?


My problem here is, that my select doesnt send me an error message if nothing is selected, because in this case "Ich bin...", is a disabled option. It doesnt let me complete the registration, which is great, but it doesnt throw an error message...

So now Im asking myself: How can I make my select throw error message when nothing (or in this case "Ich bin...") is selected ?

U can visit the page here: https://projekte.tgm.ac.at/3ahit/smeth/02BREC/Minishop/index.php?site=register

<form action="index.php?site=index_logout" method="post">
  <div class="card-panel z-depth-5">
    <div class="row">
      <h4 class="center">Registrieren</h4>
    </div>
    <div class="row">
      <div class="input-field col s12">
        <input name="username" id="username" type="text" class="validate" required>
        <label for="username">Username</label>
      </div>
      <div class="input-field col s12">
        <input name="password" id="password" type="password" class="validate" required>
        <label for="password">Password</label>
      </div>
      <div class="input-field col s6">
        <input name="first_name" id="first_name" type="text" class="validate" required>
        <label for="first_name">First Name</label>
      </div>
      <div class="input-field col s6">
        <input name="last_name" id="last_name" type="text" class="validate" required>
        <label for="last_name">Last Name</label>
      </div>
      <div class="input-field col s12">
        <select name="gender" id="test" required>
          <option value="" disabled selected>Ich bin...</option>
          <option value="1">männlich</option>
          <option value="2">weiblich</option>
          <option value="3">andere</option>
        </select>
      </div>
      <div class="input-field col s12">
        <input name="birthdate" type="text" class="datepicker" required>
        <label for="birthdate" class="">Birthdate</label>
      </div>
      <div class="input-field col s12">
        <input name="mail" id="email" type="email" class="validate" required>
        <label for="email">Email</label>
      </div>
      <div class="input-field col s12">
         <p>
           <label>
             <input name="newsletter" type="checkbox" class="filled-in" checked="checked" />
             <span>Newsletter</span>
           </label>
         </p>
       </div>
     </div>
     <div class="row">
       <div class="col s12">
         <input type="submit" name="submit" value="Registrieren"
                                    class="btn left col s12 brown lighten-2">                             
       </div>
     </div>
     <div class="row">
       <div class="col s12">
         <p class="center">Sie haben bereits ein Konto?
           <a class="modal-trigger" href="index.php#login">Anmelden</a>
         </p>
       </div>
     </div>
   </div>
 </form>

Solution

  • Achieving what you ask within Materialize is pretty tricky, and requires a hack.

    The reason being, select elements don't share the same validation properties as text inputs. (And as a side note - you should never rely solely on the Materialize validation - it is really only for UX/aesthetics). Materialize actually hides the native select and replaces it with a text input and dropdown.

    The hack:

    To make the select behave like a traditional text input, we can use jQuery to manipulate the dom and insert the validation helper field (taken from the text input documentation - remember text inputs support validation):

    // Create your validation helper text
    var validationMessage = '<span class="helper-text" data-error="Please choose an option"></span>';
    
    // Place it in the dom
    $('.select-wrapper input').after(validationMessage);
    

    Next, the logic. I have replaced your input[type=submit] with a standard button - this is so that we can perform our logic and only submit the form once we're happy. When a select option is chosen (in this case, a dropdown li), a class of slected is added to the li. So, once the submit button is pressed, we check inside the dropdown for any li's (that are not the disabled placeholder option) that have a class of selected, and if not - then we add a class of invalid to the dynamically created text input.

    // Get the dynamically created text input
    
    var select = jQuery('.select-wrapper input')[0];
    
    // Check if any of the dropdown options have a class of selected
    
    $('.submit-btn').on('click',function(){
       if ( jQuery('ul.select-dropdown li:not(.disabled).selected').length < 1 ) {
          $(select).addClass('invalid');
       }          
    });
    

    Codepen here. You should always perform more stringent validation and checks on your forms and especially if the input is going to a database.