Fix Indenting on Multiple Categories in a View Panel

I previously demonstrated a solution for fixing category indenting in a view panel that contains a totals column. In this post, I’ll provide an updated version of the code that handles indenting multiple columns properly.

For more insight into the logic, please take a look at that previous post.

Code

Here is the code that fixes the category indentation:

function fixViewIndentation(categoryClass) {
  // Get a list of all rows in the view panel.
  dojo.query('.xspDataTableViewPanel table tr').forEach(function(nodeRow, indexRow) {
	
  // Locate the category cells within the context of the view rows
  dojo.query('td.' + categoryClass, nodeRow).forEach(function(nodeCat){
    // Execute a search on the parent node (row) and remove all cells until data is found   
    var emptyCells = 0;
    var countCells = false;
    dojo.query('td', nodeRow).forEach(function(nodeTD, indexTD){
      // Start counting when the first category cell is found (this is more for levels after the top-level categorization)
      // Check all non-category cells until a non-empty cell is found
      if (dojo.hasClass(nodeTD, categoryClass)) {
        countCells = true;
      } else if (countCells){          
        if (nodeTD.innerHTML == '') {          
          emptyCells +=1;
          dojo.destroy(nodeTD);
        } else {
          countCells = false;
        }
      }    
    });
    // Add a colspan attribute to the category cell (1 + [# of empty cells])  
    // dojo.attr(nodeCat, 'colspan', 1+emptyCells);
    nodeCat.colSpan = 1+emptyCells;
  });
  });	
}

Custom Control for Easy Reuse

In order to reuse this feature easily, I put the above function in a client JavaScript library called viewPanel.js and I created this custom control (named ccViewIndentationFixer) that will execute the code onClientLoad.

Here’s the full source of the custom control:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
  <xp:this.resources>
    <xp:script src="/viewPanel.js" clientSide="true">
    </xp:script>
  </xp:this.resources>
  <xp:eventHandler event="onClientLoad" submit="false">
    <xp:this.script><![CDATA[fixViewIndentation("CATEGORY_CLASS_NAME");]]></xp:this.script>
  </xp:eventHandler>
</xp:view>

The call to the fixViewIndentation() function must pass the name of the class used on the category columns that need to be indented. (I showed how I set the category column class in the previous post.)

Per a great tip from Sven Hasselbach, I’ve learned that the best way to use it is to include it within a view panel facet by putting this in the page source:

<xp:viewPanel ...>
  <xp:this.facets>
    <xp:pager...></xp:pager>
    <xc:ccViewIndentationFixer xp:key="south" />
  </xp:this.facets>
</xp:viewPanel>
Advertisements

16 responses to “Fix Indenting on Multiple Categories in a View Panel”

  1. Baxter Jimuk says :

    Hi thanks it worked perfectly!

  2. Fatih Duranoglu says :

    Hi
    when i collapse or expand category back to begin point like added new viewpanel object but first run ok

  3. Fatih Duranoglu says :

    i solved my problem. Thanks for everythink.

  4. Senbon says :

    Can you make a sample database for this? I had no luck at making this work. If this works, it will save my life. Thank you

  5. Baxter Jimuk says :

    Hi, it’s me again. The above code has work fine for the case that it’s created for which is multiple category with total column. Now I’m trying to do the same thing for a viewPanel that has no total column, but has a column to display response document. The method to implement is the same as the one you propose above except for the code in the viewPanel.js which I changed to the following:

    function fixViewIndentation(categoryClass) {
    dojo.query(‘.xspDataTableViewPanel table tr’).forEach(function(nodeRow, indexRow) {
    dojo.query(‘td.’ + categoryClass, nodeRow).forEach(function(nodeCat){
    dojo.query(‘td.xspColumnViewMiddle’, nodeRow).forEach(function(nodeTD, indexTD){
    dojo.destroy(nodeTD);
    });
    dojo.query(‘td.xspColumnViewEnd’, nodeRow).forEach(function(nodeTD, indexTD){
    dojo.destroy(nodeTD);
    });
    nodeCat.colSpan = 10;
    });
    });
    }

    Now my notes view has the following structure: column 1 (category), column 2 (category), column 3 (for the response), column 4 and following (normal, non-reponse). Here, the response column will be indented to be behind the column 4 which is what I want. Moving to xpages and using the above code, the only problem I get is that the response column will not be indented the same way, instead it’ll be a bit at the front of the column 4 which I’ve been trying to fix for weeks to no avail. Can you help?

    Another problem is that when collapsing the viewPanel, the width won’t be 100 percent already even though that’s the option that I put. But this isn’t that important so you can just skip this one. The indent problem is more important. Thanks again.

    • Brad Balassaitis says :

      Is it possible for you to send me a sample database with the view, a few documents, and your XPage so I could take a look at it? (If you’re on Twitter, send me a direct message.)

      • Baxter Jimuk says :

        Hi Sir,

        This (http://ul.to/zz8hq4z3) is the link to the sample database (it’s < 1MB). You can just put it in your Notes data folder and run/preview in web browser locally.

        The 100 percent width on collapse seems to be solved by putting a fixed width in pixels but still it'd be better if the percent would work. Anyway never mind that one, the most important is the indentation of the response. In my application, there's only 1 level of response so if your solution can cater to that is already enough (no need to consider response to response to response and so on). Thanks.

  6. Brad Balassaitis says :

    In the example that you sent, adding this line before the nodeCat.colSpan=10; line will do the trick:

    dojo.place(‘

    ‘, nodeCat, ‘before’);

    This adds an empty table cell before the response line starts and sets it to span across the three categorized columns so the response row doesn’t start until the 4th column.

    Ultimately, if you’re going to reuse it, it would be better to automatically determine (a) the number of category columns (so the “3” isn’t hard-coded) and (b) the number of cells in the entire view, so the nodeCat.colSpan can be set properly to be the total number of columns in the view minus the number of category columns, so you don’t end up having rows with unnecessary empty space at the end.

  7. fatih duranoglu says :

    Hi Brad

    This solution not work on Bootstrap. How can i solve .

    Thanks

  8. Luis E Lopez says :

    Hi Brad !! This is a excelent solution for my view panel with categories, but i was using bootstrap and not work with this theme, could do you help me with this ??

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: