Saturday, April 30, 2011

Get running Broadcom WLAN under OpenSuse 11.4

I described how I did it in OpenSuse 11.3. OpenSuse 11.4 is shipped with an open source driver brcm80211 on board and you don't need proprietary broadcom-wl-... drivers anymore (downloaded by PackMan) for many new Broadcom cards. Please check this page for compatibility issues before you start with an installation. To see details to the available Broadcom card, use the commando lspci. My output is e.g.:

/sbin/lspci -nnk | grep -i -A2 broad
12:00.0 Network controller [0280]: Broadcom Corporation BCM4313 802.11b/g/n Wireless LAN Controller [14e4:4727] (rev 01)
Subsystem: Dell Device [1028:0010]
13:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] (rev 03)

The driver brcm80211 supports BCM4313 and BCM43224, BCM43225, BCM4329 chips. The installation is straightforward.

1) Remove all WLAN configurations in NetworkManager.
2) Install kernel-firmware from a DVD with OpenSuse 11.4. That's is the file kernel-firmware-2.6.38-1.2.1.noarch.rpm. You should see after that all brcm80211 stuff under /lib/firmware/brcm
3) You will see Broadcom WLAN Controller with the device name wlan0 in Yast's Network Settings. All stuff is recognized well. Broadcom WLAN Controller needs a small configuration if you have a WLAN router (my one is FRITZ!Box Fon WLAN 7270). You should set default gateway and input WAP or WEP key for the authentication.
4) Reboot and enjoy the wireless LAN.

Edit: I  was asked whether b43 drivers (for old BCM chips) should be removed. Yes, you can remove b43 and broadcom-wl-... drivers or do them blacklisted (see blacklist config files under /etc/modprobe.d/), so that they are not loaded at all.

Wednesday, April 13, 2011

Hooking of PrimeFaces Ajax calls as a kind of callbacks. Part II.

This is the continuation of the part I where I intended to add client-side callbacks for any PrimeFaces Ajax calls. PrimeFaces components normally have callbacks like onstart and oncomplete, but not for all events. PrimeFaces tree has e.g. onselectStart and onselectComplete, but what is about onexpandStart and onexpandComplete in dynamic trees? I guess, all such callbacks would blow up the component interface. I believe all existing component libraries mimic each other and have countless callbacks and listeners as component attributes. Why do they need them at all for Ajax calls? There is f:ajax and derivations like p:ajax which already have "listener", "execute", "render" attributes and provide all Ajax callbacks with "onevent" attribute automatically. Do they really need to blow up component attributes or would be a simple attaching of Ajax behaviors enough? Well. It's not the topic of this post.

The component blockUI is used here as reference implementation. It prevents user activity with any part of the page as long as an Ajax request / response cycle is running. We need a component class BlockUI.java, a renderer class BlockUIRenderer.java and an JavaScript blockUI.js. The component class is trivial. It has attributes "widgetVar", "for", "forElement", "source" und getter / setter. More interesting are the renderer and the script.

BlockUIRenderer.java

public class BlockUIRenderer extends CoreRenderer
{
 private static final Log LOG = LogFactory.getLog(BlockUIRenderer.class);

 @Override
 public void encodeEnd(FacesContext fc, UIComponent component) throws IOException {
  encodeMarkup(fc, component);
  encodeScript(fc, component);
 }

 public void encodeMarkup(FacesContext fc, UIComponent component) throws IOException {
  ResponseWriter writer = fc.getResponseWriter();

  writer.startElement("div", null);
  writer.writeAttribute("id", component.getClientId(fc) + "_content", null);
  writer.writeAttribute("style", "display: none;", null);
  renderChildren(fc, component);
  writer.endElement("div");
 }

