Clicking row in table 'checking' checkbox? - javascript

I hope this is the right area, as it is more theoretical than anything else. I am currently working on a page where a user can select one or many rows to edit by clicking a checkbox in the leftmost column and clicking an Edit button. I haven't decided if I wanted to try programming this feature, but would it be possible to effectively hide the checkboxes and use some sort of javascript or jquery to make clicking a row in a table equivalent to checking the corresponding row's checkbox? I have just started working with javascript and jquery, and I am baffled by how powerful this can be. Please inform me if this type of functionality is possible and if so, what is a general approach to achieving this behavior?

Doable. Here's how:
jsbin link
HTML
<table border=1>
<tr><td><input type="checkbox"></td><td>Something 1</td><td>Something else 1</td></tr>
<tr><td><input type="checkbox"></td><td>Something 2</td><td>Something else 2</td></tr>
<tr><td><input type="checkbox"></td><td>Something 3</td><td>Something else 3</td></tr>
<tr><td><input type="checkbox"></td><td>Something 4</td><td>Something else 4</td></tr>
</table>
jQuery
$('input[type=checkbox]').parent('td').hide(); // If JS disabled, checkboxes are still visible
$('table tr').click( function() {
var $chk = $(this).find('input[type=checkbox]');
$chk.prop('checked',!$chk.prop('checked'));
$(this).toggleClass('selected'); // To show something happened
});
CSS
tr.selected{
background-color:#ccc;
}

Yes this is perfectly achievable, although you might like to consider the accessibility implications in the event that somebody has JavaScript disabled in their browser.
There are a number of approaches you could take. By way of example, you could use a click handler something like the following (untested):
$(document).on('click', '#yourtable tr', function(evt) {
$(this).toggleClass('selected');
});
This would give each tr in your table (with id #yourtable) the class selected which you could then either style via CSS and/or read back via another piece of jQuery.
Within the event handler you could also perform other actions to record the selection, such as updating a hidden input field, posting straight back to the server, or checking the existing checkbox (which could optionally be hidden if you prefer).

Here is a simple implementation of the requested functionality:
$(document).ready(function() {
$('tr').click(function(e) {
var $checkbox = $(this).find('input');
var isChecked = $checkbox.prop('checked');
if (isChecked) {
$checkbox.removeProp('checked');
}
else {
$checkbox.prop('checked', 'checked');
}
});
});​

Related

Jquery Datatables.net : After sorting the table, odd times, the listeners don't work

I'm working with tables from datatables.net and i have an issue, very tricky to solve and i need ideas from everybody. So this is my table
I apply an event handler to every checkbox that i have in every row
my event handler is
function checkListagem() {
$('input:checkbox.checkboxinput').on('click',function (e) {
this.checked ? listagensParaCartas.push($(this).attr('id')) : listagensParaCartas.pop($(this).attr('id'));
var tem = $(this).parents("tr").hasClass("selecionada");
if (!tem) {
$(this).parents("tr").addClass("selecionada");
}
else {
$(this).parents("tr").removeClass("selecionada");
}
});
}
i also tried
$('"#listagens input:checkbox').on('click','.checkboxinput', function (e)
where listagens is the id of the datatable. When i click in the checkbox this aplly the name class "selecionada". example in this case i have
<tr class="odd selecionada>...</tr>
<tr class="even>...</tr>
<tr class="odd>...</tr>
but when i sort by the columns "Listagem" "Data Criação" or orther, they dont always apply the class to that tr. but is i replace for example this
$(this).parents("tr").addClass("selecionada");
for this
$(this).parents("tr").css("color","red");
the event handler works with the css but not with the addclass, or removeClass.
BUT if i click again sometimes work, sometimes dont. i think if i click sorting even times in the same column it goes back to work right, but when is odd times, does apply the class.
For now i'm going to disable the sorting, more important is having the selected, or in portuguese "selecionada", but i really need some really good idea. Thank you in advance.

Button Click to set value in table input fields in Javascript

I have table structure has created in
https://jsfiddle.net/u8sdko1a/1/
in Button Click i want to set value in table input fields.
Js Code:
$('#regform tr#cny-1131').each(function() {
$(this).find("input.dedicate").val(name);
$(this).find("input.chinese_name").val(chinese_name);
});
This code is working in Firefox but not in IE and Chrom.
Please anyone help to resolve this issue
There are plenty of errors in your jsfiddle. First you have not included the JQuery to load on the page load. Then you have used the id selector regform-0 and regform which is id for <td> and from that you have used $('#regform-0 tr#cny-cny-1130') which will look for a <tr> that is the child of element with id #regform-0. Since the element with id regform-0 is itself a <td> how can it find a <tr> as a child. Another mistake was in the class name for dedicated, it's dedicate. Overall the working code is like this
$(document).ready(function () {
$(".cny_order").on("click", function(e) {
$('#chinese tr.cny_item').find("input.dedicate").val("Tesst");
$('#chinese tr.cny_item').find("input.chinese_name").val("erer");
});
});
For your workaround here is the link to JSFIDDLE

Access hidden checkboxes with javascript and jQuery

I have a datatable, where each row has a checkbox. I'm trying to add select-all functionality to this set of checkboxes, for which I created the following function:
function selectAll() {
$(':checkbox').each(function() {
this.checked = true;
});
}
This works to select all checkboxes which are currently visible, however, the checkboxes on other pages of the datatable are not selected. I know that there is an issue with these checkboxes in general, since to submit the form and include those checkboxes, I had to add the following function:
$('form').submit(function() {
oTable1 = $('#mytable').dataTable();
$(oTable1.fnGetHiddenNodes()).find('input:checked').appendTo(this);
});
So I suspect that in order to check these checkboxes, I will somehow have to append them to the DOM, at least temporarily, check them off, and then remove them from the DOM. Or is there something simpler that I can do?
I managed to get this work using the following:
oTable1 = $('#mytable').dataTable();
$(oTable1.fnGetNodes()).find(':checkbox').attr('checked',true);
As an alternative, you can also use
$(oTable1.fnGetFilteredNodes()).find(':checkbox').attr('checked',true);
which will apply the "select-all" only to the rows that match the current filter.

how to hide field in same row as field its dependent on

I'm pretty novice at jquery but I have a table with a field in each row that is dependent on another field (checkbox) in the row. Since its in a table I need to handle them in bulk. I don't think I'm using next() correctly but I'm trying to grab the next .subnet_mask since it will be the one in the same row as hide it. I'll also have to update it once I get that far so that it handles hiding and showing if the checkbox is checked or not.
$(function() {
$('.dhcp').each(function() {
$(this).click(function(){
$('.subnet_mask').next().hide();
});
});
});
Any help is appreciated!
EDIT: ok ok :) well the page is actually written in VisualForce (for salesforce). For simplicty sake lets say its just a form wrapped around a table (up to 20 rows representing different records) displaying a checkbox field with the class .dhcp and a field after it called .subnet_mask that should be shown/hidden based on the checkbox. Is that helpful?
I'd rather do this
$('.dhcp').on('click', function() {
$(this).nextAll('.subnet_mask').toggle();
});
Then you show/hide the next .submask (assuming one .submask per <tr>) each time you click the .dhcp
I'd suggest the following, though this suggestion may well change once I see the relevant HTML:
$('.dhcp').click(
function(){
$(this).closest('tr').find('.subnet_mask').hide();
});
This assumes that there will be only one .subnet_mask element per row (otherwise this will hide all of them) in response to the click event. You mention that this depends upon a checkbox, so perhaps the following would be better, using the change() method:
$('.dhcp').change(
function(){
var that = $(this);
if (that.is(':checked')) {
that.closest('tr').find('.subnet_mask').hide();
}
else {
that.closest('tr').find('.subnet_mask').show();
}
});
References:
change().
:checked selector.
click().
closest().
find().
hide().
is().
show().
You're using next incorrectly. It should be more like this:
$(function() {
$('.dhcp').each(function() {
$(this).click(function(){
$(this).next('.subnet_mask').hide();
});
});
});
For this case, I'm assuming that .dhcp and .subnet_mask are indeed siblings, wit the latter coming immediately after the former. Otherwise, .nextAll() can be substituted for .next()
Edited as per point below.

How to align form fields within a table for inline editing?

I am developing a webapp using Spring, jsp, javascript, jquery.
I display a table using datatables.
When I click on a table row I want it to change all fields to an inline edit inputs, selects etc. In addition I want to show some extra input fields in the next row and a save button.
Now I see several ways of doing this. I am not sure which one to take.
I can get a handle to selected row and then iterate over the td and transform them to input/select fields. I can then insert an extra row for the new fields and the save button.
I don't see this as a clean solution. I will have to issue a Post manually instead of using the Spring ModelAttribute binding for the form. (Can I still use ModelAttribute here?)
I can create an edit form in a jsp file which looks like:
<form:form action="" commandName="">
<td> <input ... > </td>
<td> <select ... > </td>
</tr>
<tr>
<td> <label> <input new field> </td>
<td> <button> </td>
</tr>
Note I do not have a beginning in a jsp file as I plan to reuse the tr from the existing row in the table.
This way I would be able to have a clean form and also use the update method I have already written which binds the form to a Java class. Also I do not have to bother about the alignment of input fields with the column names.
The generated html looks like
...
The problem with this approach is the placement of form element in the html causes the entire form to be cramped into one cell of the table which does not look good and messes up the whole layout. Is there a way out? Should I just replace the contents of the table with a having a colspan and then put divs inside this element and fine tune the css to ensure that the input fields align with the column names in the table?
Is there a better solution you can suggest?
In case the question is not very clear I can fill in more details.
This is what I would do (coming from a server-side development background, as I know developers love easy solutions)
Wrap the table with a single form
on Edit row (clicking row) open an ajax request that returns pure html that looks like the exact tr, only with whatever extra you want to include:
<tr><td><input type="text" name="text1" ... /></td><td>second row... </td></tr>
<tr><td colspan="2">And hey, here is more, and the save button ... </td></tr>
in jQuery replace tr with content retrieved (myTr.replace($(ajaxResponse))) or something similar
now Save button is a regular submit for the form
if you want to submit via ajax, once done, return the old html in your ajax response and replace the two trs with the old tr (you just need to hook it by giving new trs an attribute that you can find easily in jquery)
don't forget to switch off a global key to prevent double editing, users can edit one row at a time
Update: adding a second solution to dump load on client instead of server
To avoid overloading the server (though I wouldn't be worried about it until it becomes a regular habit), you can make your form fields as a template inside your HTML and use string replacement (or jQuery Templates), so instead of ajaxing to get response in step 2, you call the template, and replace the strings with attributes you save in every row... like this:
<div id="myTemplate"> // or you can use jQuery script templates
<tr><td><input type="text" name="${Name}" ... /> id is ${Id}</td><td>${SecondRow}... </td></tr>
<tr><td colspan="2">Save button here.... and may be more text ${MoreText}</td></tr>
</div>
in every row in your code add sufficient attributes or ids to know what you want to replace with, like this:
<tr data-itemid="34"><td ><input type="text" name="text1" id="findme" ... /></td><td data-moretext="here is more text">second column </td></tr>...etc
so now in your replacement script:
$("#myTemplate").html().replace("${Name}", $(thisrow).find("#findme").attr("name"))
.replace("${Id}",$(thisrow).attr("data-itemid"));
etc...
Of course after submission it has to be a to server, but in case user "cancels" you can have another readonly template
By the way, that is the way I usually go with, I use jQuery templates, and create edit and view templates, but I also repeat edit forms and I use jQuery ajax submit manually... but that... my friend, is not a simple clean and maintainable solution I'm afraid
I've been into an issue like this a year before. This is a messy problem. Either way if you traverse each td of row and convert it into text field or You can create a separate jsp file for this.
But the best in this case is to change the content of td to input field and post the data manually. because in this case you cannot wrap form tag around tr. You have to manually post the values of each input field.
P.S The very best solution is to create an edit dialog.
There is another solution, but I'm under the impression you won't like it very much... you can use a single form for the whole datatable (wrapping the whole table in a form is permitted) generate input fields for the current row and if it's updated submit the form asyncronously with javascript and restore td contents to the original html, if you name your fields such as name="field[]" you can also submit multiple rows at a time (I don't know if you'd want that though).
You can write html code such as
<form action="">
<table>
<tr><td><input type="hidden" name="row[]" value="1"/><input name="field[]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input type="hidden" name="row[]" value="3"/><input name="field[]"/></td></tr>
</table>
</form>
you can just grab the form with jquery and submit it via xmlhttprequest as I suspect you would if each row was a separate form (which is illegal), if you don't want multiple rows, just remove the [] and submit each row
and upon submitting the values you get them numbered correctly, don't know exactly how it would behave in java but in php I'd get the following:
$_GET[row][0] = 1;
$_GET[field][0] = 'value typed in row1';
$_GET[row][1] = 3;
$_GET[field][1] = 'value typed in row3';
Alternative table definition to avoid having the same name again
<form action="">
<table>
<tr><td><input name="field[1]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input name="field[3]"/></td></tr>
</table>
</form>
It's the same table as above only you set explicit indexes for each entry thus avoiding duplicate names in the response, preferrably use a unique identifier which can describe the row from the table that you're modifying in there (when possible I use the primary key) instead of the row number, just in case that wasn't clear enough.
Have you tried:
Wrap whole table in the form
have the data entries as disabled inputs with their borders hidden via CSS
when user clicks edit, enable the inputs and show the borders
You'll probably need hidden elements for each field
When user submits the form, post via ajax and set the inputs back to disabled with hidden borders
What about contenteditable?
Demo: http://jsfiddle.net/SO_AMK/XQekC/
jQuery:
var ctrlDown = false;
$(document).keydown(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = true;
}
}).keyup(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = false;
}
});
$('#example').dataTable();
$("#example tr").click(function() {
if ($(this).hasClass("row_selected") && ctrlDown) {
submitRow($(this));
return false; // Break out so the next if doesn't run
}
else if ($(this).hasClass("row_selected") && ctrlDown == false) {
return false; // Break out so the next if doesn't run
}
if ($(this).siblings(".row_selected").length && ctrlDown == false) {
$(this).siblings(".row_selected").each(function() {
submitRow($(this));
});
}
$(this).addClass("row_selected");
$(this).children("td").each(function() {
$(this).attr("contenteditable", true);
});
});
function submitRow(elm) {
var data = [];
$(elm).removeClass("row_selected").children("td").each(function() {
data.push($(this).text());
});
alert(data); // This will stop the keyup from firing, but you won't (I hope) really be using alerts
}​
This has everything but a submit-to-server function, it's also completely inline and has support for selecting multiple rows.
The only bug is, when it shows the data alert the focus goes off of the main window so the keyup event never fires, since you probably won't be using alerts this shouldn't be an issue. To fix it in the fiddle, press and release ctrl after the alert closes before clicking a row.
I see couple of problems
Your no. Of columns in the table & the edit columns you show are different
You might not be having complete data to edit the row so you might need to do an Ajax call and get it
If you have complete data on then you don't need point 2, let's assume you have a function f called with the clicked tr as the parameter
function f(row)
{
var newRow = yourTable.insertRow(parseInt(row.rowIndex,10)+1);
//you can place the above or below the clicked row , or you can even make the row visible false And then show the new row
Var newCell = newRow.insertCell(0);
newCell.colspan = 6;//the count if columns in your table row
NewCell.innerHTML = " put your HTML content here";
}

Categories

Resources