cancel
Showing results for 
Search instead for 
Did you mean: 

Making association links work (high-level advice needed)

hbf
Champ on-the-rise
Champ on-the-rise
Like some others, I want the Web Client user to be able to click on an association in the "Details of" dialog of a node (node A, say). What would show up then is the "Details of" dialog of the content node at the end of the association (let's call it node B). Ideally, if the user clicks the "Close" button of the latter dialog, she would be back in the origin "Details of" dialog, the one of node A.

I tried to implement this and have almost succeeded. (Again, like in the case of my AMP for TinyMCE textareas in the Web Client, I want to make the result available to others in form of an AMP.)

The problem I have run in is that when the user clicks on an association, the browser visits the correct URL (showDocDetails with the noderef of B) but still, the properties of node A are shown (see this issue also).

I just need some high-level advice to be able to continue working! Can somebody help?

1. Is it correct that the problem is due to a dialog/wizard being open? (As mentioned in the issue, the link to B works if you first close the dialog and enter the link into the browsers URL textfield.)

2. Provided my assumption 1. holds, what would be the way to go to alter this dialog? I guess I would have to add ANOTHER dialog (the one for B) onto the dialog stack. Would I use the Dispatch Mechanism for this? I have the feeling I need to alter showDocDetails (i.e., the filelink-details.jsp behind it) and replace it with a version that pushes on the dialog stack…

I am grateful for any guiding sentences!

Kaspar
13 REPLIES 13

rivarola
Champ on-the-rise
Champ on-the-rise
Hello Kaspar,

I don't think the dispatch mechanism would help in your case.
If I understand what you've done, you've developped a custom AssociationEditor (and Generator) to show associations as links. I think it is OK as far as the link opens the document, but if you want the link to open the document details, generating a JSF event would probably more accurate. You could define an action listener for your custom editor action components, change the BrowseBean target document and open a new dialog on top of previous.
I'm not sure it would work, maybe the restored dialog state would not be enough to display node A when you close dialog showing node B, but I think working in the JSF/Alfresco-dialog-framework world would offer more tools than using URLs.

hbf
Champ on-the-rise
Champ on-the-rise
Hi Rivarola,

Thanks for your reply. Yes, you are correct: I added a custom AssociationEditor and Generator to show associations as links.

Regarding your other comments, I need more help (I have not much experience with JSF, sorry). Could you, or some other Alfresco engineer, outline in more detail what needs to be done? (Or is there an small example I could use as a starting point?)

It would really be nice to have such a feature in Alfresco. It seems so basic and makes life so much easier for the editors that use the Web Client to browse nodes and edit them.

Some concrete questions I have:

1. In Rivarola's approach, I would still use a custom AssociationEditor and Generator, right?

2. I understand correctly that instead of using simple URLs, as I do now:

  /**
   * (Based on Alfresco 2.1.)
   */
  protected void renderReadOnlyAssociations(FacesContext context, ResponseWriter out, NodeService nodeService) throws IOException
  {
     if (this.originalAssocs.size() > 0)
     {
        out.write("<table cellspacing='0' cellpadding='2' border='0'>");

        Iterator iter = this.originalAssocs.values().iterator();
        while (iter.hasNext())
        {
           out.write("<tr><td>");
           ChildAssociationRef assoc = (ChildAssociationRef)iter.next();
           NodeRef targetNode = assoc.getChildRef();
           // if the node represents a person, show the username instead of the name
           if (ContentModel.TYPE_PERSON.equals(nodeService.getType(targetNode)))
           {
              out.write(User.getFullName(nodeService, targetNode));
           }
           else if (ContentModel.TYPE_AUTHORITY_CONTAINER.equals(nodeService.getType(targetNode)))
           {
              // if the node represents a group, show the group name instead of the name
              int offset = PermissionService.GROUP_PREFIX.length();
              String group = (String)nodeService.getProperty(targetNode,
                    ContentModel.PROP_AUTHORITY_NAME);
              out.write(group.substring(offset));
           }
           else
           {
              /* Original:
              out.write(Repository.getDisplayPath(nodeService.getPath(targetNode)));
              out.write("/");
              out.write(Repository.getNameForNode(nodeService, targetNode));
              */
             out.write("<a href=\"/alfresco/navigate/showDocDetails/workspace/SpacesStore/");
             out.write(targetNode.getId());
             //out.write("/");
             //out.write(Repository.getNameForNode(nodeService, targetNode));
             out.write("\">");
             out.write(Repository.getNameForNode(nodeService, targetNode));
             out.write("</a>");
           }

           out.write("</tr></td>");
        }

        out.write("</table>");
     }
Instead of this, I'd generate an action, as it is done in BaseAssociationEditor.java:

/* … */
out.write("' onclick=\"");
out.write(generateFormSubmit(context, Integer.toString(ACTION_SHOW_DIALOG_FOR_LINK)));
out.write("\"/>");

Correct?

3. And I'd now add a new action, "reacting" to the above ACTION_SHOW_DIALOG_FOR_LINK, that changes the BrowseBean target and opens a dialog, right?

I guess the action would be added by overriding broadcast(FacesEvent event). But how can I change the target and open a dialog? Can you point me to an example here?

Many thanks,
Kaspar

P.S. I am also available via email: fischerk@inf.ethz.ch.

hbf
Champ on-the-rise
Champ on-the-rise
Okay, I have got everything working up to the point where a click on the link fires a Faces event which I catch in my UIChildAssociationWithLinksEditor's broadcast() method.

Only question remaining is 3. (from previous post): How can I either

* close the currently open "Details of" dialog, or
* open another dialog on top of the current "Details of" dialog

and tell the BrowseBean to show the target node of the link (I have its noderef)?

Thanks,
Kaspar

rivarola
Champ on-the-rise
Champ on-the-rise
Hello Kaspar,

1/ yes
2/ yes, but something identifying the node must be put in the submit line :
/* … */
out.write("' onclick=\"");
out.write(generateFormSubmit(context, Integer.toString(ACTION_SHOW_DIALOG_FOR_LINK+ ACTION_SEPARATOR + targetRef.toString()))));
out.write("\"/>");
3/ I think the decode method can be kept unchanged and you can modify the broadcast method to manage the ACTION_SHOW_DIALOG_FOR_LINK event.
But about the next thing to do (i.e. display the node properties), the problem is the document details dialog is not a real Alfresco dialog (its bean does not implement IDialogBean and thus is not managed by the DialogManager). As a consequence it is not "stackable" in the navigation handler view stack.
At this point you have all the power of the Alfresco Web-Client API to display your document properties, but I'm not sure a built-in action or dialog exists. Maybe you'll have to develop your own dialog based on the doc details one, or find another clue to stack several node views using another navigation mechanism.

rivarola
Champ on-the-rise
Champ on-the-rise
Cross answers…
This method is used to set the target node on the BrowseBean :
public void setupContentAction(String id, boolean invalidate)

I think you can easily update the view to show a new node this way but it will be difficult to stack the views (see my previous post about the "faked" details dialog).

hbf
Champ on-the-rise
Champ on-the-rise
Ah, the event works like a charm! Thanks a lot for the help. (I am working now on the simple version that does not use a dialog stack.)

There is one final problem left, however. Please take a look at the code:


  public void broadcast(FacesEvent event) throws AbortProcessingException
  {
    boolean handled = false;

    if (event instanceof AssocEditorEvent)
    {
      AssocEditorEvent assocEvent = (AssocEditorEvent)event;
      Node node = (Node)getValue();

      if (assocEvent.Action == ACTION_OPEN_ASSOC_LINK) {

        // get browse bean
        FacesContext fc = FacesContext.getCurrentInstance();
        BrowseBean browseBean = (BrowseBean)FacesHelper.getManagedBean(fc, BrowseBean.BEAN_NAME);

        // redirect
        String targetID = assocEvent.RemoveRef; // TODO: RemoveRef is re/mis-used!!
        logger.debug("ACTION_OPEN_ASSOC_LINK: moving to link target node " + targetID + ".");
        browseBean.setupContentAction(targetID, true); // TODO: true or false?
        handled = true;
      }
    }

    if (!handled)
      super.broadcast(event);
  }

This is the code that gets executed when you click on a link. It first extracts the id of the target node and then tells the BrowseBean to show the target node.

Unfortunately, the "Details of" dialog that shows up still shows the property sheet of the OLD node (with the property VALUES of the new one, but properties that the new node type has are NOT shown). If you click on the edit icon, the property sheet of the new node is shown (which is fine).

I turned on debugging (log4j.logger.org.alfresco.web.app.AlfrescoNavigationHandler=debug) and see that the old dialog is not closed. I suppose that's the issue here as the PropertySheet somehow remembers the sheet definition (but switches the node).

Any ideas what the issue could be?
Maybe the issue can be solved by closing the dialog? How would I do this?

PS. I am NOT using Alfresco-2.1-community but r1207 of Alfresco. Could it be that r1207 already uses dialogs?

PPS. I have create a project on forge and have uploaded the code (IT DOES NOT YET WORK, because of the issue I am writing about here…).

rivarola
Champ on-the-rise
Champ on-the-rise
I'm happy you managed to deal with JSF events so easily. It's an awfull maze ! You may not have much experience on JSF but you do understand quickly.
I think in your case the property sheet form does not get refreshed because the UIPropertySheet component (behind the propertySheetGrid tag in the document-details.jsp) does not re-create the property sheet fields if it already has children (you can see it in its encodeBegin method). That's why you get the old property sheet configuration with new values.
To reset this you have to remove all children of the property sheet having the id "document-props". Somewhere in your event management methods you have to navigate to this component and clear its children (I don't know what is the best place, this is a bit ugly but will work).
Good luck !

PS : I also use the latest SVN version of Alfresco, and the details dialog is still outside the dialog framework

hbf
Champ on-the-rise
Champ on-the-rise
Wow, again you hit the nail on the head! Just a few changes and tataaa, the thing is working.

Rivarola, many thanks for your help. I hope that by making the AMP publicly available you get (very indirectly, I admit) some value back at some point.

The AMP is available on forge (see link in previous post) and described on the Alfresco wiki.

P.S. Rivarola, can you mail me your full name so I can give credit in the README.txt? Thanks!

rivarola
Champ on-the-rise
Champ on-the-rise
Congratulations Kaspar,

I've already developped a couple of association editors for my company and I know it is not trivial. I'll certainly download your AMP extension.

Best regards,

  Philippe