Passing appended values through json object to be sent to jquery ajax - javascript

I have this appended codes here in my javascript that adds a new row every time the button is clicked to add a new employee.
Here is the code, which is working fine.
tab_workers.on('click', '.add-workers', function (e){
e.preventDefault();
var iRow = $('tbody tr:last',tab_workers).index() + 1;
var nRow = $("<tr>\n" +
"<td width='30%'><input name='worker_name_"+ iRow +"' class='form-control' placeholder='Name' /></td>\n" +
"<td width='50%'><input name='worker_address_"+ iRow +"' type='text' class='form-control' placeholder='Address'></td>\n" +
"<td width='14%'><input name='worker_phone_"+ iRow +"' type='text' maxlength='11' onkeypress='return event.charCode >= 48 && event.charCode <= 57' class='form-control' placeholder='Phone No.'></td>\n" +
"<td width='3%'><a class='btn btn-outline btn-circle btn-sm red del-workers pull-right'><i class='fa fa-remove'></i>Remove</a></td>" +
"</tr>\n");
$('tbody',tab_workers).append(nRow);
Then I have this code to sent it into the ajax post method, by wrapping it into javascript object first.
var workers = [];
$("[name^=worker_name]",tab_workers).each(function(i, wname){
//var workername = $("[name=worker_name_"+i+"]");
var workeradd = $("[name=worker_address_"+i+"]");
var workerphone = $("[name=worker_phone_"+i+"]");
workers.push({
uwiName: $(wname).val(),
uwiAddress: $(workeradd).val(),
uwiPhone: $(workerphone).val()
});
});
var workerdetails = {
umkeiWorkerInfo: workers,
};
console.log(workerdetails);
The console.log above, returns null for all the fields(name, address, phones).
Here is the ajax part,
$.ajax({
type: "post",
url: 'home/umkei/ssuForm/create/workers',
data: JSON.stringify(workerdetails),
contentType : "application/json",
success: function(d){
Metronic.unblockUI(el);
showMetronicAlert('success','check',msgSuccess);
console.log(d);
}
});
Thank you in advance.

I solved this, I use FOR loop instead of .EACH()
var workers=[];
var w = $("[name^=worker_name]",tab_workers);
var i;
for(i=1; i<=w.length;i++){
var workername = $("[name^=worker_name_"+i+"]");
var workeradd = $("[name^=worker_address_"+i+"]");
var workerphone = $("[name^=worker_phone_"+i+"]");
workers.push({
uwiName: workername.val();
uwiAddress: workeradd.val();
uwiPhone: workerphone.val();
//some other values
});
}

Related

how to make more efficient js for loop inside php while loop JSON

I'm selecting values from my db in mysql and comparing them with values from JSON. I'm receiving the right results but since I'm using append the results shows up one by one, which looks like animation I would like to get them all at once and show some kind of loading icon while the loop is running, I've tried few different ways but nothing worked.
<?php $sql= "select a_id,b_id,res_a,res_b from betts_gr where u_id='".$u_id[0]."'";
$user_bets = mysqli_query($conn,$sql);
while($user_bets1 = mysqli_fetch_array($user_bets)){
?>
<script>
$(document).ready(function() {
var a_id = "<?php echo $user_bets1[0]?>";
.....
var car = [];
$.getJSON('http://api.football-api.com/2.0/matches?
comp_id = 1204 & from_date = '+today+' & to_date = '+plusmonth+' & Authorization ',
function(data) {
var html = "";
console.log(data);
$.each(data, function(index, value) {
var teama = value.localteam_name;
var teamb = value.visitorteam_name;
.......
function add(name, point) {
car.push({
teamb: teamb,
teama: teama,
form: form,
data: data,
teama_id: teama_id,
teamb_id: teamb_id,
a_res: a_res,
b_res: b_res
});
}
add(teama, teamb, data, form, teama_id, teamb_id, a_res, b_res);
});
for (var n = 0; n < car.length; n++) {
if (car[n].teama_id == a_id && car[n].teamb_id == b_id) {
html += "<tr><td><input type='hidden' name='aid" + n + "'
value = '"+car[n].teama_id+"' > < input type = 'hidden'
name = 'bid"+n+"'
value = '"+car[n].teamb_id+"' > " +
car[n].data +
"</td><td> " + car[n].teama + "</td><td>" + car[n].a_res + "-" +
car[n].b_res + "</td><td> " +
car[n].teamb + '</td><td> you predicted ->' + pred_resa + ' - ' + pred_resb +
'</tr>';
}
}
$(".message").append(html);
});
});
</script>
<?php } ?>
the example for using the Array.map and the template literals instead of the for loop and the plain string concat:
const isTargetTeam = item => item.teama_id == a_id && item.teamb_id == b_id;
const html = car.slice(0) // copy the array car
.filter(isTargetTeam)
.map((item, index) =>
`<tr>
<td>
<input type='hidden' name='aid${index}' value='${item.teama_id}'>
<input type='hidden' name='bid${index}' value='${item.teamb_id}'>
${item.data}
</td>
<td>
${item.a_res}-${item.b_res}
</td>
<td>
${item.teamb}
</td>
<td> you predicted -> ${pred_resa} - ${pred_resb}
</tr>`
).join('')
You should not mix PHP and Javascript like that. Currently this will result in X document.ready functions with X getJSON requests.
If you want to do the API requests from the local client, you should do ONE javascript function where you pass in the selected user_bets as an array. There are different possibilities to determine if all loadings have been finished: either counting up and checking after every callback if the max number is reached, or using Promises and Promise.all().
<script>
var user_bets = <?php echo json_encode($user_bets);?>;
$(document).ready(function () {
Promise.all(user_bets.map(function (id) {
return fetchFromApi(id);
})).then(function(array){
var html = "";
for(var i = 0; i < array.length; i++){
html += processData(array[i]);
}
$(".message").append(html);
});
});
function fetchFromApi(user_id) {
return new Promise(function (resolve, reject) {
$.getJSON()
.done(function (data) {
resolve(data);
})
.fail(function (error) {
reject(error);
});
});
}
function processData(data){
var html = '';
// do your html processing of a single api call here
return html;
}
</script>
Alternatively you can use CURL to do the API requests server-side already.
Thanks for advise I just realize I should get data with one request. I've passed the whole array to js and since I'm not sure how promise.all is working I did two for loops nested and is working fine, the only thing I still can't figure out how to check if the loops are finished so I could add loading icon while loop is running.
function add(name, point) {
car.push({ teamb : teamb, teama : teama, form:form, data:data, teama_id:teama_id,
teamb_id:teamb_id, a_res:a_res, b_res:b_res});
}
add(teama,teamb,data,form,teama_id,teamb_id,a_res,b_res);
});
for(var n=0;n<car.length;n++){
var taba = [<?php echo json_encode($at1)?>];
var tchild = taba[0];
for(var u=0;u<tchild.length;u++){
if(car[n].teama_id == tchild[u].localteam_id
&& car[n].teamb_id == tchild[u].visitorteam_id){
html += "<tr><td><input type='hidden' name='aid"+n+"'
value='"+car[n].teama_id+"'>
<input type='hidden' name='bid"+n+"'
value='"+car[n].teamb_id+"'>"
+car[n].data
+"</td><td> "+car[n].teama + "</td><td>"+ car[n].a_res
+ "-"+ car[n].b_res + "</td><td> "
+ car[n].teamb + '</td><td> you predicted -
>'+tchild[u].localteam_score +' - '+tchild[u].visitorteam_score +
'</td></tr>';
}
}
}
$(".message").append(html);

