Skip to content

FormBuilder to nativescript #526

Closed
Closed

Description

@AyWa

Hello everyone,

I used FormBuilder to my webapps, and now I am trying to use it to nativescript but I thinks it’s not possible because FormBuilder need an input.
Is it possible to make it works?

thanks

Activity

  1. VladimirAmiorkov commented on Nov 9, 2016

    @VladimirAmiorkov
    Contributor

    Hi @AyWa ,

    Can you share with us which FormBuilder application or service you are referring to so that we can take a closer look at the specifics of it. We do have a dedicated RadDataForm that is coming to {N} + Angular in the next official release (1.5.0) of nativescript-telerik-ui-pro plugin which has been designed and developed to work and feel as all {N} components on both iOS and Android. You can take a look at our non Angular online documentation for more information regarding the RadDataForm component, the Angular 2 support as stated above is coming in a couple of days.

    Keep in mind that NativeScript + Angular uses the well know web technology that we love but there is a difference in what is the end result, in web or hybrid technology the end result will be a WebView + HTML elements, in NativeScript you get truly native components which is the power of {N}. Having this in mind using a pure web HTML tools for creation of UI is not possible without embedding them inside the {N} application via WebViewer which has poor performance and does not create native components.

  2. NathanWalker commented on Nov 9, 2016

    @NathanWalker
    Contributor

    @VladimirAmiorkov pretty sure @AyWa is referring to ReactiveFormsModule FormBuilder:
    https://github.com/angular/angular/blob/2.1.2/modules/%40angular/forms/src/form_providers.ts#L26-L38
    http://blog.thoughtram.io/angular/2016/06/22/model-driven-forms-in-angular-2.html

    I have been wanting to submit a PR to make that API work with nativescript-angular. Should be doable and I've heard many people desiring same thing.

  3. AyWa commented on Nov 9, 2016

    @AyWa
    Author

    @VladimirAmiorkov @NathanWalker Yeah exactly, I am talking about ReactiveFormsModule FormBuilder

  4. clarenceh commented on Nov 25, 2016

    @clarenceh

    Hi everyone,

    I have developed Angular2 for web for some time, and starts to explore NativeScript with Angular2.

    I found this feature (NativeScript to support Angular2 Reactive Forms Module) is of great potential and really can help to simplify the development of form-base input page that requires more sophisticate data model processing and validation.

    Base on my understanding, the key thing to do to integrate with Reactive Forms Module is to implement Angular Form module's ControlValueAccessor interface. Which I found in nativescript-angular, the class base-value-accessor.ts already is doing this (it's also needed to support the [(ngModel)] binding).

    From the text-value-accessor.ts class, I found it has the following line:
    selector: "TextField[ngModel], textField[ngModel], text-field[ngModel], TextView[ngModel], textView[ngModel],

    So it only support the NativeScript UI fields with the ngModel directive.

    The ideal way is also to have it support the binding of a FromControl in the component. For example, instead of the following NS currently support:
    <TextField #usernameContainer id="username" class="mek-input" autocorrect="false" autocapitalizationType="none" [(ngModel)]="login.username" updateTextTrigger="focusLost" returnKeyType="next"> </TextField>

    I can write something like the following (just like the web version):
    <TextField #usernameContainer id="username" class="mek-input" autocorrect="false" autocapitalizationType="none" formControlName="username" returnKeyType="next"> </TextField>

    Note that the directive formControlName is used instead of the [(ngModel)] binding

    And then in the component code, I can use Angular's FormBuilder to create the control programmatically:
    this.username = new FormControl(this.login.username, [Validators.required, Validators.minLength(3), Validators.maxLength(40)]);

    Afterwards, the TextField will then "binded" to the FormControl, and Angular will take care of the data binding, validation, update the control's states (i.e. dirty, touched, valid, etc.), and others.

    This way can make the experience much more align with the web development flow and have the following benefits:

    • Validation logic can be defined in the component code (custom validator also possible)
    • Additional processing of data model become much easier
    • I can subscribe to the FormControl's valueChanges event
    • Testing can be implemented much more easily

    I think this feature can definitely help developers who is already adopting this Data Model Driven Form approach in developing web applications.

    I am very happy to help contribute to this feature. But as I am not that familiar with nativescript-angular and the in-depth details of Angular2, I may need some hint and guidance from your team.

    Any other comments are much welcome and I really want to see this feature available in NativeScript.

    Cheers
    Clarence

  5. hdeshev commented on Nov 29, 2016

    @hdeshev
    Contributor

    @clarenceh This looks great! Can you point me to an article describing what's needed for value accessors in order to support formControlName?

  6. clarenceh commented on Nov 30, 2016

    @clarenceh

    Hi @hdeshev,

    The following is an excellent article which describes how to implement a custom Angular2 form control:
    http://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html

    As currently the text-value-accessor.ts and others were implemented as an Angular Directive, which has the selector hard-coded to TextField[ngModel]..., etc. I believe can simply change the selector text to the following and test it out:
    selector: "TextField[ngModel],TextField[formControlName]...

    To test whether it works, can simply test with the following:

    • Create a project with tns
    • Modify the file app.module.ts as follows:
        import { NgModule } from "@angular/core";
        import { NativeScriptModule } from "nativescript-angular/platform";
        import { NativeScriptFormsModule } from "nativescript-angular/forms";
        import { ReactiveFormsModule } from '@angular/forms';
    
        import { AppComponent } from "./app.component";
    
        @NgModule({
            declarations: [AppComponent],
            bootstrap: [AppComponent],
            imports: [
                NativeScriptModule,
                NativeScriptFormsModule,
                ReactiveFormsModule
            ]
        })
        export class AppModule { }
    
    • In app.component.html, add a TextField and try to bind to a FromControl by name:
        <StackLayout class="p-20" [formGroup]="loginForm">
            <Label text="Tap the button" class="h1 text-center"></Label>
            <Button text="TAP" (tap)="onTap()" class="btn btn-primary btn-active"></Button>
            <Label [text]="message" class="h2 text-center" textWrap="true"></Label>
            <TextField formControlName="usernameControl"></TextField>
            <Label [text]="username" class="h2 text-center" textWrap="true"></Label>
        </StackLayout>
    

    Note that we also need to add a FormGroup to the binding, Angular2 form will need this

    • In app.component.ts, add logic to build the FormGroup and FormControl for the text field:
        import { Component, OnInit } from "@angular/core";
        import { AbstractControl, FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';
    
        @Component({
            selector: "my-app",
            templateUrl: "app.component.html",
        })
        export class AppComponent {
    
            public counter: number = 16;
    
            loginForm: FormGroup;
            usernameControl: AbstractControl;
            username = '';
    
            constructor(private fb: FormBuilder) {}
    
            ngOnInit() {
                this.loginForm = this.fb.group({
                    username: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(40)]]
                });
                this.usernameControl = this.loginForm.controls['username'];
            }
    
            public get message(): string {
                if (this.counter > 0) {
                    return this.counter + " taps left";
                } else {
                    return "Hoorraaay! \nYou are ready to start building!";
                }
            }
            
            public onTap() {
                this.counter--;
                this.username = this.usernameControl.value;
            }
        }
    

    Then test to run the application to see if it works or not.

    Currently, when I run the above code, I got the following error:

    CONSOLE ERROR file:///app/tns_modules/trace/trace.js:160:30: ns-renderer: Error in app.component.html:4:15 caused by: Cannot find control with name: 'usernameControl'
    

    I believe as currently the text field value accessor doesn't pick up the attribute "formControlName", so the binding not work and Angular doesn't found any property with ControlValueAccessor implemented.

    Hope this helps.
    Clarence

  7. dave-calleja commented on Nov 30, 2016

    @dave-calleja

    👍 on this, definitely a great addition to the codebase

  8. hdeshev commented on Dec 6, 2016

    @hdeshev
    Contributor

    I tried it out, and really the formControlName selector does the trick - my FormGroup got populated correctly. Pushed a PR with that.

  9. added this to the NS 2.5 milestone on Dec 6, 2016
  10. clarenceh commented on Dec 6, 2016

    @clarenceh

    Really glad to hear that and look forward for the NS 2.5 release so that we can start using it. Thanks a lot for the help.

  11. derekdon commented on Dec 13, 2016

    @derekdon

    Is there a way to test this ahead of the release? I thought using the next tag as described here https://docs.nativescript.org/releases/running-latest might give me this functionality or npm linking to a master clone of the nativescript-angular repo but neither seemed to work.

  12. coltcook commented on Jan 3, 2017

    @coltcook

    @derekdon I also have the same problem--was hoping to use this for a new feature. Now I have to choose between not using it or not implementing it and waiting for 2.5. 👎

  13. 8 remaining items

  14. chrillewoodz commented on Apr 3, 2017

    @chrillewoodz

    @clarenceh I don't see how that is any different from what I've got: https://github.com/andresfleat/native-app/tree/sprint1

  15. clarenceh commented on Apr 3, 2017

    @clarenceh

    @chrillewoodz You are using the versions:

    • tns-core-modules: 2.5.0
    • nativescript-angular: 1.4.0
      I am using:
    • tns-core-modules: 2.5.2
    • nativescript-angular: 1.5.1
      Suggest you to update the version and see if some bug about this feature had been fixed.
      Regards
      Clarence
  16. chrillewoodz commented on Apr 3, 2017

    @chrillewoodz

    @clarenceh Is it the nativescript-cli that I have to update to get the latest?

  17. coltcook commented on Apr 3, 2017

    @coltcook

    @chrillewoodz I'm not on a dev machine so I can't confirm, but if your issue is FormBuilder, at the very least you'll want to upgrade nativescript-angular.

    I thought the change @clarenceh POC'ed went in with 1.5, but I might be mistaken?

  18. clarenceh commented on Apr 3, 2017

    @clarenceh

    @chrillewoodz
    Yes, it's the first steps. The high level steps are as follows:

    1. Update Nativescript CLI
      npm install -g nativescript
    2. Update tns-core-modules in your project
      In your project root folder:
    • Run tns info to check what update is available
    • Run tns update to update NS packages
    1. Update nativescript-angular npm package in package.json
      In your project root folder:
    • Update nativescript-angular to version 1.5.1
    • Run npm install to update the npm packages
  19. chrillewoodz commented on Apr 3, 2017

    @chrillewoodz

    @clarenceh No luck after updating everything. The values are still not updating :( Have you managed to get it to work for you with the same project I linked?

  20. chrillewoodz commented on Apr 3, 2017

    @chrillewoodz

    @clarenceh I also tried the exact same code which you use and that doesn't work as well. With the same versions on everything.

  21. chrillewoodz commented on Apr 3, 2017

    @chrillewoodz

    @clarenceh I tried moving your code in your repo to inside a lazy loaded module and guess what, it broke. I've filed an issue about this here: #735 Something behind the scenes must be happening causing it to break.

  22. clarenceh commented on Apr 4, 2017

    @clarenceh

    @chrillewoodz I see. I personally will not try to use lazy loading in NativeScript with Angular and lazy loading. Cause although NS supports Angular, it's actually mapping the transpiled JS code to underlying native component in iOS and Android. So I wonder whether it will works with lazy loading module. In addition, not sure if there will be any performance gain even though I can use lazy loading.

  23. codeback commented on Apr 17, 2017

    @codeback

    It works fine except the control state 'touched', it is always false.

    The states dirty, pristine and valid are working well.

    Somebody has the same problem?

  24. danielgek commented on Apr 17, 2017

    @danielgek

    @codeback focus and blur event are being implemented on core-modules so after that i think touched state can be implemented ref: #3889

  25. manojdcoder commented on May 16, 2017

    @manojdcoder

    Looks like #3889 is closed with all required events implemented.

    But still with NativeScript 3.0 and Angular 4.1, touched remains false always. Never turns to true or ng-touched class is never added to the element nor ng-untouched is removed.

  26. danielgek commented on May 16, 2017

    @danielgek

    @sis0k0 can you take a look at this ?

  27. sis0k0 commented on May 17, 2017

    @sis0k0
    Contributor

    Discussion moved to #804

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions