Script to run for all Table Row IDs - javascript

I have an HTML table with a date input field which currently runs an AJAX script when the date is modified. This is working well, but I now need another version of the script that acts on all table rows on the page to save the user from having to enter the date for each table row (there could be 20 on the page).
I've created another input for marking all the rows but stumped as to how to implement this. Ideally I'd like to pass an array of the table row IDs (e.g. id="61851") to a new script which calls a PHP script that handles the backend updating.
Here's my table:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/css/bootstrap-datepicker.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/locales/bootstrap-datepicker.uk.min.js"></script>
<div class="col-md-8">
<h1>Items List</h1>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<div class="col-md-6">
<table class="table table-bordered">
<tr>
<td>Flag All Received:</td>
<td><input type="text" class="form-control datepicker" name="dateReceivedAll" id="dateReceivedAll" data-date-format="dd/mm/yyyy" placeholder="Date Received"></td>
<td class="text-center">
<button type="submit" class="btn btn-success">Date Received All</button>
</td>
</tr>
</table>
</div>
<!-- /.col-md-6-->
<div class="col-md-6">
</div>
<!-- /.col-md-6-->
</div>
<!-- /.col-md-8-->
<div class="col-md-4">
</div>
<!-- /.col-md-4-->
</div>
<!-- /.row-->
<div>
<br />
<table class="table table-condensed table-striped table-bordered">
<thead>
<th class="text-center" scope="col">Item Tag</th>
<th class="text-center" scope="col">Serial Number</th>
<th class="text-center" scope="col">Received Date</th>
</thead>
<tbody>
<tr id="61851">
<td>61851</td>
<td>DTZ452432DDF</td>
<td id="61851"><input type="text" id="61851" class="form-control datepicker" autocomplete="off" placeholder="Date Rec'd" data-date-format="dd/mm/yyyy" name="dateReceived" value=""></td>
</tr>
<tr id="61852">
<td>61852</td>
<td>GZF2452542DA</td>
<td id="61852"><input type="text" id="61852" class="form-control datepicker" autocomplete="off" placeholder="Date Rec'd" data-date-format="dd/mm/yyyy" name="dateReceived" value=""></td>
</tr>
<tr id="61853">
<td>61853</td>
<td>TRA3241234ZZ</td>
<td id="61853"><input type="text" id="61853" class="form-control datepicker" autocomplete="off" placeholder="Date Rec'd" data-date-format="dd/mm/yyyy" name="dateReceived" value=""></td>
</tr>
</tbody>
</table>
</div>
and here's the current script that runs when you modify an individual date in the last column:
$(document).ready(function() {
$(".form-control.datepicker").change(function() {
var recid = $(this).closest('td').attr('id');
var dateReceived = $(this).val();
// Create a reference to $(this) here:
$this = $(this);
$.post('updateItem.php', {
recid: recid,
dateReceived: dateReceived
}, function(data) {
data = JSON.parse(data);
if (data.error) {
var ajaxError = (data.text);
var errorAlert = 'There was an error updating the Date Received - ' + ajaxError + '. Please contact the Help Desk';
$this.closest('td').addClass("has-error");
$("#dateReceivedErrorMessage").html(errorAlert);
$("#dateReceivedError").show();
return; // stop executing this function any further
} else {
$this.closest('td').addClass("has-success")
$this.closest('td').removeClass("has-error");
}
}).fail(function(xhr) {
var httpStatus = (xhr.status);
var ajaxError = 'There was an error updating the Date Received - AJAX request error. HTTP Status: ' + httpStatus + '. Please contact the Help Desk';
$this.closest('td').addClass("has-error");
$("#dateReceivedErrorMessage").html(ajaxError);
$("#dateReceivedError").show();
});
});
});
I've added the Date Received All button and separate input field to capture the date all items were received, just not sure how to have that button trigger a similar version of the current JS but this time pass an array of all the id's?

change your change event , initialize event as per below method.
$(document).on("change",".form-control.datepicker",function(){
var recid = $(this).closest('td').attr('id');
var dateReceived = $(this).val();
// Create a reference to $(this) here:
$this = $(this);
$.post('updateItem.php', {
recid: recid,
dateReceived: dateReceived
}, function(data) {
data = JSON.parse(data);
if (data.error) {
var ajaxError = (data.text);
var errorAlert = 'There was an error updating the Date Received - ' + ajaxError + '. Please contact the Help Desk';
$this.closest('td').addClass("has-error");
$("#dateReceivedErrorMessage").html(errorAlert);
$("#dateReceivedError").show();
return; // stop executing this function any further
} else {
$this.closest('td').addClass("has-success")
$this.closest('td').removeClass("has-error");
}
}).fail(function(xhr) {
var httpStatus = (xhr.status);
var ajaxError = 'There was an error updating the Date Received - AJAX request error. HTTP Status: ' + httpStatus + '. Please contact the Help Desk';
$this.closest('td').addClass("has-error");
$("#dateReceivedErrorMessage").html(ajaxError);
$("#dateReceivedError").show();
});
});

