Liferay 6: Portlet View in MAXIMIZED State - liferay

Once the request is made to the MVCPortlet class , i want to show the View in MAXIMIZED State .
This is my Code in JSP Page
<portlet:actionURL name="addBook" var="addBookURL" />
<aui:form action="<%= addBookURL.toString() %>" method="post">
<aui:input type="text" name="name"></aui:input>
<aui:input type="password" name="pwd"></aui:input>
<aui:button type="submit"></aui:button>
</aui:form>
This is my MVCPortlet class :
if(true)
{
response.setPortletMode(PortletMode.VIEW);
response.setWindowState(WindowState.MAXIMIZED);
}
else
{
response.setPortletMode(PortletMode.VIEW);
response.setWindowState(WindowState.MAXIMIZED);
}
And this is the result (Please see the image below )
My question is that , i was expecting that once the Action class is called , so the Portlet will be displayed in MAXIMIZED State .
But still the Portlet remains in NORMAL State , please let me know why ?and how can i Portlet View in MAXIMIZED State after the result from MVCPortlet class .

You have two possibilities how to display portlet in maximized mode. You either add windowState parameter with value maximized to the actionURL tag (it will allways show the link to portlet in maximized state), or you put this line
response.setWindowState(WindowState.MAXIMIZED);
into processAction method of your portlet (you can make a decision based on something).
(this is what specification says, but Liferay usually adheres to it).

Related

Setting a command button to selected by default

I have a form in which I needed to have radio buttons that look like bootstrap toggle buttons. I achieved this by using command buttons in a button group, and setting the attribute data-toggle="buttons-radio", like so:
<div id="flightChoiceButtons" class="btn-group" data-toggle="buttons-radio">
<h:commandButton type="button" styleClass="btn btn-inverse" value="One Way"><f:ajax render="flexibleDates" listener="#{searchFlightsBean.setDirectionOneWay}"/></h:commandButton>
<h:commandButton type="button" styleClass="btn btn-inverse" value="Round Trip"><f:ajax render="flexibleDates" listener="#{searchFlightsBean.setDirectionRoundtrip}"/></h:commandButton>
</div>
The problem I'm stuck with right now is that I need the "Round Trip" button to be selected, or in the down state, when the page loads. I don't need the button's ajax call to be fired, because the data displayed on the page is already in the state it needs to be in.
Anyone have any ideas?
If any more information is needed I'd be glad to supply it.
The bootstrap button's active state is identified by presence of active style class. Knowing that, you can just let JSF print the style class conditionally. The way how your model is setup is unclear, so here's just a kickoff example provided that you've a #{searchFlightsBean.direction} property returning an enum.
<h:commandButton ... styleClass="btn btn-inverse #{searchFlightsBean.direction == 'ONE_WAY' ? 'active' : ''}">...</h:commandButton>
<h:commandButton ... styleClass="btn btn-inverse #{searchFlightsBean.direction == 'ROUND_TRIP' ? 'active' : ''}">...</h:commandButton>
You can replace the #{searchFlightsBean.direction == '...'} part by any other boolean condition. You can find examples in this answer: Conditionally displaying JSF components.

h:commandLink refusing to invoke method and randomly redirects to project root

I'm been scratching my head over this one... I have plenty of projects with a working commandLink element, however I cannot for the life of me get it to work in this project. I've followed BalusC response here: commandButton/commandLink/ajax action/listener method not invoked or input value not updated down to the letter and yet still no joy.
Currently I've boiled my code down to as simple as it can go:
#ManagedBean
#SessionScoped
public class TestBean {
private #Inject transient Logger logger;
public void testEvent(ActionEvent actionEvent) {
logger.log(Level.INFO, "Event Fired!!");
return;
}
}
In my xhtml file i have:
<h:form>
<h:commandLink id="test" actionListener="#{testBean.testEvent}" value="Test Me!"/>
</h:form>
When I click the link, the method is not invoked, and I am redirected to the web-apps root (login page, despite having a login filter :/) If I change the link to a commandButton it works as expected.
The current application utilises the ui:composition tags for templating, and I've triple checked for nested h:form tags, I'm not using any ajax calls or additional JS libraries. My templates implement jsf tags where it matters i.e. h:head, h:body etc.. Could anyone provide any indication or possible causes for the weird behavior I am experiencing?
Finally I have tested this commandLink in on various pages within my web-app and the commandLink element in general just refuses to invoke.
Here is the compiled html of my link if anyone is interested:
<form id="j_idt26" name="j_idt26" method="post" action="/my-project/webpages/Login.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt26" value="j_idt26" />
<a id="j_idt26:test" href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt26'),{'j_idt26:test':'j_idt26:test'},'');return false">Test Me!</a><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-109553560791909389:-730254890454894147" autocomplete="off" />
</form>
After rebuilding the project, commandLinks work as they should and I was unable to reproduce the error in my new project. If I get time, I will try and debug my original project and determine what the original issue is/was.