TypeError: response[i] is undefined in jQuery autogenerate table rows

I have the following jquery funcion that's supposed to get a value from a text field:
My Php Code
function asset_status() {
$query = $this->db->query("SELECT count(job_card_no) as job_card_no,number,asset.type,asset.status,asset.id as asset_id FROM asset inner join assgnd_rsces on assgnd_rsces.name = asset.id inner join job_card on job_card.id = assgnd_rsces.job_card_id");
$result = $query->result_array();
echo json_encode($result);
}
ajax request
asset_status_list = '';
$.ajax({
type: "GET",
url: "<?php echo base_url(); ?>operations/asset_status",
dataType: "JSON",
success: function (response) {
console.log(response); // it gives following
//job_card_no "2" number "1" status "Active" type "Toilet"
for (i = 0; i < response.length; i++) {
asset_status_list = '<tr><td >' + response[i].job_card_no + '</td><td >' + response[i].number + '</td><td>' + response[i].type + '</td><td ><input type="hidden" name="view_more_id" class="view_more_id' + response[i].id + '" id="view_more_id" value="' + response[i].id + '"/><button id="view_more_link" class="view_more_link' + response[i].id + '"><i class="glyphicon glyphicon-zoom-in "></i>View More</button></td></tr>';
$('#asset_status_tr').append(asset_status_list);
$("#asset_status_tr").on("click", ".view_more_link" + response[i].id, function () {
var asset_id = $(".view_more_id"+response[i].id).val();
alert(asset_id);
});
}
$('#asset_table_status').DataTable({});
},
error: function (response) {
}
});
However when I try it using the above function, I get the following error on click of the button.
TypeError: response[i] is undefined
var asset_id = $(".view_more_id"+response[i].id).val();
How do I solve the above error ?
Yes, you are not getting 'json' from file that's why its length is 0 and its shown you 'undefined'.Please make sure that.