$('#sucess-btn').click(function(){
var ans = $('.table-condensed>tbody>tr').map(function(c,i,a){
return $(i).attr('id');
});
//ans is an array with numbers
});
Add this to your click event and ans array will have the IDs of the rows of the table. Add IDs to both table and the button and it will be easier to select the elements from the DOM.

Related

Building a table that pulls data from MongoDB that filters in real time, and sorts alphabetically

As the title suggests, that is what im attempting to do, but are at a lost. My best attempt is the following:
This is the nodejs code that renders the HTML page and gets the user input from HTML
app.get('/search/species', (req,res) => {
diseaseModel.find({matched: current_matched}, function (err,disease){
res.render('species', {
diseaseList: disease,
});
});
})
app.post('/search/species', async(req,res) => {
var desc = req.body.desc;
await diseaseModel.updateMany({matched: current_matched, "$text":{"$search" : `\"${desc}\"`}}, {$inc: {matched: 1}});
current_matched ++;
res.redirect(302, '/search/species');
}
}
});
})
This is the HTML page that I uses to collect user input and return the filtered options:
<form action = "/search/species" method = "POST" id="submitMessage" class="field has-addons">
<input class="form-control input is-primary" name = "desc" id = "desc" type="text" style="width: 100%;" placeholder="Enter a Description" required/>
<button type="submit" class="button is-primary" id="send">Send</button>
</form>
</div>
</div>
</section>
<table class = "content-table" align="center" style="margin: 0px auto;">
<thead>
<tr>
<th>Name</th>
<th>Species</th>
<th>Vector</th>
<th>Agent</th>
</tr>
</thead>
<tbody>
<%diseaseList.forEach(disease =>{%>
<tr data-href= 'http://localhost:8080/info?id=<%=disease.id%>'>
<th><%=disease.diseaseName%></th>
<th><%=disease.species%></th>
<th><%=disease.vector%></th>
<th><%=disease.agent%></th>
</tr>
<% })%>
</tbody>
</table>
</div>
</section>
<script>
$(document).ready(function() {
$(document.body).on("click", "tr[data-href]", function() {
window.location.href = this.dataset.href;
})
});
But this doesn't refresh in real time, as in when i type a character, it doesn't start filtering. Would I be able to do this via AJAX? Also how would I list MongoDB data out in the table in alphabetical order?

Adding more values from another field with JavaScript

Need help to solve a JavaScript problem.
i am working on an invoice in which i want to add more values to quantity field.
i am trying with script given in JSFiddle.
The problem is when i click on edit , it should popup a dialog box and by entering data in add field it should be added to current quantity of a specific item.
https://jsfiddle.net/programmer/LLmrp94y/16/
JS script
$(document).on('change', '.addQty', function () {
id_arr = $(this).attr('id');
id = id_arr.split("_");
add = $('#add_'+id[1]).val();
qty = $('#quantity_'+id[1]).val();
if (add != '' && typeof (add) != "undefined") {
$('#add_'+id[1]).val();
added = parseFloat(qty) + parseFloat(add);
$('#qtY_'+id[1]).val(added);
priceAfter = $('#price_'+id[1]).val();
$('#Total_'+id[1]).val((parseFloat(priceAfter) * parseFloat(added)).toFixed(2));
} else {
$('#quantity_'+id[1]).val(qty);
$('#Total_'+id[1]).val((parseFloat(price) * parseFloat(qty)).toFixed(2));
}
});
I made it work by doing the following :
adding an id to your edit buttons, so we can retrieve the id of the line currently being edited
replacing your 'onchange' function by a addQuantity function that takes a parameter : the id of the line being edited.
fixing a couple issues with the ids used in the code written to calculate the new quantity and the new price
Also, I replaced your php code by hard coded ids. You're going to have to replace them.
EDIT : Since you don't want to show the current quantity in the dialog, I had to change the logic and update the table after close has been clicked. Otherwise it caused too many issues. Hope you like it.
$(document).ready(function() {
calculateEachItemSubCost();
});
function calculateEachItemSubCost() {
var qtys = document.getElementsByClassName('quantity');
var price = document.getElementsByClassName('price');
var item_costs = document.getElementsByClassName('totalLinePrice');
for (var i = 0; i < item_costs.length; ++i) {
item_costs[i].value = parseFloat(qtys[i].value) * parseFloat(price[i].value).toFixed(2);
}
}
/* new function that replaces your 'onchange' listener. It handles the adding of a quantity on a given line, identified by the id parameter */
function addQuantity(id) {
var add, added, priceAfter;
add = $('#addedQuantity').val();
console.log("Adding " + add + " on line " + id);
if (add != '' && typeof add != "undefined") {
;
added = parseInt($('.add').val()) + parseInt($('#quantity_' + id).val())
$('#quantity_' + id).val(added);
priceAfter = $('#price_' + id).val();
$('#total_' + id).val((parseFloat(priceAfter) * parseFloat(added)).toFixed(2));
} else {
$('#quantity_' + id).val(qty);
$('#Total_' + id).val((parseFloat(price) * parseFloat(qty)).toFixed(2));
}
}
$(document).on('click', '.editnow', function(event) {
var lineId, quantityField;
// retrieving the id of the line that was clicked on
lineId = event.target.id.split("_")[1];
quantityField = $("#quantity_" + lineId);
$(".add").val("");
$("#edit").dialog({
show: "fold",
hide: "fold",
modal: true,
title: "Edit",
zIndex: 10000,
close: function(event, ui) {
addQuantity(lineId);
$(this).hide();
}
});
});
#edit{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/ui-lightness/jquery-ui.css"/>
<!DOCTYPE html>
<!-- Begin page content -->
<h1 class="text-center title">Invoice</h1>
<table>
<thead>
<tr>
<th width="38%">Item Name</th>
<th width="15%">Price</th>
<th width="15%">Quantity</th>
<th width="15%">Total</th>
<th width="15%">Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" value="samsung galaxy s6" id="itemName_1" ></td>
<td><input type="number" value="500" id="price_1" class="price"></td>
<td><input type="number" value="1" id="quantity_1" class="quantity"></td>
<td><input type="number" value="" id="total_1" class="totalLinePrice"></td>
<td><button type="button" class="editnow" id="edit_1"> Edit </button></td>
</tr>
<tr>
<td><input type="text" value="samsung galaxy s7" id="itemName_2" ></td>
<td><input type="number" value="700" id="price_2" class="price"></td>
<td><input type="number" value="1" id="quantity_2" class="quantity"></td>
<td><input type="number" value="" id="total_2" class="totalLinePrice"></td>
<td><button type="button" class="editnow" id="edit_2"> Edit </button></td>
</tr>
</tbody>
</table>
<div id="edit">
<table>
<tr>
<th>Add</th>
</tr>
<tr>
<td><input type="number" class="add" id="addedQuantity"></td>
</tr>
</table>
</div>
Your updated JSFiddle
I have edited it, but it does not work because of the php values not working, of course. I've added id to Edit buttons, and getting value from dialog. Based on the button id, you can enter value to corresponding quantity field
<button type="button" id="edit_<?php $i; ?>" class="editnow"> Edit </button>
Yes: function () {
var id = $(this).attr('id');
id = id.substring(id.indexOf('_')+1);
alert($('#quantityVal').val()); // just check the value
$('#quantity_'+id).val($('#quantityVal').val());
$(this).dialog("close");
},
Edit dialog number field
<td><input type="number" class="add" id="quantityVal"></td>
https://jsfiddle.net/LLmrp94y/12/

On "submit" add new row to table & save to database. Firebase even listener .on("child_added") returning multiple extra undefined rows to table

I need to create a Train Schedule, in which the user adds a new Train via HTML form and submit button. Each train is then added to a table which contains all the trains. Information should be saved using Firebase database so all trains are saved no matter who opens a new window/page. So far I am getting the results I want, but I am getting a few extra 'undefined' results added to the table. I tried to debug, but I can't seem to find why these extra ones are being added.
Here is the HTML Code for the table:
<form>
<div class="form-group">
<label for="trainName">Train Name</label>
<input type="text" class="form-control" id="trainName" placeholder="Enter the name of your train">
</div>
<div class="form-group">
<label for="destination">Destination</label>
<input type="text" class="form-control" id="destination" placeholder="Enter your train's destination">
</div>
<div class="form-group">
<label for="firstTrainTime">First Train Time (HH:MM Military Time)</label>
<input type="text" class="form-control" id="firstTrainTime" placeholder="HH:MM">
</div>
<div class="form-group">
<label for="frequency">Frequency (min)</label>
<input type="text" class="form-control" id="frequency" placeholder="MM">
</div>
<button type="submit" class="btn btn-danger" id="submitBttn">SUBMIT</button>
</form>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Train Name</th>
<th>Destination</th>
<th>Frequency (min)</th>
<th>Next Arrival</th>
<th>Minutes Away</th>
</tr>
</thead>
<tbody>
<tr>
<td>Trenton Express</td>
<td>Trenton</td>
<td>25</td>
<td>05:35 PM</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
Here is the Javascript code:
$(document).ready(function(){
firebase.initializeApp(config);
var userInptTrainName = "";
var userInptDestination = "";
var userInptFirstTT = "";
var userInptFreq = 0;
$("#submitBttn").on("click", function(event) {
event.preventDefault();
userInptTrainName = $("#trainName").val().trim();
userInptDestination = $("#destination").val().trim();
userInptFirstTT = $("#firstTrainTime").val().trim();
userInptFreq = $("#frequency").val().trim();
firebase.database().ref().push({
dataTrainName: userInptTrainName,
dataDestination: userInptDestination,
dataFirstTrainTime: userInptFirstTT,
dataFrequency: userInptFreq,
timeAdded: firebase.database.ServerValue.TIMESTAMP
});
firebase.database().ref().limitToLast(1).on("child_added", function(snapshot) {
var newRowItem = $("<tr><td>" + snapshot.val().dataTrainName + "</td><td>" + snapshot.val().dataDestination + "</td><td>" + snapshot.val().dataFirstTrainTime + "</td><td>" + snapshot.val().dataFrequency + "</td></tr>");
$("table tbody").append(newRowItem);
});
});
});
I do have the
var config = {};
in my code, I just deleted it, because it has my firebase info on there.

Update a HTML table record via jQuery

I have created a form with only three inputs, a HTML table and a submit button
<div class="form-group">
<input type="text" id="inputText1" required>
<input type="text" id="inputText2" required>
<input type="text" id="inputText3" required>
</div>
<button type="button" class="btn btn-default" id="submit">Submit</button>
</form>
<div class="table-responsive">
<table class="table table-striped table-bordered table-condensed" id="myTable" style="width:90%; margin:0 auto;">
<thead>
<tr>
<th>ID</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
that works this way:
every time the user clicks the submit button the HTML table adds to its rows the value of the inputs via jQuery + two linkbuttons and the variable cont specified as a number in a hidden element in order to easily locate the row when it comes to update it.
$(document).ready(function () {
var cont=0;
$("#submit").click(function(e) {
e.preventDefault();
cont++;
var id = $("#inputText1").val().toLowerCase();
var lastname = $("#inputText2").val();
var name = $("#inputText3").val();
if (checkId(lastname)) {
return alert('El ID ya ha sido especificado');
}
$('#myTable tbody').append('<tr><td for="id">' + id + '</td><td for="lastname">' + lastname + '</td><td>' + name + '</td><td id="cont" style="visibility:hidden">' + cont + '</td><td>Modificar Eliminar</td></tr>');
$("#inputText1").val('');
$("#inputText2").val('');
$("#inputText3").val('');
$('#inputText1').focus();
});
});
the submit button works OK the problem is when I want to modify a row, what I do now is to populate the inputs with the values of the row selected in order to let the user to modify its content but I cannot retrieve the value of the variable cont that represents an specific and different number for each row and besides of that I don't know how to update the table's row once the user decide to update the record, could you please help me, this is the jQuery code I had for the moment
$(document).ready(function () {
$("#myTable").on('click', '#select', function (e) {
e.preventDefault();
var currentRow = $(this).closest("tr");
//var contador= currentRow.$("#cont").val();
//alert(contador);
//doesn't retrieve neither show anything
var col1 = currentRow.find("td:eq(0)").text();
var col2 = currentRow.find("td:eq(1)").text();
var col3 = currentRow.find("td:eq(2)").text();
$("#inputText1").val(col1);
$("#inputText2").val(col2);
$("#inputText3").val(col3);
});
});
and also would like to dd that when the user add the info from the inputs to the table, theres a gap where the hidden field is
how could I solve this?

trying to set focus of dynamically added input

