Conditional validation for a form inputs - javascript

Starting off there is a append button that generates a row with 1 select box, 1 inputbox, and 4 checkboxes. The limit of adding this would be 1-10 rows at max. I have no idea how to make a jquery validation using for example http://formvalidation.io/ - or a standalone jquery code. The rules I would like to apply:
If the role chosen is user (not an admin) , I must validate that there is at least one checkbox checked and the user doesn't appears twice in the selections
The thing is I don't even know where to start from, can you point me any hints?
Live example :: http://jsfiddle.net/Yy2gB/131/
Append method onClick
$(document).ready(function(){
var obj = {"1":"Admin istrator","2":"User2"};
//$('.selectpicker').selectpicker();
$(".addCF").click(function(){
count = $('#customFields tr').length + 1;
var sel = $('<select name="user'+count+'">');
for(key in obj){
// The key is key
// The value is obj[key]
sel.append($("<option>").attr('value',key).text(obj[key]));
}
$('.selectpicker').selectpicker();
$("#customFields").append('<tr><td>'+sel[0].outerHTML
+'</td><td><input class="form-control" class="valid_role"'
+' data-fv-field="emails" type="text" name="role'+count
+'" /></td><td><input type="checkbox" class="mycheckbox"'
+' name="can_edit'+count+'"></td><td><input type="checkbox" '
+'class="mycheckbox" name="can_read'+count+'"></td><td><input '
+'type="checkbox" class="mycheckbox" name="can_execute'+count+'">'
+'</td><td><input type="checkbox" class="mycheckbox" '
+'name="is_admin'+count+'"></td><td><a href="javascript:void(0);"'
+'class="remCF">Remove</a></td></tr>');
$('.mycheckbox').iCheck({
checkboxClass: 'icheckbox_square-blue',
radioClass: 'iradio_square-blue'
});
$('.selectpicker').selectpicker();
});
$("#customFields").on('click','.remCF',function(){
$(this).parent().parent().remove();
});
});
HTML Form
<div class="col-md-12 col-lg-12">
<table class="table table-user-information" id="customFields">
<thead>
<tr>
<th class="standardTable_Header">User</th>
<th class="standardTable_Header">Role</th>
<th class="standardTable_Header">
<span title="administrator projektu">Can read</span>
</th>
<th class="standardTable_Header">
<span title="uprawnienie do edycji danych projektu">
edit
</span>
</th>
<th class="standardTable_Header">
<span title="uprawnienie do odczytu danych projektu oraz przypisanych do niego zadaƄ">
excute
</span>
</th>
<th class="standardTable_Header">
<span title="uprawnienie do edycji danych projektu">
admin
</span>
</th>
</tr>
</thead>
<tbody>
<button type="button" class="btn btn-default addCF">
Append
</button>
</div>
</tbody>
</table>

Using this jQuery Validation Plugin and through this demo, We could do the following:
Assumption: Roles check boxes must have at least one checked if - and only if - the select tag have the value User2
1- wrap your table with form tag that has a submit button:
<div class="col-md-12 col-lg-12">
<form id="myform">
<table class="table table-user-information" id="customFields">
...
</table>
<input type="submit" value="submit" />
</form>
</div>
2- We need to edit the checkboxes html to make them all have the same name but with different values, for example:
<input type="checkbox" class="mycheckbox" name="ourRoles" value="can_edit' ...>
<input type="checkbox" class="mycheckbox" name="ourRoles" value="can_read' ...>
and so on.
3- Add the following script:
// just for the demos, avoids form submit
jQuery.validator.setDefaults({
debug: true,
success: "valid"
});
$("#myform").validate({
rules: {
ourRoles: {
required: function () {
if ($("select[name=user2]").val() == 2) {
return true;
} else {
return false;
}
}
}
}
});
See all together with this fiddle

Related

get all td names associated with checked checkboxes and show in html input field