 protected void encodeScript(FacesContext fc, UIComponent component) throws IOException {
  ResponseWriter writer = fc.getResponseWriter();
  BlockUI blockUI = (BlockUI) component;
  String clientId = blockUI.getClientId(fc);
  String widgetVar = blockUI.resolveWidgetVar();

  String source;
  UIComponent sourceComponent = blockUI.findComponent(blockUI.getSource());
  if (sourceComponent == null) {
   source = "";
   LOG.warn("Source component could not be found for 'source' = " + blockUI.getSource());
  } else {
   source = sourceComponent.getClientId(fc);
  }

  String target;
  if (blockUI.getFor() != null) {
   UIComponent targetComponent = blockUI.findComponent(blockUI.getFor());
   if (targetComponent == null) {
    target = "";
    LOG.warn("Target component could not be found for 'for' = " + blockUI.getFor());
   } else {
    target = targetComponent.getClientId(fc);
   }
  } else if (blockUI.getForElement() != null) {
   target = blockUI.getForElement();
  } else {
   target = "";
   LOG.warn("Target is missing, either 'for' or 'forElement' attribute is required");
  }

  UIComponent facet = blockUI.getFacet("events");

  // collect all f:param
  List<UIParameter> uiParams = new ArrayList<UIParameter>();
  if (facet instanceof UIParameter) {
   // f:facet has one child and that's f:param
   uiParams.add((UIParameter) facet);
  } else if (facet != null && facet.getChildren() != null) {
   // f:facet has no or more than one child (all children included into an UIPanel)
   for (UIComponent kid : facet.getChildren()) {
    if (kid instanceof UIParameter) {
     uiParams.add((UIParameter) kid);
    }
   }
  }

  // build a regular expression for event key, value pair.
  String eventRegExp;
  if (uiParams.isEmpty()) {
   // no or empty "events" facet means all events of the given source are accepted
   eventRegExp = "/" + Constants.PARTIAL_SOURCE_PARAM + "=" + source + "(.)*$/";
  } else {
   StringBuffer sb = new StringBuffer("/");
   sb.append(source);
   sb.append("_");

   Iterator<UIParameter> iter = uiParams.iterator();
   while (iter.hasNext()) {
    UIParameter param = iter.next();

    // not set event name / value means any name / value is accepted
    sb.append("(");
    sb.append(param.getName() != null ? param.getName() : "(.)*");
    sb.append("=");
    sb.append(param.getValue() != null ? param.getValue() : "(.)*");
    sb.append("$)");

    if (iter.hasNext()) {
     sb.append("|");
    }
   }

   sb.append("/");
   eventRegExp = sb.toString();
  }

  writer.startElement("script", blockUI);
  writer.writeAttribute("type", "text/javascript", null);
  writer.write(widgetVar + " = new JsfToolkit.widget.BlockUI('"
               + ComponentUtils.escapeJQueryId(clientId) + "','"
               + ComponentUtils.escapeJQueryId(source) + "','"
               + ComponentUtils.escapeJQueryId(target) + "'," + eventRegExp + ");");
  writer.write(widgetVar + ".setupAjaxSend();");
  writer.write(widgetVar + ".setupAjaxComplete();");

  writer.endElement("script");
 }

 @Override
 public boolean getRendersChildren() {
  return true;
 }

 @Override
 public void encodeChildren(FacesContext fc, UIComponent component) throws IOException {
  // nothing to do
 }
}
The most important thing is the building of regular expressions. If we are not interesting in any special events, we will only check whether the source component in available in passed Ajax parameters (see the JS script below). The regular expression using for this check is
 
/javax.faces.source=<source>(.)*$/
 
where <source> is the clientId of the source component. Radio buttons and checkboxes I mentioned in the part I send e.g.
 
javax.faces.source=accessLevels_1
javax.faces.source=accessLevels_2
javax.faces.source=accessRights_1
javax.faces.source=accessRights_2
 
The regular expressions should be therefore
 
/javax.faces.source=accessLevels(.)*$/
/javax.faces.source=accessRights(.)*$/
 
If we interesting in specified events, we build a regular expression for each event and concatenate them with the logical OR-operator. A regular expression for each event looks as follows
 
/<source>_(<event name>=<event value>)$/
 
If the event name or value is not important, we use (.)* for any strings (empty is also allowed). Some examples:
 
/dtPropTemplates_(filtering=true)$|dtPropTemplates_(sorting=true)$/
/treeSocs_(action=SELECT)$/
/selectedGroupsUsers_(instantSelectedRowIndex=(.)*)$/
 
