How to hide portlet in liferay by using javascript - liferay

Actually on a single page I have 2 portlet but I want to hide the first portlet by clicking the submit button and only the second portlet should be visible I used the following code:
document.getElementById("portlet-id").style.visibility='none'
But after refreshing the page, again portlet is visible can anyone provide me the solution as to how I can proceed.

You can set the visibility of the portlet to false in the JSP by using the following code:
<%
renderRequest.setAttribute(WebKeys.PORTLET_CONFIGURATOR_VISIBILITY, Boolean.FALSE);
%>
This would hide your portlet from user's view.
Everytime your portlet is rendered you can check a parameter which was set in the request or session (your choice) to either show the portlet or not show the portlet, like:
<%
String paramFromRequestToHide = renderRequest.getParameter("hidePortlet");
// can also fetch from session: portletSession.getAttribute("hidePortlet");
if (paramFromRequestToHide .equals("YES")) { // you can use your favorite data-type
renderRequest.setAttribute(WebKeys.PORTLET_CONFIGURATOR_VISIBILITY, Boolean.FALSE);
} else {
renderRequest.setAttribute(WebKeys.PORTLET_CONFIGURATOR_VISIBILITY, Boolean.TRUE);
}
%>
Another method:
If you don't want to go with the above approach then you can combine your javascript approach with the parameter approach as follows:
<%
String paramFromRequestToHide = renderRequest.getParameter("hidePortlet");
if (paramFromRequestToHide .equals("YES")) {
%>
<aui:script>
Liferay.Portlet.ready(
/*
This function gets loaded after each and every portlet on the page.
portletId: the current portlet's id
node: the Alloy Node object of the current portlet
*/
function(portletId, node) {
document.getElementById(portletId).style.display = 'none';
// or alternatively using pure Alloy UI
// node.hide();
}
);
</aui:script>
<%
} else {
%>
<aui:script>
Liferay.Portlet.ready(
function(portletId, node) {
document.getElementById(portletId).style.display = 'block';
// or alternatively using pure Alloy UI
// node.show();
}
);
</aui:script>
<%
}
%>
In case you want to check-out Alloy UI API and some of the demos to learn Alloy UI since starting from Liferay 6.1 Alloy UI is the de-facto javascript library for liferay. Now Alloy UI has an official web-site with many helpful tutorials and examples.
Hope this gives you ample material to proceed :-)

You also can do like this :
If your portlet id is : callcenter_WAR_xyzyportlet
$('#p_p_id_callcenter_WAR_xyzyportlet_').css({display:'none'});

Related

Multiple actions in edit mode Liferay MVC

I am following the following example: https://github.com/liferay/liferay-blade-samples/blob/7.1/maven/apps/configuration-action/src/main/java/com/liferay/blade/samples/configurationaction/MessageDisplayConfigurationAction.java
I have multiple submit buttons in my form. I'd like to handle them in multiple methods. This is possible in Spring MVC Portlet. For example, you can do this: Attach an onlclick event of the button to a function that looks like this:
function <portlet:namespace />addGroup(){
var url = "<portlet:actionURL portletMode='edit'><portlet:param name='action' value='addGroup'/></portlet:actionURL>";
submitForm(document.<portlet:namespace />fm, url);
}
And in the code we can do like this:
#RequestMapping("EDIT")
#ActionMapping(params = "action=addGroup")
public void handleAddGroup(ActionRequest actionRequest, ActionResponse response) throws ResearchLibraryException, Exception {
PortletPreferences preferences = actionRequest.getPreferences();
// Add something to preferences
preferences.store();
}
How to do the same thing in Liferay MVC. I would like to use multiple methods. Right now, I can do only one method and switch based on the condition and identify the different clicks.
This shouldn't be much different with Liferay MVC portlets.
You should invoke a Liferay RenderCommand or ActionCommand.
Check out https://portal.liferay.dev/docs/7-0/tutorials/-/knowledge_base/t/mvc-render-command or https://portal.liferay.dev/docs/7-0/tutorials/-/knowledge_base/t/mvc-action-command
For example, the action command will be its own OSGi component:
#Component(
immediate = true,
property = {
"javax.portlet.name=your_portlet_name_YourPortlet",
"mvc.command.name=/your/jsp/action/url"
},
service = MVCActionCommand.class
)
public class YourMVCActionCommand extends BaseMVCActionCommand {
// implement your action
}
with this URL generation:
<portlet:actionURL name="/your/jsp/action/url" />
In addition to Jan's good answer: Even the portlet spec allows you to have multiple action methods with a standardized annotation. This has been made even easier with LiferayMVC portlets, in that you can even omit the annotation and just use the method name as action name:
// this is the action method defined by the portlet spec (2.0)
#ProcessAction(name="doSomething")
public void doSomething(ActionRequest request, ActionResponse response) {
log.info("doSomething");
}
// this works in Liferay MVC, the method name is the action name
public void doSomethingElse(ActionRequest request, ActionResponse response) {
log.info("doSomethingElse");
}
You'll generate the URLs like this, for example in a JSP:
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:actionURL name="doSomething" var="doSomethingURL" />
do something
<br/>
<portlet:actionURL name="doSomethingElse" var="doSomethingElseURL" />
do something else
On top of that, you can create ActionCommands and RenderCommands, as Jan mentions. This will break up the functionality even more, into individual classes. IMHO that's preferable (as it makes them all independent of each other and smaller)
A condition to get this functionality is to not override processAction, as its default implementation tries to find annotated methods, or methods with the required interface.

liferay change page title dynamically

I'm trying to change the title of the page, but the method PortalUtil.setPageTitle("title", request); is not working from the jsp. I also tried in the doView method.
My second attempt was throught servletrequest:
In doView I wrote
HttpServletRequest httpRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
httpRequest.setAttribute("hola", "hola");
And in the portal normal I tried with:
#set ($holas =$request.get('attributes').get('hola'))
#set ($holas2 = $request.getSession().getAttribute("hola"))
$holas
$holas2
but Velocity only shows $holas $holas2.
Looks like I got it wrong in my first attempt - thus I've replaced the previous answer with this one: Add this code to your JSP or doView:
<%
com.liferay.portal.util.PortalUtil.setPageTitle("Honk", request);
%>
In your jsp you should try
<%
layout.setTitle("title");
%>
layout is an Layout object generated by jsp.
Use below code,
String title = (String)renderRequest.getAttribute("title");
HtmlPageTitleUtil.setHtmlTitle(title, request, true);
Pass title attribute from the controller or you can use static text as well.
Import the above utility class as well as,
<portlet:defineObjects />
<theme:defineObjects />
this to jsp and its done.

Method to display list of available portlets in a portlet

Generally liferay has ADD option for displaying available portlets.
I want them to appear in a drop-down and that should be in a custom plugin-portlet, so I am searching in API which method is retrieving the available portlets, but I didn't find any.
Please help me in this as I am stuck with this and also on selecting from the drop-down the portlet should be added to the page.
The "Add...More" dialog is displayed by the dockbar portlet. You can find the implementation of the UI part of this in Liferay's source in portal-web/docroot/html/portlet/dockbar/add_panel.jsp, which also includes view_category.jsp in the same directory.
While this jsp code is not the prettiest, you'll easily find that PortletLocalService is the one where you find the relevant information, together with an actual sample of how to access the list of portlets by category, sort them according to the current user's locale etc.
As you're asking for more concrete pointers: In add_panel.jsp you can find:
for (PortletCategory curPortletCategory : categories) {
if (curPortletCategory.isHidden()) {
continue;
}
request.setAttribute(WebKeys.PORTLET_CATEGORY, curPortletCategory);
request.setAttribute(WebKeys.PORTLET_CATEGORY_INDEX, String.valueOf(portletCategoryIndex));
%>
<liferay-util:include page="/html/portlet/dockbar/view_category.jsp" />
<%
portletCategoryIndex++;
}
%>
and some excerpts from view_category.jsp:
<%
PortletCategory portletCategory = (PortletCategory)request.getAttribute(WebKeys.PORTLET_CATEGORY);
int portletCategoryIndex = GetterUtil.getInteger((String)request.getAttribute(WebKeys.PORTLET_CATEGORY_INDEX));
// ...
Set<String> portletIds = portletCategory.getPortletIds();
// ...
for (String portletId : portletIds) {
Portlet portlet = PortletLocalServiceUtil.getPortletById(user.getCompanyId(), portletId);
if ((portlet != null) && PortletPermissionUtil.contains(permissionChecker, layout, portlet, ActionKeys.ADD_TO_PAGE)) {
portlets.add(portlet);
// ... and so on
Hope this excerpt helps. See the rest of the file for what you can actually do with the resulting list. Also, Portlet's interface might help if you need more details.

Liferay - Link in Dockbar depedent on user group using hook

I am fairly new to the new liferay platform and using hooks. I am adding the currently logged-in user's email next to their name in the Dockbar portlet. I would like this email to link to, when clicked, to a different link depending on whether the user is in either of two groups.
This is what I have written so far in the hook...
//if user is in "group1" show this link
<aui:a cssClass='<%= "user-email" %>' href="link1" title="Gmail">
<%= "(" + HtmlUtil.escape(user.getDisplayEmailAddress() + ")") %>
</aui:a>
//if user is in "group2" show this link
<aui:a cssClass='<%= "user-email" %>' href="link2" title="Outlook">
<%= "(" + HtmlUtil.escape(user.getDisplayEmailAddress() + ")") %>
</aui:a>
How can I achieve this should I be using a <c:if> tag? or can someone exemplify?
You can retrieve the scopeGroupId available in the dockbar's jsp and from that you can retrieve the Group instance.
And then check on which group's page the User is currently and change the href accordingly.
or you can also use the following code in your JSP:
Group group = null;
if(themeDisplay.getLayout().getGroup().isSite()) { // this will tell if the Group is a site or not
group = themeDisplay.getLayout().getGroup(); // fetching the site group instance
}
String href;
if (themeDisplay.getLayout().getGroup().getName().equalsIgnoreCase("group1")) {
href = "group1_link";
} else {
href = "group2_link";
}
Note: themeDisplay is available in Liferay's JSP and to use in your custom portlets you can use <liferay-theme:defineObjects /> tag.
Hope I have understood your question properly and answered accordingly.

how do you pass in a collection to an MVC 2 partial view?

how do you pass in a collection to an MVC 2 partial view?
I saw an example where they used the syntax;
<% Html.RenderPartial("QuestionPartial", question); %>
this passes in only ONE question object..
what if I want to pass in several questions into the partial view and , say, I want to list them out.
How would I pass in SEVERAL questions?
Because your partial view will usually be placed in some other (main) view, you should strongly-type your main view to a composite ViewData object that looks something like this:
public class MyViewData
{
public string Interviewee { get; set }
// Other fields here...
public Question[] questions { get; set }
}
In your controller:
var viewData = new MyViewData;
// Populate viewData object with data here.
return View(myViewData);
and in your view:
<% Html.RenderPartial("QuestionPartial", Model.questions); %>
Then use tvanfosson's advice on the partial view.
Instead of passing question, why not pass a collection of questions, for instance List<QuestionType>?
Normally, you'd have an IEnumerable<Question> as a property in your view model -- in reality it might be a list or an array of Question objects. To use it in your partial, just pass that property of the view model as the model to the partial. The partial should be strongly typed to accept an IEnumerable<Question> as it's model.
<% Html.RenderPartial("QuestionPartial", Model.Questions ); %>
Partial:
<%# Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Question>>" %>

Resources