Hide popup loading indicator if an error/flash is thrown from an AJAX handler (#4364)

Fixes rainlab/builder-plugin#283. Credit to @bennothommo 

When using the popup widget with an AJAX handler, a loading indicator appears whilst the AJAX handler is being run. If an exception or error occurs at this point in time, the exception is shown, but neither the loading indicator nor the backdrop are removed as the popup is technically not 'open' at this stage. This fix should resolve this by tracking the loading state of the popup and removing the backdrop and loading indicator if needed.
This commit is contained in:
Ben Thomson 2019-06-11 22:52:00 +08:00 committed by Luke Towers
parent 8811c3dcd4
commit 19846037f8
2 changed files with 13 additions and 4 deletions

View File

@ -22,6 +22,7 @@
this.$modal = null
this.$backdrop = null
this.isOpen = false
this.isLoading = false
this.firstDiv = null
this.allowHide = true
@ -85,7 +86,11 @@
},
error: function(jqXHR, textStatus, errorThrown) {
this.error(jqXHR, textStatus, errorThrown).done(function(){
self.hide()
if (self.isLoading) {
self.hideLoading();
} else {
self.hide()
}
self.triggerEvent('popupError') // Deprecated
self.triggerEvent('error.oc.popup')
})
@ -178,7 +183,7 @@
this.$modal = null
this.$el = null
// In some cases options could contain callbacks,
// In some cases options could contain callbacks,
// so it's better to clean them up too.
this.options = null
@ -249,6 +254,8 @@
if (!this.$backdrop)
return;
this.isLoading = val
var self = this
if (val) {
setTimeout(function(){ self.$backdrop.addClass('loading'); }, 100)

View File

@ -3723,6 +3723,7 @@ this.$container=null
this.$modal=null
this.$backdrop=null
this.isOpen=false
this.isLoading=false
this.firstDiv=null
this.allowHide=true
this.$container=this.createPopupContainer()
@ -3743,7 +3744,7 @@ if(!this.options.content){this.setLoading(true)}
if(this.options.handler){this.$el.request(this.options.handler,{data:paramToObj('data-extra-data',this.options.extraData),success:function(data,textStatus,jqXHR){this.success(data,textStatus,jqXHR).done(function(){self.setContent(data.result)
$(window).trigger('ajaxUpdateComplete',[this,data,textStatus,jqXHR])
self.triggerEvent('popupComplete')
self.triggerEvent('complete.oc.popup')})},error:function(jqXHR,textStatus,errorThrown){this.error(jqXHR,textStatus,errorThrown).done(function(){self.hide()
self.triggerEvent('complete.oc.popup')})},error:function(jqXHR,textStatus,errorThrown){this.error(jqXHR,textStatus,errorThrown).done(function(){if(self.isLoading){self.hideLoading();}else{self.hide()}
self.triggerEvent('popupError')
self.triggerEvent('error.oc.popup')})}})}
else if(this.options.ajax){$.ajax({url:this.options.ajax,data:paramToObj('data-extra-data',this.options.extraData),success:function(data){self.setContent(data)},cache:false})}
@ -3806,7 +3807,8 @@ this.$backdrop.append($('<div class="modal-content popup-loading-indicator" />')
else if(!val&&this.$backdrop){this.$backdrop.remove()
this.$backdrop=null}}
Popup.prototype.setLoading=function(val){if(!this.$backdrop)
return;var self=this
return;this.isLoading=val
var self=this
if(val){setTimeout(function(){self.$backdrop.addClass('loading');},100)}
else{setTimeout(function(){self.$backdrop.removeClass('loading');},100)}}
Popup.prototype.setShake=function(){var self=this