Making a row editable based on a checkbox in HTML - javascript

I have a table in HTML. The contents of this table are dynamically populated. Every row of the table has text boxes and one checkbox. When the page is loaded, all the text boxes in the rows will be in a read-only state.
Now, i want to change the state of the text boxes in a particular row to editable, if the check-box in that row is selected. Also, the text boxes should be made read-only if the check box is de-selected.
How could I accomplish this using Javascript? Please help me.

stating this with plain javascript would be pure pain :)
i suggest using jQuery, eg:
$(':checkbox').click(function() {
var checkbox = $(this);
var row = checkbox.closest('tr');
var inputText = $('input[type=text]', row);
if (checkbox.is(':checked')) {
inputText.attr('readonly', 'readonly');
}
else {
inputText.removeAttr('readonly');
}
});
otherwise
function HandleClickOnCheckbox() {
var checkbox = this;
var row;
var iter = checkbox;
while (!row) {
iter = iter.parent;
if (iter == window) {
break;
}
if (iter.tagName == 'tr') {
row = iter;
break;
}
}
if (!row) {
alert('row not found');
return false;
}
var textBoxes = GetTextBoxes(row);
var method;
if (checkbox.checked) {
var disabledAttribute = document.createAttribute('disabled');
disabledAttribute.nodeValue = 'disabled';
method = function(textBox) {
textBox.setAttributeNode(disabledAttribute);
};
}
else {
method = function(textBox) {
textBox.removeAttribute('disabled', 0);
}
}
for (var i = 0; i < textBoxes.length; i++) {
var textBox = textBoxes[i];
method(textBox);
}
}
function GetTextBoxes(element) {
var textBoxes = new Array();
for (var i = 0; i < element.children.lenght; i++) {
var child = element.children[i];
if (child.tagName == 'input') {
if (child.type == 'text') {
textBoxes.push(child);
}
}
if (child.tagName == 'td') {
var childTextBoxes = GetTextBoxes(child);
if (childTextBoxes.length) {
for (var j = 0; j < childTextBoxes.length; j++) {
var childTextBox = childTextBoxes[j];
textBoxes.push(childTextBox);
}
}
}
}
return textBoxes;
}
this is not tested!

Perhaps, you can start by handling the click event of the checkbox using an if/else statement to check if the checkbox is actually checked. If it is you can use the row within which the checkbox resides to find all the textboxes in the different cells and enable/disable them.
Are you using JQuery or plain Javascript?

If you don't mind using jQuery, you could do:
$('checkbox').click(function() {
if ($(this).attr('checked')) {
$(this).parents('tr').children('input[type="text"]').each().attr('readonly', 'readonly');
} else {
$(this).parents('tr').children('input[type="text"]').each().removeAttr('readonly');
}
})
Or something like that. I'd have to test it to be sure.
Edited to reflect Andreas's comment.

Try this snippet (assumes that the checkbox has a class called "checkbox") if you are using Jquery.
jQuery('tr.checkbox').click(function() {
if (jQuery(this).is(":checked")) {
jQuery('td', this).removeAttr('disabled');
} else {
jQuery('td', this).attr('disabled', '');
}
});`

Related

I have 3 Data tables in one page i need select one in each Table

I am trying following it selecting from only one datatable
selectFirstRow(window.document.forms["irsf-form"]);
i have id's for each table "test_config","uma","example".
i had tried
selectFirstRowInTable(document.getElementById("irsf-form:test_config"));
selectFirstRowInTable(document.getElementById("irsf-form:uma"));
selectFirstRowInTable(document.getElementById("irsf-form:example"));
I have Script in that
function selectFirstRowInTable(tableObj) {
var tbodyObj = tableObj.getElementsByTagName("tbody")[0];
var inputObjs = tbodyObj.getElementsByTagName("input");
var tempChild = null;
var firstRow=-1;
for(var i=0;i<inputObjs.length;++i) {
tempChild = inputObjs[i];
if(tempChild.type == 'radio') {
if ( firstRow < 0 ) {
firstRow = i;
tempChild.checked = true;
} else {
tempChild.checked = false;
}
}
}
}
Not getting the value by id when i try getElementById
<h:dataTable binding="#{iRSFConfigBean.table}" border="1" rowClasses="evenRows,oddRows" id="test_config" name = "test"
rules="all" headerClass="standardTableHeader" styleClass="standardTable" value="#{iRSFConfigBean.configList}" var="config">
Hope this code will help you:
$('table').find("tr:first")

JavaScript table for loop wrong checkbox value

I'm for looping data in my page, and they are showing fine, but when I'm trying to click one of three checkboxes and hide desired rows, it seems that get the wrong value.
This is the link of the live page in action.
This is the code that needs to be fixed.
https://musing-jang-0e572c.netlify.com/senate-data.html -> PAGE
https://github.com/Makkoyev/ubiqum-task2/blob/master/assets/js/manipulation.js -> Checkboxes section GitHub
This is the code:
(function () {
if (currentURL.indexOf("senate-data.html") == true) {
getSenate();
cbs = document.querySelectorAll("input[type=checkbox]");
targets = document.querySelectorAll("#table tr td:nth-child(2)");
tr = document.querySelectorAll("#table tr");
for (i = 0; i < cbs.length; i++) {
cbs[i].addEventListener('change', function () {
if (this.checked) {
// Checkbox is checked..
console.log("Checkbox checked!", this.value);
for(i = 0; i < targets.length; i++){
if(this.value == targets[i].innerHTML){
console.log("Uguale", targets[i]);
targets[i].parentNode.classList.add("hide-row");
}
}
} else {
// Checkbox is not checked..
console.log("Checkbox unchecked!", this.value)
}
});
}
}
if (currentURL.indexOf("house-data.html") == true) {
getHouse();
}
})();
You likely want something like this
FIDDLE
window.addEventListener("load", function() { // on page load
[...document.querySelectorAll("input[type=checkbox]")].forEach(function(cbs) { // take all checkboxes
cbs.addEventListener('change', function() { // when they change
var vals = [...document.querySelectorAll(".filters input[type=checkbox]:checked")].map(chk => chk.value); // get all checked values
[...document.querySelectorAll("#table tr td:nth-child(2)")].forEach(function(target) { // for all cell 2
target.parentNode.classList.toggle("hide-row",
vals.indexOf(target.textContent) == -1); // hide the ones NOT in the above list
});
});
});
})

Function to display returned results count isn't working as expected

My jQuery checkbox filter works normally:
http://jsfiddle.net/EducateYourself/Lmehmj26/3/
Under checkbox form I want to show the number of results. It is 7 by default.
When I filter the results, it does not show the correct number of displayed results.
Could you please help me to find my mistake?
I commented the lines in my jsfiddle code where I added variable n to achieve the result I want.
$('.category').on('change', function () {
var n; //declare variable n
var category_list = [];
$('#filters :input:checked').each(function () {
var category = $(this).val();
category_list.push(category);
});
if (category_list.length == 0) {
$('.resultblock').show();
} else {
$('.resultblock').hide();
});
$('#count').text(n); // change the results qunatity
}
});
The problem is that you are incrementing n multiple times for a single element if it contains multiple matching tags.
You should only increment n once, at most, for each element:
Updated Example
$('.resultblock').each(function() {
var item = $(this).data('tag'),
itemArray = item.split(' '),
hasTag = false;
for (var i = 0; i < category_list.length; ++i) {
if (itemArray.indexOf(category_list[i]) >= 0) {
hasTag = true;
}
}
if (hasTag) {
$(this).show();
n++; // Only increment n once, at most, for each element.
}
});
Here is a cleaner, simplified version of your code:
Updated Example
$('.category').on('change', function() {
var categoryList = $('#filters :input:checked').map(function() {
return this.value;
}).get();
var count = 0;
$('.resultblock').hide().each(function() {
var itemTagsArray = $(this).data('tag').split(' ');
var hasTag = false;
categoryList.forEach(function(tag) {
if (itemTagsArray.indexOf(tag) > -1) {
hasTag = true;
}
});
if (hasTag) {
$(this).show();
count++;
}
});
$('#count').text(count);
});
You're counting doubles, a very easy fix is to add a check for visibility in your for loop like so
for (i = 0; i < category_list.length; ++i) {
if (itemArray.indexOf(category_list[i]) >= 0 && !$(self).is(":visible")) {
$(self).show();
n=n+1; //increase the value of n if found a result
}
}
As shown in this fiddle, that works
As a sidenote, your numbering breaks when you've selected one or more checkboxes and then deselect all. To prevent this you should change your check if there's been any checkboxes checked to
if (category_list.length == 0) {
$('.resultblock').show();
$('#count').text($('.resultblock').length);
}

What is the plain Javascript equivalent of .each and $(this) when used together like in this example?

What is the plain Javascript equivalent of .each and $(this).find when used together in this example?
$(document).ready(function(){
$('.rows').each(function(){
var textfield = $(this).find(".textfield");
var colorbox = $(this).find(".box");
function colorchange() {
if (textfield.val() <100 || textfield.val() == null) {
colorbox.css("background-color","red");
colorbox.html("Too Low");
}
else if (textfield.val() >300) {
colorbox.css("background-color","red");
colorbox.html("Too High");
}
else {
colorbox.css("background-color","green");
colorbox.html("Just Right");
}
}
textfield.keyup(colorchange);
}
)});
Here's a fiddle with basically what I'm trying to accomplish, I know I need to use a loop I'm just not sure exactly how to set it up. I don't want to use jquery just for this simple functionality if I don't have to
http://jsfiddle.net/8u5dj/
I deleted the code I already tried because it changed every instance of the colorbox so I'm not sure what I did wrong.
This is how to do what you want in plain javascript:
http://jsfiddle.net/johnboker/6A5WS/4/
var rows = document.getElementsByClassName('rows');
for(var i = 0; i < rows.length; i++)
{
var textfield = rows[i].getElementsByClassName('textfield')[0];
var colorbox = rows[i].getElementsByClassName('box')[0];
var colorchange = function(tf, cb)
{
return function()
{
if (tf.value < 100 || tf.value == null)
{
cb.style.backgroundColor = 'red';
cb.innerText = "Too Low";
}
else if (tf.value > 300)
{
cb.style.backgroundColor = 'red';
cb.innerText = "Too High";
}
else
{
cb.style.backgroundColor = 'green';
cb.innerText = "Just Right";
}
};
}(textfield, colorbox);
textfield.onkeyup = colorchange;
}
var rows = document.querySelectorAll('.rows');
for (var i=0; i<rows.length; i++) {
var row = rows[i];
var textfield = row.querySelector('.textfield');
var colorbox = row.querySelector('.box');
// ...
}
Note that you must use a for loop to iterate the rows because querySelectorAll() does not return an array, despite appearances. In particular, that means that .forEach() isn't valid on the returned list.

Asp.net multiple gridviews, checkboxes in headertemplate select all / deselect all functionality

I am using two gridview controls in my aspx page. And I have a column of checkbox in both my controls. I am facilitating the user to select/deselect all checkboxes in my both gridviews by providing a checkbox in the header template of both gridviews and using java script functions. below is the code
<script type="text/javascript">
function UncheckParent(obj) {
var isUnchecked = obj.checked;
if (isUnchecked == false) {
var frm = document.forms[0];
for (i = 0; i < frm.length; i++) {
if (frm.elements[i].id.indexOf('chkSelectAllCheckboxes') != -1) {
frm.elements[i].checked = false;
}
}
}
}
function CheckAll(obj) {
var row = obj.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
var inputs = row.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox") {
inputs[i].checked = obj.checked;
}
}
}
</script>
But the problem is that once i select or deselect one of such checkboxes all checkboxes in both the gridviews get checked. I can also give a short example of what is happening. Two gridviews gdvwStudents and gdvwTeachers. Both have checkbox column and a check box in header template. using above code when I click header checkbox of gdvwStudents, all checkboxes in gdvStudents and gdvTeachers get selected. Please
You are doing it wrong. You should be getting the check boxes inside the particular grid where the header is clicked; instead, you are getting ALL the checkboxes created on the form! That's incredibly inefficient and explains why everything is checked/unchecked regardless of which header you click.
If you can use jQuery, you should be able to rewrite those functions into something like this:
function checkAll(gridID,checkbox) {
$("#"+gridID+" input:checkbox").attr("checked",checkbox.checked);
}
See this jsfiddle for a quick example.
Add the javascript function as per below
<script type="text/javascript">
function SelectAll(id, grd) {
//get reference of GridView control
var grid = null;
if (grd = "1") {
grid = document.getElementById("<%= GridView1.ClientID %>");
}
else {
grid = document.getElementById("<%= GridView2.ClientID %>");
}
//variable to contain the cell of the grid
var cell;
if (grid.rows.length > 0) {
//loop starts from 1. rows[0] points to the header.
for (i = 1; i < grid.rows.length; i++) {
//get the reference of first column
cell = grid.rows[i].cells[0];
//loop according to the number of childNodes in the cell
for (j = 0; j < cell.childNodes.length; j++) {
//if childNode type is CheckBox
if (cell.childNodes[j].type == "checkbox") {
//assign the status of the Select All checkbox to the cell checkbox within the grid
cell.childNodes[j].checked = document.getElementById(id).checked;
}
}
}
}
}
</script>
and handle Rowbound event of gridviews bind call of javascript function as per below
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
//Find the checkbox control in header and add an attribute
((CheckBox)e.Row.FindControl("cbSelectAll")).Attributes.Add("onclick", "javascript:SelectAll('" +
((CheckBox)e.Row.FindControl("cbSelectAll")).ClientID + "'" + ", '1')" );
}
}
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
//Find the checkbox control in header and add an attribute
((CheckBox)e.Row.FindControl("cbSelectAll")).Attributes.Add("onclick", "javascript:SelectAll('" +
((CheckBox)e.Row.FindControl("cbSelectAll")).ClientID + "'" + ", '2')" );
}
}
This is how I managed it:
function UnCheckAllContainer(obj) {
var isUnchecked = obj.checked;
if (isUnchecked == false) {
var frm = document.forms[0];
for (i = 0; i < frm.length; i++) {
if (frm.elements[i].id.indexOf('chkSelectAllCheckboxesContainers') != -1
) {
frm.elements[i].checked = false;
}
}
}
}
function CheckAllContainer(chk) {
$('#<%=gdvwContainers.ClientID %>').find("input:checkbox").each(function () {
if (this != chk) {
this.checked = chk.checked;
}
});
}

Categories

Resources