Jul 20 2004

Flex MXML Sample 3: Conditional dynamic UI elements

Published by at 23:25 under Wayback Archive

During the meetings that I have with Flex MXML developers there are several questions that pop up regularly. One of the questions is how one can create a conditional interface element in Flex. Or even more specific; how to define with script whether f.e. something should be a list of checkboxes or a list of radio buttons.

The true answer to this really depends on the situation, but the sample below shows you one of the solutions using createChild(myAsClass, “id”, {myObject:myObject});

Note: The full application code can be downloaded as zip.

The sample application I have build is a proof of concept Certification Application (not final, it’s just for display purposes). The idea is to define all questions of the application in an XML document (maybe generated by a database) and then have turn that data into an interface using ActionScript and MXML. The application should decide itself – based on the XML data – whether a question is a multiple choice or a multiple answer question and then show the appropriate UI elements for that.

I have defined the application in check_vs_radio.mxml and the script in script.as. This script used createChild() and one of the classes multipleAnswer.mxml or multipleChoice.mxml.

The concept is simple, but in some situations very powerfull.

check_vs_radio.mxml
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.macromedia.com/2003/mxml” width=”100%” height=”100%”>
 <mx:Script source=”script.as” />
    <mx:Style source=”styles.css” />   
    <mx:Model id=”q” source=”questions.xml” />
 
 <mx:HBox textAlign=”left” verticalAlign=”middle”>
  <mx:Image source=”@Embed(‘assets/swf/jellylogo.swf’)” width=”50″ height=”50″ />
  <mx:Label text=”Certification Test” styleName=”applicationTitle” />
  <mx:Spacer widthFlex=”1″ />
 </mx:HBox>
 
 <mx:HBox>
  <mx:Panel title=”Questions” styleName=”questionPanel”>
   <mx:List id=”qList” heightFlex=”1″ dataProvider=”{q.q}” labelField=”label” change=”changeQuestion();” />
   <mx:ControlBar widthFlex=”1″ horizontalAlign=”right” />
  </mx:Panel>
  
  <mx:VBox styleName=”bigRoundedBox” widthFlex=”1″ heightFlex=”1″>
   <mx:VBox styleName=”smallRoundedBox” widthFlex=”1″>
    <mx:Label text=”Question:” styleName=”groupName” />
    <mx:HBox id=”questionBox” styleName=”groupContent”>
    </mx:HBox>
   </mx:VBox>
  </mx:VBox>
 </mx:HBox>
</mx:Application>

script.as
function changeQuestion(){
 var question = qList.selectedItem
 var answers:Array = question.a;
 var correctCount:Number = 0;
 var displayFormat:String = “multipleChoice”;

 // Check whether multiple choice or multiple answer
 for (var i=0; i<answers.length; i++) {
  if (answers[i].correct) {
   correctCount++;
   if (correctCount > 1) {
    displayFormat = “multipleAnswer”;
    break;
   }
  }
 }
 
 // Remove all old childs
 questionBox.destroyAllChildren();
 
 if (displayFormat == “multipleChoice”) {
  questionBox.createChild(multipleChoice, “questionForm”, {question:question});
 } else if (displayFormat == “multipleAnswer”) {
  questionBox.createChild(multipleAnswer, “questionForm”, {question:question});
 }
}

multipleAnswer.mxml
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Form xmlns:mx=”http://www.macromedia.com/2003/mxml”>
 <mx:Script>
 <![CDATA[
  var question:Object; 
 ]]>
 </mx:Script>
 
 <mx:FormItem label=”{question.label}”>
  <mx:Repeater id=”aRep” dataProvider=”{question.a}”>
   <mx:CheckBox label=”{aRep.currentItem.label}” />
  </mx:Repeater>
 </mx:FormItem>
</mx:Form>

multipleChoice.mxml
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Form xmlns:mx=”http://www.macromedia.com/2003/mxml”>
 <mx:Script>
 <![CDATA[
  var question:Object; 
 ]]>
 </mx:Script>
 
 <mx:FormItem label=”{question.label}”>
  <mx:Repeater id=”aRep” dataProvider=”{question.a}”>
   <mx:RadioButton groupName=”myGroup” label=”{aRep.currentItem.label}” />
  </mx:Repeater>
 </mx:FormItem>
