Skip to content


Stretching the capabilities of Xara Web Designer

Recently, I have been getting to grips with Xara Web Designer. And so far, I am very impressed. The pages it produces look great, and are easy to modify, at least as far as appearance and layout are concerned. But like most graphically-based packages, it has limitations when it comes to going beyond its basic capabities. Or so I initially thought…

Having explored “under the bonnet” a little, I have been impressed by how a little lateral thinking can extend the capabilities well beyond its ordinary functionality. This has a lot to do with the clean stucture of the pages it generates. The HTML, Javascript and css from Web Designer seem to be a lot less messy than most.

The direction I wanted to stretch my web pages was to produce a pop-up which was consistent with the look and feel of the site (and preferably editable using the Web Designer features), and which allowed users to copy and paste the text from the pop-up box. Web Designer has pop-up layers, but they normally disappear as soon as the mouse is clicked anywhere on the page. This makes it a tad hard to select and copy any text!

So, I set myself the task of turning the pop-up layer into something with a close button. After a couple of less-than-elegant attempts, I arrived at a solution which allows the use of the standard Xara layer architecture to design the pop-ups, but which gave me the close-box I wanted. This article describes how it can be done.

The first part of the solution is to use the “link” mechanism to run Javascript from button pushes. As you may know, HTML links don’t always have to point to web pages. For example, <a href = "mailto:someone@somewhere.com">email me</a> will open a mail compose window (assuming your browser can find a mail program). In our case, we want a link target which starts with “javascript:”. This can be inserted into any link, using the “Web Properties” dialog (Shift-Ctrl-W). In the “Link to Web or Email address:” field, you can insert the javascript. (In Web Designer 6, you have to untick the “Connect automatically” box or Xara will helpfully insert an “http://” in front of your havascript; Web Designer 7 cunningly avoids this annoyance.) As an example, create a button-shaped box, press Shift-Ctrl-W with the box selected, and try putting javascript:alert("Hello, world."); in the link field. When you preview the page, clicking the box should pop up a javascript alert. In our case, we want the button to run a javascript function that we are going to create, so enter javascript:sh_popup(true); into the link field.

So far so good. The next step is to create the layer we want to appear when we click the button. Do this by creating a new layer (I called mine popup). Put the text of the pop-up and other decoration onto that layer. Of course, by default, that will either be always visible on the page, or will not be included in the generated page at all, if you make it invisble.  How do we fool Xara into including the layer in the web page, but hidden by default? Of course, this is exactly what the “pop-up layer” option in the Web Properties does, so lets make use of that… create a small object (I used a small rectangle) and set its web properties to “Pop-up layer: popup”. We don’t want anyone actually clicking that button, so hide it unnderneath something else (I hid mine under the button we made before, which of course I actually do want people to click).

The next thing you need to know is that the way Web Deisgner handles pop-ups is to create a <div> with two attributes set: visibility: "hidden" and display: "none". (It turns out that you need both to cover different browsers’ behaviour.) All the items on our popup layer will appear within that div (albeit several levels deeper in the DOM hierachy). So the easiest way to find this div is to give something on the layer a unique id, use javascript to find it and then work up the DOM tree until we find an element with those two attributes set. (Actually, we only need to search for one of them, since they will always appear as a pair.) This is where another of Web Deisgner’s marvelous hooks comes into play: “Placeholder”.

To create something with a unique html id, we need to insert that item into the pop-up layer.  This is another tab on the Web Properties menu. Using Placeholder, one can insert any html one likes into the page (including broken html, so be careful!) When the website is built, the object with the placeholder will disappear, and be replaced by the code from the dialog tab. (You can link to external graphic images, or Flash apps too, but that’s not what we need here.) So, create an object (any object will do, but I tend to use a colourful box somwhere top left, out of the way). Pop up the Web Properties box and add the code
<span id="sh-popup"></span>
Now we have in element we can find using javascript’s getElementById() function. And having found it, we can climb back up the tree using the .parentItem attribute, until we find the hidden div. We want to do that only once, partly because that’s efficient and elegant, but mostly because we won’t be able to find the element this way once it’s visible. So, create a global variable to point to the hiden div, and only set it if it’s currently undefined. After that, we just need to set the two attributes of that divto whichever state we want the overlay — visible or hidden; block or none. Which gives us code like this (in WD7, you can put the script into the head, which is more elegant, but it works perfectly well in the body too)..

<script type='text/javascript'>

var hideHere;

function sh_popup(show)
{
  // first, check to see if hideHere has been initialised before
  // this bit of code will only be run the first time sh_popup is run
  // note that we can't do this at load time, because the DOM won't have
  // finished initialising, and we wont find the element.

  if (typeof hideHere == 'undefined')
  {
    hideHere = document.getElementById('sh-popup');
    while (hideHere.style.visibility != 'hidden')
    {
      hideHere = hideHere.parentNode;
    }
  }

  // now show or hide the pop-up layer

  if (show)
  {
    hideHere.style.display='block';
    hideHere.style.visibility='visible';
  }
  else
  {
    hideHere.style.display='none';
    hideHere.style.visibility='hidden';
  }
}
</script>

<span id = 'sh_popup'>
  <!-- finally, give ourselves a starting point -->
</span>

As you can see, not rocket science! In fact, not even very much code. Though to be fair it did take around eight hours of experimenting and optimising to reach this point.

The last thing we need to do is to add a close button to the pop-up layer. You can’t use a “standard” button for this, because that is a soft group which knows which layers the various element go on (including the mouse-over layer which changes the butten when you hover the mouse), so you’ll have to make a custom button. Using Web Properties, link this to javascript:sh_popup(false);. And then we’re done. The final page can be seen here.

Having got this far, I realised that it is relatively simple to extend the approach to support multiple overlays. The code gets a little more complicated, and you need to create a separate layer (with its own <span> and id, but the rest of the approach is just more of the same. I called the layers “sh-1”, “sh-2”, etc., just to make them easy to find. One extra hidden button for each pop-up layer, and a numbered parameter for whichever layer you want to be visible. Of course you only need one copy of the function which does the hiding and showing.

My version has a parameter for how many layers there are; sad things happen if you don’t set that correctly. If you want to be more elegant, you could use try and catch to spot when you’ve run out of ids to find. That’s left as an exercise for the reader. Here’s the extended code, and an example web page is here.

<script type='text/javascript'>

var hideHere = new Array();
var sh_pages = 3;
function sh_showpage(show)
{
  if (typeof hideHere[1] == 'undefined')
  // the "first-time-only" search for the hidden
  // elements of each pop-up layer
  {
    for (sh_count=1; sh_count <= sh_pages; sh_count++)
    {
      hideHere[sh_count] = document.getElementById('sh-'+sh_count);
      while (hideHere[sh_count].style.visibility != 'hidden')
      {
        hideHere[sh_count] = hideHere[sh_count].parentNode;
      }
    }
  }

  // the show and hide now goes through all layers,
  // and makes sure that just one is visible

  for (sh_count=1; sh_count <= sh_pages; sh_count++)
  {
    if (sh_count==show)
    {
      hideHere[sh_count].style.display='block';
      hideHere[sh_count].style.visibility='visible';
    }
    else
    {
       hideHere[sh_count].style.display='none';
       hideHere[sh_count].style.visibility='hidden';
    }
  }
}
</script>

There’s a few extra wrinkles in that page. Like using mouse-over layer to colour (and disable) the button for the currently selected layer. Go look at the source Xara .web file if you want to see what’s going on.

I hope this article helps people who want to make Web Designer do a little more than it can do out-of-the-box. Good luck, and let me know how you get on…

Posted in Technology and development.

Tagged with .