Removing & Updating Table Rows Using jQuery - javascript

I am a novice when it comes to jQuery so please bear with me a little and I apologies for my poor coding in advance.
The logic to my code is simple or at least that was the aim.
A jQuery script checks a type field and then gets its values and builds a table. That all works 100%.
The issue comes when deleting rows and then updating the table id's on the new appended rows that is generated by clicking on the new row button.
The new rows do not delete.
Here is the code but I have also created a jsfiddle so you can check it out live, but there are some bugs that are not there on the site - for instance you need to double click the button for some reason for it to work
JS:
$('.purchase-order-button').on('click', function(){
var buildcotable = '';
var buildtrs = $('#formentry15').val();
var coArray = '';
var coArrayNumber = 1;
buildcotable += '<div class="table-responsive">';
buildcotable += '<table class="table table-bordered">';
buildcotable += '<thead>';
buildcotable += '<th class="text-center">CO Number</th>';
buildcotable += '<th class="text-center">CO Price</th>';
buildcotable += '<th class="text-center">Options</th>';
buildcotable += '</thead>';
buildcotable += '<tbody id="jquerypotable">';
//lets do a check and see how many are listed
if(buildtrs.indexOf(',') !== -1){
coArray = buildtrs.split(',');
$.each(coArray, function(){
var splitCoArray = this.split('=');
var coArrayPrice = splitCoArray[1].trim().replace('£', '');
var coArrayCode = splitCoArray[0].trim();
buildcotable += '<tr id="jqueryporow'+coArrayNumber+'">';
buildcotable += '<td><input type="text" value="'+coArrayCode+'" id="jqueryponumber'+coArrayNumber+'" class="form-control"></td>';
buildcotable += '<td><input type="text" value="'+coArrayPrice+'" id="jquerypovalue'+coArrayNumber+'" class="form-control"></td>';
buildcotable += '<td class="text-center"><a class="btn btn-danger delete-co-row" id="deletepo'+coArrayNumber+'">Delete CO Number</a></td>';
buildcotable += '</tr>';
coArrayNumber += 1;
});
} else {
if(buildtrs == '' || buildtrs == 'TBC'){
buildcotable += '<tr id="jqueryporow1">';
buildcotable += '<td><input type="text" value="" id="jqueryponumber1" class="form-control"></td>';
buildcotable += '<td><input type="text" value="" id="jquerypovalue1" class="form-control"></td>';
buildcotable += '<td class="text-center"><a class="btn btn-danger delete-co-row" id="deletepo1">Delete CO Number</a></td>';
buildcotable += '</tr>';
} else {
var splitSingleCoArray = buildtrs.split('=');
var coSinglePrice = splitSingleCoArray[1].trim().replace('£', '');
var coSingleCode = splitSingleCoArray[0].trim();
buildcotable += '<tr id="jqueryporow1">';
buildcotable += '<td><input type="text" value="'+coSingleCode+'" id="jqueryponumber1" class="form-control"></td>';
buildcotable += '<td><input type="text" value="'+coSinglePrice+'" id="jquerypovalue1" class="form-control"></td>';
buildcotable += '<td class="text-center"><a class="btn btn-danger delete-co-row" id="deletepo1">Delete CO Number</a></td>';
buildcotable += '</tr>';
}
}
buildcotable += '</tbody>';
buildcotable += '</table>';
buildcotable += '<p>Add New CO Number</p>';
buildcotable += '<p>Done</p>';
buildcotable += '</div>';
$('.ubl-section-7').html(buildcotable);
$('.ubl-section-7').show();
$('.model-background').fadeIn(500);
//add new row
$('#addnewpo').on('click', function(e){
e.preventDefault();
var numPoRows = $("#jquerypotable > tr").length;
var makeNewRowNum = numPoRows + 1;
var createnewporow = '<tr id="jqueryporow'+makeNewRowNum+'">';
createnewporow += '<td><input type="text" value="" id="jqueryponumber'+makeNewRowNum+'" class="form-control"></td>';
createnewporow += '<td><input type="text" value="" id="jquerypovalue'+makeNewRowNum+'" class="form-control"></td>';
createnewporow += '<td class="text-center"><a class="btn btn-danger delete-co-row-new" id="deletepo'+makeNewRowNum+'">Delete CO Number</a></td>';
createnewporow += '</tr>';
$('#jquerypotable').append(createnewporow);
});
//delete row
$('#jquerypotable > tr').on('click', '.delete-co-row', function(e){
e.preventDefault();
var getCoId = $(this).attr('id');
var coLastChar = parseInt(getCoId.substr(getCoId.length - 1));
var coHowManyRows = parseInt($("#jquerypotable > tr").length);
var makeMinusId = '';
var newi = coLastChar;
if(coLastChar == coHowManyRows){
$('#jqueryporow'+coLastChar).remove();
} else {
//before removing rows we need to rebuild the information given.
for(newi; newi <= coHowManyRows; newi++){
if(newi == coLastChar){
$('#jqueryporow'+newi).remove();
} else {
makeMinusId = (newi - 1);
$('#jqueryporow'+newi).attr('id', 'jqueryporow'+makeMinusId);
$('#jqueryponumber'+newi).attr('id', 'jqueryponumber'+makeMinusId);
$('#jquerypovalue'+newi).attr('id', 'jquerypovalue'+makeMinusId);
$('#deletepo'+newi).attr('id', 'deletepo'+makeMinusId);
}
}
}
});
});
enter link description here
Any help is gratefully received

You added an eventListener to the delete buttons at the initialization of the page but didnt do it again when creating the rows. I suggest adding the following code to your addnewpo button:
$('#addnewpo').on('click', function(e){
// your original code here
//...
//now add an event listener to the new deletebuttons
$('#jquerypotable > tr').on('click', '.delete-co-row-new', function(e){
e.preventDefault();
$(this).closest('tr').remove();
});
});

I Found the issue, the issue was the listener needed to remove the tr.
so instead of:
/now add an event listener to the new deletebuttons
$('#jquerypotable > tr').on('click', '.delete-co-row', function(e){
It needed to be:
/now add an event listener to the new deletebuttons
$('#jquerypotable').on('click', '.delete-co-row', function(e){
Thanks everyone for trying to help :)

Related

How to populate a dropdown menu using JavaScript on multiple rows

Am trying out an invoice generation system from, https://www.phpzag.com/build-invoice-system-with-php-mysql/. Demo on https://phpzag.com/demo/build-invoice-system-with-php-mysql-demo/create_invoice.php. Everything works just fine but the fields given as examples are just input fields. However, I need to use select options from my mysql database. The fields given in the “htmlRows” are supposed to be added as much as when the user wants using the add buttons in the html form. I have created a separate function for pulling the products from the database and now I don’t know why they are not being populated in the option values on the “htmlRows”.
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click', '#checkAll', function() {
$(".itemRow").prop("checked", this.checked);
});
$(document).on('click', '.itemRow', function() {
if ($('.itemRow:checked').length == $('.itemRow').length) {
$('#checkAll').prop('checked', true);
} else {
$('#checkAll').prop('checked', false);
}
});
var count = $(".itemRow").length;
$(document).on('click', '#addRows', function() {
count++;
//Load products
$.getJSON("load.php?task=products",{ajax: 'true'}, function(j){
var options = '<option value="">--------------------------- select -------------------------</option>';
count++;
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].id + '">' + j[i].display + '</option>';
}
$("select#productCode_'"+count+"'").html(options);
});
var htmlRows = '';
htmlRows += '<tr>';
htmlRows += '<td><input class="itemRow" type="checkbox"></td>';
//This should be a drop down menu
htmlRows += '<td><select name="productCode[]" id="productCode_'+count+'" class="form-control" autocomplete="off" style="width:450px;font-weight:bold;"> <option value="">--------------------------- select -------------------------</option></select></td>';
htmlRows += '<td><input type="number" name="quantity[]" id="quantity_'+count+'" class="form-control quantity" autocomplete="off"></td>';
htmlRows += '<td><input type="number" name="price[]" id="price_'+count+'" class="form-control price" autocomplete="off"></td>';
htmlRows += '<td><input type="number" name="total[]" id="total_'+count+'" class="form-control total" autocomplete="off"></td>';
htmlRows += '</tr>';
$('#invoiceItem').append(htmlRows);
});
</script>
load.php
case 'products':
try
{
require_once("connect.php");
$sql="CALL sp_getProducts()";
$pdo = new PDOConfig();
$resultset = $pdo->query($sql);
foreach($resultset as $row)
{
$data[] = array(
'id' => $row['ProductID'],
'display' => $row['ProductDetails']
);
}
echo json_encode($data);
}
catch(PDOException $e) {
die("Could not connect to the database\n");
}
break;
Replace your javascript code with following:
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click', '#checkAll', function() {
$(".itemRow").prop("checked", this.checked);
});
$(document).on('click', '.itemRow', function() {
if ($('.itemRow:checked').length == $('.itemRow').length) {
$('#checkAll').prop('checked', true);
} else {
$('#checkAll').prop('checked', false);
}
});
var count = $(".itemRow").length;
$(document).on('click', '#addRows', function(options) {
count++;
//Load products
$.getJSON("load.php?task=products",{id: $(this).val(), ajax: 'true'}, function(j){
count++;
var options = '<option value="">--------------------------- select -------------------------</option>';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].id + '">' + j[i].display + '</option>';
}
console.log(options);
var htmlRows = '';
htmlRows += '<tr>';
htmlRows += '<td><input class="itemRow" type="checkbox"></td>';
//This should be a drop down menu
htmlRows += '<td><select name="productCode[]" id="productCode_'+count+'" class="form-control" autocomplete="off" style="width:450px;font-weight:bold;">'+options+'</select></td>';
htmlRows += '<td><input type="number" name="quantity[]" id="quantity_'+count+'" class="form-control quantity" autocomplete="off"></td>';
htmlRows += '<td><input type="number" name="price[]" id="price_'+count+'" class="form-control price" autocomplete="off"></td>';
htmlRows += '<td><input type="number" name="total[]" id="total_'+count+'" class="form-control total" autocomplete="off"></td>';
htmlRows += '</tr>';
$('#invoiceItem').append(htmlRows);
});
});
});
</script>

