I create an dyamic form with Jquery, there will be the multiple select box and textbox, how can I group the data into one based on the user name. For example, there will be the multiple select box = lim, total = 20, how can I group this 2 into array as 1.
When click the save button the final data will be like below
array(
'lim' => 40,
'tan' => 10,
);
Code here: https://jsfiddle.net/7gbvfjdc/
You mean something like this ?
You save button event listener should have following code
$('.savebtn').on('click', function() {
var mapObj = {};
$('.listable .cb').each(function(index, item) {
var selectVal = $(this).find('select').val();
if (mapObj[selectVal]) {
mapObj[selectVal] += Number($(this).find('#amt1_' + index).val());
} else {
mapObj[selectVal] = Number($(this).find('#amt1_' + index).val());
}
});
console.log(mapObj);
});
var i = 0;
$('.addRow').on('click', function() {
addRow();
});
function addRow() {
var tr = '<tr class="cb" id="row_' + i + '"><td>';
tr += '<select class="form-control select2" id="name1_' + i + ' first" name="name[]">';
tr += '<option>tan</option><option>lim</option></select></td>';
tr += '<td><input type="number" name="winlose[]" id="amt1_' + i + '" class="form-control"></td>';
tr += '<td style="text-align:center">-';
tr += '</td></tr>';
i++;
$('tbody').append(tr);
}
$('tbody').on('click', '.remove', function() {
$(this).parent().parent().remove();
});
$('.savebtn').on('click', function() {
var mapObj = {};
$('.listable .cb').each(function(index, item) {
var selectVal = $(this).find('select').val();
if (mapObj[selectVal]) {
mapObj[selectVal] += Number($(this).find('#amt1_' + index).val());
} else {
mapObj[selectVal] = Number($(this).find('#amt1_' + index).val());
}
});
console.log(mapObj);
});
<table class="table table-bordered listable">
<thead>
<tr class="text-center">
<th>name</th>
<th>amount</th>
<th style="text-align:center">+</th>
</tr>
</thead>
<tbody class="text-center">
</tbody>
</table>
<button type="button" class="btn btn-primary savebtn">Save</button>
You can use reduce on the body trs to extract the data and sum it in the wanted object format. Like this:
const result = $('tbody tr').get().reduce((prev, ne) => {
const $this = $(ne);
const type = $this.find('select').val();
prev[type] += parseInt($this.find('input').val())
return prev;
}, {
lim: 0,
tan: 0
});
var i = 0;
$('.addRow').on('click', function() {
addRow();
/*
$('.select2').select2({
theme: 'bootstrap4',
ajax: {
url: '{{ route("getMember") }}',
dataType: 'json',
},
}); */
});
function addRow() {
i++;
var tr = '<tr id="row_' + i + '"><td>';
tr += '<select class="form-control select2" id="name1_' + i + ' first" name="name[]">';
tr += '<option>tan</option><option>lim</option></select></td>';
tr += '<td><input type="number" name="winlose[]" id="amt1_' + i + '" class="form-control"></td>';
/* tr += '<td><select class="form-control select2" id="name2_'+i+'" name="name2[]">';
tr += '<option>tan</option><option>lim</option></select></td>';
tr += '<td><input type="number" name="winlose[]" id="amt2_'+i+'" class="form-control"></td>'; */
tr += '<td style="text-align:center">-';
tr += '</td></tr>';
$('tbody').append(tr);
}
$('tbody').on('click', '.remove', function() {
$(this).parent().parent().remove();
});
$('button').on('click', () => {
const result = $('tbody tr').get().reduce((prev, ne) => {
const $this = $(ne);
const type = $this.find('select').val();
prev[type] += parseInt($this.find('input').val())
return prev;
}, {
lim: 0,
tan: 0
});
console.log(result)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered">
<thead>
<tr class="text-center">
<th>name</th>
<th>amount</th>
<th>Second name</th>
<th>Second amount</th>
<th style="text-align:center">+</th>
</tr>
</thead>
<tbody class="text-center">
</tbody>
</table>
<button>
save
</button>
https://jsfiddle.net/moshfeu/20kczto7/14/
Related
So I'm working on a feature that require a user to type in a search item that will search a table for the term and highlight every occurrence. I found some code and got it to work, but I have a bug that I'm not sure how to resolve. In the search input if I hit back space to erase the search term, the unhighlight works until the last character letter. For example, I type in Demo and use back space to delete Demo, only the D is still highlighted.
Below are my code snippets.
NOTE: I have a search and render function that call the highlightActivity and renderReports functions
My CSS
.highlight {
background-color :gold
}
.highlight {
padding:1px 4px;
margin: 0 -4px;
}
My HTML
<input type="text" id="uniStringSearch" onkeyup="SearchAndRender()"></input>
<table id="currentReports" class="table table-striped table-condensed table-bordered">
<thead>
<tr>
<th><input name="select_all" id="selectedReports" value="1" type="checkbox" onclick="checkAll(this)" /> </th>
<th>DATE</th>
<th>SUMMARY TITLE</th>
<th>NAME</th>
<th>ACTIVITY TYPE</th>
<th>SUB ACTIVITY TYPE</th>
<th>ACTIVITY DETAILS</th>
</tr>
</thead>
<tbody id="reports"></tbody>
</table>
HighlightActivity Function
function highlightActivity() {
var searchTerm = $('#uniStringSearch').val();
var tableID = ''
switch (webPage) {
case 'reports':
tableID = '#currentReports';
break;
case 'analysis':
tableID = '#currentAnalysis';
break;
case 'statuses':
tableID = '#currentStatuses';
break;
default:
}
$(tableID).find('.highlight').removeClass('highlight');
$(tableID).find('tr td').each(function () {
if ((this).attr('data-search') !== 'false') {
var text = $(this).text();
var textLowerCase = text.toLowerCase();
var pos = textLowerCase.indexOf(searchTerm.toLowerCase());
var regex = new RegExp(searchTerm, 'ig');
text = text.replace(regex, (match, $1) => {
return '<span class="highlight">' + match + '</span>';
});
$(this).html(text);
if (pos !== -1) {
setTimeout(function () {
if ($(this).parent().find('.highlight').is(':empty')) {
$('.highlight').remove();
}
}.bind(this), 0);
}
else {
$(this).text(text);
}
}
if ($(this).parent().find('.highlight').length > 0) {
$(this).parent().show();
}
else {
$(this).parent().hide();
}
});
}
Render Reports Function
function renderReports(items) {
var html = '';
for (var i = 0; i < items.length; i++)
{
html = '<tr><td><input type="checkbox" id="selectedReports" onchange="chkInputChanged(event)"/></td>'
html += '<td>' + items[i].DateActivity + '</td>'
html += '<td>' + items[i].Name + '</td>'
html += '<td>' + items[i].ActivityType + '</td>'
html += '<td>' + items[i].SubActivityType + '</td>'
html += '<td id="searchActivityDetails">' + items[i].ActivityDetails + '</td></tr>'
}
$('#reports').empty();
$('#reports').append(html);
}
ALSO....one more thing, is there a way to have my highlight function to target a specific column? For example Summary Title and Activity Details
I am trying to build a search function that would allow me to search Word 1 Word 2 ... Word 'n'.
The code below allows me to search through table rows. Results are presented when there is a 1:1 match (Ignoring case). I would like to search using combinations separated by spaces.
Table data sample as below.
AAA_BBB_CCC_DDD.pdf
EEE_FFF_GGG_HHH.pdf
HTML
<script>
$(function(){
$(function(){
var requestUri = "<<URL>>/_api/web/GetFolderByServerRelativeUrl('<<Folder>>')/Files?$filter=(substringof(%27.pdf%27,Name)%20or%20substringof(%27.PDF%27,Name))&$top=1000";
$.ajax({
url: requestUri,
type: "GET",
headers: {
"accept":"application/json; odata=verbose"
},
success: onSuccess,
});
function onSuccess(data) {
var objItems = data.d.results;
var tableContent = '<table id="Table" style="width:100%"><tbody>';
for (var i = 0; i < objItems.length; i++) {
tableContent += '<tr>';
tableContent += '<td>' + [i+1] + '</td>';
tableContent += '<td>' + objItems[i].Name + '</td>';
tableContent += '<td>' + "<a target='iframe_j' href='<<URL>>" + objItems[i].ServerRelativeUrl + "'>" + "View" + "</a>" + '</td>';
tableContent += '</tr>';
}
$('#TDGrid').append(tableContent);
}
});
});
</script>
<div id="div">
<input class="form-control mb-2" id="TDSearch" type="text" placeholder=" Search">
<table id='Table' class="table table-striped table-sm small">
<tr>
<td>
<div id="TDGrid" style="width: 100%"></div>
</td>
</tr>
</table>
</div>
Current search function
$(document).ready(function(){
$("#TDSearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#TDGrid tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
You can convert string to array and then make a function, which will check match for strings of that array.
Something like
$(document).ready(function() {
$("#TDSearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
var valueArr = value.split(' ');
$("#TDGrid tr").filter(function() {
$(this).toggle(checkIfValuePresent($(this).text().toLowerCase(), valueArr));
});
});
});
function checkIfValuePresent(currRowText, valuesarr) {
let isfound = false;
for (let i = 0; i < valuesarr.length; i++) {
if (currRowText.indexOf(valuesArr[i] > -1)) {
isfound = true;
break;
}
}
return isfound;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' id='TDSearch'>
split on space, join all strings with | between them for a combined regex string search, case insensitive.
$(document).ready(function(){
$("#TDSearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#TDGrid tr").filter(function() {
$(this).toggle(new RegExp(value.replace(/\./g,'[.]').split(' ').join('|'),'gi').test($(this).text()))
});
});
});
I am adding rows dynamically with autofilled values from database. After adding it, it has to calculate total. Now it is calculating total only for 1st row. for 2nd row onwards it is not calculating anything. And also overall total is not happening.
Here is my code
html form
<table class="table table-bordered">
<tr>
<th><input class='check_all' type='checkbox' onclick="select_all()" /></th>
<th>No</th>
<th>Item ID</th>
<th>Description</th>
<th>UOM</th>
<th>Price</th>
<th>Tax</th>
<th>Quantity</th>
<th>Discount</th>
<th>Amount</th>
</tr>
<tr>
<td><input type='checkbox' class='case' /></td>
<td><span id='snum'>1.</span></td>
<td><input type="text" class="form-control" id="productcode_1" name="productcode[]"></td>
<td><input type="text" class="form-control" id="description_1" name="description[]"></td>
<td><input type="text" class="form-control" id="uom_1" name="uom[]"></td>
<td><input type="text" class="form-control price" id="price_1" name="price[]"></td>
<td><input type="text" class="form-control tax" id="tax_1" name="tax[]"></td>
<td><input type="text" class="form-control quantity" id="quantity_1" name="quantity[]"></td>
<td><input type="text" class="form-control discount" id="discount_1" name="discount[]"></td>
<td><input type="text" class="form-control amount" id="amount_1" name="amount[]"></td>
<td><button type="button" class='btn btn-danger delete'>-</button></td>
<td><button type="button" class='btn btn-success addmore'>+ </button></td>
</tr>
<tfoot>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th style="text-align:center;" class="total">0<b></b></th>
</tfoot>
</table>
javascript
$(".delete").on('click', function() {
$('.case:checkbox:checked').parents("tr").remove();
$('.check_all').prop("checked", false);
check();
});
var i = $('table tr').length - 1;
$(".addmore").on('click', function() {
count = $('table tr').length - 1;
var data = "<tr><td><input type='checkbox' class='case'/></td><td><span id='snum" + i + "'>" + count + ".</span></td>";
data += "<td><input class='form-control' type='text' id='productcode_" + i + "' name='productcode[]'/></td> <td><input class='form-control' type='text' id='description_" + i + "' name='description[]'/></td><td><input class='form-control' type='text' id='uom_" + i + "' name='uom[]'/></td><td><input class='form-control' type='text' id='price_" + i + "' name='price[]'/></td><td><input class='form-control' type='text' id='tax_" + i + "' name='tax[]'/></td><td><input class='form-control' type='text' id='quantity_" + i + "' name='quantity[]'/></td><td><input class='form-control' type='text' id='discount_" + i + "' name='discount[]'/></td><td><input class='form-control' type='text' id='amount_" + i + "' name='amount[]'/></td></tr>";
$('table').append(data);
row = i;
$('#productcode_' + i).autocomplete({
source: function(request, response) {
$.ajax({
url: 'ajax.php',
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: 'items_table',
row_num: row
},
success: function(data) {
response($.map(data, function(item) {
var code = item.split("|");
return {
label: code[0],
value: code[0],
data: item
}
}));
}
});
},
autoFocus: true,
minLength: 0,
select: function(event, ui) {
var names = ui.item.data.split("|");
id_arr = $(this).attr('id');
id = id_arr.split("_
$('#description_' + id[1]).val(names[1]); $('#uom_' + id[1]).val(names[2]); $('#price_' + id[1]).val(names[3]); $('#tax' + id[1]).val(names[4]);
}
});
i++;
});
function select_all() {
$('input[class=case]:checkbox').each(function() {
if ($('input[class=check_all]:checkbox:checked').length == 0) {
$(this).prop("checked", false);
} else {
$(this).prop("checked", true);
}
});
}
$('body').delegate('.quantity,.price,.discount,.tax', 'keyup', function() {
var tr = $(this).parent().parent();
var qty = tr.find('.quantity').valr price = tr.find('.price').val tax = tr.find('.tax').val
var dis = tr.find('.discount').valr amt = (qty * price) - (qty * price * dis) / 100;
var tax1 = (amt) * (tax / 100);
tr.find('.amount').val(tax1al();
});
function total() {
var t = 0;
$('.amount').each(function(i, e) {
var amt = $(this).val() - 0;
t += tax1;
});
$('.total').html(t);
}
function check() {
obj = $('table tr').find('span');
$.each(obj, function(key, value) {
id = value.id;
$('#' + id).html(key + 1);
});
}
$('#productcode_1').autocomplete({
source: function(request, response) {
$.ajax({
url: 'ajax.php',
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: 'items_table',
row_num: 1
},
success: function(data) {
response($.map(data, function(item) {
var code = item.split("|");
return {
label: code[0],
value: code[0],
data: item
}
}));
}
});
},
autoFocus: true,
minLength: 0,
select: function(event, ui) {
var names = ui.item.data.split("|");
$('#description_1').val(names[1]);
$('#uom_1').val(names[2]);
$('#price_1').val(names[3]);
$('#tax_1').val(names[4]);
}
});
ajax.php
<?php
require_once '../connect.php';
if($_POST['type'] == 'items_table'){
$row_num = $_POST['row_num'];
$name = $_POST['name_startsWith'];
$query = "SELECT items.iid, items.description, items.uom, items.selling_price, items.tax_id, taxes.tax_id, taxes.name, taxes.rate FROM items INNER JOIN taxes ON items.tax_id=taxes.tax_id where items.iid LIKE '".strtoupper($name)."%'";
$result = mysqli_query($con, $query);
$data = array();
while ($row = mysqli_fetch_assoc($result)) {
$name = $row['iid'].'|'.$row['description'].'|'.$row['uom'].'|'.$row['selling_price'].'|'.$row['rate'].'|'.$row_num;
array_push($data, $name);
}
echo json_encode($data);
}
?>
Only 1st row total is getting calculated. Not getting what is wrong
I got it resolved.Because of the class i have used
$('body').on('change', '.quantity,.price,.discount,.tax', function() {
var tr = $(this).parent().parent();
var qty = tr.find('.quantity').val();
var price = tr.find('.price').val();
var tax = tr.find('.tax').val();
var dis = tr.find('.discount').val();
var amt = (qty * price) - (qty * price * dis) / 100;
var tax1 = (amt * (tax / 100));
//alert(tax1);
tr.find('.tamount').val(tax1);
ttotal();
tr.find('.amount').val(amt);
total();
});
function total() {
var t = 0;
$('.amount').each(function(i, e) {
var amt = $(this).val() - 0;
t += amt;
});
$('.total').html(t);
}
function ttotal() {
var tt = 0;
$('.tamount').each(function(i, e) {
var tax = $(this).val() - 0;
tt += tax;
});
$('.ttotal').html(tt);
}
function check() {
obj = $('table tr').find('span');
$.each(obj, function(key, value) {
id = value.id;
$('#' + id).html(key + 1);
});
}
I have create javascript to calulate the total of ext. form json but I have problem is it append twice to #total div I don't know what cause maybe because of renderTable function.can someone help me ??
HTML
<div data-role="collapsible" data-collapsed="true" id="poInfos">
<h3 id="poInfo"></h3>
<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>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<div id="total">
</div>
</div>
</div>
</div>
javascript
//render table view all PO for vendor
function renderTable(data){
var $table = $('#productOrders tbody');
var plist = data[0].pslList;
for(var i in plist) {
var row = $('<tr><td>' + plist[i].prodcd + '</td><td>' + plist[i].prodname + '</td><td class="dollars">' + numberToCurrency(plist[i].price) + '</td><td>' + plist[i].qty + '</td><td>' + numberToCurrency(plist[i].ext) + '</td></tr>');
$table.append(row);
calculateTotal(data);
}
}
//calculateTotal
function calculateTotal(data)
{
var $totalDiv = $('#total');
var tax = 0.00;
var sub = 0.00;
var totalsub_tax = 0.00;
var plist = data[0].pslList;
for(var i in plist) {
sub += plist[i].ext;
totalsub_tax = sub +tax;
}
$totalDiv.append("<strong>Sub:</strong>"+numberToCurrency(sub)+"<br/><strong>Total:</strong>"+numberToCurrency(totalsub_tax) +"<br/>");
}
//convert numberToCurrency
function numberToCurrency(amount) {
var thousandsSeparator = ","
var currencyNum = "";
var amountString = amount.toString();
var digits = amountString.split("");
var countDigits = digits.length;
var revDigits = digits.reverse();
for(var i=0; i<countDigits; i++) {
if ((i%3 == 0) && (i !=0)) {
currencyNum += thousandsSeparator+revDigits[i];
} else {
currencyNum += digits[i];
}
};
var revCurrency = currencyNum.split("").reverse().join("");
var finalCurrency = "$"+revCurrency;
return finalCurrency;
}
});
You're running the function calculateTotal() for EACH item instead of after the items have been dealt with.
for(var i in plist) {
var row = $('<tr><td>' + plist[i].prodcd + '</td><td>' + plist[i].prodname + '</td><td class="dollars">' + numberToCurrency(plist[i].price) + '</td><td>' + plist[i].qty + '</td><td>' + numberToCurrency(plist[i].ext) + '</td></tr>');
$table.append(row);
// not here calculateTotal(data);
}
calculateTotal(data); // here
Your call to calculateTotal(data) is within the loop over plist. You should move it outside.
I have a form that has a block called "Product", containing text inputs. Inside that block, the user can press "add item" and have the JS show one more field. Till now everything works.
I've tried to add a function for adding a new "Product" block but no luck. Do you have any hints for me?
Product
Item: <input> Price: <input>
Item: <input> Price: <input>
<a>add item</a> <- this works
<a>add Product</a> <- this is the part that I can't figure out :(
Any help will be appreciated.
Thank you!
Update:
Here is the JS for the Item and Price fields:
<script type="text/javascript">
$(document).ready(function(){
var counter = 2;
$("b.add-item").click(function () {
if(counter>5){ alert("Max 6 items allowed"); return false; }
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html(
'<span class="item">' +
'<label>Item:</label>'+
'<input type="text" name="item1[]" id="textbox' + counter + '" value="" >' +
'<label> Price:</label>'+
'<input type="text" name="price1[]" id="textbox' + counter + '" value="" >' +
'</span>'
);
newTextBoxDiv.appendTo(".items");
counter++;
});
$("b.remove-item").click(function () {
if(counter==1){alert("No more textbox to remove");
return false; } counter--;
$("#TextBoxDiv" + counter).remove();});
$("#getButtonValue").click(function () { var msg = ''; for(i=1; i<counter; i++){ msg += "\n Textbox #" + i + " : " + $('#textbox' + i).val(); }alert(msg); });
});
</script>
Maybe make a table and add new rows?
HTML:
<table id="myTable">
<tr>
<th>Item</th>
<td><input /></td>
<th>Price</th>
<td><input /></td>
</tr>
<tr>
<th>Item</th>
<td><input /></td>
<th>Price</th>
<td><input /></td>
</tr>
</table>
<a onclick="add_row(); return false;">Add Product</a>
JavaScript:
function add_row()
{
var table = document.getElementById('myTable');
if(!table) return;
// Table row
var row = document.createElement('row');
table.appendChild(row);
// "Item:"
var th1 = document.createElement('th');
th1.innerText = 'Item:'
row.appendChild(th1);
// Item input
var td1 = document.createElement('td');
row.appendChild(td1);
var input1 = document.createElement('input');
td1.appendChild(input1);
// "Price:"
var th2 = document.createElement('th');
th2.innerText = 'Price:'
row.appendChild(th2);
// Price input
var td2 = document.createElement('td');
row.appendChild(td2);
var input2 = document.createElement('input');
td1.appendChild(input2);
}
I think this should work...