Corresponding Ajax requests have parameters (Ajax options):
 
dtPropTemplates_filtering=true
dtPropTemplates_sorting=true
treeSocs_action=SELECT
selectedGroupsUsers_instantSelectedRowIndex=<rowId>
// <rowId> is the internal Id of the currently selected row
 

blockUI.js

The script provides two functions to register ajaxSend and ajaxComplete events where I check Ajax options in order to find the appropriate event. The check uses mentioned above regular expressions.
JsfToolkit.widget.BlockUI = function(id, source, target, regExp) {
 var clientId = id;
 var sourceId = source;
 var targetId = target;
 var eventRegExp = regExp;
 
 // global settings
 jQuery.blockUI.defaults.theme = true;
 jQuery.blockUI.defaults.fadeIn = 0;
 jQuery.blockUI.defaults.fadeOut = 0;
 jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
 
 /* public access */
 
 this.setupAjaxSend = function () {
  jQuery(sourceId).ajaxSend(function(event, xhr, ajaxOptions) {
   // first, check if event should be handled 
   if (isAppropriateEvent(ajaxOptions)) {
    var targetEl = jQuery(targetId);

    // second, check if the target element has been found
    if (targetEl.length > 0) {
     // block the target element
     targetEl.block({message: jQuery(clientId + "_content").html()});

     // get the current counter
     var blocksCount = targetEl.data("blockUI.blocksCount");
     if (typeof blocksCount === 'undefined') {
      blocksCount = 0;
     }

     // increase the counter
     targetEl.data("blockUI.blocksCount", blocksCount+1);
    }
   }
  });
 }
 
 this.setupAjaxComplete = function () {
  jQuery(sourceId).ajaxComplete(function(event, xhr, ajaxOptions) {
   // first, check if event should be handled
   if (isAppropriateEvent(ajaxOptions)) {
    var targetEl = jQuery(targetId);

    // second, check if the target element has been found
    if (targetEl.length > 0) {
     // get the current counter
           var blocksCount = targetEl.data("blockUI.blocksCount");

           // check the counter
     if (typeof blocksCount !== 'undefined') {
      if (blocksCount == 1) {
       // unblock the target element and reset the counter
       jQuery(targetId).unblock();
       targetEl.data("blockUI.blocksCount", 0);
      } else if (blocksCount > 1) {
       // only decrease the counter
       targetEl.data("blockUI.blocksCount", blocksCount-1);
      }
     }
    }
   }
  });
 }
 
 /* private access */
 
 var isAppropriateEvent = function (ajaxOptions) {
  if (typeof ajaxOptions === 'undefined' || ajaxOptions == null ||
   typeof ajaxOptions.data === 'undefined' || ajaxOptions.data == null) {
   return false;
  }

  // split options around ampersands
  var params = ajaxOptions.data.split(/&/g);
  
  // loop over the ajax options and try to match events
  for (var i = 0; i < params.length; i++) {
   if (eventRegExp.test(params[i])) {
    return true;
   }
  }

  return false;
 }
}
ajaxSend increase a counter bound to target element and ajaxComplete decrease the counter. This is necessary if many sources blocks the same target. The target is unblocked if the counter is 1. The parsing of Ajax options is the main part and the clou of the question how to find any Ajax events to be able to fire client-side callbacks.

Saturday, April 9, 2011

Hooking of PrimeFaces Ajax calls as a kind of callbacks. Part I.

Using PrimeFaces I have needed client-side callbacks for events causing Ajax calls like sorting, pagination, filtering of datatable or tree node expansion. I can understand that it's impossible to define all kinds of callbacks. Therefore I was looking for a generic way and believe I have found it. I'm able now to "add" any callbacks to any components. Firstly some words about PrimeFaces Ajax driven events. A PrimeFaces Ajax request triggered by any component has a parameter describing the event. It consist of component's clientId, underline, name and value, e.g. myTabview_tabChange=true. We are especially interesting in names and values. They are e.g.
 
Datatable:
name="filtering" value="true"
name="sorting" value="true"
name="paging" value="true"

Tree:
name="action" value="SELECT"
name="action" value="EXPAND"

