Aeseir
Aeseir

Reputation: 8434

How to validate select option for a Materialize dropdown?

I've got a basic select box using materializecss.

<select id="type" name="type" required="required" class="validate">
    <option value="" disabled="true" selected="selected">Choose your option</option>
    <option value="general">General</option>
    <option value="tech">Tech</option>
    <option value="person">Personnel</option>
    <option value="resource">Resourcing</option>
</select>
<label data-error="Select an option">Type of Question</label>

I want the user to select an option before being able to submit the form.

How can I get it to display the data-error for the label if user doesn't select an option?

Upvotes: 6

Views: 18498

Answers (8)

NaN
NaN

Reputation: 9104

Definitive Solution

The problem is actually with the rendered input that replaces the select element. It is irrelevant that this select is hidden or not. The Materialize CSS engine does not verify if your select element is required or has the validate class. I don't know why they didn't put that code I will show you below, but that will solve the problem if you put it in a JavaScript file in your page:

<script>
$(document).ready(function(){
    $('.tooltipped').tooltip(); // dica que aparece quando o usuário põe o mouse em cima do componente
    $('select').formSelect(); // montagem de campos <select> com material design
    // isto corrige o problema de renderização em campos select que exigem validação quando o campo é de preenchimento obrigatório
    const _requiredSelects = $("select[required].validate");
    _requiredSelects.parent().find('input').addClass('validate').attr('required', true)
    .keydown(function($event) { 
        return $event.keyCode == 9;
    });
    _requiredSelects.change(function($event) { 
        const _select = $event.target;
        const _value = $(_select).val();
        const _input = $(_select).parent().find('input');
        _input.removeAttr('readonly', '');
        _input.val(_select.options[_select.options.selectedIndex].label);
        if (_value != '') {
            _input.addClass('valid');
            _input.removeClass('invalid');
        } else {
            _input.addClass('invalid');
            _input.removeClass('valid');
        }
    });
    _requiredSelects.each(function(){
        const _this = $(this);
        const _helper = _this.parent().parent().find('.helper-text');
        if (_helper !== undefined) {
            const _input = _this.parent().find('input');
            _helper.insertAfter(_input);
        }
    });
});
</script>

Upvotes: 0

Poncho
Poncho

Reputation: 182

this worked better for me and JavaScript was not neccesary, just some simple CSS:

select[required]:focus{
    outline: none !important;
}

select[required]{
    display: block;
    padding: 0;
    position: absolute;
    background: transparent;
    color: transparent;
    border: none;
    top: 0;
}

Upvotes: 1

Dave de Jong
Dave de Jong

Reputation: 1025

hemu's answer helped me along with some discussions on the materialize forum. I came up with this solution which integrates nicely. The trick was to position the error label properly and give it it's color:

.select-wrapper label.invalid {
    margin-top: 62px;
    margin-left: -11px;
    color: #F44336;
}

You can find this and some more error placement trickery in the below Fiddle:

http://jsfiddle.net/b8frk03m/6/

Upvotes: 1

Ashwin
Ashwin

Reputation: 431

Piggybacking on a previous answer, I found adding the visibility hidden attribute helped clean things up

  $("select[required]").css({
    display: "block", 
    position: 'absolute',
    visibility: 'hidden'
  })

Upvotes: 2

Imran Saleem
Imran Saleem

Reputation: 380

$("select[required]").css({display: "block", height: 0, padding: 0, width: 0, position: 'absolute'});

Upvotes: 12

hemu
hemu

Reputation: 3261

I faced similar problem. I little search I found an easy solution:

Step 1:

material_select makes your select hidden (display: none). And As mentioned in this post, jQuery validator ignores hidden fields. So as a mentioned workaround, add following before validate method:

$.validator.setDefaults({
       ignore: []
});

$("#yourForm").validate({
        errorClass: "invalid form-error",       
        errorElement : 'div',       
        errorPlacement: function(error, element) {
            error.appendTo( element.parent() );
        }
});

Also note that form-error class is custom class in my css:

.form-error{color: #D8000C;}

Step 2:

Make your select required, which is already applied in this question's select tag. Alternatively you can add your select marking as required: true in rules of validate method. But this is not necessary, if you have added required in your html select tag then that is fine.

That's it. With this, when a form is submitted or $("#yourForm").valid() is called, it will validate your select.

Upvotes: 9

Rhuan
Rhuan

Reputation: 135

$("select[required]").css({display: "inline", height: 0, padding: 0, width: 0});

Upvotes: 1

Sumit Chawria
Sumit Chawria

Reputation: 95

Hope this would be helpful:

$('form').on('submit',function(e){
    $(".error_note").remove();
    var select = $(this).find('select').filter("[required=required]");
    $.each(select , function(index, elm){
        val = $(this).val();    
        target = $(this).closest('.input-field');
        if (typeof target !== "undefined") {
            input_target = target.find('input.select-dropdown');
            if (typeof input_target !== "undefined") {                  
                if(val == '' || val == false || val == 0 || val == null){

                    input_target.css({'border-color':'#EA454B','box-shadow':'0 1px 0 0 #EA454B'});
                    input_target.after('<span class="error_note" style="color: #EA454B;font-size: 12px;">Please select this field.</span>');

                    $('html,body').animate({ scrollTop: $("body").offset().top},'slow' );
                    e.preventDefault();

                }else{
                    input_target.css({'border-color':'#9e9e9e'});
                }

            }
        }           
    });
});

Upvotes: 1

Related Questions