-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I'm working doing things the MVVM way (at least trying to) and currently most of my ViewModels kick of various ajax requests to return data which causes the "processing" dialog to appear.
What I'd love is if I could get the default behavior of the processing dialog to always make my entire screen modal. To do this manually all the time per different windows/components seems a bit tedious and I've posted about my initial attempts with things here http://www.zkoss.org/forum/listComment/19544-ZK6-Handling-a-long-process-event-with-ViewModel-docs-seem-a-bit-off-as-well and and Dennis has some solutions on github (referenced in thread above.)
I've found out how I can center the processing spinner with css, but I'm unable to figure out a way that I could default its behavior to always cause the entire window to become modal? If I could get this to work, I wouldn't really need to anything special as currently the 'processing' dialog is showing up by default under the circumstances that it needs to without me having to code for it.
Is what I'm asking for possible? Or is there some kind of global listener I could set up that will achieve what I want? [ Most of the time I'd think when something is "processing" you don't want the user to be able to click on other things, so to me that's what I'd prefer the default behavior to be.]
Hi rickcr,
You can override the default action in /WEB-INF/zk.xml as below:
<zk> <device-config> <device-type>ajax</device-type> <embed><![CDATA[ <script type="text/javascript"> zk.afterLoad("zk", function () { // store the old functions var oldShowBusy = zAu.cmd0.showBusy; var oldClearBusy = zAu.cmd0.clearBusy; zAu.cmd0.showBusy = function (uuid, msg) { if (arguments.length == 2) { oldShowBusy(null, msg); } else oldShowBusy.apply(this, arguments); }; zAu.cmd0.clearBusy = function (uuid) { oldClearBusy(null); } }); </script> ]]></embed> </device-config> </zk>
Then test with the fragment below, you will see whole window is covered when you click any button.
<zk> <label id="lb" value="test label" /> <button label="busy on page"> <attribute name="onClick"> Clients.showBusy("busy..."); tmOne.start(); </attribute> </button> <!-- Show busy on label 'lb' and clear it after 3 seconds --> <button label="busy on listbox"> <attribute name="onClick"> Clients.showBusy(lb, "busy..."); tmTwo.start(); </attribute> </button> <timer id="tmOne" delay="3000" repeats="false" running="false" onTimer="Clients.clearBusy();" /> <timer id="tmTwo" delay="3000" repeats="false" running="false" onTimer="Clients.clearBusy(lb);" /> </zk>
Regards,
Ben
Thanks Ben this works great IF it's based off a button (or other UI item) for a direct call to showBusy() like you've shown.
I can't seem to get it to work by default for when my View Models are causing the busy dialog to show up baed on a change of a bound collection. Is there a different device type that I need to associate it with in my zk.xml?
If I add an alert in your zk.afterLoad it never shows up for cases where my view model triggers the load that causes the show busy to show up.
I'm not aware of all that is going on 'under the hood' in the internals of Zk, but to be more specific... I have listboxes backed by view models.
On the zul there are lists like...
<listbox model="@bind(vm.categories)" selectedItems="@bind(vm.selectedCategories)" ... >
When something causes the 'categories' to change backed in the view model (like after a search operation), I'll get the processing dialog, but it's not firing the ajax script for afterLoad so therefore the modal affect is not applied.
Any suggestions how to handle this? Thanks again.
Hi,
You can change the 'script' as the fragment below to override the progress mask:
<script type="text/javascript"> zk.afterLoad("zk", function () { var oldProgressbox = zUtl.progressbox; zUtl.progressbox = function () { oldProgressbox.apply(this, arguments); var $mask = jq('.z-loading'); if ($mask) { var $img = jq('.z-loading-indicator'), $body = jq(document.body), body = $body[0], bw = $body.width() + body.scrollLeft - 10, bh = $body.height() + body.scrollTop - 10; // update mask and image's style $mask.width(bw); $mask.height(bh); $img.width('150px'); $img.css('margin-left', (bw - $img.width()) / 2 + 'px'); $img.css('margin-top', (bh - $img.height()) / 2 + 'px'); // update mask size when window scroll if (!window.eventBinded) { var $win = jq(window); $win.scroll(function () { var $maskInst = jq('.z-loading'); if ($maskInst[0]) { $maskInst.width(bw + $win.scrollLeft()); $maskInst.height(bh + $win.scrollTop()); } }); window.eventBinded = true; } } } }); </script>
Regards,
Ben
Awesome Ben! Thanks so much!!!!
This should be in a wiki or the core documentation somewhere for sure (if it is my apologies).
In my opinion, this should be the default behavior of "processing," since typically I don't think you want the user to be able to click around while processing is taking place (and if you do, it's usually when you control the dialog to appear in a specific listbox not in the 'general sense' that the default behavior provides out-of-the-box with zk .)
(Side note in case anyone else uses the script.. pretty obvious - but to change the opacity of the mask some I added: $mask.css('opacity', .75); )
Thanks benbai for the solution and thanks rickcr for the opacity tip.
Works like a charm :D
Asked: 2012-07-03 14:24:19 +0800
Seen: 800 times
Last updated: Aug 20 '12