Change specific dynamically created table row html and text from ajax response - php

From the database, I have a dynamic table like this:
<table>
<?php
$query = ....;
foreach ($query as $row) {
echo '<tr>';
echo '<td>' . ' <span class="bName">' . $row['brand_name'] . '</span>'.
'<input name="product_id" type="number" value="' . $row['product_id'] . '">'.
'<input name="company_id[]" type="number" value="' . $row['company_id'] . '">'.
'<button name="exchange" type="button">Click Me!</button></td>';
echo '</td>';
echo '</tr>';
}
?>
</table>
It returns say 4 rows with brand_name inside the <span> and product_id inside an <input>. The exchange button on click calls an ajax request that query another random brand_name and returns the query as JSON like this:
{product_id: '2206', brand_name: 'New name', company_id: '234' }
The script for ajax is
<script>
$(document).ready(function() {
$('button[name="exchange"]').click(function() {
$.ajax({
url: 'ajaxChangeBrand.php',
type: 'POST',
data: 'keyword=' + $(this).parent().find('input[name="product_id"]').val(),
success: function(response) {
var data = JSON.parse(response);
$('.bName').html(data.brand_name); // Problem is here
$('.company_id').html(data.company_id); // and here
console.log(data);
},
});
});
});
</script>
My target is to change the brand_name inside class bName and company_id value with the new values from ajax response for that specific row. But my problem is it changes all the spans with bName class and all the inputs with class company_id. What should be the best approach to change the specific row of that table from the ajax data?

Store a reference to the cell that the button that was actually clicked exists in so you can find within that cell the specific elements.
Also note that the company_id value is in an input thaat you ned to use val() on and you need to give it a class name
$('button[name="exchange"]').click(function() {
// cell this button instance is in
const $cell = $(this).closest('td');
$.ajax({
url: 'ajaxChangeBrand.php',
type: 'POST',
data: 'keyword=' + $(this).parent().find('input[name="product_id"]').val(),
success: function(response) {
var data = JSON.parse(response);
$cell.find('.bName').html(data.brand_name); // Problem is here
$cell.find('.company_id').val(data.company_id); // and here
console.log(data);
},
});
});

