ICEfaces
  1. ICEfaces
  2. ICE-2967

Incorrect positioning of dynamically positioned components in Liferay portal.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.7
    • Fix Version/s: None
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      liferay portal portlet
    • Workaround Exists:
      Yes
    • Workaround Description:
      Hide
      The following script can be used to work-around the Liferay "style='position: relative;'" issue.
      This script is safe to call many times so it can be added to each ICEfaces portlet as required:


      if (Liferay.Columns && !Liferay.Columns._ICE_positionSet) {
       Liferay.Util.actsAsAspect(Liferay.Columns);
       Liferay.Columns.after(
       'add',
       function(portlet) {
       jQuery(portlet).css('position', 'static');
       }
       );
      Liferay.Columns._ICE_positionSet = true;
      }
      Show
      The following script can be used to work-around the Liferay "style='position: relative;'" issue. This script is safe to call many times so it can be added to each ICEfaces portlet as required: if (Liferay.Columns && !Liferay.Columns._ICE_positionSet) {  Liferay.Util.actsAsAspect(Liferay.Columns);  Liferay.Columns.after(  'add',  function(portlet) {  jQuery(portlet).css('position', 'static');  }  ); Liferay.Columns._ICE_positionSet = true; }

      Description

      Certain component elements are positioned incorrectly when running as portlets in Liferay. The behavior is only manifested when signed in - not when using Liferay as a guest. The problem is that the dynamically positioned components - like submenus, draggable ghosts, tooltips, popupPanel etc. - are much farther down the page than the mouse. The offset calculation is off by a wide margin.

      The cause of this problem is a behavior in Liferay that injects relative positioning into a style attribute on the page container when you login, apparently to support LIferay's own drag and drop mechanism.

      Liferay is going to be changing this behavior in their upcoming 5.1 release, but you can use the workaround noted here in the meantime.

        Issue Links

          Activity

          Hide
          Deryk Sinotte added a comment -

          The problem is that, when signed in, a different set of styles is in effect (at least with the Jedi theme that comes with Liferay 4.4.2). When you are signed in with the test account, there is a style applied to a div containing the portlet content.

          An example of the problematic style is:

          <div class="portlet-boundary portlet-boundary_components_menubar_WAR_componentshowcase_" id="p_p_id_components_menubar_WAR_componentshowcase_INSTANCE_ZZpe_" style="top: 0pt; left: 0pt; position: relative;">

          It's the position:relative that causes the grief with our own component positioning. The solution that was recommended to us directly from the Liferay UI development team involves adding a touch of JavaScript. This is the quote from Liferay:

          "For more information about using this technique, check out my blog entry here:

          http://www.liferay.com/web/ncavanaugh/home/blogs/hooking_into_liferay_s_javascript_functions

          And here's the code:

          if (Liferay.Columns) {
          Liferay.Util.actsAsAspect(Liferay.Columns);
          Liferay.Columns.after(
          'add',
          function(portlet)

          { jQuery(portlet).css('position', 'static'); }

          );
          }

          (Also, make sure this code runs outside of any sort of onLoad function)."

          Show
          Deryk Sinotte added a comment - The problem is that, when signed in, a different set of styles is in effect (at least with the Jedi theme that comes with Liferay 4.4.2). When you are signed in with the test account, there is a style applied to a div containing the portlet content. An example of the problematic style is: <div class="portlet-boundary portlet-boundary_components_menubar_WAR_componentshowcase_" id="p_p_id_components_menubar_WAR_componentshowcase_INSTANCE_ZZpe_" style="top: 0pt; left: 0pt; position: relative;"> It's the position:relative that causes the grief with our own component positioning. The solution that was recommended to us directly from the Liferay UI development team involves adding a touch of JavaScript. This is the quote from Liferay: "For more information about using this technique, check out my blog entry here: http://www.liferay.com/web/ncavanaugh/home/blogs/hooking_into_liferay_s_javascript_functions And here's the code: if (Liferay.Columns) { Liferay.Util.actsAsAspect(Liferay.Columns); Liferay.Columns.after( 'add', function(portlet) { jQuery(portlet).css('position', 'static'); } ); } (Also, make sure this code runs outside of any sort of onLoad function)."
          Hide
          Deryk Sinotte added a comment -

          Gathering related cases under this parent case.

          Show
          Deryk Sinotte added a comment - Gathering related cases under this parent case.
          Hide
          Deryk Sinotte added a comment -

          Gathering related cases under this parent case.

          Show
          Deryk Sinotte added a comment - Gathering related cases under this parent case.
          Hide
          Deryk Sinotte added a comment -

          Slight change to the script so that it's a bit more efficient when it's potentially added multiple times:

          if (Liferay.Columns && !Liferay.Columns._ICE_positionSet) {
          Liferay.Util.actsAsAspect(Liferay.Columns);
          Liferay.Columns.after(
          'add',
          function(portlet)

          { jQuery(portlet).css('position', 'static'); }

          );
          Liferay.Columns._ICE_positionSet = true;
          }

          Show
          Deryk Sinotte added a comment - Slight change to the script so that it's a bit more efficient when it's potentially added multiple times: if (Liferay.Columns && !Liferay.Columns._ICE_positionSet) { Liferay.Util.actsAsAspect(Liferay.Columns); Liferay.Columns.after( 'add', function(portlet) { jQuery(portlet).css('position', 'static'); } ); Liferay.Columns._ICE_positionSet = true; }
          Hide
          Ken Fyten added a comment -

          Liferay issue, won't fix.

          See work-around.

          Show
          Ken Fyten added a comment - Liferay issue, won't fix. See work-around.
          Hide
          Deryk Sinotte added a comment -

          Added an extra check to the workaround so that errors are not logged when running in a portlet other than Liferay. Here's the new snippet:

          if ( (typeof(Liferay) != 'undefined') ) {
          if (Liferay.Columns && !Liferay.Columns._ICE_positionSet) {
          Liferay.Util.actsAsAspect(Liferay.Columns);
          Liferay.Columns.after(
          'add',
          function(portlet)

          { jQuery(portlet).css('position', 'static'); }

          );
          Liferay.Columns._ICE_positionSet = true;
          }
          }

          Show
          Deryk Sinotte added a comment - Added an extra check to the workaround so that errors are not logged when running in a portlet other than Liferay. Here's the new snippet: if ( (typeof(Liferay) != 'undefined') ) { if (Liferay.Columns && !Liferay.Columns._ICE_positionSet) { Liferay.Util.actsAsAspect(Liferay.Columns); Liferay.Columns.after( 'add', function(portlet) { jQuery(portlet).css('position', 'static'); } ); Liferay.Columns._ICE_positionSet = true; } }
          Hide
          Hüseyin Aptioglu added a comment -

          how can i add this script to my app , where i should to ad this

          Show
          Hüseyin Aptioglu added a comment - how can i add this script to my app , where i should to ad this
          Hide
          Deryk Sinotte added a comment -

          It's JavaScript that needs to be added to any portlet that has a component with a positioning issue (e.g. menus). The JavaScript can either be inlined directly with <script> tags or added via a .js file.

          Show
          Deryk Sinotte added a comment - It's JavaScript that needs to be added to any portlet that has a component with a positioning issue (e.g. menus). The JavaScript can either be inlined directly with <script> tags or added via a .js file.
          Hide
          Alexandru Pitis added a comment -

          In case I'm not wrong:

          • this fix works for Liferay 5.0.1
          • this fix does not work for Liferay 5.1

          Do you know whether there's a fix for Liferay 5.1?

          Many thanks

          Show
          Alexandru Pitis added a comment - In case I'm not wrong: this fix works for Liferay 5.0.1 this fix does not work for Liferay 5.1 Do you know whether there's a fix for Liferay 5.1? Many thanks
          Hide
          Deryk Sinotte added a comment -

          For Liferay 5.1, the Liferay.Publisher API is being removed (not deprecated) and replaced by Liferay.Events API. The Liferay developers provided this snippet of code that shows how to map the old API to the new one:

          if (Liferay.Events && !Liferay.Publisher) {
          Liferay.Publisher = {
          deliver: function(publisher)

          { var data = Array.prototype.slice.call(arguments, 1); Liferay.trigger(publisher, data); }

          ,

          register: function(publisher) {
          },

          subscribe: function(publisher, func, obj) {
          Liferay.bind(publisher, function(event, data)

          { func.call(this, data); }

          , obj || window);
          },

          unsubscribe: function(publisher, func)

          { Liferay.unbind(publisher, func); }

          };
          }

          If you are moving to 5.1, you may want to consult Liferay's documenation about the Liferay.Events API so that you are using the officially recommended mechanism.

          Show
          Deryk Sinotte added a comment - For Liferay 5.1, the Liferay.Publisher API is being removed (not deprecated) and replaced by Liferay.Events API. The Liferay developers provided this snippet of code that shows how to map the old API to the new one: if (Liferay.Events && !Liferay.Publisher) { Liferay.Publisher = { deliver: function(publisher) { var data = Array.prototype.slice.call(arguments, 1); Liferay.trigger(publisher, data); } , register: function(publisher) { }, subscribe: function(publisher, func, obj) { Liferay.bind(publisher, function(event, data) { func.call(this, data); } , obj || window); }, unsubscribe: function(publisher, func) { Liferay.unbind(publisher, func); } }; } If you are moving to 5.1, you may want to consult Liferay's documenation about the Liferay.Events API so that you are using the officially recommended mechanism.
          Hide
          Deryk Sinotte added a comment -

          Just capturing an additional comment from Liferay. Another suggestion was made to simply add the following style to the portlet content where the problem occurs:

          .portlet-boundary

          { position: static !important; }
          Show
          Deryk Sinotte added a comment - Just capturing an additional comment from Liferay. Another suggestion was made to simply add the following style to the portlet content where the problem occurs: .portlet-boundary { position: static !important; }

            People

            • Assignee:
              Unassigned
              Reporter:
              Deryk Sinotte
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: