Now there are essentially two things that you can edit via a normal capture interface namely properties e.g. FirstName and single relationships e.g. PersonType. Habanero Faces allows you to dynamically create a editable user interface based on an xml definition of that user interface. In this case we are looking at editable forms. For each control on the editable form (called a field in the xml Definition). You can specify the control type and the Control Mapper type. This gives you infinite flexibility in that you can create a custom control and map it to the property via a custom mapper. So let's take the problem I had today. SCENARIO: Let’s say you have two business objects, ‘Classroom’ and ‘Student’, having a one-to-many relationship (a classroom has many students). You have a UIForm for the Business Object ‘Student’ which contains a ‘StudentName’ textbox and a ‘Classroom’ combobox to select a class the student belongs to. The UIForm captures students and each must be assigned to an active classroom, therefore the combobox needs to be filtered by a criteria of “[Classroom.Status] = ‘Active’”.
OK this is a bit of a weak example but stick with me.
By default Firestarter will use a combo and will use the AutoMappingRelationshipComboBoxMapper. What this basically does is loads all the potentially Related Objects (ClassRooms in this case) and loads these into the combo box. The problem is that it loads all ClassRooms and not just the active ones.
Well it turned out to be hideously simple to create a custom Mapper that behaved exactly as I wanted. This custom mapper is nice and orthogonal and fully testable by itself.
I have called this the 'ClassRoomAutoLoadingRelationshipComboBoxMapper' I have included below the code for the Mapper and the change to the ClassDef.xml required so that this custom mapper is used.
namespace SchoolManagement.UI.Mappers publicclass ClassRoomAutoLoadingRelationshipComboBoxMapper : AutoLoadingRelationshipComboBoxMapper { public ClassRoomAutoLoadingRelationshipComboBoxMapper(IComboBox comboBox, string relationshipName, bool isReadOnly, IControlFactory controlFactory) : base(comboBox, relationshipName, isReadOnly, controlFactory){} protected override void LoadCollectionForBusinessObject() { //Add you custom load here.... BusinessObjectCollection classrooms = Broker.GetBusinessObjectCollection("Status = 'Active'"); this.BusinessObjectCollection = classrooms; } }
namespace SchoolManagement.UI.Mappers
publicclass ClassRoomAutoLoadingRelationshipComboBoxMapper : AutoLoadingRelationshipComboBoxMapper
{
public ClassRoomAutoLoadingRelationshipComboBoxMapper(IComboBox comboBox, string relationshipName, bool isReadOnly, IControlFactory controlFactory) : base(comboBox, relationshipName, isReadOnly, controlFactory){}
//Add you custom load here....
BusinessObjectCollection classrooms = Broker.GetBusinessObjectCollection("Status = 'Active'");
this.BusinessObjectCollection = classrooms;
}
The LoadCollectionForBusinessObject() loads a collection of classrooms that are active.
Having created the class and added your custom load, you can change the ‘mapperType’ and ‘mapperAssembly’values to your class name and class namespace respectively for the relevant UIForm.e.g:
<ui name="default"> <form width="300" height="250" title=""> <tab name="default"> <columnLayout width="-1"> <field label="Student Name" property="StudentName" type="TextBox" assembly="System.Windows.Forms" editable="true" ></field> <field label="Class Room Name" property="Classroom" type="ComboBox" assembly="System.Windows.Forms" mapperType=" ClassRoomAutoLoadingRelationshipComboBoxMapper " mapperAssembly=" SchoolManagement.UI.Mappers " editable="true"></field> </columnLayout> </tab> </form> </ui>
Happing mapping!!!
This website is best viewed in Internet Explorer 7 & 8; Firefox 3.6.11; Opera 10.63; & Safari 4.