PDA

View Full Version : multiple dialogs because of dynamic content



PurpleNurple
2 Feb 2007, 5:20 AM
Hi,

I have a page which loads into my site via async request and on this page there is a dialog (works fine), issue is when that dynamic page comes in a second time and i run this code. (i know i might not be explaining that very well, i have a center content region and a script that loads a page into it via async, on load of that page a dialog is setup. if you request the page multiple times, multiple dialogs are created right below the body tag)



document.body.insertBefore(dlgEl.dom, document.body.firstChild);


since there was already an element there from the first time this script is run it creates a second, which breaks all of my events. how can i destroy the previous dialog if one already existed

tryanDLS
2 Feb 2007, 7:06 AM
Look at all the examples that create dialogs. They all do lazy creation of dialogs and only build it the 1st time thru.

PurpleNurple
2 Feb 2007, 7:27 AM
thank you for replying, as far as i can tell i am doing 'lazy' load of the dialog as the docs suggest



showDialog : function(){
if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new YAHOO.ext.LayoutDialog("hello-dlg", {
modal:true,
width:600,
height:400,
shadow:true,
minWidth:300,
minHeight:300,
west: {
split:true,
initialSize: 150,
minSize: 100,
maxSize: 250,
titlebar: true,
collapsible: true,
animate: true
},
center: {
autoScroll:true,
tabPosition: 'top',
closeOnTab: true,
alwaysShowTabs: true
}
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog);

var layout = dialog.getLayout();
dialog.beginUpdate();
layout.add('west', new YAHOO.ext.ContentPanel('west', {title: 'West'}));
layout.add('center', new YAHOO.ext.ContentPanel('center', {title: 'Inner Tab'}));
dialog.endUpdate();
}
dialog.show(showBtn.dom);
}

tryanDLS
2 Feb 2007, 7:31 AM
You could add code to check the dom in addition to looking for a variable name.

Or, you might consider rearranging your code. Why do you need to build the dialog every time? Why not build it once and just load the content via Ajax to update the dialog body?

PurpleNurple
2 Feb 2007, 7:37 AM
i think i figured it out (maybe), i am moving the element to beneath the body tag in the 'init' function, this is basically a sample copy/pasted right out of docs (aside from the 'insertBefore' that i put in), but that the page that contains this script comes in via async

here is the full code for the page


<script language="javascript">
var LayoutExample = function(){

var dialog, showBtn;

var toggleTheme = function(){
getEl(document.body, true).toggleClass('ytheme-gray');
};
// return a public interface
return {
init : function(){
showBtn = getEl('show-dialog-btn');
showBtn.on('click', this.showDialog, this, true);

getEl('theme-btn').on('click', toggleTheme);

var dlgEl = getEl('hello-dlg');
document.body.insertBefore(dlgEl.dom, document.body.firstChild);
},

showDialog : function(){
if(!dialog){ // lazy initialize the dialog and only create it once
dialog = new YAHOO.ext.LayoutDialog("hello-dlg", {
modal:true,
width:600,
height:400,
shadow:true,
minWidth:300,
minHeight:300,
west: {
split:true,
initialSize: 150,
minSize: 100,
maxSize: 250,
titlebar: true,
collapsible: true,
animate: true
},
center: {
autoScroll:true,
tabPosition: 'top',
closeOnTab: true,
alwaysShowTabs: true
}
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);
dialog.addButton('Submit', dialog.hide, dialog);

var layout = dialog.getLayout();
dialog.beginUpdate();
layout.add('west', new YAHOO.ext.ContentPanel('west', {title: 'West'}));
layout.add('center', new YAHOO.ext.ContentPanel('center', {title: 'Inner Tab'}));
dialog.endUpdate();
}
dialog.show(showBtn.dom);
}
};
}();

YAHOO.ext.EventManager.onDocumentReady(LayoutExample.init, LayoutExample, true);
</script>

<div id="hello-dlg" style="visibility:hidden;">
<div class="ydlg-hd">Layout Dialog</div>
<div class="ydlg-bd">
<div id="west" class="ylayout-inactive-content">
West
</div>
<div id="center" class="ylayout-inactive-content">

<input type="button" id="theme-btn" value="Toggle Theme" />
</div>
</div>
</div>

<input type="button" id="show-dialog-btn" value="Show Dialog" />



your suggestion is exactly what i'm trying to accomplish. I don't want to load all the app's dialogs unless they are going to be used, so i planned on letting developers define dialogs where needed. i don't need to create it every time, but just the first time. looking for a clean way to accomplish this.

or, were you suggesting to only create 1 dialog object that will be used as a container for all dialogs and just use the code coming in from async to update the content? (that does sound better)

PurpleNurple
4 Feb 2007, 8:11 AM
Or, you might consider rearranging your code. Why do you need to build the dialog every time? Why not build it once and just load the content via Ajax to update the dialog body?


can you show me an example of how to do this? i know how to use updateManager to bring in new content, but that new content might need a new layout to display. (i posted about this in another thread) I either need to re-build the layout before the content is brought in- or have the content being brought in have the code to re-build the layout (which i would prefer), but i can't figure out how to access the layout object outside of the class that created it.

would most appreciate any help

Animal
4 Feb 2007, 8:17 AM
You'll have to inform the server about the layout needed - container names and all that.

I had to do this with my ListManager class. The detail panel was pulled in from a servlet, and that servlet had to be passed the id of the container into which it was being rendered, and also the name of the controlling ListManager object. I have my ListManagers register themselves in an array in application namespace. "Aspicio.widget.ListManagers[name]"

Basically, you'll have to come up with a scheme for letting the generated and loaded code know about the environment it's operating in.

PurpleNurple
4 Feb 2007, 10:35 AM
ok, i can probably put together a scheme to communicate the layout back to the server- but i think the issue i'm having is a bit more fundamental. how to actually modify the layout.



{what_layout_object_do_i_call}.beginUpdate();

Animal
4 Feb 2007, 12:37 PM
Surely you as the page author know that, and have to pass the id (as an index into an Array) back to the server so that it can generate code which manipulates that layout.

PurpleNurple
4 Feb 2007, 12:51 PM
i 'thought' i knew what layout object to call, that is why i say my problem is more fundamental- here is the code i use to create the dialog initially (pretty much right out of the examples).



var objLayoutDialog = function(){

var dialog, showBtn;

// return a public interface
return {
init : function(){
var dlgEl = getEl('mkpDialog');
document.body.insertBefore(dlgEl.dom, document.body.firstChild);
},

showDialog : function(elm){
if(!dialog){ // lazy initialize the dialog and only create it once

showBtn = getEl(elm);
dialog = new YAHOO.ext.LayoutDialog("mkpDialog", {
modal:true,
width:600,
height:400,
shadow:true,
minWidth:300,
minHeight:300,
west: {
split:true,
initialSize: 150,
minSize: 100,
maxSize: 250,
titlebar: true,
collapsible: true,
animate: true
},
center: {
autoScroll:true,
tabPosition: 'top',
closeOnTab: true,
alwaysShowTabs: true
}
});
dialog.addKeyListener(27, dialog.hide, dialog);
dialog.addButton('Close', dialog.hide, dialog);

var layout = dialog.getLayout();
dialog.beginUpdate();
layout.add('west', new YAHOO.ext.ContentPanel('west', {title: 'Menu'}));
layout.add('center', new YAHOO.ext.ContentPanel('center', {title: 'Content'}));
layout.add('center', new YAHOO.ext.ContentPanel('center2', {title: 'Content2', closable: true}));
dialog.endUpdate();
}
dialog.show(showBtn.dom);
}
};
}();


YAHOO.ext.EventManager.onDocumentReady(objLayoutDialog.init, objLayoutDialog, true);


then later on down the road i'm trying to call


objLayoutDialog.getLayout() so i can modify it, but that does not work (says objLayoutDialog has no properties)- i don't know enough about javascript to access that 'dialog' object i created in the class, how do i do it?

Bobafart
4 Feb 2007, 2:19 PM
why dont you use the update manager to load the content into the dialog?

http://www.yui-ext.com/deploy/yui-ext/docs/output/YAHOO.ext.UpdateManager.html

why not do something like (from Jack's code):



var el = getEl('foo');
var mgr = el.getUpdateManager();
mgr.update('http://myserver.com/index.php', 'param1=1&param2=2');


where parameter1 is the id of the content you wish to query from your database.

and 'foo' is the id of the articlebody <div>

and create the dialog <div> in the markup once only

--

for the more experience yui-ext users, is this not a decent solution to his problem?

PurpleNurple
4 Feb 2007, 7:44 PM
that works perfectly fine but as i said before


i know how to use updateManager to bring in new content, but that new content might need a new layout to display.

i get the feeling i'm not explaining this properly so i'll try again. i have a main layout page that loads a layoutDialog object but does not populate it (i have an empty layout dialog to use as a shell)- all is good.

i then bring another page somewhere using ajax that needs to modify not only the content of the dialog (which i can handle) but also the 'layout' of the layoutDialog. (maybe i need to add another content panel)- this is where i'm stuck.

this is what i'm doing wrong, i have


var objLayoutDialog = function(){

var dialog, showBtn;

// return a public interface
return {
init : function(){
var dlgEl = getEl('mkpDialog');
document.body.insertBefore(dlgEl.dom, document.body.firstChild);
},

i have pasted the full code a few times in this thread, this also includes the 'showDialog' method that builds the layout


var layout = dialog.getLayout();
dialog.beginUpdate();
layout.add('west', new YAH.... etc...


now here 'layout' is a private variable so in my ajax page i cannot access it, what i am trying to do is


objLayoutDialog.getLayout();

so that i can update it, but this is not the proper way of getting the layout- that is what i need to know how to fix.

tryanDLS
4 Feb 2007, 8:44 PM
I think you need to take a step back and learn some more javascript - specifically variable scopingand objects. How can code something like objLayoutDialog.getLayout() when that method doesn't even exist in your object?

zaps
4 Feb 2007, 9:16 PM
try this
declare your "var dialog " at the top of js file may be it works

Animal
5 Feb 2007, 1:51 AM
You can always retreeve references to Dialogs given the id ("mkpDialog" in your case):

http://www.yui-ext.com/deploy/yui-ext/docs/output/YAHOO.ext.DialogManager.html#get

LayoutDialog allows you to access its layout manager:

http://www.yui-ext.com/deploy/yui-ext/docs/output/YAHOO.ext.LayoutDialog.html#getLayout

PurpleNurple
5 Feb 2007, 4:56 AM
How can code something like objLayoutDialog.getLayout() when that method doesn't even exist in your object?


i know that would not work, i said that would not work- and that the 'dialog' variable was private to that method, so the question was how do i get the layout object. i knew given that example you would know what i was trying to do. you know, i think 97% of all questions on this forum could be answered with the standard 'learn more javascript, rtfm, etc..etc..'. i am trying, so please bare with me.

zaps, thanks for the tip but i had already tried that and it does not seem to work (although i thought it would too and am still wondering why it doesn't :))

animal, that seems it may be what i need- i will give it a try with the get() method then try to get the layout object, thank you.

PurpleNurple
5 Feb 2007, 10:01 AM
ok, i am officially going insane (although i am getting closer)- all my code is the same except my objLayoutDialog object now has this method


getLayout : function(dlg){
var tDialog;
tDialog = YAHOO.ext.DialogManager.get(dlg);

return tDialog.getLayout(tDialog);
},


called from some other page like so


tLayout = objLayoutDialog.getLayout('mkpDialog');


thinking this will return me my layout object (it doesn't)- after some debugging i noticed that the issue is in the 'get()' method of dialogManager


get : function(id){
return typeof id == 'object' ? id : list[id];
},


in my case the list object is empty, should i not have 1 item in 'list' for each dialog i have created? i noticed the 'register' function is what populates list, but i'm guessing that is supposed to be a private function (since it's not in the docs) that gets called internally. i registered it manually which did put my object in the list array but opened up other issues so i quickly took that out

can anybody tell me what is going on?

PurpleNurple
5 Feb 2007, 8:55 PM
can anyone help me out with this? if i'm doing nothing wrong this appears to be a bug but i can't believe it would not have been found- how does the 'list' array from dialogManager get populated? given my previous code, why would the get() function not work?

brian.moeskau
5 Feb 2007, 9:33 PM
It's hard to tell unless you post a full code sample, including your complete class and your complete calling code, but I'll take a stab at it. You are defining a class 'objLayoutDialog' with the methods init, showDialog and getDialog. This class is declared as a singleton, but the dialog instance that is internal to the class will not actually get created until you call objLayoutDialog.showDialog() since the dialog is lazy-instantiated (starts off undefined when the class is created). So, the way things are set up, you MUST call showDialog BEFORE attempting to retrieve your dialog, else it will not yet exist -- is this your issue? Another thing about this is that since your dialog object is stored off inside the class as a class variable, you should not even need to pass the id back into getLayout. Instead of


var tDialog;
tDialog = YAHOO.ext.DialogManager.get(dlg);
return tDialog.getLayout(tDialog);
you should be able to simply say

return dialog.getLayout();
I've never actually done this and I don't see .getLayout() in the docs for BasicDialog, but I assume that this is a valid method? But the point is how you're referencing the dialog instance to begin with. If it doesn't exist yet, make sure it gets created first.

If you still can't get it solved, please post your complete current code, including the caller.

PurpleNurple
6 Feb 2007, 5:11 AM
YES! that was exactly it, so simple- i had not created the dialog before the ajax request was made- thank you very much for setting me straight. everything else is working like a charm now (including modifying the layout after ajax requests !) :D