Bind Jquery event to table rows dynamically added to table - php

I have a table with a button that adds 5 rows with cells to the table when clicked. I want to bind an event to cells in the 5th column of the table. All of these cells are named "Count_" followed by the row number. So, the cell in Row 0 is:
<td name="CountCell_0">
<input type="text" name="Count_0">
</td>
And I'm trying to update the input with name Count_X (where X is the row number).
The binding works for the cells that existed on the page originally. However, the event is not triggering for cells that were added with the button.
Here is an example of a cell that was dynamically added:
<td>
<input type="text" name="Count_348">
</td>
Here is my Jquery event:
$(document).ready(
function() {
$(document).on('change','[name^="Count_"]',function() {
console.log('here'); //not triggering on dynamic cell
var cell = $(this).attr('name');
var idx = cell.split('_')[1];
var amount = $(this).val() * $('[name="AvgCost_' + idx + '"]').html();
$('#ExtendedCostCell_' + idx).html(amount.toFixed(2));
});
}
);

I think the problem was here [name^="Count_"]' you need a selector so change to this input[name^="Count_"]' and the anonimous function is not performed
$(document).ready(
(function() {
$(document).on('change','input[name^="Count_"]',function() {
console.log('here'); //not triggering on dynamic cell
var cell = $(this).attr('name');
var idx = cell.split('_')[1];
var amount = $(this).val() * $('[name="AvgCost_' + idx + '"]').html();
$('#ExtendedCostCell_' + idx).html(amount.toFixed(2));
});
}());
);

I moved the function outside of the document ready, and it now triggers on the dynamic rows.

Related

Live filter in Laravel

I have a form that looks like below.
I have three "white" dropdowns to filter the value for the Equipment Registration Tag dropdown ( The values of the dropdown input field that has the Equipment Registration Tag label will only come out after the user selects values for the three "white" dropdowns). So the Equipment Registration Tag values will differ based on the "white" dropdowns value.
I want it to be a live filter, the dropdown options will change immediately every time user selects the "white" dropdown value. Currently, my approach is to use the onchange=" this.form.submit()" attribute on the "white" dropdowns and return the values after the filter, but I realize this method has a disadvantage which is a user might accidentally submit the form when changing the value of "white" dropdowns. How can I prevent this and only allow users to submit the form by clicking the save button?
$this->Calibration_Location = $request->get('selected_location');
$this->Calibration_Category = $request->get('selected_category');
$this->categories = Equipment::select('Category')->distinct()->get()->toArray();
$this->locations = Equipment::select('Location')->distinct()->get()->toArray();
$matchThese = ['Category' => $this->Calibration_Category, 'Location' => $this->Calibration_Location];
$this->Registration_Select_Tags = Equipment::select('Registration Tag')->distinct()->where($matchThese)->get();
I have also tried jQuery, but I can only trigger by a specified dropdown field, not any one of them.
<script type="text/javascript">
$(document).ready(function() {
var location, category
$('#selected_transfer_location').change(function() {
location = $(this).val();
console.log(location);
$('#selected_transfer_category').change(function() {
category = $(this).val();
console.log(category);
});
// $('#transfer_registration_tag').find('option').not(':first').remove();
$.ajax({
url: 'Transaction/' + location + '/' + category,
type: 'get',
dataType: 'json',
success: function(response) {
var len = 0;
if (response.data != null) {
len = response.data.length;
}
if (len > 0) {
for (var i = 0; i < len; i++) {
var id = response.data[i]['Registration Tag'];
var name = response.data[i]['Registration Tag'];
var option = "<option value='" + id + "'>" + name +
"</option>";
$("#transfer_registration_tag").append(option);
}
}
}
})
});
});
</script>
I hope my question is clear, still new to Laravel and I hope could receive some hints from you.
First approach could be that, you use call ajax Query on change of each on of them and fetch filtered results. Something like this:
$('#dropdown1, #dropdown2, #dropdown3').change(function(){
var val1 = $('#dropdown1').val();
var val2 = $('#dropdown2').val();
var val3 = $('#dropdown3').val();
//And then your ajax call here to fetch filtered results.
});
Only issue is this Ajax call will occur min 3 times, one for each of them.
Second approach could be you give small button below those dropdowns, something like FetchTags. When user selects all the 3 values, will click on that button and you call your ajax onClick of that btn. So that your Ajax will be called only once.
You can use livewire to do that. It easy.
To install it, you have to use composer by taping the fowllowing command:
composer req livewire/livewire
Please check this tutorial to see how to how to do what you want to do using the framework.

PHP AJAX HTML: changing unique table data in foreach loop

I'm new to PHP and Ajax. I am trying to create a table of object data where I can select the displayed data based on a <select><option>... form.
I have a PHTML template which looks like the following:
<?php
$content = "";
// creates data selector
$content .= "
<form id = select_data>
<select id = data_selection>
<option value = data1>Data 1</option>
<option value = data2>Data 2</option>
<option value = data3>Data 3</option>
<option value = data4>Data 4</option>
</select>
<input id = selected_data type=submit />
</form>";
// creates table header
$content .= "
<tr>
<th>Data</th>
</tr>";
$array_ids = array(1, 2, 3); // etc, array of object id's
foreach ($array_ids as $array_id) {
$object = // instantiate object by array_id, pseudocode
$object_data = $object->getData('default-data'); // get default data to display
// create table item for each object
$content .= "
<tr>
<td><p>$object_data</p></td>
</tr>";
}
print $content;
?>
This prints out the table content, loads objects by their id, then gets and displays default data within the <p> tag.
And then I have some Javascript which looks like the following:
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(document).ready(function(){
$('#select_data').on('submit', function(e){ // get selected data type
e.preventDefault();
var data_selected = $("#data_selection :selected").val(); // create var to pass to ajax
$.ajax({
type: "POST",
url: 'post.php',
data: {data_selected: data_selected},
success: function(data){
$("p").html(data); // replace all <p> tag content with data
}
});
});
});
</script>
This Javascript gets the selected data type, creates a variable out of it to pass on to the ajax which then calls post.php, which looks like the following:
<?php
$attribute = false;
if (isset($_POST['data_selected'])){
$data = $_POST['data_selected']; // assigns variable out of ajax data
$object = //instantiate object, again pseudocode
$object_data = $object->getData($data); // get new data to replace into the ```<p>``` tag
echo $object_data;
}
?>
The problem is that the Javascript that I have changes every single <p> tag to the last data iterated by the foreach loop because each <p> tag is not uniquely identified and the Ajax does not update the data based on a unique identifier, such as maybe the $array_id. Which brings me to my attempted solution.
I tried to identify each <p> tag with the following:
<td><p id = $array_id>$object_data</p></td>
And then creating a new Javascript variable out of the array ID:
var p_tag_id = <?php echo $array_id; ?>;
And finally making the Ajax success function target element ID's based on var p_tag_id:
$("#" + p_tag_id).html(data);
While this does not change all the <p> tags like previously, it only changes the final <p> tag and leaves all instances before it unchanged because the Javascript is not iterating over each <p> tag, or because the foreach loop does not call the Javascript as a function for each $array_id.
How can I rewrite this code so that the Ajax updates the data of each table item uniquely instead of updating them all with the same data? Is there a better way to approach this problem?
You need a way to identify the table row containing the <p> tag you wish to update, and perhaps the value attribute of the SELECT element could help.
You can get the number of the clicked option from your data_selected variable by using slice to strip-off the last character (i.e. the number):
var num = data_selected.slice(-1) - 1;
(Subtract 1 because the table rows are zero-indexed)
Then, in the AJAX code block's success function:
$('table tr').each(function(i,v){
if (i == num){
$(v).find('td').find('p').html(data);
}
});
The above grabs all the table rows (as a collection) and loops through them one-by-one. In the function, i is the index number of the row and v is the row itself. Index numbers begin at zero, which is why you earlier subtracted 1 from the (for eg) data3 [3] value, leaving num == 2. When you find the right row number, use .find() to find the <td> in that row, and then the <p> in that <td> and Bob's yer uncle.
I haven't tested the above code so there could be bugs in the example, but off-the-cuff this approach should work.
I figured out a solution. I assigned the $array_id to each <p> tag after all in order to identify them uniquely:
<td><p id = $array_id>$object_data</p></td>
Then I looped over all the <p> tags and assigned the $array_id of this <p> tag to a variable like so:
$("p").each(function() {
var array_id = $(this).attr("id");
And finally I made the Ajax success target elements based on their ID:
$("#" + array_id ).html(data);
Here is the full Javascript code for anybody who is interested. Hopefully this helps someone else out!
<script>
$(document).ready(function(){
$('#select_data').on('submit', function(e){
e.preventDefault();
var data_selected = $("#data_selection :selected").val();
$("p").each(function() {
var array_id = $(this).attr("id");
$.ajax({
type: "POST",
url: 'post.php',
data: {data_selected: data_selected, array_id: array_id},
success: function(data){
$("#" + array_id).html(data);
}
});
});
});
});
</script>

jQuery - Search Mysql for results, then display within table, but also have a click link for each record

Ive spent several hours trying to resolve an issue with very limited experience with jQuery which is not helping me.
I am wanting to search a database for a list of results using a few input fields and then a submit button, when you click submit the values are passed to a .php script which returns the results and these are displayed in a table within a div container which works perfect.
Each record is then displayed in its own row within the table, with columns for different data.
record number
name
town
What i want is for the record number to be a click link of some kind, which when clicked, it then passes that value and does a different mysql request displaying that unique records data in more detail in a different div container. This is the part i cant get to work as i believe its something to do with BINDING, or the .ON which i dont really know anything or understand how it works, as my experience is very limited.
<script type="text/javascript">
$(document).ready(function() {
$(".click").click(function() {
var name = $("#name").val();
var name = $(this).attr("id");
$('#2').load("mysqlrequest_unique.php?recordid=" +name);
});
$("#get").click(function() {
var sales_record_number = "sales_record_number=" + $("#sales_record_number").val() + "&";
var item_id = "item_id=" + $("#item_id").val() + "&";
var user_id = "user_id=" + $("#user_id").val() + "&";
var buyer_fullname = "buyer_fullname=" + $("#buyer_fullname").val() + "&";
var sale_date = "sale_date=" + $("#sale_date").val() + "&";
var paypal_transaction_id = "paypal_transaction_id=" + $("#paypal_transaction_id").val() + "&";
var ship_to_zip = "ship_to_zip=" + $("#ship_to_zip").val() + "&";
var item_title = "item_title=" + $("#item_title").val() + "&";
$('#1').load("mysqlrequest_all.php?"+sales_record_number+item_id+user_id+buyer_fullname+sale_date+paypal_transaction_id+ship_to_zip+item_title, function(){
var name = $("#name").val();
var name = $(this).attr("id");
$('#2').load("mysqlrequest_unique.php?recordid=" +name);
}
);
});
});
</script>
<div id="1" name='container_display_all'></div>
<div id="2" name='container_display_unique'></div>
This is what each row would have in the table, which doesnt work when its contained in generated html using a jQuery
<a class = 'click' id = '19496'>19496</a>
This isn't working because you are adding html elements dynamically and the event handlers aren't being added to the dynamically added elements.
$(document).ready(...) is only run when the document loads. So if all the elements that have the class click are being added dynamically, this bit of code $(".click") (inside $(document).ready(...) ) will return a jquery object that contains no elements (as there are currently none in the DOM with the class click).
Then later your elements (with class click) are added to the DOM but have no handlers on them. What you need to do is set the handlers for those object when you add them.
So change this line:
$('#1').load("mysqlrequest_all.php?"+sales_record_number+item_id+user_id+buyer_fullname+sale_date+paypal_transaction_id+ship_to_zip+item_title);
to this:
$('#1').load("mysqlrequest_all.php?"+sales_record_number+item_id+user_id+buyer_fullname+sale_date+paypal_transaction_id+ship_to_zip+item_title, function(){
$(".click").click(function() {
var name = $("#name").val();
var name = $(this).attr("id");
$('#2').load("mysqlrequest_unique.php?recordid=" +name);
});
}
);
This code will execute the function that is passed once the new html is loaded into the first div, which will add the needed handlers to the new elements.

sending html table data into mysql table

I have a dynamic (via jquery) html table like this:
<form action="index.php" method="post">
<table class="myTable" id="cup">
<tbody>
<tr><td class="header" colspan="6">YOUR SELECTIONS</td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> //selected
</tbody>
</table>
<input type="submit" value="submit">
</form>
First, the table has only 1 row and 6 cells (except "selections" part). After some conditions satisfied, the cells get filled with some values and the "selected" row is appended into the table via jquery. But my problem here, is not related to jquery.
Each of 6 cells will be inserted into the mysql table part by part. My database table structure like this:
ID | Selection1 |...| Selection6 | Date, time stuffs and other info.
So, I need some code that will do these jobs:
define an array with 6 element.
counter=0;
loop(until there is no traveled cell in the html table)
{
find a cell that is not NULL or its value is not "selections";
array[counter] <-- value of cell;
counter++;
if (counter == 6)
{
insert all of them into the mysql table (?)
counter=0;
}
}//end loop
So, this is my problem. I just can't know how to do it. Should I have to add "id" or "name" stuffs in the html tags or what? :)
EDIT: I don't want you guys to code it for me of course. The thing I couldn't get is how to separate these values 6 by 6 and send them into the database. I just need ideas.
From the html table data you can construct a JSON object. For instance:
var myData = [],
keys = ['ID','Selection1','Selection2', ..... ]
url = './index.php';
$('table').find('tr:gt(0)').each(function( i, row ) {
var oRow = {};
$( row ).find( 'td' ).each( function( j, cell ) {
oRow[ keys[ j ] ] = $( cell ).text();
});
myData.push( oRow );
});
//myData = [ {"ID":"3u3y","Selection1",....},{"ID":"jdjdj",...}.... ]
//now you can use one key to send all the data to your server
$.post( url, { mydata: JSON.stringify( myData ) }, function(d) {
alert( 'Server said, ' + d );
});
//In your PHP script you would look for the data in mydata --> $_POST['mydata']
EDIT
Click the link below to go to a demo.
In THIS DEMO click submit and then look at the console on the right. Click the plus on the left of the failed ajax call and then click the Post tab to examine the data the call attempted to send.
Does that help?

jQuery fast mouse move mouseleave event triggers before previous event completes

If a users mouse goes over a table cell then a dropdown box replaces the html with data loaded via a post call. This works fine if the users mouse move is not too quick, but if it is too fast the html doesn't update so that when the user moves the mouse back in the html is incorrect.
$(".edit_dropdown").bind('mouseenter', function () {
$(this).unbind('mouseenter');
var a = $.trim($(this).html());
var id = $(this).attr('id');
$(this).html("<span id='s-" + id + "'></span>");
$.post('save/dropdown.php', {
id: id,
a: a
}, function (data) {
$("#s-" + id).html(data);
$(".edit_dropdown").bind('mouseleave', function () {
var id = $(this).attr('id');
var a = $("#e-" + id).val();
var dir = $(this).attr('class');
$(this).html(a);
$(this).bind('mouseenter', function () {
$(this).unbind('mouseenter');
var a = $.trim($(this).html());
var id = $(this).attr('id');
$(this).html("<span id='s-" + id + "'></span>");
$.post('save/dropdown.php', {
id: id,
a: a
}, function (data) {
$("#s-" + id).html(data);
});
});
});
});
});
html
<tr>
<td>customer county</td>
<td class="edit_dropdown" id="customer-cust_s_county"><?php echo $row['cust_s_county']; ?></td>
</tr>
The $.post file returns a list of UK counties, if the county name matches the html then that county is returned as the selected option.
The problem occurs because the mouseleave handler is only put in place in response to an asynchronous response to the mouseenter handler.
You should be looking for a simpler overall code structure that doesn't involve detaching and reattaching handlers.
It should be possible to write two handlers that remain permanently attached, as follows :
$(".edit_dropdown").on('mouseenter', function () {
//Perform all mouseenter actions here.
//If necessary, test for different states and branch as required.
}).on('mouseleave', function () {
//Perform all mouseleave actions here.
//If necessary, test for different states and branch as required.
});
Another point: As the list of counties is static, you can serve it once as part of the page's original HTML. You then need to return only the name or id of the county to be selected rather than repeatedly returning the whole list.

Categories