i am developing a quote generator. what i am trying to do is when the user select a feature it should display associated tfeature name in html input field with id features
here is what i have tried
html
<table class="table" id="table">
<thead class="thead-dark">
<tr>
<th scope="col"></th>
<th scope="col">Features</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" name="product" value="300" type="checkbox" onclick="totalIt()">
<label class="form-check-label" for="exampleCheck1"></label>
</div>
</td>
<td>Homepage</td>
<td>Simplistic design with standard element</td>
</tr>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" name="product" value="200" type="checkbox" onclick="totalIt()">
<label class="form-check-label" for="exampleCheck1"></label>
</div>
</td>
<td>Login</td>
<td>Standard Login with forgot password functionality</td>
</tr>
</tbody>
</table>
<div class="form-group">
input type="text" class="form-control" placeholder="Feature 1, Feature 2, ..." value="" id="features">
</div>
<input type="button" value="Get Selected" class="tble_submit" onclick="GetSelected()" />
so here when user select a checkbox the feature field like homepage, login should be displayed in html input field
here is updated jquery code
<script src="../js/checkbox-total.js"></script>
<script type="text/javascript">
$(".tble_submit").click(function() {
$('.table tr input[type="checkbox"]:checked').each(function() {
var abc = [];
var $row = $(this).closest('tr');
//used :not(:first-child) to skip first element (the checkbox td)
$('td:not(:first-child)', $row).each(function(i) {
abc.push($row.find('td:nth-child(2)').text());
})
$.each(abc, function(i, v) {
document.getElementById("features").value += v
})
});
});
</script>
but it is not working.
here when i select 2 features it should display homepage,login in input field but it shows description of login in input field
output - homepage,homepage,login,login
expected output - Homepage, Login
$(".tble_submit, input[name ='product']").click(function() {
var abc = []; //move the array to here
$('.table tr input[type="checkbox"]:checked').each(function() {
var $row = $(this).closest('tr');
//used :not(:first-child) to skip first element (the checkbox td)
$('td:nth-child(2)', $row).each(function(i) {
abc.push($(this).text());
});
});
document.getElementById("features").value = abc.join(',');
});

Add the total checkbox checked in the textbox

I have a View as below
#using (Html.BeginForm("SubmitSelected", "Costumer", FormMethod.Post, new { id = "form-Costumer", enctype = "multipart/form-data", name = "myform" }))
{
<input type="checkbox" id="checkall" /><span>Check All</span>
<div id="checkboxes">
<table class="table table-bordered">
<thead>
<tr>
<th>
Select //this is from the class where datatype is bool
</th>
<th>
ContactNumber
</th>
<th>
ConsumerName
</th>
</tr>
</thead>
#Html.EditorFor(model => model.transaksiSelectionViewModel.Transactions)
</table>
</div>
<div class="form-group">
#Html.Label("Total Checked")
<div class="col-sm-10">
<input type="text" id="total" class="form-control" />//the result of the number checked here
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
function toggleChecked(status) {
$("#checkboxes input").each(function () {
// Set the checked status of each to match the
// checked status of the check all checkbox:
$(this).prop("checked", status);
});
}
$(document).ready(function () {
//Set the default value of the global checkbox to true:
$("#checkall").prop('checked', false);
// Attach the call to toggleChecked to the
// click event of the global checkbox:
$("#checkall").click(function () {
var status = $("#checkall").prop('checked');
toggleChecked(status);
});
});
</script>
}
The script above only runs to check all checkboxes on each row.
and I want to create a function to calculate the number of checkboxes that have been checked, the results are in the textbox(Total Checked).
I tried but it didn't work. Please help:)
You can use this when trigger function go on.
var checkedCount = $("[type='checkbox']:checked").lenght
use this on your document.ready function..
var checkednum = $('input:checkbox:checked').length;
alert(checkednum)

Dynamically created elements having the different values but the same index