TabView:
name="tabChange" value="true"
 
This anatomy is not disclosed. Name / value pairs are undocumented, so that you need to look into JS files (for something like params[this.id + '_tabChange'] = true;) or corresponding component renderers to figure out what are the parameters of any event. The other problem is that a name / value pair can be changed in next releases. The new tree (since PrimeFaces 3.x) will have e.g.
 
name="instantSelection" value="<Node Id>"
name="expandNode" value="<Node Id>"
 
It would be very nice and appreciated by community if the PrimeFaces team could standardize and document all Ajax driven events. Please :-)

jQuery has a capability to register callbacks for Ajax events. There are ajaxStart .... ajaxComplete events in jQuery. With ajaxStart you can register a handler to be called when the first Ajax request begins, with ajaxComplete a handler to be called when Ajax requests complete, etc. We can use them to catch PrimeFaces Ajax calls and check passed parameters in order to figure out whether the event occurs we are interesting in.

I'm going to demonstrate this approach on basis of a component I have implemented recently. This component calls blockUI and it's based on the jQuery plugin blockUI. By means of this component we can block any piece of page during various Ajax calls. Very handy if you have e.g. a large datatable and sorting, filtering, pagination takes much time. The component has the following parameters: "widgetVar" for the underlying widget (as all PrimeFaces components have it), "for", "forElement" to specify target component or HTML element which gets blocked and "source" to specify source component which causes an Ajax request. Events, we are interesting in, are specified via a facet "events" and f:param within the facet. I'm going to start with facelets part and show three examples.

Playing together with p:dataTable
 
<h:panelGroup id="dtPropTemplatesGroup" layout="block">
 <p:dataTable id="dtPropTemplates" var="propTemplate"
       value="#{propTemplates.templates}" paginator="true" rows="20" ...>
  ...
 </p:dataTable>
 <jtcomp:blockUI source="dtPropTemplates" for="dtPropTemplates">
  <f:facet name="events">
   <f:param name="filtering" value="true"/>
   <f:param name="paging" value="true"/>
   <f:param name="sorting" value="true"/>
  </f:facet>
  <h:panelGrid columns="2">
   <h:graphicImage library="themes" name="app/images/ajaxIndicator.gif"/>
   <h:outputText value="Please wait, data are processing ..."/>
  </h:panelGrid>
 </jtcomp:blockUI>
</h:panelGroup>
 
Filtering, paging and sorting events display a half transparent overlay over the same table and a rotating Ajax indicator with the message "Please wait, data are processing ...".


Playing together with p:tree
 
<h:panelGroup id="treeSocsGroup" layout="block">
 <p:tree id="treeSocs" value="#{socsBean.socsRootNode}" var="socNode" 
  dynamic="true" cache="true" selectionMode="single" 
  nodeSelectListener="#{socsBean.onNodeSelect}"
  nodeExpandListener="#{socsBean.onNodeExpand}" ...>
  <p:treeNode>
   <h:outputText value="#{socNode.displayName}" escape="false"/>
  </p:treeNode>
  <p:treeNode type="leafSoc" styleClass="leafSoc">
   <h:outputText value="#{socNode.displayName}" styleClass="leafContent"/>
  </p:treeNode>
 </p:tree>
 <jtcomp:blockUI source="treeSocs" forElement="overviewSocsRightGroup">
  <f:facet name="events">
   <f:param name="action" value="SELECT"/>
  </f:facet>
  // the same stuff as above
 </jtcomp:blockUI>

 <h:panelGroup id="overviewSocsRightGroup" layout="block">
  // menus, tables and other stuff
 </h:panelGroup>
</h:panelGroup>
 
A click on any tree node blocks the panelGroup with id "overviewSocsRightGroup" and the mentioned above overlay, indicator and message are displayed.


Playing together with p:ajax

Sometimes we are not interesting in any special events. In this case no f:facet for events is required. Assume we have a table, radio buttons and checkboxes. A click on any table row should block the radio buttons and checkboxes. A click on any radio button or checkbox should block the table, radio buttons and checkboxes. Remaining part of the page should stay untouched. Note: tables should be wrapped with a div element if they have to be blocked because a table can't be blocked nice in all browsers.
 
