JSFiddle - React, Tailwind, and code Playground

by kittonian

HTML

<html>
<head>
	
</head>
<body>

<p>I need a custom parsley validator to ensure that at least 5 of the select boxes are set to Yes (or &lt;option value="t"&gt;).<br>
If there are less than 5 of the select boxes set to Yes the form should not submit and Parsley should show an error next to the select boxes set to No.</p>

<p>The commented JS code works but not the way I need it to with Parsley. The main custom validation code is checking for duplicates across<br>
all the select boxes but not for at least 5 set to Yes.</p>

<form name="select_test" id="postfeatured" method="post" action="#">

<div class="choice">

<div>
<select name="post_featured1" id="post_featured1" class="select enabled" data-parsley-group="minselect" data-parsley-enabled="1">
<option value="t">Y</option>
<option value="f">N</option>
</select>
</div>

<div>
<select name="post_featured2" id="post_featured2" class="select enabled" data-parsley-group="minselect" data-parsley-enabled="2">
<option value="t">Y</option>
<option value="f">N</option>
</select>
</div>

<div>
<select name="post_featured3" id="post_featured3" class="select enabled" data-parsley-group="minselect" data-parsley-enabled="3">
<option value="t">Y</option>
<option value="f">N</option>
</select>
</div>

<div>
<select name="post_featured4" id="post_featured4" class="select enabled" data-parsley-group="minselect" data-parsley-enabled="4">
<option value="t">Y</option>
<option value="f">N</option>
</select>
</div>

<div>
<select name="post_featured5" id="post_featured5" class="select enabled" data-parsley-group="minselect" data-parsley-enabled="5">
<option value="t">Y</option>
<option value="f">N</option>
</select>
</div>

<div>
<select name="post_featured6" id="post_featured6" class="select enabled" data-parsley-group="minselect" data-parsley-enabled="6">
<option value="t">Y</option>
<option value="f">N</option>
</select>
</div>
</div>

<div class="submit">
<input type="submit" value="SUBMIT"...

CSS

.choice {
	display:grid;
	grid-template-columns:280px;
	grid-row-gap:18px;
}

.submit {
	margin-top: 25px;
}

input.parsley-success,
select.parsley-success,
textarea.parsley-success {
/*
  color: #468847;
  background-color: #DFF0D8;
  border: 1px solid #D6E9C6;
*/
}

input.parsley-error,
select.parsley-error,
textarea.parsley-error {
  color: #B94A48;
  background-color: #F2DEDE;
  border: 1px solid #EED3D7;
}

.parsley-errors-list {
  margin: 2px 0 3px;
  padding: 0;
  list-style-type: none;
  font-size: 0.9em;
  font-family: 'proxima_novaregular',Helvetica,sans-serif;
  line-height: 0.9em;
  opacity: 0;
  color: #B94A48;

  transition: all .3s ease-in;
  -o-transition: all .3s ease-in;
  -moz-transition: all .3s ease-in;
  -webkit-transition: all .3s ease-in;
}

.parsley-errors-list.filled {
  opacity: 1;
}

.select {
font-family:'proxima_novaregular',Helvetica,sans-serif;
font-size:14px;
background-color: #FFFFFF;
color: #000000;
border: 1px solid #999999;
margin: 0px;
padding:2px;
}

.submitbutton {
display:inline-block;
width:70px;
height:30px;
border:1px solid #999999;
filter:progid:DXImageTransform.Microsoft.Gradient 
(GradientType=0,StartColorStr='#ffffff',EndColorStr='#ffffff');
color:#000000;
font-family:'proxima_novaregular',sans-serif;
font-size:14px;
text-transform:uppercase;
text-align:center;
text-decoration:none;
line-height:14px;
box-sizing:border-box;
border-radius:6px;
background-color:transparent;
outline:none;
cursor:pointer;
}

JavaScript

var validating;

$("#post_featured").parsley();

$('select.featured').change(() => {
  if (!validating) return;
  $("#post_featured").parsley().validate({
    group: 'minselect'
  });
});

window.Parsley.addValidator("featured", {
  validateMultiple: function(values) {
    return values.length > 0;
  },
  requirementType: "string",
  validateString: function(value, current) {
    validating = true;
    var currentYesCount = $('#post_featured select').filter(function() {
      return $(this).val() === 't';
    }).length;
   if (value === 't') {
     return true;
    } else {
      if (currentYesCount > 4) {
        return true;
      } else {
        return false;
      }}
  },
  priority: 33,
  messages: {
    en: 'You must have at least 5 featured posts'
  }
});