Work-rounds, kludges, and hacks - oh my!
Category Technical
Bookmark :
I am at a client site again this week, and while here I ran into two problems - and I wanted to share them with you, and the workarounds I came up with. Incidentally, both of these problems deal with Web/Domino development. The first problem concerns IE's window.showModalDialog method, and the other problem deals with document.forms[0].submit that doesn't submit.
Problem #1 - doing more with showModalDialog
In IE there is a method on the window object called showModalDialog. This method is similar to window.open, in that it allows you to launch a window as a dialog box. However, there are distinct differences. Window.open is a full-blown new browser window, and has all the functionality of a browser window; additionally it has properties such as window.opener, which provides access to the "parent" window object. This is extremely handy when creating very interactive dialog boxes that work with the parent document. The drawback to window.open is that the window it opens is "modeless", i.e. the parent window is independent of the dialog window, meaning the user can click away from the dialog and change the parent window, close it, etc. This can really mess up your workflow. I needed to have a "modal" dialog window that acts like a Notes dialog box, i.e. the user must close/clear the dialog before doing anything to the parent window. I found the window.showModalDialog method - and then I found some limitations with it.
Window.showModalDialog is great in that it provides a truly modal dialog, but it has some serious limitations when wanting to create interactive dialogs. The best way to think of window.showModalDialog is that it is simply a dialog - it gathers values and can return a value. It does not have any "real" relationship to the calling window, except that it returns a single value to the calling code. It does not have a window.opener property, and as stated earlier, when called it does not provide a handle to the dialog window through the calling code - it simply provides a single, scalar return value once the box is closed. This can seriously mess up your code if you have interactive dialogs. Another problem I found with showModalDialog - any and all links in the dialog, including "javascript:function" links, launch into a new window - not in the dialog window. This is also undesired behavior. So, how can you get around this? Well, since we're already writing IE-specific code, let's go ahead and use another IE-specific call - iFrames.
Solution #1 - use an iframe
I did some scrounging around on the net, and found that the best solution to this dilemma is to use an iframe, and load your dialog into that iframe. Translating this to Domino development, here's how I implemented this. I created a new form called dialogOpener. In this form I have a simple, single line of passthru HTML:
<iframe name="receivedDlg" width="100%" height="100%" src="/<computed text>/your_dlg?OpenForm&<computed text>" frameborder="0"></iframe>
The first computed text computes the relative path to the db, and the second computed text pulls the query string values off of the URL and passes them on to the "real" dialog form. By loading the "real" dialog form into the iframe, I get all the functionality that I want and I get a modal dialog box. But hold on - we do need to make a minor modification to our javascript in our dialog form. Remember that I said earlier that the showModalDialog method doesn't provide a window.opener object? Here's how you get around this. One of the parameters of the showModalDialog method is the dialogArguments parameter (refer to the link above for syntax). This allows you to pass an entity - a value, an object, etc. - to the modal dialog for processing. Well, you can pass the calling window to the modal dialog by using the self object, like this:
window.showModalDialog(your_url, self, your_args)
And then in the JSHeader of your dialog form you can retrieve the window.opener like this:
if (window.opener) {
parentdoc = window.opener.document
} else {
var dargs = window.dialogArguments;
parentdoc = dargs.document
};
This code checks for an opener object, and if one isn't found the object is retrieved from the dialogArguments property, which contains the self object passed in the showModalDialog method. Now your code will work as you originally designed it, with the added bonus of being a modal dialog.
The second problem seems to be related to the first solution - but I can't prove this for sure. Let's talk about problem #2.
Problem #2 - the document.forms[0].submit() that doesn't
Now I don't know if this problem is related to the solution previously described, but in any case it is a problem that was extremely frustrating. I found that my document.forms[0].submit() call was intermittent in my dialog boxes. It would work, and then it wouldn't, and then it would start working again, and there was no rhyme nor reason to when it would and wouldn't work. I did some searching on the net and found that others have encountered this as well. It appears that Domino can ignore the document.forms[0].submit() call when it is called from a dialog. The javascript code continues to run as if it were successful, but the changes made aren't saved to the document. The workaround that seems to work best is to replace the javascript submit() call with @Command([FileSave]); @Command([FileCloseWindow]). This works well as it consistently and reliably saves the dialog values to the document, but this workaround doesn't solve all my problems.
In my dialog box I am saving the values to a document, but also updating values in the parent window's document and then closing the dialog window. So I need the save to values, I need to update the parent window document, and I need to close the dialog window. I have a validate() javascript function call that needs to validate the dialog before saving and closing as well. I tried various combinations of window.close() in the javascript, all to no avail. So then it was time to venture into Kludgeland.
Solution #2 - getting weird with $$Return
I finally solved this by doing a couple of things. First, I placed my validate() function call in the onSubmit event - the validate() function returns a true/false, which in turn will stop the processing of the save/close. I then created a new form called dialogCloser. In this form I have a simple window.close() in the onLoad event. I then call the dialogCloser form in a $$Return field on my dialog form. So, if the dialog passes validation the dialogCloser form is launched, which immediately closes the dialog.
Conclusion
Yeah, I know these aren't pretty, but they got the job done, and I got the functionality that I and my client want. I wanted to make these available to hopefully save someone else the frustrations of figuring all of this out. Incidentally, if you have and similar problems and solved them differently, I would love to hear about it.
Enjoy!
Rock
**He looks like a dwarf who was dipped in a barrel of pubic hair. -- Boy George on Prince







Blog Roll









Comments
I've been reading many articles and blogs about this problem.
The iframe solution seems to be the most common workaround.
But this solution (like Leon said) was the simplest and it worked for me:
putting <base TARGET="_self"> in the head section of the page.
Dangeriz
Posted by Dangeriz At 08:36:26 AM On 02/16/2005 | - Website - |
Get this book....
http://www.amazon.com/exec/obidos/tg/detail/-/1565924940/qid=1062077490/sr=8-1/ref=sr_8_1/002-1247701-5133653?v=glance&s=books&n=507846
Covering HTML, JavaScript, DOM and CSS, it is a must have for any web application developer.
Best of Luck.
Posted by mac guidera At 10:14:35 AM On 10/31/2003 | - Website - |
in the initialise code (via OnLoad) place this code
window.name='fred';
then in the html form tag use: <FORM ID=frm NAME=frm ... TARGET="fred"> you'll find that when you submit the form with document.frm.submit(); it will load into the same dialog.
the only problem i've found is that the title of the dialog is lost - any ideas how to rectify this?
Posted by Si At 10:29:22 AM On 06/15/2005 | - Website - |
Posted by Miracle At 03:20:32 PM On 07/20/2005 | - Website - |
Rock
Posted by Rock At 10:14:34 AM On 10/31/2003 | - Website - |
Posted by Sesh At 10:19:59 AM On 06/20/2006 | - Website - |
"onBlur=\'self.focus()\'"
so then the form would crank out something like:
<body onBlur='self.focus()'>
that will keep the window on top and basically force the user to do something with it (unless they have javascript turned off). might be an easier way to go, depending on your workflow.
i've worked with the showModalDialog thing, i thought it was pretty darn cool. of course, it was on an intranet where IE is the supported browser. but still, it did exactly what i wanted it / needed it to do. i guess its all in the requirements...
Posted by jonvon At 10:14:35 AM On 10/31/2003 | - Website - |
problem is
i have a parent page with one text box and button. clicking on the button the page will open using showmodaldialog() method.and i have some set of values in the child window. if i add one value the value should return to the parent window.
but i was not able to do this the child window value is stored in the window.opener.document.forms['formname'].elements['fieldname'].value='value';
any solution for this problem
sathish
Posted by sathish At 05:14:14 AM On 01/17/2005 | - Website - |
I didn't even need the iframe, just had to get a reference to the window opener to make what I already had work right.
Some people just need to relax a little and realize there is always a situation that merits the use of a bit of unorthodox code.
Posted by Brett Stinson At 03:44:27 PM On 02/21/2006 | - Website - |
Posted by Prasanth NV At 10:33:35 AM On 09/16/2004 | - Website - |
Best regards
Leon
Posted by Leon Jollans At 08:28:03 AM On 12/02/2004 | - Website - |
...can a fool who knows their wisdom still be called fool...
Posted by wise fool At 05:52:56 AM On 12/15/2004 | - Website - |
function closePopup(formName, eventTarget)
{
if (formName != null && eventTarget != null)
{
var da = window.dialogArguments;
var theform;
theform = da.document.forms[formName];
theform.__eventTarget.value = eventTarget;
theform.__eventArguments.value = "frompopup";
theform.submit();
}
window.close();
}
Basically on some browsers theform variable is giving output as undefined. i could not resolve this problem.
If anyone knows the solution, please reply it to me
Thanks
Posted by Deepali At 06:03:47 AM On 06/16/2005 | - Website - |
Posted by Marcin At 10:14:34 AM On 10/31/2003 | - Website - |
Rock
Posted by Rock At 10:23:27 AM On 01/17/2005 | - Website - |
Posted by shreyas At 10:14:59 AM On 04/19/2005 | - Website - |
For a CSS web reference, try http://www.alistapart.com.
Posted by Stan Rogers At 10:14:34 AM On 10/31/2003 | - Website - |
I tried <body onBlur='self.focus()'> . The problem I face is that I have 2 drop down lists in my modal popup window & I cannot select anything from the dropdown. Is there any way to olve this issue ?
Thanks
SD.
Posted by SD At 05:32:30 PM On 05/18/2004 | - Website - |
Posted by At 10:01:21 PM On 05/25/2005 | - Website - |
And, with looking at my Visibone chart, iframe and ilayer are both part of the W3.org definition, but iframe is not supported in IE and ilayer is Netscape 6 and under only. Mozilla seems to support both.
Posted by John At 10:14:35 AM On 10/31/2003 | - Website - |
Posted by Miracle At 03:23:57 PM On 07/20/2005 | - Website - |
Keep the sharing spirit on.
- thanks
vishal
Posted by vishal At 05:37:13 AM On 04/15/2005 | - Website - |
Posted by jeffrey At 02:12:53 PM On 06/23/2005 | - Website - |
Rock
Posted by Rock At 08:03:51 AM On 04/14/2005 | - Website - |
"wise fool" - thanks for the support - and I agree with you
Oh, and I love that this post keeps getting traffic from Experts Exchange. Tres' kewl...
Rock
Posted by Rock At 10:29:54 PM On 12/15/2004 | - Website - |
makes the opener window refreh after the modal dialog closed..
Posted by Neslihan Kırımlı At 01:22:32 PM On 06/09/2005 | - Website - |
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>New Page 1</title>
<SCRIPT language='javaScript' src="validate.js"></script>
<script language='javascript'>
var confirmMessage = '';
var confirmFlag = false;
function checkFocus()
{
if (window.navigator.appVersion.indexOf("MSIE")==-1)
{
if ( modalWin != null && !modalWin.closed )
{
self.blur();
modalWin.focus();
}
}
}
function deleteBul()
{
var del = openConfirmDialog('Are you sure you want to delete this building?');
if (del)
{
alert('weclome');// i need to inter
// here when press ok from the
//ConfirmDialogE.html
}
}
function openConfirmDialog(message)
{
confirmMessage = message;
confirmFlag = false;
//window.showModalDialog("ConfirmDialogE.html", window, "dialogWidth:375px;dialogHeight:150px;scroll:no;resizable:no;status:no;help:no;");
window.open("ConfirmDialogE.html", '','dialogWidth:400px;dialogHeight:150px;scroll:no;resizable:no;status:no;help:no;');
return confirmFlag;
}
</script>
</head>
<body onload="checkFocus();">
<from id='frm'>
<div id='save' ></div>
<table width="188">
<tr>
<td>window.opener();</td>
<td class="tableCellNormal" width='14%'>
<A href="javascript:deleteBul()" >Delete</A>
</td>
</tr>
</table>
</from>
</body>
</html>
ConfirmDialogE.html is
<html>
<head><title>Confirm</title>
<script language='javascript'>
function ok(){
//dialogArguments.confirmFlag = true;
opener.confirmFlag = true;
window.close();
}
function cancel() {
//dialogArguments.confirmFlag = false;
opener.confirmFlag = false;
window.close();
}
function confirmMessage(){
document.getElementById('validationTD').innerHTML =""+ opener.confirmMessage;
}
</SCRIPT>
</head>
<body onload='confirmMessage()'>
<table width="100%" border="0" align="center" dir=ltr>
<tr>
<td width="12%" align="left"><img src="QuestionMark.jpg" width="54" height="53"></td>
<td width="88%" class ='StanderdFont' align="center" id="validationTD"> </td>
</tr>
<tr>
<td colspan="2" class='StanderdFont' align='center' dir=ltr height='75%' valign=top > </td>
</tr>
<tr align="center">
<td colspan="2">
<img style="CURSOR:hand" src="yes.jpg" border=0 onclick='ok()' >
<img style="CURSOR:hand" src="no.jpg" border=0 onclick='cancel()'>
</td>
</tr>
</table>
</body>
</html>
please help me????
Posted by ahmad At 03:22:54 AM On 01/03/2005 | - Website - |
Posted by ilgian At 04:08:03 AM On 06/01/2005 | - Website - |
That methods is so powerful. ^^
Posted by Lak At 07:26:14 AM On 04/14/2005 | - Website - |
Do you know why there isn't a modal dialog in the W3C standards? Because they're a bad design decision in the first place. You're thinking like a Notes developer working on the web -- stop that!
If you really want to present something like that, make a hidden DIV that has the info you want, then use CSS-P to absolute position it on the page at the top Z-index. Make yourself an artificial "OK" button that just hides the DIV again. *That's* web development. :)
Posted by Nathan T. Freeman At 10:14:34 AM On 10/31/2003 | - Website - |
Nice to see a place where people discussing something related to my problem...sir i want a solution for this...hope you people can find it out.
My form is containing an Iframe and it is opening a dialog window... my problem is i want to refresh the parentform of that iframe on submit of that dialogwindow....i am able to refresh the iframe but i want to get a hold of iframe and refresh its parent.......
can you please help me....
chaitu
Posted by chaitanya At 01:03:53 PM On 01/05/2005 | - Website - |
More on this later.
Posted by Andrew Pollack At 10:14:34 AM On 10/31/2003 | - Website - |
http://www.bradsoft.com/topstyle/
Posted by Mike Munnis At 10:14:35 AM On 10/31/2003 | - Website - |
Posted by At 12:02:13 PM On 04/28/2005 | - Website - |
It is very good work around to use Iframe, but iam not able to close this window using document.close()
Posted by chakra At 06:19:45 AM On 03/03/2004 | - Website - |
Posted by Stephan H. Wissel At 10:14:34 AM On 10/31/2003 | - Website - |
unfortunately this base tag does not help in Domino environment because of the javascript generated by Domino. Thank you Rocky for the good workaround, just one improvement to avoid dialogCloser form:
1. make an ERRORS_CFD field that makes server side checks
2. make submit button like this
@Command( [FileSave] );
@If( ERRORS_CFD = ""; @Command( [FileCloseWindow] ); "" )
3. put $$Return field like this
@If( ERRORS_CFD = "";
"<script>window.dialogArguments.RETURN_FIELD.value = 'okay'; window.close()</script>";
"" )
Posted by Anton Apostolov At 05:23:00 PM On 12/09/2004 | - Website - |