<h:panelGroup id="rightsGroup" layout="block">
 <h:panelGroup id="selectedGroupsUsersGroup">
  <p:dataTable id="selectedGroupsUsers" var="selGrUs" value="#{rightsBean.selectedGroupsUsers}" dynamic="false"
        selection="#{rightsBean.selectedGroupUser}" selectionMode="single" update="levelsRightsGrid">
   ...
  </p:dataTable>
  <jtcomp:blockUI source="selectedGroupsUsers" forElement="levelsRightsPanel">
   <f:facet name="events">
    <f:param name="instantSelectedRowIndex"/>
   </f:facet>
   // the same stuff as above
  </jtcomp:blockUI>
 </h:panelGroup>

 <h:panelGrid id="levelsRightsGrid" columns="2">
  <h:panelGroup id="accessLevelsGroup">
   <h:selectOneRadio id="accessLevels" value="#{rightsBean.level}" layout="pageDirection">
    <f:selectItem itemLabel="Custom" itemValue="Custom" itemDisabled="true"/>
    <f:selectItems value="#{rightsBean.selectableLevels}"/>
    <p:ajax event="click" process="@this" update="accessRightsGroup,selectedGroupsUsersGroup"/>
   </h:selectOneRadio>
   <jtcomp:blockUI source="accessLevels" for="rightsGroup">
    // the same stuff as above
   </jtcomp:blockUI>
  </h:panelGroup>
  
  <h:panelGroup id="accessRightsGroup">
   <h:selectManyCheckbox id="accessRights" value="#{rightsBean.selectedAccessRights}" layout="pageDirection">
    <f:selectItems value="#{rightsBean.accessRights}"/>
    <p:ajax event="click" process="@this" update="accessLevelsGroup,selectedGroupsUsersGroup"/>
   </h:selectManyCheckbox>
   <jtcomp:blockUI source="accessRights" for="rightsGroup">
    // the same stuff as above
   </jtcomp:blockUI>
  </h:panelGroup>
 </h:panelGrid>
</h:panelGroup>
 

The event instantSelectedRowIndex doesn't have a specified value. That means we are not interesting in a value (everything is valid). Unfortunately Ajax handlers can not be bound with jQuery .live() method. Therefore I had to wrap radio button and checkboxes with a h:panelGroup to get blockUI updated every time together with corresponding radio button and checkboxes.

The second part will cover the implementation and reveal more details. Stay tuned.

Thursday, April 7, 2011

How to filter p:dataTable on enter event

PrimeFaces' datatable doesn't support the filtering for "onenter" event. It's not a DOM event, but it makes sense for large datatables to filter a dataset when the enter (return) key was pressed. Many users complain that they can't filter large datasets on each keystroke, only hitting of return key makes sense for them. That's exactly my case too. I use "onenter" event for filtering because a datatable sends too many requests if user inputs and removes characters very quickly. An update of the table is very slow then. The solution is not difficult. Use filterEvent="enter" in any p:column needing a filtering like this
 
<p:dataTable id="myTable" var="user" value="#{myBean.users}"
             widgetVar="myTblWidget">
  ...
  <p:column filterBy="#{user.name}" filterEvent="enter">
    ...
  </p:column>
  ...
</p:dataTable>
 
and place this little JavaScript direct after p:dataTable (can be also placed into an ui:include for better reusing)
 
<script type="text/javascript">
/* <![CDATA[ */
  jQuery(myTblWidget.jqId).find('th .ui-column-filter[onenter]').each(function(idx) {
  var curEl = jQuery(this);
  curEl.unbind('keydown');

  curEl.keydown(function(event) {
    var e = (window.event) ? window.event : event;
    if(e.keyCode == 13) {
      event.preventDefault();
      eval(curEl.attr('onenter'));
    }
  })
});
/* ]]> */
</script>
 
