I'm developping an ASP MVC application that use Globalize.js. In the _Layout.cshtml I added this code
<script>
(function () {
$(function () {
$.when(
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/likelySubtags.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/main/fr/numbers.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/numberingSystems.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/main/fr/ca-gregorian.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/main/fr/timeZoneNames.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/timeData.json")"),
$.getJSON("#Url.Content("~/Scripts/cldr/supplemental/weekData.json")")
).then(function () {
// Normalize $.get results, we only need the JSON, not the request statuses.
return [].slice.apply(arguments, [0]).map(function (result) {
return result[0];
});
}).then(Globalize.load).then(function () {
Globalize.locale("fr");
});
});
})();
</script>
It's working. But when I tried to use it in other page in $(document).ready or $(window).load I Have the error JavaScript: E_DEFAULT_LOCALE_NOT_DEFINED: Default locale has not been defined.
It seems Like that The Globalize is not yet loaded.
I know that this is a very old story, but I stumbled upon it and the answer is pretty simple - instead of doing what you want to do on the $(document).ready event, you have to wait for the globalize to finish loading the resources and then do your stuff.
The simple way of doing this is to trigger your own event after you loaded globalize like this:
function loadcldr() {
var currentCultureCode = $("#hfTwoCharsCultureCode").val();
var publicCdnGlobalizeCompleteUrl = "/Resources/cldr/";
$.when(
$.get(publicCdnGlobalizeCompleteUrl + "main/" + currentCultureCode + "/ca-gregorian.json"),
$.get(publicCdnGlobalizeCompleteUrl + "main/" + currentCultureCode + "/numbers.json"),
$.get(publicCdnGlobalizeCompleteUrl + "main/" + currentCultureCode + "/currencies.json"),
$.get(publicCdnGlobalizeCompleteUrl + "supplemental/likelySubtags.json"),
$.get(publicCdnGlobalizeCompleteUrl + "supplemental/timeData.json"),
$.get(publicCdnGlobalizeCompleteUrl + "supplemental/weekData.json")
).then(function () {
// Normalize $.get results, we only need the JSON, not the request statuses.
return [].slice.apply(arguments, [0]).map(function (result) {
return result[0];
});
}).then(Globalize.load).then(function () {
Globalize.locale(currentCultureCode);
customNumberParser = Globalize.numberParser();
$(document).trigger("globalizeHasBeenLoadedEvent");
});
}
The line that is of interest for you is $(document).trigger("globalizeHasBeenLoadedEvent"); because this triggers the custom event.
And then you can wait for that event to happen and then do your stuff:
$(document).on("globalizeHasBeenLoadedEvent",
function () {
alert("I'm done loading globalize...");
});
Hope it helps someone in the future... (not once I had an issue and I've searched on SO and found my own answers) :-))
Related
I have a post that work well when I run from VS2015 debug:
$("#DisplayChartType").bind("change", function () {
$.post("../Employee/ChangeDisplayChartType", { displayChartType: $("#DisplayChartType").val() }, function (data) {
iDependOnMyParameter(data);
})
});
But post does not work once I have published to IIS. I tried using ../, / and ~/ in the post but none work. I searched web and found the approach below but I still get ARG1 being sent as a parameter instead of my javascript variable.
$("#DisplayChartType").bind("change", function () {
$.post("#Html.Action("ChangeDisplayChartType", "Employee", new { displayChartType = "ARG1" })".replace("ARG1",$("#DisplayChartType").val()) , function (data) {
iDependOnMyParameter(data);
})
});
How should I do this? I really would like to stay with $.post approach as that works nicely in VS.
You can try this code.
$("#DisplayChartType").bind("change", function () {
var chartType = $("#DisplayChartType").val();
var url="#Url.Action("ChangeDisplayChartType", "Employee", new { displayChartType = "ARG1" })";
$.post(url.replace("ARG1", chartType), function (data) {
iDependOnMyParameter(data);
})
});
So add it to the url
$.post("../Employee/ChangeDisplayChartType?displayChartType=" + encodeURIComponent($("#DisplayChartType").val()), function(){});
or change your original code to GET and the value will be added to the querystring.
You can use window.location.origin or document.location.origin to get the origin of your website, whether running in VS 2015 debug or on IIS.
So instead of doing
$.post("../Employee/ChangeDisplayChartType"
You can try
$.post(document.location.origin + "/Employee/ChangeDisplayChartType"
#OJ Raqueno put me on the right path.
At top of script I now declare "myPath". My website URL ends with "secure" so this test gives me the right path:
var myPath = document.URL;
if (!myPath.endsWith("secure")) {
myPath = "";
}
Then I do this:
$("#DisplayChartType").bind("change", function () {
$.post(myPath + "/Employee/ChangeDisplayChartType", { displayChartType: $("#DisplayChartType").val() }, function (data) {
alert($("#DisplayChartType").val());
iDependOnMyParameter(data);
})
});
I have this script, and there is a very noticeable 1-2 second delay to change the border color around a textbox (has-success) or (has-error). Basically I want to change the color (Green or Red) and show/hide a glyphicon based on an if/else statement.
$(document).ready(function () {
$("#lookupExtGuest").click(function () {
$.ajax({
url: "/NewUserRequest/LookupData",
data: { userInput: document.getElementById("ExtGuestID").value },
success: function (result) {
if (result.indexOf("was found") != -1) {
var d = document.getElementById("extGuestlookup")
d.className = d.className + " has-success"
$('#extGuestGlyphiconOK').show();
$('#extGuestGlyphiconRemove').hide();
}
else {
var d = document.getElementById("extGuestlookup")
d.className = d.className + " has-error"
$('#extGuestGlyphiconOK').hide();
$('#extGuestGlyphiconRemove').show();
}
}
});
});
});
Here is the reponse times from the chrome Network menu:
The javascript in the success function should only take a few milliseconds to run provided the result string is only a few kilobytes. A good way to test something like this is with console.time():
<script>
$(document).ready(function () {
$("#lookupExtGuest").click(function () {
console.time('lookupDataRequestTimer');
$.ajax({
url: "/NewUserRequest/LookupData",
data: { userInput: document.getElementById("ExtGuestID").value },
success: function (result) {
console.timeEnd('lookupDataRequestTimer');
console.time('lookupDataCallbackTimer');
if (result.indexOf("was found") != -1) {
var d = document.getElementById("extGuestlookup")
d.className = d.className + " has-success"
$('#extGuestGlyphiconOK').show();
$('#extGuestGlyphiconRemove').hide();
}
else {
var d = document.getElementById("extGuestlookup")
d.className = d.className + " has-error"
$('#extGuestGlyphiconOK').hide();
$('#extGuestGlyphiconRemove').show();
}
console.timeEnd('lookupDataCallbackTimer');
}
});
});
});
</script>
I've added some console.time functions into the code you posted. If you run this you should see the timing in the web-inspector's console. This way you can see whether the ajax call (lookupDataRequestTimer) or the success callback (lookupDataCallbackTimer) is slower and by how much.
If the ajax call is much slower and the file being requested isn't too large (which I suspect) you'll probably find the server is quite slow. To speed things up you could run the GET request on page load and cache the data into a variable and access it immediately on click.
Edit: I see you've just added the network screenshot. The request's size is very small, 590b, but it's taking 2.47s. This is definitely the server which is taking a while to respond. Can you take another picture of the entire network tab, including the times for the html page itself.
Maybe you can use ('#parent children').remove() and then ('#parent').append('<element><\element>') for each node.
Or, to hide slow:
hide('slow') or show('slow')
I have the problem that the jQuery mobile slider fires too often to get handled properly on the server. I have something like this:
$("#testSlider").change(function( event, ui ) {
$.getJSON($SCRIPT_ROOT + '/_update_sliders', {
c: $('#testSlider').val()
}, function(data) {
g4.updateOptions( { 'file': data.result } );
});
This works perfectly fine, /_update_sliders starts a function in python which sends data.result back to the site. The problem occurs if I change the slider too fast - too many requests are send, when I stop the slider it takes quite some time too catch up and it even mixes up the requests - so the end state might not even present the actual slider value.
What is a clean solution to this? Anyway to restrict the amount of times the change event fires up?
Thank you and kind regards
lakerz
You could put a throttle on it using following concept. Uses setTimeout() to add delay, and if changes are constantly happening delay gets pushed back and it will not fire until a full delay period has ended
var sliderTimer,
sliderAjaxDelay = 100;
$("#testSlider").change(function (event, ui) {
if (sliderTimer) {
clearTimout(sliderTimer); /* if already a timeout, clear it */
}
// throttle requests using setTimeout
sliderTimer = setTimeout(sliderAjaxUpdate, sliderAjaxDelay);
});
function sliderAjaxUpdate() {
$.getJSON($SCRIPT_ROOT + '/_update_sliders', {
c: $('#testSlider').val()
}, function (data) {
g4.updateOptions({
'file': data.result
});
});
}
Adjust the delay variable to what suits you
I found a solution in jQuery which works, but I'm not sure if this is a "clean" way:
var complete = 0;
$("#testSlider").change(function (event, ui) {
if (complete == 1) {
sliderAjaxUpdate();
complete = 0;
};
});
function sliderAjaxUpdate() {
$.getJSON($SCRIPT_ROOT + '/_update_sliders', {
c: $('#testSlider').val()
}, function (data) {
g4.updateOptions({
'file': data.result
});
});
};
$( document ).ajaxComplete(function() {
complete = 1;
});
I tried for several hours to get the following code working.
The code should be paused until the page is loaded. The problem that I'm encountering is that the AJAX is executing asynchronously. How would I force the code to wait before executing?
var i = 1;
function On_Success(){
i = i+1;
if(i<=10){
$('<div id="p'+i+'">b</div>').replaceAll('#b');
$('#p'+i).load('tabelle.html');
//here shoul be waited, til the page is loaded
On_Success();
};
};
function knopf(){
$('body').append('<div id="p'+i+'">a</div>');
$('#p'+i).load('tabelle.html');
On_Success();
};
Both Ajax and load have an on successs function that can be run when the response is fully returned.
$.ajax({
async: true,
type: "GET",
url: url,
data: params,
success: function(html){
//do stuff here
},
error: handleAjaxErrors
});
If you want to use load, there is a success callback as well:
$("#myDiv").load('/ajax/data/get', function() {
//do stuff here
});
The load function has a success handler:
$('#p'+i).load('tabelle.html', function() {
On_Success();
});
The success handler is only called after the ajax call completes successfully, and after the provided content has been added to the DOM.
You can see full documentation here:
http://api.jquery.com/load/
If you also want to capture error conditions on the client you will need to use the full $.ajax call as per #Chris's answer.
.load accepts a callback that runs when loading is complete; you can use this instead of the more verbose jQuery.ajax function, which will require you to write additional code to populate your element.
jQuery("#p", i).load("tabelle.html", function() {
//code to run when tabelle.html has finished loading
});
Change your code to the following. It should work:
var i = 1;
function On_Success() {
i = i + 1;
if (i <= 10) {
$('<div id="p' + i + '">b</div>').replaceAll('#b');
$('#p' + i).load('tabelle.html', On_Success);
};
};
function knopf() {
$('body').append('<div id="p' + i + '">a</div>');
$('#p' + i).load('tabelle.html', On_Success);
};
On another note, is it absolutely necessary that you should wait for one load to complete before populating the other divs? Why can't you do something like this:
function On_Success() {
var i = 0;
while(i < 11) {
$('<div id="p' + i + '">b</div>').replaceAll('#b');
$('#p' + i).load('tabelle.html');
};
};
Also, I'm not sure what the knopf function is doing. What should the value of i be in that function? How are you calling your code?
hoping some one can shed some light on my problem. Basicly I only want to execute a block of code if a certain DOM element exists. If it does I then perform a few bits and bobs and then call a function. However it complains that the function is not defined, suggesting that the function is not in scope. Below is the code :
$(document).ready(function ()
{
if ((document.getElementById("view<portlet:namespace/>:editSplash")!= null)) {
console.log("notifications scripted started");
// hide loading box/ notify on body load
$('.ajaxErrorBox').hide();
$('.loadingNotifications').hide();
$('.notifyWindow').hide();
getFeed();
// set up refresh button for reloading feed
$('.refreshFeed').click(function() {
$('.notifyWindow').hide();
$('.notifyWindow').empty();
console.log("notifications clicked");
getFeed();
});
// begin ajax call using jquery ajax object
function getFeed ()
{
$('.notifyWindow').empty();
console.log("ajax call for feed starting");
$.ajax ({
type: "GET",
url: "http://cw-pdevprt-05.tm-gnet.com:10040/notificationsweb/feed?username=uid=<%# taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %><wps:user attribute="uid"/>",
dataType: "text/xml",
timeout: 10000,
success: parseXml
});
};
// show loading box on start of ajax call
$('.notifyWindow').ajaxStart(function() {
$('.refreshFeed').hide("fast");
$('.notifyWindow').hide();
$('.ajaxErrorBox').hide();
$('.loadingNotifications').show("fast");
});
// hide loading box after ajax call has stopped
$('.notifyWindow').ajaxStop(function() {
$('.loadingNotifications').hide("slow");
$('.refreshFeed').show("fast");
});
$('.notifyWindow').ajaxError(function() {
$('.loadingNotifications').hide("slow");
$('.ajaxErrorBox').show("fast");
$('.refreshFeed').show("fast");
});
// parse the feed/ xml file and append results to notifications div
function parseXml (xml) {
console.log("xml parsing begining");
if (jQuery.browser.msie)
{
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(xml);
xml = xmlDoc;
}
$(xml).find("entry").each(function()
{
var $item = $(this);
var title = $item.find("title").text();
var linkN = $item.find("link").attr("href");
var output = "<a href='" + linkN + "' target='_self'>" + title + "</a><br />";
$(".notifyWindow").append($(output)).show();
});
}
}
else {
console.log("notifications not available");
return false;
}
});
If the DOM element exists I then try and call the getFeed function "getFeed();" however it comes back undefined. If anyone could shed some light on this it would be greatly appreciated.
Thanks in advance
It seems that you're calling getFeed before it is defined. Try moving the if statement to after the function definition. Note that this behaviour is actually implementation specific, so some browsers may work this way and some may not.
Oh - And seriously? view<portlet:namespace/>:editSplash for an id?
Problem solved - I moved my functions outside of the if statement. We live and learn lol :-)