Playing with titlebar and navigator II


In last blogpost I wrote about titlebar and menu in it. Also I promised some navigator hacking, which is more complex (and crazy has many javascript code) and amazing, so I decided to write whole blogpost on it. Here we are go!

Navigator jsp is pretty simple, but it's not plus for us, because whole navigator is a component – r:navigator. That should not be a problem, but this component has no documentation and what is much worse, this component's aim is just to view that simple menu with Guest home, Alfresco home, My home and Company home. Nothing less, nothing more, no editings.So what to do with that crap? Let's do some hacking! You can see my result at following picture, I added one more link:

 

Image and video hosting by TinyPic    Image and video hosting by TinyPic

 

Navigator.jsp is in /jsp/sidebar/ and at start there is just that component:

 <r:navigator id="navigator" activeArea="#{NavigationBean.toolbarLocation}" />

 This component renders ahref links inside divs, like this:

<div id="navigator">
      <div><a href="foo">bar</a></div>
      <div><a href="bar">foo</a></div>
          . . .
</div>

So I need to insert my own container with my link (both styled some way). ActionLink doesn't take 'class' attribute, so I need to inject that attribute with simple javascript:

 <a:booleanEvaluator value="#{BrowseSessionBean.isArchivaceExist}">
    <f:verbatim>
        <div id="navigatorArchivaceBox" class="sidebarButton" style="background-image: url(/alfresco/images/parts/navigator_grey_gradient_bg.gif);">
    </f:verbatim>
    <a:actionLink id="navigatorArchivaceLink" value="Archivace" href="#{BrowseSessionBean.archivaceUrl}"/>
    <f:verbatim>
            <script type="text/javascript">
                   var link = document.getElementById("navigatorArchivaceLink");
                   link.setAttribute("class","sidebarButtonLink");
            </script>
        </div>
    </f:verbatim>
</a:booleanEvaluator>

I personally hate that opening div inside verbatim tag and also that closing div, but what I can do else :-/. So this simple hack added my own link into navigator menu, it's clickable, it's styled, that link works, but that box is not selectable. After deploy this probably look like left picture a few rows higher. All that code is placed inside evaluator, because I need to have destination space accessible, to display this link in menu.

So next thing to do is to deselect all boxes and all links after 'my link' is clicked and also select my box and my link. Sounds simple, but it isn't thanks to 'My Alfresco' link. I'm doing all this stuff only when I'm at the right place (my Archivace space), so I need evaluator:

<a:booleanEvaluator value="#{BrowseSessionBean.isInsideArchivace}">
<f:verbatim>

Inside this evaluator I have simple javascript, which goes through elemnts under navigator container – links and divs – and for each set 'unselected' style:

<script type="text/javascript">
    // disabling 'selected' style at all links
    var links = document.getElementById("navigator").getElementsByTagName('a');
    for(var i=0; i<links.length; i++){
        links[i].setAttribute("class","sidebarButtonLink");
    }

    // disabling 'selected' style at all boxes
    var links = document.getElementById("navigator").getElementsByTagName('div');
    for(var i=0; i<links.length; i++){
        links[i].setAttribute("class","sidebarButton");
        links[i].setAttribute("style","background-image: url(/alfresco/images/parts/navigator_grey_gradient_bg.gif)");
    }

Now it's time to set 'selected' style just for my (selected) link. I know its ids, so I can access them directly through getElementById:

document.getElementById("navigatorArchivaceBox").setAttribute("style","background-image: url(/alfresco/images/parts/navigator_blue_gradient_bg.gif)");
document.getElementById("navigatorArchivaceLink").setAttribute("class","sidebarButtonSelectedLink");

And now all I have to do is 'just' to create evaluator – isInsideArchivace. That is not so hard – just getting current node and asking, if it has wanted aspect ;-).

public boolean getIsInsideArchivace(){
    if(this.getCurrentLocation()==null)return false;
    return this.navigator.getCurrentNode().hasAspect(cz.shmoula.ArchivaceModel.archSummary);
}

Now it's all doomed to work, like on first and second image :-). BUT – 'My Alfresco' is not an ordinary space, it's some virtual space or something, so when I left my 'Archivace' space by clicking on 'My Alfresco', My Alfresco screen is opened, but selected option is still 'Archivace'. What to do? Look at breadcrumb, because when there is node, it's ordinary space. But when there's nothing, it's probably 'My Alfresco' space (if not, it doesn't matter, because it is not my 'Archivace' space) and it's neccessarynot to display 'Archivace' as selected node. Soall that is inside that getCurrentLocation, which fragments are stolen somewhere from Alfresco sources:

 public String getCurrentLocation(){
        List<IBreadcrumbHandler> location = this.navigator.getLocation();
        String name = null;
          if (location.size() != 0){
              for (int i=0; i<location.size(); i++){
                 IBreadcrumbHandler element = location.get(i);
                 if (element instanceof IRepoBreadcrumbHandler){
                    NodeRef nodeRef = ((IRepoBreadcrumbHandler)element).getNodeRef();
                    name = Repository.getNameForNode(this.getNodeService(), nodeRef);
                 }
              }
          }
          return name;
    }

At this time it's all and it works! Ugly and hacky solution, but it works (FF3). Maybe it'll be better to write own component (eg. some tree browsing component), but now I wanted some simple and fast (and really ugly). Oh, I almost forget – this thread helped me a lot!


Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *