It may just be my eye-mind coordination (or lack thereof), but I have trouble adjusting to abrupt user interface changes. For example, if I click a button and a dialog box instantly appears, my business-related thought processes pause for a moment while I try to mentally digest what just happened and why. It is mentally easier for me if user interface changes occur through fast, but gradual animations. Don't waste my time with a slow animation... but then again, don't waste my time with no animation. I function best when enterprise application developers use animations to prepare my mind for the next step. So here I am developing an enterprise application with Oracle JET and using ojDialog. As my ojDialog appears, I think to myself, "Where is the animation?"
Here is how I added fade-in animation to ojDialog. Starting from the ojDialog cookbook recipe, I added the class animate
as a rootAttribute
to identify that this dialog should be animated:
<div id="dialogWrapper"> <div style="display:none" id="modalDialog1" title="Modal Dialog" data-bind="ojComponent:{component: 'ojDialog', initialVisibility: 'hide', rootAttributes: { class: 'animate' }}"> <div class="oj-dialog-body"> The dialog window can be moved, resized and closed with the 'x' icon. Arbitrary content can be added to the the oj-dialog-body and oj-dialog-footer sections. </div> <div class="oj-dialog-footer"> <button id="okButton" data-bind="click: closeDialog, ojComponent: {component: 'ojButton', label: 'OK'}"> </div> </div> <button id="buttonOpener" data-bind="click: openDialog, ojComponent: {component: 'ojButton', label: 'Open Modal Dialog'}"> </div>
Next I added some CSS to set the initial opacity for all animated ojDialogs to 0, meaning fully transparent:
.oj-dialog.animate { opacity: 0; transition: opacity .25s ease-in-out; }
Now when I invoke the open
method, the dialog will appear, but it will be fully transparent which means I won't actually be able to see it (talk about usability and user interface design!). Then I added a new selector and corresponding CSS to represent a dialog in the fully opaque state:
.oj-dialog.animate.fully-opaque { opacity: 1; }
The plan is to toggle the fully-opaque
class on the oj-dialog.animate
selector when the dialog opens. Let's revisit that dialog HTML definition and add an open
event handler:
<div style="display:none" id="modalDialog1" title="Modal Dialog" data-bind="ojComponent:{component: 'ojDialog', initialVisibility: 'hide', open: dialogOpen, rootAttributes: { class: 'animate' }}">
And now the JavaScript to handle the open
event:
self.dialogOpen = function(event, ui) { $(event.target) .closest(".oj-dialog.animate") .addClass("fully-opaque"); };
Since we added a CSS transform to oj-dialog.animate
the ojDialog container will fade in from 0 to 100% opacity. Notice the interesting selector in that JavaScript fragment? The event target is the ojDialog div we defined, but Oracle JET wraps that element in a new root element. It is THAT element we want to animate (hence the use of rootAttributes
in the ojDialog definition). There are probably a million different selectors I could have chosen. In fact, $(event.target).parent()
was my first idea, but then I thought, "what if the ojDialog structure changes?"
If you followed these steps, you should now have an ojDialog with a fade-in effect. What about fade-out? I don't have a good answer here. I tried both the close
and beforeClose
events, but those happen too quickly, meaning the dialog display is changed to hidden before the animation. My not-so-good work-around is to perform the animation when the user clicks the OK button in the dialog footer:
self.closeDialog = function(data, event) { // attempt fadeOut with jQuery $(event.target) .closest(".oj-dialog.animate") .fadeOut(function() { $("#modalDialog1").ojDialog("close"); }); };
I put together a jsFiddle named ojDialog Fade-in to demonstrate the animated ojDialog. Once Oracle JET starts accepting pull requests, perhaps animations would be a valuable community enhancement?
No comments:
Post a Comment