I have a table of data from mysql rendered on page via PHP into a HTML table.
Within this table of data, I have a row of data that should be focussed on (let's call it) row X.
I want the 2 rows above and below row X to be shown but all others hidden, as row X moves up and down, this would change (obviously) what was hidden, when row X is at the top/bottom I want to show 4 rows below/above.
I have done this with static content and JQuery, I am just unsure how to track row X and then apply the class names as required
I thought this was an interesting request so I threw up an example here. The interesting part is the selectors to select the siblings to display. Here is a function i wrote.
function rowXMoved()
{
// hide all rows besides rowX
$('.tableCSS tr:not(.rowX)').hide();
if($('.rowX').prev('tr').size() == 0)
{
// we are row number 1, show 4 more
$('.rowX').siblings('tr:lt(4)').show(); //:lt is less than(index)
}
else if($('.rowX').next('tr').size() == 0)
{
// we are the last row
// find the index of the tableRow to show.
var rowCount = $('.tableCSS tr').size();
$('.rowX').siblings('tr:gt(' + (rowCount - 6) +')').show(); //:gt is greater than(index)
}
else
{
// show 2 rows before and after the rowX
// there is probably a better way, but this is the most straight forward
$('.rowX').prev('tr').show().prev('tr').show();
$('.rowX').next('tr').show().next('tr').show();
}
}
You can show hide the normal way and based on the current row in focus change the innerHtml of the div in focus.
Lets say there are 4 divs holding four rows of data then if focus is on div 2 then it will contain row 2 data in inner html. As focus move or onchange the content in div 2 will keep changing based on which row is in focus. I hope the drift helps
You could give each row a class name, and set a click event handler. When the user clicks for the first time, hide the entire table except for the clicked row and four below if row < 4, four above if row > row.last-4, or two above and two below (if neither of the foregoing is true).
Basically it's dom manipulation so I'd take a look at the prev() and next() functions if I were you. You can get the number of rows in the table by doing, for example, $("table > tr").length.
Noah
Okay I have wrote an example that illustrates selecting different rows. Enter a number into the box (1 - 10) and click the button. Rows 1 or 10 will be shown (here you will change your class with jQuery or whatever) with one row above or below. Selecting other numbers (2 - 9) will show its self, and show one row above and one below.
Obvously this isn't exactly what you asked for - but it should illustrate the logic of how this can be done...
Enter row:
<input id="Text1" type="text" />
<input id="Button1" type="button" value="button" onClick="updateTable()"/>
<!-- Example table, note the Ids -->
<table id="yourTable">
<tr><td id="row1">Row 1</td></tr>
<tr><td id="row2">Row 2</td></tr>
<tr><td id="row3">Row 3</td></tr>
<tr><td id="row4">Row 4</td></tr>
<tr><td id="row5">Row 5</td></tr>
<tr><td id="row6">Row 6</td></tr>
<tr><td id="row7">Row 7</td></tr>
<tr><td id="row8">Row 8</td></tr>
<tr><td id="row9">Row 9</td></tr>
<tr><td id="row10">Row 10</td></tr>
</table>
<script type="text/javascript">
function updateTable()
{
var table = document.getElementById('yourTable');
var row = parseInt(document.getElementById('Text1').value);
var rows = table.rows.length;
// Reset the classes, styles etc etc for each row
for (var i = 0; i < rows; i++) {
table.rows[i].style.visibility = 'hidden';
}
// Subtract one as we start from 0.
row = row - 1;
// Top row, select the first and one below.
if (row == 0) {
table.rows[0].style.visibility = 'visible';
table.rows[1].style.visibility = 'visible';
}
// Rows in between. Select the middle, one above and one below.
if ((row > 0) && (row < rows - 1)) {
table.rows[row - 1].style.visibility = 'visible';
table.rows[row].style.visibility = 'visible';
table.rows[parseInt(row + 1)].style.visibility = 'visible';
}
// Bottom row, select the last row and one above that.
if (row == rows - 1) {
table.rows[row].style.visibility = 'visible';
table.rows[row - 1].style.visibility = 'visible';
}
}
</script>
Related
I'm hoping I'm on the right track here....
I have some elements on my page (tables).. that are dynamically generated based on the results of querying a DB.... (I add inside of a container DIV)..
inside these tables are some text..and a handful of checkboxes... each table is the same (outside of the value of the text fields)..
When a user clicks on a checkbox.. I add an element to another container DIV off to the side.
If a user un-checks the checkbox.. it removes the element from the container DIV on the side. On each 'click' event..... I am also either adding or removing the 'selections' from an ARRAY (and also updating this array to my PHP SESSION)..
When the user is done.. they click a button and go to another page.. where this SESSION array is grabbed and reviews/summarizes their 'choices'..
*there is no FORM tags.. checkboxes are free-form in the tables (not wrapped in any FORM tags..so there is NO general POST action to grab everything.. hence the use of an array/SESSION)
If the user goes BACK to the original 'selection page' (with the tables/checkboxes)..
I am re-populating the PAGE (both re-checking any checkboxes...and re-populating the elements in the container DIV to the side.. all based on the SESSION data)
In each checkbox.. I am adding a little PHP function to write in checked="checked" or not.. when the checkboxes instantiate)
like so:
<label><input id="articlesnaming" name="Articles Naming Expert" type="checkbox" value="0.00" <?=sessionCheck($row["id"] ."-A","Articles Naming Expert") ?> onclick=""/> Articles Naming Expert</label>
FYI: on the function being called:
function sessionCheck($recordID, $checkBoxID){
if(isset($_SESSION['userPicks']) && count($_SESSION['userPicks']) != 0){
for($r = 0; $r< count($_SESSION['userPicks']); $r++){
if($_SESSION['userPicks'][$r]['recordid'] == $recordID){
for($z=0; $z < count($_SESSION['userPicks'][$r]['itemsordered']); $z++){
if($_SESSION['userPicks'][$r]['itemsordered'][$z]['name'] == $checkBoxID){
return 'checked="checked"';
}else if($z == (count($_SESSION['userPicks'][$r]['itemsordered']) - 1)){
return "";
}
}
}else if($r == (count($_SESSION['userPicks']) - 1)){
return "";
}
}
}else{
return "";
}
}
Everything up to this point works fine...
Its when I go to dynamically build/add (append) those elements in the container DIV on the side... where problems happen.
I am getting them added just fine and when a user RE-VISITS the page.. previous checkboxes they had selected were/are checked again... -and-.. the elements ARE in the container DIV to the side of the stage/screen)...
PROBLEM: When I un-check one of the checkboxes, it DOES NOT remove the element in the container DIV on the side? I have to re-click the checkbox..(which adds a duplicate).. then I can un-check it.. but it only removes the NEW one..
Everything seems to work fine until a refresh/re-visit of the page (and I have to automatically populate the checkboxes and the elements in the container DIV on the side).. then the checkboxes stop behaving/interacting with the elements that were adding through another function (still same ID's...paths..from what I can tell)....and -not- added through an initial checkbox event/action..
I am grasping at straws here.... it is perhaps because I'm using a PHP function to set the checkboxes on refresh? and it maybe doesn't know its current state? (although the visual state of the checkbox is accurate/correct)
Any ideas are appreciated.
Code used to set/un-set checkboxes & add/remove elements from the side container DIV :
<script>
//var to hold current check box clicked
var targetCheckbox;
//var to hold cumulative total
var totalPrice = 0;
//array to keep track of user picks from returned record results
//try to get SESSION array (if available/set) from PHP into jQuery using json_encode()
<?php if(isset($_SESSION['userPicks'])){ ?>
//overwrite jQuery userPicks MAIN array
var userPicks = <?php echo json_encode($tempArray) ?>;
<? }else{ ?>
//create new jQuery userPicks MAIN array, and populate through user clicks/interaction
var userPicks = [];
<? } ?>
$(document).ready(function() {
//check to see if seesion and populate checks and side column from previous picks
//if existing session, loop through and populate the CHOICES column
if(userPicks.length > 0){
console.log("SESSION EXISTS, POPULATE CHOICES COLUMN FROM ARRAY");
for(i=0; i<userPicks.length; i++){
//build up sub array data first then append at one time.
var subArrayLength = userPicks[i].itemsordered.length;
var subArray = '';
for(s=0; s<subArrayLength; s++){
subArray += '<li id="' + userPicks[i].orderid + userPicks[i].checkboxid + '">' + userPicks[i].itemsordered[s].name + '</li>';
}
$("#choicesWrapper #itemList").append('<div class="recordChoices"><h5>CASE NAME: '+userPicks[i].casename+'</h5><ul id="'+userPicks[i].recordid+'">'+subArray+'</ul></div>');
}
}
//onClick event
$('.orderOptions').on('click', 'input:checkbox', function () {
//routine when checkbox is checked
if ($(this).is(":checked")) {
$(this).prop("checked", true);
console.log("checked");
//console.log('doesnt exist..create it');
$("#choicesWrapper #itemList").append('<div class="recordChoices"><h5>CASE NAME: '+caseName+'</h5><ul id="'+resultsID+'"><li id="'+orderID+targetCheckbox+'">'+itemOrdered+'</li></ul></div>');
}else{
$(this).prop("checked", false);
console.log("un-checked");
//remove the option from right column (li element)
console.log("REMOVE TARGET: #choicesWrapper #itemList #"+resultsID+" "+orderID+targetCheckbox);
$("#choicesWrapper #itemList #"+resultsID+" #"+orderID+targetCheckbox).remove();
//check if no more children and remove parent/title (record container/div)
if ($("#choicesWrapper #itemList #"+resultsID+" li").length > 0) {
//console.log("Still has children...do nothing");
}else{
//console.log("No Children...");
$("#choicesWrapper #itemList #"+resultsID).parent().remove();
}
}
}
}
</script>
Oddly enough, when things are 'auto-populated' from the SESSION data (like on refresh or re-visiting the page) and when things 'break', unchecking the checkboxes doesn't remove things, but when I uncheck the very last checkbox in a group, it does remove the parent (so that parent removal code/routine is being executed...but not then child )
I'm thinking this is a pathing issue? (I believe I am creating things with exactly the same ID's/classes...etc).
Definitely worth the +1 if you answer! :)
The only other thing I can think of is.. HOW the userPicks array gets created.. initial visit to page, I just create an empty JS/jQuery array and wait to push/populate it when a user clicks a checkbox (code above for onClick stuff).
But when a user visits the page (refresh or re-visit) and -HAS- (previous) SESSION data still available.... then I grab the PHP SESSION array.. and pass it to jQuery using json_encode()...
Do I need to add/delete from that array differently than I do if I created normally?
There are probably other similar posts, but here goes nothing.
I am currently reworking on an existing site and some of the changes required involves column and row highlighting, like here (tutorial / demo).
Since there are several web pages to go through, I would like to have some kind of shortcut to dynamically add <colgroup></colgroup> like in the example without having to go through each page and table by hand.
I've considered php's preg_replace function, but I doubt that's the simplest way to go around it. In an optimal scenario, I would be able to verify if there is an existing <colgroup></colgroup> array for each column.
Using jQuery you could dynamically prepend the <colgroup></colgroup> to each table before your highlight script. Something like -
if($("table > colgroup").length == 0){ // If the table does not have <colgroup></colgroup>
var colCount = 0;
$('tr:nth-child(1) td').each(function () { // Get the count of table columns
if ($(this).attr('colspan')) { // if there is a <td colspan>
colCount += +$(this).attr('colspan');
} else {
colCount++;
}
});
var colgroupList = '';
for (i=0;i<colCount;i++){ // Add a <colgroup></colgroup> for each <td>
colgroupList += '<colgroup></colgroup>';
}
$("table").prepend(colgroupList);
}
$("table").delegate('td','mouseover mouseleave', function(e) {
...
jsFiddle example http://jsfiddle.net/BGR22/1/
Edit
If you have multiple tables on a page, you need to add a selector to only get the parent table -
var $table = $(this).closest("table");
So now your $("table").delegate() would look like
$("table").delegate('td','mouseover mouseleave', function(e) {
var $table = $(this).closest("table");
if (e.type == 'mouseover') {
$(this).parent().addClass("hover");
$table.children("colgroup").eq($(this).index()).addClass("hover");
} else {
$(this).parent().removeClass("hover");
$table.children("colgroup").eq($(this).index()).removeClass("hover");
}
});
Updated jsFiddle - http://jsfiddle.net/BGR22/3/
and with 3 tables - http://jsfiddle.net/BGR22/4/
In PHP, I have a dynamic number of tables, and each table has a dynamic number of rows. The last column in the table ($reasonstr) is a drop down list. I want to capture the change in that drop down. If I do this:
$('#reason2td3').change(
function(){
}
I'm able to capture what I need. However, I want this to be dynamic, based on the number of tables and rows on the page.
I have identified the tables & rows as follows:
table, where $id increases with each table on the page:
echo sprintf('<table cellspacing="0" class="myTable" id="myTable%s">',$id);
so, if there are two tables on the page, they are #myTable1 and #myTable2.
rows, where $tdid increases with each row in the table:
echo '<tbody>';
foreach ($record as $r) {
echo sprintf('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>$ %s</td><td>%s</td><td id="reason%std%s">%s</td></tr>',
$r['org_number'],
$r['dept_descr'],
$r['supplier_number'],
$r['supplier_name'],
$r['invoice_number'],
$r['receive_date'],
$r['final_qty'],
number_format($r['final_cost'],2),
$r['inv_status'],
$id,
$tdid,
$reasonstr);
$tdid++;
}
echo '</tbody></table>';
$tdid=0;
so, the 3rd row in table 2 is #reason2td3.
How do I capture the $id and $tdid from PHP and use it in JQuery?
Use the attribute starts with selector :
$('[id^="myTable"]').on('change', function(){
var $id = this.id;
// do stuff
});
That will target all elements with an ID starting with myTable, for instance myTable1, myTable2, myTableStackOverflowChineseOldMan etc.
Inserting the elements with PHP doesn't really make them dynamic, so delegated event handlers shouldn't be needed for this.
i am working in a code igniter. i have a form which contain three input boxes in a row . ..i put them in a for loop which is less then five ..so now my form has five rows with three input boxes in a row .. now what i am doing write now i am adding the values of two input boxes and displaying in 3rd input box .. now what i want to do is when every "total"(3rd input box) is filled .. then i am gonna add all the totals and then display all the totals in last box which i display at the bottom ..
here is my view
<td><input type="text" id = "price_<?php echo $i ?>"
onkeyup='addition(<?php echo "$i"?>)'>
</td>
<td> <input type="text" id = "quantity_<?php echo $i ?>" onkeyup='addition(<?php echo "$i"?>)'>
</td>
<td><input type="text" id = "total_<?php echo $i ?>">
</td>
<?php echo form_input($subtotal)?></td> // here i want to display sum of all the totals
here is my javascript..this function is multiplying the price and quantity ..i mean first and 2nd input box and then displaying in the 3rd box ..
function addition (obj)
{
var subtotal = 0;
var num1=parseInt($('#price_'+obj).val());
var num2=parseInt($('#quantity_'+obj).val());
var num4=parseInt($('#total_'+obj).val());
if ($('#price_'+obj).val() !='' && $('#quantity_'+obj).val() !='')
{
var num3=num1*num2;
$('#total_'+obj).val(num3);
}
else
{
$('#total_'+obj).val('');
}
}
i have uploaded the image also ..
I see that you use jQuery, I have modified your code a bit to use jQuery better. You can see the demo at JsBIN
The idea is lock all "total" cell, when you update one "total" cell by calculating the result. Sum all "total" cell to the "grand-total" cell. I listen on the "keyup" event.
Here is jsFiddle example: http://jsfiddle.net/Ner7M/2/
Code of interest:
var table = $('table');
// nth-child is 1-based, not 0
function totalColumn(table, idx) {
var total = 0;
var tds = $('table')
.find('tr td:nth-child(' + idx + ') input')
.each(function() {
total += parseInt($(this).val());
});
return total;
}
totalColumn(table, 3);
I have a dynamically generated table with php that has same rows. Need to get value from cell 1 in row 1 and value from cell 1 in row 2 and compare them. If they are the same remove entire row or hide... Do that for the whole table... Any help is appreciated.. Thanks!!
Haave this so far:
var numRows = $('table#changeSubjectKatedra tr').lenght;
var i = 0;
do {
var cur = $('input#'+i).val();
var next = $('input#'+(i+1)).val();
if(cur == next){
$('tr#'+i).remove();
}
i++;
} while(i<numRows);
The row in table looks like this:
<tr id='idNum'><td>someText<input type='hidden' value='someData' id='idNum'>
</td><td>someText</td></tr>
Note 1. You should do in on server side with PHP, not with JavaScript.
Note 2. You must use unique id for each element.
Note 3. Avoid using numerical ids of elements.
Note 4. You don't need ids at all for doing what you want.
If you still want to do it in JavaScript, I suggest you to do it this way: (live demo here)
var rows = $("#changeSubjectKatedra tr");
for(var i = 0; i <= rows.length - 2; i++) {
if ($(rows[i]).find("input").val() ==
$(rows[i+1]).find("input").val()) {
$(rows[i]).remove();
}
}
You can use jQuery's .each function. This should work according to the description you provided:
$('table#changeSubjectKatedra tr').each(function() {
if (repeat == $(this).children("input")[0].value) {
$(this).remove();
}
repeat = $(this).children("input")[0].value;
});