Model class only popups on first button when used in append - javascript

I am using Material UI to build a website. I have append a list with data and it also has a popup on button. But the popup works only on first button click.
I want to make a new popup on every button click. Also here is a error from console.
"Uncaught DOMException: Failed to execute 'showModal' on 'HTMLDialogElement': The element already has an 'open' attribute, and therefore cannot be opened modally.
at HTMLDivElement."
Here is HTML
<div id="order">
<dialog style="width: 40%;" class="mdl-dialog">
<div class="mdl-dialog__content">
<table id="table" style="width: 100%;" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Material</th>
<th>Quantity</th>
<th>Unit price</th>
</tr>
</thead>
<tbody style="width: 100%;" id="producttable">
</tbody>
</table>
</div>
<div class="mdl-dialog__actions">
<button type="button" class="mdl-button close">Confirm Order</button>
<button type="button" class="mdl-button">Order Shipped</button>
<button type="button" class="mdl-button">Order Delivered</button>
<button type="button" class="mdl-button">Order Canceled</button>
</div>
</dialog>
</div>
Here is JS
$("#order").append(
'<div style="padding-top:6px; padding-bottom:6px; margin-bottom: 16px;" class="card-wide mdl-card-order mdl-shadow--2dp"><h3 id="orderID" style="margin: 16px;" class="mdl-card__title-text">' +
'<a style="float: left; width: 65%;">Order ID : ' + orderid + ' </a><a style="float: right; width: 35%;">Date : ' + orderDate +
'</a></h3><div style="margin-left: 16px;"><p id="client_name" style=" font-size: 18px;"> Name - ' +
name + '</p><p id="client_email" style=" font-size: 18px;">Phone - ' + phone +
'</p><p id="client_email" style=" font-size: 18px;">Address - ' + address +
'</p></div><div class="mdl-card__menu"></div><div id="dialog" class="mdl-card__actions mdl-card--border"> <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" onclick="purchaseList(' + orderid + ')"> Purchase List </a></div></div>');
function purchaseList(listid) {
var starCountRef = firebase.database().ref('Orders/' + listid).child('foodItems');
starCountRef.on('child_added', snapshot => {
var snaps = snapshot.val();
var itemPrice = snaps.price;
var itemName = snaps.productName;
var itemQuantity = snaps.quantity;
console.log(itemName);
$("#producttable").append(
'<tr><td class="mdl-data-table__cell--non-numeric">' + itemName + '</td><td>' + itemQuantity + '</td><td>' + itemPrice + '</td></tr>'
);
});
var dialog = document.querySelector('dialog');
var showDialogButton = document.querySelector('#dialog');
if (!dialog.showModal) {
dialogPolyfill.registerDialog(dialog);
}
showDialogButton.addEventListener('click', function () {
dialog.showModal();
});
dialog.querySelector('.close').addEventListener('click', function () {
var element = document.getElementById("producttable");
while (element.lastChild) {
element.removeChild(element.lastChild);
}
dialog.close();
});
}

