daattali / shinyalert

🗯️ Easily create pretty popup messages (modals) in Shiny
https://daattali.com/shiny/shinyalert-demo/
Other
241 stars 26 forks source link

Fixes #48 and #46; A delay is no longer required #86

Closed ch0c0l8ra1n closed 4 months ago

ch0c0l8ra1n commented 4 months ago

Whenever we create html content using js instead of shiny::insertUI and similar functions, we also need to bind/unbind accordingly. When 2 sweet alerts are fired back to back, swal service adds the second sweet alert to a queue, which is then opened when the first one closes. The problem arises because when swalservice.js opens the second swal, corresponding functions in shinyalert.js and shinyalert.r (I'm not 100% sure exactly when shiny does the binding) that are responsible for handling the bindings are not called.

We can fix this by adding a simple Shiny.bindAll whenever swalservice has to open a queued up swal in openNextSwal

This is a simple one liner fix that doesn't even modify the underlying sweetalert library. It only makes modifications to swalservice.js, which is a code snippet taken from this issue.

daattali commented 4 months ago

Thanks a lot, this does seem to work and it's such a simple solution! Thank you to @stla also for his comment

Could you modify the minified javascript version and use the minified version in the code? And also add a NEWS entry please

The minified version is:

var SwalService=function(s){this.pendingSwal=[],s&&null!=s.showPendingMessage&&(this.showPendingMessage=s.showPendingMessage),this.initialize()};SwalService.prototype={currentSwal:null,showPendingMessage:!0,swalFirstCalled:!1,__swal:swal,pendingSwal:null,nextId:1,swal:function(){var s={args:arguments,id:this.nextId++};return this._swalWithId(s)},_swalWithId:function(s){return this.isSwalOpen()||this.isClosing?this.pendingSwal.push(s):(this.__swal.apply(null,s.args),this.currentSwal=s,this.swalFirstCalled||($(".sweet-alert").prepend('<span class="other-messages"></span>'),this.swalFirstCalled=!0)),this.refreshPendingText(),s.id},onClosed:function(){this.isClosing=!1,this.openNextSwal()},refreshPendingText:function(){this.showPendingMessage&&(0===this.pendingSwal.length?$(".other-messages").text(""):$(".other-messages").text(this.pendingSwal.length+" unread alerts"))},close:function(s){if(void 0===s||this.currentSwal&&this.currentSwal.id==s)this.__swal.close();else if(void 0!==s&&this.pendingSwal.length>0){for(var e,n=0;n<this.pendingSwal.length;n++)if(this.pendingSwal[n].id==s){e=n;break}void 0!==e&&(this.pendingSwal.splice(e,1),this.refreshPendingText())}},openNextSwal:function(){var s=this;if(s.pendingSwal.length>0){var e=s.pendingSwal.shift();s._swalWithId(e),Shiny.bindAll($(".sweet-alert"))}},isSwalOpen:function(){return null!=this.currentSwal&&null!=this.currentSwal},closeAndFireCallback:function(s,e){var n=this.currentSwal;(this.close(s),n&&n.args&&n.args.length>1&&"function"==typeof n.args[1])&&(0,n.args[1])(e)},initialize:function(){var s=this,e=this.__swal.close;this.__swal.close=function(){s.isClosing=!0,e(),s.currentSwal=null,setTimeout((function(){s.onClosed()}),400)}}};
ch0c0l8ra1n commented 4 months ago

Updated as requested!

daattali commented 4 months ago

Thank you so much this is a perfect fix!