Extending Crosslight Form Builder

Since you’ve managed to get started with Crosslight Form Builder, let’s move on a bit to see how we can extend the capabilities of the Crosslight Form Builder beyond its original capabilities. In this post we’re going to learn how to add an option to choose the driver in CrosslightFormBuilder sample, as well as showing a custom view with the driver’s photo in the form, with the driver’s phone number, which when tapped, will initiate a call to the driver.

Untitled.001

 

There are two major enhancements to be done:

  • Providing driver selection
  • Providing custom driver view

Providing Driver Selection

Let’s try to create the Driver selection. At a quick overview, here’s a list of subtasks to be done in order to achieve this functionality:

  • Prepare the Driver model
  • Prepare the Driver Repository that populates the list of drivers.
  • Prepare the DriverListViewModel that populates the items from the repository.
  • Update the Form Metadata and connect the DriverListViewModel.

Let’s go through each one, step-by-step.

Prepare the Driver model

To create the Driver model, let’s create a new file named Driver.cs under CrosslightFormBuilder.Core/Models folder. The contents are as follows.

The Driver model contain 4 MVVM-ready properties: ID (int), Image (byte[]), Name (string), and Phone (string). That’s basically it. I’ve also prepared a constructor for quick and easy initialization. Now your Driver model is ready. Let’s move on.

Prepare the Driver Repository

Upon reading the heading, you might have two questions: What is this repository thingy and why do I need it? The repository pattern is more of a best-practice design pattern that handles the actual data processing for your applications. A data repository for your app.

For example, right now your app might currently retrieve data by performing queries to a database server, then one day you decided to change the data retrieval process. Rather than making changes to each and every ViewModel, you can do so by just replacing the data repository. No changes in ViewModel needed. To learn more about the Repository Pattern, check out our Developer Center documentation here.

So, let’s get started in creating our Driver repository. First thing you need to do is define the interfaces needed for the repository. Create a new interface in CrosslightFormBuilder.Core/ModelServices, named IDataRepository.cs, also creating the folder as necessary. The contents of the file are as follows.

We’ll prepare an interface to get the Driver entity based on the given ID. Notice that everything is defined as generic here. Also another interface to return all entities when calling GetAll() method.

Proceed by creating the interface for the Driver repository in CrosslightFormBuilder.Core/ModelServices folder, named IDriverRepository.cs, also creating the folder as necessary.

There’s nothing much to see here, we simply added a new method to get the Driver entity by the driver’s Name by subclassing the previously created IDataRepository interface. Let’s move on by creating the concrete DriverRepository implementation. Create a new file called DriverRepository.cs inside CrosslightFormBuilder.Core/ModelServices folder.

Here, you can then provide the real implementation to retrieve the list of drivers, also getting the drivers by name and ID. The highlighted line shows how the list of Drivers are populated, by utilizing the constructor we’ve provided for our Driver model earlier. Also notice that we’ve provided the image to be used for each driver. Oh yeah, before we forget, let’s go ahead and use these images for the drivers and put it inside the CrosslightFormBuilder.Core/Assets folder, also creating the folder as needed.

brad  charles  john

 

 

 

 

Make sure that these images’ BuildAction is set to EmbeddedResource so that they can be used in your application. Also, if you try to build the project now, you might get an error on the ToByte() method. To fix this, create a new file that contains an extension method to convert a Stream to array of bytes. Create a file named StreamExtensions.cs, and put it inside the CrosslightFormBuilder.Core/Extensions folder.

A handy tip for you: these extension method provides an easy way to extend the functionalities of a certain class, that is reusable within your application. For example, if you wish to create an extension, for let’s say, converting a string to a byte[], you can definitely do something similar to this.

Now that you’ve the got the repository part ready, let’s hook it up to the ViewModel.

Prepare the DriverListViewModel

Start by creating a new ViewModel file called DriverListViewModel.cs and put it inside CrosslightFormBuilder.Core/ViewModels folder. Here’s the contents of the file.

Here, we populate the SourceItems when the DriverListViewModel is constructed, just by calling the previously created GetAll() method from our interface. Also notice that we’ve provided the Repository property which is resolved upon the property’s getter. This is also called as IoC (Inversion of Control). To use the IoC pattern, you’ll need to register the previously created DriverRepository to be used globally in the application. To do this, open up the AppService.cs file in the CrosslightFormBuilder.Core/Infrastructure folder and add this line in the constructor.

Your ViewModel is now ready to be used to populate the list of Drivers.

Update the FormMetadata

Since you already have the list of drivers properly populated from the DriverListViewModel, we’ll need to modify the OrderFormMetadata a bit. From the initial OrderFormMetadata class in the Order.cs file, let’s modify the TaxiChoiceSection class to include the driver selection.

The highlighted lines above shows the added definition for the driver selection. Let’s inspect this line by line.

  • [Editor(EditorType.Selection)]
    This determines which editor type to be used.
    selection.002
  • [SelectedItemBinding(Path = “Driver”)]
    This attribute determines which binding path for the selected item used in the Form Builder. In this case, the item for the Form Builder is of type Order, which has the Driver property. That’s where we’re going to bind our selection into. (OrderViewModel.Item.Driver)
  • [Binding(Path = “Driver.Name”)]
    The BindingAttribute determines which property of the Driver model that is going to be displayed in the form after selection has completed.
    binding
  • [SelectionInput(SelectionMode.Single, DisplayMemberPath = “Name”, ListSourceType = typeof(DriverListViewModel))]
    The SelectionInputAttribute determines the selection editor behavior, which ViewModel provides the items source for the list, as well as the property to be displayed on the list of selection, or also often known as DisplayMemberPath.
    selection editor