Dont know if it is the point but
dialog.querySelector('.close').addEventListener(...
wont work with multiple classes. You have to use the
classList.contains('close')
for example but i would just give an id to the .close element to get it easy
<button type="button" id ="close" class="mdl-button">Confirm Order</button>
dialog.querySelector("#close");
or even better generate your HTML tag elements in JS to have direct access like
const closeBtn = document.createElement("button");
closeBtn.className = "mdl-button";
closeBtn.type = "button";
dialog.querySelector(".mdl-dialog__actions").append(closeBtn);
closeBtn.addEventListener("click", (e)=>{
//Todo on click
})

Related

How to add dynamic fields in ajax post call

function submitData(productSubtypeId, orderNumber) {
// Get all dynamic input fields belonging to a class so that we can check if a value for those were provided or not
var cells = document.getElementsByClassName(
orderNumber + "-" + productSubtypeId + "-" + "supplData"
);
for (var i = 0; i < cells.length; i++) {
if (
document.getElementById(
orderNumber + "-" + productSubtypeId + "-" + cells[i].name
).value == ""
)
alert(cells[i].name + " is required");
return false;
}
if (
confirm(
"Confirm submitted data for order " +
orderNumber +
"?\nDon't forget to close the order after submitting supplemental data."
)
) {
$.ajax({
url: "FillSupplData.cfm",
type: "post",
data: {
productSubtypeId: productSubtypeId,
orderNumber: orderNumber,
DEPLOY_DATE: document.getElementById(
orderNumber + "-" + productSubtypeId + "-" + "DEPLOY_DATE"
).value,
},
success: function (response) {
// Remove data submit (supplemental) button once data is successfully submitted
$(
"#" + orderNumber + "-" + productSubtypeId + "-" + "fillSupplData"
).remove();
// Disable all supplemental data input fields for this order
//var cells = document.getElementsByClassName(orderNumber + '-' + productSubtypeId + '-' + 'supplData');
for (var i = 0; i < cells.length; i++) {
cells[i].disabled = true;
}
// Make order close button visible
document.getElementById(
orderNumber + "-" + productSubtypeId + "-" + methodInvoked
).style.display = "block";
},
error: function (jqXHR, exception) {
var msg = "An error occurred";
alert(msg);
},
});
}
}
This is part of the HTML code I have :
<table class="order w100p" id="3202643984">
<tbody>
<tr>
<td style="width: 50%; vertical-align: top">
<div>
<table class="order-header">
<tbody>
<tr>
<th style="width: 15%">Order Number</th>
<th style="width: 20%">Scheduled Ship Date</th>
<th style="width: 30%">Customer Name</th>
<th style="width: 20%">Customer Number</th>
<th style="width: 20%">Customer PO</th>
</tr>
<tr>
<td>
<a
id="3202643984-104"
class="orderLink"
style="display: block"
>3202643984</a
>
</td>
<td />
<td>LOGAN COUNTY SHERIFF</td>
<td>1000269359</td>
<td>RG212738</td>
</tr>
</tbody>
</table>
</div>
</td>
<td style="width: 30%; vertical-align: top">
<div id="3202643984-line-items">
<table>
<tbody>
<tr>
<th style="width: 15%">Line Num</th>
<th style="width: 20%">Part Number</th>
<th style="width: 15%">Qty</th>
<th style="width: 50%">Description</th>
</tr>
<tr>
<td>1.1</td>
<td>AAS00100</td>
<td>1</td>
<td>EVIDENCE BWC AS A SERVICE</td>
</tr>
<tr>
<td>2.1</td>
<td>AAS00101</td>
<td>1</td>
<td>VIDEO-AS-A-SERVICE</td>
</tr>
</tbody>
</table>
</div>
</td>
<form id="SupplDataForm" action="FillSupplData1.cfm" method="post" />
<input type="hidden" name="orderNumber" value="3202643984" />
<input type="hidden" name="productSubtypeId" value="104" />
<input type="hidden" name="toolSectionId" value="Watchguard" />
<td style="vertical-align: top">
<div style="padding-bottom: 10px">
<strong>Additional Order Data</strong>
</div>
<div style="width: 150px">
<div>
Deploy Date:
<input
type="date"
id="3202643984-104-DEPLOY_DATE"
name="DEPLOY_DATE"
placeholder="Deploy Date"
value=""
class="3202643984-104-supplData"
style="border: 2px solid lightgray; width: 90%"
size="200"
required
/>
<strong style="color: red; font-size: 24px">*</strong>
</div>
</div>
</td>
<td style="width: 10%; vertical-align: top; padding-top: 40px">
<input
id="3202643984-104-fillSupplData"
style="float: right; width: 125px; margin: 0px 5px"
type="button"
class="button"
value="Submit Data"
onclick="submitData(productSubtypeId = 104, orderNumber = '3202643984');"
/>
<button
type="button"
id="3202643984-104-close"
onclick="manualMethod(productSubtypeId = 104, methodInvoked = 'close', orderNumber = '3202643984');"
style="margin-bottom: 10px; display: none"
>
Close
</button>
</td>
</tr>
</tbody>
</table>
Now the issue I need help with is that the input fields for the orders are dynamic depending on the product sub type they belong to and I need to grab those fields and create variables so that I can submit the values in ajax call.
data: {
productSubtypeId: productSubtypeId,
orderNumber: orderNumber,
DEPLOY_DATE : document.getElementById(orderNumber + '-' + productSubtypeId + '-' + 'DEPLOY_DATE').value
}
Here, I have DEPLOY_DATE but how can I do it so that I don't have to hardcode field name and value. I can have 2-3 different fields here depending on what fields are required for this product sub type.
Thanks for your help in this regard
Looks like you've got everything you need in the <form> itself.
Use the .serialize() function to capture all the <form> element data. I would also recommend listening to the submit event rather than a button click so you have a direct reference to the form
$("table.order form").on("submit", (e) => {
e.preventDefault(); // prevent normal submit
const form = $(e.target); // <form> ref
const cells = form.find("[class$='-supplData']");
// get the names of any empty inputs
const emptyData = cells
.filter((_, { value }) => value === "")
.map((_, { name }) => name)
.get();
if (emptyData.length) {
alert(`${emptyData.join(", ")} required`);
return false;
}
const orderNumber = form.find("[name='orderNumber']").val();
if (
!confirm(
"Confirm submitted data for order " +
orderNumber +
"?\nDon't forget to close the order after submitting supplemental data."
)
) {
return false;
}
$.post("FillSupplData.cfm", form.serialize())
.done((response) => {
form.find("button[type=submit]").remove();
form.find("button[type=button]").show();
cells.prop("disabled", true);
})
.fail((_, ...errors) => {
console.warn(...errors);
alert("An error occurred");
});
});
The only change to the HTML would be for your buttons
<button
id="3202643984-104-fillSupplData"
style="float: right; width: 125px; margin: 0px 5px"
type="submit"
class="button"
value="Submit Data"
/>
<button
type="button"
id="3202643984-104-close"
onclick="manualMethod(104, 'close', '3202643984');"
style="margin-bottom: 10px; display: none"
>
Close
</button>
var formData = {
productSubtypeId: 108,
orderNumber: 5673856
};
What I wanted was to add a property to an object that I am passing in ajax. That can be achieved like this :
formData['newPropertyName'] = document.getElementById(orderNumber + '-' + productSubtypeId + '-' + 'newPropertyName').value;

how can i delete row that i clicked its button?

I have table tag in cshtml page and append tr and td via ajax,now i dont know how to say delete row when i click on it,furthermore i dont know how to get value of inputs in each row.
/// <reference path="jquery-2.2.4.js"/>
$(document).ready(function () {
$.ajax({
type: "GET",
url: "api/ProductsApi/GetProducts",
success: function (Products) {
debugger;
let item0 = '<tr>' +
'<th>d</th>' +
'<th>d</th>' +
'<th>d</th>' +
'<th>d</th>' +
'<th>d</th>' +
'</tr>';
$("#AdminProductList").append(item0);
for (var i = 0; i < Products.length; i++) {
var d = Products[i].split("/");
let item = '<tr >' +
'<td><img src="/locker/' + d[0] + ' "alt="gnjh " style="width:70px;height:70px" /></td>' +
'<td>'+d[3]+'</td>' +
'<td>'+d[2]+'</td>'+
'<td>' + d[1] + '</td>' +
'<input id="AdminProductId'+i+'" type="hidden" value="'+d[5]+'" />'+
'<td id="'+i+'">' +
'<button data-toggle="tooltip" value="'+d[5]+'" class="pd-setting-ed eachEdit"><i class="fa fa-pencil-square-o" aria-hidden="true"></i><input type="hidden" value="' + d[5] +'"/></button>' +
'<button data-toggle="tooltip" title="Trash" class="pd-setting-ed eachTrash"><i class="fa fa-trash-o" aria-hidden="true"></i></button>' +
'</td>' +
'</tr>';
$("#AdminProductList").append(item);
}
},
error: function (f) {
debugger;
alert("nashod");
}
});
})
<div id="ListPage" style="display:none" class="product-status mg-tb-15">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="product-status-wrap" style="direction:rtl;">
<h4>f</h4>
<button style=" border: 0;width: 270px;padding: 10px;-webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;display: block;text-decoration: none;text-align: center;font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size: 1.2em;color: #FFF;background: #bc3737;-webkit-box-shadow: 0 3px 1px #950d0d;-moz-box-shadow: 0 3px 1px #950d0d;box-shadow: 0 3px 1px #950d0d;" class="add-product" id="Edit"> افزودن محصول</button>
<table id="AdminProductList" style="direction:rtl;">
</table>
</div>
</div>
</div>
</div>
</div>
i dont kow how to say when i click,by id................................
...............................................................................
.........................................................
..................................................
........................................................................
......................................................................
.
.......................
I think you should add an event listener to the table rows in order to delete them:
$(document).on('click', '#AdminProductList>tr', function(){
$(this).remove()
});
And if you want to get input values, actually there are a lot of ways to do it. If you want to get all the input values, you can traverse over them like this:
function getInputValues(){
$('tr input').each(function(){
console.log($(this).val());
});
}
Try like this:
$.ajax({
type:'POST',
url:'delete.php',
data:{del_id:del_id},
success: function(data){
if(data=="YES"){
$ele.fadeOut().remove();
}else{
alert("can't delete the row")
}
}
})
})
$('button').click(function(){
var tr = $(this).closest('tr');
var inputs = tr.find('input');
alert($(inputs[0]).val());
alert($(inputs[1]).val());
tr.remove();
})
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="text" /></td>
<td>Hidden value here<input type="hidden" value="test hidden" /></td>
<td><button>Remove</button></td>
</tr>
</table>
You can use this script
$('button').click(function(){
$(this).closest('tr').remove();
})
or write click method
<button click="remove(this)" data-toggle="tooltip" title="Trash" class="pd-setting-ed eachTrash"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
function remove(item){
$(item).closest('tr').remove();
}
Updated: i create a demo for get input value.
var inputs = tr.find('input');
alert($(inputs[0]).val());
alert($(inputs[1]).val());
You need to add an on click event handler for the delete button and then delete that specific row.
I have edited your code to add the event listener and also delete the element.
/// <reference path="jquery-2.2.4.js"/>
$(document).ready(function () {
window.deleteTableRow = function (selector) { $('tr'+selector).remove(); }
$.ajax({
type: "GET",
url: "api/ProductsApi/GetProducts",
success: function (Products) {
debugger;
let item0 = '<tr>' +
'<th>d</th>' +
'<th>d</th>' +
'<th>d</th>' +
'<th>d</th>' +
'<th>d</th>' +
'</tr>';
$("#AdminProductList").append(item0);
for (var i = 0; i < Products.length; i++) {
var d = Products[i].split("/");
let item = '<tr class="data-delete-index-'+ i +'">' +
'<td><img src="/locker/' + d[0] + ' "alt="gnjh " style="width:70px;height:70px" /></td>' +
'<td>'+d[3]+'</td>' +
'<td>'+d[2]+'</td>'+
'<td>' + d[1] + '</td>' +
'<input id="AdminProductId'+i+'" type="hidden" value="'+d[5]+'" />'+
'<td id="'+i+'">' +
'<button data-toggle="tooltip" value="'+d[5]+'" class="pd-setting-ed eachEdit"><i class="fa fa-pencil-square-o" aria-hidden="true"></i><input type="hidden" value="' + d[5] +'"/></button>' +
'<button onclick="deleteTableRow(\'.data-delete-index-'+ i +'\')" data-toggle="tooltip" title="Trash" class="pd-setting-ed eachTrash"><i class="fa fa-trash-o" aria-hidden="true"></i></button>' +
'</td>' +
'</tr>';
$("#AdminProductList").append(item);
}
},
error: function (f) {
debugger;
alert("nashod");
}
});
})

how to retrieve data from indexeddb and show in a div

I have created a function readAll() which is fetching data into the todos div but it is not showing data on the click function but it is not working data is adding successfully in the index db but it is not showing. Now I first i have empty the table after that I just have append the data into the html from the javascript.
function readAll() {
var objectStore = db.transaction("todostore").objectStore("todostore");
$("#todos").empty();
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
$("#todos").append("<tr><td>" + cursor.key + "</td><td>" + cursor.value.todo + "</td><td><button onclick=\"update('" + cursor.key + "','" + cursor.value.todo + "')\">Update</button></td><td><button onclick=\"removetodo('" + cursor.key + "','" + cursor.value.todo + "')\">Delete</button></td></tr>");
cursor.continue();
}
};
};
now I am calling the function on the click I am just calling the readAll Function
$(".clickme").click(function(){
readAll();
});
I have created a div of id view inside the div i have use a table head now I am just appending the code from the JavaScript and populate into the html
<div id="view">
<thead>
<tr class="ui-bar-d">
<th data-priority="2">Timestamp</th>
<th data-priority="1">To Do</th>
<th data-priority="3">Update</th>
<th data-priority="4">Delete</th>
</tr>
</thead>
<tbody id="todos">
</tbody>
</table>
</div>
<label for="todo">To Do:</label>
<input id="todo" type="text">
<input id="toprice" type="text">
<button class="clickme">clickme</button>
<button class="ui-shadow ui-btn ui-corner-all" onclick="add()">Add</button>
As IDB is async.You will need to call you're function in ....
transaction.oncomplete = function(event) {
$(".clickme").click(function(){
readAll();
});
};
https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/oncomplete

