Skip to content
jmarceli edited this page Mar 31, 2015 · 12 revisions

Select2 validation on submit

To enable the validation of select2 inputs on form Submission add the following to your javascript after requiring rails.validations

ClientSideValidations.selectors.validate_inputs += ', .select2-container:visible + :enabled[data-validate]';
ClientSideValidations.selectors.inputs += ', .select2-container:visible + :enabled[data-validate]';

It is just validation after form submission. Simple but not "live".

Possible implementation complete Select2 integration

Full live (client side) validation, "developed" to use with simple_form and foundation markup (should work in other cases too).

Create separate .coffee file e.g. client_side_select2.js.coffee with following code:

    # Add select2 support
    ClientSideValidations.selectors.validate_inputs += ', select[data-validate]'
    ClientSideValidations.selectors.inputs += ', .select2-container'

    getSelect2 = (element) ->
      $(element).parent().find('select')

    $.fn.base = window.ClientSideValidations.enablers.input

    window.ClientSideValidations.enablers.input = (element) ->
      extend = ->
        unless $(element).hasClass 'select2-container'
          $.fn.base(element)
        else
          $placeholder = $(element)
          $select = $placeholder.parent().find('select')
          form   = $select[0].form
          $form  = $(form)

          if $select.attr('data-validate')
            # only focus event should be handled by placeholder
            $placeholder.on(event, binding) for event, binding of {
              'focusout.ClientSideValidations': ->
                getSelect2(@).isValid(form.ClientSideValidations.settings.validators)
            }
            $select.on(event, binding) for event, binding of {
              'change.ClientSideValidations':   -> getSelect2(@).data('changed', true)
              # Callbacks
              'element:validate:after.ClientSideValidations':  (eventData) -> ClientSideValidations.callbacks.element.after(getSelect2(@),  eventData)
              'element:validate:before.ClientSideValidations': (eventData) -> ClientSideValidations.callbacks.element.before(getSelect2(@), eventData)
              'element:validate:fail.ClientSideValidations':   (eventData, message) ->
                element = $(@)
                ClientSideValidations.callbacks.element.fail(element, message, ->
                  form.ClientSideValidations.addError(element, message)
                , eventData)
              'element:validate:pass.ClientSideValidations':   (eventData) ->
                element = $(@)
                ClientSideValidations.callbacks.element.pass(element, ->
                  form.ClientSideValidations.removeError(element)
                , eventData)
            }
      extend()

Require this file after rails.validations in your appplication.js.coffee e.g.:

    #= require rails.validations
    #= require client_side_select2

Now add data-validate="true" attribute to your select2 select element to get the following markup:

    <select data-select2-select="true" data-validate="true" style="display: none;">
      <option value="">Default option</option>
      <option value="1">Option 1</option>
      ... other options ...
    </select>

    <span class="select2 select2-container select2-container--default" dir="ltr" style="width: 291px;">
    ... rest of the select2 markup ...
    </span>

Now everything should work.

Good luck.

I suppose that support for select2 without validation might be an issue with the code above, but I'm not sure.