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 create an instance of PropertyEditorStyle and set it to the PropertyEditor's
propertyEditorStyle property. 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 EntityProperty. 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

export function changeEditorFill() {
    var property = 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 GroupTitleStyle and set it to the PropertyGroup's
titleStyle property. 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

export function changeGroupLabelTextColor() {
    var group = 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 XML

<df:EntityProperty name="name" >
    <df:EntityProperty.editor>
        <df:PropertyEditor type="Text">
            <df:PropertyEditor.propertyEditorStyle>
                <df:PropertyEditorStyle strokeColor="#00695c" strokeWidth="2" fillColor="#4db6ac"
                        labelHidden="false" labelTextSize="18"
                        labelPosition="Left" labelWidth="60"
                        ios:labelFontName="Times New Roman" android:labelFontName="sans-serif-light"
                        labelFontStyle="Italic" labelTextColor="#00695c"/>
            </df:PropertyEditor.propertyEditorStyle>
        </df:PropertyEditor>
    </df:EntityProperty.editor>
</df:EntityProperty>

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": 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

export function 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));
}

export function 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 editorOffsets = new UIEdgeInsets({ top: editorPaddingVertical, left: editorPaddingHorizontal, bottom: editorPaddingVertical, right: editorPaddingHorizontal });
    editor.style.insets = editorOffsets;

    // Update core editor padding
    var textOffsets = new UIEdgeInsets({ top: coreEditorPaddingVertical, left: coreEditorPaddingHorizontal, bottom: coreEditorPaddingVertical, right: coreEditorPaddingHorizontal });
    if (editorHasValueLabel(editorType)) {
        editor.showAccessoryImage = false;
        editor.editorValueLabel.textInsets = textOffsets;
    } else if (editorIsTextField(editorType)) {
        editor.editor.textInsets = textOffsets;
    }

    // Update core editor background
    var layer = editorHasValueLabel(editorType) ? editor.editorValueLabel.layer : editor.editor.layer;
    layer.borderColor = strokeColor.ios.CGColor;
    layer.borderWidth = strokeWidth;
    layer.cornerRadius = cornerRadius;
} else {
    // Update editor padding
    var editorOffsetH = utilsModule.layout.toDevicePixels(coreEditorPaddingHorizontal);
    var editorOffsetV = utilsModule.layout.toDevicePixels(coreEditorPaddingVertical);
    editor.rootLayout().setPadding(editorOffsetH, editorOffsetV, editorOffsetH, editorOffsetV);

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

    // Update core editor background
    var drawable = new android.graphics.drawable.GradientDrawable();
    drawable.setCornerRadius(utilsModule.layout.toDevicePixels(cornerRadius));
    drawable.setStroke(utilsModule.layout.toDevicePixels(strokeWidth), strokeColor.android);
    drawable.setColor(fillColor.android);
    coreEditorView.setBackgroundDrawable(drawable);
}

References

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

Related articles you might find useful: