Question

I have used the '@media only screen' in my CSS to determine how and what information should be shown depending on the users screen size. I have a class called panelContainer which is set to display when the screen is greater than 767px, and a class called mobileContainer which displays when the screen is less than that.

I have a couple of custom controls, one that contains the standard form layout and another that contains the mobile device form layout. Originally I placed a div around each with the appropriate styleClass. The problem with it this way was that although only one form is visible, they were both loaded so this caused save issues.

<xp:div id="panelContainer" styleClass="panelContainer">
    <xc:content_sCompany></xc:content_sCompany>
</xp:div>
<xp:div id="mobileContainer" styleClass="mobileContainer">
    <xc:content_iCompany></xc:content_iCompany>
</xp:div>

I have since added a div to my Xpage with the styleClass of panelContainer, I then added onLoad and onResize events which return the style.display of the div, these should then write the result to a viewScope. But I found it would only write onLoad and although the function was being called onResize it wouldn't change the viewScope variable.

<xp:scriptBlock id="scriptBlock1" type="text/javascript">
    <xp:this.value>
        <![CDATA[var init = function() {
            obj=document.getElementById('formType');
            if(getStyleDisplay(obj)=="none"){
                formType='#{javascript:viewScope.put("formFormat","mobile");}';
            }else{ 
                formType='#{javascript:viewScope.put("formFormat","standard")}';
           }
        }

        dojo.addOnLoad(init);
        dojo.connect(window,"onresize",init);

        function getStyleDisplay(obj) {
            if(obj.currentStyle) { // IE – Opera
                return obj.currentStyle.display;
            } else { // firefox
                return getComputedStyle(obj,'').getPropertyValue('display');
            }
        }]]>
    </xp:this.value>
</xp:scriptBlock>
<div id="formType" class="panelContainer"></div>

.....this viewScope variable is then used in the following way:

<xc:content_Company xp:key="ContentControl">
    <xp:this.facets>
        <xc:content_sCompany id="content_sCompany"
            xp:key="standard">
        </xc:content_sCompany>
        <xc:content_iCompany id="content_iCompany"
             xp:key="mobile">
        </xc:content_iCompany>
    </xp:this.facets>
</xc:content_Company>

.....extract from content_Company......

<xp:callback facetName="#{viewScope.formFormat}" id="cbkCompanyFormContent">
</xp:callback>

I feel this is the better way to achieve the result I need, as when I have tried it manually it does only load one of the forms and they work as expected.

I cannot see why the viewScope is not being set properly, it is always being set to 'standard', even if I shrink my page before loading the page. I did try writing the value to a Hidden Input, which worked but whenever I tried to access the value using getComponent("hiddenInput1").getValue() it would return null, even though I could see that value had been set when viewing in firebug.

Was it helpful?

Solution

Ok can you check (or tell me if you already have) through some console.log("") 's that the onResize is being called and the correct display is being pulled down etc.

next it may be firing the onResize but are you then partail refreshing the area which is using the viewScope?

Code example of this: (replace controlID with yours)

XSP.partialRefreshGet("controlID", {
    onError: function() { console.log('Error'); }
});

I'm a little confused about what the purpose of using onResize is for ? if is to decide what to show whether on mobile or normal screen there are much more efficient ways of doing this.

  1. Using the new redirect control in the latest release of the ExtLib on openNTF. It does exactly what the name suggests and redirects based on certain expressions. leaving you to drop it on a page and say if mobile (or whatever) redirect to this page.

  2. Having a dummy default load page that checks the useragent string to see which page to load (having a separate mobile / fullscreen pages). This is what the teamroom template application that comes with the ExtLib does with its main.xsp and then this is set as the default launch option.

Or if you are trying to do something with whether the phone / tablet is on landscape or portrait you should be using the onOrientationChange event not onResize. check out this example (not the code in the question is what I'm pointing you too, he has a problem getting that to work in a webview):

how to handle javascript onorientationchange event inside uiwebview

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top