Add Row After Particular Class JQuery - javascript

I have problem with add more button with particular row. It was adding row at last in each row. I discussed my problem in details:
Please See The Code Snipest :
var i = 2;
$(document).on("click",".btn_add",function(){
var str1 = '<tr><td>'+i+'</td><td>Row '+i+'</td><td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td></tr>';
$(this).parent().parent().parent().find("tr:last").after(str1);
i++;
});
$(document).on("click",".btn_addsub",function(){
var str1 = '<tr><td>'+i+'</td><td>Row '+i+'</td><td><button class="btn btn-sm btn-danger btn_remove">Remove</button></td></tr>';
//$(this).parent().find('tr:last').after(str);
$(this).parent().parent().parent().find("tr:last").after(str1);
i++;
});
$(document).on("click",".btn_remove",function(){
$(this).parent().parent().remove();
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table">
<tr>
<th>#</th>
<th>Row</th>
<th>Action</th>
</tr>
<tr>
<td>1</td>
<td>Row 1</td>
<td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td>
</tr>
</table>
Problem
Step 1. Click On Row 1 Add Sub Button
Step 2. Again Click On Row 1 Add Sub Button
Step 3. Now Click On Row 1 Add Button
Step 4. Now Click On Row 4 Add Sub Button
That's Working Properly. But Now If I Click On Button Add Sub Button Of Row 1: Then It Will be added after Row 3. Currently it is added after Row 5.
So Please Help Me To Overcome this problem.
Thank You in advance.
One Solution I Tried But No Idea about this : Like Generated Code Will See Like This :
<tr class="row_1">
<td>1</td>
<td>Row 1</td>
<td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td>
</tr>
<tr>
<td>1</td>
<td>Row 1</td>
<td><button class="btn btn-sm btn-danger btn_remove">Remove</button></td>
</tr>
<tr>
<td>1</td>
<td>Row 1</td>
<td><button class="btn btn-sm btn-danger btn_remove">Remove</button></td>
</tr>
<tr class="row_2">
<td>1</td>
<td>Row 1</td>
<td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td>
</tr>

As per your comment
Can I add This At Last Of that first tr
, here's a demo:
1) Get all of the trs' index that has .btn_add
var index = $(this).closest('table').find('.btn_add').map(function(){
return $(this).closest('tr').index()
}).get()
2) Find the index of the current row
var thisIndex = $(this).closest('tr').index()
3) Find next tr's index from index array
var nextIndex = index[index.indexOf(thisIndex) + 1]
4) If the current index is the last one, then nextIndex would be undefined and add the new row to the last of the table. Or add the new row before the nextIndex's tr.
if(nextIndex)
$(this).closest('table').find('tr').eq(nextIndex).before(str1);
else
$(this).closest('table').find("tr:last").after(str1);
var i = 2;
$(document).on("click", ".btn_add", function() {
var str1 = '<tr><td>' + i + '</td><td>Row ' + i + '</td><td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td></tr>';
$(this).closest('table').find("tr:last").after(str1);
i++;
});
$(document).on("click", ".btn_addsub", function() {
var str1 = '<tr><td>' + i + '</td><td>Row ' + i + '</td><td><button class="btn btn-sm btn-danger btn_remove">Remove</button></td></tr>';
var index = $(this).closest('table').find('.btn_add').map(function(){
return $(this).closest('tr').index()
}).get()
var thisIndex = $(this).closest('tr').index()
var nextIndex = index[index.indexOf(thisIndex) + 1]
if(nextIndex)
$(this).closest('table').find('tr').eq(nextIndex).before(str1);
else
$(this).closest('table').find("tr:last").after(str1);
i++;
});
$(document).on("click", ".btn_remove", function() {
$(this).closest('tr').remove();
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table">
<tr>
<th>#</th>
<th>Row</th>
<th>Action</th>
</tr>
<tr>
<td>1</td>
<td>Row 1</td>
<td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td>
</tr>
</table>

Is this what you want?
I've changed $(this).parent().parent().parent().find("tr:last").after(str1); to $(this).closest("tr").after(str1);
Demo
var i = 2;
$(document).on("click", ".btn_add", function() {
var str1 = '<tr><td>' + i + '</td><td>Row ' + i + '</td><td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td></tr>';
$(this).parent().parent().parent().find("tr:last").after(str1);
i++;
});
$(document).on("click", ".btn_addsub", function() {
var str1 = '<tr><td>' + i + '</td><td>Row ' + i + '</td><td><button class="btn btn-sm btn-danger btn_remove">Remove</button></td></tr>';
$(this).closest("tr").after(str1);
i++;
});
$(document).on("click", ".btn_remove", function() {
$(this).parent().parent().remove();
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table">
<tr>
<th>#</th>
<th>Row</th>
<th>Action</th>
</tr>
<tr>
<td>1</td>
<td>Row 1</td>
<td><button class="btn btn-sm btn-success btn_add">Add</button> <button class="btn btn-sm btn-success btn_addsub">Add Sub</button></td>
</tr>
</table>

Related

Enable button if all rows below have been deleted

I have created with JQuery a table where I can add a certain text by pressing a button.
As you can see Product 2 and Product 3 can only be added once. Product 4 can be added several times. All text that is inserted can also be deleted by pressing the x-button.
$(".btn.btn-primary.btn-sm").on("click", this.ourClickDispatcher.bind(this))
$("#tableProd").on("click", ".btn.btn-danger.btn-sm.deleteMe", this.deleteRow.bind(this))
function deleteRow(e) {
let deleteBtn = $(e.target).closest(".deleteMe");
deleteBtn.closest('tr').remove()
}
function ourClickDispatcher(e) {
let targetButton = $(e.target).closest(".btn.btn-primary.btn-sm")
let targetButtonParent = targetButton[0].parentElement.parentElement
targetButtonParent.insertAdjacentHTML('afterend', `
<tr>
<td></td>
<td>
<img src="" alt="" height="42" width="42">
<a href="">
Test Product2
</a>
</td>
<td class="deleteMe">
<button type="button" class="btn btn-danger btn-sm deleteMe">x</button>
</td>
</tr>
`)
if (targetButton.hasClass('product3') || targetButton.hasClass('product2')) {
targetButton.attr("disabled", true);
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableProd" style="float: left;" class="table table-bordered">
<tbody>
<tr>
<td>Product 2</td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product 2
</button>
</td>
</tr>
<tr>
<td>Product 3</td>
<td>
<button type="button" data-exists="product3" class="btn btn-primary btn-sm product3">
Add Product 3
</button>
</td>
</tr>
<tr>
<td>Product 4</td>
<td>
<button type="button" data-exists="product4" class="btn btn-primary btn-sm product4">
Add Product 4
</td>
</tr>
</tbody>
</table>
My problem is that if I delete all rows below a disabled button I cannot add any new rows again. This case is shown in the picture below:
Any suggestions how to enable the button if all rows below have been deleted?
I appreciate your replies!
I added you one new function to your javascript
function enableButton(elemId) {
console.log(document.getElementById(elemId));
if (!document.getElementById(elemId)) {
var str = elemId.split('_');
var button = $('#'+str[1]);
$('#'+str[1]).removeAttr('disabled');
}
}
and i also set ids on your html buttons
$(".btn.btn-primary.btn-sm").on("click", this.ourClickDispatcher.bind(this))
$("#tableProd").on("click", ".btn.btn-danger.btn-sm.deleteMe", this.deleteRow.bind(this))
function deleteRow(e) {
let deleteBtn = $(e.target).closest(".deleteMe");
let itemId = e.target.getAttribute('id');
deleteBtn.closest('tr').remove();
enableButton(itemId);
}
function enableButton(elemId) {
if (!document.getElementById(elemId)) {
var str = elemId.split('_');
var button = $('#'+str[1]);
$('#'+str[1]).removeAttr('disabled');
}
}
function ourClickDispatcher(e) {
let targetButton = $(e.target).closest(".btn.btn-primary.btn-sm");
let targetButtonParent = targetButton[0].parentElement.parentElement;
var elemId = 'item_'+e.target.getAttribute('id');
targetButtonParent.insertAdjacentHTML('afterend', `
<tr>
<td></td>
<td>
<img src="" alt="" height="42" width="42">
<a href="">
Test Product2
</a>
</td>
<td class="deleteMe">
<button id='`+elemId+`' type="button" class="btn btn-danger btn-sm deleteMe">x</button>
</td>
</tr>
`)
if (targetButton.hasClass('product3') || targetButton.hasClass('product2')) {
targetButton.attr("disabled", true);
}
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableProd" style="float: left;" class="table table-bordered">
<tbody>
<tr>
<td>Product 2</td>
<td>
<button type="button" id='btn2' data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product 2
</button>
</td>
</tr>
<tr>
<td>Product 3</td>
<td>
<button type="button" id='btn3' data-exists="product3" class="btn btn-primary btn-sm product3">
Add Product 3
</button>
</td>
</tr>
<tr>
<td>Product 4</td>
<td>
<button type="button" id='btn4' data-exists="product4" class="btn btn-primary btn-sm product4">
Add Product 4
</button>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Just add $(".btn.btn-primary.btn-sm").attr("disabled", false); at the end of deleteRow method.
$(".btn.btn-primary.btn-sm").on("click", this.ourClickDispatcher.bind(this))
$("#tableProd").on("click", ".btn.btn-danger.btn-sm.deleteMe", this.deleteRow.bind(this))
function deleteRow(e) {
let deleteBtn = $(e.target).closest(".deleteMe");
deleteBtn.closest('tr').remove();
$(".btn.btn-primary.btn-sm").attr("disabled", false);
}
function ourClickDispatcher(e) {
let targetButton = $(e.target).closest(".btn.btn-primary.btn-sm")
let targetButtonParent = targetButton[0].parentElement.parentElement
targetButtonParent.insertAdjacentHTML('afterend', `
<tr>
<td></td>
<td>
<img src="" alt="" height="42" width="42">
<a href="">
Test Product2
</a>
</td>
<td class="deleteMe">
<button type="button" class="btn btn-danger btn-sm deleteMe">x</button>
</td>
</tr>
`)
if (targetButton.hasClass('product3') || targetButton.hasClass('product2')) {
targetButton.attr("disabled", true);
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableProd" style="float: left;" class="table table-bordered">
<tbody>
<tr>
<td>Product 2</td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product 2
</button>
</td>
</tr>
<tr>
<td>Product 3</td>
<td>
<button type="button" data-exists="product3" class="btn btn-primary btn-sm product3">
Add Product 3
</button>
</td>
</tr>
<tr>
<td>Product 4</td>
<td>
<button type="button" data-exists="product4" class="btn btn-primary btn-sm product4">
Add Product 4
</td>
</tr>
</tbody>
</table>

Insert row below clicked button

I am looking for a way to insert an element directly below a row. My table should look like the following:
As you can see the following element is inserted below my row:
<tr>
<td></td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
</td>
</tr>
Below you can find my viable example:
$(".btn.btn-dark.btn-sm").on("click", this.clickDispatcherTable.bind(this))
function clickDispatcherTable(e) {
let plusButton = $(e.target).closest(".btn.btn-dark.btn-sm")
if (plusButton.hasClass("product2")) {
let plusButtonParent = plusButton[0].parentElement
plusButtonParent.insertAdjacentHTML('beforebegin', `
<tr>
<td></td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
</td>
</tr>
`)
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="float: left;" class="table table-bordered">
<tbody>
<tr>
<td>Product 1</td>
<td>
<button type="button" data-exists="cpu" class="btn btn-primary btn-sm product1">
Add Product1
</button>
</td>
</tr>
<tr>
<td>Product 2</td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
<button type="button" class="btn btn-dark btn-sm product2">+</button>
</td>
</tr>
<tr>
<td>Product3</td>
<td>
<button type="button" data-exists="product3" class="btn btn-primary btn-sm product3">
Add Product 3
</button>
<button type="button" class="btn btn-dark btn-sm product3">+</button>
</td>
</tr>
</tbody>
</table>
As you can see the element is inserted on the side and not at the bottom.
Any suggestions how to insert the element below the row?
I appreciate your replies!
It is an issue with your Javascript. You were close!
This is the problematic line:
let plusButtonParent = plusButton[0].parentElement;
You are accessing the <td> element. So inserting a <tr> before the <td> starts would result in something like this:
<tr>
<tr> <!-- this code is added -->
<td>...</td> <!-- this code is added -->
</tr> <!-- this code is added -->
<td>...</td>
</tr>
That's clearly not what you want. So target the parent <tr> instead, and problem solved.
let plusButtonParent = plusButton[0].parentElement.parentElement;
And you will probably want to keep the Product 2 at the top like in your example. Easy, just change beforebegin to afterend.
$(".btn.btn-dark.btn-sm").on("click", this.clickDispatcherTable.bind(this))
function clickDispatcherTable(e) {
let plusButton = $(e.target).closest(".btn.btn-dark.btn-sm")
if (plusButton.hasClass("product2")) {
let plusButtonParent = plusButton[0].parentElement.parentElement;
plusButtonParent.insertAdjacentHTML('afterend', `
<tr>
<td></td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
</td>
</tr>
`)
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="float: left;" class="table table-bordered">
<tbody>
<tr>
<td>Product 1</td>
<td>
<button type="button" data-exists="cpu" class="btn btn-primary btn-sm product1">
Add Product1
</button>
</td>
</tr>
<tr>
<td>Product 2</td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
<button type="button" class="btn btn-dark btn-sm product2">+</button>
</td>
</tr>
<tr>
<td>Product3</td>
<td>
<button type="button" data-exists="product3" class="btn btn-primary btn-sm product3">
Add Product 3
</button>
<button type="button" class="btn btn-dark btn-sm product3">+</button>
</td>
</tr>
</tbody>
</table>

Jquery - Limit insertion of an element

I am trying to create a repeater field within my table.
Basically I want the following behavior:
If no "Test Product2" has been added to the table, the user cannot add another field below.
If a "Test Product2" has been added to the table, the user is allowed to add a field below and can add another "Test Product2" next to the new blue button.
The below an example of the second case for the behaviour.
$(".btn.btn-dark.btn-sm.product2").on("click", this.clickDispatcherTable.bind(this))
//$(".btn.btn-primary.btn-sm").on("click", this.ourClickDispatcher.bind(this));
$("#miningTable").on("click", ".btn.btn-primary.btn-sm.product2", this.ourClickDispatcher.bind(this));
function clickDispatcherTable(e) {
let plusButton = $(e.target).closest(".btn.btn-dark.btn-sm")
if (plusButton.hasClass("product2")) {
let plusButtonParent = plusButton[0].parentElement.parentElement;
plusButtonParent.insertAdjacentHTML('afterend', `
<tr>
<td></td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
</td>
</tr>
`)
}
}
function ourClickDispatcher(e) {
let targetButton = $(".btn.btn-primary.btn-sm.product2")
let targetButtonParent = targetButton[0].parentElement
targetButtonParent.insertAdjacentHTML('beforebegin', `
<td>
<img src="" alt="" height="42" width="42">
<a href="">
Test Product2
</a>
</td>
`)
targetButton.attr('class', 'btn btn-danger btn-sm product2'); // change button class to red
targetButton.text(function() {
return $(this).text().replace("Add", "Edit");
});
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="miningTable" style="float: left;" class="table table-bordered">
<tbody>
<tr>
<td>Product 2</td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
<button type="button" class="btn btn-dark btn-sm product2">+</button>
</td>
</tr>
<tr>
<td>Product 3</td>
<td>
<button type="button" data-exists="product3" class="btn btn-primary btn-sm product3">
Add Product3
</button>
</td>
</tr>
<tr>
<td>Product 4</td>
<td>
<button type="button" data-exists="product4" class="btn btn-primary btn-sm product4">
Add Product4
</td>
</tr>
</tbody>
</table>
As you can see in the above example a user can add multiple fields as he want. There is currently no restriction.
Any suggestions how to restrict the user for adding a field if a condition is not satisfied?
I appreciate your reply!
If I correctly understand your problem, think this is your answer
function clickDispatcherTable(e) {
let plusButton = $(e.target).closest(".btn.btn-dark.btn-sm")
let sw = true;
$( "tbody tr" ).each(function(index, row) {
if(row.children.length != 3) {
sw = false;
}
});
if (sw) {
$('tbody tr:last').after(`
<tr>
<td></td>
<td>
<button type="button" data-exists="product2" class="btn btn-primary btn-sm product2">
Add Product2
</button>
</td>
</tr>`)
}
}

PHP Form/Table - Sending row contents when checked

I am working on a project and have an idea but not sure how to accomplish (new to PHP/JS).
Basically, I have a table within a form with one row being a checkbox. I would like to check the box(es) and when the form is submitted it sends the values of each column in the selected rows.
For example:
1 - Domain | MatchedTo | Percentage | Checkbox
2 - Domain | MatchedTo | Percentage | Checkbox
If row 1 is checked I would like the submit to POST the domain, matchedto and percentage values.
Here is what I have so far:
<script type="text/javascript">
$('#test-form').submit(function(event) {
event.preventDefault();
var buttonAction = event.originalEvent.explicitOriginalTarget.value;
var formData = $(this).serialize();
var varData = formData + "&action=" + buttonAction;
$.ajax({
type: 'POST',
url: 'test_submit.php',
data: varData,
success: function() {
window.location.reload(true);
console.log("Form posted successfully.", varData);
}
})
});
</script>
<form method="POST" id="test-form">
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Ratio</th>
<th>Domain</th>
<th>Matched</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr id="6" role="row" class="odd">
<td>50</td>
<td class="sorting_1">www.test.com</td>
<td class="sorting_1">anothertest2.com</td>
<td><button type="button" class="btn btn-danger del_domain" domain="www.test.com">Remove</button>
<button type="button" class="btn btn-primary update_domain" domain="www.test.com" matchedto="anothertest2.com">Keep</button>
<input name="domain[]" value="www.test.com" type="checkbox"></td>
</tr>
<tr id="6" role="row" class="odd">
<td>50</td>
<td class="sorting_1">www.test2.com</td>
<td class="sorting_1">anothertest2.com</td>
<td><button type="button" class="btn btn-danger del_domain" domain="www.test2.com">Remove</button>
<button type="button" class="btn btn-primary update_domain" domain="www.test.com" matchedto="anothertest2.com">Keep</button>
<input name="domain[]" value="www.test2.com" type="checkbox"></td>
</tr>
</tbody>
</table>
<button class="btn btn-success" type="submit" value="save"><span class="fa fa-arrow-right">Save Selected</span></button>
<button class="btn btn-danger" type="submit" value="delete"><span class="fa fa-times">Delete Selected</span></button>
<button class="btn btn-warning" type="reset" value="reset"><span class="fa fa-times">Clear Selected</span></button>
</form>
I am assuming I need to create an input field for each column? How do I go about POSTing all of these fields when a box is checked?
Thank you for any assistance.
If you're going to submit via ajax, you'll probably want to create the string you'll be submitting. Something like the following may be a starting-point, if I understand what you're trying to do.
Note that this doesn't address actually sending the data, it's simply about how to hijack the form and create the format you're looking for.
// First, I'm stopping the default behaviors
$("button").on("click", function(event){
event.stopPropagation();
event.preventDefault();
})
// Now, when we click save, I want to format
// a string.
$("button[value='save']").on("click", function(){
var returnString = "";
// The following selector gets all the rows
// that have a CHECKED checkbox. Note I
// don't get the checkbox, simply the row.
var rowEls = $("#test-form").find("tr:has(input[type='checkbox']:checked) ");
// For every row, we'll add to our string...
rowEls.each(function(){
var rowEl = $(this);
// First, a row id
returnString += rowEl.attr("id")+" - ";
var cells = rowEl.children("td");
// Next the contents of each cell THAT
// HAS A data-content ATTRIBUTE. This
// way, we don't get the remove/keep.
cells.each(function(){
if($(this).data("content")){
returnString += $(this).data("content")+"="+$(this).text();
if($(this).not(":last"))
returnString += " | ";
}
})
returnString += " ";
})
console.log(returnString);
})
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="POST" id="test-form">
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Ratio</th>
<th>Domain</th>
<th>Matched</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr id="6" role="row" class="odd">
<td data-content="ratio">50</td>
<td class="sorting_1" data-content="domain">www.test.com</td>
<td class="sorting_1" data-content="matched">anothertest2.com</td>
<td><button type="button" class="btn btn-danger del_domain" domain="www.test.com">Remove</button>
<button type="button" class="btn btn-primary update_domain" domain="www.test.com" matchedto="anothertest2.com">Keep</button>
<input name="domain[]" value="www.test.com" type="checkbox"></td>
</tr>
<tr id="6" role="row" class="odd">
<td data-content="ratio">50</td>
<td class="sorting_1" data-content="domain">www.test2.com</td>
<td class="sorting_1" data-content="matched">anothertest2.com</td>
<td><button type="button" class="btn btn-danger del_domain" domain="www.test2.com">Remove</button>
<button type="button" class="btn btn-primary update_domain" domain="www.test.com" matchedto="anothertest2.com">Keep</button>
<input name="domain[]" value="www.test2.com" type="checkbox"></td>
</tr>
</tbody>
</table>
<button class="btn btn-success" type="submit" value="save"><span class="fa fa-arrow-right">Save Selected</span></button>
<button class="btn btn-danger" type="submit" value="delete" disabled><span class="fa fa-times">Delete Selected</span></button>
<button class="btn btn-warning" type="reset" value="reset" disabled><span class="fa fa-times">Clear Selected</span></button>
</form>

JQuery selector bug - not working

I have a weird JQuery bug that I cannot find the cause for.
There is an edit button for each row that changes the title and body cells to an input and textarea field.
It works for the first row but not for any other rows
If I click the first row, it will work for consecutive rows.
Can someone please have a look over my code
#extends('layouts')
#section('content')
<div class="container">
<h1>Diary Application</h1>
<button style="margin-bottom: 10px;" class="btn btn-primary"></span></button>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Date</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody>
#foreach($entries as $entry)
<tr id={{ $entry->id }}>
<td>{{ $entry->created_at->format('l h:ia d/m/Y') }}</td>
<td id="title">{{ $entry->title }}</td>
<td id="body">{{ $entry->body }}</td>
<td id="buttons"><button class="btn btn-danger"><a href={{ url("/deleteEntry/$entry->id")}}>Delete</a></button> <button class="btn btn-warning" id="edit" data-id={{ $entry->id }}>Edit</button></td>
</tr>
#endforeach
</tbody>
</table>
</div>
#endsection
#section('scripts')
<script>
$(document).ready(function() {
$("button#edit").click( function() {
var id = $(this).data("id");
var titleField = $("tr#" + id + " > td#title");
var contentField = $("tr#" + id + " > td#body");
alert("tr#" + id + " > td#body");
alert($("tr#" + id + " > td#body").html());
titleField.replaceWith("<td style='vertical-align: center;'><input type=text name='title' value=" + titleField.html() + "></td>");
contentField.replaceWith("<td style='vertical-align: center;'><textarea rows='3' name='body'> " + contentField.html() + "</textarea></td>");
$("tr#" + id + " > td#buttons").append(" <button class='btn btn-success'>Save</button>");
$("tr#" + id + " > td#buttons > .btn-warning").attr('disabled', 'disabled');
});
});
</script>
#endsection
Change id to class and try the below code,
$(document).ready(function() {
$("button.edit").click( function() {
var tr = $(this).closest("tr");
var titleField = tr.find(".title");
var contentField = tr.find(".body");
alert(contentField);
alert(contentField.html());
titleField.replaceWith("<td style='vertical-align: center;'><input type=text name='title' value=" + titleField.html() + "></td>");
contentField.replaceWith("<td style='vertical-align: center;'><textarea rows='3' name='body'> " + contentField.html() + "</textarea></td>");
tr.find(".buttons").append(" <button class='btn btn-success'>Save</button>")
.find(".btn-warning") // use chaining
.prop('disabled', true);// use prop instead of attr
});
});
Your HTML should be,
<tr id={{ $entry->id }}>
<td>{{ $entry->created_at->format('l h:ia d/m/Y') }}</td>
<td class="title">{{ $entry->title }}</td>
<td class="body">{{ $entry->body }}</td>
<td class="buttons"><button class="btn btn-danger"><a href={{ url("/deleteEntry/$entry->id")}}>Delete</a></button> <button class="btn btn-warning edit" data-id={{ $entry->id }}>Edit</button></td>
</tr>
Snippet,
$(document).ready(function() {
$("button.edit").click(function() {
var tr = $(this).closest("tr");
var titleField = tr.find(".title");
var contentField = tr.find(".body");
titleField.replaceWith("<td style='vertical-align: center;'><input type=text name='title' value=" + titleField.html() + "></td>");
contentField.replaceWith("<td style='vertical-align: center;'><textarea rows='3' name='body'> " + contentField.html() + "</textarea></td>");
tr.find(".buttons").append(" <button class='btn btn-success'>Save</button>")
.find(".btn-warning") // use chaining
.prop('disabled', true); // use prop instead of attr
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr id="1">
<td>Date 1</td>
<td class="title">Title1</td>
<td class="body">Body1</td>
<td class="buttons"><button class="btn btn-danger">Delete</button> <button class="btn btn-warning edit" data-id="1">Edit</button></td>
</tr>
<tr id="2">
<td>Date 2</td>
<td class="title">Title2</td>
<td class="body">Body2</td>
<td class="buttons"><button class="btn btn-danger">Delete</button> <button class="btn btn-warning edit" data-id="2">Edit</button></td>
</tr>
<tr id="3">
<td>Date 3</td>
<td class="title">Title3</td>
<td class="body">Body3</td>
<td class="buttons"><button class="btn btn-danger">Delete</button> <button class="btn btn-warning edit" data-id="3">Edit</button></td>
</tr>
</table>
First change the IDs to Classes &
Use jQuery's $.closest() like below
$(document).ready(function() {
$("button#edit").click( function() {
var tr = $(this).closest("tr"); // This will give you the TR in which your elements reside.
....
your rest of the code with some modifications
....
});
});
You are generating several button tags with de same id (#edit), in the html document an id attibute must be unique, you could use a class selector like this.
<button class="btn btn-warning edit" data-id={{ $entry->id }}>Edit</button>
And then in your javascript use:
$("button.btn.edit").click( function() {...});

Categories

Resources