My code is to create search suggestions after triggering the 'keyup' event, hence creating dynamic elements with a class "suggestion-box". On clicking any of "suggestion-box" classes, new dynamic elements, each with parent class "transaction-entry", are created. Each of the dynamically created "transaction-entry" classes has child class 'quantityInput' which is an input element. The major problem is this, each of the 'quantityInput' classes display their corresponding input values when delegated to a static element through the 'keyup' event trigger but not their corresponding indexes (displays only 0).
HTML CODE
<div class="col-sm-1">
<button type="button" id="delete-transact" class="btn btn-default" data-toggle="tooltip" title="Delete All Entries" data-placement="right">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</div>
<!-- Input field for search suggestion -->
<form method="POST" action="{{URL::to('/search/transaction')}}" id="transAction">
{{ csrf_field() }}
<div class="col-sm-12">
<div class="form-group">
<input type="text" name="searchItem" id="transProductSearch" class="form-control" value="" title=""
placeholder="Search product">
<!--Container for dynamically created class "suggestion-box"-->
<div id="suggestion-container"></div>
</div>
</div>
</form>
<div class="cover">
<div class="table-responsive">
<form action="" method="">
<table class="table table-hover">
<thead>
<tr>
<th>Product</th>
<th>Quantity purchased</th>
<th>Quantity Available</th>
<th>Price</th>
</tr>
</thead>
<!--Container for dynamically created class "transaction entry"-->
<tbody id="transaction-body">
</tbody>
<tfoot>
<tr class="tfoot">
<td>Total</td>
<td class="transactionTotal"></td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
JQUERY CODE
$('#transProductSearch').on('keyup',function (e) { //Event listener for ajax request
e.preventDefault();
if($(this).val() !== ""){
$.ajax({
type: "POST",
url: $('#transAction').attr('action'),
data: $('#transAction').serialize(),
success: function (response) {
$(".suggestion-box").remove();//Removing every dynamically created "suggestion-box" class on every successful AJAX request;
pEntities = [];
response = jQuery.parseJSON(response);
$.each(response, function (indexInArray, value) {
$("#suggestion-container").append($('<div>',{class:"suggestion-box", text:value.productName}));
pEntities[indexInArray] = {prodQuantity:"",prodId:"",prodPrice:"",prodName:""};
pEntities[indexInArray].prodQuantity = value.quantity;
pEntities[indexInArray].prodId = value.id;
pEntities[indexInArray].prodPrice = value.price;
pEntities[indexInArray].prodName = value.productName;
});
},
error: function () {
console.log($('#transAction').val());
}
});
}
else{
$('.suggestion-box').remove()//Removing every suggestion box if input field is empty
}
});
$('#suggestion-container').on("click",'.suggestion-box', function (e) { // Event delegation to append new "transaction-entry" class
var index = $(this).index();
$('#transaction-body').append('<tr class="transaction-entry"><input hidden class="prodId" value="'+pEntities[index].id+'"/><td>'+pEntities[index].prodName+'</td><td><input class="quantityInput" style="color:black" type="number"></td><td>'+pEntities[index].prodQuantity +'</td><td class="productPrice">'+pEntities[index].prodPrice +'</td></tr>');
$('.suggestion-box').remove();
})
$('#delete-transact').click(function (e) {//Event listener to remove all transaction entry classes
e.preventDefault();
$('#transaction-body').empty();
})
$('#transaction-body').on("keyup",'.quantityInput',function (e) {//Event Delegation to output quantityInput value and index
console.log($(this).val()+" "+$(this).index());
});

radio button in a table checked and unchecked

I have a radio button in table and I want to implement select all functionality for radio button based on name. This is my code:
var checked = false;
$scope.acceptOrRejectAllOrders = function(selectedVal) {
if (selectedVal == 'Accept all') {
jQuery("#bundleAcceptAll").attr('checked', 'checked');
// $("#bundleAcceptAll").prop("checked", true);
//$("#bundleAcceptAll").attr('checked', 'checked');
var aa = document.getElementsByName("bundleAcceptAll");
for (var i = 0; i < aa.length; i++) {
document.getElementsByName(bundleAcceptAll).checked = true;
}
//$scope.quoteRequest.quotationRequestItems[0].quotes.length
} else {
}
};
<div style="border:1px #f5f4f4 solid;background: #f9f9f9;" ng-repeat="(key,quoteAndOrder) in getQuotesAndOrders()">
<div style="background: #fff;">
<table border="0" style="width: 100%;" class="table table-striped">
<thead>
<tr style="background: #ff7900;color: #fff;">
<th>Quote ID</th>
<th>{{key}}</th>
</tr>
<tr>
<th>Accept or Reject Orders:</th>
<th>
<span style="float: left;background: #f9f9f9;">
<input type="radio" name ="bundleAcceptAll" ng-change="" class="radioSignatory" value="Approve Order" ng-disabled="">
<p class="labelRadioSignatory">Approve Order</p>
<input type="radio" name ="bundleRejectAll" ng-change="" class="radioSignatory" value="Reject Order" ng-disabled="">
<p class="labelRadioSignatory">Reject Order</p>
</span>
</th>
</tr>
</thead>
<tr ng-repeat="odr in quoteAndOrder">
<td> {{odr.id}} </td>
<td>{{odr.status}}</td>
</tr>
</table>
<hr>
</div>
</div>
I am not able to select all radio buttons with name bundleAcceptAll. It is basically a list in which each row will have a radio button. I want all radio buttons in the list to be selected. Only one button gets selected
AFAIK if you choose radio button and use the same name it will treated as group that will only one item selected. Perhaps you could just change it into checkbox.
function oncheckClick()
{
$('input[name=chkBox]').prop('checked',true)
}
function onUnCheckClick()
{
$('input[name=chkBox]').prop('checked',false)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name="chkBox">
<button id="check" onclick="oncheckClick()" value="Check">Check</button>
<button id="check" onclick="onUnCheckClick()" value="UnCheck">UnCheck</button>
if it is list, you can loop through the list and check or uncheck
$("input[type=radio][name='" + name + "']").each(function() {
//code here
});
As was mentioned above, it's not radio button functionality to have multiple items checked, it's checkboxes. But you can style checkboxes so they would look like radiobuttons. See for example: How to make a checkbox in circle shape with custom css?

Combines table filters in jquery

I have a table with different places, and implemented some simple buttons that allow you to filter the list. First filter is location (north, east, central, south, west) which is based on postcode. Another filter is on "impress". This shows you only the places that have have 4 or higher value in the column. Filters work great separately, but not together. The result that I am after is when I press "West" is shows me the places in "West, when I then click impress, I expect to see the places in west with a 4 or 5 score for impress.
JSFiddle here
$('.table td.postcode').each(function() {
var cellText = $(this).html();
var locationString = cellText.substring(0,2);
if (locationString.indexOf('W') > -1){
$(this).parent().addClass('west');
}
if (locationString.indexOf('C') > -1){
$(this).parent().addClass('central');
}
if (locationString.indexOf('E') > -1){
$(this).parent().addClass('east');
}
if (locationString.indexOf('S') > -1){
$(this).parent().addClass('south');
}
if (locationString.indexOf('N') > -1){
$(this).parent().addClass('north');
}
});
$("input[name='filterStatus'], select.filter").change(function () {
var classes = [];
$("input[name='filterStatus']").each(function() {
if ($(this).is(":checked")) {
classes.push('.'+$(this).val());
}
});
if (classes == "") {
// if no filters selected, show all items
$("#StatusTable tbody tr").show();
} else {
// otherwise, hide everything...
$("#StatusTable tbody tr").hide();
// then show only the matching items
rows = $("#StatusTable tr").filter(classes.length ? classes.join(',') : '*');
if (rows.size() > 0) {
rows.show();
}
}
});
$("input[name='impressStatus']").change(function(){
var classes = [];
$("input[name='impressStatus']").each(function() {
if ($(this).is(":checked")) {
classes.push('.'+$(this).val());
}
});
if(classes == ""){
$("#StatusTable tbody tr").show();
}
else{
$(".table td.impress").each(function(){
if($(this).data("impress") >= 4){
$(this).parent().show();
}
else{
$(this).parent().hide();
}
});
}
});
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--BUTTON FILTERS -->
<div class="btn-toolbar" role="toolbar" aria-label="...">
<div class="btn-group" style="" data-toggle="buttons">
<label class="btn btn-primary outline">
<input type="checkbox" name="filterStatus" value="north" autocomplete="off">North
</label>
<label class="btn btn-primary outline">
<input type="checkbox" name="filterStatus" value="east" autocomplete="off" class="radio">East
</label>
<label class="btn btn-primary outline">
<input type="checkbox" name="filterStatus" value="central" autocomplete="off" class="radio">Central
</label>
<label class="btn btn-primary outline">
<input type="checkbox" name="filterStatus" value="south"autocomplete="off" class="radio">South </label>
<label class="btn btn-primary outline">
<input type="checkbox" name="filterStatus" value="west" autocomplete="off" class="radio">West
</label>
</div><!-- button group -->
<label class="btn btn-primary outline">
<input type="checkbox" name="impressStatus" class="radio" aria-pressed="true" autocomplete="off">Impress her
</label>
</div><!-- btn toolbar-->
<!--TABLE -->
<table class="table" id="StatusTable">
<thead>
<tr>
<th data-sort="string" style="cursor:pointer">name</th>
<!-- <th>Description</th> -->
<th data-sort="string" style="cursor:pointer;">postcode</th>
<th data-sort="int" style="cursor:pointer;">price</th>
<th data-sort="int" style="cursor:pointer;">total</th>
<th data-sort="int" style="cursor:pointer;">impress</th>
<th colspan="4"></th>
</tr>
</thead>
<tbody>
<tr data-link="/places/1">
<td>Name of place 1</td>
<td class="postcode">NW1</td>
<td class="price" data-price='3'>3</td>
<td class="rating" data-rating='69'>69</td>
<td class="impress" data-impress='4'>4</td>
</tr>
<tr data-link="/places/2">
<td>Name of place 2</td>
<td class="postcode">E3</td>
<td class="price" data-price='4'>4</span></td>
<td class="rating" data-rating='89'>89</td>
<td class="impress" data-impress='5'>5</td>
</tr>
<tr data-link="/places/3">
<td>Name of place 3</td>
<td class="postcode">SW3</td>
<td class="price" data-price='2'>2</td>
<td class="rating" data-rating='51'>51</td>
<td class="impress" data-impress='3'>3</td>
</tr>
</tbody>
</table>
Code is probably not the most efficient, but it works :). Once I got this working, I want to add more filters.
(sorry for my bad english)
if these are the only filters you need, you can use two different type of filter:
hide via Javascript
hide via Css
if you use 2 types of filters the filters can work correctly without use a complex javascript code to manage a big number of different cases and combination:
I add a initial (on document load) control that check if a tr has the value impress cell >4, if has it add a new class: is_impress else add an other: no_impress.
$('.table td.impress').each(function(){
var _class = ($(this).data("impress") >= 4) ? "is_impress" : "no_impress";
$(this).parent().addClass(_class);
});
The code of filter by position is the same... but... I edit the filter by impress to add a class to table () when is active and take it off when isn't:
$("input[name='impressStatus']").change(function(){
(!$(this).is(":checked"))
? $("#StatusTable").removeClass("active_impress")
: $("#StatusTable").addClass("active_impress");
});
if the table has the class active_impress a css rules override the inline code of dispaly to hide all the row that haven't an impress >4:
#StatusTable.active_impress tr.no_impress{
display:none !important;
}
This type of filter override any other display modification until the checkbox stay checked.
I edit your fiddle:
https://jsfiddle.net/Frogmouth/gkba343L/1/
USE CSS to more filter
First change on load check, add price:
$('.table tbody tr').each(function(){
var _class = "";
_class += ($(this).find(".price").data("price") >= 2) ? "is_price " : "no_price ";
_class += ($(this).find(".impress").data("impress") >= 4) ? "is_impress " : "no_impress ";
console.log(_class);
$(this).addClass(_class);
});
Add an other handler to new filter:
$("input[name='priceStatus']").change(function(){
(!$(this).is(":checked"))
? $("#StatusTable").removeClass("active_price")
: $("#StatusTable").addClass("active_price");
});
add new selector to the css rule:
#StatusTable.active_impress tr.no_impress,
#StatusTable.active_price tr.no_price{
display:none !important;
}
This is the result:
https://jsfiddle.net/Frogmouth/gkba343L/3/
Optimize code to add more filter:
HTML filter button:
<label class="btn btn-primary outline">
<input type="checkbox" name="impress" class="cssFilter radio" aria-pressed="true" autocomplete="off">Impress her
</label>
use cssFilter to indicate that is a css filter button and use name attribute to define the name of the filter, than use this namespace into the css class:
.active_{name} .no_{name} .is_{name}
And use a generic handler:
$("input.cssFilter").change(function(){
var _name = $(this).attr("name");
console.log(_name);
(!$(this).is(":checked"))
? $("#StatusTable").removeClass("active_"+_name)
: $("#StatusTable").addClass("active_"+_name);
});
With this you can manage all the filter with an unique handler, remember to add the filter to onload check and the new selector for each new filter.
Fiddle:
https://jsfiddle.net/Frogmouth/gkba343L/4/

Categories

Resources