data coming back but not able to post in jquery ajax

For the life of me I can not see why this is happening.
Basically I am using the following code to bring back table rows from the database.
var getCposInputs = {
'type': 'viewcpos',
'quoteid': '<?php echo $_GET['id']; ?>'
};
$.ajax({
type: 'POST',
url: '/Applications/Controllers/Quotes/ajax-add-sin.php',
data: getCposInputs,
dataType: 'html',
encode: true
}).done(function(data){
//$('body').html(data);
buildcotable += data;
});
So as you can see there is commented out line that when removed shows the details straight into the body instead of the variable which is later sent out using the .html() function within JavaScript.
So the full jQuery code is:
var buildcotable = '';
var buildtrs = $('#formentry15').val();
var coArray = '';
var coArrayNumber = 1;
buildcotable += '<div class="table-responsive">';
buildcotable += '<table class="table table-bordered">';
buildcotable += '<thead>';
buildcotable += '<th class="text-center">Number</th>';
buildcotable += '<th class="text-center">Price</th>';
buildcotable += '<th class="text-center">Installments</th>';
buildcotable += '<th class="text-center">Contact Initials</th>';
buildcotable += '<th class="text-center">Options</th>';
buildcotable += '</thead>';
buildcotable += '<tbody id="jquerypotable">';
//lets do a check and see how many are listed
if(buildtrs != 'TBC'){
var getCposInputs = {
'type': 'viewcpos',
'quoteid': '<?php echo $_GET['id']; ?>'
};
$.ajax({
type: 'POST',
url: '/Applications/Controllers/Quotes/ajax-add-sin.php',
data: getCposInputs,
dataType: 'html',
encode: true
}).done(function(data){
$('body').html(data);
buildcotable += data;
});
} else {
buildcotable += '<tr id="jqueryporow1">';
buildcotable += '<td><input type="hidden" value="No" id="jqueryponumber1" class="form-control">No CPO\'s have been submitted</td>';
buildcotable += '<td><input type="hidden" value="" id="jquerypovalue1" class="form-control"></td>';
buildcotable += '<td class="text-center"><input type="hidden" value="" id="jquerypoinstallments1" class="form-control"></td>';
buildcotable += '<td><input type="hidden" value="" id="jquerypocontactinitials1" class="form-control"></td>';
buildcotable += '<td class="text-center"> </td>';
buildcotable += '</tr>';
}
buildcotable += '</tbody>';
buildcotable += '</table>';
buildcotable += '<p>Add New CPO Number</p>';
buildcotable += '<p>Done</p>';
buildcotable += '</div>';
$('.ubl-section-7').html(buildcotable);
I know that the data is coming back fine, because when I remove the comment for $('body').html(data); then it shows the information.
But if trying to put it into a variable it simply does nothing.
Any ideas on why this is happening?
Thanks
You have to make sure that the output is generated after the ajax request retrieved its data. Else your last line of code is run even before the buildcotable += data; has been executed, because the ajax request isn't ready yet (it's asynchronous). Try something like this:
var buildcotable_beg = '<table><tr> ...';
var buildcotable_cnt = '';
var buildcotable_end = '...</table>';
var full_bld_tbl = '';
if (buildtrs != 'TBC') {
$.ajax(...).done(function(buildcotable_cnt) {
full_bld_tbl = buildcotable_beg + buildcotable_cnt + buildcotable_end;
$('.ubl-section-7').html(full_bld_tbl);
});
} else {
buildcotable_cnt = '<tr>...</tr>';
full_bld_tbl = buildcotable_beg + buildcotable_cnt + buildcotable_end;
$('.ubl-section-7').html(full_bld_tbl);
}

Jquery nested table creation clean approach

I have written below code which creates a table inside another table from json response.
Main Table Code
var user = '<table width="98%" cellspacing="0" cellpadding="1" style="text-align: left; margin: 0 auto;';
user += 'border-collapse: collapse;" >';
$.each(html.ListOfReportModelData, function (key, val) {
user += '<tr>';
user += '<td>';
user += '<table width="100%" id="internalTable" border="0" cellspacing="2px" cellpadding="2px" >';
if (flag == "false") {
user += '<tr class="GreenColor">';
user += '<td style="width: 15%" class="accord">';
user += 'PR Number';
user += '</td>';
user += '<td style="width: 10%" class="accord">';
user += 'Created On';
user += '</td>';
user += '<td style="width: 10%" class="accord">';
user += 'Site Name';
user += '</td>';
user += '<td style="width: 10%" class="accord">';
user += 'Order ID';
user += '</td>';
user += '<td style="width: 55%" class="accord">';
user += 'File Name';
user += '</td>';
user += '</tr>';
}
var count = 0;
$.each(val.Orders, function (key, child) {
//debugger;
user += '<tr class="PinkColor">';
if (count == 0) {
user += '<td valign="top" rowspan="' + val.Orders.length + '" style="width: 15%"><a href="javascript:GetFinanceData(' + "'" + val.SiteName + "','" + val.Req_Number + "'" + ');">';
user += val.Req_Number;
user += '</a></td>';
count = 1;
}
user += '<td valign="top" style="width: 10%">';
user += val.CreatedDateText;
user += '</td>';
user += '<td valign="top" style="width: 10%">';
user += val.SiteName;
user += '</td>';
user += '<td valign="top" style="width: 10%">';
user += child.OrderId;
user += '</td>';
user += '<td style="width: 55%;break-word: word-wrap;">';
if (child.ShowLink) {
user += '<a href="javascript:Export(' + "'" + child.ID + "','" + val.SiteName + "'" + ');">';
}
user += child.Attachments_FileName;
if (child.ShowLink) {
user += '</a>';
}
user += '</td>';
user += '</tr>';
});
user += '<tr class="PinkColor">';
user += '<td colspan="5"><div id="' + val.Req_Number + '" ></div>';
user += '</td>';
user += '</tr>';
user += '</table>';
user += '</td>';
user += '</tr>';
flag = "true";
});
user += '</table>';
Child Table Creation
$.getJSON("/Home/FinancialInformation", data, function (html) {
totalRecords = html.FinanceData.length;
if (totalRecords == 0) {
$('#' + Req_Number + '').empty();
alert('No Finance Data Available!!!!!');
}
else {
var Fin = '<table id=' + Req_Number + ' width="100%" border="0" cellpadding="2px" cellspacing="2px" >';
Fin += '<tr class="GreenColor">';
Fin += '<td class="accord" style="width: 45%">Approval Type</td>';
Fin += '<td class="accord" style="width: 10%">Approval Required</td>';
Fin += '<td class="accord" style="width: 15%">Approved By</td>';
Fin += '<td class="accord" style="width: 10%">Approved By 521</td>';
Fin += '<td class="accord" style="width: 20%">Approved Date</td>';
Fin += '</tr>';
$.each(html.FinanceData, function (key, val) {
Fin += '<tr class="PinkColor">';
Fin += '<td style="width: 45%">' + val.Approval_Type + '</td>';
Fin += '<td style="width: 10%">' + val.Approval_Required + '</td>';
Fin += '<td style="width: 15%">' + val.Approved_By + '</td>';
Fin += '<td style="width: 10%">' + val.Approved_By_521 + '</td>';
Fin += '<td style="width: 20%">' + val.Approved_Date + '</td>';
Fin += '</tr>';
});
Fin += '</table>';
$('#' + Req_Number + '').empty()
$('#' + Req_Number + '').append(Fin);
}
});
I can see my table created correctly but I see lot of cumbersome activity in creating these codes.Is there better approach to achieve the same thing?Mostly using some plugins.
How others have said you should use a template engine like : handlebarsJS, mustacheJS, underscoreJS or maybe something like reactJS
Or if you want to keep it with jQuery, you can structure your code like :
Instead of injecting html directly like that, you can use jQuery syntax to create each element
You can split logic with functions
You can use only CSS classes(no style) and add it with jQuery
Here it's an example :
var getParentTable = function() {
// add style to CLASS in CSS
return $('<table></table>').addClass('parentTableClass');
};
var getInternalTable = function() {
return $('<table></table>')
.addClass('childTableClass')
.attr('id', 'internalTable');
};
var getRow = function(classValue) {
return $('<tr></tr>').addClass(classValue);
};
var getCol = function(textValue, classValue) {
return $('<td></td>')
.addClass(classValue)
.text(textValue);
};
var parentTable = getParentTable();
parentTable.append(internalTable);
$.each(html.ListOfReportModelData, function (key, val) {
var internalTable = getInternalTable();
var simpleRow = getRow();
var simpleCol = getCol();
var row1 = getRow('GreenColor');
var row3 = getRow('PinkColor');
row1
.append(getCol('PR Number', 'td1 accord'))
.append(getCol('Created On', 'td2 accord'))
.append(getCol('Site Name', 'td3 accord'))
.append(getCol('Order ID', 'td4 accord'))
.append(getCol('File Name', 'td5 accord'));
internalTable.append(row1);
$.each(val.Orders, function (key, child) {
var row2 = getRow('PinkColor');
.append(getCol(val.Req_Number, 'td1 accord'))
.append(getCol(val.CreatedDateText, 'td2 accord'))
.append(getCol(val.SiteName, 'td3 accord'))
.append(getCol(child.OrderId, 'td4 accord'))
.append(getCol(child.ShowLink, 'td5 accord'));
internalTable.append(row2);
});
internalTable.append(row3);
simpleCol.append(internalTable);
simpleRow.append(simpleCol);
parentTable.append(simpleRow);
});

jquery fadeIn effect with <tr>

I am adding rows dynamically to a table based on selection yet I would like to add fadeIn effect.
I am posting the part in which I add the rows to table.
Any help will be appreciated.
(I am trying to use the fadeIn effect while adding newRow to table and removing tblGraphPattern content afterwards). I want to have the effect in the lines
$("table.selectPattern").append(newRow);
$("#tblGraphPattern tr").remove();
var newRow = $("<tr>");
newRow.attr("align","center");
newRow.css("outline", "thin solid");
for(var i = 1; i<counter;++i)
{
if($("#divSubject"+i+"").length>0)
{
var cols = "";
subjectText=$("#divSubject"+i+"").html();
if(subjectText=="Any")
{subjectVal = "?s"+selectCounter;}
else{subjectVal=$("#txtGraphSubject"+i+"").val();}
predicateText=$("#divPredicate"+i+"").html();
if(predicateText=="Any")
{predicateVal = "?p"+selectCounter;}
else{predicateVal=$("#txtGraphPredicate"+i+"").val();}
objectText=$("#divObject"+i+"").html();
if(objectText=="Any"){objectVal="?o"+selectCounter;}
else{
objectVal=$("#txtGraphObject"+i+"").val();
}
cols += '<tr><td align="right"><div id="divSelectSubject'+num+'">'+subjectText+'</div><input type="text" value="'+subjectVal+'" name="txtSelectSubject'
+ num + '" id="txtSelectSubject' + num + '"/></td>';
cols += '<td align="center"><div id="divSelectPredicate'+num+'">'+predicateText+'</div><input type="text" value="'+predicateVal+
'" name="txtSelectPredicate' + num + '" id="txtSelectPredicate' + num + '"/></td>';
cols += '<td align="left"><div id="divSelectObject'+num+'">'+objectText+'</div><input type="text" value="'+objectVal+
'" name="txtSelectObject' + num + '" id="txtSelectObject' + num + '"/></td></tr>';
newRow.append(cols);
}
num++;
}
selectCounter++;
newRow.append('<td><input type="button" class="ibtnDel" value="Delete"></td>');
$("table.selectPattern").append(newRow);
$("#tblGraphPattern tr").remove();
Make your newRow hidden by setting display:none; before appending it to table.selectPattern and then fadeIn after appending is done.
var newRow = $('<tr style="display:none;"></tr>');
// your remaining code
$("table.selectPattern").append(newRow);
$("#tblGraphPattern tr").remove();
newRow.fadeIn(2000);

Get values of textareas generated dynamically

In the below code,the textareas are generated dynamically, now how to get these values for validations in valid() function..
<script>
function valid()
{
//get all textarea vales for validation
}
function add(col_det)
{
var row = '<tr>';
row += '<td>';
row += '<textarea rows = "8" cols = "8" class = "input" WRAP id="row_details'+r_count+'" name ="row_details'+r_count+'"></textarea>';
row += '</td>';
for (var i=0;i<col_det.length;i++)
{
row += '<td> <div id = "div_content_bold"> <textarea rows = "2" cols = "8" class = "input" id="c_details'+c_count+'" name="col_details'+l_count+'" WRAP ></textarea> </div> </td>';
}
row += '<td></td>';
row += '</tr>';
return row;
}
$(document).ready(function() {
var cnt = '<input type="text" name="title" id="title" ><br><br>';
cnt += '<table cellspacing="0" cellpadding="0" border="1" width="100%" id="l_table">';
cnt += '<tr>';
cnt += '<th width="30%">Category</th>';
cnt += headers(col_data);
cnt += '<th width="10%">Grade obtained</th>';
cnt += '</tr>';
for(var i=0;i<criteria;i++)
{
cnt += add(col_data,i);
}
cnt += '</table>';
$('#content').append(cnt);
});
</script>
<form action="create/" method="post" name="aa">
<div id="content"></div>
<table>
<tr><td>
<input type="submit" value="Save" id="Save" onclick="javascript:var ret=validate(row_c,c_count);return ret;"/></td></tr>
You can loop over all the textareas on the page and validate the contents by using .each
$('textarea').each(function(i){
// do validation here using $(this).val()
});
If they are assigned dynamically, add classes so you can select them.
$('textarea.generated').each (function(i) { });

Categories

Resources