By now, you’ve successfully provided a driver selection for the Form Builder. How about adding the custom view on the bottom of the form?

Providing Custom Driver View

After the user has selected the driver, it’s best for us to show the driver that the user has selected by providing a custom view at the bottom of the form. Let’s learn how you can use a custom view resource to be used along with the Form Builder, complete with data binding capabilities. In overall, there are several steps needed to achieve this:

  • Provide the custom driver view for iOS
  • Update the Form Metadata
  • Provide the Binding Provider
  • Bind to ViewModel
  • Provide the custom driver view for Android

Let’s go through each step, one-by-one.

Provide the Custom Driver View for iOS

To provide the custom driver view for iOS, all you need to do is creating a new Crosslight view for iPhone. To do this, you can utilize the item template shipped with Crosslight. In your iOS project, in the Views folder, right-click and add a new file. Under Crosslight, choose Crosslight iOS View for iPhone.

Screen Shot 2015-11-13 at 6.27.32 PM

Let’s give it a name of CallDriverButton. What this will do is Crosslight will create two files, namely CallDriverButton.xib and CallDriverButton.cs. All you need to do is create a new layout by opening the CallDriverButton.xib in Xcode Interface Builder.

xcode-interface-builder

Create your layout any way you want it. Just create an ImageView, a Label, and a Button.

outlet

Set the outlet for each.

  • ImageView: DriverImage
  • Label: DriverName
  • Button: CallButton

I know, my layout looks awful. But all I really want to show you is how you can inject your own custom views into the form using the Form Builder. So, after your layout’s done, save it and go back to Xamarin Studio.

Update the Form Metadata

Now that your layout is done, let’s update our OrderFormMetadata a bit to include this new view in our form layout. Open up Order.cs, and let’s create a new section and call it CallDriverSection, or anything you want.

Now I’d like you to pay attention how easy it is to embed a custom view into a Crosslight Form. From the definition above, you can see that we simply set the editor type to custom, then set the CustomEditorIdentifier set to CallDriverButton. In iOS, this corresponds to the name of the XIB that we’ve defined for our custom view. While on Android, this also corresponds to the name of the Android Layout file we’ve defined for our custom view layout. Simple as that.

We’ve made it super easy for developers to create a beautiful platform-specific data form by combining robust pre-built editors for common input and flexible custom views for more complex user interface. This allows you to mix and match what works best for you, and let Crosslight do the magic at runtime.

After you’ve created this section, let’s add this at the bottom of our form.

You’re done with the form metadata. But there’s something missing. What about those outlets we’ve defined earlier? How can we bind data to it?

Provide the Binding Provider

Simple. It’s basically the way you would do any data binding with Crosslight. Yes, you should provide a BindingProvider for the form. In addition to automatic bindings, Form Builder also supports natural data binding process through the use of BindingProvider. In this case, let’s create a new BindingProvider called OrderBindingProvider.cs. Let’s put this under CrosslightFormBuilder.Core/BindingProviders folder. The contents of the OrderBindingProvider are as follows.

Here, we’ve simply used the outlets we’ve defined earlier and bind them automatically to the selected Driver in the form. We’ve also added a binding from the CallButton to the CallCommand in the ViewModel, which can be used to call the driver immediately upon click. And don’t forget to use the newly created OrderBindingProvider in your OrderViewController.

Again, Crosslight does a lot of magic behind the scene which enables you to define data binding in such a simple definition. Looking back, we just need to create a view, define the outlets, and provide the bindings. Crosslight takes care the connection between all those layers at runtime.

Bind to ViewModel

Afterwards, in the OrderViewModel, we simply add a new DelegateCommand for the phone number.

Everything seems pretty much the same, except for the additional CallCommand we’ve defined for the CallButton. Run the project and you should now see iOS version is now working properly. Try selecting a driver and that driver detail will be automatically shown in the custom view you’ve defined. When you run this on an iPhone, you can even immediately perform a phone call to the driver’s number directly.

 

What about Android?

Provide the Custom Driver View for Android

This is where the Form Builder excels. Since you’ve completed the iOS version, all you need to do is just provide the custom layout and use the previously created OrderBindingProvider. Let’s take a look how to achieve this.

First, create a new Android Layout file by right clicking on the CrosslightFormBuilder.Android/Resources/layout folder. Then choose Add, New Item. Select Android, Layout. Remember to give it a name of CallDriverButton, as this corresponds to the CustomViewIdentifier defined in the FormMetadata earlier.

Screen Shot 2015-11-13 at 9.49.39 PM

Provide the layout as follows.

After ensuring the IDs are correct, you’re only left to hook up the OrderBindingProvider in your OrderActivity. Let’s do that now.

You’re done. Run the project and you’ll get the same result with iOS version.

 

Beautiful, isn’t it?

Wrapping Up

The entire project for this tutorial can be found here. To use this sample, you’ll need to use at least Crosslight 4.0.5000.321 and above. Hopefully this will help you learn more about the Crosslight Form Builder.

You’ve seen how you can easily inject a custom view to the form by using the ViewResource custom editor. Probably some time in the future I’ll add a custom ViewBuilder tutorial as well. This will be very useful for those of you who wants to build a custom control that works seamlessly with the FormBuilder. We’ve also used this approach in building Crosslight Form Builder for each platform inside Crosslight framework.

Cheers,
Nicholas Lie

Leave a Reply