Unable to test using AJAX but perhaps this might help. Use the event of the click function to find the parentNode and from that use querySelector to target the particular elements in the table row.
$(document).ready(function() {
$('button[name="exchange"]').click(function(e) {
let tr=e.target.parentNode;
let span=tr.querySelector('span.bName');
let pid=tr.querySelector('input[name="product_id"]');
let cid=tr.querySelector('input[name="company_id[]"]');
console.info( span.textContent, cid.value, pid.value)
$.ajax({
url: 'ajaxChangeBrand.php',
type: 'POST',
data: 'keyword=' + $(this).parent().find('input[name="product_id"]').val(),
success: function(response) {
var data = JSON.parse(response);
span.textContent=data.brand_name;
cid.value=data.company_id;
pid.value=data.product_id;
},
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>
<span class="bName">Womble</span>
<input name="product_id" type="number" value="23">
<input name="company_id[]" type="number" value="88">
<button name="exchange" type="button">Click Me!</button>
</td>
</tr>
<tr>
<td>
<span class="bName">Bagpuss</span>
<input name="product_id" type="number" value="39">
<input name="company_id[]" type="number" value="12">
<button name="exchange" type="button">Click Me!</button>
</td>
</tr>
<tr>
<td>
<span class="bName">Clanger</span>
<input name="product_id" type="number" value="47">
<input name="company_id[]" type="number" value="91">
<button name="exchange" type="button">Click Me!</button>
</td>
</tr>
</table>

Related

Jquery select data-id from second row on table

I've been trying to make a table with a list of users for a school project.
I'm doing this with jquery, php and mysql.
I'm retrieving all data from the mysql database and printing it out in a table.
now i'm trying to add an update button to i can easily update data for each specific row.
This however is not working as expected. It only selects the data from the same row. While the data-id value is different. Could anyone tell me why this is happening? I'll leave my code below for clearance
JS:
$(document).ready(function () {
$(document).on('click', '#update-btn', function () {
var id =$("[id='update-btn']").attr('data-id');
var username = $('#username').val();
var dob = $('#dob').val();
var address = $('#address').val();
$.ajax({
url: 'ajax/update.php',
method: 'POST',
data: {
ID: id,
username: username,
dob: dob,
address: address
},
success: function (data) {
if (data){
console.log(data);
swal({
title: 'Update successful',
icon: 'success',
text: 'User with ID ' + id + ' updated.'
});
setTimeout(function () {
window.location = 'medewerkers.php';
}, 5000)
}
else if (data === "update_failed"){
}
}
});
});
});
PHP:
public static function loadMedewerkers(){
$mysql = Database::DBCon()->prepare('
SELECT * FROM medewerkers
');
$mysql->execute();
while ($fetch = $mysql->fetch(PDO::FETCH_ASSOC))
{
$html = '<tr>
<td><input type="text" value="'. $fetch['username'] .'" id="username"></td>
<td><input type="text" value="'. $fetch['dob'] .'" id="dob"></td>
<td><input type="text" value="'. $fetch['address'] .'" id="address"</td>
<td><button type="button" class="btn btn-danger" id="delete-btn" data-id="'. $fetch['ID'] .'">Delete</button>
<button type="button" class="btn btn-warning" id="update-btn" data-id="'. $fetch['ID'] .'">Update</button></td>
</tr>';
echo $html;
}
}
The problem is because your loop is causing multiple elements to have the same id, when id attributes must be unique within the DOM. To fix this use common classes on the elements within the loop, then DOM traversal to find them when the button is clicked.
public static function loadMedewerkers()
{
$mysql = Database::DBCon()->prepare('SELECT * FROM medewerkers');
$mysql->execute();
while ($fetch = $mysql->fetch(PDO::FETCH_ASSOC))
{
$html = '<tr>
<td><input type="text" value="'. $fetch['username'] .'" class="username"></td>
<td><input type="text" value="'. $fetch['dob'] .'" class="dob"></td>
<td><input type="text" value="'. $fetch['address'] .'" class="address"</td>
<td>
<button type="button" class="btn btn-danger delete-btn" data-id="'. $fetch['ID'] .'">Delete</button>
<button type="button" class="btn btn-warning update-btn" data-id="'. $fetch['ID'] .'">Update</button></td>
</tr>';
echo $html;
}
}
$(document).ready(function() {
$(document).on('click', '.update-btn', function() {
var $row = $(this).closest('tr');
var id = $(this).data('id');
var username = $row.find('.username').val();
var dob = $row.find('.dob').val();
var address = $row.find('.address').val();
// ajax request here...
});
});
Note the use of data() to retrieve the data attribute. Also note that you could put the data-id attribute itself on the tr instead of each button to DRY up the HTML slightly.
You are using ID in your buttons when returning
ID is unique for each object in the screen
try using class
something like this:
$(document).ready(function () {
$(document).on('click', '.update-btn', function () {
var id =$(this).data('id');
var username = $(this).closest('tr').find('.username').val();
var dob = $(this).closest('tr').find('.dob').val();
var address = $(this).closest('tr').find('.address').val();
$.ajax({
url: 'ajax/update.php',
method: 'POST',
data: {
ID: id,
username: username,
dob: dob,
address: address
},
success: function (data) {
if (data){
console.log(data);
swal({
title: 'Update successful',
icon: 'success',
text: 'User with ID ' + id + ' updated.'
});
setTimeout(function () {
window.location = 'medewerkers.php';
}, 5000)
}
else if (data === "update_failed"){
}
}
});
});
});
public static function loadMedewerkers(){
$mysql = Database::DBCon()->prepare('
SELECT * FROM medewerkers
');
$mysql->execute();
while ($fetch = $mysql->fetch(PDO::FETCH_ASSOC))
{
$html = '<tr>
<td><input type="text" value="'. $fetch['username'] .'" class="username"></td>
<td><input type="text" value="'. $fetch['dob'] .'" class="dob"></td>
<td><input type="text" value="'. $fetch['address'] .'" class="address"</td>
<td><button type="button" class="btn btn-danger delete-btn" data-id="'. $fetch['ID'] .'">Delete</button>
<button type="button" class="btn btn-warning update-btn" data-id="'. $fetch['ID'] .'">Update</button></td>
</tr>';
echo $html;
}
}
same goes for your delete button
and use .data() instead of attr()
Also, in other columns for getting the username, dob and address you have to use class instead of id.

Using ajax on select change for multiple selects

I have a table row where I added the ability to add/remove using .clone and .remove
I also have an ajax call to my controller in code igniter to grab the data and populate the other inputs based on data.
It currently works one the first one, I am able to select an option from the dropdown and it fills the values of the neighboring inputs. My problem is when I click add and it successfully clones the row, when I change that dropdown its like the .change and .ajax events no longer work.
Here is my jQuery which is here I think I am having the problem:
$('.invoice_line_item').each(function(){
$(this).change(function(){
var table = $(this).closest('.tr_clone');
var select_value = $(this).val();
//alert(item_id + ' ' + select_value);
console.log(item_id + select_value);
$.ajax({
url: '<?php echo site_url("Invoice_item/get_item"); ?>',
type: 'POST',
dataType: "JSON",
data: ({'id' : select_value}),
success: function (data, status)
{
//alert('Success ' + data);
console.log(data);
$(table).find('.description').val(data['work_description']);
$(table).find('.amount').val(data['amount']);
$(table).find('.quantity').val(data['quantity']);
$(table).find('.price').val(data['amount']);
},
error: function (data, xhr, desc, err)
{
alert('An Error Occurred: ' + xhr + ' ' + desc + ' ' + err);
console.log(data);
}
});
});
});
Here is the HTML:
<tbody>
<tr class="tr_clone" id="inv_line_1">
<td>
<select id="line_item_1" name="invoice_line_item" class="invoice_line_item">
<option></option>
<?php
foreach($prefix_line_items as $line_item)
{
?>
<option value="<?php echo $line_item['id']; ?>"><?php echo $line_item['item']; ?></option>
<?php
}
?>
</select>
</td>
<td><input type="text" id="description_1" name="description" class="description" value="" /></td>
<td><input type="currency" id="amount_1" name="amount" class="amount" value="" /></td>
<td><input type="number" id="quantity_1" name="quantity" class="quantity" value="" /></td>
<td><input type="currency" id="price_1" name="price" class="price" value="" readonly/></td>
<td><i class="fa fa-plus"></i> <i class="fa fa-minus"></i></td>
</tr>
</tbody>
No errors in console, works the first time for the first row but when I click the Add button and it duplicates the row, I change the (cloned) select element and its like the jQuery no longer fires so it isnt grabbing the data via ajax or printing to the console.
While cloning the element, by default, it does not copy the event handlers to new elements. For that you have to pass true to tell clone method to do so.
Good practice is to clone the element and then copy only required events manually to the new element.
Check below example given on jquery's website,
/ Original element with attached data
var $elem = $( "#elem" ).data( "arr": [ 1 ] ),
$clone = $elem.clone( true )
Hope it helps..

Get Ajax variable from the PHP foreach loops

I have a simple ajax (jquery version) script and very short php function and they works fine without problem.
When I submit the value from the form input are, the ajax will work to send and get result from
the php script, in this case to get a total amount of the book order.
The Ajax script and html section are as follows:
<script language="JavaScript">
$(document).ready(function() {
$("form").mouseout( function() {
// get field value
var qtyVal = $('#qty').val();
// use HTTP GET get ajax
$.ajax({
type: 'GET',
url: 'getSunBody.php',
data: { qty : qtyVal,
},
success: function(data) {
//get xml value
$('#result').html($(data).find('qty').text());
$('#result1').html($(data).find('caution').text());
}
});
return false;
});
});
</script>
<body>
Total price:<div id="result" class="box" style="height=350px;"></div><div id="result1" class="box" style="height=350px;"></div>
<form>
<p>
<label>quantity: </label>
<input type="text" id="qty" name="qty"/>
<br/>
<input type="submit" value="submit">
total price:</p>
<p> </p>
</form>
And the following php script serving as xml also works fine with above ajax request:
<?php
// XML document
header("Content-Type: text/xml");
header("Content-Type:text/html; charset=utf-8");
// get field values
$qty = (isset($_POST["qty"]) ) ? $_POST["qty"] : $_GET["qty"];
echo "<?xml version=\"1.0\" ?>";
echo "<datetime>";
echo "<qty>" . $qty*100 . "</qty>";
$total=$qty*100;
if ($total==0)
echo "<caution>"."please input number!"."</caution>";
else if ($total<=500)
echo "<caution>"."you shoud buy more!"."</caution>";
echo "";
echo "</datetime>";
?>
However when I combine the above scripts with my shopping cart foreach loops, it doesn't work and the ajax script failed to get variables from the form input area. I don't know if it is a variable scope issue (globals or local)? or anything else?
The following is the total script I would like to fixed with:
<script language="JavaScript">
$(document).ready(function() {
$("form").mouseout( function() {
// get value from the form
var qtyVal = $('#qty').val();
// get
$.ajax({
type: 'GET',
url: 'getSunBody.php',
data: { qty : qtyVal,
},
success: function(data) {
// get XML value
$('#result').html($(data).find('qty').text());
$('#result1').html($(data).find('caution').text());
}
});
return false;
});
});
</script>
</head>
<body>
<table border="1" align="center">
<tr>
<th>no</th>
<th>name</th>
<th>price</th>
<th>qty</th>
<th>update</th>
</tr>
<?php
foreach( $_SESSION["psn"] as $i => $data ){
?>
<form action="sessionCartUpdate.php">
<input type="hidden" name="psn" value="<?php echo $_SESSION["psn"][$i];?>">
<tr>
<td><?php echo $_SESSION["psn"][$i];?></td>
<td><?php echo $_SESSION["pname"][$i];?></td>
<td><?php echo $_SESSION["price"][$i];?></td>
<td><input type="text" id="qty" name="qty" value="<?php echo $_SESSION["qty"][$i];?>"></td>
<input type="submit" name="qty"
<td><input type="submit" name="btnUpdate" value="update" />
<input type="submit" name="btnDelete" value="delete" />
</td>
</tr>
</form>
<?php
}
?>
<tr><td colsan="5">total amount:<div id="result" class="box" style="height=350px;"></div><div id="result1" class="box" style="height=350px;"></div></td></td>
</table>
<p>continue to shop
<p>Put your order
</body>
</html>
I would be very grateful if anyone can offer kind or possible suggestion or advice?
My goal is to put different number (variables) in the "input area" (name or id as "qty") throught the using of ajax to get a total amount of price and show the result in the div box (id="result" or "result1").
You should replace the id attribute with class because id is supposed to be unique in the dom and using class you can do a loop to get all quantities of the items in the cart
Another thing i have noticed that you have made the an individual form foreach item in the cart there should be one form having the multiple fields,also remove this line <input type="submit" name="qty" it doesent makes sense
<form action="sessionCartUpdate.php">
<?php
foreach( $_SESSION["psn"] as $i => $data ){
?>
<input type="hidden" name="psn" value="<?php echo $_SESSION["psn"][$i];?>">
<tr>
<td><?php echo $_SESSION["psn"][$i];?></td>
<td><?php echo $_SESSION["pname"][$i];?></td>
<td><?php echo $_SESSION["price"][$i];?></td>
<td><input type="text" class="qty" name="qty[]" value="<?php echo $_SESSION["qty"][$i];?>"></td>
<td><input type="submit" name="btnUpdate" value="update" />
<input type="submit" name="btnDelete" value="delete" />
</td>
</tr>
<?php
}
?>
</form>
<script language="JavaScript">
$(document).ready(function() {
$("form").mouseout( function() {
var qtyVal =0;
$( ".qty" ).each(function() {
qtyVal =qtyVal + parseInt($(this).val());
});
// get
$.ajax({
type: 'GET',
url: 'getSunBody.php',
data: { qty : qtyVal,
},
success: function(data) {
// get XML value
$('#result').html($(data).find('qty').text());
$('#result1').html($(data).find('caution').text());
}
});
return false;
});
});
</script>
// get field values
$qty = (isset($_POST["qty"]) ) ? $_POST["qty"] : $_GET["qty"];
Instead of using both $_GET and $_POST, you can use $_REQUEST which will give data from either POST or GET.

Doing an ajax call to a php page

I have this star rating, I implemented from jQuery and I need to save the comments, the user id and the value of the star clicked. What I do not know is how to pass that through the ajax call and what the PHP should have at the least to process the call? Here is my code
stars code - as you can see it has a comments box , the stars with star value and the user id is stored in a variable called
$user_id
Here is the code
<tr>
<td style="padding:10px;">
<span style="font-size: 20px; vertical-align:top;">Comments</span>
</td>
<td style="padding:10px;">
<textarea name="comments1" cols="60" rows="2"></textarea>
</td>
<td>
<div>
<input name="star1" value "1" type="radio" class="star"/>
<input name="star1" value="2" type="radio" class="star"/>
<input name="star1" value="3" type="radio" class="star"/>
<input name="star1" value="4" type="radio" class="star"/>
<input name="star1" value="5" type="radio" class="star"/>
</div>
</td>
<tr>
The ajax call - This is the attempted call to the page where I am sending the request, but how can I include the comments and user id on this call?
$('.star').rating({
callback: function(value, link) {
var name = $(this).attr('name');
$.ajax({
url: "ajax.php",
data: "name=" + name + "&value=" + value,
cache: false,
success: function(response) {
try {
console.log(response);
} catch (err) {
alert(response);
}
}
});
}
});
Now, ajax.php has variables $passed_user_id, $passed_comments, $passed_ratingval. How am I retrieving these values when the call is triggered in php? something like
$passed_comments = //get the value being passed from ajax call
$passed_ratingval = //get the value being passed for the rating value
$passed_user_id = //get the value being passed for the user_id`
I do have all set up, the insert query, connection everything works. I'm just not sure how to make this work with the ajax call.
Kinda hacky, but this will work for you. It also will allow for multiple ratings on one page (which I assume you might be doing considering the TR).
HTML:
<tr>
<td style="padding:10px;">
<input type="hidden" name="userID" value="<?php echo $user_id ?>">
<span style="font-size: 20px; vertical-align:top;">Comments</span>
</td>
<td style="padding:10px;">
<textarea name="comments" cols="60" rows="2"></textarea>
</td>
<td>
<div>
<input name="star1" value "1" type="radio" class="star"/>
<input name="star1" value="2" type="radio" class="star"/>
<input name="star1" value="3" type="radio" class="star"/>
<input name="star1" value="4" type="radio" class="star"/>
<input name="star1" value="5" type="radio" class="star"/>
</div>
</td>
<tr>
JS:
$('.star').rating({
callback: function(value, link) {
var name = $(this).attr('name');
var userID = $(this).closest('tr').find('input[name="userID"]').val();
var comments = $(this).closest('tr').find('textarea[name="comments"]').val();
$.ajax({
url: "ajax.php",
data: "name=" + name + "&value=" + value + "&userID=" + userID + "&comments=" + comments,
cache: false,
success: function(response) {
try {
console.log(response);
} catch (err) {
alert(response);
}
}
});
}
});
Also, if you use POST instead of GET, you can format your ajax call a bit nicer like below. Remember to use $_POST[] in your ajax.php file.
$('.star').rating({
callback: function(value, link) {
var name = $(this).attr('name');
var userID = $(this).closest('tr').find('input[name="userID"]').val();
var comments = $(this).closest('tr').find('textarea[name="comments"]').val();
$.ajax({
url: "ajax.php",
type: "POST",
data: {
name: name,
value: value,
userID: userID,
comments: comments
},
cache: false,
success: function(response) {
try {
console.log(response);
} catch (err) {
alert(response);
}
}
});
}
});
Here is example code of mine, which I use on one project:
jQuery.post("load.php", {
op_type : opType,
xor : xor.toString(),
or : or.toString(),
and : and.toString(),
from : seeds.toString(),
last_id : jQuery("input[type=hidden]:last").val(),
last_update : last_update_time
}, function(data) {
var json = jQuery.parseJSON(data);
if (json.list.length > 0) {
last_update_time = Math.floor(new Date().getTime() / 1000);
jQuery("div#list_content ul.no-list").append(json.list);
}
});
And in PHP to receive data I use:
$_POST['op_type']
and in this manner I get other variables too.
To return something I do like this:
echo json_encode(array("list"=>$html));
So afyer jQuery parses JSON it can get access to $html variable via list property.
So what you need is to specify request type in jQuery and get that request type in PHP. Sending data in JSON is one of the options. jQuery and PHP also support XML, but I didn't worked with it.

JQuery .load() removing .sortable() function from sortable list

I will try to explain my problem with as little code as possible.
Basically I have several sortable lists connected in the usual way. Each item in the list has some hidden elements that are toggled with a button on the respective items. There is also a second button that causes the list item to slideUp and be removed from the list - then being sent to a new list. This works in conjunction with an ajax call which when successful uses the .load() function to refresh the receiving sortable list.
The problem: When I use .load() to refresh the receiving sortable list, the new list item is present but the list loses its sort-ability and all the hidden items on each list item are displayed. Any idea why the .load() function removes the interactivity of refreshed page elements?
This is the code to remove an item and refresh a new list:
$(document).ready(function click(){
$(".finished").click(function() {
if (confirm('Are you sure is complete?')) {
$(this).closest(".card").slideUp();
var id = $(this).closest(".card").find(".hiddenid").val();
var machinequantity = $(this).closest(".card").find(".machinequantity").val();
$.ajax({
url: "update_item_machine_complete.php",
type: "POST",
data: "&id="+id+"&machinequantity="+machinequantity,
success: function() {
$('#complete').load('index.php #sortable4')
}
});
}
});
});
Here's an example of the receiving list:
<div id="complete" class="box">
<ul id="sortable4" class="sortable">
<li class="notsortable"><h1>Complete</h1></li>
<?php
include("php/database_connect.php");
$result = mysql_query("SELECT * FROM orders WHERE misc='complete' ORDER BY columnpos ASC ");
while($row = mysql_fetch_array($result))
{
echo'
<li id="id_' . $row['id'] . '">
<div class="card">
<table>
<tr>
<td class="left">' . $row['customer'] . '</td>
<td></td>
<td class="right">' . $row['ponumber'] . '</td>
</tr>
<tr>
<td class="left">' . $row['partnumber'] . '</td>
<td><div class="show"></div></td>
<td class="right">' . $row['quantity'] . ' x Black</td>
</tr>
</table>
<div class="hide">
<p>Quantity Done: <span><input class="machinequantity" type="text" value="' . $row['quantity'] . '" /><input type="submit" value="update" /></span></p>
<p><input class="finished" type="submit" value="Finished" /></p>
<input class="hiddenid" type="hidden" value="' . $row['id'] . '" />
</div>
</div>
</li>
';
}
?>
</ul>
</div>
EDIT: This is the .sortable() code I'm using to record column and position:
$(document).ready(function {
$("#sortable01, #sortable0, #sortable1, #sortable2, #sortable3, #sortable4").sortable({
connectWith : ".sortable",
items : "li:not(.notsortable)",
receive : function(event, ui){
var column = $(this).parent().attr('id');
var index = ui.item.index() + 1;
var id = $("#"+column+" li:nth-child("+index+") .hiddenid").val();
$("#"+column+" li:nth-child("+index+") ").addClass('notsortable');
$.ajax({
url: "update_column.php",
type:"POST",
data: "column="+column+
"&id="+id,
success: function(){
$("#"+column+" li:nth-child("+index+") ").removeClass('notsortable');
}
});
},
beforeStop : function (event, ui) {
$.ajax({
url: "update_column_order.php",
type:"POST",
data: {
sort0:$('#sortable0').sortable('serialize'),
sort1:$('#sortable1').sortable('serialize'),
sort2:$('#sortable2').sortable('serialize'),
sort3:$('#sortable3').sortable('serialize')
}
});
},
})
.disableSelection();
$(".hide").hide();
});
Reinitialize the sortable functionality on the ajax-replaced elements within load's callback:
$('#complete').load('index.php #sortable4', function() {
$('#sortable4').sortable(options);
});
This happens because those elements are completely replaced, you'll need to call .sortable() on the list again...since you're replaced it, for example:
$('#complete').load('index.php #sortable4', function() {
$("#sortable4").sortable();
});

Categories