The script binds "keydown" event for the enter key on every input field using for the filtering (select boxes using for this purpose don't matter here). If the enter key has been detected, the built-in client-side callback being executed (by means of the JS eval function) and sends an Ajax request to filter the table. It works like a charm. I also have a meaningful tooltip for every input field using for the filtering. The reason is clear - this kind of the filtering is not always easy to understand for end users. A tooltip seems to be very handy.

Friday, April 1, 2011

Subclass creation and inheritance in JavaScript or how to extend widgets

There are many books and articles describing the inheritance in JavaScript. I'm using Prototype, jQuery an YUI JavaScript frameworks in my old and new web projects. A quite common task for me is an extension of existing widgets. There is a classic article from John Resig which shows a pure simple solution for JavaScript inheritance without using of any frameworks. Nice implementation. I'm going to show my approved techniques with and without frameworks. They are quite simple. They work for me and I would like to share them with readers of my blog.

Assume we have a JS object (widget) called SuperWidget and want to create a subclass of it called ExtendedWidget. Assume ExtendedWidget has a constructor with four parameters and SuperWidget with two parameters.

1) Pure JS
First we create a new constructor for ExtendedWidget and call the super constructor inside of this to make sure that the instance will be correctly initiated. After that we set some new property values. Finally if the constructor is created we set the prototype to a "new SuperWidget".
 
function ExtendedWidget(param1, param2, param3, param4) {
   // call super
   this.SuperWidget = SuperWidget;
   this.SuperWidget(param1, param2);
   
   // set additional properties
   this.param3 = param3;
   var param4 = param4;

   // implement a new public method
   this.myNewMethod = function(a, b) {
      // do something
      ...
   }
   
   // implement a new private method
   var mySecondNewMethod = function(c, d) {
      // do something
      ...
   }
}

ExtendedWidget.prototype = new SuperWidget;
 
This examples also shows a definition of public and private fields and methods. The keyword "this" marks fields and methods with public access and "var" with private one. In this example "param4" and "mySecondNewMethod" can not be accessed outside after ExtendedWidget was instantiated.

2) Yahoo UI
Yahoo library offers a couple of simple calls out-of-box for subclass creation.
 
ExtendedWidget = function(param1, param2, param3, param4) {
   // call super
   ExtendedWidget.superclass.constructor.call(param1, param2);

   // set additional properties
   this.param3 = param3;
   var param4 = param4;

   // do something
   ...
}

// extend super class
YAHOO.lang.extend(ExtendedWidget, SuperWidget);

// implement a new method
ExtendedWidget.prototype.myNewMethod = function(a, b) {
   // do something
   ...
}

// extend an existing method for additional functionality
ExtendedWidget.prototype.someMethod = function(c, d) {
   ExtendedWidget.superclass.someMethod.call(this, c, d);
   
   // do something extra
   ...
}
 

3) jQuery
jQuery doesn't offer this feature directly, but we can call the superclass constructor in the extended object and extend properties by using of "extend" method. The method jQuery.extend() merges the contents of two or more objects together. We need to merge prototypes.
 
ExtendedWidget = function(param1, param2, param3, param4) {
   // call super    
   SuperWidget(param1, param2);

   // set additional properties
   this.param3 = param3;
   var param4 = param4;

   // do something
   ...
}

// merge properties into the first object ExtendedWidget
jQuery.extend(ExtendedWidget.prototype, SuperWidget.prototype);

// implement a new method
ExtendedWidget.prototype.myNewMethod = function(a, b) {
   // do something
   ...
}
 

4) Prototype
Prototype offers the JS inheritance with "Class.create". I don't want to blow up this post, read the official documentation please :-)

That's all. Now we can use ExtendedWidget as the subclass of SuperWidget like this
 
var extendedWidget = new ExtendedWidget(1, 2, 3, 4);
extendedWidget.myNewMethod("Hello", "World");
 

Announcement: In the next post I will show how to extend a PrimeFaces widget (my preferred JSF library) for command button in order to prevent multiple clicks. I will leverage the jQuery based approach 3). But before I want to present a quite special "delicacy" - hooking of PrimeFaces Ajax calls as a kind of callbacks. Anatomy of PrimeFaces events will be revealed. You will be able to "add" any callbacks to any components on-the-fly. As example I have implemented a new component based on the jQuery plugin blockUI to block any piece of page during various Ajax calls.