Hmm… upgrades!

Marky Roden has published an excellent post on the difference between what’s good for developers and what’s good for users over at his Xomino blog. I wanted to give my reply due consideration, and spent a bit of time thinking about why there’s this dichotomy of interests. And I ultimately realized that in order to do the topic justice, I would have to develop both solutions and compare. I set myself a simple task: have an XPage with two radio button groups, one that would show & hide a div using partial refresh, and another that would show & hide a div using client-only code.

The first part was easy enough and took about 5 minutes. It looks like this…

<xp:div id="partialTarget">
<xp:radioGroup id="radioGroup1" value="#{viewScope.partialRadio}" defaultValue="hide">
<xp:selectItem itemLabel="show" itemValue="show"/>
<xp:selectItem itemLabel="hide" itemValue="hide"/>
<xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="partialTarget" execMode="partial" execId="partialTarget"/>
</xp:radioGroup>
<xp:div>
<xp:this.rendered><![CDATA[#{javascript:return viewScope.partialRadio=="show";}]]></xp:this.rendered>
<xp:label value="Partial Refresh area now being shown!" id="label1"/>
</xp:div>
</xp:div>


But then a funny thing happened when I went to do the client-only version. I couldn’t. I thought it would be easy enough to add a client event handler to the radio button that toggled the visibility of the target div, but I discovered that I didn’t know how to get the value for the radio button. And a bit of Google-fu revealed that I wasn’t the only person to have this challenge. Because of the arcane way that radio button groups work, lots of people have struggled with this problem.

In the end, I had to turn to people who know client-side Javascript better than I, including the esteemed Dr. Roden himself, to come up with a solution. It looks like this…

<xp:div>
<xp:radioGroup id="clientRadio" value="#{viewScope.clientRadio}" defaultValue="hide">
<xp:selectItem itemLabel="show" itemValue="show"/>
<xp:selectItem itemLabel="hide" itemValue="hide"/>
</xp:radioGroup>
<xp:scriptBlock>
<xp:this.value><![CDATA[dojo.query("input[name=#{id:clientRadio}]").connect("onchange", function() {
    dojo.style( dojo.query("div[id=#{id:clientTarget}]")[0], "display", (this.value=="show" ? "" : "none") );
});]]></xp:this.value>
</xp:scriptBlock>
<xp:div id="clientTarget" style="display:none">
<xp:label value="Client refresh area now being shown!" id="label2"/>
</xp:div>
</xp:div>

Needless to say, this is quite a bit different. I hesitate to say it’s more complicated, because if you’re thoroughly familiar with Dojo, it’s not much code. But Designer didn’t offer me any help in solving the problem client-side. I might even say that it actively got in the way by misleading me with the onChange event in the IDE not being able to provide me with the selected value of the radio button.

But as I look at what code gets generated at the browser level, there’s no particular reason why the Designer components couldn’t do this. Indeed, if I’m willing to switch to a Dojo radio button set, I can do this with a client simple action. It looks like this…

<xp:div>
<xe:djRadioButton label="show" id="djRadioButton1" value="#{viewScope.dojoRadio}" defaultValue="show" selectedValue="show" groupName="dojoRadio">
<xp:eventHandler event="onChange" submit="false">
<xe:this.script><xe:dojoFadeIn node="dojoTarget"/></xe:this.script>
</xp:eventHandler>
</xe:djRadioButton>
<xe:djRadioButton label="hide" id="djRadioButton2"  value="#{viewScope.dojoRadio}" selectedValue="hide" groupName="dojoRadio">
<xp:eventHandler event="onChange" submit="false">
<xe:this.script><xe:dojoFadeOut node="dojoTarget"/></xe:this.script>
</xp:eventHandler>
</xe:djRadioButton>
<xp:div id="dojoTarget">
<xp:label value="Dojo refresh area now being shown!" id="label3"/>
</xp:div>
</xp:div>

Definitely more complicated but perhaps worth it.

So how do we solve this conflict between developer productivity and user experience? Better tooling, of course. We need new components that are as simple to use and understand as the partial refresh example, while providing the user experience and efficiency of the client-side or Dojo examples. To me, the obvious place to do this is in the Bootstrap4XPages open source project.

Who’s in?

Advertisements
Posted in Uncategorized
2 comments on “Hmm… upgrades!
  1. It would be awesome if we could extend the eventHandler, to allow the user to define the submitId, to optimise the POST request further. And even a property to turn it into a GET request instead of a POST request (although if you can define a submitId, that could be virtually be done by setting submitId to the component surrounding the eventHandler and using “Do not validate or update values”)

  2. Phil Witton says:

    Very interesting. I am re-coding an XPage to react to radio button clicks. Fortunately I could use JQuery to add a listener to all input:radio and get the id and value from the returned object to use in my code. The Client side code removes many partial refreshes (and a complete one) and server touches that were unnecessary.

Take the red pill.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: