1
votes

In my application, I need to access the remote applications (The application which is running on other tomcat instance) dynamically in my portlet. So I have created the portlet in view and edit mode so that I am able see the "preferences" option in portlet setting options. my preference page has three input fields with submit button. Now based on the input fields I need to render my portlet content. On click of submit button I am able to get the URL in configuraionActionImpl class. Now I can I set the portlet view as that URL web page content? Let's say in preferences If user enters "http://localhost:8080/Myapp/events" and on click of submit button in preference configation page then the portlet view should be changed to events page of Myapp application, If user wants to modify the URL from "http://localhost:8080/Myapp/events" to "http://localhost:8080/Myapp/tasks" and on click of submit button in preference page of the config page, Then the portlet view should render the Tasks page.

portlet.xml

 <portlet-name>FRunner</portlet-name>
            <display-name>FRunner</display-name>
            <portlet-class>com.liferay.util.bridges.mvc.MVCPortlet</portlet-class>
            <init-param>
                    <name>view-template</name>
                    <value>/view.jsp</value>
            </init-param>
            <init-param>
                    <name>config-template</name>
                    <value>/preferences.jsp</value>
            </init-param>
            <expiration-cache>0</expiration-cache>
            <supports>
                    <mime-type>text/html</mime-type>
                    <portlet-mode>view</portlet-mode>
                <portlet-mode>edit</portlet-mode>
            </supports>

liferay-portlet.xml

<liferay-portlet-app>
        <portlet>
                <portlet-name>FRunner</portlet-name>
                <icon>/icon.png</icon>
                <configuration-action-class>com.demo.formrunner.ConfigurationActionImpl</configuration-action-class>
                <header-portlet-css>/css/main.css</header-portlet-css>
                <footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
                <css-class-wrapper>FRunner-portlet</css-class-wrapper>
        </portlet>
</liferay-portlet-app>

preferences.jsp

<portletefineObjects />
<liferay-portlet:actionURL portletConfiguration="true" var="configurationURL" />
<aui:form action="<%= configurationURL %>" method="post">
  <aui:fieldset label="Form Runner Portlet Settings">
    <aui:layout>
       <aui:column>
          <aui:input type="text" name="url" label="URL:" inlineLabel="true"/>
       </aui:column>
       <aui:button-row>
          <aui:button type="submit" value="Submit"/>
         <aui:button type="button" value="Cancel" last="true"/>
      </aui:button-row>
   </aui:layout>
 </aui:fieldset>
</aui:form>

ConfigurationActionImpl.java

package com.demo.formrunner;
public class ConfigurationActionImpl extends DefaultConfigurationAction {

