Why is async causing issues in my javascript? - asynchronous

Can anyone tell me why async: false; doesn't allow my spinner to display during data load?
But when I used async: true; it reverses my default display toggle?
I currently have list set up with 5 different items. 3 of those items are set up to display by default when the page loads. Then they can be clicked off or the other 2 items can be clicked on. When I use async: true; to get my spinner to display, its like it doesn't recognize the default toggles. Even though they are selected on page load, the information does not display. It only displays after they are UNselected.
$(function () {
var HistoryViewModel;
var xspinner = new Spinner();
$.ajax({
url: '/Users/GetAccountHistory',
type: 'POST',
async: false,
cache: false,
data: { accountId: #Model.Account.AccountID },
beforeSend: function () {
xspinner.showSpinner("Getting History Information...");
},
complete: function () {
xspinner.hide();
},
success: function (data) {
HistoryViewModel = new RCM.ViewModels.History.HistoryViewModel(ko.mapping.fromJS(data));
ko.applyBindings(HistoryViewModel, document.getElementById('ListPanel'));
ko.applyBindings(HistoryViewModel, document.getElementById("DetailsPanel"));
ie9HeightFix();
},
error: function (xhr, textStatus, errorThrown) {
notify.show({ type: 'error', header: 'Error!', content: 'Error fetching History, ' + xhr.statusText });
return false;
}
});
function ie9HeightFix() {
if(document.addEventListener && !window.requestAnimationFrame)
{
var eTop = $('.AccountHx').offset().top; //get the offset top of the element
var dTop = eTop - $(window).scrollTop(); //position of the ele w.r.t window
var cHeight = $(window).height() - dTop - $(".colophon").height();
$(".AccountHx").css("height", cHeight);
$(".AccountHx").css("position", "relative");
$(".AccountHx").css("overflow-x", "hidden");
$(".AccountHx-detailsPanel").css("left", "32rem");
$(".viewDetailsButton").css("right", "2rem");
}
}
$(window).resize(function() {
ie9HeightFix();
});
$("#vToggle").click();
$("#pToggle").click();
$("#sToggle").click();
$(".search-button").click(function(event){
$(".subHeader").toggleClass("search-visible");
$(".AccountHx-items").toggleClass("search-visible");
$(".search-button").toggleClass("search-visible");
});
$(".filter-button, .modal-close").click(function(event){
$(".AccountHx-filtersPanel").toggleClass("filters-visible");
$(".filter-birdBeak").toggle();
});
$(".filterButtons input").attr("disabled", false);
});
$("#vToggle").click(function(){
$(".js-vItem").toggle();
$("#vToggle").toggleClass("is-active");
});
$("#cToggle").click(function(){
$(".js-claimItem").toggle();
$("#cToggle").toggleClass("is-active");
});
$("#nToggle").click(function(){
$(".js-nItem").toggle();
$("#nToggle").toggleClass("is-active");
});
$("#sToggle").click(function(){
$(".js-sItem").toggle();
$("#sToggle").toggleClass("is-active");
});
$("#pToggle").click(function(){
$(".js-pItem").toggle();
$("#pToggle").toggleClass("is-active");
});
$("li.filterButton").click(function(){
$(this).parent().siblings(".clearButton").show();
$(".AccountHx-filtersPanel .clearButton--all").css('display', 'inline-block');
});
$(".clearButton").click(function(){
var hiddenOption = $(this).siblings(".filterButtons").children(".hiddenOption");
hiddenOption.siblings('.is-active').removeClass('is-active');
hiddenOption.toggleClass("is-active");
$(this).hide();
});
$(".AccountHx-filtersPanel .clearButton--all").click(function() {
$(".AccountHx-filtersPanel .filterButton").removeClass("is-active");
$(".AccountHx-filtersPanel .hiddenOption").toggleClass("is-active");
$(".AccountHx-filtersPanel .filterCheckbox").attr('checked', false);
$(".AccountHx-filtersPanel .clearButton").hide();
$(this).hide();
})

The answer that I discovered is to move the
$("#visitToggle").click();
$("#paymentToggle").click();
$("#statementToggle").click();
inside the following section
success: function (data) {...}
and change async to true

Related

fullcalendar - multiple sources to turn off and on

I've a calendar that I want to list various types of event on and enable a checkbox filter to show/hide those kind of events.
Is there a way to say on this action, ONLY load from 1 data-source AND remember that URL on month next/prev links?
I've started using eventSources, but it loads them all, rather than the one(s) I want.. Here's what I have.
var fcSources = {
all: {
url: tournament_url + '/getCalendar/?typefilter=[1,2]'
},
type1: {
url: tournament_url + '/getCalendar/?typefilter=[1]'
},
type2: {
url: tournament_url + '/getCalendar/?typefilter=[2]'
}
};
These URLS all provide a json string of events, based on the types prrovided.
Here's my calendar:
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek'
},
firstDay: 1, // Monday = 1
defaultDate: new Date(), // Now
editable: true,
eventSources: [ fcSources.all ],
events: fcSources.all,
nextDayThreshold: '00:00:00',
... etc etc
Above my calendar I have this:
input type="checkbox" name="event_filter[]" value="type1" /> Type 1
input type="checkbox" name="event_filter[]" value="type2" /> Type 2
And finally , two Jquery fucntions.. one to get all the filters:
function getFilters(getName) {
var filters = [];
var checked = [];
$("input[name='"+getName+"[]']").each(function () {
filters.push( $(this).val() );
});
$("input[name='"+getName+"[]']:checked").each(function () {
checked.push( $(this).val() );
});
return [filters, checked];
}
and the last to load them:
$(".event_filter").on('click', function() {
var doFilters = getFilters('event_filter');
$('#calendar').fullCalendar( 'removeEvents' );
if (doFilters[0] === doFilters[1]) {
$('#calendar').fullCalendar( 'addEventSource', fcSources.all );
} else {
$.each(doFilters[1], function(myFilter, myVal) {
console.log(myVal);
$('#calendar').fullCalendar( 'addEventSource', fcSources.myVal );
});
}
// $('#calendar').fullCalendar( 'refetchEvents' );
});
Since the sources are all the same place and just different data on the URL, this approach could meet your needs. In the demo it just alerts the URL that is being tried but doesn't actually supply any data...
https://jsfiddle.net/gzbrc2h6/1/
var tournament_url = 'https://www.example.com/'
$('#calendar').fullCalendar({
events: {
url: tournament_url + '/getCalendar/',
data: function() {
var vals = [];
// Are the [ and ] needed in the url? If not, remove them here
// This could (should!) also be set to all input[name='event_filter[]'] val's instead of hard-coded...
var filterVal = '[1,2]';
$('input[name="event_filter[]"]:checked').each(function() {
vals.push($(this).val());
});
if (vals.length) {
filterVal = '[' + vals.join(',') + ']' // Are the [ and ] needed in the url? If not, remove here too
}
return {
typefilter: filterVal
};
},
beforeSend: function(jqXHR, settings) {
alert(unescape(settings.url));
}
}
});
// when they change the checkboxes, refresh calendar
$('input[name="event_filter[]"]').on('change', function() {
$('#calendar').fullCalendar('refetchEvents');
});
Try this!
$('#calendar').fullCalendar({
events: function( start, end, timezone, callback ) {
var checked = [];
$("input[name='event_filter[]']:checked").each(function () {
checked.push( $(this).val() );
});
var tournament_url = 'https://www.example.com';
$.ajax({
url: tournament_url + '/getCalendar/',
data: {typefilter: '['+checked.join(',')+']'},
success: function(events) {
callback(events);
}
});
}
});
$('input[name="event_filter[]"]').on('change', function() {
$('#calendar').fullCalendar('refetchEvents');
});
This works for me.

