q.js show method (v1.1)

0 views
Skip to first unread message

andy

unread,
Jun 25, 2010, 12:33:44 PM6/25/10
to Qutensil
hi, looking at the q.js show method it is as follows:

// show holder
show: function(force) {
if (Q.active != this || force) {
this.positionHolder();

if (typeof this.setValue == "function" && this.input)
this.setValue(this.input.value);

Q.callback('onShow', this);

Q.active = this;
this.holder.appear({ duration: 0.1 });
}
},

Im facing a problem whereby I have created a new subclass of q.window
which when initiated draws a qwindow and places it in the center of
the screen. To do this I have created a center method which is
called when the qmodal window is built just like the alert/confirm
etc:

this.show();
this.protection.appear({ duration: 0.1, to: 0.5 });
this.center(); <---- center method here.

the center method then gets the elements width/height and viewport and
centers accordingly, this isnt working as the current q.js onshow
method has onShow before the holder is displayed, I changed this and
moved Q.callback('onShow',this) after this.holder.appear({duration:
0.1}); it still didnt work because the appear effect has a duration, I
removed this and just used : this.holder.show(); and everything
worked great and the height/width were correctly caculated as the
element had been shown.

Couple of questions: - 1 - is this a bug?
2 - If not is there a way I can override the default q.js onShow
without changing any original files.
3 - I guess a solution for me would be to put a timeout on the center
method to give the 0.1 appear duration chance to run... do you think
this is the best way to go?

Hope that all makes sense,


Sorry if Im annoying you with all my posts!!

wonderingwout

unread,
Jun 25, 2010, 1:08:58 PM6/25/10
to Qutensil
Ok, you'll have two options.

1. overwrite the onShow method in your subclass.
Just add a function in your class called onShow and put your action
inside there.
This will eliminate the onShow method in the Q.Window superclass and
you can reorganize things like you want.
It's always best not to touch the original files, makes upgrading to
newer versions harder.

2. Delaying a function with prototype is an option ad quite easy
actually.
Write:

(function() { this.center() }).bind(this).delay(0.1);

So that could be an option as well, though I prefer the first one but
that's up to you :-)

Wout

andrew edmundson

unread,
Jun 25, 2010, 1:30:44 PM6/25/10
to qute...@googlegroups.com
Thanks for great advice again,

If I override the onShow such as:

onShow: function(){
this.restack();

//DO ALTERNATIVE to default this.show();
this.holder.show();
This.center();
},

If I don't call this.show(); will I need to copy the code from q.js show method (shown below) into my onshow for everything to work correctly still?


// show holder
show: function(force) {
if (Q.active != this || force) {
this.positionHolder();

if (typeof this.setValue == "function" && this.input)
this.setValue(this.input.value);

Q.callback('onShow', this);

Q.active = this;
this.holder.appear({ duration: 0.1 });
}
},


Thanks again


Andy

wonderingwout

unread,
Jun 25, 2010, 1:42:08 PM6/25/10
to Qutensil
In that case you can even overwrite the show function and leave onShow
(onShow only exists to call restack() before show()).
So if you create a customized show function in your subclass, that
will work, as long as you call:

this.holder.appear()

or

this.holder.show()

somewhere to show your window.

wonderingwout

unread,
Jun 25, 2010, 1:57:17 PM6/25/10
to Qutensil
By the way, if you have specific feature requests, please let me know.
If we think they can improve Q.Window, we'll implement them.

andrew edmundson

unread,
Jun 25, 2010, 2:00:38 PM6/25/10
to qute...@googlegroups.com
Cool nice one, I don't want you to get naffed off with me keep emailing you.. lol


andy

wonderingwout

unread,
Jun 25, 2010, 2:03:45 PM6/25/10
to Qutensil
As long as it stays within the boundaries of 'support', we'll
manage ;-)

andrew edmundson

unread,
Jun 25, 2010, 2:13:59 PM6/25/10
to qute...@googlegroups.com
The only things I would find, others might too but maybe they wouldn't are:

Splitting the default show() method in Q.js to call onBeforeShow() before the window is shown and onAfterShow() after the window is shown, these could be skeleton methods with nothing in ready to override so for example if you load up a window with some ajax containing a login form / any form you would want an onAfterShow to run any js code on the form once its show and inserted into the DOM, this way would guarantee it would run in onAfterShow etc..

andrew edmundson

unread,
Jun 25, 2010, 2:24:02 PM6/25/10
to qute...@googlegroups.com
For your ref:

I have this In my subclass now and all working well...


show:function(force){
//leave this here - copied from main q.js show


if (Q.active != this || force)
{
this.positionHolder();
if (typeof this.setValue == "function" && this.input)
this.setValue(this.input.value);

//restack from qwindow onshow
this.restack();
Q.active = this;
//show the window
this.holder.show();
//window shown - run aftershow
(function() { this.onAfterShow() }).bind(this).delay(0.1);
}
},
onAfterShow: function(){
//center window if desired
if (this.options.centered)
this.center();
//Run js code passed back via ajax json object
if (this.options.execute){
try{ eval(this.options.execute);}catch(e){alert(e);}
}
},


Thanks for all your help again!

Ill show show you what im using it on once all my framework is in place!!

wonderingwout

unread,
Jun 25, 2010, 2:27:26 PM6/25/10
to Qutensil
I think a before and after show are irrelevant to the window class.
When you want to achieve that you'll nee to create the window instance
at another time.

