How to have editable fields through liferay search container? - liferay

I am new to liferay development.
I have done good work to display the liferay grid by using liferay search container.
But now the requirement is that some of the fields in the grid should have provision to be modified by user.
Is it possible through liferay search container or do I need to follow any other approach to achieve editable liferay grid?

You can use <liferay-ui:search-container-column-jsp tag or directly use <aui-input /> inside the <liferay-ui:search-container-column-text tag.
Example (I have included code comments with the code sample for your understanding):
<liferay-ui:search-container
emptyResultsMessage="no-assets-selected"
iteratorURL="<%= configurationRenderURL %>"
total="<%= assetEntries.size() %>"
>
<liferay-ui:search-container-results
results="<%= assetEntries.subList(searchContainer.getStart(), searchContainer.getResultEnd()) %>"
/>
<liferay-ui:search-container-row
className="com.liferay.portlet.asset.model.AssetEntry"
escapedModel="<%= true %>"
keyProperty="entryId"
modelVar="assetEntry"
>
<aui:form action="doesThisWork?">
<%-- this is the normal way --%>
<liferay-ui:search-container-column-text
name="type"
value="<%= assetRendererFactory.getTypeName(locale, false) %>"
/>
<liferay-ui:search-container-column-date
name="modified-date"
value="<%= assetEntry.getModifiedDate() %>"
/>
<%--
this is the JSP way
You can include anything in the JSP like <input /> fields, textarea, select drop-down etc.
--%>
<liferay-ui:search-container-column-jsp
align="right"
path="/html/portlet/asset_publisher/asset_selection_action.jsp"
/>
<%--
Here is including <input /> field inside the column text field.
Notice I am not using the "value" attribute of this tag, instead I am
writing HTML inside the body of this tag.
--%>
<liferay-ui:search-container-column-text
name="type"
>
<aui:input type="text" name="enterSomething" value="I can enter input here" />
<aui:input type="text" name="enterSomething" value="<%=assetEntry.getTitle %>" />
<aui:input type="hidden" name="enterSomething" value="this is a hidden field of the form" />
</liferay-ui:search-container-column-text>
</aui:form>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator paginate="<%= total > SearchContainer.DEFAULT_DELTA %>" />
</liferay-ui:search-container>
In the above example, there would be a <form> for each row, so you can have a submit button at the end of each row to submit the data for that row.
But you can do it in other ways as well:
You can write the <form> outside the Search-container tag so that you just have one form and can submit all the row data togather
Or else you can have a <form> somewhere down the page and through javascript populate the value in the form and then submit.
Or else you can use ajax and other stuff to accomplish this. Or a combination of several approaches.
I leave this upto you to figure out.
Disclaimer: I have not test this code. But as per my understanding this should work. :-)

Related

Liferay: How to remove a "Delete" button from "user-profile-portlet"?

I want to remove a "delete" action button from the "user-profile-portlet". I am not core Liferay developer so facing this issue. Any help would be appreciated:
Sample code:
<portlet:renderURL windowState="<%= LiferayWindowState.POP_UP.toString() %>" var="editUserPortraitURL">
<portlet:param name="jspPage" value="/edit_user_portrait.jsp" />
<portlet:param name="redirect" value="<%= currentURL %>" />
<portlet:param name="p_u_i_d" value="<%= String.valueOf(user.getUserId()) %>" />
<portlet:param name="portrait_id" value="<%= String.valueOf(user.getPortraitId()) %>" />
</portlet:renderURL>
<liferay-ui:logo-selector
currentLogoURL="<%= user.getPortraitURL(themeDisplay) %>"
defaultLogoURL="<%= UserConstants.getPortraitURL(themeDisplay.getPathImage(), user.isMale(), 0) %>"
editLogoURL="<%= editUserPortraitURL %>"
imageId="<%= user.getPortraitId() %>"
logoDisplaySelector=".user-logo"
showBackground="<%= false %>"
/>
I recomemend you not to modify directly the portlet, but to modify the permission for the roles that you consider. Here it is explained:
https://dev.liferay.com/discover/portal/-/knowledge_base/6-2/roles-and-permissions
If it is not enough, you can create a hook that will overwrite the jsp you need to modify. For doing this, I recommend you following this:
https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/customizing-jsps-by-extending-the-original
Good luck!
liferay-ui:logo-selector is the tag which displays image and other change and delete control buttons.
Below file is responisble to render that part.
https://github.com/liferay/liferay-portal/blob/master/portal-web/docroot/html/taglib/ui/logo_selector/page.jsp
You have to customize this jsp using hook plugins as mentioned in the link given in #Doc Manhattan's answer.

Issue with Liferay UI tab Navigation

I am using <liferay-ui:tabs> for displaying jsp pages as tabs. I am able to see my pages as tabs but If I navigate to one of my pages in the tab and on click of the button then it is navigating to some other page, that it showing in a separate page instead of showing under that tab. I need to click of button events the control should be still under the tabs. my Code is as follows,
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%><%#include file="/html/users/init.jsp"%>
<portlet: defineObjects />
<portlet:renderURL var="navigateTabURL"/>
<% String navigateTab = ParamUtil.getString(request, "tabs1","Current"); %>
<liferay-ui:tabs names="Current, Available" url="<%=navigateTabURL.toString()%>" >
<c:if test='<%= navigateTab.equalsIgnoreCase("Current")%>' >
<jsp:include page="current_members.jsp" flush="true" />
</c:if>
<c:if test='<%= navigateTab.equalsIgnoreCase("Available")%>' >
<jsp:include page="available_members.jsp" flush="true" />
</c:if>
</liferay-ui:tabs>
The pages "Current" and "Available" are showing correctly, But If I click any button in my Current page it is navigating to some other jsp I need that jsp also under that tabs only not showing as a separate page.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%><%#include file="/html/users/init.jsp"%>
<portlet: defineObjects />
<%
List<User> userList = (List) request.getAttribute("UserGroupList");
//out.println(userList.size());
%>
<%!
List<User> users = null;
int totalNoOfUsers=0;
String value = null;
%>
<%
//totalNoOfUsers = UserLocalServiceUtil.getUsersCount();
totalNoOfUsers = userList.size();
users = userList;
%>
<liferay-ui:search-container delta="5" emptyResultsMessage="no-users-were-found" rowChecker="<%= new RowChecker(renderResponse) %>" >
<liferay-ui:search-container-results results="<%= ListUtil.subList(users,searchContainer.getStart(),searchContainer.getEnd()) %>"
total="<%= totalNoOfUsers %>">
</liferay-ui:search-container-results>
<liferay-ui:search-container-row className="com.liferay.portal.model.User" keyProperty="userId" modelVar="user">
<liferay-ui:search-container-row-parameter name="userIds" value="<%= user.getUserId()%>">
</liferay-ui:search-container-row-parameter>
<liferay-ui:search-container-column-text name="UserName" value="
<%= user.getScreenName()%>" />
<liferay-ui:search-container-column-text name="First Name" value="<%= user.getFirstName() %>">
</liferay-ui:search-container-column-text>
<liferay-ui:search-container-column-text name="Last Name" value="<%= user.getLastName() %>">
</liferay-ui:search-container-column-text>
<liferay-ui:search-container-column-jsp align="right" path="/html/users/custom_user_actions.jsp" />
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
<liferay-ui:search-container delta="5" emptyResultsMessage="no-users-were-found" />
<portlet:actionURL name="viewEntry" var="viewEntryURL"></portlet:actionURL>
<aui:form action="<%= viewEntryURL %>" name="<portlet:namespace />fms">
<aui:button type="submit" value="Cancel"></aui:button>
</aui:form>
How do I navigate the tabs as dynamic requests. Any suggestions please!!
To retain a tab selection, "value" attribute of should be mentioned with name of tab to select.
If "value" attribute not specified then first tab will be considered as active.
For example, please refer following file in liferay portal sources.
portal-web/docroot/html/portlet/dockbar/add_panel.jsp
Also, below post in liferay forum should help.
http://www.liferay.com/en_GB/community/forums/-/message_boards/message/4809190

Query optimization in liferay

I have created a portlet where I want to print the list of users based on some parameter. So for showing list of users I use the following code,
<liferay-ui:search-container delta="10" emptyResultsMessage="no-users-were-found">
<liferay-ui:search-container-results
results="<%= UserLocalServiceUtil.getUsers(0, UserLocalServiceUtil.getUsersCount())%>"
/>
<liferay-ui:search-container-row
className="com.liferay.portal.model.User"
keyProperty="userId"
modelVar="user"
>
<liferay-ui:search-container-column-text
name="name"
value="<%= user.getFullName() %>"
/>
<liferay-ui:search-container-column-text
name="first-name"
property="firstName"
/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
<liferay-ui:search-container delta="10" emptyResultsMessage="no-users-were-found">
But i don't want all the users list. I need only the list of users whose facebookId = 12345. How can query the condition? Any suggestions please..
Thanks in advance

How to convert a portal URL to its corresponding friendly URL

I have implemented friendly-url successfully for few of my custom portlets and it is working fine.
When click-able links are generated, it correctly shows the friendly-url.
Now my requirement is that, I need to send this render-URL (say URL01) as a parameter (param02) to another URL (URL02) and this URL01 then would be displayed on another page.
This is how URL01 is generated:
<portlet:renderURL var="URL01" windowState="<%=WindowState.MAXIMIZED.toString() %>">
<portlet:param name="redirect" value="<%= currentURL %>" />
<portlet:param name="myId" value="<%= String.valueOf(myObject.getMyId()) %>" />
<portlet:param name="title" value="<%= myObject.getTitle() %>" />
<portlet:param name="name" value="<%= myObject.getName() %>" />
</portlet:renderURL>
This is how URL02 is generated
<portlet:renderURL var="URL02" windowState="<%= LiferayWindowState.POP_UP.toString() %>">
<portlet:param name="redirect" value="<%= currentURL %>" />
<portlet:param name="URL01" value="<%=URL01 %>" />
<portlet:param name="ownerId" value="<%= String.valueOf(ownerId) %>" />
<portlet:param name="groupId" value="<%= String.valueOf(scopeGroupId) %>" />
</portlet:renderURL>
This URL02 would open a pop-up and the URL01 would be displayed as below in the JSP:
URL: <%= ParamUtil.getString(request, "URL01") %>
But this shows URL01 (unfriendly-URL) as:
URL: http://localhost:8080/web/guest/mypage?p_p_id=my_WAR_myportlet&p_p_lifecycle=0&p_p_state=maximized&p_p_mode=view&_my_WAR_myportlet_myId=10989&_my_WAR_myportlet_title=This+is+miine&my_WAR_myportlet_name=What+name
If this is a clickable link it generates perfectly as (friendly-URL):
Click me!
So I need a utility which can convert my unfriendly-url to friendly-URL, something like if a String of unfriendly-url is passed - it would convert that to the friendly-url shown above.
Or I have to create an implementation of my own to achieve this?
Edit:
<route>
<pattern>/{myId:\d+}/{title:.+}/{name:.+}/{p_p_state}</pattern>
<ignored-parameter name="redirect" />
<implicit-parameter name="p_p_id">my_WAR_myportlet</implicit-parameter>
<implicit-parameter name="p_p_lifecycle">0</implicit-parameter>
<implicit-parameter name="p_p_mode">view</implicit-parameter>
</route>
And yes the URL01 is written above the URL02 in the JSP.
I think you can create your own <portlet-url-class> and it will be used when you create the portlet URL with the <portlet:renderURL> tag.
In liferay-portlet.xml, you can define the <portlet-url-class> entry.
If you check the source code of PortletResponseImpl.java, the method createLiferayPortletURL() checks for the PortletURLGenerationListener for that portlet.
I think, you can create a this one and modify URL as you want to.

How to use two (multiple) Liferay UI Search Container tags in a single JSP

I need to use two different <liferay-ui:search-container> tags in a single JSP.
The pagination gives issues if we use two <liferay-ui:search-container> tags:
When I click on the 3rd page of the first <liferay-ui:search-container> tag the second <liferay-ui:search-container> tag also moves to the third page.
Also if for the first <liferay-ui:search-container> tag I am on page-3 and I click page-2 of second <liferay-ui:search-container> tag then the second tag goes to page-2 but the first tag results is reset to page-1.
They should be independent of each other.
Environment: Liferay 6.+
I found two different ways to do this:
This is possible through the use of curParam attribute in <liferay-ui:search-container> tag, noticed the curParam="folderCurParam" and curParam="fileCurParam" in the following code, I found this way through liferay's source code docroot/html/portlet/document_library_display/view.jsp and docroot/html/portlet/document_library_display/view_file_entries.jspf:
<liferay-ui:search-container
curParam="folderCurParam"
emptyResultsMessage="no-folders-to-display"
iteratorURL="<%= portletURL %>"
delta="10">
<liferay-ui:search-container-results
results="<%=folderResults %>"
total="<%= folderTotal %>" />
<liferay-ui:search-container-row
className="com.liferay.portal.kernel.repository.model.Folder"
keyProperty="userId"
modelVar="folder">
<liferay-ui:search-container-column-jsp align="left"
path="/html/documentdisplay/folder_search_results.jsp" />
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
<liferay-ui:search-container
curParam="fileCurParam"
emptyResultsMessage="no-files-to-display"
iteratorURL="<%= portletURL %>"
delta="10">
<liferay-ui:search-container-results
results="<%=fileResults %>"
total="<%= fileTotal %>" />
<liferay-ui:search-container-row
className="com.liferay.portal.kernel.repository.model.FileEntry"
keyProperty="userId"
modelVar="fileEntry">
<liferay-ui:search-container-column-jsp align="left"
path="/html/documentdisplay/files_search_results.jsp" />
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
I found this again in liferay's source code docroot/html/portlet/journal/select_document_library.jsp, this uses the SearchContainer constructor to set the curParam, notice the parameter "cur1" for folders and for files it is "cur2":
// for folders
SearchContainer searchContainer = new SearchContainer(renderRequest, null, null, "cur1", SearchContainer.DEFAULT_DELTA, portletURL, headerNames, "there-are-no-folders");
// for files
searchContainer = new SearchContainer(renderRequest, null, null, "cur2", SearchContainer.DEFAULT_DELTA, portletURL, headerNames, "there-are-no-documents-in-this-folder");
Hope this helps someone.

Resources