I have a page that uses a couple of AJAX calls to get and update data. A user enters a product number in an input box, then clicks a <button>, which runs a function that has a jQuery AJAX call to populate a div. See below.
HTML
<form rol="form">
<div class="form-group">
<label for="sku" id="sku-label">Please enter the SKU below</label>
<input class="form-control text-center" type="input" id="sku">
<button class="btn btn-primary col-md-12" type="button" id="bClick" onclick="getSku( $( '#sku' ).val() );">Get SKUs</button>
</div>
<input type="hidden" id="badgeNum" value="<?php echo $_SESSION['BADGE_NUMBER']; ?>">
</form>
<div class="col-md-12" id="sku-results"><!--This div gets populated. -->
</div>
jQuery
function getSku(sSku) {
//AJAX call to get SKUs goes here.
$.ajax({
type: 'POST',
url: 'sku-query.php',
async: false,
mimeType: 'json',
//dataType: 'application/json',
data: {sku: sSku},
success: function(data) {
var disp = "";
disp += "<div class='col-md-12' id='skuDisplay'>";
disp += "<div class='col-md-2'><strong>SKU</strong></div>";
disp += "<div class='col-md-3'><strong>Description</strong></div>";
disp += "<div class='col-md-2'><strong>Master</strong></div>";
disp += "<div class='col-md-2'><strong>Daughter</strong></div>";
disp += "<div class='col-md-2 text-center'><strong>Location</strong></div>";
disp += "<div class='col-md-1 text-center'><strong>Update</strong></div>";
disp += "</div>";
counterp = 0;
$.each(data, function(i, data) {
disp += "<div class='col-md-12' id='skuDisplay'>";
disp += "<div class='col-md-2' id='dSku' >" + data[0] + "</div>";
disp += "<div class='col-md-3' id='dDesc'>" + data[1] + "</div>";
disp += "<div class='col-md-2' id='dMast'>" + data[2] + "</div>";
disp += "<div class='col-md-2 text-center' id='dDaughter'>";
disp += "<input class='col-md-6 text-center' type='number' value='"+ data[3] + "' id='dChange'>";
disp += "</div>";
disp += "<input type='hidden' id='oldQty' value='" + data[3] + "'>";
disp += "<div class='col-md-2 text-center' id='dLoc'>" + data[4] + "</div>";
disp += "<div class='col-md-1 text-center'><a class='inv-click' id='" + counterp + "' onclick='updateDaughter(this.id)' value='" + counterp + "'><i class='fa fa-check-square-o'></i></a></div>";
disp += "</div>";
counterp = counterp + 1;
});
//Success function if all goes well.
$( "#sku-results" ).empty();
$( "#sku-results" ).append( disp );
},
error: function() {
alert('There seems to be an error fetching SKUs.');
}
});
}
So the above code works fine. In each div that is appended to the page, there is an <a> element. The purpose of these divs being added is that each div has an input box where the user can change a value. When the value is changed and the a element is clicked, another function, with another AJAX call is run. When the second AJAX call in this function is done running, I need to then run the first function AGAIN to update the page with the updated value. See the second function below.
function updateDaughter(getId)
{
var master = $( "#" + getId ).closest("#skuDisplay").children("#dMast").html();
var daughter = $( "#" + getId ).closest("#skuDisplay").children("#dDaughter").children("#dChange").val();
var loc = $( "#" + getId ).closest("#skuDisplay").children("#dLoc").html();
var oldQty = $( "#" + getId ).closest("#skuDisplay").children("#oldQty").val();
var emp_id = $( "#badgeNum" ).val();
var sku = $( "#" + getId ).closest("#skuDisplay").children("#dSku").html();
var dDate = new Date();
var dDay = ("0" + dDate.getDate() ).slice(-2);
var dMonth = ("0" + dDate.getMonth()).slice(-2);
var dYear = dDate.getFullYear();
var dHour = ("0" + dDate.getHours() ).slice(-2);
var dMin = ("0" + dDate.getMinutes()).slice(-2);
var dSec = ("0" + dDate.getSeconds()).slice(-2);
var dFullDate = dYear + "-" + dMonth + "-" + dDay;
var dFullTime = dHour + ":" + dMin + ":" + dSec;
var dAllDate = dFullDate + " " + dFullTime;
var move_from = "Adjustment";
//var created = date('Y-m-d h:i:s');
var worktype = "Reslot";
var qty = daughter - oldQty;
alert("DATE:" + dAllDate + ". SKU:" + sku + ". MASTER:" + master + ". LOC:" + loc + ". DAUGHTER:" + daughter + ". OLD:" + oldQty + ". EMPID:" + emp_id + ". QTY:" + qty + ". MOVEFROM:" + move_from + ". TYPE:" + worktype);
var workTypeId = "";
if (worktype = 'Putaway') {workTypeId = 1;}
if (worktype = 'RTI') {workTypeId = 2;}
if (worktype = 'Replen') {workTypeId = 3;}
if (worktype = 'Manual Replen'){workTypeId = 4;}
if (worktype = 'Reslot') {workTypeId = 5;}
if (worktype = '01 Replen') {workTypeId = 6;}
if (worktype = '03 Replen') {workTypeId = 7;}
if (worktype = '02 Replen') {workTypeId = 8;}
$.ajax({
type: 'POST',
url: 'http://a/location/that/works',
async: false,
data: JSON.stringify({
workTypeID: workTypeId,
completedDate: dAllDate,
startLocation: move_from,
endLocation: loc,
quantity: qty,
assignedAdministratorID: emp_id,
createdDate: dAllDate,
startedDate: dAllDate,
createdAdministratorID: emp_id,
sku: sku
}),
contentType: 'application/json',
success: function(data) {
if(data.status == 'Success') {
$('#result').text(data.status);
} else {
$('#result').text('Failed on update: ' + data.status + ', ' + data.errorMessage);
}
},
error: function() {
$('#result').text('There might be some problem on the web service. Please contact administrator.');
}
});
$( "#bClick" ).click();
}
What's the problem?
The second function works in that it updates the corresponding database with the information that it needs to update it with. The problem is that I cannot get my page to then reload with the updated information. After I change the value and click the <a> tag, the page runs the first function again but the old value shows up. The only way I can get the new value to show up is if I click on the button with the same product number again.
Upon reading about this, I came across that AJAX will run its own process apart from the rest of your function. So in my second function, if I am calling my first function again, what looks like is happening is that my first function is being called in my second function before the AJAX call is even done.
What I tried
-I figured that I would try adding async: false to both of my jQuery AJAX functions, which did not work.
-I tried running my first function in my second function in various places. Inside of the AJAX success parameter, after the AJAX call altogether, etc... This did not work either.
-I tried to patch this by replacing the old value with the new value in the input box manually (empty() then append()) just to show the user than their changes have "updated", but even this gets overwritten by the old data (which is not even there anymore because of the second AJAX call). The AJAX call is getting "outraced" by the rest of the function, it seems.
-I tried just triggering the button to be "clicked" again inside, and after the second AJAX call by $( "#bClick" ).click();. Same thing. Didn't work.
What I need
This is what I need to happen:
-The user types a product number (works)
-The user clicks a button (works)
-The button triggers a function that runs an AJAX call to populate the page with info; each row of info has an input box with a number that can be changed, and an <a> button that will run another function. (works)
-When the <a> button is clicked, another function is run that has another AJAX call that updates a database with information, including the changed value in the input box. (works)
-Inside of the second function, after the AJAX call is run, the first function with the first AJAX call should be run again to update the page with the changed information. (does not work)
Can someone help me figure this out?
Related
I have displayed records from MySQL database. After displaying records added javascript onclick function. It works only for the first record and not works for other records.
In the above image, I clicked the first link which works fine. But if I click second click nothing happens.
<script>
function Confirm(title, msg, $true, $false, $link) {
/*change*/
var $content =
"<div class='dialog-ovelay'>" +
"<div class='dialog'><header>" +
" <h3> " +
title +
" </h3> " +
"<i class='fa fa-close'></i>" +
"</header>" +
"<div class='dialog-msg'>" +
" <p> " +
msg +
" </p> " +
"</div>" +
"<footer>" +
"<div class='controls' style='text-align:right'>" +
" <button class='button button-danger doAction'>" +
$true +
"</button> " +
" <button class='button button-default cancelAction'>" +
$false +
"</button> " +
"</div>" +
"</footer>" +
"</div>" +
"</div>";
$("body").prepend($content);
$(".doAction").click(function() {
$(this)
.parents(".dialog-ovelay")
.fadeOut(500, function() {
var subtotal = document.getElementById("subtotal").innerHTML;
var price = "<?php echo $price ;?>";
var subtotal = +subtotal + +price;
var totalitems = document.getElementById("totalitems").innerHTML;
var totalitems = +totalitems + +1;
document.getElementById("totalitems").innerHTML = totalitems;
document.getElementById("subtotal").innerHTML = subtotal.toFixed(2);
var total = +subtotal + +8 + +4;
document.getElementById("total").innerHTML = total.toFixed(2);
$(this).remove();
});
});
$(".cancelAction, .fa-close").click(function() {
$(this)
.parents(".dialog-ovelay")
.fadeOut(500, function() {
$(this).remove();
});
});
}
$("#linkdup").click(function() {
Confirm(
"Are you sure you want to Duplicate Frame",
"One more frame will be added to Cart",
"Yes",
"No"
); /*change*/
});
</script>
You are working with IDs here. An ID is unique, if you query it, you will get one result (the first).
Example:
// This selects one
const result = document.getElementById('myId').innerHTML;
console.log(result);
// This selects all
const elements = document.querySelectorAll('[id=myId]');
elements.forEach(function(element) {
console.log(element.innerHTML);
// add click event to element here
});
<div id="myId">Test 1</div>
<div id="myId">Test 2</div>
Use classes for this. Using an ID multiple times is invalid, even though you can make it work as shown in example.
With the code below I am trying to update PartialView's HTML.
open_Modal_AssignAmendRoles = function (url) {
$.ajax({
url: url,//PartialView URL
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
var modalhtml = data;
var result = datafetchfunction("action URL", )
if (result.compleate == true) {
result.data.employeeroles.forEach(function (roletype) {
var tagbox = $(modalhtml).find("#tagbox" + roletype.clientroletypeid);
var span = $(modalhtml).find("#rolecontainer" + roletype.clientroletypeid);
var roletypeid = roletype.clientroletypeid
roletype.roles.forEach(function (role) {
var roleid = role.FK_ClientRoleID
var roledescription = role.ClientRole_Description;
var rolecode = role.ClientRole_Code
var markup = ""
markup += " <li class='taglist' id='" + roleid + "'>"
markup += " <button onclick='$(this).parent().remove()' class='tagclose'>"
markup += " <span class='glyphicon glyphicon-remove' aria-hidden='true'></span>"
markup += " </button>"
markup += " <a class='assignedrole' href='Javascript:void(0);' onclick='pop_click_fn(this)'"
markup += " role-id='" + roleid + "' role-type-id=" + roletypeid + ""
markup += " data-toggle='popover' data-trigger='hover' data-content='" + roledescription + "' data-placement='top' > " + rolecode + " </a>"
markup += " </li>";
$(span).append(markup)
})
})
openModal( modalhtml);
}
}
});
}
Step 1:
On button click the open_Modal_AssignAmendRoles() function is called. Then it goes to the success() function.
Step 2:
var result = datafetchfunction("action URL" )
this fetch data as JSON format
Step 3:
Then I start some loop, I already create some spans and find them with
var span = $(modalhtml).find("#rolecontainer" + roletype.clientroletypeid);
Step 4:
then I build a markup and assign this
$(span).append(markup)
and finally, call
openModal( modalhtml);
But modalhtml is not updated as expected, it means lis which I created with loop is not added.
Can someone tell me what is the problem and how to solve this?
Hi All i have a quick question about JSON data into href for AJAX
I have JSON coming into AJAX example data[i].listingid
How do i put that into a href inside the ajax?
Below are my codes, it will explain the situation more clearly.
Thanks for your time
<script>
$.ajax({
type: "GET",
url: "listing.php",
dataType: 'json',
success: function (data) {
for (var i = 0; i < data.length; i++) {
console.log(data)
var listingid = data[i].listingid;
var myOtherUrl =
"SpecificListing.html?Listingid=" + encodeURIComponent(listingid);
var html1 = "<div class=two> Listing Address : " + data[i].address + "<a href=myOtherurl>" +
data[i].listingid + "Click to view the details" + "</div>" +
"</a>"
$('#display12').append(html1);
}
}
});
</script>
You can straightly add it with concatenation like below :
var html1 = "<div class=two> Listing Address : " + data[i].address +
"<a href='"+ myOtherurl + "'>"+
data[i].listingid+"Click to view the details" + "</a></div>";
or else you can use jquery attr method after you finish with appending html to div like below:
var listingid = data[i].listingid;
var myOtherUrl = "SpecificListing.html?Listingid=" + encodeURIComponent(listingid);
var html1 = "<div class=two> Listing Address : " + data[i].address +
"<a id='hrefholder' >"+
data[i].listingid+"Click to view the details" + "</a></div>";
$('#display12').append(html1);
$('#hrefholder').attr("href",myOtherurl );
Tip : Don't forget to add id to anchor tag
Here's a cleaned up version of your callback (I try to avoid string concatenation for HTML as much as possible):
var successCallback = function(data) {
var baseUrl = 'SpecificListing.html?Listingid=';
for (var i=0; i<data.length; i++) {
var listingId = data[i].listingid;
var newUrl = baseUrl + encodeURIComponent(listingId);
var $newDiv = $('<div />').addClass('two');
var $newLink = $('<a />')
.attr('href', newUrl)
.text(listingId + ': Click to view details');
$newDiv.append($newLink);
$('#display12').append($newDiv);
}
};
Find a full working implementation including simulated AJAX call here:
http://jsfiddle.net/klenwell/N2k8X/
var html1 = "<div class=two> Listing Address : " + data[i].address + "<a href=myOtherurl>" + data[i].listingid+"Click to view the details" + "</a></div>";
Will work. Are u binding ajax event to this link?
Anjith and Orion are both right but ya'll have a typo:
the variable in your definition is called myOtherUrl but inside your concatenated string it is myOtherurl. Variables are case-sensitive.
your variable will be parsed as a variable if you leave your double quotes around it so it's good as is
BACKGROUND
My app consist of 2 static pages and x number of dynamically generated pages. The number of dynamically generated pages varies from time to time. My first static page is a login page. Once you login you are taken to the 2nd static page which is a welcome screen and then you can start swiping left to view the dynamically generated pages.
What i want to achieve
I basically want to get the page id of the currently active page. As in i want to get the id of the page i am currently viewing. i tried the following
pageId = $('body').pagecontainer('getActivePage').prop("id");
console.log('==========================>THIS IS ID: '+pageId);
It only gives me the page id of the 2nd static page and not the id of the dynamically generated pages because when i swipe left to view my dyanamically generated pages the console log does not print at all.
Here is the code for the entire relevant js
var widgetNames = new Array();
var widgetId = new Array();
//ActivePageId
var pageId = ''
$(document).on("pagecreate", function () {
$("body > [data-role='panel']").panel().enhanceWithin();
});
$(document).on('pagecreate', '#page1', function () {
$("#log").on('click', function () {
$.ajax({
url: "script.login",
type: "GET",
data: {
'page': 'create_user',
'access': 'user',
'username': $("input[name='username']").val(),
'password': $("input[name='password']").val()
},
dataType: "text",
success: function (html) {
console.log(html);
widgetNames = new Array();
widgetId = new Array();
var res = html.match(/insertNewChild(.*);/g);
for (var i = 0; i < res.length; i++) {
var temp = res[i].split(',');
if (temp.length >= 3) {
widgetNames[i] = (temp[2].replace('");', '')).replace('"', '');
widgetId[i] = temp[1].replace("'", "").replace("'", "").replace(/ /g, '');
}
}
var AllWidgets = ''
var testwidget = new Array();
var tempWidgetContent = html.match(/w\d+\.isHidden(.*)\(\) == false\)[\s\S]*?catch\(err\)\{ \}/gm);
for (var i = 0; i < tempWidgetContent.length; i++) {
var widgetContent = tempWidgetContent[i].substring(tempWidgetContent[i].indexOf('{') + 1);
testwidget[i] = widgetContent.replace("site +", "");
}
var widgetPart = new Array();
for (var i = 0; i < widgetNames.length; i++) {
var pageHeaderPart = "<div data-role='page' id='" + widgetId[i] + "' data-pageindex='" + i + "' class='dynPageClass'><div data-role='header' data-position='fixed'><a data-iconpos='notext' href='#panel' data-role='button' data-icon='flat-menu'></a><h1>BASKETBALL FANATICO</h1><a data-iconpos='notext' href='#page2' data-role='button' data-icon='home' title='Home'>Home</a></div> <div data-role='content'>";
var pageFooterPart = "</div><div data-role='footer' data-position='fixed'><span class='ui-title'><div id='navigator'></div></span></div></div>";
var check = "<div data-role='content'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='b'>" + widgetNames[i] + "</div>";
widgetPart[i] = '<DIV style=\" text-align: center; background-color:#989797; font-size: 75pt;\" id=widgetContainer_' + widgetId[i] + '></DIV><SCRIPT>' + 'function UpdateWidgetDiv' + widgetId[i] + '() {' + testwidget[i] + '$(\"#widgetContainer_' + widgetId[i] + '").html(counterValue);' + '}' + 'setInterval(function(){UpdateWidgetDiv' + widgetId[i] + '()},3000)' + '</SCRIPT>';
AllWidgets += '<a href="#' + widgetId[i] + '" class="widgetLink" data-theme="b" data-role="button" >' + widgetNames[i] + '</a>';
var makePage = $(pageHeaderPart + check + widgetPart[i] + pageFooterPart);
makePage.appendTo($.mobile.pageContainer);
}
$('#items').prepend(AllWidgets).trigger('create');
//Get Active Page ID
$( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) {
pageId = $('body').pagecontainer('getActivePage').prop("id");
alert( "The page id of this page is: " + pageId );
});
}
});
});
});
Please advise and sorry if it is a bad question to ask as I am a beginner.
You were getting the active page from within the ajax call, not when swiping to a new page.
The detection code needs to fire when you are on one of the dynamic pages, show you could use pagecontainershow to detect the pageID as soon as the page displays (http://api.jquerymobile.com/pagecontainer/#event-show).
$( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) {
pageId = $(":mobile-pagecontainer" ).pagecontainer('getActivePage').prop("id");
});
UPDATE: Using pageid when updating pages:
It looks like you want an update every 3 seconds on the active page. so create a function for the entire page:
function UpdateActivePage(){
//get active page
pageId = $(":mobile-pagecontainer" ).pagecontainer('getActivePage').prop("id");
//figure out index
var idx;
for (var i=0; i<widgetId.length; i++){
if (widgetId[i] == pageid){
idx = i;
break;
}
}
//run your update
eval(testwidget[idx]);
$("#widgetContainer_" + pageid).html(updated stuff);
}
setInterval(UpdateActivePage, 3000);
I'm trying to make a request/reply section in my project.
I want to achieve these functionality in that code (that I'm not able to implement; so guys please help me out):
1> When user click on reply button; other reply area(text-area +button) should be hide (means at a time only one reply area should be visible to the user).
2> when user click on reply button text-area will focus and page will slide down (suppose user reply 10 comment focus will automatically set to the 10 number text area and page will slide down to that position accordingly).
Here is my so far code guys:
//method call on the click of reply link.
function linkReply_Clicked(issueId) {
Id = issueId;
textId = "text_" + issueId + count;
btnReply = "btnReply_" + issueId + count;
btnCancel = "btnCancel_" + issueId + count;
var textareasArray = document.getElementsByTagName("textarea");
var btnArray = document.getElementsByTagName("input");
for (i = 0; i < textareasArray.length; i++) {
textareasArray[i].style.display = "none";
btnArray[i].style.display = "none";
}
var str = "<table cellpadding='3' cellspacing='0' width='58%'>";
str += "<tr><td valign='top' align='left'>";
str += "<textarea id=" + textId + " rows='5' cols='60'></textarea>";
str += "</td></tr>";
str += "<tr><td valign='top' align='right'>";
str += "<input id=" + btnReply + " type='button' onclick='btnReply_Clicked(Id ,textId)' value='Reply' /> ";
str += "<input id=" + btnCancel + " type='button' onclick='btnCancel_Clicked(Id ,textId)' value='Cancel' /> ";
str += "</td></tr>";
str += "</table>";
document.getElementById("divOuter_" + issueId).innerHTML = str;
$("#" + textId + "").focus();
}
// submit user reply and try to hide that reply area.
function btnReply_Clicked(issueId, textID) {
var comment = document.getElementById(textID).value;
if (comment != '') {
$.getJSON("/Issue/SaveComment", { IssueId: issueId, Comment: comment }, null);
$("#text_" + issueId + count).hide();
$("#btnReply_" + issueId + count).hide();
$("#btnCancel_" + issueId + count).hide();
document.getElementById(textID).value = '';
count = count + 1;
}
}
// cancel user reply and try to hide that reply area.
function btnCancel_Clicked(issueId, textId) {
$("#text_" + issueId + count).hide();
$("#btnReply_" + issueId + count).hide();
$("#btnCancel_" + issueId + count).hide();
document.getElementById(textId).value = '';
count = count + 1;
}
I changed a bit of this because you can do it much easier since you're already using jQuery :)
Go here for the demo version
You can replace all of your posted code with this:
function linkReply_Clicked(issueId) {
$(".replyTable").hide();
var tbl = $("<table class='replyTable' cellpadding='3' cellspacing='0' width='58%'></table>");
tbl.append("<tr><td valign='top' align='left'><textarea rows='5' cols='60'></textarea></td></tr>");
tbl.append("<tr><td valign='top' align='right'><input type='button' class='reply' value='Reply' /> <input type='button' class='cancel' value='Cancel' /> </td></tr>");
tbl.find(".reply").click(function() {
var comment = $(this).closest("table").find("textarea").val();
if (comment != '') {
$.getJSON("/Issue/SaveComment", { IssueId: issueId, Comment: comment }, null);
$(this).closest("div").empty();
}
}).siblings(".cancel").click(function() {
$(this).closest("div").empty();
});
var div = $("#divOuter_" + issueId).empty().append(tbl);
$('html, body').animate({ scrollTop: $(div).offset().top }, 500,
function() { div.find("textarea").focus(); });
}
This does the following things differently with the slide effect & the hiding and scrolling from the question:
Click handlers for reply/cancel buttons are now in-line, no need for extra functions
The inputs no longer have IDs you need to track, it just finds them relatively
Table has a class replyTable so it all old ones can be hidden quickly
Inputs have classes to find them easier (to bind the click handlers)
No more count, no need :)
Animates the body, does a quick scroll effect to the location and focuses the text area
Removes old tables to cleanup