Change components with ajax. (Ractivejs)

views.list = Ractive.extend({/*...*/});
var Content = Ractive.extend({
template: '#template-content',
components: {
//view: views['list']
},
onrender: function() {
/* call this.request */
},
request: function(route) {
var self = this;
$.ajax({
url: route,
type: 'GET',
data: {},
dataType: 'json',
success: function(data){
self.components.view = views[data.view];
}
});
}
});
Ajax request returns {view:'list'}. I write in the console: "Content.components.view" and see:
function ( options ) {
initialise( this, options );
}
But "Content.findComponent('view')" returns "null".
It will work if I uncomment the line "//view: views['list']" in the components. How to dynamically change the component?
Update 1:
I thought I can do this:
var Content = Ractive.extend({
components: {
// Aaaand add listener for data.view?
view: function(data) {
return views[data.view];
// But no, it is not updated when changes data.view ...
}
},
data: {},
oninit: function() {
var self = this;
self.set('view', 'list');
},
});
Not work.. Why then need "data" argument?
I won :)
// Create component globally
Ractive.components.ListView = Ractive.extend({});
// Create ractive instance
var Content = Ractive.extend({
template: '#template-content',
partials: {
view: 'Loading...' // So... default
},
oninit: function() {
var self = this;
$.ajax({
...
success: function(data){
// Hardcore inject component
self.partials.view = '<'+data.view+'/>';
// Little hack for update partial in template
self.set('toggle', true);
self.set('toggle', false);
}
});
},
});
In Content template:
{{^toggle}}{{>view}}{{/}}
It's works-fireworks!

jquery loading animation issue

