| Page 1 of 2 | [ 13 posts ] | Go to page 1, 2 Next |
|
Hi All,
I have a very simple overlay (styled as a facebook popup) that I am creating via Code: FbLike = Y.Base.create('facebook', Y.Overlay, [Y.WidgetModality, Y.WidgetAutohide], {..},{}); It mixes in the WidgetModality and WidgetAutohide extensions. The test case is here: https://gist.github.com/1347632 The strangeness I don't understand is: 1. the Overlay attributes of width, centered, zIndex, render, visible, headerContent, bodyContent and footerContent can all be nicely setup in the base class attributes property. BUT, modal and hideOn (the extension attributes) won't work from there. I have to create a base constructor and manage them separately in this init method. Why? 2. I want to bind an event to the UI. I am used to using the bindUI method as part of the widget lifecyle for this - but if I do this from the base class, the footerContent of the overlay has not yet been rendered (I would have thought the render phase would be complete by this point). I must listen for the footerContentChange event before I can fire my bind to achieve the outcome I want. All works, but having my attribute properties managed in separate locations and being unable to rely on the bindUI to be post-widget render seems strange. Is this the intended behaviour, and if so, what is the reasoning behind points 1 and 2? Cheers, Simon |
|
You shouldn't extend Overlay. Look at the source of overlay.js. It's just a call to Y.Base.create('overlay', Y.Widget, [ <a bunch of class extensions> ]);
For your FB modal, do the same (use Widget as the base class), but add the modal and auto-hide extensions to those used to define Overlay. Separately, the init method is likely causing trouble, because init is defined on Y.Base, and you're probably overwriting it. Use initializer rather than init. |
|
Hi Luke,
Many thanks for your reply. I've tried as you've suggested, but have had no luck (my second test case: https://gist.github.com/1351297) My call is now: Code: FbLike = Y.Base.create("facebook", Y.Widget, [Y.WidgetStdMod, Y.WidgetPosition, Y.WidgetStack, Y.WidgetPositionAlign, Y.WidgetPositionConstrain, Y.WidgetModality, Y.WidgetAutohide], {..},{..}); I've mixed in Y.WidgetModality and Y.WidgetAutohide at the end, however I'm finding their attributes are still not read from the base attribute property: Code: ATTRS: { width: {value:400}, centered: {value:true}, zIndex: {value:100}, render: {value:true}, visible: {value:false}, headerContent: {value:"Title"}, bodyContent: {value:"<div class='fbUrl'>Subtitle</div><div class='fb-like'>content</div>"}, footerContent: {value: "<a class='close' href='#'>Close</a>"}, // these two attributes are not read modal: true, hideOn: [{eventName: 'clickoutside'}] } My use of the init method isn't one of choice - I've tried all other possibilities (including initializer) but nothing works. The only way I can set the attributes for the modality and autohide mixins is via the init. It feels like there is a lifecycle problem with the extension mixin mechanism (or the two extensions themselves) that is preventing those mixins from being initialised off the base ATTRS. It seems this lifecycle issue extends to the bindUI method, which leaves me with my event trigger on footerContentChange necessary to effectively bypass the lifecycle hook that bindUI would normally give. Is that possible? |
|
Ok, I had a look and there are two separate problems:
1) WidgetModality has a bug. It only attaches modal behavior if modal:true is passed in the constructor. You should file this bug. 2) WidgetAutoHide defines the hideOn attribute with a valueFn, and valueFn has higher precedence than value in the config. The way you're dealing with it is a reasonable workaround for #1. For #2, try defining in your ATTRS Code: hideOn: { valueFn: undefined, value: [ <what you have already> ] } |
|
Simon, sorry that you ran into these weird issues.
Luke, thanks for hunting down the issues. I went ahead and created tickets, and pushed these changes to GitHub. lsmith wrote: Ok, I had a look and there are two separate problems: 1) WidgetModality has a bug. It only attaches modal behavior if modal:true is passed in the constructor. You should file this bug. Ticket: http://yuilibrary.com/projects/yui3/ticket/2531401 Commit: https://github.com/ericf/yui3/commit/73 ... 4cff6c01b1 lsmith wrote: 2) WidgetAutoHide defines the hideOn attribute with a valueFn, and valueFn has higher precedence than value in the config. Ticket: http://yuilibrary.com/projects/yui3/ticket/2531402 Commit: https://github.com/ericf/yui3/commit/48 ... 5a6cae49c6 |
|
Many thanks Eric and Luke, and thanks Eric for jumping on those tickets and patches.
I do however have one question that is unanswered from above (sorry to keep at it). I've updated my gist here to better illustrate it: https://gist.github.com/1354698 1) The FB overlay sets its footer content via the base ATTRS.footerContent. Code: footerContent: {value: "<a class='close' href='#'>Close</a>"}, 2) I bind a click event to the <a> tag in the footer content to call the overlay hide method. 3) I fire the bind method from bindUI Code: bindUI: function() { this._myBind(); // must comment previous line and uncomment here //this.after('facebook:footerContentChange', Y.bind(this._myBind, this)); }, _myBind: function() { var fb = this, aRef = this.get('boundingBox').one('a'); if (!aRef) { alert('footer content not rendered: cannot bind'); } else { aRef.on('click', function(e){ e.preventDefault(); fb.hide(); }); } } Problem: when bindUI fires, the footerContent has not been rendered and the bind fails. I assumed when bindUI fires, all renderUI methods have been called and my footerContent should be available. To work around it, I manually listen for the footerContentChange event and then bind. My question is, have I got this sequence wrong? Am I wrong in assuming I can use bindUI as I expected? |
|
To add to this, I've just tried to plugin drag to my base class ATTRS property (using Luke's precedence work around):
Code: plugins: {value:[ Y.Plugin.Drag ], valueFn:undefined} and .. it doesn't work. I have to plugin via the init method, and then it works: Code: init: function(config) { // pass extras in via constructor (bug workaround for incomplete ATTRS support) config.modal = true; config.plugins = [ Y.Plugin.Drag ]; // continue with the superclass method FbLike.superclass.init.apply(this, arguments); }, Am I right to assume plugins can be set via ATTRS and this is a bug as well? |
|
Ok - moving on then.
I've filed an additional 2 tickets: Fix Widget plugin init-time logic: http://yuilibrary.com/projects/yui3/ticket/2531442 Fix Widget bindUI timing when subclassed: http://yuilibrary.com/projects/yui3/ticket/2531443 Re this forum thread - that's 4 bugs from trying to subclass an Overlay widget. If these last 2 bugs arise from my misunderstanding of the Y.Base.create inheritance model - my apologies. Regards, Simon |
|
Simon, sorry I didn't see your forum posts until now (I thought I would have been auto-subscribed), anyways I'll reply in the tickets.
|
|
Simon, you want do be doing something more like this:
http://jsfiddle.net/ericf/k9AaZ/ Let me know if you have any specific questions about what I did… |
| Page 1 of 2 | [ 13 posts ] | Go to page 1, 2 Next |
| You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum |
© 2006-2013 Yahoo! Inc. All rights reserved.
All code on this site is licensed under the BSD License unless stated otherwise.
About This Site · Security Contact Info
Powered by phpBB® Forum Software © phpBB Group