This is a migrated thread and some comments may be shown as answers.

Programmatic Styling requires "one tick delay"

5 Answers 66 Views
DataForm
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Robert
Top achievements
Rank 1
Robert asked on 24 Jun 2017, 02:24 PM

I really struggled to get programmatic styling to work on the RadDataForm using Angular. The problem is that in ngOnInit and ngAfterViewInit the properties on the form are not yet fully initialized, so you cannot set those styles. That is, the sequence

let group = this.formComponent.dataForm.getGroupByName(groupName);
group.titleStyle.labelTextColor = "Blue";

fails when called inside either of those methods because titleStyle and/or labelTextColor don't exist.

Although it's not mentioned anywhere in your documentation, I discovered the "runtime-updates" sample in the demo app and saw that those calls work great if called dynamically, such as in response to a button tap. This made me realize that if I simply do the styling one tick after the page is built then those properties will exist and it should work. Indeed, that was the case.

So now, inside ngOnInit, after I do my other programmatic setup of the DataForm, I call setTimeout(this.styleForm, 0); Although a bit of a nuisance, it works.

The most frustrating part of this whole exercise was having to discover these things on my own. The documentation mentions capabilities and gives hints, but it doesn't do a good job of walking you through the steps for a lot of these scenarios.

5 Answers, 1 is accepted

Sort by
0
Deyan
Telerik team
answered on 26 Jun 2017, 11:42 AM
Hello Robert,

Thanks for writing and taking the time to share your feedback.

I am sorry to hear about your struggle with styling the RadDataForm component. I have opened an issue with our team and we will immediately proceed with improving the documentation considering the limitations you are pointing out.

Please accept our apologies and do let us know in case you have further questions or need assistance.

Regards,
Deyan
Progress Telerik
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
0
Nianwei
Top achievements
Rank 1
answered on 08 Jan 2018, 08:45 PM

I also ran into similar issue when trying to style form programmatically. Almost all samples in  https://github.com/telerik/nativescript-ui-samples/tree/release/sdk/app/dataform have styles defined in the XML, which means they are already initialized when the code executes. However in my use case those entities are defined in a server JSON call, so everything is created on the fly, using metadata binding "

<df:RadDataForm source="{{ source }}" metadata="{{metadata}}"></df:RadDataForm>

 is the most appropriate choice when I can do a fetch to populate metadata. 

  There are a few places with somewhat misleading documentation. For example: https://docs.telerik.com/devtools/nativescript-ui/api/classes/raddataform.html#editorupdateevent it states "An event fired when an editor is updated and allows for its customization. ". and pre http://docs.telerik.com/devtools/nativescript-ui/Controls/NativeScript/DataForm/dataform-styling#styling-editors it states "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", so I attached an editorUpdate Handler:

 

<df:RadDataForm source="{{ source }}" metadata="{{metadata}}" editorUpdate="onEditorUpdate"></df:RadDataForm>

 

in code:

function onEditorUpdate(dfEventData){

var style = new PropertyEditorStyle ();

style.labelTextSize=20;

dfEventData.editor.propertyEditorStyle = style;

}

 

It did not work, looks like editorUpdate event was fired too soon (meaning it's not truly available for customization), and a default editor style was created later and replaced the custom one. 

Also, there should be a "load" event to siginal the true "readiness" for customization, compare to using a delay timeout as a workaround. Somehow the fact that all sample code pre-define all elements in XML masked the problem. 

 

 

 

0
Nikolay Tsonev
Telerik team
answered on 09 Jan 2018, 11:14 AM
Hi Nianwei,

First of all, thank you for your interest in UI for NativeScript and for contacting us.

I reviewed your case and found that to access the editors you should get the property by its name and then to apply the needed style on the editorUpdate event. For example, in my sample project I populate the DataForm component with the following data:
{
  "isReadOnly": false,
  "commitMode": "Immediate",
  "validationMode": "Immediate",
  "propertyAnnotations":
  [
    {
      "name": "name",
      "displayName": "Name",
      "index": 0
    },
    {
      "name": "age",
      "displayName": "Age",
      "index": 1,
      "editor": "Number"
    },
    {
      "name": "email",
      "displayName": "E-Mail",
      "index": 2,
      "editor": "Email"
    },
    {
      "name": "city",
      "displayName": "City",
      "index": 3,
      "editor": "Picker",
      "valuesProvider": ["New York", "Washington", "Los Angeles"]
    },
    {
      "name": "street",
      "displayName": "Street Name",
      "index": 4
    },
    {
      "name": "streetNumber",
      "displayName": "Street Number",
      "index": 5,
      "editor": "Number"
    }
  ]
}
Then I get the needed editor by name and add the new style:

XML
<df:RadDataForm id="myDataForm"  editorUpdate="onEditorUpdate" source="{{ person }}" metadata="{{ personMetadata }}"/>

TypeScript
import viewModel = require("./../view-models/person-model-2");
import dataFormModule = require("nativescript-pro-ui/dataform");
import {Color} from "color"
export function onPageLoaded(args) {
    var page = args.object;
    page.bindingContext = new viewModel.PersonModel2();
}
 
 
export function onEditorUpdate(dfEventData:dataFormModule.DataFormEventData){
console.log("onEditorUpdate");
    var style = new dataFormModule.PropertyEditorStyle ();
    style.labelTextColor = "#0060fc"
    style.labelTextSize=20;
    setTimeout(() => {
        dfEventData.object.getPropertyByName("age").editor.propertyEditorStyle=style;
    }, 1);
 
    }

Regarding the loaded event. The component already has a similar event, which will be fired while the component is loaded in the application, however, while loading the metadata from JSON the time of editors initializing does not match with this loaded event.


SOmething more, I would like to point you that we have already logged feature request in our feedback repository, where it is requested to provide an support for styling the DataForm via CSS. You could review it and provide your personal feedback for this functionality. For further info, you could keep track on the issue.

Hope this information helps
Regards,
nikolay.tsonev
Progress Telerik
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
0
Nianwei
Top achievements
Rank 1
answered on 09 Jan 2018, 11:53 AM

Hello, nikolay

 

Thank you for the reply. Appreciate the sample code. A few more questions follows:

Aside from a specific "age" property used in a handler fired by every editor, which I assume it's just for illustration purpose, I still feel it will be helpful to have more info on:

1. setTimeout: How much should the timeout be? 0,1,or something else, is that controlled by the time the main thread need to complete initialization of all editors in the form, or just this one that fired the event? Could there be an event that truly signal the readiness for customization, like editorReady? or editorLoaded? (the existing editorSetup sounds good, but only for iOS and not sure still need setTimeout).

2. The event already pass in "editor" property in the dfEventData.editor, why would getPropertyByName(propertyName).editor  be any different? Is there a chance the editor can be replaced with a different object AFTER the editorUpdate event? This worries me. Based on what I see, because editors can be created by different method (XML, metadata JSON, or from source default), there is a chance that multiple editor objects can be created for one property at some point. This timeout trick seems to the "hack" of letting these potentially conflicting ones fight off, settle down, then customize the winning one. 

3. Can you provide more example on creating those editors in pure code, and how to prevent them from be overwritten by the default?  So far the samples are basically creating them by XML, but the setting of source and/or metadata combined with binding seems trigger the form doing things on it's own (default) and ignore what the code already set, so it's kind of very important to know WHEN to customize the editor, or propertyEditorStyle, and it's not clear either in documentation or SDK samples. I can not pre-determine the properties in XML because they are dynamically loaded from server. 

 

Thanks

 

0
Nikolay Tsonev
Telerik team
answered on 10 Jan 2018, 03:54 PM
Hi Nianwei,

Thank you for writing us back,

As I mentioned in my previous comment at this time the appropriate event for applying the styling to the editor is , however for Android, we should also use a timeout and to delay the applying of the needed styling option no more than 1 millisecond. This is needed because while the DataForm is generated via JSON object the component will need some more time to create the native instance of the created editors.

Regarding the second question. Indeed the return value from the  event will contain an editor property, however, this property will not point to the runtime generated editors and to handle this case you should get every editor by its name and to attach the style via accessing its propertyEditorStyle.

Indeed similar feature for an event which is fired while all editors are loaded will usefully. You could log it in our feedback repository, where you could provide more info about this feature and what you expected as a final result.


About your last question. The main idea while building the DataForm component was to create generate it only while using XML or HTML code, which also is the recommended way. JSON generator was added as an extra feature, which is still improving. That is the reason why the most of the examples are demonstrated via XML definitions. It would help if you provide more info about what you are trying to achieve a final result for the editor's style. Also for further help, I would suggest using our forum or StackOverflow thread.

Regards,
nikolay.tsonev
Progress Telerik
Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
Tags
DataForm
Asked by
Robert
Top achievements
Rank 1
Answers by
Deyan
Telerik team
Nianwei
Top achievements
Rank 1
Nikolay Tsonev
Telerik team
Share this question
or