Think about it, when should a beforeShow callback be sent out?
onShow is sent when the window is shown, and there are no window
related events before that (except initialization).

You will have to build an ajax function creating the Q.Window instance
when it is done loading.
In the meantime you can work with a pending of Q.Informer for example,
to indicate the loading process...

And the same thing with afterShow.
After showing the window itself, that's the end of the process, and
next steps should be defined by the wrapping function...

wonderingwout

unread,
Jun 25, 2010, 2:33:01 PM6/25/10
to Qutensil
I think it might be a better idea to create an AJAX window, or add
AJAX capabilities to the current class.
If it is 'aware' of the multiple states in a loading process, those
callbacks would make sense...

andrew edmundson

unread,
Jun 25, 2010, 2:37:37 PM6/25/10
to qute...@googlegroups.com
Yeah, that's the sort of angle im coming from as I currently have an ajax process that gets a json object containing some HTML to display, a window title, the windows size, whether its centered etc and any code to run after the window is shown. With talking to you its made me move more of the ajax stuff into the new subclass I created so I guess we are both on the same tracks with that...

wonderingwout

unread,
Jun 25, 2010, 2:43:47 PM6/25/10
to Qutensil
I'm curious to see your subclass in action.
You're actually the first to make your own (that I know of)...

andrew edmundson

unread,
Jun 25, 2010, 4:17:47 PM6/25/10
to qute...@googlegroups.com
Hi wout, this is my code so far....

I have a subclass of window that gets its content from a remote RPC url using JSON...

var win = new Q.AjaxWindow({
ajaxmethod:'get or post',
ajaxurl:'http://blahblah.com',
ajaxpostvars:'&var=val', //post vars if posting ajax request
ajaxgetvars:'&var2=val2', //get vars if normal ajax request
id: id,
style: className,
});

So the above for example is called from a link to login to my system...

Please feel free to use any of it if it is of use or let me know which bits are 'rubbish' so to speak... works really fast because of the small q.js footprint as opposed to stuff ive used before like xilinus prototype windows....very impressed with Q.

Things ill probably add are:

Update method - to pass a new url / params to the window.
Refresh method - to refresh the window via ajax with the current url/params.

Plus loads of bits to tweak...just added some css for visibility to fix being able to see the window shown in its default position before being centered.


Q.AjaxWindow = Class.create(Q.Window, {
initialize: function($super, options) {
// merge options
options = $H({
onHide : function(){this.remove();}.bind(this),
centered : (options && options.centered ? options.centered : true),
ajaxmethod : (options && options.ajaxmethod ? options.ajaxmethod : 'get')
}).merge(options || {})
.toObject();
var ajax = new Ajax.Request(options.ajaxurl,{
evalJSON:true,
parameters: options.ajaxgetvars,
method:options.ajaxmethod,
postBody:options.ajaxpostvars,
onFailure:function(request){
alert('AJAX call failed');
},
onSuccess:function(transport){
json = transport.responseJSON;
if (json){
if (json.title) options.title = json_decode(json.title);
if (json.draggable) options.draggable =json.draggable;
if (json.resizable) options.resizable =json.resizable;
if (json.width) options.width = json.width;
if (json.height) options.height = json.height;
if (json.content) options.text = json_decode(json.content);
if (json.execute) options.execute = json_decode(json.execute);
//initialise window (this will call build) as cant call ajaxwindow from here.
$super(options);
}
}
});

},
// build the ajax window
build: function($super) {
//override build - call superclass build then our subclass init stuff
$super();
this.ajaxwindow();
},
ajaxwindow:function(){
// window resize event keep the window central
this.onWindowResize = (function() {
this.center();
}).bind(this);
(document.onresize ? document : window).observe("resize", this.onWindowResize);

// create blocking cover
this.holder
.addClassName("q-window-blocking")
.setStyle({ zIndex: 99998 });

// create protective layer
this.protection = new Element("div")
.addClassName("q-protective-layer");
this.div
.insert({ top: this.protection });
this.protection
.hide();

this.protection.appear({ duration: 0, to: 0.5 });
this.show();

},


show:function(force){
//leave this here - copied from main q.js show

if (Q.active != this || force) {
this.positionHolder();
if (typeof this.setValue == "function" && this.input)
this.setValue(this.input.value);

Q.active = this;

this.holder.setStyle({visibility:'hidden'});
this.holder.show();
//show the window
//if (this.options.centered)
// this.center();


//window shown - run aftershow
(function() { this.onAfterShow() }).bind(this).delay(0.1);
}
},
onAfterShow: function(){

//restack from qwindow onshow
this.restack();

//center window if desired
if (this.options.centered)
this.center();

this.holder.setStyle({visibility:'visible'});


//Run js code passed back via ajax json object
if (this.options.execute){
try{ eval(this.options.execute);}catch(e){alert(e);}
}

},

// remove all elements and the instance itself as well
remove: function() {
this.protection.fade({ duration: 0.01 });
(function() {
try {
this.protection.remove();
//this.
// holder.
// remove();
delete this;
} catch(e) {
// well, we've tried
}
}).bind(this).delay(0.2);
},
center: function(){
var dim = document.viewport.getDimensions();
var layout = new Element.Layout(this.holder);
this.holder.setStyle({
left: (dim.width / 2) - (layout.get('width')/2) + 'px',
top: (dim.height / 2) - (layout.get('height')/2) + 'px'
});
this.holder.setOpacity(1);
}
})

Reply all
Reply to author
Forward
0 new messages