• Do not register here on develop.twiki.org, login with your twiki.org account.
• Use View topic Item7848 for generic doc work for TWiki-6.1.1. Use View topic Item7851 for doc work on extensions that are not part of a release. More... Close
• Anything you create or change in standard webs (Main, TWiki, Sandbox etc) will be automatically reverted on every SVN update.
Does this site look broken?. Use the LitterTray web for test cases.

Item5569: ActionTracker: safely closing the pop-up window

Item Form Data

AppliesTo: Component: Priority: CurrentState: WaitingFor: TargetRelease ReleasedIn
Extension ActionTrackerPlugin Enhancement Waiting for Feedback TWiki:Main.SeanCMorgan n/a 4.1.0, 4.2.0

Edit Form Data

Summary:
Reported By:
Codebase:
Applies To:
Component:
Priority:
Current State:
Waiting For:
Target Release:
Released In:
 

Detail

Here's a javascript fix to safely close the pop-up window for edit action items:
<script language='JavaScript' type='text/javascript'>
   // If arrived here (which is possibly an old meeting) from the
   // action editor, the data has already been successfully saved.
   // So it is now safe to reload the opener, and close this window.
   myRE = /skin=action%2cpattern;atp_action/;
   if (document.referrer.match(myRE)) {
      window.opener.location.reload(true); // 'true' forces the cache to be ignored
      window.close();
   }
</script>

After editing an action item, the pop-up window displays the topic that the action item was created in: if you are using this for meeting minutes, that will usually be the minutes for a previous meeting and not the current one. So to implement this, the script needs to appear in each topic where items are created, so that the old minutes are closed, and the new ones are reloaded. If you have used a template (e.g., MeetingViewTemplate), just put it in there, and you're done.

Further enhancement: when it reloads the parent, it's at the top of the page, rather than at the position where the 'edit' link was first clicked. The user has to scroll-down to see the change. Obviously a 'name' tag on the item and reload would help.

-- TWiki:Main/SeanCMorgan - 27 Apr 2008

Sounds good.

  1. Does this work on all the commonest browsers (Firefox, IE, Safari)?
  2. Your RE is specific to pattern skin, which is too inflexible. It might be better to use some unique parameter - for example, myRE = /atp_return=thisisuniquetoaviewafteranactionedit/. That way you are not limiting it to use with =pattern skin. However care has to be taken to ensure that parameter doesn't get passed on to other URLs (e.g. REST calls).
  3. It is possible to determine a scroll position for a window that could be passed on to the action editor, and then targeted in the return.
function getScrollPosition() {
    var y = ((typeof window.pageYOffset != 'undefined') ? window.pageYOffset : document.scrollTop);
    var x = ((typeof window.pageXOffset != 'undefined') ? window.pageXOffset : document.scrollLeft);
    return {x: x, y: y};
};
Then, when the document is shown again, you just:
        window.scrollTo(x, y);
Of course this requires some additional logic in the perl code. If you passed the scroll location as the value of the atp_return parameter, you could kill two birds with one stone.

i look forward to checking in your patch.....