Sum dynamically generated fees

I am designing fee system where in user can define fees component and themseleves. I have managed to create facility for user to define the fee component and fee amount as per their need. But when I am trying to add them this doesnt seems to be working even though I am trying to add them by allocating class to them. Below is the html code :
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
<link rel="stylesheet" href="masterfees.css" />
<title>feemaster</title>
<script type="text/javascript" src="ffees.js"></script>
<script type="text/javascript">
function totalfixfees(){
var tffees = 0;
var cusid_ele = document.getElementsByClassName('ffeetotal');
for (var i = 0; i < cusid_ele.length; ++i) {
if (!isNaN(parseFloat(cusid_ele[i].value)) )
tffees += parseFloat(cusid_ele[i].value);
}
document.getElementById('tffees').value=tffees;
}
</script>
<script></script>
<style>
</style>
</head>
<body>
<!-- Trigger/Open The Modal for adding fees -->
<button id="myBtn">Add New Fees</button>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-header">
<span class="close"><button>✖</button></span>
<h2>Create Fees</h2>
</div>
<div class="modal-body">
<fieldset>
<legend>Fixed Fees Component</legend>
<div id="wrapper">
<table align='center' cellspacing=2 cellpadding=5 id="data_table" border=1>
<tr>
<th>Name</th>
<th>Amount (in Rs)</th>
</tr>
<tr id="row1">
<td id="ffname_row1">Annual Fees</td>
<td id="ffamount_row1" class="ffeetotal">1000</td>
<td>
<input type="button" id="edit_button1" value="Edit" class="edit" onclick="edit_row('1')">
<input type="button" id="save_button1" value="Save" class="save" onclick="save_row('1')">
<input type="button" value="Delete" class="delete" onclick="delete_row('1')">
</td>
</tr>
<tr id="row2">
<td id="ffname_row2">Medical Fees</td>
<td id="ffamount_row2" class="ffeetotal">2000</td>
<td>
<input type="button" id="edit_button2" value="Edit" class="edit" onclick="edit_row('2')">
<input type="button" id="save_button2" value="Save" class="save" onclick="save_row('2')">
<input type="button" value="Delete" class="delete" onclick="delete_row('2')">
</td>
</tr>
<tr id="row3">
<td id="ffname_row3">Tution Fees</td>
<td id="ffamount_row3" class="ffeetotal">3000</td>
<td>
<input type="button" id="edit_button3" value="Edit" class="edit" onclick="edit_row('3')">
<input type="button" id="save_button3" value="Save" class="save" onclick="save_row('3')">
<input type="button" value="Delete" class="delete" onclick="delete_row('3')">
</td>
</tr>
<tr>
<td><input type="text" id="new_ffname"></td>
<td><input type="number" id="new_ffamount" class="ffeetotal"></td>
<td><input type="button" class="add" onclick="add_row();" value="Add Row"></td>
</tr>
</table>
</div>
<br>
<label> Fixed Fee Total </label>
<input name="tffees" type="text" id="tffees" class="n1fees" value="" readonly>
<button onclick="totalfixfees()">Calculate Total Fees</button>
</div>
<div class="modal-footer">
<h3></h3>
</div>
</div>
</div>
<script>
// Get the modal
var modal = document.getElementById('myModal');
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
</body>
</html>
The javascript is
function edit_row(no)
{
document.getElementById("edit_button"+no).style.display="none";
document.getElementById("save_button"+no).style.display="block";
var ffname=document.getElementById("ffname_row"+no);
var ffamount=document.getElementById("ffamount_row"+no);
var ffname_data=ffname.innerHTML;
var ffamount_data=ffamount.innerHTML;
ffname.innerHTML="<input type='text' id='ffname_text"+no+"' value='"+ffname_data+"'>";
ffamount.innerHTML="<input type='number' class='ffeetotal' id='ffamount_text"+no+"' value='"+ffamount_data+"'>";
}
function save_row(no)
{
var ffname_val=document.getElementById("ffname_text"+no).value;
var ffamount_val=document.getElementById("ffamount_text"+no).value;
document.getElementById("ffname_row"+no).innerHTML=ffname_val;
document.getElementById("ffamount_row"+no).innerHTML=ffamount_val;
document.getElementById("edit_button"+no).style.display="block";
document.getElementById("save_button"+no).style.display="none";
}
function delete_row(no)
{
document.getElementById("row"+no+"").outerHTML="";
}
function add_row()
{
var new_ffname=document.getElementById("new_ffname").value;
var new_ffamount=document.getElementById("new_ffamount").value;
var table=document.getElementById("data_table");
var table_len=(table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr id='row"+table_len+"'><td id='ffname_row"+table_len+"'>"+new_ffname+"</td><td id='ffamount_row"+table_len+"'>"+new_ffamount+"</td><td><input type='button' id='edit_button"+table_len+"' value='Edit' class='edit' onclick='edit_row("+table_len+")'> <input type='button' id='save_button"+table_len+"' value='Save' class='save' onclick='save_row("+table_len+")'> <input type='button' value='Delete' class='delete' onclick='delete_row("+table_len+")'></td></tr>";
document.getElementById("new_ffname").value="";
document.getElementById("new_ffamount").value="";
}
I am not sure where I am going wrong. Can you please help me ?
Thanks
You have to add the ffeetotal class to the newly added td in add_row function. Use this fiddle:
JS:
function totalfixfees(){
var tffees = 0;
var cusid_ele = document.getElementsByClassName('ffeetotal');
//debugger;
for (var i = 0; i < cusid_ele.length; i++) {
if (!isNaN(parseFloat(cusid_ele[i].innerText)) )
tffees += parseFloat(cusid_ele[i].innerText);
}
document.getElementById('tffees').innerText = tffees;
}
function add_row() {
var new_ffname = document.getElementById("new_ffname").value;
var new_ffamount = document.getElementById("new_ffamount").value;
var table = document.getElementById("data_table");
var table_len = (table.rows.length) - 1;
var row = table.insertRow(table_len).outerHTML = "<tr id='row" + table_len + "'><td id='ffname_row" + table_len + "'>" + new_ffname + "</td><td class='ffeetotal' id='ffamount_row" + table_len + "'>" + new_ffamount + "</td><td><input type='button' id='edit_button" + table_len + "' value='Edit' class='edit' onclick='edit_row(" + table_len + ")'> <input type='button' id='save_button" + table_len + "' value='Save' class='save' onclick='save_row(" + table_len + ")'> <input type='button' value='Delete' class='delete' onclick='delete_row(" + table_len + ")'></td></tr>";
document.getElementById("new_ffname").value = "";
document.getElementById("new_ffamount").value = "";
}
You are reading the value property for retrieving the fees, but these elements are not input elements, but td elements, which don't have a value property.
Instead use textContent:
function totalfixfees(){
var tffees = 0;
var cusid_ele = document.getElementsByClassName('ffeetotal');
for (var i = 0; i < cusid_ele.length; ++i) {
if (!isNaN(parseFloat(cusid_ele[i].textContent)) )
tffees += parseFloat(cusid_ele[i].textContent);
}
document.getElementById('tffees').value=tffees;
}
Make sure to also add the class ffeetotal to the relevant td elements when you insert new rows. So change accordingly the following assignment:
var row = table.insertRow(table_len).outerHTML="...
.. so it has the class mentioned in this part:
"... <td id='ffamount_row"+table_len+"' class='ffeetotal'> ..."

Dynamically creating buttons with popovers

I try to create buttons with popovers via JS dynamically. So far so good but I can't make it to get Div content attached to the popovers. They show up if I press the button but except of the headline they are just empty. Therefore I guess the problem lies in the //Append newDiv to Popovercontent - Part. But exactly with this function I am able to append div boxes to my popovers statically.
HTML:
<table id="table">
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
<tr>
<td></td>
<td>
<div id="div" style="display:none">
<input type="checkbox"> Label 1</input><br>
<input type="checkbox"> Label 2</input>
</div>
</td>
<td style="text-align: center; vertical-align: middle;">
<button data-toggle="popover" id="btn1" data-original-title="Popover" data-html="true" data-placement="bottom" type="button" class="btn btn-default" aria-label="Left Align">
<span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span>
</button>
</td>
</tr>
</table>
JS:
$("#btn1").popover({
html: true,
content: function() {
return $("#div").html();
}
});
var id = 2;
function addButton() {
//Creating HTML-Code for popovers
var newHTML = "<div style='display:none' id = 'newDiv" + id + "'>";
for (i = 0; i < 2; i++) {
newHTML += "<input type=\"checkbox\" name=\"name" + id + i + "\">Label" + i + "</input><br>";
}
newHTML += "</div><button data-toggle=\"popover\" id=\"btn" + id + "\" data-original-title=\"Popover\" data-html=\"true\" data-placement=\"bottom\" type=\"button\" class=\"btn btn-default\" aria-label=\"Left Align\">";
newHTML += "<span class=\"glyphicon glyphicon-chevron-down\" aria-hidden=\"true\"></span></button>";
//Creating new Element
var trhtml = document.getElementById("table").insertRow();
var tdhtml = document.createElement("td");
tdhtml.style = "text-align: center; vertical-align: middle;";
tdhtml.innerHTML = newHTML;
trhtml.appendChild(tdhtml);
//Initialize new Popover
$('[data-toggle="popover"]').popover();
//Append newDiv to Popovercontent
$("#btn" + id).popover({
html: true,
content: function() {
return $("#newDiv" + id).html();
}
});
id=id+1;
}
Thank you very much!
You are facing this problem because are binding id inside popover content callback and then you are using variable id to create jquery selector $("#newDiv" + id).html()
But the id variable is incremented each time, When the actual popover event called it receive id value NoOfRowInTable+1 for all popover content function calllback.
For example if you have called addButton() 2 time the value of id inside popover content callback will be revived as 4 for all popover content callback function.
You can find a better explanation here
JavaScript closure inside loops – simple practical example
Although for your example you don't need to make a hidden div with some id
you can create html String for checkboxes and then add it to popover content callback .
Here is working demo
EDIT : Use .bind() to bind id properly
$("#btn1").popover({
html: true,
content: function() {
return $("#div").html();
}
});
var id = 2;
$("#btn1").popover({
html: true,
content: function() {
return $("#div").html();
}
});
var id = 2;
function addButton() {
//Creating HTML-Code for popovers
var newHTML = "<div style='display:none' id = 'newDiv" + id + "'>";
for (i = 0; i < 2; i++) {
newHTML += "<input type=\"checkbox\" name=\"name" + id + i + "\">Label" + i + "</input><br>";
}
newHTML += "</div><button data-toggle=\"popover\" id=\"btn" + id + "\" data-original-title=\"Popover\" data-html=\"true\" data-placement=\"bottom\" type=\"button\" class=\"btn btn-default\" aria-label=\"Left Align\">";
newHTML += "<span class=\"glyphicon glyphicon-chevron-down\" aria-hidden=\"true\"></span></button>";
//Creating new Element
var trhtml = document.getElementById("table").insertRow();
//add empty first empty column
var tdhtml0 = document.createElement("td");
trhtml.appendChild(tdhtml0);
var tdhtml1 = document.createElement("td");
tdhtml1.style = "text-align: center; vertical-align: middle;";
tdhtml1.innerHTML = newHTML;
trhtml.appendChild(tdhtml1);
//Append newDiv to Popovercontent
$("#btn" + id).popover({
html: true,
content: function(id) {
return $("#newDiv" + id).html();
}.bind(this, id)
});
id = id + 1;
}
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="//code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<table id="table" class="table">
<tr>
<th>Col 1</th>
<th>Col 2</th>
</tr>
<tr>
<td>
<div id="div" style="display:none">
<input type="checkbox">Label 1
<br>
<input type="checkbox">Label 2
</div>
</td>
<td style="text-align: center; vertical-align: middle;">
<button data-toggle="popover" id="btn1" data-original-title="Popover" data-html="true" data-placement="bottom" type="button" class="btn btn-default" aria-label="Left Align">
<span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span>
</button>
</td>
</tr>
</table>
<button onclick="addButton()">Add Row</button>

Categories