i have a table that i compare row values using checkbox to see if they are the same, am using a jquery code to compare the table rows that were selected by a checkbox, it works perfectly, now what i want is to be able to exclude two columns from the comparison and compare other columns in the two selected rows
$('.ApprovalForm').submit(function(event) {
event.preventDefault(); // Prevent the form from submitting via the browser
if ($(":checkbox:checked").length < 2 || $(":checkbox:checked").length > 2) {
alert('You have to select two flights');
} else {
var form = $(this);
//get all checkboxes that are selected
var selected = $("input:checked");
//loop through your columns
var x = 0;
for (var i = 1; i <= 17; i++) {
var prev = null;
$.each($(selected), function() {
var curr = $(this).closest("tr").find("td").eq(i).text();
//if at least one value is different highlight the column
if (curr !== prev && prev !== null) {
x++;
console.log(3333);
}
prev = curr;
})
}
console.log(x);
if (x <= 0) {
$("#modal-Approve").modal('show');
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
}).done(function(response) {
$("#MessageStatus ").val(response);
location.reload();
}).fail(function(data) {
// Optionally alert the user of an error here...
alert(data);
});
} else {
alert('Selected flights are not the same, check if they are the same by using detail button');
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th style="display:none">id</th>
<th>Mission</th>
<th>First Pilot</th>
<th>Second Pilot</th>
<th>Aircraft</th>
<th>No</th>
<th style="display:none">TakeOffTime</th>
<th style="display:none">LandingTime</th>
<th style="display:none">Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:20</td> <!-- exclude this from the values that will be compared -->
<td>12/1/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
<tr>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:30</td> <!-- exclude this from the values that will be compared -->
<td>12/2/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
</tbody>
</table>
so the idea is to be able to exclude some td values from the comparison
Add 'exc_toggle' class to each th in your header row
Add event listener for clicking these classes to toggle an 'exclude' data attribute
Add a hidden cell to each row in tbody so your column counts are the same between the header and tbody rows
Add to your form submit event listener to iterate over the 'exc_toggle' class and create a to_ignore index for each data-exclude = 1
Skip your comparison when i is found in your ignore index
Code below.
HTML:
<table>
<thead>
<tr id="header_row">
<th style="display:none" class="exc_toggle">id</th>
<th class="exc_toggle">Mission</th>
<th class="exc_toggle">First Pilot</th>
<th class="exc_toggle">Second Pilot</th>
<th class="exc_toggle">Aircraft</th>
<th class="exc_toggle">No</th>
<th class="exc_toggle">TakeOffTime</th>
<th class="exc_toggle">LandingTime</th>
<th class="exc_toggle">Date</th>
</tr>
</thead>
<tbody>
<tr>
<td style="display:none"></td>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:20</td> <!-- exclude this from the values that will be compared -->
<td>12/1/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
<tr>
<td style="display:none"></td>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:30</td> <!-- exclude this from the values that will be compared -->
<td>12/2/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
</tbody>
</table>
jQuery (in document header):
$(document).on('click', '.exc_toggle', function(){
if($(this).data('exclude') == 1)
{
$(this).data('exclude', 0);
$(this).css('background-color', '');
} else {
$(this).data('exclude', 1);
$(this).css('background-color', '#F00');
}
});
jQuery (modified ApprovalForm submit event):
$('.ApprovalForm').submit(function(event) {
event.preventDefault(); // Prevent the form from submitting via the browser
if ($(":checkbox:checked").length < 2 || $(":checkbox:checked").length > 2) {
alert('You have to select two flights');
} else {
var ignore_indices = [];
var cnt = 0;
$('.exc_toggle').each(function(){
if($(this).data('exclude') == 1)
{ignore_indices.push(cnt);}
cnt++;
});
var form = $(this);
//get all checkboxes that are selected
var selected = $("input:checked");
//loop through your columns
var x = 0;
for (var i = 1; i <= 17; i++) {
if(ignore_indices.indexOf(i) < 0)
{
var prev = null;
$.each($(selected), function() {
var curr = $(this).closest("tr").find("td").eq(i).text();
//if at least one value is different highlight the column
if (curr !== prev && prev !== null) {
x++;
console.log(3333);
}
prev = curr;
})
} else {
prev = null;
}
}
console.log(x);
if (x <= 0) {
$("#modal-Approve").modal('show');
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
}).done(function(response) {
$("#MessageStatus ").val(response);
location.reload();
}).fail(function(data) {
// Optionally alert the user of an error here...
alert(data);
});
} else {
alert('Selected flights are not the same, check if they are the same by using detail button');
}
}
});
To compare duplicate takeoff times, add the class 'takeoff' to each td in your takeoff time column, then add this jQuery:
$(document).on('change', 'input:checkbox', function(){
var takeoff = '';
$('.takeoff').css('background-color', '');
$('input:checked').each(function(){
var td_target = $(this).closest('tr').find('.takeoff');
takeoff = td_target.html();
var matches = $('input:checked').parents('tr').find('.takeoff:contains("'+takeoff+'")');
if(matches.length > 1)
{td_target.css('background-color', '#F00');}
else
{td_target.css('background-color', '');}
});
});
Related
I have a table and I want to clone the last line of it after the [Add New] link is pressed. The table has 8 columns. When I press the [Add New] link, only the first 3 column has the same value like the one above it. The delete function is also unable to delete row.
Here is the page when it loads.
Now, I key in values for PX, Date, and Place:
Then, when i click on the [Add New] link, new row appeared below. But only 3 columns are populated:
I want the row below to clone exactly the values from the previous row.
Here's the code of the table:
<div style="width:700px; padding:5px; background-color:white;">
#using (Html.BeginForm("PxDataEntry", "PxAndTitle", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
if (ViewBag.Message != null)
{
<div style="border:solid 1px green">
#ViewBag.Message
</div>
}
<div>+ Add New</div>
<table id="dataTable" border="0" cellpadding="0" cellspacing="0">
<tr>
<th>PX</th>
<th>Date</th>
<th>Place</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
#if (Model != null && Model.Count > 0)
{
int j = 0;
foreach (var i in Model)
{
<tr style="border:1px solid black">
<td>#Html.TextBoxFor(a => a[j].px)</td>
<td>#Html.TextBoxFor(a => a[j].sDate)</td>
<td>#Html.TextBoxFor(a => a[j].Place)</td>
<td>#Html.TextBoxFor(a => a[j].PId)</td>
<td>#Html.TextBoxFor(a => a[j].FId)</td>
<td>#Html.TextBoxFor(a => a[j].createdBy)</td>
<td>#Html.TextBoxFor(a => a[j].createdAt)</td>
<td>#Html.TextBoxFor(a => a[j].PxStatus)</td>
<td>
#if (j > 0)
{
Remove
}
</td>
</tr>
j++;
}
}
</table>
<input type="submit" value="Save Bulk Data" />
}
Here is the script:
#section Scripts{
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript">
$(document).ready(function () {
//1. Add new row
$("#addNew").click(function (e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone();
var suffix = $trNew.find(':input:first').attr('name').match(/\d+/);
$trNew.find("td:last").html('Remove');
$.each($trNew.find(':input'), function (i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
//Replaced value
var type = $(this).attr('type');
if (type.toLowerCase() == "text") {
$(this).attr('value', '');
}
// If you have another Type then replace with default value
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
// Re-assign Validation
var form = $("form")
.removeData("validator")
.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
});
// 2. Remove
$('a.remove').live("click", function (e) {
e.preventDefault();
$(this).parent().parent().remove();
});
});
</script>
}
First issue is because you empty your inputs values which are cloned i.e : $(this).attr('value', ''); remove this line if you need values as well from your previous trs .Then, onclick of a tag you can simply use .closest("tr") to remove entire tr from table .
Demo Code :
$(document).ready(function() {
//1. Add new row
$("#addNew").click(function(e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone();
var suffix = $trNew.find(':input:first').attr('name').match(/\d+/);
$trNew.find("td:last").html('Remove');
$.each($trNew.find(':input'), function(i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
//Replaced value
var type = $(this).attr('type');
if (type.toLowerCase() == "text") {
//this line empty value of inputs
// $(this).attr('value', '');
}
// If you have another Type then replace with default value
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
})
$(document).on("click", "a.remove", function(e) {
e.preventDefault();
$(this).closest("tr").remove(); //remove closest trs
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table id="dataTable" border="0" cellpadding="0" cellspacing="0">
<tr>
<th>PX</th>
<th>Date</th>
<th>Place</th>
<th></th>
<th></th>
</tr>
<tr style="border:1px solid black">
<td><input type="text" name="a[0]"></td>
<td><input type="text" name="sDate[0]"></td>
<td><input type="text" name="Place[0]" value="somthing"></td>
<td><input type="text" name="Pid[0]" value="1"></td>
<td>
Remove
</td>
</tr>
</table>
<button id="addNew">Add</button>
I have a table in which there is button in last cell of each row when i click on that button the values of other cells in the same row stored in an array now i want if i click on button the values of it rows should stored in an array which is working but if i click on another button of the other row the values of its rows should store in another array not overwirte the values in first array and when i click the button 3rd time in another row it should give the message "you have selected 2 row"
I don't want that if 3rd time i click button it shouldn't store its values in any array
and I want first and second click should store their corresponding values in different arrays
$('#tbl tbody').on( 'click', 'td:last-child', function (e) {
var row = $(this).parent().parent().children().index($(this).parent());
var datas=[];
var data=[];
var imgs=[];
var img=[];
var target = e.srcElement || e.target;
while (target && target.nodeName !== "TR") {
target = target.parentNode;
}
if (target) {
var cells = target.getElementsByTagName("td");
for (var i = 0; i < cells.length-2; i++) {
img = cells[i].querySelector('img');
if(img){
data.push(img.src);
}else{
data.push(cells[i].innerHTML);}
}
}
});
In this when i click on the button which in last cell of each row then I get the values of the corresponding cells in same row
This is code of my table
<table id="tbl" class="table table-bordered table-dark">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Auth Provider</th>
<th scope="col">Auth Unique Id</th>
<th scope="col">Match Id</th>
<th scope="col">Game Mode</th>
<th scope="col">Character 1</th>
<th scope="col">Character 2</th>
<th scope="col">Character 3</th>
<th scope="col">Character 4</th>
<th scope="col">Character 5</th>
<th scope="col">Character 6</th>
<th scope="col">Match Time</th>
<th scope="col">Action</th>
<th scope="col">Schedule Match</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
$(document).ready(function() {
var trHTML = "";
$.ajax({
url: '../php/admin/schedule_match.php',
type: 'post',
data: {},
success: function(response) {
var data = $.parseJSON(response);
var table;
//table.clear();
table = $('#tbl').DataTable();
table.clear();
if(data!='') {
$.each(data, function(i, item) {
table.row.add([ data[i].name, data[i].provider,data[i].auth,data[i].mid,data[i].mode,'<img width="100px" height= "70px" src=' + data[i].p1 + '>','<img width="100px" height= "70px" src=' + data[i].p2 + '>','<img width="100px" height= "70px" src=' + data[i].p3 + '>','<img width="100px" height= "70px" src=' + data[i].p4 + '>','<img width="100px" height= "70px" src=' + data[i].p5 + '>','<img width="100px" height= "70px" src=' + data[i].p6 + '>',data[i].time,'<button class="btn btn-primary delete" data-id-id=' + data[i].id + '>Delete</button>','<button class="btn btn-primary schedule" data-id-id=' + data[i].id + '>Schedule</button>']);
});
table.draw();
}
}
})
});
Please try this, the data will be saved in selected variable key = tr index and value equal array list of tr child values,
$(function() {
var selected = { };
$('#tbl tbody').on( 'click', 'td:last-child', function (e) {
var index = $(this).closest("tr").index();
if(Object.keys(selected).length == 2 ){
alert("You can selecto two only");
return;
}
if( selected.hasOwnProperty(index)){
alert("You have already select this");
return;
}
var children = $(this).closest("tr").children();
var childData = [];
selected[index] = [];
for (var i = 0; i < children.length-2; i++) {
img = children[i].querySelector('img');
if(img){
childData.push(img.src);
}else{
childData.push(children[i].innerHTML);}
}
selected[index] = childData ;
console.log(selected);
});
});
the output like this
{
0: ["123", "asd", "123343", "asd"] ,
2: ["13234", "asd", "123343", "asd"]
}
to get the selected values
Object.values(selected) // [ ["123", "asd", "123343", "asd"] , ["13234", "asd", "123343", "asd"] ]
to get the selected tr indexes
Object.keys(selected) // [ 0 , 2 ]
Code will check if the user select more than two rows it will alert , you can change it, if user select two and clicked on row selected before it will not get any alert, you can delete && !selected.hasOwnProperty(index) to alert what ever this selected or not.
i am writing a code to select/remove the product from display table, and when the product is selected,then product with its price mus be displayed in some other table where at the end sum total is also needed which get updated as per selected product prices
<table id="table-example" class="table">
<thead>
<tr>
<th>Cause</th>
<th>Monthly Charge</th>
</tr>
</thead>
<tbody>
<tr>
<div id="selectedServices"></div>
<td id="myDiv"></td>
</tr>
</tbody>
</table>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<table id="table-example" class="table">
<thead>
<tr>
<th>Cause</th>
<th>Monthly Charge</th>
</tr>
</thead>
<div>
<tbody>
<p>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>table</label>
</td>
<td>80</td>
</tr>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>chair</label>
</td>
<td>45</td>
</tr>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>set</label>
</td>
<td>10</td>
</tr>
</tbody>
</div>
</table>
script
$(function() {
$(":checkbox").change(function() {
var arr = $(":checkbox:checked").map(function() { return $(this).next().text(); }).get();
$("#myDiv").text(arr.join(','));
});
});
function ToggleBGColour(item) {
var td = $(item).parent();
if (td.is('.rowSelected'))
td.removeClass("rowSelected");
else
td.addClass("rowSelected");
}
Here is the corresponding fiddle.
Based on your comment for my other answer, this should work for you then:
$(":checkbox").change(function () {
// Toggle class of selected row
$(this).parent().toggleClass("rowSelected");
// Get all items name, sum total amount
var sum = 0;
var arr = $(":checkbox:checked").map(function () {
sum += Number($(this).parents('tr').find('td:last').text());
return $(this).parents('tr').clone();
}).get();
// Display selected items and their sum
$("#selectedServices").html(arr).find('input').remove();
$("#total").text(sum);
});
This avoids the need for creating new HTML elements in the JavaScript code, and reduces the number of .maps() and .each() loops to one.
http://jsfiddle.net/samliew/uF2Ba/
Here is the javascript for but u need to remove onClick attrs :
$(function() {
$(":checkbox").change(function() {
ToggleBGColour(this);
var arr = $(":checkbox:checked").map(function() {
return $(this).next().text();
}).get();
var nums = $(":checkbox:checked").map(function() {
return parseInt($(this).parent().next().html());
}).get();
var total = 0;
for (var i = 0; i < nums.length; i++) {
total += nums[i] << 0;
}
$("#myDiv").text(arr.join(',') + 'total : '+total);
});
});
function ToggleBGColour(item) {
var td = $(item).parent();
if (td.is('.rowSelected'))
td.removeClass("rowSelected");
else
td.addClass("rowSelected");
}
I updated your fiddle with my answer : http://jsfiddle.net/A2SKr/9/
Here's what i've changed.
Slightly better formatted.
i removed the onclick attribute. Its bad practice to use this because of performance issues. Use delegates
Ive also changed a lil bit of your HTML. the output is now a table
added a total element to the output as well
javascript code :
$(":checkbox").change(function () {
var total = 0;
var check = $(":checkbox:checked");
var causes = check.map(function () {
return $(this).next().text();
}).get();
var costs = check.map(function () {
return $(this).parent().next().text()
}).get();
var tbody = $("#table-example tbody").empty();
$.each(causes, function (i, cause) {
tbody.append("<tr><td>" + cause + "</td><td id='" + i + "'><td/></tr>");
});
$.each(costs, function (i, cost) {
$('#' + i + '').html(cost);
total += parseInt(cost, 10);
});
tbody.append("<tr><td>Total</td><td>" + total + "<td/></tr>");
});
});
I am trying to use the Javascript search from the below website however was wondering if there is a way to return only the exact term searched for, as if I type part of a word it returns the table row also.
ie. Seach for "Heath" returns the same result as searching Heathesh", is there a simple workaround?
Script: http://heathesh.com/post/2010/05/06/Filtering-or-searching-an-HTML-table-using-JavaScript.aspx
Example: http://heathesh.com/code/javascript/tablesearch/
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<th>ID</th>
<th>First Name</th>
<th>Surname</th>
<th>Website</th>
</tr>
<tbody id="data">
<tr>
<td>1</td>
<td>Heathesh</td>
<td>Bhandari</td>
<td>http://heathesh.com</td>
</tr>
<tr>
<td>2</td>
<td>Candice</td>
<td>David</td>
<td>http://candicedavid.com</td>
</tr>
</tbody>
</table>
//define the table search object, which can implement both functions and properties
window.tableSearch = {};
//initialize the search, setup the current object
tableSearch.init = function() {
//define the properties I want on the tableSearch object
this.Rows = document.getElementById('data').getElementsByTagName('TR');
this.RowsLength = tableSearch.Rows.length;
this.RowsText = [];
//loop through the table and add the data to the table search object
for (var i = 0; i < tableSearch.RowsLength; i++) {
this.RowsText[i] = (tableSearch.Rows[i].innerText) ? tableSearch.Rows[i].innerText.toUpperCase() : tableSearch.Rows[i].textContent.toUpperCase();
}
}
Next create the actual JavaScript function to run the search like so:
//onlys shows the relevant rows as determined by the search string
tableSearch.runSearch = function() {
//get the search term
this.Term = document.getElementById('textBoxSearch').value.toUpperCase();
//loop through the rows and hide rows that do not match the search query
for (var i = 0, row; row = this.Rows[i], rowText = this.RowsText[i]; i++) {
row.style.display = ((rowText.indexOf(this.Term) != -1) || this.Term === '') ? '' : 'none';
}
}
//handles the enter key being pressed
tableSearch.search = function(e) {
//checks if the user pressed the enter key, and if they did then run the search
var keycode;
if (window.event) { keycode = window.event.keyCode; }
else if (e) { keycode = e.which; }
else { return false; }
if (keycode == 13) {
tableSearch.runSearch();
}
else { return false; }
}
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<input type="text" size="30" maxlength="1000" value="" id="textBoxSearch" onkeyup="tableSearch.search(event);" />
<input type="button" value="Search" onclick="tableSearch.runSearch();" />
</td>
</tr>
</tbody>
</table>
You are matching this with rowText.indexOf() in the code below, that will return the row if the term is found anywhere in the string.
for (var i = 0, row; row = this.Rows[i], rowText = this.RowsText[i]; i++) {
row.style.display = ((rowText.indexOf(this.Term) != -1) || this.Term === '') ? '' : 'none';
}
To get exact matches, change rowText.indexOf(this.Term) != -1 to rowText.toUpperCase() === this.Term.toUpperCase(). The .toUpperCase() converts both strings to uppercase before comparing to make the search case insensitive.
for (var i = 0, row; row = this.Rows[i], rowText = this.RowsText[i]; i++) {
row.style.display = ((rowText.toUpperCase() === this.Term.toUpperCase()) || this.Term === '') ? '' : 'none';
}
The following code will do a partial search if an exact word match did not give any results:
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
<title>Search table</title>
</head>
<body style=" background-color:white;">
<input type="text" size="30"
value=""
id="textBoxSearch"
onkeyup="tableSearch.search(this.value);" />
<div id="table"></div>
<script type="text/javascript">
// create a 4 column table with random text
function getRandomText(len){
ret=[];
for(var i =0;i<len;i++){
ret.push(String.fromCharCode(
Math.floor((Math.random()*(85-65))+65)
));
}
return ret.join("");
}
function createRandomTable(){
var ret=["<table>"],i=0,
j=0;
while(i<50){
j=0
ret.push("<tr>");
while(j<5){
ret.push("<td>");
ret.push(getRandomText(5));
ret.push("</td>");
j++;
}
ret.push("</tr>");
i++;
}
document.getElementById("table")
.innerHTML=ret.join("");
}
createRandomTable();
// Code that does the search
tableSearchF=function(){
//private variables
var table=document.getElementById("table")
.getElementsByTagName("table")[0];
var rows=table.getElementsByTagName("tr");
var rowVals=[];
for(var i=0;i<rows.length;i++){
var tmp=[];
var c=rows[i].getElementsByTagName("td");
for(var j=0;j<c.length;j++){
tmp.push(
(c[j].textContent)?c[j].textContent:c[j].innerText
)
}
rowVals.push(tmp);
}
var searchTable=function(r){
var match=false;
var doPartial=true;
// for each row
for(var i=0;i<rowVals.length;i++){
match=false;
//for each cell
cellmatch:
for(var j=0;j<rowVals[i].length;j++){
if(r.test(rowVals[i][j])===true){
console.log("positive match");
match=true;
doPartial=false;
break cellmatch;
}
}
rows[i].style.display=(match)?"":"none";
}
return doPartial;
}
// publicly available methods
return {
search:function(searchText){
var txt = searchText.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g
,'\\$1')
.replace(/\x08/g, '\\x08'),
r = new RegExp("\\b"+txt+"\\b","igm");
if(searchTable(r)){
// no exact match, do a partial
r=new RegExp(txt,"igm");
searchTable(r);
}
}
}
}
//initialise tableSearch
var tableSearch=tableSearchF();
</script>
</body>
</html>
I am trying to enable and disable checkboxes based on selection of checkboxes. If you take a look here for a live version of my code
http://jsfiddle.net/prady/VZ4yW/3/
What i want is there cannot be 2 checkboxes selected in the same row and there cannot be 2 checkboxes selected in the same column. Looking at the link might give you a clear understanding of what i wanted.
There can be only one checkbox selected in the column "Change this parameter" and "Generate simulated value for this param" but both cant be of the same row.
Just in case you are not able to view the link here is the code
<table>
<tr>
<td></td>
<td></td>
<td>Change this parameter</td>
<td>Generate simulated value for this param</td>
</tr>
<tr>
<td>Project cost</td>
<td><input type ="text" id ="pc"/></td>
<td><input class="change" type="checkbox" name="chkBox" id="chkBox"></input></td>
<td><input class="sim" type="checkbox" name="chkBox1" id="chkBox1"></input></td>
</tr>
<tr>
<td>Avg hours</td>
<td><input type ="text" id ="avghrs"/></td>
<td><input class="change" type="checkbox" name="chkBoxa" id="chkBoxa"></input></td>
<td><input class="sim" type="checkbox" name="chkBox1a" id="chkBox1a"></input></td>
</tr>
<tr>
<td>Project completion date</td>
<td><input type ="text" id ="cd"/></td>
<td><input class="change" type="checkbox" name="chkBoxb" id="chkBoxb"></input></td>
<td><input class="sim" type="checkbox" name="chkBox1b" id="chkBox1b"></input></td>
</tr>
<tr>
<td>Hourly rate</td>
<td><input type ="text" id ="hr"/></td>
<td><input class="change" type="checkbox" name="chkBoxc" id="chkBoxc"></input></td>
<td><input class="sim" type="checkbox" name="chkBox1c" id="chkBox1c"></input></td>
</tr>
</table>
<script type="text/javascript">
$(document).ready(function(){
$('#chkBox').click(function(){
var paramChangeBoxes = $('input:checkbox.change');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBox1').attr('disabled', 'disabled');
$('#chkBox').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1').removeAttr('disabled');
}
});
$('#chkBoxa').click(function(){
var paramChangeBoxes = $('input:checkbox.change');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBox1a').attr('disabled', 'disabled');
$('#chkBoxa').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1a').removeAttr('disabled');
}
});
$('#chkBoxb').click(function(){
var paramChangeBoxes = $('input:checkbox.change');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBox1b').attr('disabled', 'disabled');
$('#chkBoxb').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1b').removeAttr('disabled');
}
});
$('#chkBoxc').click(function(){
var paramChangeBoxes = $('input:checkbox.change');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBox1c').attr('disabled', 'disabled');
$('#chkBoxc').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1c').removeAttr('disabled');
}
});
$('#chkBox1').click(function(){
var paramChangeBoxes = $('input:checkbox.sim');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBox').attr('disabled', 'disabled');
$('#chkBox1').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1').removeAttr('disabled');
$('#chkBox').removeAttr('disabled');
}
});
$('#chkBox1a').click(function(){
var paramChangeBoxes = $('input:checkbox.sim');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBoxa').attr('disabled', 'disabled');
$('#chkBox1a').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1a').removeAttr('disabled');
$('#chkBoxa').removeAttr('disabled');
}
});
$('#chkBox1b').click(function(){
var paramChangeBoxes = $('input:checkbox.sim');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBoxb').attr('disabled', 'disabled');
$('#chkBox1b').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1b').removeAttr('disabled');
$('#chkBoxb').removeAttr('disabled');
}
});
$('#chkBox1c').click(function(){
var paramChangeBoxes = $('input:checkbox.sim');
if ($(this).is(':checked')) {
paramChangeBoxes.attr('disabled', 'disabled');
$('#chkBoxc').attr('disabled', 'disabled');
$('#chkBox1c').removeAttr('disabled');
}
else
{
paramChangeBoxes.removeAttr('disabled');
$('#chkBox1c').removeAttr('disabled');
$('#chkBoxc').removeAttr('disabled');
}
});
});
</script>
You need to store busyRows and busyCols and add row and col attr to checkbox;
Update them after each change event and then update disabled attributes.
function getCB_x(elt) { return elt.parentNode.cellIndex; }
function getCB_y(elt) { return elt.parentNode.parentNode.rowIndex; }
$(document).ready(function(){
var busyRows = [], busyCols = [];
var checkboxes = $("table input[type=checkbox]");
// get topleft checkbox
var firstCb = checkboxes[0];
// and calculate its offsets
var colOffset = getCB_x(firstCb);
var rowOffset = getCB_y(firstCb)
// get bottomright checkbox
var lastCb = checkboxes.last()[0];
// calculate offsets and init busy flags
for (var i = getCB_x(lastCb) - colOffset; i >=0; i--) busyCols[i] = false;
for (var i = getCB_y(lastCb) - rowOffset; i >=0; i--) busyRows[i] = false;
// define callback
function updateCB(){
var col = getCB_x(this) - colOffset;
var row = getCB_y(this) - rowOffset;
// set corresponding row and col as "busy"
busyRows[row] = this.checked;
busyCols[col] = this.checked;
// update column with current checkbox
for (var r = 0; r < busyRows.length; r++) {
cb = checkboxes[r*busyCols.length+col];
if ((busyRows[r] || busyCols[col]) && !cb.checked) {
$(cb).attr('disabled', 'disabled');
} else {
$(cb).removeAttr('disabled', 'disabled');
}
}
// update row with current checkbox
for (var c = 0; c < busyCols.length; c++) {
cb = checkboxes[row*busyCols.length+c];
if ((busyRows[row] || busyCols[c]) && !cb.checked) {
$(cb).attr('disabled', 'disabled');
} else {
$(cb).removeAttr('disabled', 'disabled');
}
}
}
// update state for already set items
for (var i = 0; i < checkboxes.length; i++) {
var cb = checkboxes[i];
if (cb.checked) updateCB.call(cb);
}
// assign onlick handler
checkboxes.click(updateCB);
});
This code will work for any regular dense grid of checkboxes. Regular means that every row should have the same amount of checkboxes and every column should have the same amount of checkboxes. Dense means there should be no rows w/o chekcboxes between rows with checkboxes. The same for columns.
If you'll have additional checkboxes in table, which should not be included in grid, add some class to them (e.g. "non-grid") and select only cb's w/o that class:
var checkboxes = $("table input[type=checkbox]:not(.non-grid)");