JSF - Send object to bean parameter

I am learning JSF and when I send an object to a bean parameter the instance of the object is not correct.
I have a page that list a lot of movies, if I want to see the complete information about a movie, I click on a link that send me to a page with this code:
<h:form>
<h:commandLink action="#{sharedMovie.share(movie)}" value="Share">
<div class="movieDetail">
<div class="movieDetailTitle">"#{movie.title}"</div>
<div class="movieDetailYear">"#{movie.year}"</div>
<div class="movieDetailSynopsis">"#{movie.synopsis}"</div>
</div>
</h:form>
The movie bean have a request scope.
The problem is that when I click on "Share" my class sharedMovie receives a new instance of Movie, instead of the displayed movie in the page. All the displayed data is correct, only when I call the other page that this problem happens.
I already tried sending just the movie ID (but it is always 0), using f:setPropertyActionListener, f:param, but nothing works. If I debug my project, when I click on share link it always hit the breakpoint inside the constructor of Movie class.
How I can pass this instance correctly?

Difference between h:button and h:commandButton

In JSF 2, what is the difference between h:button and h:commandButton ?
<h:button>
The <h:button> generates a HTML <input type="button">. The generated element uses JavaScript to navigate to the page given by the attribute outcome, using a HTTP GET request.
E.g.
<h:button value="GET button" outcome="otherpage" />
will generate
<input type="button" onclick="window.location.href='/contextpath/otherpage.xhtml'; return false;" value="GET button" />
Even though this ends up in a (bookmarkable) URL change in the browser address bar, this is not SEO-friendly. Searchbots won't follow the URL in the onclick. You'd better use a <h:outputLink> or <h:link> if SEO is important on the given URL. You could if necessary throw in some CSS on the generated HTML <a> element to make it to look like a button.
Do note that while you can put an EL expression referring a method in outcome attribute as below,
<h:button value="GET button" outcome="#{bean.getOutcome()}" />
it will not be invoked when you click the button. Instead, it is already invoked when the page containing the button is rendered for the sole purpose to obtain the navigation outcome to be embedded in the generated onclick code. If you ever attempted to use the action method syntax as in outcome="#{bean.action}", you would already be hinted by this mistake/misconception by facing a javax.el.ELException: Could not find property actionMethod in class com.example.Bean.
If you intend to invoke a method as result of a POST request, use <h:commandButton> instead, see below. Or if you intend to invoke a method as result of a GET request, head to Invoke JSF managed bean action on page load or if you also have GET request parameters via <f:param>, How do I process GET query string URL parameters in backing bean on page load?
<h:commandButton>
The <h:commandButton> generates a HTML <input type="submit"> button which submits by default the parent <h:form> using HTTP POST method and invokes the actions attached to action, actionListener and/or <f:ajax listener>, if any. The <h:form> is required.
E.g.
<h:form id="form">
<h:commandButton id="button" value="POST button" action="otherpage" />
</h:form>
will generate
<form id="form" name="form" method="post" action="/contextpath/currentpage.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form" value="form" />
<input type="submit" name="form:button" value="POST button" />
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="...." autocomplete="off" />
</form>
Note that it thus submits to the current page (the form action URL will show up in the browser address bar). It will afterwards forward to the target page, without any change in the URL in the browser address bar. You could add ?faces-redirect=true parameter to the outcome value to trigger a redirect after POST (as per the Post-Redirect-Get pattern) so that the target URL becomes bookmarkable.
The <h:commandButton> is usually exclusively used to submit a POST form, not to perform page-to-page navigation. Normally, the action points to some business action, such as saving the form data in DB, which returns a String outcome.
<h:commandButton ... action="#{bean.save}" />
with
public String save() {
// ...
return "otherpage";
}
Returning null or void will bring you back to the same view. Returning an empty string also, but it would recreate any view scoped bean. These days, with modern JSF2 and <f:ajax>, more than often actions just return to the same view (thus, null or void) wherein the results are conditionally rendered by ajax.
public void save() {
// ...
}
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
When should I use h:outputLink instead of h:commandLink?
Differences between action and actionListener
h:button - clicking on a h:button issues a bookmarkable GET request.
h:commandbutton - Instead of a get request, h:commandbutton issues a POST request which sends the form data back to the server.
h:commandButton must be enclosed in a h:form and has the two ways of navigation i.e. static by setting the action attribute and dynamic by setting the actionListener attribute hence it is more advanced as follows:
<h:form>
<h:commandButton action="page.xhtml" value="cmdButton"/>
</h:form>
this code generates the follwing html:
<form id="j_idt7" name="j_idt7" method="post" action="/jsf/faces/index.xhtml" enctype="application/x-www-form-urlencoded">
whereas the h:button is simpler and just used for static or rule based navigation as follows
<h:button outcome="page.xhtml" value="button"/>
the generated html is
<title>Facelet Title</title></head><body><input type="button" onclick="window.location.href='/jsf/faces/page.xhtml'; return false;" value="button" />
This is taken from the book - The Complete Reference by Ed Burns & Chris Schalk
h:commandButton vs h:button
What’s the difference between h:commandButton|h:commandLink and
h:button|h:link ?
The latter two components were introduced in 2.0 to enable bookmarkable
JSF pages, when used in concert with the View Parameters feature.
There are 3 main differences between h:button|h:link and
h:commandButton|h:commandLink.
First, h:button|h:link causes the browser to issue an HTTP GET
request, while h:commandButton|h:commandLink does a form POST. This
means that any components in the page that have values entered by the
user, such as text fields, checkboxes, etc., will not automatically
be submitted to the server when using h:button|h:link. To cause
values to be submitted with h:button|h:link, extra action has to be
taken, using the “View Parameters” feature.
The second main difference between the two kinds of components is that
h:button|h:link has an outcome attribute to describe where to go next
while h:commandButton|h:commandLink uses an action attribute for this
purpose. This is because the former does not result in an ActionEvent
in the event system, while the latter does.
Finally, and most important to the complete understanding of this
feature, the h:button|h:link components cause the navigation system to
be asked to derive the outcome during the rendering of the page, and
the answer to this question is encoded in the markup of the page. In
contrast, the h:commandButton|h:commandLink components cause the
navigation system to be asked to derive the outcome on the POSTBACK
from the page. This is a difference in timing. Rendering always
happens before POSTBACK.
Here is what the JSF javadocs have to say about the commandButton action attribute:
MethodExpression representing the application action to invoke when
this component is activated by the user. The expression must evaluate
to a public method that takes no parameters, and returns an Object
(the toString() of which is called to derive the logical outcome)
which is passed to the NavigationHandler for this application.
It would be illuminating to me if anyone can explain what that has to do with any of the answers on this page. It seems pretty clear that action refers to some page's filename and not a method.

