ZCT
ZCT

Reputation: 329

jquery-validator cannot validate semantic-ui dropdowns

I am trying to use jquery-validator to validate a form that uses the semantic-ui dropdown() function to transform a select element into a searchable text box. The issue I am having is jquery-validator doesn't notice that the select has been populated until after you click somewhere near the error message. I think it should probably validate when the field changes or when it loses focus in addition to when there is a click.

$(function() {
  $('#identifier').dropdown({
    forceSelection: false
  });
  $.validator.setDefaults({
    debug: true,
    //jquery-validator has a panic attack about the search element not having a name tag.
    ignore: ".search",
    submitHandler: function() {
      //$.blockUI({message: '<div id="parent"><div id="loaderIcon" class="loader"></div><div id="loaderText" >Working on it....</div></div>'});
      return false;
    }
  });
  $("#ticketform").validate({
    rules: {
      identifier: "required"
    },
    messages: {
      identifier: "Please select an IP address"
    },
    errorPlacement: function(error, element) {
      error.addClass("ui red pointing label transition");
      error.insertAfter(element.closest('.ui.input'));
    },
    highlight: function(element, errorClass, validClass) {
      alert("isError");
      //$(element).parents(".row").addClass(errorClass);
    },
    unhighlight: function(element, errorClass, validClass) {
      alert("isValid");
      //$(element).parents(".row").removeClass(errorClass);
    }
  });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.js"></script>

<div class="ui grid sem">
  <div class="four wide column"></div>
  <div class="eight wide column">
    <div class="ui secondary segment">
      <form id="ticketform" name="ticketform" action="open_ticket.php" method="post" class="ui grid form" style="padding: 10px">
        <input type="hidden" name="action" value="submit">
        <div class="row field">
          <label class="six wide column" for="identifier">Please Select an IP address</label>
          <div class="eight wide column">
            <div class="ui input">
              <select name="identifier" class="ui fluid search selection dropdown" id="identifier">
                <option value="" selected>Please choose...</option>
                <option value="4.4.4.4">4.4.4.4</option>
                <option value="8.8.8.8">8.8.8.8</option>
              </select>
            </div>
          </div>
        </div>
        <div class="row">
          <label class="six wide column"></label>
          <div class="eight wide column">
            <input id="button" type="submit" name="btnsubmit" value="Submit ticket" class="uibutton normal">
          </div>
        </div>
      </form>
    </div>
  </div>
</div>
<div class="four wide column"></div>

Upvotes: 0

Views: 1022

Answers (1)

Sparky
Sparky

Reputation: 98748

That's because the Semantic UI plugin is replacing the select with its own constructed element. Therefore the user is no longer interacting with something that the jQuery Validate plugin is watching. When you click outside of the element however, you are triggering the Validate plugin's default onfocusout handler; the element is re-validated and error clears.

The solution is to construct your own event handler that programmatically triggers validation whenever the select is changed.

$('[name="identifier"]').on('change', function() {
    $(this).valid(); // force validation
});

$(function() {

  $('#identifier').dropdown({
    forceSelection: false
  });

  $.validator.setDefaults({
    debug: true,
    //jquery-validator has a panic attack about the search element not having a name tag.
    ignore: ".search",
    submitHandler: function() {
      //$.blockUI({message: '<div id="parent"><div id="loaderIcon" class="loader"></div><div id="loaderText" >Working on it....</div></div>'});
      return false;
    }
  });

  $("#ticketform").validate({
    rules: {
      identifier: "required"
    },
    messages: {
      identifier: "Please select an IP address"
    },
    errorPlacement: function(error, element) {
      error.addClass("ui red pointing label transition");
      error.insertAfter(element.closest('.ui.input'));
    },
    highlight: function(element, errorClass, validClass) {
      alert("isError");
      //$(element).parents(".row").addClass(errorClass);
    },
    unhighlight: function(element, errorClass, validClass) {
      alert("isValid");
      //$(element).parents(".row").removeClass(errorClass);
    }
  });

  $('[name="identifier"]').on('change', function() {
    $(this).valid(); // force validation
  });

});
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.js"></script>

<div class="ui grid sem">
  <div class="four wide column"></div>
  <div class="eight wide column">
    <div class="ui secondary segment">
      <form id="ticketform" name="ticketform" action="open_ticket.php" method="post" class="ui grid form" style="padding: 10px">
        <input type="hidden" name="action" value="submit">
        <div class="row field">
          <label class="six wide column" for="identifier">Please Select an IP address</label>
          <div class="eight wide column">
            <div class="ui input">
              <select name="identifier" class="ui fluid search selection dropdown" id="identifier">
                <option value="" selected>Please choose...</option>
                <option value="4.4.4.4">4.4.4.4</option>
                <option value="8.8.8.8">8.8.8.8</option>
              </select>
            </div>
          </div>
        </div>
        <div class="row">
          <label class="six wide column"></label>
          <div class="eight wide column">
            <input id="button" type="submit" name="btnsubmit" value="Submit ticket" class="uibutton normal">
          </div>
        </div>
      </form>
    </div>
  </div>
</div>
<div class="four wide column"></div>

Upvotes: 1

Related Questions