martincarlin87
martincarlin87

Reputation: 11042

jQuery select2 Form Validation Bug

In my projects I make use of the select2 plugin extensively but one problem I've had is a bug that affects my form validation logic.

var valid = 1;

$('form .required').each(function() {
    if ($(this).val() == '') {
        $(this).parents('.form-group').addClass('has-error');
        valid = 0;
    } else {
        $(this).parents('.form-group').removeClass('has-error');
    }

    console.log($(this))
    console.log($(this).val())
});

This works for non select2 form elements but select's initialised with select2 are incorrectly marked as invalid.

e.g. from the debugging from the above, the select2 div is causing the error because it has no value but the actual dropdown is fine but I didn't expect this to happen because div's don't have a value attribute.

div#s2id_select2.select2-container.form-control.required.select2-allowclear
// no value

select#select2.form-control.required.select2-offscreen
// correct value

An easy way around this is to have a specific check for select2 initialised drop-downs but I am hoping to avoid that so that I can use my more generic approach without having to worry about individual cases.

Upvotes: 0

Views: 617

Answers (2)

John S
John S

Reputation: 21482

With Select2 4.0, the .val() function is supposed to work the way you want it to, but Select2 4.0 is still in beta at this time. Also, it is not backwards compatible with previous versions.

With an older version of Select2, you will have to perform a different check for Select2 elements than for the other elements. You can check $(this).data('select2') to see if an element is instrumented with Select2. (It will not be undefined if the element is a Select2 element.) If the element is a Select2 element, you can use $(this).select2('val') to see if it has a value. That function returns a string for a single select and an array for a multiple select.

function isFieldEmpty(field) {
    var $field = $(field);
    if ($field.data('select2')) {
        var val = $field.select2('val');
        return $.isArray(val) ? (val.length == 0) : (val == '');
    }
    return ($field.val() == '');
}

var valid = 1;

$('form .required').each(function() {
    if (isFieldEmpty(this)) {
        $(this).parents('.form-group').addClass('has-error');
        valid = 0;
    } else {
        $(this).parents('.form-group').removeClass('has-error');
    }
});

Upvotes: 1

martincarlin87
martincarlin87

Reputation: 11042

One way that I've just found after posting the question is to update the selector like so:

$('.create_form .required').not('.select2-container').each(function() {

but maybe there is a more elegant approach.

Upvotes: 0

Related Questions