RadDataForm: Styling

If you followed the getting started section, you now know how to edit an object's properties with RadDataForm for NativeScript. This article will show you how to change the style of each editor, its label or the groups if grouping is enabled.

Figure 1: RadDataForm with some of the editor's styling properties changed on Android (left) and iOS (right)

NativeScriptUI-DataForm-Styling-01-Android NativeScriptUI-DataForm-Styling-02-iOS

Styling Editors

In order to change the style of an editor, you need to follow these steps:

  • Declare the TKEntityProperty and set the tkPropertyGroupProperties inline directive to it in your HTML.
  • Between its tags declare an TKPropertyEditor and set the tkEntityPropertyEditor inline directive to it.
  • Finally between the TKPropertyEditor tags declare the TKPropertyEditorStyle and set the tkPropertyEditorStyle inline directive to it

Here's what you can update in editor through its style:

If you need to make changes to the styles runtime, you can get access the current style of an editor through the TKEntityProperty. Here's an example of how to change the fillColor for the editor of the property name.

Example 1: Changing the fillColor of an editor

public changeEditorFill() {
    var property = this.myRuntimeDataFormComp.dataForm.getPropertyByName("name");
    property.editor.propertyEditorStyle.fillColor = "LightBlue";
}

Note that in this example we make the change when RadDataForm is already loaded and its editors are initialized (in this case on a button tap), otherwise the default PropertyEditorStyle may not be initialized and propertyEditorStyle will be undefined.

Styling Group Headers

In order to change the style of the header of a group, you need to create an instance of TKGroupTitleStyle containing the tkPropertyGroupTitleStyle inline directive and declare it between the TKPropertyGroup's tags. Here's what you can update in the header of a group through its style:

  • fillColor: The color that will be used as background of the group header.
  • strokeColor: The color of the border of the group header.
  • strokeWidth: The width of the border of the group header.
  • separatorColor: The color of the line separator of the group header /iOS only/.
  • labelTextSize: The size of the text of the group header.
  • labelFontName: The name of the font that is used for the text of the group header.
  • labelFontStyle: The FontStyle for the text of the group header.

If you need to make changes to the styles runtime, you can get access the current style of a group title through the PropertyGroup. Here's an example of how to change the labelTextColor for the group Main Info.

Example 2: Changing the labelTextColor of a group header

public changeGroupLabelTextColor() {
    var group = this.myRuntimeDataFormComp.dataForm.getGroupByName("Main Info");
    group.titleStyle.labelTextColor = "Blue";
}

Note that in this example we make the change when RadDataForm is already loaded and its groups are initialized (in this case on a button tap), otherwise the default GroupTitleStyle may not be initialized and titleStyle will be undefined.

Example 3: Using some of the abovementioned styling properties in HTML

<TKEntityProperty tkPropertyGroupProperties name="name">
    <TKPropertyEditor tkEntityPropertyEditor type="Text">
        <TKPropertyEditorStyle tkPropertyEditorStyle strokeColor="#00695c" strokeWidth="2" fillColor="#4db6ac" labelHidden="false"
            labelTextSize="18" ios:labelFontName="Times New Roman" android:labelFontName="sans-serif-light" labelFontStyle="Italic"
            labelPosition="Left" labelWidth="60" labelTextColor="#00695c"></TKPropertyEditorStyle>
    </TKPropertyEditor>
</TKEntityProperty>

Styling Native Components

Figure 2: RadDataForm with editors' colors updated independently on Android (left) and iOS (right)

NativeScriptUI-DataForm-Styling-02-Android NativeScriptUI-DataForm-Styling-02-iOS

If you need to provide a more customized styling which is not covered by the above properties, you can always fine-tune the native editors for each platform. In order to do this, you can use the editorUpdate event in RadDataForm. First you can use the propertyName from the passed arguments with the events to determine if the currently updated editor is the one you want to customize:

Example 4: Apply styling based on the name of a property

