-1

I want to create h:datatable with list of data:

<h:dataTable id="dataTable" value="#{SessionsController.dataList}" binding="#{table}" var="item">
    <!-- Check box -->
        <h:column>
            <f:facet name="header">
                <h:outputText value="Select" />
            </f:facet>
            <h:selectBooleanCheckbox  onclick="highlight(this)"
                value="#{item.selected}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="№"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="№" value="№" />
                </h:commandLink>
            </f:facet>
            <h:outputText
                value="#{table.rowIndex + SessionsController.firstRow + 1}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Account Session ID"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Account Session ID" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.aSessionID}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="User ID"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="User ID" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.userID}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Activity Start Time"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Activity Start Time" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.activityStart}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Activity End Time"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Activity End Time" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.activityEnd}" />
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:commandLink value="Activity"
                    actionListener="#{SessionsController.sort}">
                    <f:attribute name="sortField" value="Activity" />
                </h:commandLink>
            </f:facet>
            <h:outputText value="#{item.activity}" />
        </h:column>
    </h:dataTable>

I want when I click on a table row to open a new page which displays more details. I want to use the table key aSessionID which will be used for SQL query to get a data from the database. I know that I can use h:commandLink to pass the key but I don't want ugly html link. Is there other way to click on the JSF table row, pass a key and open a new window?

Best Wishes

EDIT

I found one possible solution here

Using this JavaScript code it's possible to open a new window when the user clicks on a row:

<table id="row_link"> 
  <tbody> 
    <tr>
      <td><a href="link1.html">link</a></td> 
      <td>info 1</td> 
    </tr>       
    <tr>
      <td><a href="link2.html">link</a></td> 
      <td>info 2</td> 
    </tr>       
  </tbody> 
</table>

$("table#row_link tbody tr").click(function () {
    window.location = $(this).find("a:first").attr("href");
});

The question is how I can pass this key aSessionID to the new window. In the above example href is used to pass the link to the new window. What attribute can be used in JSF table?

Community
  • 1
  • 1
Peter Penzov
  • 1,126
  • 134
  • 430
  • 808

1 Answers1

2

@BalusC (JSF expert) has a post about managing Datatable in JSF 1.2 but it works for JSF 2.x too. You're interested in the select row on click section.

UPDATE:

Let me explain the example. First, every JSF component ID will have this form: :, example:

<h:form id="myForm">
    <h:inputText id="myInputText" value="#{myBean.textValue}" />
</h:form>

This will generate the HTML:

<form id="myForm">
    <input type="text" id="myForm:myInputText" />
</form>

Second, you have to update the generated DOM for the datatable. He's doing that by javascript and also gives you the js code:

function addOnclickToDatatableRows() {
    //gets all the generated rows in the html table
    var trs = document.getElementById('form:dataTable').getElementsByTagName('tbody')[0]
        .getElementsByTagName('tr');
    //on every row, add onclick function (this is what you're looking for)
    for (var i = 0; i < trs.length; i++) {
        trs[i].onclick = new Function("highlightAndSelectRow(this)");
    }
}

Third, define the highlightAndSelectRow js function (you can change the name to whatever you want).

function highlightAndSelectRow(tr) {
    //get all the datatable rows
    var trs = document.getElementById('form:dataTable').getElementsByTagName('tbody')[0]
        .getElementsByTagName('tr');
    //find the selected rowby using the tr parameter
    for (var i = 0; i < trs.length; i++) {
        if (trs[i] == tr) {
            //once found it, change the color (maybe you don't need this part)
            trs[i].bgColor = '#ff0000';
            //update a hidden value in the form (maybe you need this code)
            document.form.rowIndex.value = trs[i].rowIndex;
            //here, you can add js code to open a new window
            //or simulate a button/link click or something else you need.
        } else {
            trs[i].bgColor = '#ffffff';
        }
    }
}

UPDATE 2:

I've made a test for this case. I'll show you the code to get it done using facelets.

DataTable.xhtml

<script type="text/javascript">
    function addOnclickToDatatableRows() {
        //gets all the generated rows in the html table
        var trs = document.getElementById('myForm:dataTable').getElementsByTagName('tbody')[0]
            .getElementsByTagName('tr');
        //on every row, add onclick function (this is what you're looking for)
        for (var i = 0; trs.length > i; i++) {
            trs[i].onclick = new Function("rowOnclick(this)");
        }
    }

    function rowOnclick(tr) {
        var elements = tr.cells[0].childNodes;
        for(var i = 0; elements.length > i; i++) {
            //get the link
            if ((typeof elements[i].id !== "undefined") &amp;&amp;
                (elements[i].id.indexOf("lnkHidden") > -1)) {
                //open a new window/tab using the href generated in link
                window.open(elements[i].href);
                break;
            }
        }
        return false;
    }
</script>

<h:form id="myForm">
    <h1>Show data</h1>
    <h:dataTable id="dataTable" var="data" value="#{datatableBean.lstData}">
        <h:column>
            <f:facet name="header">
                <h:outputText value="ID" />
            </f:facet>
            <h:outputText value="#{data.id}" />
            <!-- define a hidden link for every row of the datatable
                 the value attribute contains the page to redirect. -->
            <h:outputLink id="lnkHidden" value="AnotherPage.xhtml"
                            style="display:none">
                <f:param name="id" value="#{data.id}" />
            </h:outputLink>
        </h:column>
        <h:column>
            <f:facet name="header">
                <h:outputText value="Value" />
            </f:facet>
            <h:outputText value="#{data.value}" />
        </h:column>
    </h:dataTable>
</h:form>

DataTableBean class

@ManagedBean
@ViewScoped
public class DatatableBean {

    private List<Data> lstData;
    /**
    * Creates a new instance of datatableBean
    */
    public DatatableBean() {
        lstData = new ArrayList<Data>();
        lstData.add(new Data(1, "Hello World"));
        lstData.add(new Data(2, "Hello StackOverflow"));
        lstData.add(new Data(3, "Hello Luiggi"));
        System.out.println("LOL");
    }
    //define getters and setters...
}

AnotherPage.xhtml

<h1>This is another page</h1>
<h:panelGrid columns="2">
    <h:outputText value="Selected ID" />
    <h:outputText value="#{anotherPageBean.id}" />
</h:panelGrid>

AnotherPageBean class

@ManagedBean
@RequestScoped
public class AnotherPageBean {

    private int id;
    /**
    * Creates a new instance of AnotherPageBean
    */
    public AnotherPageBean() {
        try {
            this.id = Integer.parseInt((String)FacesContext
               .getCurrentInstance().getExternalContext()
               .getRequestParameterMap().get("id"));
            //by getting the id you can get more data
        }
        catch (Exception e) {
            this.id = 0;
        }
    }
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • I don't understand how this example can be used. – Peter Penzov Apr 29 '12 at 20:00
  • As far as I see if I add this code when I select a row the row will be just highlighted. I need to open a new page when I select the row. – Peter Penzov May 01 '12 at 19:22
  • 1
    @PeterPenzov that's what I've told you in the js comments – Luiggi Mendoza May 02 '12 at 03:26
  • 1
    I updated the post. I found easy solution to my problem but I don't know how to edit the JSF table. In the example that I found "href" is used to tell the JavaScript which web page to open. is there a similar attribute in JSF which I can use? – Peter Penzov May 02 '12 at 08:50
  • 2
    @PeterPenzov http://www.mkyong.com/jsf2/jsf-2-link-commandlink-and-outputlink-example/ – Daniel May 02 '12 at 09:58
  • what is this in into the function rowOnclick? - && Maybe you mean '&&'? – Peter Penzov May 02 '12 at 18:53
  • 1
    If you have a working example would you upload it for example here, please http://www.2shared.com/ I would like to see how it works. – Peter Penzov May 02 '12 at 19:01
  • @PeterPenzov I've uploaded the sources here http://www.2shared.com/file/2HSzkdAY/DataTableExample.html – Luiggi Mendoza May 02 '12 at 19:34
  • 1
    @PeterPenzov in facelets its not permitted the & symbol, that's why i wrote & twice to simulate && – Luiggi Mendoza May 02 '12 at 19:40
  • Well, Netbeans gives many errors. Anyway, thank you the example works! – Peter Penzov May 02 '12 at 20:33
  • One more question, how I can modify the code instead of opening new page when I click on a row - I wan to open a new page in the same window. – Peter Penzov May 02 '12 at 20:35
  • 1
    @PeterPenzov `window.open('elements[i].href','_self')` or `location.href=elements[i].href` any of those will do the work. – Luiggi Mendoza May 03 '12 at 02:06
  • 1
    I want to ask one more question: I tested the example, it works fine. I saw that the value is passed using the http header. Example: http://localhost:8080/test/AnotherPage.xhtml?id=2 Is there any other way to pass this value somehow hidden from the user? – Peter Penzov May 03 '12 at 13:26
  • 1
    @PeterPenzov you can achieve it by using a `h:commandLink` instead of `h:outputLink` and send the parameter via session scope in the action method. – Luiggi Mendoza May 04 '12 at 02:27
  • Is it possible to do this in @ViewScope? – Peter Penzov May 04 '12 at 09:06
  • One interesting question: If I configure the managed bean in faces-config.xml in ViewScope and I place @SessionScope into the bean body is it going to work? – Peter Penzov May 04 '12 at 09:08