Liferay 7新手开发者求助:实现组织机构级联下拉选择框
实现Liferay 7中组织机构联动下拉框
嘿,作为Liferay 7的新手,你已经成功迈出了第一步!接下来咱们一步步搞定依赖第一个下拉框的子组织机构选择功能,实现无刷新的联动效果~
一、后端修改:添加子机构资源接口
首先咱们需要在你的NetcofilmoPortlet中添加一个资源处理方法,用来接收前端传递的父机构ID,返回对应的子组织机构数据。Liferay的MVCPortlet通过serveResource方法处理AJAX这类资源请求,非常适合这个场景:
import com.liferay.portal.kernel.json.JSONArray; import com.liferay.portal.kernel.json.JSONFactoryUtil; import com.liferay.portal.kernel.json.JSONObject; import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet; import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.StringUtils; import com.liferay.portal.kernel.service.OrganizationLocalServiceUtil; import com.liferay.portal.kernel.model.Organization; import javax.portlet.ResourceRequest; import javax.portlet.ResourceResponse; import java.io.IOException; import java.util.List; public class NetcofilmoPortlet extends MVCPortlet { // 你原来的getOrga方法保留不变 public List<Organization> getOrga() { Long companyId = PortalUtil.getCompanyIds()[0]; Long parentOrgaId = OrganizationLocalServiceUtil.getOrganizationId(companyId, "Crédit Agricole"); List<Organization> Siege = OrganizationLocalServiceUtil.getOrganizations(companyId, parentOrgaId); return Siege; } @Override protected void doDispatch(RenderRequest request, RenderResponse response) throws IOException, PortletException { request.setAttribute("listeOrganisations", getOrga()); super.doDispatch(request, response); } // 新增:处理子机构AJAX请求的方法 @Override public void serveResource(ResourceRequest request, ResourceResponse response) throws IOException, PortletException { super.serveResource(request, response); // 获取前端传递的父机构ID String parentOrgIdStr = request.getParameter("parentOrgId"); if (StringUtils.isNotEmpty(parentOrgIdStr)) { Long parentOrgId = Long.parseLong(parentOrgIdStr); // 从请求中获取当前公司ID(比直接取数组第一个更健壮) Long companyId = PortalUtil.getCompanyId(request); // 查询该父机构下的子组织机构 List<Organization> subOrganizations = OrganizationLocalServiceUtil.getOrganizations(companyId, parentOrgId); // 把数据转成JSON格式返回给前端 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(); for (Organization org : subOrganizations) { JSONObject jsonObj = JSONFactoryUtil.createJSONObject(); jsonObj.put("id", org.getOrganizationId()); jsonObj.put("name", org.getName()); jsonArray.put(jsonObj); } // 设置响应类型为JSON response.setContentType("application/json"); response.getWriter().write(jsonArray.toString()); } } }
二、前端修改:实现AJAX联动
接下来修改前端代码,把原来的整页提交改成AJAX请求,动态渲染子机构下拉框:
<%@ taglib prefix="aui" uri="http://liferay.com/tld/aui" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0" %> <!-- 第一个组织机构下拉框:修改onChange事件,调用自定义JS函数 --> <aui:select name="Siege" onChange="loadSubOrganizations(this.value);" id="Siege"> <aui:option value="" selected="true">---Select---</aui:option> <c:forEach var="organisation" items="${listeOrganisations}"> <aui:option value="${organisation.organizationId}">${organisation.name}</aui:option> </c:forEach> </aui:select> <!-- 第二个子组织机构下拉框:初始仅显示默认选项 --> <aui:select name="subOrga" id="subOrga"> <aui:option value="" selected="true">---Select Sub Organization---</aui:option> </aui:select> <script type="text/javascript"> function loadSubOrganizations(parentOrgId) { // 获取子机构下拉框元素(注意加上Portlet命名空间,Liferay会自动生成) var subOrgaSelect = document.getElementById('<portlet:namespace />subOrga'); // 清空现有选项,保留默认提示 subOrgaSelect.innerHTML = '<option value="" selected="true">---Select Sub Organization---</option>'; // 如果没有选择父机构,直接返回 if (!parentOrgId) { return; } // 发送AJAX请求到Portlet的资源接口 var xhr = new XMLHttpRequest(); // 使用portlet标签生成资源请求URL xhr.open('POST', '<portlet:resourceURL />', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 请求成功后的处理逻辑 xhr.onload = function() { if (xhr.status === 200) { // 解析返回的JSON数据 var subOrgs = JSON.parse(xhr.responseText); // 遍历子机构数据,动态添加选项 subOrgs.forEach(function(org) { var option = document.createElement('option'); option.value = org.id; option.textContent = org.name; subOrgaSelect.appendChild(option); }); } }; // 发送请求参数:父机构ID xhr.send('parentOrgId=' + encodeURIComponent(parentOrgId)); } </script>
三、关键注意事项
- Portlet命名空间:Liferay会为每个Portlet的表单元素添加唯一命名空间,所以JS中获取元素ID时必须用
<portlet:namespace />前缀,否则会找不到元素。 - CompanyId的获取:我把你原来的
PortalUtil.getCompanyIds()[0]改成了PortalUtil.getCompanyId(request),这样能适配多公司场景,更健壮。 - 依赖导入:确保你的Portlet项目中已经导入了
JSONFactoryUtil、StringUtils等类的依赖,Liferay的内核包中已经包含这些类,不需要额外引入。
这样修改后,当你选择第一个下拉框的组织机构时,第二个下拉框就会自动加载对应的子组织机构,实现无刷新的联动效果啦!
内容的提问来源于stack exchange,提问作者Steve Diarrassouba
相关产品推荐
相关产品推荐

