Appended new row is not behaving like previous one (row) - javascript

I have a HTML table in side which i have several td as input field,my table is dynamic, when page loads i am appending the 1st row of my table and focus on first input field, in my case i.e Item Name
I have 3 input fields in my row which are Item Name,Unit Qty and Disc%
When user clicks inside ItemName input field i am searching for itemnames from a data which is objects inside a array to populate itemnames
After selecting Item NAme i am moving my focus to next input field which is Unit Qty then after that focus in to next input field which is Disc% in between this some calculation are happening to calculate Total Amount
Then after this when user is focus out from Disc% i am appending a new row, actually i have a function inside which i have code to append the row, so i am calling that function on focus out of Disc%
After focus out of Disc% i want my focus should go to the ItemName of new row and should behave like it was behaving (Like search from data) and so on
I have commented the lines in my code to better user understanding what is happening where
function rowappend() // this one is appending row
{
var markup = '<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
'</td><td id="itemCodetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
'<td id="purRatetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
'<td id="discAmttd" class="commantd"></td>' +
'<td id="gstPercentagetd" class="commantd"></td>' +
'<td id="gstAmttd" class="commantd"></td>' +
'<td id="totalAmttd" class="commantd"></td></tr>'
$("table tbody").append(markup);
$("itemNametd").next().focus();
}
rowappend()
var data = [ //data to populate Item Name search input field
{
"ItemName": "Butter"
},
{
"ItemName": "Rice"
},
{
"ItemName": "Milk"
},
{
"ItemName": "Ice Cream"
},
{
"ItemName": "Curd"
}
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
"ItemName": "Butter",
"ItemCode": 400564,
"PurRate": 8,
"DiscAmt": 6,
"gstPercentage": 35,
"gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
let itemName = data.map(value => { //using autocomplete to for searching input field
return value.ItemName;
});
$("#itemNametd").autocomplete({
source: itemName
});
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this
data1.map(value => {
$("#itemCodetd").text(value.ItemCode);
$("#purRatetd").text(value.PurRate);
$("#discAmttd").text(value.DiscAmt);
$("#gstPercentahgetd").text(value.gstPercentage);
$("#gstAmttd").text(value.gstAmt);
});
});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
unitQuantity = $("#unitQtytd").val();
purchaseRate = $("#purRatetd").text();
totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
$("#totalAmttd").text(totalAmount);
});
$("#discPercentagetd").focusout(function() { //here when user is focus out i am calling the fuinction which is creating new row
rowappend()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<div class="container commonDivInvoice">
<div class="row tableInvoice" id="commonDvScroll">
<table class="table table-bordered" id="tableInvoice">
<thead>
<tr>
<th id="itemNameth" class="commanth">Item Name</th>
<th id="itemCodeth" class="commanth">Item Code</th>
<th id="unitQtyth" class="commanth">Unit Qty</th>
<th id="purRateth" class="commanth">Pur.Rate</th>
<th id="discPercentageth" class="commanth">Disc%</th>
<th id="discAmtth" class="commanth">Disc Amt</th>
<th id="gstPercentageth" class="commanth">Gst%</th>
<th id="gstAmtth" class="commanth">Gst Amt</th>
<th id="totalAmtth" class="commanth">Total Amount</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
From my side i think i am using wrong approach to do this task
NOTE :- in future on each focus out i may be doing some calculations so please help me out in that way
I have provided all the information if it is not sufficient then you all can ask me in comments
EDIT
as per Wils's answer after focus out from Disc% new row is appending and focus is also shifting to new row's Item Name but issue is when new row is appending the autocomplete is not working in first row initially when page loads when i type m inside the input field of Item Name all the item name containing m are displayed as drop-down but for 2nd row its not showing up
function rowappend() // this one is appending row
{
var markup = $('<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
'</td><td id="itemCodetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
'<td id="purRatetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
'<td id="discAmttd" class="commantd"></td>' +
'<td id="gstPercentagetd" class="commantd"></td>' +
'<td id="gstAmttd" class="commantd"></td>' +
'<td id="totalAmttd" class="commantd"></td></tr>');
$("table tbody").append(markup);
$("#itemNametd", markup).focus();
}
rowappend()
var data = [ //data to populate Item Name search input field
{
"ItemName": "Butter"
},
{
"ItemName": "Rice"
},
{
"ItemName": "Milk"
},
{
"ItemName": "Ice Cream"
},
{
"ItemName": "Curd"
}
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
"ItemName": "Butter",
"ItemCode": 400564,
"PurRate": 8,
"DiscAmt": 6,
"gstPercentage": 35,
"gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
let itemName = data.map(value => { //using autocomplete to for searching input field
return value.ItemName;
});
$("#itemNametd").autocomplete({
source: itemName
});
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this
data1.map(value => {
$("#itemCodetd").text(value.ItemCode);
$("#purRatetd").text(value.PurRate);
$("#discAmttd").text(value.DiscAmt);
$("#gstPercentahgetd").text(value.gstPercentage);
$("#gstAmttd").text(value.gstAmt);
});
});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
unitQuantity = $("#unitQtytd").val();
purchaseRate = $("#purRatetd").text();
totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
$("#totalAmttd").text(totalAmount);
});
$('body').on('focusout', '#discPercentagetd', function() {
rowappend()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<div class="container commonDivInvoice">
<div class="row tableInvoice" id="commonDvScroll">
<table class="table table-bordered" id="tableInvoice">
<thead>
<tr>
<th id="itemNameth" class="commanth">Item Name</th>
<th id="itemCodeth" class="commanth">Item Code</th>
<th id="unitQtyth" class="commanth">Unit Qty</th>
<th id="purRateth" class="commanth">Pur.Rate</th>
<th id="discPercentageth" class="commanth">Disc%</th>
<th id="discAmtth" class="commanth">Disc Amt</th>
<th id="gstPercentageth" class="commanth">Gst%</th>
<th id="gstAmtth" class="commanth">Gst Amt</th>
<th id="totalAmtth" class="commanth">Total Amount</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
Note :- if anybody out here help me out like what should be my approach towards this task, then it can be helpful

There are several issues with your code
The two most important are
You use multiple elements with the same id. But iss must be unique. JavaScript/jQuery will always use the first element with the id, if multiple elements have the same (CSS is different). I used name instead of id here
You add event listeners to elements, which are not there at run-time. Only the first input-row is created, when you listen to the focusout events. I listen to the focusout event on the whole document. If you focus out of an input, the event will bubble up to the document, where I decide, what to do based on the event's target property.
I restructured your code a bit and made some improvements, but it's far from perfect.
"use strict";
console.clear()
const data = [ //data to populate Item Name search input field
{"ItemName": "Butter"},
{"ItemName": "Rice"},
{"ItemName": "Milk"},
{"ItemName": "Ice Cream"},
{"ItemName": "Curd"}
]
const data1 = {// this data will be dynamic but for now to test i am using this single data
butter: {
"ItemName": "Butter",
"ItemCode": 400564,
"PurRate": 8,
"DiscAmt": 6,
"gstPercentage": 35,
"gstAmt": 5
},
rice: {
"ItemName": "Rice",
"ItemCode": 400565,
"PurRate": 3,
"DiscAmt": 2,
"gstPercentage": 20,
"gstAmt": 8
},
milk: {
"ItemName": "Milk",
"ItemCode": 200569,
"PurRate": 1,
"DiscAmt": 1,
"gstPercentage": 50,
"gstAmt": 2
},
'ice cream': {
"ItemName": "Ice cream",
"ItemCode": 800002,
"PurRate": 16,
"DiscAmt": 2,
"gstPercentage": 15,
"gstAmt": 2
},
curd: {
"ItemName": "Curd",
"ItemCode": 100289,
"PurRate": 9,
"DiscAmt": 1,
"gstPercentage": 12,
"gstAmt": 4
},
}
var totalAmount = "";
var unitQuantity = "";
function rowappend(tbody) {// this one is appending row{
const markup =
`<tr>
<td>
<input type="text" class="form-control commantd" name="itemNametd">
</td>
<td name="itemCodetd" class="commantd"></td>
<td>
<input type="text" class="form-control commantd" name="unitQtytd">
</td>
<td name="purRatetd" class="commantd"></td>
<td>
<input type="text" class="form-control commantd" name="discPercentagetd">
</td>
<td name="discAmttd" class="commantd"></td>
<td name="gstPercentagetd" class="commantd"></td>
<td name="gstAmttd" class="commantd"></td>
<td name="totalAmttd" class="commantd"></td>
</tr>`
$(tbody).append(markup);
setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);
const itemName = data.map(value => { //using autocomplete to for searching input field
return value.ItemName;
});
$("[name=itemNametd]", tbody).last().autocomplete({
source: itemName
});
}
rowappend($('tbody', '#tableInvoice'))
function getValues(row) {
const search = ($('[name=itemNametd]', row).val()).toString()
const value = data1[search.toLowerCase()];
if (value) {
$(row).find("[name=itemCodetd]").text(value.ItemCode);
$(row).find("[name=purRatetd]").text(value.PurRate);
$(row).find("[name=discAmttd]").text(value.DiscAmt);
$(row).find("[name=gstPercentahgetd]").text(value.gstPercentage);
$(row).find("[name=gstAmttd]").text(value.gstAmt);
}
}
function calc(row) {
const unitQuantity = $(row).find("[name=unitQtytd]").val();
const purchaseRate = $(row).find("[name=purRatetd]").text();
const totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
$(row).find("[name=totalAmttd]").text(totalAmount);
}
$(document).on('focusout', (e) => {
const row = e.target.parentElement.parentElement
if (e.target.matches('[name=discPercentagetd]')) {
if ($(row).parent().find('tr').length - $(row).index() === 1) { // only last row
rowappend(e.target.parentElement.parentElement.parentElement)
}
}
if (e.target.matches('[name=unitQtytd]')) {
calc(e.target.parentElement.parentElement)
}
if (e.target.matches("[name=itemNametd]")) {
getValues(e.target.parentElement.parentElement)
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<div class="container commonDivInvoice">
<div class="row tableInvoice" id="commonDvScroll">
<table class="table table-bordered" id="tableInvoice">
<thead>
<tr>
<th id="itemNameth" class="commanth">Item Name</th>
<th id="itemCodeth" class="commanth">Item Code</th>
<th id="unitQtyth" class="commanth">Unit Qty</th>
<th id="purRateth" class="commanth">Pur.Rate</th>
<th id="discPercentageth" class="commanth">Disc%</th>
<th id="discAmtth" class="commanth">Disc Amt</th>
<th id="gstPercentageth" class="commanth">Gst%</th>
<th id="gstAmtth" class="commanth">Gst Amt</th>
<th id="totalAmtth" class="commanth">Total Amount</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>

You can assign the element selector target in this case markup.
You have to add the listener again after you create a new DOM element.
function rowappend() // this one is appending row
{
var markup = $('<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
'</td><td id="itemCodetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
'<td id="purRatetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
'<td id="discAmttd" class="commantd"></td>' +
'<td id="gstPercentagetd" class="commantd"></td>' +
'<td id="gstAmttd" class="commantd"></td>' +
'<td id="totalAmttd" class="commantd"></td></tr>');
$("table tbody").append(markup);
$("#itemNametd",markup).focus();
}
rowappend()
var data = [ //data to populate Item Name search input field
{
"ItemName": "Butter"
},
{
"ItemName": "Rice"
},
{
"ItemName": "Milk"
},
{
"ItemName": "Ice Cream"
},
{
"ItemName": "Curd"
}
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
"ItemName": "Butter",
"ItemCode": 400564,
"PurRate": 8,
"DiscAmt": 6,
"gstPercentage": 35,
"gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
let itemName = data.map(value => { //using autocomplete to for searching input field
return value.ItemName;
});
$("#itemNametd").autocomplete({
source: itemName
});
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this
data1.map(value => {
$("#itemCodetd").text(value.ItemCode);
$("#purRatetd").text(value.PurRate);
$("#discAmttd").text(value.DiscAmt);
$("#gstPercentahgetd").text(value.gstPercentage);
$("#gstAmttd").text(value.gstAmt);
});
});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
unitQuantity = $("#unitQtytd").val();
purchaseRate = $("#purRatetd").text();
totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
$("#totalAmttd").text(totalAmount);
});
$('body').on('focusout','#discPercentagetd', function(){
rowappend()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<div class="container commonDivInvoice">
<div class="row tableInvoice" id="commonDvScroll">
<table class="table table-bordered" id="tableInvoice">
<thead>
<tr>
<th id="itemNameth" class="commanth">Item Name</th>
<th id="itemCodeth" class="commanth">Item Code</th>
<th id="unitQtyth" class="commanth">Unit Qty</th>
<th id="purRateth" class="commanth">Pur.Rate</th>
<th id="discPercentageth" class="commanth">Disc%</th>
<th id="discAmtth" class="commanth">Disc Amt</th>
<th id="gstPercentageth" class="commanth">Gst%</th>
<th id="gstAmtth" class="commanth">Gst Amt</th>
<th id="totalAmtth" class="commanth">Total Amount</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>

Related

How can I associate a number to a specific string and use that string to filter an iteration in AngularJS?

I am new to AngularJS and I'm having problems doing a reusable generic filter.
Let's say I have a colors, types, and list objects as seen below (New JSON).
I want to make a generic filter that will take colors and types objects and filter the list object without having to use the string match as filter.
For now I did specific filters by strings as seen below.
I will have a lot of information in these objects and I don't want to update the controller each time a new property is being included in the JSON.
How do I associate the number to its specific string value?
Old JSON
[
{
"id": 1,
"name": "Spike",
"type": "dog",
"color": "gray"
},
{
"id": 2,
"name": "Tom",
"type": "cat",
"color": "blue"
},
{
"id": 3,
"name": "Butch",
"type": "cat",
"color": "black"
}
]
New JSONs
// colors
[
{"gray": 1},
{"black": 2},
{"blue": 3},
]
// types
[
{"dog": 1},
{"cat": 2}
]
// data list
[
{
"id": 1,
"type": 1,
"name": "Spike",
"color": 1
},
{
"id": 2,
"type": 2,
"name": "Tom",
"color": 3
},
{
"id": 3,
"type": 2,
"name": "Butch",
"color": 2
}
]
Filters
<table class="table table-bordered table-condensed table-striped table-hover">
<thead>
<tr>
<th>
<a>
Filters:
</a>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in typeItems">
<td>
<label class="check">
<input type="checkbox" ng-model="typeFilterItems[item.type]">{{item.type}}
</label>
</td>
</tr>
<tr ng-repeat="item in colorItems">
<td>
<label class="check">
<input type="checkbox" ng-model="colorFilterItems[item.color]">{{item.color}
</label>
</td>
</tr>
</tbody>
</table>
List
<table class="table table-bordered table-condensed table-striped table-hover header-fixed">
<thead>
<tr>
<th>ID</th>
<th>Type</th>
<th>Color</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr class="list" ng-repeat="item in animals | filter:typeFilter | filter:colorFilter">
<td>{{item.id}</td>
<td>{{item.type}}</td>
<td>{{item.color}}</td>
<td>{{item.name}}</td>
</tr>
</tbody>
</table>
Controller
Animals.list().then(function (data) {
$scope.animals = data;
});
$scope.colorFilterItems = { 'black': true, 'gray': false, 'blue': false }; // doing this to have a predefined filter selection ... for now
$scope.colorItems = [{ name: 'black' }, { name: 'gray' }, { name: 'blue' }];
$scope.colorFilter = function (item) {
return $scope.colorFilterItems[item.color]
};
$scope.typeFilterItems = { 'dog': true, 'cat': false }; // doing this to have a predefined filter selection ... for now
$scope.typeItems = [{ name: 'black' }, { name: 'gray' }, { name: 'blue' }];
$scope.typeFilter = function (item) {
return $scope.typeFilterItems[item.type]
};
Since no one answered I eventually found a solution.
The answer to all this is to use lodash directly inside the service and create a filter method inside the promise that looks for the selected property inside the filter objects and compares them to the data we want to display.
filterAnimals = () => {
intersectedResults =
_.filter(animals,(animal: iAnimal) => {
var colors = _.find(colorLabels,(item: iFilter) => {
return (animal.color ? item.label === animal.color : item.label == null) && item.selected;
});
var types = _.find(typeLabels,(item: iFilter) => {
return (animal.type ? item.label === animal.type : item.label == null) && item.selected;
});
return colors && types;
});
return data;
};
After doing this I acces the filterAnimals() function from the controller and bind the checkbox filters to my data. When doing an ng-change on the checkbox this function executes and checks the filters against the data and it shows the data I need.

Bootstrap table footer functions not working data-footer-formatter

I've been strugling with this for a few days and I can't manage to get it work.
In bootstrap table, when I can't get footer functions to work. It seems that the function is never call. But beside that the function works perfectly.
This is what I get at the bottom of the page.This is what I get at the bottom of the page
Here is my code:
$('#table_calcularIngresos').bootstrapTable({
});
function footerStyle(row, index) {
return {
css: {
"font-weight": "bold"
}
};
};
function totalTextFormatter(data) {
return 'Total ingresado: $';
}
function sumFormatter(data) {
field = this.field;
return data.reduce(function(sum, row) {
return sum + (+row[field]);
}, 0);
}
<table id="table_calcularIngresos"
data-search="true"
data-show-refresh="false"
data-show-toggle="false"
data-show-columns="false"
data-show-export="false"
data-card-view="false"
data-minimum-count-columns="2"
data-pagination="true"
data-show-pagination-switch="false"
data-page-list="[10, 25, 50, 100, ALL]"
data-show-footer="true"
data-footer-style="footerStyle"
data-url="../data/ajax.php?tipo=bienes"
>
<thead>
<tr>
<th data-field="cup_numero" data-footer-formatter="totalTextFormatter">Cupon Numero</th>
<th data-field="cliente_apellido">Apellido</th>
<th data-field="cliente_nombre">Nombre</th>
<th data-field="cliente_dni">DNI</th>
<th data-field="bien_marca">Marca</th>
<th data-field="bien_modelo">Modelo</th>
<th data-field="cup_fecha_pago">Fecha pago</th>
<th data-field="cup_costo" data-footer-formatter="sumFormatter">Monto</th>
<th data-field="es_nombre_corto">Compañía</th>
</tr>
</thead>
</table>
This to me looks like a scope problem. I assume the formatters must be made available on the global scope in case the data-footer-formater attribute is used to set the formatter.
I adapted a formatter example below. The globally available formatter works. The private formatter doesn't, displaying the same problem as you've described.
function globalPriceSumFormatter(items) {
var totalPrice = 0;
items.forEach(function(item) {
totalPrice = totalPrice + item.price;
});
return totalPrice;
}
(function() {
function privatePriceSumFormatter(items) {
var totalPrice = 0;
items.forEach(function(item) {
totalPrice = totalPrice + item.price;
});
return totalPrice;
}
})();
function dollarCurrencyFormatter(value) {
return "$" + value;
}
var items = [{
"id": 0,
"name": "Item 0",
"price": 0
},
{
"id": 1,
"name": "Item 1",
"price": 1
},
{
"id": 2,
"name": "Item 2",
"price": 2
},
{
"id": 3,
"name": "Item 3",
"price": 3
}
];
$("#bootstrapTable").bootstrapTable({
data: items
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.js"></script>
<div class="container">
<h1>Footer formatter</h1>
<p>Use <code>footer-formatter</code> column option to format the display of bootstrap table column footer.</p>
<table id="bootstrapTable" data-data="items" data-show-footer="true">
<thead>
<tr>
<th data-field="id" data-formatter="ID: %s">ID</th>
<th data-field="name">Item Name</th>
<th data-field="price" data-formatter="dollarCurrencyFormatter" data-footer-formatter="globalPriceSumFormatter">Item Price</th>
<th data-field="price" data-formatter="dollarCurrencyFormatter" data-footer-formatter="privatePriceSumFormatter">Item Price 2</th>
</tr>
</thead>
</table>
</div>

Boostrap Table How to add commas between numbers

Hi Have the following code which populates bootstrap table.
During the table generation how do I format and add "$" before the number
and any number should be displayed in this order $100,00,00.00 or $100,00.00 or $100.00
here is my code
$(function () {
$.getJSON("https://api.myjson.com/bins/89vsf", function (jsonFromFile) {
$('#table1').bootstrapTable({
data: jsonFromFile.rows
})
var data = $('#table1').bootstrapTable('getData');
var total1 = data.reduce(function(a, b){
return a + parseFloat(b.LongMarketValue.replace('$',''));
}, 0);
document.querySelector('.total1').innerHTML = total1;
});
});
HTML table
<table id="table1">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="Account">Account #</th>
<th data-field="ClientName">Client</th>
<th data-field="AccountType">Account Type</th>
<th data-field="MarketValue"> Market Value</th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
<td></td>
<th></th>
<th> Total <span class="total1"></span></th>
</tr>
</tfoot>
</table>
JSON
{
"Name": "Jie wn",
"Account": "C10",
"LoanApproved": "12/5/2015",
"LastActivity": "4/1/2016",
"PledgedPortfolio": "1000",
"MaxApprovedLoanAmt": "10000",
"LoanBalance": "1849000",
"AvailableCredit": "2877.824375",
"Aging": "3",
"Brokerage": "My Broker",
"Contact": "oJohnson",
"ContactPhone": "-3614",
"RiskCategory": "Yellow",
"rows": [{
"Account": "06-1234",
"ClientName": "S Smth",
"AccountType": "tail",
"LongMarketValue": "$40000"
}, {
"Account": "08-1235",
"ClientName": "all Sth",
"AccountType": "REV Trust",
"LongMarketValue": "$55000"
},
{
"Account": "086-1236",
"ClientName": "Sly Smith",
"AccountType": "Reail",
"LongMarketValue": "$5500"
}]
}
You could use toLocaleString() to convert number to currency format. Or use regular expression to do this, How to print a number with commas as thousands separators in JavaScript
Working example.
$(function () {
$.getJSON("https://api.myjson.com/bins/89vsf", function (jsonFromFile) {
var rows = jsonFromFile.rows.map(function(item){
item.LongMarketValue = parseFloat(item.LongMarketValue.replace('$',''));
item.LongMarketValue = getFormattedCurrency(item.LongMarketValue);
return item;
});
$('#table1').bootstrapTable({
data: rows
})
var data = $('#table1').bootstrapTable('getData');
var total1 = data.reduce(function(a, b){
return a + parseFloat(b.LongMarketValue.replace('$','').split(',').join(''));
}, 0);
document.querySelector('.total1').innerHTML = getFormattedCurrency(total1);
});
});
function getFormattedCurrency(number){
return number.toLocaleString('en-US',{style: 'currency', currency: 'USD'});
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<table id="table1">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="Account">Account #</th>
<th data-field="ClientName">Client</th>
<th data-field="AccountType">Account Type</th>
<th data-field="LongMarketValue"> Market Value</th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
<td></td>
<td></td>
<th></th>
<th> Total <span class="total1"></span></th>
</tr>
</tfoot>
</table>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://rawgit.com/wenzhixin/bootstrap-table/master/src/bootstrap-table.js"></script>
<script src="script.js"></script>
</body>
</html>
Working plunkr http://plnkr.co/edit/PSCR5iS7DSWkuQb1jv5P?p=preview
Hope this helps.
a couple of prototype functions that I use for this
String.prototype.toTwoDecimals = function () {
var value = this;
if (isNaN(value)) {
value = 0;
}
return parseFloat(Math.round(value * 100) / 100).toFixed(2);
};
String.prototype.toCommaSeperated = function () {
var value = this;
if (isNaN(value)) {
value = 0;
}
while (/(\d+)(\d{3})/.test(value.toString())) {
value = value.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
}
return value;
};
String.prototype.toUSD = function () {
var value = this;
if (isNaN(value)) {
value = 0;
}
return '$' + this.toString().toTwoDecimals().toCommaSeperated();
};
then you can use "10000".toCommaSeperated() or "100000".toUSD()

Filter results in too much data being displayed

I am testing the underscore library.
This is my first example:
<!--This is the html code-->
<table id="table" border="1">
<thead>
<tr><th>Nombre</th><th>Ciudad</th><th>Edad</th></tr>
</thead>
</table>
//This is the javascript code for to load the table
var clienList = [
{name:'Juan' , city:'Madrid', age:27},
{name:'Peter', city:'Madrid', age:31},
{name:'Ana' , city:'Barcelona', age:28},
{name:'Oscar', city:'Madrid', age:24},
{name:'Dani' , city:'Bilbao', age:43},
{name:'Pedro', city:'Valencia', age:25},
{name:'Pablo', city:'Sevilla' , age:27},
{name:'Marta', city:'Sevilla' , age:32}
];
I am loading a table using one array of javascript, when i make onclick in the middle cell column (City), i apply the filtering table basing me in the cell content. But the funcionality is not correct, because i dont know update the array.
when applying the filter, for example, "Madrid", add me to the table arrays elements with the city "Madrid", but i follow seeing all rows, when only should show me the rows with the Madrid city
// This is event onclick of the city column table
$("#table-client table tr td.filter-city").click(function() {
var cell = $(this);
var filterCity = _.where(clienList, {city: cell.text()});
//clienList.length = 0;
//uso de underscore
_.each(filterCity,function(element) {
$("#table").append("<tbody><tr><td>"+element.name+"</td><td class='filter-city'><a href='#'>"
+element.city+
"</a></td><td>"+element.age+"</td></tr></tbody>");
})
});
Thanks for help me,
Your problem is you always add filtered result to table, without clearing old.
So you can a bit fix your function for updating table, for example with replaceWith.
//This is the javascript code for to load the table
var clienList = [{
name: 'Juan',
city: 'Madrid',
age: 27
}, {
name: 'Peter',
city: 'Madrid',
age: 31
}, {
name: 'Ana',
city: 'Barcelona',
age: 28
}, {
name: 'Oscar',
city: 'Madrid',
age: 24
}, {
name: 'Dani',
city: 'Bilbao',
age: 43
}, {
name: 'Pedro',
city: 'Valencia',
age: 25
}, {
name: 'Pablo',
city: 'Sevilla',
age: 27
}, {
name: 'Marta',
city: 'Sevilla',
age: 32
}];
// This is event onclick of the city column table
$("#table-client table tr td.filter-city").click(function() {
var cell = $(this);
var filterCity = _.where(clienList, {
city: cell.text()
});
$("#table tbody").replaceWith("<tbody>" +
filterCity.reduce(function(acc, element) {
return acc +
"<tr><td>" + element.name + "</td><td class='filter-city'><a href='#'>" + element.city +
"</a></td><td>" + element.age + "</td></tr>"
}, "") +
"</tbody>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<div id="table-client">
<table >
<tr>
<td class="filter-city">Madrid</td>
</tr>
<tr>
<td class="filter-city">Barcelona</td>
</tr>
<tr>
<td class="filter-city">Bilbao</td>
</tr>
<tr>
<td class="filter-city">Valencia</td>
</tr>
<tr>
<td class="filter-city">Sevilla</td>
</tr>
</table>
</div>
<!--This is the html code-->
<table id="table" border="1">
<thead>
<tr>
<th>Nombre</th>
<th>Ciudad</th>
<th>Edad</th>
</tr>
</thead>
<tbody></tbody>
</table>
UPDATE: yet another way just remove all children before adding, like
//This is the javascript code for to load the table
var clienList = [{
name: 'Juan',
city: 'Madrid',
age: 27
}, {
name: 'Peter',
city: 'Madrid',
age: 31
}, {
name: 'Ana',
city: 'Barcelona',
age: 28
}, {
name: 'Oscar',
city: 'Madrid',
age: 24
}, {
name: 'Dani',
city: 'Bilbao',
age: 43
}, {
name: 'Pedro',
city: 'Valencia',
age: 25
}, {
name: 'Pablo',
city: 'Sevilla',
age: 27
}, {
name: 'Marta',
city: 'Sevilla',
age: 32
}];
// This is event onclick of the city column table
$("#table-client table tr td.filter-city").click(function() {
var cell = $(this);
var filterCity = _.where(clienList, {
city: cell.text()
});
$("#table tbody").empty();
//uso de underscore
_.each(filterCity, function(element) {
$("#table tbody").append("<tr><td>" + element.name + "</td><td class='filter-city'><a href='#'>" + element.city +
"</a></td><td>" + element.age + "</td></tr>");
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<div id="table-client">
<table>
<tr>
<td class="filter-city">Madrid</td>
</tr>
<tr>
<td class="filter-city">Barcelona</td>
</tr>
<tr>
<td class="filter-city">Bilbao</td>
</tr>
<tr>
<td class="filter-city">Valencia</td>
</tr>
<tr>
<td class="filter-city">Sevilla</td>
</tr>
</table>
</div>
<!--This is the html code-->
<table id="table" border="1">
<thead>
<tr>
<th>Nombre</th>
<th>Ciudad</th>
<th>Edad</th>
</tr>
</thead>
<tbody></tbody>
</table>
One thing can be it's case sensitive. So if you search for madrid it won't show up but only if you search exactly Madrid it would show up.
If that is the case you can use capitalize mixin given as example in underscore page.
_.mixin({
capitalize: function(string) {
return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
}
});
And use it like
var filterCity = _.where(clienList, {city: _(cell.val()).capitalize()});
Your code ( with a bit of modification)
//This is the javascript code for to load the table
var clienList = [
{name:'Juan' , city:'Madrid', age:27},
{name:'Peter', city:'Madrid', age:31},
{name:'Ana' , city:'Barcelona', age:28},
{name:'Oscar', city:'Madrid', age:24},
{name:'Dani' , city:'Bilbao', age:43},
{name:'Pedro', city:'Valencia', age:25},
{name:'Pablo', city:'Sevilla' , age:27},
{name:'Marta', city:'Sevilla' , age:32}
];
_.mixin({
capitalize: function(string) {
return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
}
});
// This is event onclick of the city column table
$("#search").click(function() {
var cell = $('#text');
var filterCity = _.where(clienList, {city: _(cell.val()).capitalize()});
console.log(filterCity.length);
//clienList.length = 0;
//uso de underscore
$("#table tbody").empty();
_.each(filterCity,function(element) {
$("#table").append("<tbody><tr><td>"+element.name+"</td><td class='filter-city'><a href='#'>"
+element.city+
"</a></td><td>"+element.age+"</td></tr></tbody>");
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<input type="text" id="text">
<br>
<input type="button" id="search" value="search">
<br>
<table id="table" border="1">
<thead>
<tr>
<th>Nombre</th>
<th>Ciudad</th>
<th>Edad</th>
</tr>
</thead>
</table>

How to bind bind inner json list to html row jqMobile table

just I want to know how can I bind inner json list "pslList" to html row
<table data-role="table" id="productOrders" data-mode="reflow">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Price</th>
<th>Qty.</th>
<th>Ext</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
json
[
{
"amount": 12,
"podate": "2013-11-28T00:00:00",
"ponumber": 7,
"pslList": [
{
"ext": 210,
"ponumber": 7,
"prodcd": "ffrff",
"price": 70,
"prodname": "games",
"qty": 3
},
{
"ext": 70,
"ponumber": 7,
"prodcd": "rrfrr",
"price": 14,
"prodname": "DVDs",
"qty": 5
}
],
"vendorno": 1
}
]
After retrieving the json, you can iterate over the list, create rows and then add them to the table:
var $table = $('#productOrders tbody');
var plist = json[0].pslList;
for (i in plist) {
var row = $('<tr><td>' + plist[i].prodcd + '</td><td>' + plist[i].prodname + '</td><td>' + plist[i].price + '</td><td>' + plist[i].qty + '</td><td>' + plist[i].ext + '</td></tr>');
$table.append(row);
}

Resources