I'm trying to hide the menu, show animated gif, hide gif, return updated menu.
The menu disappears and reappears, but the animated gif won't show.
What am I doing wrong?
$(document).ready(function () {
$("#menu").wijmenu({
orientation: 'vertical'
});
$("#TDButtons a").click(function () {
var href = $(this).attr("href");
$('#menuAjax').hide(0, LoadAjaxContent(href));
return false;
});
function LoadAjaxContent(href) {
$.ajax({
url: href,
success: function (data) {
$("#menuAjax").html(data)
.addClass("loading")
.delay(5000)
.removeClass("loading")
.fadeIn('slow');
$("#menu").wijmenu({
orientation: 'vertical'
});
}
});
}
Please let me know if you need more info. Thanks
It doesn't show cause you are delaying something that isn't a queueable animation:
.addClass("loading")
.delay(5000)
.removeClass("loading")
.fadeIn('slow');
is interpreted like:
.addClass("loading")
.removeClass("loading")
.delay(5000)
.fadeIn('slow');
You could do:
function LoadAjaxContent(href) {
$.ajax({
url: href,
success: function (data) {
$("#menuAjax").html(data).removeClass("loading").fadeIn('slow');
$("#menu").wijmenu({ orientation: 'vertical' });
}
});
}
$("#TDButtons a").click(function (e) {
e.preventDefault();
var href = this.href;
$('#menuAjax').addClass("loading").hide();
LoadAjaxContent(href);
});
You are adding, removing the loading class from the element once the data is already received. You should do it with ajaxStart and ajaxStop function which eventually adds the loading class before the request is send and removes once the ajax operation is completed.
$(document).ready(function () {
$("#menu").wijmenu({
orientation: 'vertical'
});
$("#TDButtons a").click(function () {
var href = $(this).attr("href");
$('#menuAjax').hide(0, LoadAjaxContent(href));
return false;
});
$.ajaxStart(function(){
$("#menuAjax").addClass("loading");
});
$.ajaxStop(function(){
$("#menuAjax").removeClass("loading");
});
function LoadAjaxContent(href) {
$.ajax({
url: href,
success: function (data) {
$("#menuAjax").html(data)
.delay(5000)
.fadeIn('slow');
$("#menu").wijmenu({
orientation: 'vertical'
});
}
});
}
You have your loading the wrong way round
Your class of loading should be added before the request is sent, and then removed after. You are adding it, (and as roXon pointed out using the .delay function incorrectly) and then removing it again, not giving it any time to be shown.
Try something like this
$(document).ready(function () {
$("#menu").wijmenu({
orientation: 'vertical'
});
$("#TDButtons a").click(function () {
var href = $(this).attr("href");
$('#menuAjax').hide(0, LoadAjaxContent(href));
return false;
});
function LoadAjaxContent(href) {
$("#menuAjax").addClass("loading")
$.ajax({
url: href,
success: function (data) {
$("#menuAjax").html(data)
//.delay(5000) Not needed!
.removeClass("loading")
.fadeIn('slow');
$("#menu").wijmenu({
orientation: 'vertical'
});
}
});
}

Backbone delete model

In this case it wont fire the Http method Delete in firebug when i click clear even if the element is removed from the DOM.
var DecisionItemView = Backbone.View.extend({
tagName: "li",
template: _.template($('#item-template').html()),
initialize: function () {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},
events:{
"click span.decision-destroy": "clear"
},
render: function () {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
clear: function () {
var answer = confirm("Are you sure you want to delete this decision?");
if (answer) {
this.model.destroy({
success: function () {
console.log("delete was a success");
}
});
}
},
remove: function(){
$(this.el).remove();
}
});
Does your model have an id? If not, the destroy method won't fire an http request.
Some code to check this
var M=Backbone.Model.extend({
url:'/echo/json/'
});
var DecisionItemView = Backbone.View.extend({
tagName: "li",
initialize: function () {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},
events:{
"click span.decision-destroy": "clear"
},
render: function () {
var txt=(this.model.get("id")) ? "Clear with id":"Clear without id";
$(this.el).html("<span class='decision-destroy'>"+txt+"</span>");
return this;
},
clear: function () {
var answer = confirm("Are you sure you want to delete this decision?");
if (answer) {
this.model.destroy({
success: function () {
console.log("delete was a success");
}
});
}
},
remove: function(){
$(this.el).remove();
}
});
var m1=new M({id:1}); var m2=new M();
var view1=new DecisionItemView({model:m1});
$("ul").append(view1.render().$el);
var view2=new DecisionItemView({model:m2});
$("ul").append(view2.render().$el);
And a Fiddle http://jsfiddle.net/rSJP6/

JQuery AutoComplete with ASP.Net

Below is my JavaScript
<script>
$(function () {
function log(message) {
$("<div/>").text(message).prependTo("#log");
$("#log").attr("scrollTop", 0);
}
$("#city").autocomplete({
source: function (request, response) {
$.ajax({
url: "getpostcodes.aspx",
dataType: "jsonp",
data: {
like: request.term
},
success: function (data) {
response($.map(data.RegionList, function (item) {
return {
label: item.Detail,
value: item.Detail
}
}));
}
});
},
minLength: 2,
select: function (event, ui) {
log(ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function () {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
});
</script>
And below is my JSON Returned by the server
{"RegionList":[{"Detail":"2250, GOSFORD"}]}
But my auto complete doesn't show up the result? am i doing anything wrong?
What is the HTTP Status code response? I had problemas sometimes because I received the answer, but the status code was 500

Resources