how to bind jquery change event to dynamic tables/rows? - php

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.

Related

How to get the value of entire dynamic row in PHP?

I have a table that is being populated by a given sql query, that has a radio button at the end.
How can i get the entire row value of a selected radio button passed to a different page?
results=mysqli_query($conn,$sqlitem);
while ($dat=mysqli_fetch_assoc($results)){
echo "<tr>";
echo "<td>".$dat['sellername']."</td>";
echo "<td>".$dat['itemname']."</td>";
echo "<td>".$dat['maker']."</td>";
echo "<td>".$dat['details']."</td>";
echo "<td>".$dat['condition']."</td>";
echo "<td>".$dat['price']."</td>";
echo "<td> <input type='radio' name='selc' width ='5px'> </td>";
echo "</tr>";
}
I have tried various combinations but for some reason the entire row value doesn't come. The last and closest option that I tried was this SOMETHING CLOSELY SIMILAR
I took the script portion and updated still isn't working. I believe there should be some solution for this.
You should probably use the MySQL primary key for each row, pass that info to the next page and have PHP perform a query for that item on the new page rather than explicitly passing content around from page to page.
That said, you can keep track of the order that you are echoing the keys in an array, then use that array to turn the row into an object:
var keys = ['sellername','itemname','maker','details','condition','price'];
$('input[type=radio]').on('change', function(event) {
if (this.checked) {
var $tr = $(this).closest('tr');
var $cells = $tr.find('td');
var obj = {};
$.each($cells, function(index, cell) {
obj[keys[index]] = cell.textContent;
});
console.log('row data', obj);
}
});
Note this is untested, but just demonstrates how you can match up an array of key names to the index their data can be found in a table cell

jQuery iterate through table column

I'd like to iterate through a tables columns. Given I have a cell Id, I then want to get the values of the rest of the cells in that column.
The reason for this is, I want to add some validation so that 3 cells in a column, can't all contain the same class.
I'm open to ideas using both jQuery or PHP.
If you require more information, please comment.
In JQuery to get an item's column:
var column = $('#myID').index();
To parse through the table by the nth column:
var columnNth = $('#myID').index() + 1;
var items = [];
$('#tblID tbody tr td:nth-child('+columnNth +')').each( function(){
//add item to array
items.push( $(this).attr('class'); );
});

Codeigniter get value from table row for edit or delete

I am retrieving data from MySQL table and displaying in a HTML Table by <?php foreach ?> loop like below.
Now I want to edit/delete the data of a particular row of the above HTML table by pressing the edit or delete button of the table. My MySQL table primary key is branch_code.
I know how to update/delete data in MySQL table in Codeigniter but I do not know how to retrieve the data from the table row. I could not try because I do not know how to start it.
I found similar questions like
Get values from html table using codeigniter
PHP-CodeIgniter: How to get the corresponding html table row values to be deleted by Javascript
In No#1 it was written Collect all this data in an array and "send" it to your PHP via an Ajax POST request. ----- ok great, but how could I do that ?
Can you please help me ?
May be my question is duplicate, but I didn't get any answer from those originals or I would say, I am unable to proceed the process.
Thank you in advance.
Update:
from the No#2 I got the below...
$(document).on('click', '#deleteRow', function() {
var obj = $(this).parent().parent();
var companyId = obj.attr('branch_code');
obj.remove();
});
I understood that I should add unique attribute to <tr>.
Now how can I pass the value in a variable to a model so that I can update my MySQL table ($this->db->where('branch_code', $branch_code);) ?
The way I usually do this is when you make render the html table you would create a unique id for each <tr> , so you'd do something like this:
<?php foreach ( $table->result() as $row): ?>
<tr id="branch_<?= $row->branch_code ?>">
<td>Whatever you want here</td>
<td></td>
</tr>
<?php endforeach; ?>
Then you can do an AJAX call to delete and grab that id with it.
<script>
function deleteBranch(id) {
$.post('controller_url', {"branch_code" : id }, function(data){
//Your controller method would echo a 1 for success
if (data == 1) {
$("#branch_" + id).fadeOut();
//show some kind of message
}
});
}
</script>
So from the controller you could now have a $this->input->post("branch_code") that you could reference to get the branch to delete.

best practice for updating a list in database associated with checkboxes in a html form

I have thought of two solutions to my problem and I would like to know all good viable solutions if you think there may be better.
I have a list in my MySQL database which is associated with a check-box in my html form. I want to add or delete the list items with the form and subsequently do the same in my database. I have an auto-increment ID column for the list. The problem is, how do I update the table as I perform my add and delete operations. The list must be ordered chronologically, which is usually done by the database automatically as we add new items to the table.
Solution 1:
The check-boxes will have name attribute 'items[]' so when I can read them in as a $_POST array and delete the matching list item in my database. This of course requires that my ID column always be ordered continuously from first to the last, ie. 1, 2, 3... So I'll have to update the ID column every time I delete an item. The solution is suggested here: Reorder / reset auto increment primary key
Solution 2:
I give the new item a checkbox value that equals the max ID+1, so that each time an item is entered, the ID is distinct. This way I don't have to update the ID column. I just need to find the largest ID in my table and add 1 to it for my checkbox value.
To summarize, the first way updates the list ID's each time an item is deleted, which seems to be a bigger hassle. The second way just gives a new distinct ID value and I'll just query the database for the largest ID at the time, which seems more efficient.
I'm open to other suggestions :) much obliged
This is a quick response and may not do everything the way you need, but hopefully there are some ideas you can use.
Here's a solution using one field, in one table.
Imagine a table named "scratchpad", with one field called "cb_list".
Store the checkboxes/IDs in the cb_list field as a JSON string:
{"cb1":1,"cb2":0,"cb3":0,"cb4":1}
When creating page, a PHP command reads the field and converts into an array:
$cb_json = mysql_result(mysql_query("SELECT `cb_list` FROM `scratchpad`"), 0);
$cb_arr = json_decode($cb_json);
Now, loop through that array and create HTML for the checkboxes:
$out = '<div id="chkboxDIV">';
foreach( $cb_arr AS $key =>$val ){
$chkd = ($val==1) ? 'checked="checked"' : '';
$out .= $key. " <input type='checkbox' id='" .$key. "' " .$chkd. " />";
}
$out .= "</div>";
echo $out;
To add a new checkbox, you can use jQuery (or js) code to append a new checkbox to the DIV:
var lbl = prompt('Label?');
$('#chkbox').append(lbl+ ': <input id="' +lbl+ '" type="checkbox" /> ');
When checkboxes are ready to be stored again, use this javascript to loop through the checkboxes and save their IDs and values:
var arrCB = {};
$("#chkbox>input[type='checkbox']").each(function(){
var el = $(this);
var id = el.attr('id');
arrCB[id] = (this.checked ? 1 : 0)
});
var json_cb = JSON.stringify(arrCB);
Now, you can use AJAX to send the string -- similar to what you got from the database at the beginning -- back to PHP for storage:
$.ajax({
type: 'POST',
url: 'your_php_file.php',
data: the_json=json_cb
});
On the PHP side, your AJAX processor file (in this example called your_php_file.php) will look something like this:
<?php
$j = $_POST['the_json'];
$result = mysql_query("UPDATE `scratchpad` SET `cb_list` = '$j' ");
Here is a jsFiddle with examples of the javascript/jQuery.
Resources:
You might find this helpful: $.ajax - dataType

Dynamically hiding a portion of a HTML table

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>

Categories