How can I get the values submitted from a JSP in Liferay?

I am using Liferay Portal 6 version.
How can I get the UserName and Password values with in the same page?
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%#page import="javax.portlet.RenderRequest"%>
<portlet:defineObjects />
This is the <b>Kiran</b> portlet.
<form>
<p><b>UserName:</b> <input type="text" name="UserName" size="10"></p>
<p><b>Password:</b> <input type="Password" name="Password"
size="10"></p>
<p><input type="submit" value="Submit" name="submit"><input type=
"reset" value="Reset" name="reset"></p><hr><hr>
</form>
<%
// here
%>
I'm not sure if its submitting the values correctly as your form has no target and is not refering to a portlet action url.
This tutorial shows some basic usage and parameter retrieval. Check the JSP portlet section. You should be able to access the request object in your jsp as well.
I wouldn't start writing JSP portlets. Its quite outdated nowadays. Check Spring Portlet MVC or even consider JSF.
In a portal/portlet all identifiers must be properly namespaced - you never know what other content ends up on the same html document with you. Thus a form control should rather read:
<input type="text" name="<portlet:namespace/>user" .../>
in order to be able to retrieve the parameter as "user" from the request.
If, in Liferay 6, you use the AlloyUI taglibs, a lot of this namespacing is done automatically for you.
Also, you should add the portlet action URL as Udo Held suggests:
<form action="<portlet:actionURL/>">
What are you trying to get ? Do you want to get the username and password in some other .java file or .jsp file ?? Or do you want to get the username and password once a user logs in ?
If you are trying to get user details set in present jsp page in some other .java or .jsp, then simply use the PortletSession.
Eg: From jsp
PortletSession portletSession = actionRequest.getPortletSession();
portletSession.setAttribute("liferayUserMap", liferayUserMap,PortletSession.APPLICATION_SCOPE);
From .java/.jsp
PortletSession portletSession = actionRequest.getPortletSession();
portletSession.getAttribute("liferayUserMap",PortletSession.APPLICATION_SCOPE);
By doing so, you can share the data among different files in different portlets too.
For case 2: If you are trying to get the user details, simply do the following:
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
themeDisplay.getUser();
I hope you are following the portlet structures while coding, otherwise the above mentioned code wouldn't work. Since you have to point to some action class, in the 'struts-config' and 'tiles-def'

Resources