Assign ID to current table row dynamically, tr using jQuery - javascript

I need to assign id to specific row in table out of 5 using jQuery function.
I have managed to managed to apply CSS for test purpose but it applying all rows not only the current one
$("#AdditionalTenent").find("tr").css("background-color", "red");
Table structure
<table class="table-bordered">
<thead>
<tr id="AdditionalTenentHeader">
<th>Student UWL ID</th>
<th>Title</th>
<th>First Name</th>
<th>Middle Name</th>
<th>Last Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr class="AdditionalTenentRecord">
<td><input type="text" value="" name="listedStudentUWLID" id="listedStudentUWLID" class="form-control additionalTententUWLID"></td>
<td><input type="text" value="" name="listedStudentTitle" id="listedStudentTitle" class="form-control listedStudentTitle"></td>
<td><input type="text" value="" name="listedStudentFirstName" id="listedStudentFirstName" class="form-control listedStudentFirstName"></td>
<td><input type="text" value="" name="listedStudentMiddleName" id="listedStudentMiddleName" class="form-control listedStudentMiddleName"></td>
<td><input type="text" value="" name="listedStudentLastName" id="listedStudentLastName" class="form-control listedStudentLastName"></td>
<td><a class="DeleteEntryInline_Icon DeleteAdditionalTenentEntry" href="#"></a></td>
</tr>
<tr class="AdditionalTenentRecord">
<td><input type="text" value="" name="listedStudentUWLID" id="listedStudentUWLID" class="form-control additionalTententUWLID"></td>
<td><input type="text" value="" name="listedStudentTitle" id="listedStudentTitle" class="form-control listedStudentTitle"></td>
<td><input type="text" value="" name="listedStudentFirstName" id="listedStudentFirstName" class="form-control listedStudentFirstName"></td>
<td><input type="text" value="" name="listedStudentMiddleName" id="listedStudentMiddleName" class="form-control listedStudentMiddleName"></td>
<td><input type="text" value="" name="listedStudentLastName" id="listedStudentLastName" class="form-control listedStudentLastName"></td>
<td><a class="DeleteEntryInline_Icon DeleteAdditionalTenentEntry" href="#"></a></td>
</tr>
<tr class="AdditionalTenentRecord">
<td><input type="text" value="" name="listedStudentUWLID" id="listedStudentUWLID" class="form-control additionalTententUWLID"></td>
<td><input type="text" value="" name="listedStudentTitle" id="listedStudentTitle" class="form-control listedStudentTitle"></td>
<td><input type="text" value="" name="listedStudentFirstName" id="listedStudentFirstName" class="form-control listedStudentFirstName"></td>
<td><input type="text" value="" name="listedStudentMiddleName" id="listedStudentMiddleName" class="form-control listedStudentMiddleName"></td>
<td><input type="text" value="" name="listedStudentLastName" id="listedStudentLastName" class="form-control listedStudentLastName"></td>
<td><a class="DeleteEntryInline_Icon DeleteAdditionalTenentEntry" href="#"></a></td>
</tr>
</tbody>
</table>
I have tried following jQuery script but its still applying css to all records in table not the $(this) one!
$("#AdditionalTenent").find(".AdditionalTenentRecord").closest("tr").css("background-color", "yellow");
javaScript Code
$(".additionalTententUWLID").on("change", function () {
var StudentUWLID = $(this).val();
$.ajax({
url: '#Url.Action("GetStudentRecordByID", "StudentProfile")',
type: "POST",
dataType: "JSON",
data: { _GivenStudentUWLID: StudentUWLID },
cache: false
}).done(function (data, textStatus, jqXHR) {
if (data.RecordStatus == "NotAvailable")
{
$(this).MyMessageDialog({
_messageBlockID: "_StatusMessage",
_messageContent: "<div class='warningMessage'> <h4>Given Student Cannot Be Enter As Additional Tenant.</h4> <br/> Student Need to Have their Profile Completed On Student Village Portal Before Can Be Added As Additional Tenant Within The Tendency Form! <br/><br/> Or Enter Correct Student UWL ID "+"</div>",
_messageBlockWidth: "400px"
});
}
else if(data.RecordStatus=="recordFound")
{
alert(data.Response);
var paraedData = JSON.parse(data.Response);
// alert(paraedData.Title + " " + paraedData.FirstName);
// $("#AdditionalTenent").find("tr").css("background-color", "red");
$("#AdditionalTenent").find(".AdditionalTenentRecord").closest("tr").css("background-color", "yellow");
???????????????????
//I need to apply css or ID to row only in use so that in following line I can set values to text field only in single row NOT all of them
$("#AdditionalTenent").find(".listedStudentTitle").val(paraedData.Title);
$("#AdditionalTenent").find(".listedStudentFirstName").val(paraedData.FirstName);
$("#AdditionalTenent").find(".listedStudentMiddleName").val(paraedData.MiddleName);
$("#AdditionalTenent").find(".listedStudentLastName").val(paraedData.LastName);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
alert("error");
});
});

I assume you are using a jQuery click event, if that is the case, you can use:
$(this).closest('tr').remove();

$(".additionalTententUWLID").on("change", function () {
var StudentUWLID = $(this).val();
$(this).attr('id', StudentUWLID);
$.ajax({............my rest of code
and in success response
$("#" + StudentUWLID).closest('tr').css('background-color', 'red');
$("#" + StudentUWLID).closest('tr').find(".listedStudentTitle").val(paraedData.Title);
$("#" + StudentUWLID).closest('tr').find(".listedStudentFirstName").val(paraedData.FirstName);
$("#" + StudentUWLID).closest('tr').find(".listedStudentMiddleName").val(paraedData.MiddleName);
$("#" + StudentUWLID).closest('tr').find(".listedStudentLastName").val(paraedData.LastName);

Related

Parse and access data in JSON by taking vallues from input fields of table : JavaScript

<html>
<body>
<table id="table">
<tr>
<td><input name="name" type="text"><input name="id" type="hidden"></td>
<td><input name="age" type="text"></td>
<td><input name="qty"type="text"></td>
<td><input name="perc" type="text"></td>
<td><input name="address" type="text"></td>
</tr>
</table>
<button onclick="show()">show</button>
</body>
</html>
<!-- language: lang-js -->
<script>
function show(){
var data = '[';
$("#table tr").each(function() {
data += '{"name":"' + $(this).find('td').eq(0).find('input[type="text"]').val() +
'","id":"' + $(this).find('td').eq(0).find('input[type="hidden"]').val() +
'","age":"' + $(this).find('td').eq(1).find('input[type="text"]').val() +
'","qty":"' + $(this).find('td').eq(2).find('input[type="text"]').val() +
'","perc":"' + $(this).find('td').eq(3).find('input[type="text"]').val() +
'","address":"' + $(this).find('td').eq(4).find('input[type="text"]').val() + '"},'
});
data += ']';
var p = data;
var arr = JSON.parse(JSON.stringify(p));
alert(arr[0].name);
}
</script>
<!-- end snippet -->
How to parse and access data?
I want the output to be first value of first input field.
The above code gives value as undefined.
The key in json is independent of input field name.
IMO, you should not construct string and then convert to json. you can create Javascript object directly.
var data = [];
$("#table tr").each(function() {
data.push({
name: $(this).find('td').eq(0).find('input[type="text"]').val(),
id: $(this).find('td').eq(0).find('input[type="hidden"]').val(),
age: $(this).find('td').eq(1).find('input[type="text"]').val(),
qty: $(this).find('td').eq(2).find('input[type="text"]').val(),
perc: $(this).find('td').eq(3).find('input[type="text"]').val(),
address: $(this).find('td').eq(4).find('input[type="text"]').val()
})
});
I think you are going to run into all kinds of issues if you try and generate the JSON yourself, I would instead do something like this:
var data = [];
$("#table tr").each(function() {
data.push({
name: $(this).find('td').eq(0).find('input[type="text"]').val(),
id: $(this).find('td').eq(0).find('input[type="hidden"]').val(),
age: $(this).find('td').eq(1).find('input[type="text"]').val(),
qty: $(this).find('td').eq(2).find('input[type="text"]').val(),
perc: $(this).find('td').eq(3).find('input[type="text"]').val(),
address: $(this).find('td').eq(4).find('input[type="text"]').val()
});
});
console.log(data[0].name);
The most elegant is to use a map - especially if you have more than one row
Perhaps the downvoters will retract their vendetta votes now I show it works as expected
$(function() {
$("#show").on("click", function() {
let data = $("#table tr").map(function() {
return $(":input", this).map(function() {
return {
[$(this).attr("name")]: $(this).val()
};
}).get();
}).get();
console.log(data);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table">
<tr>
<td><input name="name" type="text" value="Joe"><input name="id" type="hidden" value="ID1"></td>
<td><input name="age" type="text"></td>
<td><input name="qty" type="text"></td>
<td><input name="perc" type="text"></td>
<td><input name="address" type="text"></td>
</tr>
<tr>
<td><input name="name" type="text" value="Jane"><input name="id" type="hidden" value="ID2"></td>
<td><input name="age" type="text"></td>
<td><input name="qty" type="text"></td>
<td><input name="perc" type="text"></td>
<td><input name="address" type="text"></td>
</tr>
</table>
<button type="button" id="show">Go</button>

parseInt() functionis not working

I have a input element to accept number type. I know javascript takes input as a string. so I am using parseInt() to convert into integer. but it is not working.
My code is:
<tr>
<td rowspan="6"><br><br><br><br><br>B1<br> Salary/Pension:</td>
<td>(1) Salary (excluding all allowances, perquisites and profit in lieu of salary</td>
<td><input type="text" id="sal" value="0" name="sal" placeholder="" class="form-control "></td>
</tr>
<tr>
<td>(2) Allowances not exempt</td>
<td><input type="text" id="allowance" value="0" name="allowance" placeholder="" class="form-control "></td>
</tr>
<tr>
<td>(3)Value of perquisites</td>
<td><input type="text" id="perquisites" value="0" name="perquisites" placeholder="" class="form-control "></td>
</tr>
<tr>
<td>(4) Profits in lieu of salary</td>
<td><input type="text" id="profit" name="profit" value="0" placeholder="" class="form-control"></td>
</tr>
<tr>
<td>(5)Deduction u/s 16</td>
<td><input type="text" id="ded16" name="ded16" value="0" placeholder="" class="form-control"></td>
</tr>
<tr>
<td>(6)Income chargable under the head 'Salaries':</td>
<td><input type="text" id="inchargesal" value="0" name="inchargesal" placeholder="" class="form-control" readonly></td>
</tr>
//js part is:
$(document).ready(function() {
function change() {
f = a + b + c + d - e;
alert(f);
$('#inchargesal').removeAttr('readonly').val(f);
}
$('#sal').on('change', function() {
var a = parseInt(document.getElementsById("sal").value);
alert("hi");
change();
});
$('#allowance').on('change', function() {
b = parseInt(document.getElementById("allowance").value)
change();
});
$('#perquisites').on('change', function() {
c = parseInt(document.getElementsById("perquisites").value);
change();
});
$('#profit').on('change', function() {
d = parseInt(document.getElementsById("profit").value);
change();
});
$('#ded16').on('change', function() {
e = parseInt(document.getElementsById("ded16").value);
change();
});
});
here to notice is, when I use alert("hi") above the parseInt statement then alert works fine, however when I use it after that, alert("hi") doesn't work.
what's going wrong? please help.
You are using incorrect method of document. There is no such method saying getElementsById(). In HTML DOM the id field is unique so it can never be getElements but getElement. Use getElementById('id') to make it work.
Also its always better to check console first where most of your problems can be resolved on your own.
Console -

Comparing readonly value with a value entered by a user

I have table which have available quantity value of a readonly and a quantity entered by a user. I check if the available quantity is more than what the user entered. If value entered by user is more than available quantity I tell the user to enter value less than available quantity. The first entered quantity value gets validated correctly. I get problem when the user enter second quantity. How can I tackle this? I use availableQuantity and quantity as my id's
Here is my code HTML
<div id="makeOrders">
<table id="myDatatable" class="display datatable">
<thead>
<tr>
<th>Part No</th>
<th>Description</th>
<th>Model No</th>
<th>Available QTY</th>
<th>Tick To Order</th>
<th>Quantity</th>
<!-- <th>Edit</th> -->
</tr>
</thead>
<tbody>
<!-- Iterating over the list sent from Controller -->
<c:forEach var="list" items="${compatibility}">
<tr>
<td>${list.partNumber}</td>
<td>${list.itemDescription}</td>
<td>${list.compitableDevice}</td>
<td><input type="number" id="avaliableQuantity"
name="avaliableQuantity" class="form-control" readonly="readonly"
value="${list.quantity}"></td>
<td><input type="checkbox" class="form-group"
id="checkedOrder" name="selectedItem"
value="${list.partNumber},${list.compitableDevice},${list.itemDescription}"></td>
<td><input type="number" id="quantity" name="quantity"
class="form-control" onblur="compareQuantity()" value="" /></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
This my JavaScript code
<script type="text/javascript">
/*Compare available quantity with entered quantity*/
function compareQuantity() {
var ourAvaliableQuantity = document.getElementById("avaliableQuantity").value;
var yourQuantity = document.getElementById("quantity").value;
if ( ourAvaliableQuantity > yourQuantity ) {
alert("Your quantity (" +yourQuantity+ ") is less or equal to available quantity (" + ourAvaliableQuantity+ ") order.\n You can now place your order");
console.log("True,",yourQuantity + " is less than " + ourAvaliableQuantity);
console.log("Place an Order");
}else if(ourAvaliableQuantity < yourQuantity) {
alert("Your order quantity (" +yourQuantity+ ") can not be greater than available quantity (" + ourAvaliableQuantity+ "). \n Please enter less quantity");
document.getElementById("quantity").value = "";
console.log("False,",ourAvaliableQuantity + " is small than " + yourQuantity);
console.log("You can not place an order, enter less quantity");
console.log("Enter value between 1 till " +ourAvaliableQuantity+ " not more than " +ourAvaliableQuantity);
}
}
</script>
The id attribute specifies a unique id for an HTML element, it must must be unique within the HTML document. try use the id concatenating an unique value from the 'list' variable. Or pass the '${list.quantity}' to the function.
<c:forEach var="list" items="${compatibility}">
<tr>
<td>${list.partNumber}</td>
<td>${list.itemDescription}</td>
<td>${list.compitableDevice}</td>
<td><input type="text" id="${list.partNumber}_avaliableQuantity"
name="avaliableQuantity" class="form-control" readonly="readonly"
value="${list.quantity}"></td>
<td><input type="checkbox" class="form-group"
id="checkedOrder" name="selectedItem"
value="${list.partNumber},${list.compitableDevice},${list.itemDescription}"></td>
<td><input type="text" id="${list.partNumber}_quantity" name="quantity"
class="form-control" onblur="compareQuantity(this, ${list.quantity})" value="" /></td>
</tr>
</c:forEach>
And in your javascript
function compareQuantity(element, availableQuantity) {
if (availableQuantity >= element.value){
....
You may only have one ID per page. Develop a name scheme such that you don't have two or more id="availableQuantity" or id="quantity" on the page. For instance:
<tr>
<td>${list.partNumber}</td>
<td>${list.itemDescription}</td>
<td>${list.compitableDevice}</td>
<td><input type="text" id="avaliableQuantity-1" name="avaliableQuantity" class="form-control" readonly="readonly" value="${list.quantity}"></td>
<td><input type="checkbox" class="form-group" id="checkedOrder" name="selectedItem" value="${list.partNumber},${list.compitableDevice},${list.itemDescription}"></td>
<td><input type="text" id="quantity-1" name="quantity" class="form-control" onblur="compareQuantity()" value="" /></td>
</tr>
<tr>
<td>${list.partNumber}</td>
<td>${list.itemDescription}</td>
<td>${list.compitableDevice}</td>
<td><input type="text" id="avaliableQuantity-2" name="avaliableQuantity" class="form-control" readonly="readonly" value="${list.quantity}"></td>
<td><input type="checkbox" class="form-group" id="checkedOrder" name="selectedItem" value="${list.partNumber},${list.compitableDevice},${list.itemDescription}"></td>
<td><input type="text" id="quantity-2" name="quantity" class="form-control" onblur="compareQuantity()" value="" /></td>
</tr>
1) A document should only have one element with each ID, so maybe you want to use classes or data- attributes to find the available quantity. For example, you could add 'data-available-quantity' on the element, and then you can just check this with this.dataset.availableQuantity.
2) You don't need to look up the element because you can just pass it when onBlur is called, like
<input type="text" onblur="checkQuantity(this)" data-available-quantity="25" name="quantity" ...
and then your function looks like
function checkQuantity(element) {
if (parseInt(element.dataset.availableQuantity) < parseInt(element.value()))
// this is where you add a message
(edit: added parseInt to make sure they're all integers)

Get value of class with dynamic id jquery

I have the table bellow and I want to get the input $('.note') value from the id of the previous input :
<tr>
<td><input type="text" id='student_1' class='student'></td>
<td><input type="text" class='note'></td>
</tr>
<tr>
<td><input type="text" id='student_2' class='student'></td>
<td><input type="text" class='note'></td>
</tr>
So it can be something like that :
$(".student").change(function () {
alert(this.id.parent('td input.note').val())
})
You could use this.value or $(this).val() :
$('.classname').on('click',function(){
console.log(this.value, $(this).val(), this.id);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' class='classname' id="id_1" value='value_1'/>
<input type='text' class='classname' id="id_2" value='value_2'/>
<input type='text' class='classname' id="id_3" value='value_3'/>
<input type='text' class='classname' id="id_4" value='value_4'/>
Edit :
Go up to the parent tr using .closest('tr') then search for the related input note using .find('.note') and get the value :
$(".student").on('input', function () {
console.log( $(this).closest('tr').find('.note').val() );
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="text" id='student_1' class='student'></td>
<td><input type="text" class='note' value="1111"></td>
</tr>
<tr>
<td><input type="text" id='student_2' class='student'></td>
<td><input type="text" class='note' value="2222"></td>
</tr>
</table>
You can use a combination of closest and find.
$(".student").on('change', function () {
// the student input to which the change event is bound
var $this = $(this);
// Get the wrapper in which the inputs are present
var $closestTr = $this.closest('tr');
// the input vale that is needed
alert($closestTr.find('.note').val());
});
Yes, you can do this $('#' + this.id).val()
You don't need to include the class in the selector because IDs are unique.

Adding to a value declared in another function

It is hard to explain, you can see a DEMO HERE
I have a products table that dynamically creates/deletes new lines of products. I also have a totals table that totals up the totals of each line together.
In that totals box, I have a travel box I want to add to the grand total, but the issue I am having is the travel input is outside the table that is totaling all the values. I can replace the total with a new total, but I can not seem to call the sub total, add the travel and output a grand total.
HTML
<table class="order-details">
<tbody>
<tr>
<td><input type="text" value="" name="" placeholder="Work Description" class="wei-add-field description 1"/></td>
<td><input type="text" value="" name="" placeholder="QTY" class="wei-add-field quantity 1" /></td>
<td><input type="text" value="" name="" placeholder="$0.00" class="wei-add-field unit-price 1"/></td>
<td><input type="text" value="" name="" placeholder="$0.00" class="wei-add-field price-total 1" id=""/></td>
<td> </td>
</tr>
</tbody>
</table>
<div class="wei-add-service">Add Item</div>
<table class="wei-add-totals">
<tr>
<td width="50%">Sub Total</td>
<td width="50%" class="wie-add-subtotal"> </td>
</tr>
<tr class="alternate travel">
<td>Travel</td>
<td><input type="text" value="" placeholder="0.00" class="wei-add-field travel" /></td>
</tr>
<tr>
<td>Taxes</td>
<td><input type="text" value="" placeholder="0.00" class="wei-add-field wie-total-taxes" id="wei-disabled" disabled/> </td>
</tr>
<tr class="alternate total">
<td>Total</td>
<td><input type="text" value="" placeholder="0.00" class="wei-add-field wie-grand-total" id="wei-disabled" disabled/></td>
</tr>
</table>
Javascript
var counter = 1;
var testArray = [ 2,3,4,5];
jQuery('a.wei-add-service-button').click(function(event){
event.preventDefault();
counter++;
var newRow = jQuery('<tr><td><input type="text" class="wei-add-field description ' + counter + '"/></td><td><input type="text" class="wei-add-field quantity ' + counter + '" /></td><td><input type="text" class="wei-add-field unit-price ' + counter + '"/></td><td><input type="text" value="" name="" placeholder="$0.00" class="wei-add-field price-total ' + counter + '" id=""/></td><td>X</td></tr>');
jQuery('table.order-details').append(newRow);
});
jQuery('table.order-details').on('click','tr a',function(e){
e.preventDefault();
var table = $(this).closest('table');
jQuery(this).parents('tr').remove();
reCalculate.call( table );
});
jQuery('table.order-details').on("keyup", "tr", reCalculate);
function reCalculate() {
var grandTotal = 0;
jQuery(this).closest('table').find('tr').each(function() {
var row = jQuery(this);
var value = +jQuery( ".unit-price", row ).val();
var value2 = +jQuery( ".quantity", row ).val();
var total = value * value2;
grandTotal += total;
jQuery( ".wei-add-field.price-total", row ).val( '$' + total.toFixed(2) );
});
jQuery(".wie-add-subtotal").text( '$' + grandTotal.toFixed(2));
}
I don't think, given the task of creating this, I would have chosen to do it in the way you did.
However, using your existing code you can bind the Travel value on change, paste, or keyup and run a function on any of those actions. Within that function I have removed the special character ($) from ".wie-grand-total" using a regex and converted the value of ".wie-grand-total" to a float using parseFloat. I also converted the Travel value to a float using parseFloat. I then added them together and made the sum your new value for "wie-grand-total".
/* NEW SINCE COMMENTS */
//Add to your HTML New table
<table class="order-details">
<tbody>
<tr>
<td><input type="text" value="" name="" placeholder="Work Description" class="wei-add-field description 1"/></td>
<td><input type="text" value="" name="" placeholder="QTY" class="wei-add-field quantity 1" /></td>
<td><input type="text" value="" name="" placeholder="$0.00" class="wei-add-field unit-price 1"/></td>
<td><input type="text" value="" name="" placeholder="$0.00" class="wei-add-field price-total 1" id=""/></td>
/* NEW SINCE COMMENTS*/
<td><input type="text" id="travelHid" value=""></td>
<td> </td>
</tr>
</tbody>
</table>
/* NEW SINCE COMMENTS */
$('#travelHid').hide();
var travelVal = 0;
function updateTravelVal(travelVal){
var travelVal = travelVal;
$('#travelHid').val(travelVal);
};
updateTravelVal();
$("#travelVis").bind("change paste keyup", function() {
var noChars = jQuery(".wie-grand-total").val().replace(/[^0-9.]/g, "");
var newTot = parseFloat(noChars) + parseFloat($(this).val());
jQuery(".wie-grand-total").val( '$' + newTot.toFixed(2));
//added error checking
var checkError = jQuery(".wie-grand-total").val( '$' + newTot.toFixed(2));
//if the value that would go in input is NaN then use travelVal
//since there is no value in .wie-grand-total yet
if (typeof checkError !== "string") {
jQuery(".wie-grand-total").val( '$' + travelVal.toFixed(2))
} else if (typeof checkError === "string") {
jQuery(".wie-grand-total").val( '$' + newTot.toFixed(2))
}
/* NEW SINCE COMMENTS */
updateTravelVal(travelVal);
});
A fiddle for demonstration (now with hiddenVal per comment)
http://jsfiddle.net/chrislewispac/wed6eog0/3/
Only potential problems here are it only runs when you change, paste, or key up the value in #TravelVis.
/EXPLAINED SINCE COMMENTS/
It the html I added a td with input. Input id="travelHid". I then make that invisible by applying jQuery method .hide(). I then exposed travelVal to global scope an initiated it with a value of zero then created a function to update that value.
Within that function I set the value to the argument travelVal or to 0 if there are no args. I then immediately call it.
Then, I added a call to that function with the arg travelVal from our bind function to update it if a value is present.
And finally:
Just add a row to the table with preset value of Travel and Quant 1.
http://jsfiddle.net/chrislewispac/xntn7p5p/5/

Categories

Resources