1

I am currently using an h:selectOneRadio to display three filtering options. When a radio button is clicked, a JavaScript function is called to iterate through a number of items below to change the display CSS property corresponding to the filter option selected. This works very well, and does not have a round trip to the server (no POST or AJAX).

This will give you an idea of the current implementation.

<script type="text/javascript">
function criteria_filterClick(radio)
{
    radio.value == 'selected' ? criteria_showOnlySelected() :
        radio.value == 'significant' ? criteria_showFirstOrSelected() :
        criteria_showAll();
}
</script>

<h:selectOneRadio id="filter" onclick="criteria_filterClick(this); return true;"
        value="#{searchBean.criterionFilter}">
    <f:selectItem itemValue="selected" itemLabel="Selected"/>
    <f:selectItem itemValue="significant" itemLabel="Basic"/>
    <f:selectItem itemValue="all" itemLabel="All"/>
</h:selectOneRadio>

However, I feel like having tabs would be a better UI metaphor than radio buttons. I'm looking at PrimeFaces' p:tabMenu component with p:menuitems inside it. However, the documentation for those two components doesn't appear to have any support for straight JavaScript.

Here's what I've got started, but I don't know where to go from there:

<p:tabMenu activeIndex="#{searchBean.criterionFilter == 'selected' ? 0 : (searchBean.criterionFilter == 'significant' ? 1 : 2)}">
    <p:menuitem value="Selected"/>
    <p:menuitem value="Basic"/>
    <p:menuitem value="All"/>
</p:tabMenu>

At this point, there is no functionality (it doesn't even change tab highlighting when you click on one of them). Is there a way to add JavaScript to p:tabMenu? Or is this not the right way to go?

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
Pixelstix
  • 702
  • 6
  • 21
  • 2
    Please do not include an *answer* inside the *question*, as an *answer* is usually no *question*. If you have an *answer* that surpasses all other answers given to you already, feel free to post an *answer* to your own question. After three days time you can then accept your answer as correct. If it is no *new answer* but just slightly improves another answer (without conflicting with the authors intent) you might propose an edit to that answer aswell. – derM - not here for BOT dreams May 11 '17 at 22:38
  • 1
    @derM - thanks. I moved that to a separate answer. It felt awkward adding that to the existing answer by OTM since it seems different than a slight improvement. – Pixelstix May 12 '17 at 14:16

2 Answers2

2

Yes, you could achieve what you desire by calling JavaScript function using onclick attribute on each p:menuitem element and not on the p:tabMenu.

For example, for the "Selected" p:menuitem you could have

<p:menuitem value=Selected" onclick="criteria_showOnlySelected(); return false;"/>

The return false; is to prevent default action submit behaviour. Similarly, for the other two p:menuitems you need to call the other specific JavaScript functions.

[NOTE from the OP: This answer gives the crucial JavaScript call logic, but a little extra work was required to change the selected tab. See the edited question above for the full final solution.]

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
OTM
  • 656
  • 5
  • 8
  • I don't see `onclick` in the documentation for `p:menuitem`, but it does indeed call the requested function! The only thing it doesn't do is change the tab selection. Any ideas on that part of it? After playing around with it, I got it to switch, but I don't know if it's the best way. See the added description at the end of the question. Is there a cleaner way? – Pixelstix May 11 '17 at 18:02
  • Please see the showcase reference: it uses param for activeIndex to do the selection switch. Looks cleaner. https://www.primefaces.org/showcase/ui/menu/tabMenu.xhtml?i=1 – OTM May 12 '17 at 03:36
  • 1
    p:menuitem tag reference has onclick: https://www.primefaces.org/docs/vdl/3.5/primefaces-p/menuitem.html – OTM May 12 '17 at 03:39
  • @Pixelstix I don't know what documentation you were using, but it **is** documented. Please use the PDF, the showcase only gives you a few basic examples. And even then, not everything is properly documented in the PDF, as a last resort you can check out the source at GitHub. – Jasper de Vries May 12 '17 at 06:56
  • @Jasper - I used the PDF (6.0 User Guide), read through the attributes probably 4 or 5 times and somehow overlooked it every time; it's not grouped with the other "on..." attributes. Thanks for pointing that out! – Pixelstix May 12 '17 at 14:21
  • @OTM: Thanks, for the links. I hadn't had the VDL documentation links, those will come in handy. For the showcase link, I'm not sure how the `f:param` would help when doing something without a postback; notice the demo does a postback. – Pixelstix May 12 '17 at 14:22
0

(Moving my final solution to a separate answer to more closely comply with derM's note. I've left OTM's answer marked as that is what led to these exact code changes.)

Adding more logic to OTM's answer to switch tab highlight, the following seems to work, but looks a bit ugly:

function updateSettingTo(tabMenu, activeIdx)
{
    for (var idx = 0; idx &lt; tabMenu.items.length; idx++)
    {
        var item = $(tabMenu.items[idx]);
        if (idx == activeIdx)
            item.addClass("ui-state-active");
        else
            item.removeClass("ui-state-active");
    }
}

<p:tabMenu activeIndex="#{searchBean.criterionFilter == 'selected' ? 0 : (searchBean.criterionFilter == 'significant' ? 1 : 2)}" widgetVar="criteriaSelectionTabs">
    <p:menuitem value="Selected" onclick="criteria_showOnlySelected(); updateSettingTo(PF('criteriaSelectionTabs'), 0); return false;"/>
    <p:menuitem value="Basic" onclick="criteria_showFirstOrSelected(); updateSettingTo(PF('criteriaSelectionTabs'), 1); return false;"/>
    <p:menuitem value="All" onclick="criteria_showAll(); updateSettingTo(PF('criteriaSelectionTabs'), 2); return false;"/>
</p:tabMenu>
Pixelstix
  • 702
  • 6
  • 21
  • Just one suggestion to see if it works. Can you try with tabMenu.select(activeIdx); in updateSettingTo function to switch selection ? – OTM May 12 '17 at 16:04
  • That results in an `Uncaught TypeError: tabMenu.select is not a function` error on the console (in Google Chrome). I tried going down level of the `
      ` in the DOM with `tabMenu.jq.get(0).childNodes[0].selectedIndex = (activeIdx);`, but that doesn't change the styles. I obviously don't know enough about jQuery or PrimeFaces object layouts to know what I should be looking for in the debugger. Thanks for your interest and ideas!
    – Pixelstix May 12 '17 at 18:37