I'm having a bear of a time getting this input to focus. It is dynamically loaded. On the blur of the input, it is supposed to do some checking and then go back to that input if incorrect id entered. $(itemID) is what I am trying to focus.
Here is my javascript function that is called on page load.
function addBlurEvent() {
$("#brochureItems").on("blur", ".item-ID", (function (e) {
var itemID = $(this);
var itemIDVal = $.trim($(this).val());
if (itemIDVal != "") {
var item = "";
$.each(window.listOfItems, function(i, v) {
if (v.No.search(itemIDVal) != -1) {
item = v.Description;
return;
}
});
if(item != "") {
$(itemID).parent().parent().siblings(".item-desc").find("input").first().val(item);
$(itemID).parent().siblings(":last").find("input").first().focus();
} else {
slideDownMsg("Item: " + itemIDVal + " not found.");
slideUpMsg(3000);
$(itemID).focus();
}
} else {
$(itemID).parent().siblings(".item-desc").find("input").first().val("");
$(itemID).parent().siblings(":last").find("input").val("")
}
}));
$(".removeRow").on('click', function() {
$(this).closest("tr").remove();
});
}
And here is the dynamically added table:
<table class="table table-bordered table-striped" id="brochureItems">
<thead>
<tr>
<th>
Item Code
</th>
<th>
Brochure Code
</th>
<th width="35%">
Item Description
</th>
<th>
Retail
</th>
<th>
Remove
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="row">
<div class="col-md-8">
<input id="brochureItems_0__itemNo" class="form-control text-box single-line valid item-ID" data-val="true" data-val-required="The Item Code field is required." name="brochureItems[0].itemNo" aria-invalid="false" type="text">
</div>
</td>
<td class="row">
<div class="col-md-8">
<input id="brochureItems_0__brocCode" class="form-control text-box single-line" data-val="true" data-val-required="The Brochure Code field is required." name="brochureItems[0].brocCode" type="text">
</div>
</td>
<td class="row item-desc">
<div class="col-md-12">
<input id="brochureItems_0__itemDesc" class="form-control text-box single-line" data-val="true" data-val-required="The Item Description field is required." name="brochureItems[0].itemDesc" readonly="readonly" tabindex="-1" onfocus="this.blur()" type="text">
</div>
</td>
<td class="row">
<div class="col-md-8">
<input id="brochureItems_0__retail" class="form-control text-box single-line" data-val="true" data-val-number="The field Retail must be a number." data-val-required="The Retail field is required." name="brochureItems[0].retail" type="text">
</div>
</td>
<td class="remove"><span class="glyphicon glyphicon-remove removeRow"></span></td>
</tr>
</tbody>
I can only see that in the inspector. Source code shows an empty div where the table is supposed to go.
I don't think it matters, but that addBlurEvent function is getting called in the success of an ajax call. Here is the first function that gets called:
function loadItems() {
$.ajax({
url: '#Url.Action("_BrochureItems", "Brochure")',
type: 'POST',
data: { model: #Html.Raw(Json.Encode(#Model.brochureItems)) },
success: function (results) {
$("#itemList").html(results);
addBlurEvent();
},
error: function (request, status, error) {
displayError("Error", request.responseText);
}
});
}
Finally figured it out. I figured there must be a way because my other events in that function were working, just not that focus event. Ended up finding this SO Q&A which solved my issue: jquery focus back to the same input field on error not working on all browsers
Essentially, I had to set a timeout on the focus. So here is the code to do that:
setTimeout(function() { itemID.focus(); }, 50);
Remove the () around your function.
Issues with the siblings I made assumptions
Some code is useless and I commented it out.
Some code is "not present" in your example so I commented out references to that.
I made some assumptions that you wanted to focus the "cell" in the same TD row referenced by the "td" with a .row class.
function addBlurEvent() {
$("#brochureItems").on("blur", ".item-ID", function(e) {
var itemID = $(this);
var itemIDVal = $.trim(itemID.val());
if (itemIDVal != "") {
var item = "";
/* $.each(window.listOfItems, function(i, v) {
if (v.No.search(itemIDVal) != -1) {
item = v.Description;
return;
}
});
*/
if (item != "") {
// only one input in a cell (td)
// itemID.parent('.row').siblings(".item-desc").find("input").first().val(item);
itemID.parent('.row').siblings(".item-desc").find("input").val(item);
// no siblings of the inputs parent div exist in the TD cell
itemID.parent('.row').siblings(":last").find("input").first().focus();
} else {
//slideDownMsg("Item: " + itemIDVal + " not found.");
//slideUpMsg(3000);
itemID.focus();
}
} else {
itemID.parent('.row').siblings(".item-desc").find("input").val("");
itemID.parent('.row').siblings().last().find("input").val("")
}
});
$(".removeRow").on('click', function() {
$(this).closest("tr").remove();
});
}
Reference fiddle: https://jsfiddle.net/xL8wh3qo/
See this updated fiddle where I show examples of how to save a table row, clone it and then allow you to add new rows to your table from that. Even if all the rows are removed, you can add a new one from the saved clone, with proper id's based on your original row: https://jsfiddle.net/DTcHh/27778/

Categories

Resources