</mx:Form>

questions.xml
<?xml version=”1.0″ encoding=”iso-8859-1″?>
<questions>
 <q label=”What does CF stand for”>
  <a correct=”true” label=”ColdFusion” />
  <a label=”Chineese Food” />
  <a label=”Children Fun” />
  <a label=”CodeFusion” />
 </q>
 <q label=”What are Macromedia tools”>
  <a correct=”true” label=”Dreamweaver” />
  <a correct=”true” label=”Flash” />
  <a label=”Illustrator” />
  <a correct=”true” label=”Homesite” />
 </q>
 <q label=”What is the current CF version?”>
  <a label=”5″ />
  <a label=”MX 2004″ />
  <a correct=”true” label=”MX” />
  <a label=”6″ />
 </q>
</questions>

8 responses so far

8 Responses to “Flex MXML Sample 3: Conditional dynamic UI elements”

  1. Marco Casario says:

    Hi Waldo,
    very cool stuff..i was very enthusiastic to test your code, but i was not able to download the zip.
    Could you checl if it’s all ok ?
    thanks a lot,

  2. Waldo Smeets says:

    Hi Marco, thanks for the note! I was not aware of it. I’ve fixed the link now so you should be fine to download the ZIP. Have fun with it 🙂

  3. Vinny Timmermans says:

    Good work. I have implemented the same idea in the system (MS technologies) I have shown you recently. It will become really powerfull when you go one step further: dynamic detail pages. This allows you to set up an ideal information model and let the detailspage vary according to the information provided by the user. For example: a CRM system. Suppose you have created a comprehensive information model which defines every aspect of a customer. Because this model will not apply to every customer, some items will stay blank when the form is filled. By dynamically generating the detailspage and showing only those fields that were filled, The information shown on the detailspage is different for each and every customer. It increases the usability of your application (no blank fields anymore on the detailspage) and it makes it far more effective ans usefull. I have used this concept on a range of projects for different purposes. It has become one of those elements I use for every application I design. Good to see a Flex implementation.

  4. Waldo Smeets says:

    Hi Marco, thanks for the note! I was not aware of it. I’ve fixed the link now so you should be fine to download the ZIP. Have fun with it 🙂

  5. Vinny,

    Are you sure that conditonally hiding the form elements that didn’t get filled in is more usable? Shouldn’t there be a visual inidcation of what isn’t filled in, rather than nothing at all.

    Best,
    Allen

  6. Waldo Smeets says:

    Allen, the way I read Vinny his post is that he is hiding form items BEFORE the user enters the form. This means that a user only sees the fields that are relevant to him (instead of ‘if you selected A in the previous question, fill in the textarea below’) etc etc.

  7. Vinny Timmermans says:

    What I am doing is showing ALL the items in the form. So ALL users who are authorized to INSERTor UPDATE data will see ALL the fields and can fill them. Those users who are only authorized to VIEW data will see only the non-empty fields. Now the benefits.
    1. Higher usability. How often do we let our eyes scan the screen only to find empty fields. Just take a look at your contacts application in Outlook and you know what I mean. This is tiring for users. If there are only six fields that contain data. The user will see only six fields. Not six useful fields and a lot useless fields.
    2. One datamodel/multiple presentations without any additional coding. For example I have designed a CRM system that contains account profiles. An account profile consists of more than 40 general elements that are not useful for each and every account. When you use dynamic detail pages, it gives people the impression each account profile is not a general profile but a profile specifically created for this account. You can do this with OO as well, but in some situations it is not as flexible and pure overkill.
    3. Open book management. This is a management practice introduced some years ago. The basics are to provide your employees with all the information they need. Be open. Show them your books. Most companies embracing this management practice introduce this system gradually. Dynamic details pages provide you with a good way to do so. Implement the final, most open information model, but let contentmanagers responsible for inserting and updating the information gradually fill more fields. So employees get more information over time without any additional coding or maintenance required. The perfect model has been implemented from the start.

    Make sense?

    Vinny

  8. Oh I see. You have an ‘uber-form’ for lack of a better term that has all form items, and then you dynamicly configure it based on the user. Form personalisation it seems.

    Yes it makes good sense. Good food for thought!

    Best,
    Allen