Tuesday, March 23, 2010

jqGrid hints and tips

I’ve been spending a lot of time with jqGrid recently. It’s a marvellous piece of work but the documentation doesn’t always match up to the quality of the code. I’m not complaining, I realise it’s free, it’s flipping great and as a developer myself I know documentation is always the last thing I want to tackle. But here are a few things I’ve discovered along the way where it wasn’t immediately apparent what was causing the problem.

Multiple rows being selected – This can be caused by a couple of things. The first thing to check is that the row IDs being used are sensible. My problem was caused by having some rows with the same ID. Another time the problem cropped up when I used email addresses as my row IDs. It seems the grid has problems with certain characters being used in IDs. The @ symbol did it for me but there are others, like spaces, that can cause problems.

Arbitrary XML – The docs say that jqGrid can accept any arbitrary XML document, so long as you provide a mapping to describe how to map it to the standard XML format. This is almost true, but falls over if your XML document contains attributes that you want to pull into the grid. Attributes aren’t supported at all. I managed to get round this in a couple of steps. First I had to hack jqGrid so the loadComplete event was triggered before the grid was actually populated, rather than after. Then I could fiddle with my returned XML before jqGrid tried to read it. Then I wrote some code to convert attributes to elements with he same name (this could probably be improved with some jQuery magic but it did the job for me) and called it for the relevant attributes.

function setNodeText(newElem, text) {
  if (text != null) {
    try {
      newElem.textContent = text;
    }
    catch (e) {
      newElem.text = text;
    }
  }
}

function convertAttributeToElement(xml, node, attributeName) {
  var name = node.getAttribute(attributeName);
  addChildNode(xml, node, attributeName, name);
}

function addChildNode(xml, parent, nodeName, value) {
  var newElem = xml.createElement(nodeName);
  setNodeText(newElem, value);
  parent.appendChild(newElem);
}

Word wrap – I wish this was on by default, since it is now the first thing I do when I’m setting up a grid for the first time. Just modify the ui.jqgrid.css file so the definition for .ui-jqgrid tr.jqgrow td includes the following white-space: normal;

3 comments:

Klas Mellbourn said...

It's free? I couldn't find any free version.

Doogal Bell said...

The ASP.NET and PHP versions cost money but the standard Javscript version is free.

Download it from here

Anonymous said...

This was super helpful, thanks! I'm not able to change the XML being returned by the server, so this is just what I need to do.