Posts Tagged: ‘XSnippet’

XSnippets: viewPanelHelper

28. November 2012 Posted by Sven Hasselbach

I have added a new XSnippet, the viewPanelHelper. The code helps to keep the selection of the selected documents in a view panel even if pager is used or categories are expand or collapsed.

It is not required to modify the view: Only the script and the hidden field must be added to the facets section of the panel and the CSJS class “viewPanelHelper” must be added to the XPage (the class is loaded only once and can be stored in a separate CSJS resource file).

The selected documents are stored in the hidden field “viewPanelSelectedIds”.
Tested in IE 9 and FF 15 – 17.

Quick-n-Dirty: Disable Validation for FileDownload control

24. Oktober 2012 Posted by Sven Hasselbach

If you are using the file download control,  you sooner or later want to allow your users to delete an existing file. But if you have some required fields on your XPage, a deletion is not possible because the validation is always fired before the attachment is removed.

To disable to validation you can use this little SSJS snippet which sets the “disableValidators” property for all events of the UIFileDownload control. Just add the following code to the beforeRenderResponse event of your XPage and change the id of the component to fit your requirements.

<xp:this.beforeRenderResponse>
   <![CDATA[#{javascript:
      /***
       * disable validation for UIFileDownload control
       * 
       * @param UIFileDownload component
       * @author Sven Hasselbach
       * @category SSJS
       * @category UI
       * @version 0.2
       */
      function disableFileDownloadValidation( fDownload:com.ibm.xsp.component.UIFileDownload ){
         if( fDownload === null )
            return;

         rekDisableFileDownloadValidation( fDownload );
      }

      function rekDisableFileDownloadValidation( component:javax.faces.component.UIOutput ){
         try{
            var children:java.util.List = component.getChildren();
            var it:java.util.Iterator = children.iterator();
            var curChild:javax.faces.component.UIOutput;

            while( it.hasNext() ){
               curChild = it.next();
               if( typeof( curChild ) === 'com.ibm.xsp.component.xp.XspEventHandler' )
                  curChild.setDisableValidators( true );

               rekDisableFileDownloadValidation( curChild );
            }
         }catch(e){}    
      }

      disableFileDownloadValidation( getComponent( 'fileDownload1' ) );
   }]]>
</xp:this.beforeRenderResponse>

P.S. Keep in mind that this article has been posted in the “Quick-n-Dirty” category.

XSnippets: Cancel a partial refresh via SSJS

3. Mai 2012 Posted by Sven Hasselbach

With the assistance of Philippe Riand I was able to shorten the original idea of canceling a partial refresh to a single SSJS function.  By setting the HTTP header “X-XspRefreshId” to “@none” it is possible to get the same result as in the posting before, but there is no “Dojo hack” required.

function cancelPartialRefresh(){
   var response = facesContext.getExternalContext()
      .getResponse();
   response.setHeader("X-XspRefreshId", "@none");
   response.reset();
   response.commitResponse();
   facesContext.responseComplete();
}

To use this function you just have to call it.  Here is the same example like in the previous posting:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
   <xp:button value="Label" id="button1">
      <xp:eventHandler event="onclick" submit="true"
         refreshMode="partial" refreshId="label1">
      </xp:eventHandler>
   </xp:button>
   <xp:br/><xp:br/>
   <xp:label id="label1">
      <xp:this.value>
      <![CDATA[#{javascript:
      function cancelPartialRefresh(){
         var response = facesContext.getExternalContext()
            .getResponse();
         response.setHeader("X-XspRefreshId", "@none");
         response.reset();
         response.commitResponse();
         facesContext.responseComplete();
      }

      var ajax = new com.ibm.xsp.ajax.AjaxUtil();
      if( ajax.isAjaxPartialRefresh(facesContext) == true){
         cancelPartialRefresh();
         return; // stop execution of SSJS code
      }
      java.lang.System.currentTimeMillis();}]]>
      </xp:this.value>
   </xp:label>
</xp:view>

I have added the code to the XSnippet Contest. Here is the link to the XSnippet: http://openntf.org/XSnippets.nsf/snippet.xsp?id=cancel-partial-refresh

If you want to read more information about the HTTP header  you can read an earlier posting (Sorry, on german only).

XSnippets: Fire querySave / postSave – Events

22. April 2012 Posted by Sven Hasselbach

The second XSnippet I have added to the XSnippet Contest is a help to fire the querySave- and postSave-events from SSJS: Save Datasource & Fire querySave/postSave events

If you only do a simple document1.save() , the events of a datasource won’t be executed. To fix this, you have to use the save() method of com.ibm.xsp.model.domino.DominoDocumentData instead:

var dsName = "document1.DATASOURCE"; // change this to the name of
                                     // the datasource you want
                                     // to save
var app = facesContext.getApplication();
var ds = app.getVariableResolver()
           .resolveVariable(facesContext, dsName);
ds.save( facesContext, true);

The variable dsName contains the name of the datasource to save, followed by “.DATASOURCE“. To use it f.e. with the current document, you have to change the variable to “currentDocument.DATASOURCE“.

The difference here is the type of object that is used: If you save a document datasource, the save method of an object of type NotesXspDocument is called. The com.ibm.xsp.model.domino.DominoDocumentData object has another method for saving. The first object type is like a backend NotesDocument, the second object is like the NotesUIDocument class.

XSnippets: XPages Localization Setter

22. April 2012 Posted by Sven Hasselbach

I have submitted some XSnippets for the XSnippets-Contest. This is the first one, the XPages Localization Setter: The Snippet allows to change the language settings of a XPage “On-The-Fly”, including the browser language used, the dojo settings, the ressource files etc.

package ch.hasselba.xpages.jsf.core;

import javax.faces.context.FacesContext;
import javax.faces.application.Application;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.component.UIViewRoot;
import java.util.Locale;
import java.util.Map;

public class LocalizationSetter implements PhaseListener {

    private static final long serialVersionUID = -1L;
    private static final String scopeVarName = "Language";
    private static final String scopeName = "sessionScope";

    public void afterPhase(PhaseEvent event) {}

    public void beforePhase(PhaseEvent event) {
        FacesContext facesContext = event.getFacesContext();
        UIViewRoot view = facesContext.getViewRoot();
        view.setLocale( getLanguage(facesContext) ) ;
    }

    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

    private Locale getLanguage( FacesContext facesContext ){       
        try{
            Application app = facesContext.getApplication();
            Object obj = app.getVariableResolver()
                  .resolveVariable(facesContext, scopeName );
            Object lang = ((Map) obj).get( scopeVarName );
            if( lang != null ){
                return new Locale((String) lang);
            }
        }catch(Exception e){}

        return Locale.getDefault();
    }
}

This phase listener updates the language settings of the UIViewRoot-Element during the rendering of the response. The language the XPage will be set to is stored in a session scope variable named “Language”. If you want to change this you just have to change the variable scopeVarName to fit your requirements.

To activate the phase listener in your XPages-Application you have to alter the faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
    <lifecycle>
        <phase-listener>
           ch.hasselba.xpages.jsf.core.LocalizationSetter
        </phase-listener>
    </lifecycle>
</faces-config>

Here is a simple example to demonstrate the XSnippet:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:comboBox id="comboBox1" value="#{sessionScope.Language}">
   <xp:selectItem itemLabel="Chinese" itemValue="zh" />
   <xp:selectItem itemLabel="German" itemValue="de" />
   <xp:selectItem itemLabel="Turkish" itemValue="tr" />
   <xp:eventHandler event="onchange" submit="true"
      refreshMode="complete" />
</xp:comboBox>
</xp:view>

If you are choosing “turkish” from the combobox, the html source looks like this after the refresh:

If you are add a simple date picker to your XPage and change the language to chinese, the dojo dialog will be in chinese from now on:

To add more languages you have to use the two letter ISO 639 code. To get a list of all available locales you can use this small repeat control:

<xp:repeat id="repeat1" rows="999" var="locale">
   <xp:this.value>
      <![CDATA[#{javascript:
         java.text.SimpleDateFormat.getAvailableLocales();
      }]]>
   </xp:this.value>
   <xp:label id="label1">
      <xp:this.value>
         <![CDATA[#{javascript:
            locale.getDisplayName() + " -> " + locale.toString()
         }]]>
      </xp:this.value>
   </xp:label>
   <xp:br/>
</xp:repeat>

Note:

After changing the language a full refresh is required!