Create custom components based on existing WebMap Component
The goal of this post is to explain how to create a complete custom component (Front-End and Back-End) based on existing one
Last updated
The goal of this post is to explain how to create a complete custom component (Front-End and Back-End) based on existing one
Last updated
Sometimes we have faced some scenarios in WebMap where is necessary to modify just some functionality or add extra features that are not supported in the migrated components. As we know if this feature is a not native feature of the original migrated component, we will not be able to modify original component behaviors.
Most of mentioned scenarios are presented when there is a third-party component in a legacy application is not supported by WebMap controls. In those cases, most of not supported controls are replaced by a similar WebMap control in migration. However sometimes customers require to keep original features of third-party components. For those scenarios a good workaround could be create a new custom control in the migrated project extending from an existing control and overwriting needed behavior.
The idea of this entry is to explain how to create a complete custom component (Front-End and Back-End) based on existing one.
There are some scenarios which it is enough to create a custom component just in Front-End side and overwrite some methods, keeping Back-End component without changes and with the same behaviors. However, for this case we will do a complete scenario in which we will modify the Front-End and Back-End. For our example, we will create a Custom DateTimePicker component which allows assign null values, and we will create components in Front-End and Back-End.
Code created for this solution can be improved. However, the scope of the tutorial is centered in showinh how to create custom control and not best practices for coding.
For this scenario we are going to create a customDateTimePicker component which allows null values. Null value feature is not supported in current Mobilize DateTimePicker component. Even when null value is supported by kendo datepicker component, logic in mobilize component was created for working as native windows forms DateTimePicker which doesn’t allow null values. First thing that we need to achieve that behavior is create a new component that inherits from Mobilize DateTimePicker component which belongs to WebFormsComponents which is the frontend project containing all Winforms components for WebMap to WinForms migration. Custom component must be created in migrated project location and under Angular structure. So you should create a new folder with the name of the customComponent in the same level than previous migrated components in frontend project (Angular project).
For creating a component according to Angular component structure you must create 3 adittional files: html, ts and scss file with the name of the component (in this case customdatetimepicker.component).
HTML file will have all HTML required for visual control. In this case as we do not need to customize the component in the visual part, we will keep the same HTML tags than the base Front-End component (In this case DateTimePicker).
In case of scss file the same rules are applied as we don’t have to modify anything in visual part. So we should copy css style assigned to base datetimepicker component.
The most important file is the TS file that have all logic and code which allows component works in a properly way. In this case component should work in the same thing than base component. The only we need is to make some changes for allowing send null values to backend. As we only need that extra feature we only need to overwrite setter and getter in value property and in addition we will add some additional logic in change event.
In TS file the first to have in mind is create a class with the name of the component inhering to the base DateTimepicker component. In addition, you need to import packages regarding where DateTimePickerComponent component is located.
When you create a component in angular one of the most important part is to define selector, selector allows you to call the created component from a tag with the name of selector.
In addition we are going to need to create a constructor for the custom component based in DataTimepickerCOmponent constructor, also go to DateTimePickerComponent in winforms components and copy all methods and properties we will need to overwrite to achieve null value behavior (constructor, valueChanged, set and get value).
We need to include a new nullValue property in component for allowing send null values to Back-End and receive null values in Front-End from Back-End. Also we will add setter and getter methods for new property.
In addition new value must be included in valueChangeEvent event to notify value of property when datetimepicker value has changed. In this case we have added the code for valueChanged method and we are overwriting parent behavior.
By other hand we need to identify when null value is setting in control and inform to Back-End to allow null value so we will add a validation on setter value property. Kendo DatePicker supports null value when entered date is invalid o incomplete, then validation in setter method in value property allows to set NullValue property to 1 in case entered value is null or incorrect and in this way inform to Back-End a null value is assigned.
Also, we will overwrite get value method in this case to establish kendo component with no selected date when null value has been sent from Back-End side.
With all changes made in the new component we need to register it for using inside migrated project. So we need to locate migrated application module file (for this case windows-forms-app1.module.ts) and add some imports in the file. The first one is add the custom created component import, also add kendo datetime picker libraries import and finally include imported classes to @NgModules imports,exports,declarations and boostrap sections.
Finally, to use custom component in Front-End migrated project you need to replace mobilize datetimepicker tag with the new selector of the created component in this case wm-customdatetimepicker
Now that we have created a extended component in frontend, we need (for this scenario) to create all code needed to support the same behavior (null value) but this time in Back-End side. So for that case we need to create 3 new files:
CustomDateTimePicker.cs (Control Object): It should be the class that contains all methods an properties for the control.
CustomDateTimePicker.cs (DataTransfer Object): It should be the class that contains all properties sended to frontend or sended to backend.
CustomDateTimePickerMapper (Mapper Object): Contains methods ApplyChanges and Map which allow communicate sent properties from frontend with backend and vice versa. So, in case of Applychanges method DTO Object properties are validated and apply changes to Control Object only if properties have changed (properties different than null). So in that case we need to add extra logic due to previous validation because in this case we need to update value property even if value is null. For doing that we need to add also NullValue property in Back-End.
For creating each class we recommend create a new folder containing new classes needed by customs components in Back-End migrated project (similar than we did in Front-End). So we have created CustomComponents folder (but you can call folder whatever you want). Another suggestion is related to create inside previous folder 3 additional folders to separate each class according to behavior explained above for each class.
Now we are going to start with CustomDateTimePicker control class. As we talk the idea is create a custom component class in the same way than Front-End but in this case based on Back-End DateTimePicker component class. So It should have the same behavior than DateTimePicker but the only change should be modify value property to allow null values.
The issue in this case is related that we can overwrite the functionality of a method but we can not to overwrite the type of returned data by the same method. For this case the easiest way is create a new component with same properties and methods than DateTimePicker control class (you will be able to find the required classes in WFNetDCP project, It is the backend that contains winforms components used for winforms migrations) but inheriting from Mobilize.Web Control class (another solution could be generating an interface or intermediate class but for the example we will apply current solution for doing less extensive the explanation). With all code copied we will change only property value from Datetime type to Datetime? Type (nulleable datetime type).
As soon as we have changed data type returned in value to nulleable we need to modify some additional code in the class to remove all issues caused by the change. For example, another change we need to do is on GetTextValue property to return a empty string when value property is null.
Next class to customize will be CustomDateTimePicker DataTransfer Class. We have to copy the same code than DateTimePicker DataTranfer class to the new one and you will need to create the property NullValue which is needed to add additional validations in next class CustomDateTimePicker. It allows us to identify when value property in the component is setting up with null value. The possible values assigned to this property can be 0 (for indicating we have sent a common date in the value) 1 (for indicating we are sending a null value from Front-End side), 2 (for indicating we are sending a null value from Back-End side).
By other hand another important thing to have in mind is to change DataTransfer attribute to new one which allows identify control in Back-End and in Front-End as an only one. Just remember that the name of the attribute used in Back-End should be the same used than in Front-End components.
DataTransfer attribute Back-End custom component
DataTransfer attribute Front-End custom component
Finally, we need to create last class CustomDateTimePickerMapper. we will copy all code from original DateTimePickerMapper class but we are going to need to add some extra logic in ApplyChanges and Map methods in order CustomDateTimePicker component allows to store null in Value property. So in ApplyChanges that is method used when request are made from Front-End side to Back-End side, we need to validate NullValue property, In this way if sent value is equal than 1 we can determine null value has been sent and we assign that value to CustomDateTimePicker control component.
The other change that we must to do is in Map method. This method is used to generate responses from Back-End to Front-End. It is possible that we need to inform if a null value is sent to Front-End in order to change the look of the Front-End component when null is sent. As is not possible to send value with null in the response to frontend then it is necessary to indicate we are sending null from Back-End. This indication will be done through NullValue property assigning 2 value.
Now that we have all 3 classes, we need to include a Mapper in migration project to allow new component works in a proper way. So we must search for RegistrationClass class in project and include mapper registration in RegisterModelMappers Method.
In this way we have finished all necessary steps to create a custom component. Then last step will be related with modify all references of native Mobilize DateTimePicker class to CustomDateTimePicker in Back-End migrated project.