, I have a slider on my html page which has a databind to an observable.
Like this.
<input id="ex2" data-slider-id="ex2Slider" type="text" data-bind="sliderValue: {value: borrowOrInvestAmount, min:0, max: 5000, step: 1, formatter:formatter2}"
style="display: none;">
And as well as I have a table which shows interest like this.
<td <input data-bind=" valueUpdate: 'afterkeydown'"><input data-bind="value: amount1"/></td>
Basically what I want is that, when I change the value on the slider, it should call this function which takes in value from the observable borrowOrInvestAmount
and should return the interest rate which will be put into the observable and shown on the table. And each time the slider value changes it should call this function again.
function DoBusinessViewModel(root) {
var self = this;
self.items = ko.observableArray();
self.itemsNotFoundMsg = ko.observable(null);
var borrowOrInvestAmount_tmp = 0;
var moneyBorrOrInvUri;
if (root.boolInvestments()) {
moneyBorrOrInvUri = BASEURL + 'index.php/moneyexchange/SearchRequestsOrInvestments/' + auth + '/' + root.borrowOrInvestAmount() + '/' + root.borrowOrInvestCurrency() + '/' + 0 + '/' + 1;
} else {
moneyBorrOrInvUri = BASEURL + 'index.php/moneyexchange/SearchRequestsOrInvestments/' + auth + '/' + root.borrowOrInvestAmount() + '/' + root.borrowOrInvestCurrency() + '/' + 0 + '/' + 0;
}
$.ajax({
type: 'GET',
url: moneyBorrOrInvUri,
contentType: 'application/json; charset=utf-8'
})
.done(function(BorrowOrInvestDetails) {
$.each(BorrowOrInvestDetails, function (index, item) {
self.items.push(item);
/* here is where I am trying to get the value of interest from for the table*/
self.interest(self.item()[0].Interest);
borrowOrInvestAmount_tmp += parseFloat(item.borrowOrInvestAmount);
/* If we are reading borrowing request and thee are any requests with payment_term = 2 = Monthly,
* we must set root.paymentTerm observable to 2 = Monthly. */
if (!root.boolInvestments()) {
if (item.payment_term == 2) {
if (root.paymentTerm() == 1) {
root.paymentTerm(2);
}
}
}
});
root.borrowOrInvestAmount(borrowOrInvestAmount_tmp.toFixed(2));
root.borrowOrInvestAbbreviation(self.items()[0].Abbreviation);
if (root.boolInvestments()) {
root.getFee(root.borrowOrInvestAmount(), root.borrowOrInvestCurrency(), 'money_request', 'borrow');
} else {
root.getFee(root.borrowOrInvestAmount(), root.borrowOrInvestCurrency(), 'money_offer', 'invest');
}
root.getPaymentPlanForMultibleItems(self.items());
})
.fail(function(jqXHR, textStatus, errorThrown) {
self.itemsNotFoundMsg(errorThrown);
})
.always(function(data){
});
};
Since I added the value borrowOrInvestAmount to the slider I Am not sure if its actually calling the dobusinessfunction. Dont know what I am missing.
Related
I have a small weather app. I get the weather data via "POST" request and append it to the document, that works good.
The users can query the weather by City, now I wanted to load an image of that city with a separate jQuery $Ajax() request.
However, I always get the same result.
The app relevant app structure looks like this:
<input id="getIt" name="cityajax" type="text" class="ghost-input"
placeholder="Enter a City" required> // get user input, querying a city
<button id="submit">Submit</button>
<span class="humidLogo">Current humidity:</span> <i class="fas fa-temperature-low" ></i> <span class="apiHumidity"> % </span>
<div class="FlickResponse"></div> // flickrResposnse gets appended here
</div>
The CSS is not relevant, so I follow up with the relevant JS function right away:
var destination = $("#getIt").val(); // cache the user input, I am not sure I have to listen for a change event here and then update the state.
var flickerAPI =
"https://api.flickr.com/services/feeds/photos_public.gne?format=json&tags=" +
destination; // the url to get access the api
$.ajax({
url: flickerAPI,
dataType: "jsonp", // jsonp
jsonpCallback: "jsonFlickrFeed", // add this property
success: function(result, status, xhr) {
$(".FlickResponse").html(""); // here I want to empty the contents of the target div, but this never happens
$.each(result.items, function(i, item) {
$("<img>")
.attr("src", item.media.m)
.addClass("oneSizeFitsAll")
.appendTo(".FlickResponse");
if (i === 1) {
return false;
}
});
},
error: function(xhr, status, error) {
console.log(xhr);
$(".FlickResponse").html(
"Result: " +
status +
" " +
error +
" " +
xhr.status +
" " +
xhr.statusText
);
}
});
That is all. So why do I always get the same response from the API? Do I have to listen to change events on the input field? Because the POSt request work without a change event listener.
Is it because I am querying 2 APIs and I am using the same input field for the value(stupid question, but you never know x).?
Here is a Codepen with the full code, just enter a city and click the submit button:
https://codepen.io/damPop/pen/qLgRvp?editors=1010
I would pull the image retrieval (and weather lookup) into another function as shown below, then you're good!
I've forked to another codepen: updated example
function loadDestinationImage() {
var destination = ($("#getIt").val());
var flickerAPI = "https://api.flickr.com/services/feeds/photos_public.gne?format=json&tags=" + destination;
$.ajax({
url: flickerAPI,
dataType: "jsonp", // jsonp
jsonpCallback: 'jsonFlickrFeed', // add this property
success: function (result, status, xhr) {
$(".FlickResponse").html("");
$.each(result.items, function (i, item) {
$("<img>").attr("src", item.media.m).addClass("oneSizeFitsAll").appendTo(".FlickResponse");
if (i === 1) {
return false;
}
});
},
error: function (xhr, status, error) {
console.log(xhr)
$(".FlickResponse").html("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText)
}
});
}
I'd do the same with the weather:
function loadWeather() {
var destination = ($("#getIt").val());
$.post("https://api.openweathermap.org/data/2.5/weather?q=" +
destination +
"&units=metric&appid=15c9456e587b8b790a9092494bdec5ff",
function (result, status, xhr) {
var APIresponded = result["main"]["temp"];
var APIweather = result["weather"][0]["description"];
var sunGoing = result["sys"]["sunset"];
var output = destination.capitalize();
var humidValue = result["main"]["humidity"];
var windy = result["wind"]["speed"];
var windDirection = result["wind"]["deg"];
if (windDirection <= 90) {
windDirection = "southwest"
}
if (windDirection <= 180) {
windDirection = "northwest"
}
if (windDirection <= 270) {
windDirection = "northeast"
}
if (windDirection <= 360) {
windDirection = "southeast"
}
if (APIweather.includes("snow")) {
$('#displaySky').addClass('far fa-snowflake');
}
if (APIweather.includes("rain")) {
$('#displaySky').addClass('fas fa-cloud-rain');
}
if (APIweather.includes("overcast")) {
$('#displaySky').addClass('fas fa-smog');
}
if (APIweather.includes("sun") || APIweather.includes("clear")) {
$('#displaySky').addClass('fas fa-sun');
}
if (APIweather.includes("scattered")) {
$('#displaySky').addClass('fas fa-cloud-sun');
}
$("#message").html("The temperature in " + output + " is : " + APIresponded + " degrees. The sky looks like this: ");
$(".apiHumidity").text(humidValue + " %");
$('.apiWind').html(windy + 'km per hour. The wind direction is ' + windDirection);
console.log(APIweather);
}
).fail(function (xhr, status, error) {
alert("Result: " + status + " " + error + " " +
xhr.status + " " + xhr.statusText);
});
}
And call from the submit function:
$("#submit").click(function (e) {
loadDestinationImage();
loadWeather();
});
Consider the following JQuery loop. It appends this:
"<div id='1'>" + feedback + "</div>"
1st Question.
I want to increment the id of the appended div after the first one has been appended so that the first appended div's id is 1, the second div's id is 2 and so on.
2nd Question.
When the number of divs reaches 10, I want to delete the first appended div. Which in our case is:
<div id="1">php result</div>
This should keep looping and deleting older divs.
Here's the Jquery ajax loop:
new get_fb();
function get_fb(){
var feedback = $.ajax({
type: "POST",
url: "algorithm.php",
async: false
}).success(function(){
setTimeout(function(){get_fb();}, 8000);
}).responseText;
$('#BuzFeed').append("<div id='1'>" + feedback + "</div>");
}
For counting:
var get_fb = (function() {
var counter = 1;
return function(){
var feedback = $.ajax({
...
}).responseText;
$('#BuzFeed').append("<div id='" + counter + "'>" + feedback + "</div>");
}
})();
get_fb();
and for automatic removal, after
var $buzfeed = $('#BuzFeed').append("<div id='" + counter + "'>" + feedback + "</div>");
add
var $buzfeedDivs = $buzfeed.children('div');
if ($buzfeedDivs.length > 10) { $buzfeedDivs.first().remove(); }
Additionally, your code uses some not-so-good practices. The re-write, including my additions would be:
var get_fb = (function() {
var counter = 0;
var $buzfeed = $('#BuzFeed');
return function(){
$.ajax({
type: "POST",
dataType: "html", // based on chat
url: "algorithm.php"
}).done(function(feedback) {
counter += 1;
var $buzfeedresults = $("<div id='BuzFeedResult" + counter + "'></div>");
$buzfeedresults.text(feedback);
$buzfeed.append($buzfeedresults);
var $buzfeedDivs = $buzfeed.children('div');
if ($buzfeedDivs.length > 10) { $buzfeedDivs.first().remove(); }
setTimeout(get_fb, 8000);
}).fail(function(jqXhr, textStatus, errorThrown) {
var $buzfeedresults = $("<div id='BuzFeedError'></div>");
$buzfeedresults.text('Error: ' + textStatus);
if (typeof console !== 'undefined') {
console.error(jqXhr, textStatus, errorThrown);
}
});
};
})();
get_fb();
I have web methods that are called via AJAX in a .Net 4.0 web app. In many cases, the AJAX calls are made repeatedly in a for loop. My problem is, the information the web method is syncing to my server is time stamped and therefore must be synced in the order in which I am sending it to AJAX. Unfortunately, it seems whatever finishes first, simply finishes first and the time stamps are all out of order. I need to basically queue up my AJAX requests so that they execute in order rather than Asynchronously, which I know is the A in AJAX so this might be a totally dumb question.
How do I force the order of execution for AJAX calls done in a for loop?
Edit: Some code
for (var i = 0; i < itemCnt - 1; i++) {
try {
key = items[i];
item = localStorage.getItem(key);
vals = item.split(",");
type = getType(key);
if (type == "Status") {
var Call = key.substring(7, 17);
var OldStat = vals[0];
var NewStat = vals[1];
var Date1 = vals[2];
var Time1 = vals[3];
var miles = vals[4];
try {
stat(Call, OldStat, NewStat, Date1, Time1, miles, key);
}
catch (e) {
alert("Status " + e);
return;
}
}
else if (type == "Notes") {
var Call = key.substring(6, 16);
var Notes = item;
try {
addNotes(Call, Notes);
}
catch (e) {
alert("Notes " + e);
return;
}
}
else if (key == "StartNCTime" || key == "EndNCTime") {
var TechID = vals[0];
var Date = vals[1];
var Time = vals[2];
var Activity = vals[3];
var Location = vals[4];
var Type = vals[5];
try {
logTime(TechID, Date, Time, Activity, Location, Type,
}
catch (e) {
alert(key + ' ' + e);
return;
}
}
}
catch (e) {
alert(key + ' ' + e);
return;
}
}
function stat(Call, OldStat, NewStat, Date1, Time1, miles, key) {
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
url: "Service.asmx/update_Stat",
data: '{ CallNumber:"' + Call + '", OldStat:"' + OldStat + '", NewStat:"' + NewStat + '", Date1:"' + Date1 + '", Time1:"' + Time1 + '", Miles: "' + miles + '"}',
success: function (data) { },
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert("Sync Update Stat: " + err.Message);
location = location;
}
});
}
function logTime(TechID, Date, Time, Activity, Location, Type, key) {
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
url: "Service.asmx/nonCallTime",
data: '{ TechID:"' + TechID + '", Date1:"' + Date + '", Time1:"' + Time + '", Activity:"' + Activity + '", Location:"' + Location + '", Type: "' + Type + '"}',
success: function (data) { },
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert("Sync Non Call Time: " + err.Message);
location = location;
}
});
}
function addNotes(Call, Notes) {
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
url: "Service.asmx/addNote",
data: '{ Call:"' + Call + '", Notes:"' + Notes + '"}',
success: function (data) { },
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert("Sync Notes: " + err.Message);
location = location;
}
});
}
You have to use callbacks.
function ajax1(){
//..some code
//on ajax success:
ajax2();
}
//etcetera...
Or might I suggest using a javascript library like jQuery to synchronize your ajax requests for you.
set the third parameter in xmlhttp object's open method to false to make it synchronous.
http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
A general pattern for making actions serial would be such:
function doAjax(data, cb) {
...
// when ready call cb
}
(function (next) {
var xhr = doAjax(data, next);
})(function (next) {
var xhr = doAjax(data, next);
})(function (next) {
doAjax(data);
});
Doing so in a for loop would require recursion.
(function next() {
if ( i < n ) {
doAjax(data[i++], next);
}
})();
i created a jquery autocomplete it work true, but loading LOADING... it after removed value by Backspace don't work true. it not hide and Still is show.
how can after removed value by Backspace, hide LOADING... ?
EXAMPLE: Please click on link and see problem
my full code:
$(document).ready(function () {
/// LOADING... ///////////////////////////////////////////////////////////////////////////////////////
$('#loadingDiv')
.hide() // hide it initially
.ajaxStart(function() {
$(this).show();
})
.ajaxStop(function() {
$(this).hide();
});
/// autocomplete /////////////////////////////////////////////////////////////////////////////////////////
$('.auto_complete').keyup(function () {
var specific = '.' + $(this).closest('div.auto_box').find('b').attr('class');
var cl_list = '.' + $(this).closest('div.auto_box').find('ul').attr('class');
var id = '#' + this.id;
var url = $(id).attr('class');
var dataObj = $(this).closest('form').serialize();
$.ajax({
type: "POST",
dataType: 'json',
url: url,
data: dataObj,
cache: false,
success: function (data) {
//alert(url)
var cl_list = '.' + $('.auto_box '+ specific +' ul').attr('class');
var id_name = $(cl_list).attr('id');
$(cl_list).show().html('');
if (data == 0) {
$(cl_list).show().html('<p><b>There is no</b></p>');
}
else {
$.each(data, function (a, b) {
//alert(b.name)
$('<p id="' + b.name + '">' + b.name + '</p>').appendTo(cl_list);
});
$(cl_list + ' p').click(function (e) {
e.preventDefault();
var ac = $(this).attr('id');
$('<b>' + ac + '، <input type="text" name="'+id_name+'[]" value="' + ac + '" style="border: none; display: none;" /></b>').appendTo($('.auto_box ' + specific + ' span'));
$(this).remove();
return false;
});
$('.auto_box span b').live('click', function (e) {
e.preventDefault();
$(this).remove();
return false;
});
}
if ($(specific + ' input').val() == '') {
$(cl_list + " p").hide().remove();
$(cl_list).css('display','none');
$(".list_name").show().html('');
};
$('body').click(function () {
$(cl_list + " p").hide().remove();
$('.auto_complete').val('');
$(cl_list).show().html('');
$(cl_list).css('display','none')
});
},
"error": function (x, y, z) {
// callback to run if an error occurs
alert("An error has occured:\n" + x + "\n" + y + "\n" + z);
}
});
});
});
I recommend you to use jsfiddle next time you post code examples in a link.
Nevermind. The "loading" message keeps there because there's no fallback to empty values on results.
A quick fix could be just by test that there's a value in the input before making any post like if(this.value == ""){
$(cl_list).css('display', 'none');
return false;
}
Here's how it works with it
Sorry about the odd question wording. In all honesty I'm in right at the deep end here, having to learn a huge amount all at once.
I'm trying to figure out how to perform an asynchronous search on a database using AJAX, but it keeps coming up with a "500 internal server error". I've done some AJAX tutorials but none of them involve the MVC method of web development. I'm a bit lost with what information needs to be sent where, and how.
All I know is that a 500 Server Error means it's happening on the server side rather than the client side, so I presume there's a break in logic at the point where the controller starts to get involved. That's just a newbie guess though.
I'll paste all of what I believe to be the relevant code. For context, the database info is from an 'accounts' table in a mock bank database I've been working with for practice.
Thanks for any help.
Firstly, here's the error information I get when looking at debug info on Chrome
Now here's the code involved.
Javascript/JQuery:
var $j = jQuery.noConflict();
var key = 0;
$j(function () {
$j("#search_btn").click(function () {
key = $j("#acc-id-search").val();
searchAcc();
return false;
})
});
function searchAcc() {
var callback = function (data) {
$j("#account_data_table").empty();
var htmlArray = [];
if (data.total > 0) {
$j.each(data.items, function (i, item) {
htmlArray.push("<tr>");
htmlArray.push('<td class="text-center">' + item.account_id + '</td>');
htmlArray.push('<td class="text-center">' + item.product_id + '</td>');
htmlArray.push('<td class="text-center">' + item.cust_id + '</td>');
htmlArray.push('<td class="text-center">' + item.open_date + '</td>');
htmlArray.push('<td class="text-center">' + item.close_date + '</td>');
htmlArray.push('<td class="text-center">' + item.last_activity_date + '</td>');
htmlArray.push('<td class="text-center">' + item.status + '</td>');
htmlArray.push('<td class="text-center">' + item.open_branch_id + '</td>');
htmlArray.push('<td class="text-center">' + item.open_emp_id + '</td>');
htmlArray.push('<td class="text-center">' + item.avail_balance + '</td>');
htmlArray.push('<td class="text-center">' + item.pending_balance + '</td>');
htmlArray.push("</tr>");
});
}
else {
htmlArray.push('<tr><td colspan="10">No results!</td></tr>');
}
$j("#account_data_table").append(htmlArray.join(''));
alert("Sucess?");
};
alert("Searching for '" + key + "'");
postData('#Url.Content("~/Accounts/Index")', key, callback, '#account_data_table');
}
function postData(url, data, callback, lockObj, dataType, loadingMessage)
{
data = data || {};
dataType = dataType || 'json';
loadingMessage = loadingMessage || 'Loading...';;
var isLock = !!lockObj;
$.ajax({
url: url,
data: data,
method: 'post',
dataType: dataType,
cache: false,
beforeSend: function(){
alert("About to send");
},
success: callback,
error: function(){
alert("Failed..!");
},
complete: function(){
}
});
}
The controller that '#Url.Content("~/Accounts/Index")' points to:
[HttpPost]
public NewtonJsonResult Index(int key)
{
var _service = new BankEntities();
var searchCondition = new account() { account_id = key };
var resultObj = new AjaxDataResult();
var allitems = _service.All(searchCondition);
var itemArray = new JArray();
resultObj.total = allitems.Count();
JObject temp;
foreach(var item in allitems)
{
temp = new JObject();
temp["account_id"] = item.account_id;
temp["product_cd"] = item.product_cd;
temp["cust_id"] = item.cust_id;
temp["open_date"] = item.open_date;
temp["close_date"] = item.close_date;
temp["last_activity_date"] = item.last_activity_date;
temp["status"] = item.status;
temp["open_branch_id"] = item.open_branch_id;
temp["open_emp_id"] = item.open_emp_id;
temp["avail_balance"] = item.avail_balance;
temp["pending_balance"] = item.pending_balance;
itemArray.Add(temp);
}
resultObj.items = itemArray;
return new NewtonJsonResult(resultObj);
}
The 'All(searchcondition)' method which is used to find the required items in the table:
public List<account> All(account acc)
{
var data = accounts.Where(x => x.status == "ACTIVE");
if(acc.account_id != 0)
{
data = data.Where(x => x.account_id == acc.account_id);
}
return data.OrderBy(x => x.account_id).ToList();
}
Special thanks to #nnnnnn whose answer lies in the comments after the initial question:
The method might not be called because you're not setting the right
request parameters, so no method exists for the request hence the 500
error. Your current code is trying to include the key value without
giving it a request parameter name. Try changing key =
$j("#acc-id-search").val(); to key = { key: $j("#acc-id-search").val()
};. (The actual request would then end up with a parameter
key=thesearchvaluehere.)