switch (args.propertyName) {
    case "appVolume": this.editorSetupSliderAndroid(args.editor); break;

If you want the customization to reflect all editors of specific editor type you can do the check through the EntityProperty that you can get with RadDataForm's getPropertyByName method. Then you can check the editor type:

Example 5: Apply styling based on the type of an editor

var entityProperty : EntityProperty =
    (<RadDataForm>args.object).getPropertyByName(args.propertyName);
switch (entityProperty.editor.type) {
    case "Slider": editorSetupSliderIOS(args.editor); break;

If the currently updating editor is the one we want to customize we can access the native editor through the editor property of the arguments passed with the event. Then depending on the platform, we can access the actual view of the editor with the getEditorView() method on Android and with the editor property on iOS. Here's an example of changing the style of the Slider editor independently on each platform:

Example 6: Change the colors of native Slider editor on each platform

public editorSetupSliderAndroid(editor) {
    var coreEditor = <android.widget.SeekBar>editor.getEditorView();
    coreEditor.getThumb().setColorFilter(new android.graphics.PorterDuffColorFilter(colorDark.android, android.graphics.PorterDuff.Mode.SRC_IN));
    coreEditor.getProgressDrawable().setColorFilter(new android.graphics.PorterDuffColorFilter(colorLight.android, android.graphics.PorterDuff.Mode.SRC_IN));
}

public editorSetupSliderIOS(editor) {
    var coreEditor = <UISlider>editor.editor;
    coreEditor.tintColor = colorLight.ios;
    coreEditor.thumbTintColor = colorDark.ios;
}

In this example we used the properties of the native views that represent the Slider editor: SeekBar on Android and UISlider in iOS.
Here's a list with each of the RadDataForm editors and the corresponding types of the native views used for that editor on each platform:

Editor Android Native View iOS Native View
Text EditText TKTextField
MultilineText EditText UITextView
Email EditText TKTextField
Password EditText TKTextField
Phone EditText TKTextField
Number EditText TKTextField
Decimal EditText TKTextField
Switch SwitchCompat UISwitch
Stepper RadNumberPicker UIStepper
Slider SeekBar UISlider
Picker Spinner UIPickerView
SegmentedEditor RadioGroup UISegmentedControl
List ListView TKLabel
DatePicker EditText UIDatePicker
TimePicker EditText UIDatePicker
AutoCompleteInline RadAutoCompleteTextView TKAutoCompleteTextView
Label TextView UILabel

Now that you know how to access the core editor view and what its type is you can dive deeper into the capabilities that the access to the native elements provides. For example you can further adjust the location of an editor and its background:

Figure 3: RadDataForm with editors' background updated manually on Android (left) and iOS (right)

NativeScriptUI-DataForm-Styling-03-Android NativeScriptUI-DataForm-Styling-03-iOS

This is achieved again by using the editorUpdate event in RadDataForm and the native editor taken from the parameters of the event arguments:

Example 7: Change the editor background of native editors on each platform

if (ios) {
    // Update editor padding
    var editorInsets = new UIEdgeInsets({ top: this._editorPaddingVertical, left: this._editorPaddingHorizontal, bottom: this._editorPaddingVertical, right: this._editorPaddingHorizontal });
    editor.style.insets = editorInsets;

    // Update core editor padding
    var coreEditorInsets = new UIEdgeInsets({ top: this._coreEditorPaddingVertical, left: this._coreEditorPaddingHorizontal, bottom: this._coreEditorPaddingVertical, right: this._coreEditorPaddingHorizontal });
    if (this._editorHasValueLabel(editorType)) {
        editor.showAccessoryImage = false;
        editor.editorValueLabel.textInsets = coreEditorInsets;
    } else if (this._editorIsTextField(editorType)) {
        editor.editor.textInsets = coreEditorInsets;
    }

    // Update core editor background
    var layer = this._editorHasValueLabel(editorType) ? editor.editorValueLabel.layer : editor.editor.layer;
    layer.borderColor = this._strokeColor.ios.CGColor;
    layer.borderWidth = this._strokeWidth;
    layer.cornerRadius = this._cornerRadius;
} else {
    // Update editor padding
    var editorOffsetH = utilsModule.layout.toDevicePixels(this._coreEditorPaddingHorizontal);
    var editorOffsetV = utilsModule.layout.toDevicePixels(this._coreEditorPaddingVertical);
    editor.rootLayout().setPadding(editorOffsetH, editorOffsetV, editorOffsetH, editorOffsetV);

    // Update core editor padding
    var coreEditorView = editor.getEditorView();
    var textOffsetH = utilsModule.layout.toDevicePixels(this._coreEditorPaddingHorizontal);
    var textOffsetV = utilsModule.layout.toDevicePixels(this._coreEditorPaddingVertical);
    coreEditorView.setPadding(textOffsetH, textOffsetV, textOffsetH, textOffsetV);

    // Update core editor background
    var drawable = new android.graphics.drawable.GradientDrawable();
    drawable.setCornerRadius(utilsModule.layout.toDevicePixels(this._cornerRadius));
    drawable.setStroke(utilsModule.layout.toDevicePixels(this._strokeWidth), this._strokeColor.android);
    drawable.setColor(this._fillColor.android);
    coreEditorView.setBackgroundDrawable(drawable);
}

References

Want to see these scenarios in action?
Check our SDK examples for Angular repo on GitHub. You will find these and many other practical examples with NativeScript UI.

Related articles you might find useful: