0

I have a example with h:datatable which is used to open a new page when the user clicks on a table row. Unfortunately this example uses the http header to pass argument to the opened page. My question is can this be implemented but with passing the argument into the background not with the header?

This is the complete source code:

This is the JSF page:

<?xml version="1.0" encoding="UTF-8"?>
<!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">
    <head>
        <title>test</title>
        <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 childNodes = tr.childNodes;
                //                for(var i = 0; childNodes.length > i; i++) {
                //                    
                //                }

                var elements = tr.cells[0].childNodes;
                for(var i = 0; elements.length > i; i++) {
                    if ((typeof elements[i].id !== "undefined") &amp;&amp;
                    (elements[i].id.indexOf("lnkHidden") > -1)) {
                      //opne in a new window//  window.open(elements[i].href);
                        location.href=elements[i].href
                        break;
                    }
                }
                return false;
            }
        </script>
    </head>
    <body onload="addOnclickToDatatableRows();">
        <h:form id="myForm">
            <h1>Click on table row example</h1>
            <h:dataTable id="dataTable" var="data" value="#{datatableBean.lstData}" border="1">
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="ID" />
                    </f:facet>
                    <h:outputText value="#{data.id}" />
                    <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="Value1" />
                    </f:facet>
                    <h:outputText value="#{data.value}" />
                </h:column>
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="Value2" />
                    </f:facet>
                    <h:outputText value="#{data.value}" />
                </h:column>
            </h:dataTable>
        </h:form>
    </body>
</html>

This is the managed bean:

    package edu.home;

    import edu.home.model.Data;
    import java.util.ArrayList;
    import java.util.List;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;

    @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 123"));
            lstData.add(new Data(3, "Hello abv"));
            lstData.add(new Data(4, "Hello qaz"));
        }

        /**
         * @return the lstData
         */
        public List<Data> getLstData() {
            return lstData;
        }

        /**
         * @param lstData the lstData to set
         */
        public void setLstData(List<Data> lstData) {
            this.lstData = lstData;
        }
    }

This is the class Data:

package edu.home.model;

public class Data {

    private int id;
    private String value;

    public Data(int id, String value) {
        this.id = id;
        this.value = value;
    }
    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * @return the value
     */
    public String getValue() {
        return value;
    }

    /**
     * @param value the value to set
     */
    public void setValue(String value) {
        this.value = value;
    }
}

I'm sure that this is possible but I can thing of a way to pass the argument into the appropriate way.

Best wishes

EDIT I understand that the h:outputLink must be changed this way:

<h:column>
    <f:facet name="header">
        <h:outputText value="ID" />
    </f:facet>
    <h:outputText value="#{data.id}" />
    <h:commandLink id="lnkHidden" value="AnotherPage.xhtml"
                    style="display:none">
        <f:param name="id" value="#{data.id}" />
    </h:commandLink>
</h:column> 

But I don't understand how the managed bean must be changed. Maybe I suppose if AnotherPage.xhtml can access the managed bean of DataTable.xhml and take the value that I want to pass? But maybe then I need to change the javaScript?

berkay
  • 3,907
  • 4
  • 36
  • 51
Peter Penzov
  • 1,126
  • 134
  • 430
  • 808
  • 2
    I've already answered you when you asked this in [older post](http://stackoverflow.com/q/10374620/1065197): you should change `` to `` or a `` perform the logic and navigation in your action method. You should try some code before asking for help. – Luiggi Mendoza May 07 '12 at 13:46
  • 1
    Peter you should learn how the tag components work in JSF 2. I recommend you read [JSF 2 commandbutton](http://www.mkyong.com/jsf2/jsf-2-button-and-commandbutton-example/) and [action for commandButton](http://stackoverflow.com/a/3807808/1065197), last one made by BalusC (JSF expert) – Luiggi Mendoza May 07 '12 at 14:47
  • ok, I changed the JSF page this way: http://pastebin.com/BCZSNsEh But now when I click on the table row I get this header: http://localhost:8080/test-1.0-SNAPSHOT/# Maybe the JavaScript must be changed? – Peter Penzov May 07 '12 at 17:18
  • 1
    I've made an example of navigation using `` [using this code](http://pastebin.com/MCB2v4BN). NOTE: When you execute a button using javascript, you call the `click` method: `elements[i].click()`. Also, check [this link](http://www.devdaily.com/blog/post/servlets/view-servlet-httpsession-variables-from-jsf) to know how to access HttpSession (to access HttpRequest is similar but use `facesContext#getExternalContext()#getRequest()`) – Luiggi Mendoza May 07 '12 at 18:24
  • 2
    You basically want an idempotent POST request. This is not possible. You should either live with the parameters being visible in the URL (I do for life not understand why that is a problem), or to live with the URL not being changed due to the nature of a server side forward. I have ever answered the right approach on one of your previous chameleon questions, but I deleted it because you were asking for the impossible and didn't want to change mind. Oh, please don't call an URL a "header". A HTTP header is something entirely different. – BalusC May 10 '12 at 15:27
  • I have one idea. Luiggi showed me how to click on a datatable row and open a new page. Maybe it can be implemented this way: When the row is clicked the id of the row can be set to the managed bean of the row using setter. The bean of the row will hold the id. After that when the new page is open the managed bean of the new page will get the value from the managed bean of the datatable bean(maybe with CDI or extending classes). I can image it simple but I'm not that good in Java or JSF. Sorry for my bad English. – Peter Penzov May 10 '12 at 19:05

1 Answers1

2

You try using and render your table by yourself.

Here is my sample. Modify it according to your requirement. I used JSF 2.0

<h:form id="nextPage">

    <table>
        <ui:repeat var="row" value="#{shoppingCartMB.shoppingItems}">
            <tr onclick="clickedMe('#{row.productId}');">
                <td>#{row.productId}</td>
            </tr>
        </ui:repeat>
    </table>

    <script>

        function clickedMe(id)
        {

            // Please modify following URL base on ur requirment.. 
            // Following is just for sample..
            location.href="#{request.contextPath}/product/" + id;
        }

    </script>
</h:form>

Here is some of pretty-config.xml

<url-mapping id="productMB-loadProductDetail">
    <pattern value="/product/#{ productMB.productId }" />
    <view-id value="/pages/product-detail.jsf" />      
    <action>#{productMB.loadProductDetail}</action>  
</url-mapping>

There inside productMB (managed bean) 's loadProductDetail() , you put another redirect(..).

Something like this..

response.sendRedirect(request.getContextPath() + "/product-info");

in pretty config again..

You have to put config for above url..

<url-mapping id="product-info">
    <pattern value="/product-info" />
    <view-id value="/pages/product-info.jsf" />
</url-mapping>

In my app, I did something like that to hide some URL.

Hope this help.

Here is my sample source code and my understanding.. I uploaded in zip file to 4shared.com http://www.4shared.com/zip/ctPZ4Dbj/URL_Hidding.html

Aung Thaw Aye
  • 437
  • 3
  • 7
  • OP mentioned he don't want the row identifier in URL. – BalusC May 11 '12 at 13:56
  • Please try use PrettyFace.. you may be able to hide that url. Do smth like this below.. I edited my old post – Aung Thaw Aye May 11 '12 at 14:05
  • That won't work on a GET where the product ID is not been passed. – BalusC May 11 '12 at 14:15
  • Umm.. Just now I have tested with small module and it works fine.. When I clicked table row.. it load the detail of that product and showed in another page with URL smth like this localhost:8080/flower/product/product-info (Here flower is my context) – Aung Thaw Aye May 11 '12 at 14:16
  • Thank you for the example! @Code Behind would you upload the code here, please: http://www.2shared.com/ I downloaded the torrent but there is no seed. – Peter Penzov May 11 '12 at 17:24