Autocomplete not working for dynamically created content

I am having a bit of trouble trying to add a autocomplete field to my dynamically created content. Previously it worked fine as the textbox was generated in HTML, but I cannot figure how to make it work with dynamically generated content (even trough I am using static textbox id for test purposes)
Autocomplete:
jQuery(document).ready(function($){
var products= JSON.parse( '<?php echo json_encode($products_list) ?>' );
var t = 0;
var r = '<?php echo json_encode($number_of_rows_tuote) ?>';
var availableProducts = [];
var cellPlace = [];
while(t < r){
availableProducts.push(products[t]['prsku']+":"+products[t]['prname']);
cellPlace.push(t);
t++;
}
$( "#product2" ).autocomplete({
source: availableProducts
});
});
Dynamic create content
function addElement()
{
var contentID = document.getElementById('more');
var newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id','strText'+intTextBox);
newTBDiv.innerHTML ="<br><div class='product'><TABLE><tr>";
newTBDiv.innerHTML += "<td><input type='text' placeholder = 'product_code' name='sku_" + intTextBox + "' id='sku_" + intTextBox + "'/></td><td><input type='text' id='product2' name='product2'></td>;
contentID.appendChild(newTBDiv);
}
<body onload="addElement();">
Try to call your autocomplete function after the addElement function .
OR
simply add
$( "#product2" ).autocomplete({
source: availableProducts
});
these lines at the last of your addElement function like this
function addElement()
{
var contentID = document.getElementById('more');
var newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id','strText'+intTextBox);
newTBDiv.innerHTML ="<br><div class='product'><TABLE><tr>";
newTBDiv.innerHTML += "<td><input type='text' placeholder = 'product_code' name='sku_" + intTextBox + "' id='sku_" + intTextBox + "'/></td><td><input type='text' id='product2' name='product2'></td>;
contentID.appendChild(newTBDiv);
$( "#product2" ).autocomplete({
source: availableProducts
});
}
Call function to bind autocomplete as shown below and remove onload from body.
<body>
NOTE - you have missed " at the end of dynamic element string i.e. after </td>, please correct it.
jQuery(document).ready(function($){
var products= JSON.parse( '<?php echo json_encode($products_list) ?>' );
var t = 0;
var r = '<?php echo json_encode($number_of_rows_tuote) ?>';
var availableProducts = [];
var cellPlace = [];
while(t < r){
availableProducts.push(products[t]['prsku']+":"+products[t]['prname']);
cellPlace.push(t);
t++;
}
$('body').load(function(){
var contentID = document.getElementById('more');
var newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id','strText'+intTextBox);
newTBDiv.innerHTML ="<br><div class='product'><TABLE><tr>";
newTBDiv.innerHTML += "<td><input type='text' placeholder = 'product_code' name='sku_" + intTextBox + "' id='sku_" + intTextBox + "'/></td><td><input type='text' id='Product2' name='product2'></td>";
contentID.appendChild(newTBDiv);
//bind autocomplete
$( "#Product2").autocomplete({
source: availableProducts
});
});
});

how to add Button to a select2 dropdown on a dynamic table

Good day!
I'm doing a Dynamic table which you can add/remove row, and I'm using select2 to search Items on the database via ajax and its working well at the moment, then I want to add another button ("add new item") to my select2's input box. It was also working but when I add another row, the previous rows will have 2 (add new item) buttons on it, and when I add another row something weird is happening on my input box then.
Without adding new rows
After adding new rows
Here is my code:
$(document).ready(function() {
addRow();
});
addRow.js
var rowCount = document.getElementById('tblItemList').rows.length - 1 ;
var rowArrayId = rowCount ;
function addRow(){
var toBeAdded = document.getElementById('toBeAdded').value;
if (toBeAdded=='')
{ toBeAdded = 2; }
else if(toBeAdded>10)
{
toBeAdded = 10;
}
for (var i = 0; i < toBeAdded; i++) {
var rowToInsert = '';
rowToInsert = "<tr><td><input id='itemId"+rowArrayId+"' name='product["+rowArrayId+"][name]' class='form-control col-lg-5 itemSearch' type='text' placeholder='select item' /></td>";
$("#tblItemList tbody").append(
rowToInsert+
"<td><textarea readonly name='product["+rowArrayId+"][description]' class='form-control description' rows='1' ></textarea></td>"+
"<input type='hidden' name='product[" + rowArrayId + "][itemId]' id='itemId'>"+
"<td><input type='number' min='1' max='9999' name='product["+rowArrayId+"][quantity]' class='qty form-control' required />"+
"<input id='poItemId' type='hidden' name='product[" + rowArrayId + "][poContentId]'></td>"+
"<td><input type='number' min='1' step='any' max='9999' name='product["+rowArrayId+"][price]' class='price form-control' required /></td>"+
"<td class='subtotal'><center><h3>0.00</h3></center></td>"+
"<input type='hidden' name='product["+rowArrayId+"][delete]' class='hidden-deleted-id'>"+
"<td class='actions'><a href='#' class='btnRemoveRow btn btn-danger'>x</a></td>"+
"</tr>");
var rowId = "#itemId"+rowArrayId;
$(rowId).select2({
placeholder: 'Select a product',
formatResult: productFormatResult,
formatSelection: productFormatSelection,
dropdownClass: 'bigdrop',
escapeMarkup: function(m) { return m; },
minimumInputLength:1,
ajax: {
url: '/api/productSearch',
dataType: 'json',
data: function(term, page) {
return {
q: term
};
},
results: function(data, page) {
return {results:data};
}
}
});
rowArrayId = rowArrayId + 1;
};
$(".select2-drop").append('<table width="100%"><tr><td class="row"><button class="btn btn-block btn-default btn-xs" onClick="modal()">Add new Item</button></div></td></tr></table>');
function productFormatResult(product) {
var html = "<table><tr>";
html += "<td>";
html += product.itemName ;
html += "</td></tr></table>";
return html;
}
function productFormatSelection(product) {
var selected = "<input type='hidden' name='itemId' value='"+product.id+"'/>";
return selected + product.itemName;
}
$(".qty, .price").bind("keyup change", calculate);
};
Please Help me find solution for this one, been trying to solve this on my own but I cant get it working. Any suggestions, answers and comments would really be appreciated. Thank you very much and have a good day!
In my case I just added this function
formatNoMatches: function( term ) {
$('.select2-input').on('keyup', function(e) {
if(e.keyCode === 13)
{
$("#modalAdd").modal();
$(".select2-input").unbind( "keyup" );
}
});
return "<li class='select2-no-results'>"+"No results found.<button class='btn btn-success pull-right btn-xs' onClick='modal()'>Add New Item</button></li>";
}

Splitting an array

I have two javascript functions, the first one is working, teh second is working but not echoing the correct value in the hidden inputs.
Ive manage to get the last hidden input value correct but I'm not sure how
var customTicketsArr = Array();
function EditEventAddTicket(){
alertWrongTime = false;
var TicketName = jQuery("#ticketname").val();
var TicketPrice = jQuery("#ticketprice").val();
var ticketquantity = jQuery("#ticketquantity").val();
var storeString = "TicketName" + TicketName + "TicketPrice" + TicketPrice + "Quantity" + ticketquantity + '';
customTicketsArr.push(storeString);
EditEventUpdateTickets(true);
}
function EditEventUpdateTickets(fade){
jQuery("#custom_tickets_string").val(customTicketsArr);
var output = "";
var style = "";
for (i = customTicketsArr.length-1; i >= 0; i--){
ticketname = customTicketsArr[i].split("TicketName");
ticketprice = customTicketsArr[i].split("TicketPrice");
ticketquantity = customTicketsArr[i].split("Quantity");
if(fade){
if (customTicketsArr.length - 1 == i){
style = "display: none; ";
var fadeInDiv = i;
} else {
style = "";
}
}
if (i % 2 == 1) { style += "background-color: #660000; "}
html = "<div id='customticket" + i + "' class='customeventbase' style='" + style + "'>";
html += '<input type="hidden" name="customTicketid[' + i + '][Name]" id="customticketName' + i + '" value="'+ ticketname + '" />';
html += '<input type="hidden" name="customTicketid[' + i + '][Price]" id="customticketPrice' + i + '" value="' +ticketprice[1] +'" />';
html += '<input type="hidden" name="customTicketid[' + i + '][Quantity]" id="customticketQuantity' + i + '" value="'+ ticketquantity[1] +'" />';
html += '<button class="customeventdel" type="button" onClick="EditEventRemoveDate(' + i + ')"></button>';
html += '<div class="clear"></div>';
html += '</div>\n';
output += html;
}
output += "<input type='hidden' id='custom_ticket_info' name='custom_ticket_info' value='" + customTicketsArr + "' />";
jQuery("#custom_ticket_container").html(output);
if(fade){
setTimeout("EditEventfadeInDiv(" + fadeInDiv +")", 10);
}
}
this outputs:
<div style="background-color: #660000; " class="customeventbase" id="customticket1">
<input type="hidden" value=",testTicketPrice50Quantity44" id="customticketName1" name="customTicketid[1][Name]">
<input type="hidden" value="undefined" id="customticketPrice1" name="customTicketid[1][Price]">
<input type="hidden" value="44" id="customticketQuantity1" name="customTicketid[1][Quantity]">
<button onclick="EditEventRemoveDate(1)" type="button" class="customeventdel"></button>
<div class="clear"></div></div>
the values for the first two hidden fields are incorrect
They're not incorrect values - split() is doing exactly what it is supposed to - returning an array of substrings after removing the separator.
With your string structure, splitting on TicketName will give you two strings - the substring before the separator and the substring after - TicketName itself is not included.
Thus, for the string "TicketNametestTicketPrice50Quantity44", you will get "" and "testTicketPrice50Quantity44" when you split on "TicketName" . Splitting the same string on TicketPrice will give you "TicketNametest" and "50Quantity44".
I'd suggest putting objects into your array instead -
var storeObject = {
"TicketName" : TicketName,
"TicketPrice" : TicketPrice,
"Quantity" : ticketquantity
};
customTicketsArr.push(storeObject);
You can then get back the data as:
for (i = customTicketsArr.length-1; i >= 0; i--){
var currentObject = customTicketsArr[i];
var ticketname = currentObject.TicketName;
var ticketprice = currentObject.TicketPrice;
var ticketquantity = currentObject.Quantity;
//do other stuff here
}
why do you save it as a string? I would recommend storing it in an object:
function EditEventAddTicket(){
alertWrongTime = false;
var TicketName = jQuery("#ticketname").val();
var TicketPrice = jQuery("#ticketprice").val();
var ticketquantity = jQuery("#ticketquantity").val();
var ticket = {"TicketName": TicketName, "TicketPrice": TicketPrice, "Quantity": ticketquantity};
customTicketsArr.push(ticket);
EditEventUpdateTickets(true);
}
and then you can simply load the data:
for (i = customTicketsArr.length-1; i >= 0; i--){
ticketname = customTicketsArr[i].TicketName;
ticketprice = customTicketsArr[i].TicketPrice;
ticketquantity = customTicketsArr[i].Quantity;
// ...
}
Why not just make a two dimensional array?
var customTicketsArr = Array();
function EditEventAddTicket() {
customTicketsArr.push({
'name' : jQuery("#ticketname").val(),
'price' : jQuery("#ticketprice").val(),
'qty' : jQuery("#ticketquantity").val()
});
}

Categories

Resources