I am trying to validate this form. I want to make sure the user selects at least 1 user and enters something in the body. The form uses a select2 field and a summernote
textarea. What am I doing wrong?
The Form:
<form id="ShareThisForm" method="post">
<div class="modal fade" id="Share" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light"><i class="fas fa-share-alt mr-1"></i>Share to</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body p-3">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="fas fa-user mr-2"></i>Users
</span>
</div>
<select class="form-control select2bs4 select2-hidden-accessible" multiple="" data-placeholder="Share to" tabindex="-1" aria-hidden="true" id="sharing" name="users[]" data-select2-id="sharing">
<?php foreach($this->Database->get('users')->fetchAll() as $user){ ?>
<option value="<?=$user['id']?>"><?=ucwords(str_replace('_',' ',str_replace('.',' ',$user['username'])))?></option>
<?php } ?>
</select>
</div>
</div>
<div class="form-group">
<textarea class="form-control wysihtml5-alt" name="body"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" name="ShareThis" class="btn btn-primary"><i class="fas fa-share-alt mr-1"></i>Share</button></div>
</div>
</div>
</div>
</div>
</form>
The Script:
<script>
var select2label
$(document).ready(function () {
$("#ShareThisForm").validate({
rules: {
"users[]": {
required: true,
},
body: {
required: true,
},
},
});
});
</script>
I believe you are using select2
plugin for your users
multiple selection dropdown
. jQuery validate
will not work with select2
plugin by default you need to use errorPlacement method to add a required field
message label below the select field.
I can see you are using boostrap
as well for your modal so you can also a class text-danger
to make sure the validation
message is in red color.
If nothing is selected
from the dropdown
then the validation
message will appear on clicking submit
button OR if something is selected
then we need to use select2
plugin change
function to make sure our error label is removed is after selecting a user. We need to store the select2
label as a global variable so that it can be accessible to removed after a selection is made OR else show the error message again.
$('#users').on("change", function(e) {
if (select2label){
select2label.remove(); //remove label
}
});
As you are adding your select
option name attributes as an array
=> users[]
you need to add the rules for validation like this below:
"users[]": {
required : true
},
Edit: As you have mentioned now that you are using summernote for your textarea and you have provided a reference to ignore it. I have added ignore: ".note-editor *",
in my answer as well.
Live Working Demo:
//Initiate select2 plugin on users
$('#users').select2()
//global var for select 2 label
var select2label
$(document).ready(function() {
$("#ShareThisForm").validate({
ignore: ".note-editor *", //ignore summernote validation
rules: {
"users[]": {
required: true
},
body: {
required: true,
},
},
errorPlacement: function(label, element) {
if (element.hasClass('select2bs4')) {
label.insertAfter(element.parent()).addClass('mt-2 text-danger');
select2label = label
} else {
label.insertAfter(element).addClass('mt-2 text-danger');
}
},
submitHandler: function(form) {
//submit modal form
},
});
});
//watch the change on select - if label exist then remove it
$('#users').on("change", function(e) {
if (select2label) {
select2label.remove(); //remove label
}
});
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#Share">
Open Modal
</button>
<form id="ShareThisForm" method="post">
<div class="modal fade" id="Share" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header bg-primary">
<h5 class="modal-title text-light"><i class="fas fa-share-alt mr-1"></i>Share To</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="'.$this->Language->_ARRAY['Close'].'">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body p-3">
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="fas fa-user mr-2"></i>Users
</span>
</div>
<select class="form-control select2bs4" multiple data-placeholder="Share to" tabindex="-1" aria-hidden="true" id="users" name="users[]" data-select2-id="users">
<option value="0">User1</option>
<option value="1">User2</option>
</select>
</div>
</div>
<div class="form-group">
<textarea class="form-control wysihtml5-alt" name="body"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" name="ShareThis" class="btn btn-primary"><i class="fas fa-share-alt mr-1"></i>Submit</button></div>
</div>
</div>
</div>
</div>
</form>