0
votes

I'm using Primefaces' columnToggler together with the watermark component, to add custom text to the column, following this answer -> how to add placeholder text in the filter box in datatable column headers.

<p:column id="analysisStartTimeColumn"
          filterBy="#{analysis.startTime}"
          sortBy="#{analysis.startTime}"
          filterFunction="#{filterController.filterByDate}"
          filterMatchMode="contains"
          visible="#{analysisBean.analysesDatatableColumnStates.get(6)}">
  <f:facet name="header">
    <h:outputText value="#{msg['Analysis.startTime']}"/>
    <p:watermark value="#{msg['placeholder.chooseDate']}"
                 for="analysisStartTimeColumn"/>
  </f:facet>
  <f:facet name="filter">
     <p:calendar id="analysisStartTimeCalendar"
                 locale="de"
                 navigator="true"
                 pattern="dd.MM.yyyy"
                 mask="true">
        <p:ajax event="dateSelect"
                oncomplete="PF('analysesDatatableWdgtVar').filter()"/>
     </p:calendar>
  </f:facet>
  <h:outputText value="#{analysis.startTime}">
     <f:converter converterId="localDateTimeConverter"/>
     <f:attribute name="pattern" value="dd.MM.yyyy HH:mm:ss"/>
  </h:outputText>
</p:column>

The problem is, that the primefaces component gets added to the header name and therefore the header names are uglified within the columnToggler.

Watermark in ColumnToggler

I know that i could place the watermark inside the column and not the header facet but then i would have to specify the "for" attribute of watermark component starting with the parent form like this: ":formId:...:tableId:columnId"... and I already read (Primefaces, dataexporter and watermark) that I would have to customize the dataExporter to not export the watermark. And I don't want to do that as it would add plenty of additional work to do.

I already found a thread (columnToggler commandButton list of column headers) with the same problem but the answer won't solve my problem..

Is there anything that i can do so the watermark is not used within the columnToggler component?

1
One option you always have is to download the source, check what is happening and improve it. Maybe some small substring replacement in the watermark js file will already help since it all seems to start with the same $(function(){PrimeFaces...Kukeltje
Sorry, that should be the columntoggler jsKukeltje
Already tried via PrimeFaces.widget.ColumnToggler.prototype.render = function () {...} but couldn't get the override to work. Im currently working out why it doesn't override its default behaviourMatze.N
So I'm still not able to override any primefaces behaviour via prototype. Can you help me with that @Kukeltje?Matze.N

1 Answers

1
votes

As suggested, I tried to override the columnToggler's default behaviour. The header names are generated within the .render() method. I created a new file called columnToggler.js and included it in my template.xhtml header.

I first tried it with a regex but ended up reading it from another html node because the regex wasn't flexible enough (column header name and the watermark script where alligned in the same order how their xhmtl components where placed in the datatable's header facet)

columnToggler.js

PrimeFaces.widget.ColumnToggler.prototype.render = function () {

    this.columns = this.thead.find("> tr > th:not(.ui-static-column)");
    this.panel = $("<div></div>").attr("id", this.cfg.id).attr("role", "dialog").addClass("ui-columntoggler ui-widget ui-widget-content ui-shadow ui-corner-all").append('<ul class="ui-columntoggler-items" role="group"></ul>').appendTo(document.body);
    this.itemContainer = this.panel.children("ul");
    var a = this.tableId + "_columnTogglerState";
    this.togglerStateHolder = $('<input type="hidden" id="' + a + '" name="' + a + '" autocomplete="off" />');
    this.table.append(this.togglerStateHolder);
    this.togglerState = [];
    for (var f = 0; f < this.columns.length; f++) {
        var c = this.columns.eq(f), g = c.hasClass("ui-helper-hidden"),
            h = g ? "ui-chkbox-box ui-widget ui-corner-all ui-state-default" : "ui-chkbox-box ui-widget ui-corner-all ui-state-default ui-state-active",
            k = (g) ? "ui-chkbox-icon ui-icon ui-icon-blank" : "ui-chkbox-icon ui-icon ui-icon-check";
        var children = c.children(".ui-column-title");
        var nodeList = children[0].childNodes;
        var arr = Array.from(nodeList);
        var l = arr.filter(function (node) {
            return node.nodeType === Node.TEXT_NODE;
        })[0].data;

        this.hasPriorityColumns = c.is('[class*="ui-column-p-"]');
        var n = $('<li class="ui-columntoggler-item"><div class="ui-chkbox ui-widget"><div class="ui-helper-hidden-accessible"><input type="checkbox" role="checkbox"></div><div class="' + h + '"><span class="' + k + '"></span></div></div><label>' + l + "</label></li>").data("column", c.attr("id"));
        if (this.hasPriorityColumns) {
            var b = c.attr("class").split(" ");
            for (var e = 0; e < b.length; e++) {
                var d = b[e], m = d.indexOf("ui-column-p-");
                if (m !== -1) {
                    n.addClass(d.substring(m, m + 13))
                }
            }
        }
        if (!g) {
            n.find("> .ui-chkbox > .ui-helper-hidden-accessible > input").prop("checked", true).attr("aria-checked", true)
        }
        n.appendTo(this.itemContainer);
        this.togglerState.push(c.attr("id") + "_" + !g)
    }
    this.togglerStateHolder.val(this.togglerState.join(","));
    this.closer = $('<a href="#" class="ui-columntoggler-close"><span class="ui-icon ui-icon-close"></span></a>').attr("aria-label", PrimeFaces.getAriaLabel("columntoggler.CLOSE")).prependTo(this.panel);
    if (this.panel.outerHeight() > 200) {
        this.panel.height(200)
    }
    this.hide()
};

template.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      lang="en">

    <h:head>
        <f:facet name="first">
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
            <meta name="apple-mobile-web-app-capable" content="yes" />
        </f:facet>
        <title><ui:insert name="title">...</ui:insert></title>
        <ui:insert name="head"/>

        <h:outputScript type="text/javascript" name="/resources/.../js/custom.js"/>

    </h:head>

    <h:body>

        ...

    </h:body>

</html>