trsvax / tapestry-bootstrap

Tapestry module for Twitter Bootstrap

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pagination Issue with the "..."

mischat opened this issue · comments

Hello,

I am having problems when trying to use the bootstrap styled pagination in Grid Components.

I am looking at the PaginationProvider.java class, and it looks like the issue stems from the fact that Tapestry's pagination HTML has a string "..." which isn't encapsulated within any element, and this means that your "visit" function doesn't seem to pick up the three dots.

I am trying to fix this, but it looks like the fix might have to be pretty ugly, any thoughts/pointers would be much appreciated!

screen shot 2013-08-13 at 02 00 45

I tried to fix your plugin, but I couldn't have gone with :

//The two below fix a tapestry/tapestry-bootstrap bug
$('ul.pagination').parent().contents().filter(function() {
    return this.textContent.indexOf('...') >= 0 && this.nodeType === 3;
}).remove();

var tval = 0;
$('ul.pagination li').each(function(i,el) {
    elval = $(el).text();�
    if (Math.abs(tval-elval) > 1) {
        $(el).before('<li><a href="#"><span>...</span></a></li>');
    };
    tval = elval;
 �});�

In a recent non-bootstrap project I also needed to fix "..." in grid pager. I did this on the server-side using mixin.

In my case I wrapped "..." text node to with <span class="dots"></span> element and fixed layout using this CSS selector: DIV.t-data-grid-pager span.dots. Maybe you can do something similar?

import java.util.List;

import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.MixinAfter;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.dom.Node;
import org.apache.tapestry5.dom.Text;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@MixinAfter
public class GridPagerMixin
{
    private static final Logger logger = LoggerFactory.getLogger(GridPagerMixin.class);

    @Inject
    private ComponentResources resources;

    void afterRender(MarkupWriter writer)
    {
        Element gridDiv = writer.getElement();

        Element dataGrid = getChildElement(gridDiv, "t-data-grid");

        if (dataGrid == null)
        {
            logger.debug("Unable to apply mixin, no data grid");
            return;
        }

        replaceDots(getChildElement(dataGrid, 0)); // top pager
        replaceDots(getChildElement(dataGrid, -1)); // bottom pager
    }

    private Element getChildElement(Node node, String className)
    {
        if (!(node instanceof Element))
        {
            return null;
        }

        List<Node> children = ((Element) node).getChildren();

        if (children == null)
        {
            return null;
        }

        for (Node child : children)
        {
            if (!(child instanceof Element))
            {
                continue;
            }

            if (className.equals(((Element) child).getAttribute("class")))
            {
                return (Element) child;
            }
        }

        return null;
    }

    private Element getChildElement(Node node, int index)
    {
        if (!(node instanceof Element))
        {
            return null;
        }

        List<Node> children = ((Element) node).getChildren();

        if (children == null)
        {
            return null;
        }

        if (index < 0)
        {
            index = children.size() + index;
        }

        Node child = index >= 0 && index < children.size() ? children.get(index) : null;

        return (Element) (child instanceof Element ? child : null);
    }

    private void replaceDots(Element pagerDiv)
    {
        if (pagerDiv == null || !"t-data-grid-pager".equals(pagerDiv.getAttribute("class")))
        {
            logger.debug("Unable to apply mixin, invalid pager element");
            return;
        }

        for (Node child : pagerDiv.getChildren())
        {
            if (child instanceof Text)
            {
                child.wrap("span", "class", "dots");
            }
        }
    }
}

Applying mixin to grid is as simple as: <t:grid ... t:mixins="gridPagerMixin">.

PS:
Updated code sample to fail silently.

PPS:
Updated code once again with bugfixes.

I had the problem with the '...' and with the 'active' page not being greyed out.
I first tackled the problem by trying to change the tapestry-bootstart source code. While I solved the 'active' page problem, the '...' problem remained. It's been about two months, but if I remember correctly, there's some problem with the css and/or html that 'hoists' the '...' up from it's

  • , and then the css can't be applied. I'm no html/css/JavaScript expert so I have no idea why this happens.

    As the first approach failed, I JQuery'ed the grid to hell:

    1 - Remove all css from the grid. (specially "fwtype= ... " )
    2 - Include the following code in the page:

    prettifyGrid = function() {
        $j(".t-data-grid").addClass("table table-condensed table-striped").removeClass("t-data-grid");
        $j(".t-data-grid-pager").contents().filter(function() {
            return this.nodeType == Node.TEXT_NODE; 
        }).wrap('<span class="current" />');
    
        if (!$j("span.current").parent().is("a")) {
            $j("span.current").wrap('<a href="#" />');
        }
    
        $j(".t-data-grid-pager").children().wrapAll("<ul />").wrap("<li />");
        $j(".t-data-grid-pager").find("span.current").parent().parent().addClass("active");
        $j(".t-data-grid-pager").addClass("pagination").removeClass("t-data-grid-pager");
    };
    
    Tapestry.onDOMLoaded(function() {
        $('grid').observe(Tapestry.ZONE_UPDATED_EVENT, prettifyGrid);
        prettifyGrid()
    });

    This applies the tapestry bootstrap styles to the default tapestry grid, and you have greyed out 'active' page and '...' in the right place.

    I know this is slower than a server-side solution, but it fits my needs.