Search code examples
javascriptprimefacescallbackcalendaronmouseover

How to show tooltips onmouseover in p:calendar


I want to show tooltips when hovering over certain dates in a p:calendar element in PrimeFaces 6.2. I think the way to go is to use global tooltips and change the title of the a-elements inside the calendar. How can I access these?

I tried to use the onmouseover - attribute of p:calendar, hoping to get access to the element as a parameter. As a first step, I wanted to print something to the console:

calendar.xhtml:

[...]
<h:outputScript library="js" name="calendar.js" />
<p:calendar
      id="calendar"
      value="#{calendarManagedBean.dateToday}"
      mode="inline"
      onmouseover="hoverDate"
      beforeShowDay="colorizeDate"
      />
[...]

calendar.js:

[...]
function hoverDate() {
  console.log("hoverTest");
}
[...]

I expect this to print "hoverTest" to the javascript-console of the browser when I hover over dates in the calendar, but it does not do anything. I tried with 0, 1, and 2 parameters for hoverDate(). The documentation (page 54) only says "Client side callback to execute when a pointer button is moved onto input element.", not saying anything about parameters.

The method colorizeDate is in the same javascript-file and works fine, so the problem can't be that the method hoverDate cannot be found.

What am I doing wrong?


Solution

  • As the comments to your question already hint at, the mouseover event of the p:calendar component is bound to the parent date input text, not the date picker or the individual dates in the date picker.

    Obviously the solution is to manually do this binding in JavaScript. With PrimeFaces 7.0 the following solution should work,

    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
        <h:head>
            <title>Calendar hover test</title>
        </h:head>
        <h:body>
            <h:form>
                <p:calendar />
            </h:form>       
            <script>
                $(document).on("mouseenter", ".ui-datepicker-calendar td", function() {
                    console.log(this.dataset.year, this.dataset.month, this.children[0].textContent);
                });
            </script>
        </h:body>
    </html>
    

    This will set up a live/dynamic binding on all "td" elements contained under a PrimeFaces date picker table and print out something similar to the following onto the JavaScript console;

    2019 7 27
    2019 7 6
    2019 7 13
    2019 7 12
    2019 7 19
    

    Depending on your needs you can also take this further and bind it to a backing bean Java callback using either h:commandScript (if you are on JSF 2.3) or p:remoteCommand. Then you can also access the Java side when this event happens.

    If you are using an older version of PrimeFaces, the class name of the date picker might be different (although I think it has been the same for quite some time). In that case you can use the DOM inspector of the browser to look up the path of the binding.