    @Override
    public void processAction(PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {

        super.processAction(portletConfig, actionRequest, actionResponse);
        PortletPreferences prefs = actionRequest.getPreferences();
        String urlVal= prefs.getValue("url", "");
        System.out.println("URL Value is" + urlVal); // able to get the url value here. Now How to update the portlet view with this URL
    }
} 

1) How do I need to render my portlet view based on the input URL? the URL should be like http request (http://localhost:8080/Demo/myPage)

Please suggest me the guidelines to archive the same.

4
In addition to the answers given below (I've had this in draft, unsent, for a few days, just rediscovered it) : * You're mixing preferences (JSR-286 portlet edit mode) and Liferay's custom configuration mode - I suggest that you decide for one of them. * Your action handler just prints the current preferencesOlaf Kock

4 Answers

2
votes

You can modify your code with the below code,

In your configuration.jsp

<aui:form action="<%= configurationURL %>" method="post" name="fm">
  <aui:fieldset label="Form Runner Portlet Settings">
    <aui:layout>
       <aui:column>
          <aui:input autoFocus="<%= (windowState.equals(WindowState.MAXIMIZED) || windowState.equals(LiferayWindowState.POP_UP)) %>" cssClass="lfr-input-text-container" label="source-url" name="preferences--src--" prefix="<%= relative ? StringPool.TRIPLE_PERIOD : StringPool.BLANK %>" type="text" value="<%= src %>" />

       </aui:column>
       <aui:button-row>
         <aui:button type="submit" />
      </aui:button-row>
   </aui:layout>
 </aui:fieldset>
</aui:form> 

In view.jsp

String src = portletPreferences.getValue("src", StringPool.BLANK);

<%
//String iframeSrc = StringPool.BLANK;
String iframeSrc = src;
if (relative) {
        iframeSrc = themeDisplay.getPathContext();
}

//iframeSrc += (String)request.getAttribute(WebKeys.IFRAME_SRC);

if (Validator.isNotNull(iframeVariables)) {
        if (iframeSrc.contains(StringPool.QUESTION)) {
                iframeSrc = iframeSrc.concat(StringPool.AMPERSAND).concat(StringUtil.merge(iframeVariables, StringPool.AMPERSAND));
        }
        else {
                iframeSrc = iframeSrc.concat(StringPool.QUESTION).concat(StringUtil.merge(iframeVariables, StringPool.AMPERSAND));
        }
}

String baseSrc = iframeSrc;

int lastSlashPos = iframeSrc.substring(7).lastIndexOf(StringPool.SLASH);

if (lastSlashPos != -1) {
        baseSrc = iframeSrc.substring(0, lastSlashPos + 8);
}

String iframeHeight = heightNormal;

if (windowState.equals(WindowState.MAXIMIZED)) {
        iframeHeight = heightMaximized;
}
%>

<c:choose>
        <c:when test="<%= auth && Validator.isNull(userName) && !themeDisplay.isSignedIn() %>">
                <%-- <div class="alert alert-info">
                        <a href="<%= themeDisplay.getURLSignIn() %>" target="_top"><liferay-ui:message key="please-sign-in-to-access-this-application" /></a>
                </div> --%>
        </c:when>
        <c:otherwise>
                <div>
                        <iframe alt="<%= HtmlUtil.escapeAttribute(alt) %>" border="<%= HtmlUtil.escapeAttribute(border) %>" bordercolor="<%= HtmlUtil.escapeAttribute(bordercolor) %>" frameborder="<%= HtmlUtil.escapeAttribute(frameborder) %>" height="<%= HtmlUtil.escapeAttribute(iframeHeight) %>" hspace="<%= HtmlUtil.escapeAttribute(hspace) %>" id="<portlet:namespace />iframe" longdesc="<%= HtmlUtil.escapeAttribute(longdesc) %>" name="<portlet:namespace />iframe" onload="<portlet:namespace />monitorIframe();" scrolling="<%= HtmlUtil.escapeAttribute(scrolling) %>" src="<%= HtmlUtil.escapeHREF(iframeSrc) %>" title="<%= HtmlUtil.escapeAttribute(title) %>" vspace="<%= HtmlUtil.escapeAttribute(vspace) %>" width="<%= HtmlUtil.escapeAttribute(width) %>">
                                <%= LanguageUtil.format(pageContext, "your-browser-does-not-support-inline-frames-or-is-currently-configured-not-to-display-inline-frames.-content-can-be-viewed-at-actual-source-page-x", HtmlUtil.escape(iframeSrc)) %>
                        </iframe>
                </div>
        </c:otherwise>
</c:choose>

<aui:script>
        function <portlet:namespace />monitorIframe() {
                var url = null;

                try {
                        var iframe = document.getElementById('<portlet:namespace />iframe');

                        url = iframe.contentWindow.document.location.href;
                }
                catch (e) {
                        return true;
                }

                var baseSrc = '<%= HtmlUtil.escapeJS(baseSrc) %>';
                var iframeSrc = '<%= HtmlUtil.escapeJS(iframeSrc) %>';        

                if ((url == iframeSrc) || (url == (iframeSrc + '/'))) {
                }
                else if (Liferay.Util.startsWith(url, baseSrc)) {
                        url = url.substring(baseSrc.length);

                        <portlet:namespace />updateHash(url);
                }
                else {
                        <portlet:namespace />updateHash(url);
                }

                return true;
        }

        Liferay.provide(
                        window,
                        '<portlet:namespace />init',
                        function() {
                                var A = AUI();

                                var hash = document.location.hash.replace('#', '');

                                // LPS-33951

                                if (!A.UA.gecko) {
                                        hash = A.QueryString.unescape(hash);
                                }

                                var hashObj = A.QueryString.parse(hash);

                                hash = hashObj['<portlet:namespace />'];

                                if (hash) {
                                        var src = '';

                                        if (!(/^https?\:\/\//.test(hash))) {
                                                src = '<%= HtmlUtil.escapeJS(baseSrc) %>';
                                        }

                                        src += hash;

                                        var iframe = A.one('#<portlet:namespace />iframe');

                                        if (iframe) {
                                                iframe.attr('src', src);
                                        }
                                }
                        },
                        ['aui-base', 'querystring']
                );

        Liferay.provide(
                        window,
                        '<portlet:namespace />updateHash',
                        function(url) {
                                var A = AUI();

                                var hash = document.location.hash.replace('#', '');

                                var hashObj = A.QueryString.parse(hash);

                                hashObj['<portlet:namespace />'] = url;

                                var maximize = A.one('#p_p_id<portlet:namespace /> .portlet-maximize-icon a');

                                hash = A.QueryString.stringify(hashObj);

                                if (maximize) {
                                        var href = maximize.attr('href');

                                        href = href.split('#')[0];

                                        maximize.attr('href', href + '#' + hash);
                                }

                                var restore = A.one('#p_p_id<portlet:namespace /> a.portlet-icon-back');

                                if (restore) {
                                        var href = restore.attr('href');

                                        href = href.split('#')[0];

                                        restore.attr('href', href + '#' + hash);
                                }

                                // LPS-33951

                                location.hash = A.QueryString.escape(hash);
                        },
                        ['aui-base', 'querystring']
                );

        <portlet:namespace />init();

</aui:script>

<aui:script use="aui-autosize-iframe">
var iframe = A.one('#<portlet:namespace />iframe');

if (iframe) {
        iframe.plug(
                A.Plugin.AutosizeIframe,
                {
                        monitorHeight: <%= resizeAutomatically %>
                }
        );

        iframe.on(
                'load',
                function() {
                        var height = A.Plugin.AutosizeIframe.getContentHeight(iframe);

                        if (height == null) {
                                height = '<%= HtmlUtil.escapeJS(heightNormal) %>';

                                if (themeDisplay.isStateMaximized()) {
                                        height = '<%= HtmlUtil.escapeJS(heightMaximized) %>';
                                }

                                iframe.setStyle('height', height);

                                iframe.autosizeiframe.set('monitorHeight', false);
                        }
                }
        );
}
</aui:script>

It will save the value in the portlet preferences and you can able to render dynamic pages as you need.

Note: Don't forget to import required classes.

2
votes

In your Action:

package com.demo.formrunner;
public class ConfigurationActionImpl extends DefaultConfigurationAction {

@Override
public void processAction(PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {

    super.processAction(portletConfig, actionRequest, actionResponse);
    PortletPreferences prefs = actionRequest.getPreferences();
    String urlVal= prefs.getValue("url", "");
    System.out.println("URL Value is" + urlVal); // able to get the url value here. Now How to update the portlet view with this URL

    actionResponse.setRenderParameter("url", urlVal);
    actionResponse.setRenderParameter("jspPage","/html/yourNewJsp.jsp"); 
}

}

yourNewJsp.jsp

...
<iframe src="<%=request.getParameter("url") %>"></iframe>
...

However, if you use the preferences you can retrieve the url directly from preferences in the yourNewJsp.jsp without passing that parameter actionResponse.setRenderParameter("url", urlVal); from the action. You can also use just one jsp in which if the "urlVal" in preferences is not null or empty show the <iframe>.

2
votes

in your ConfigurationAction:

package com.demo.formrunner;
public class ConfigurationActionImpl extends DefaultConfigurationAction {

@Override
public void processAction(PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {


    PortletPreferences prefs = actionRequest.getPreferences();
    String urlVal= prefs.getValue("url", "");
    System.out.println("URL Value is" + urlVal); // able to get the url value here. Now How to update the portlet view with this URL


        try {
            prefs.store();
        }
        catch (ValidatorException ve) {
            SessionErrors.add(
                    actionRequest, ValidatorException.class.getName(), ve);
            return;
        }

        SessionMessages.add(
                actionRequest,
                PortalUtil.getPortletId(actionRequest) +
                SessionMessages.KEY_SUFFIX_REFRESH_PORTLET,
                portletResource);

        SessionMessages.add(
                actionRequest,
                PortalUtil.getPortletId(actionRequest) +
                SessionMessages.KEY_SUFFIX_UPDATED_CONFIGURATION);

}

in your view.jsp

<%
    PortletPreferences prefs = liferayPortletRequest.getPreferences();
    String url = prefs.getValue("url", "");
%>

...
<iframe src="<%=url %>"></iframe>
...
1
votes

I think the problem is the use of button item. The few times I used a button item it took me some headaches, and it was required to follow it with a onclick property.

Try to use a aui:input type="submit" item instead aui:button.