-- CrawfordCurrie - 12 May 2008

  1. It works on IE6 and IE7, and should work on all but ancient browsers (according to http://en.wikipedia.org/wiki/Comparison_of_web_browsers#JavaScript_support).
  2. Yes, searching for pattern was bad (what was I thinking?). Until atp_return is available (next item), the combination of /bin/edit and atp_action should be sufficient to detect the desired state. Adding the line alert(document.referrer) for debugging provides the string
    <protocol>://<host>/bin/edit/<topic>?skin=action%2cpattern;atp_action=<uid>;...
    So a better Regular Expression would be
    myRE = /.*\/bin\/edit\/.*\?.*;atp_action=\d*;.*/;
  3. That's cool. I looked for something like that a while ago for another app and couldn't find anything. I'll definitely look into it.

-- TWiki:Main.SeanCMorgan - 12 May 2008

On point #3, here a fix for the scrolling

Just before the pop-up closes, the parent browser window is reloaded to ensure that the updated information is displayed. Unfortunately a reload leaves the browser at the top of the page instead of where the 'edit' link was clicked. If there are a lot of action items on the pge, it can take time find where we were. A javascript modification was used to write the scroll offset into the topic itself, and to scroll back down to it.

Perhaps it's a bit of overkill, but it updates the scroll position every second, so that the correct value is used when an 'edit' link is clicked.
[SMELL: instead of polling, add an onclick call to ActionTracker's edit links?].

There are two components to this hack: 1) an invisible 'div' tag, and 2) custom javascript:

  1. The div tag (<div id="DivPos" style="display:none;"></div>) serves two purposes:
    1. It stores the location that the browser is currently scrolled to.
    2. By placing the <div> at the end of the document, the fact that it can be accessed means that the page has fully loaded. The page can then be scrolled down to the saved position. [SMELL: I had difficulty detecting when the page was finished loading, and finally settled on this method, even though it means more of a lag before the pop-up window can close. Normally the scrollTo command would be included in the onLoad event, but it isn't accessible in TWiki?]
  2. The javascript to close the edit window isn't quite so simple anymore...
<script language='JavaScript' type='text/javascript'>
    myRegExp = /.*\/bin\/edit\/.*\?.*;atp_action=\d*;.*/;
    if (document.referrer.match(myRegExp)) {
        // Arrived here (which is possibly an old meeting) from the action
        // edit window, which means the data was successfully saved. So it
        // is now safe to reload the opener and close this window.
        yOffset = window.opener.DivPos.innerHTML;
        window.opener.location.reload(true); // 'true' forces cache to be ignored
        scrollAfterLoad(yOffset); // Can't scroll down before the page has loaded
    } else {
        setInterval("scrollPos()", 1000); // Start polling for scroll position
    }

    function scrollAfterLoad(yOffset)
    {
        try {
            window.opener.DivPos.innerHTML; // The page has loaded if DivPos is accessible.
        } catch(err) {
            setTimeout('scrollAfterLoad(yOffset);', 250); // wait then try it again
        }
        if(!err) {
            // *Not* part of 'try', else the window will close. Only do this if 'try' worked.
            window.opener.scrollTo(0,yOffset);
            window.close();
        }
    }

    function scrollPos() {
        // Browser-tolerant detection of scroll position, from http://javascript.about.com/library/blbomfunc.htm
        DivPos.innerHTML =
            typeof window.pageYOffset != 'undefined' ?
            window.pageYOffset :
            document.documentElement && document.documentElement.scrollTop ?
            document.documentElement.scrollTop :
            document.body.scrollTop;
    }
</script>

-- TWiki:Main.SeanCMorgan - 20 May 2008

Crikey Sean, that one is almost worthy of a "most obscure solution" award! wink

I don't understand why this wouldn't work; assume there is an 'onclick' handler on action edit links. That handler does this:

function onclick_actionEdit(e) {
    if (!e) var e = window.event; // IE
    var targ;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    while (targ && (targ.nodeType == 3 || targ.tagName != "A"))
        targ = targ.parentNode;
    if (!targ) return true;
    var y = ((typeof window.pageYOffset != 'undefined') ? window.pageYOffset : document.scrollTop);
    var x = ((typeof window.pageXOffset != 'undefined') ? window.pageXOffset : document.scrollLeft);
    targ.href += ";atp_return=" + x + "," + y;
    return true;
}
then using your first code again:
   // If arrived here (which is possibly an old meeting) from the
   // action editor, the data has already been successfully saved.
   // So it is now safe to reload the opener, and close this window.
   if (var match = /atp_return=(\d+),(\d+)/.exec(document.referrer)) {
       var opener = window.opener;
       window.close();
       opener.location.reload(true); // 'true' forces the cache to be ignored
       opener.scrollTo(match[1], match[2]);
   }
I haven't tried this, but I think it should work. OK, so it won't always scroll to exactly the right place, but it seems a lot simpler to me....

-- CrawfordCurrie - 21 May 2008

ok, to ask a stupid q, why are you not using twistie plugin to show&hide your 'popup'? It works, and is already in the default install.

Basically, if you have a twistie that contains a div that you position:absolute, and otherwise style, you get popup dialogs.

-- TWiki:Main.SvenDowideit - 21 May 2008

For that matter, why am I not using Dojo widgets? Because the action tracker predates all of that, that's why. Some day I'll recode it to make use of all the new features that have come along since it was written, but not any time soon, I fear.

-- TWiki:Main.CrawfordCurrie - 21 May 2008

ItemTemplate
Summary ActionTracker: safely closing the pop-up window
ReportedBy TWiki:Main.SeanCMorgan
Codebase 4.1.0, 4.2.0
SVN Range TWiki-5.0.0, Tue, 15 Apr 2008, build 16676
AppliesTo Extension
Component ActionTrackerPlugin
Priority Enhancement
CurrentState Waiting for Feedback
WaitingFor TWiki:Main.SeanCMorgan
Checkins

TargetRelease n/a
ReleasedIn 4.1.0, 4.2.0
Edit | Attach | Watch | Print version | History: r9 < r8 < r7 < r6 < r5 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r9 - 2008-09-18 - SeanCMorgan
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2018 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback