Closed AyWa closed 7 years ago
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.
@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.
@VladimirAmiorkov @NathanWalker Yeah exactly, I am talking about ReactiveFormsModule FormBuilder
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:
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
@clarenceh This looks great! Can you point me to an article describing what's needed for value accessors in order to support formControlName
?
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:
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 { }
<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
π on this, definitely a great addition to the codebase
I tried it out, and really the formControlName selector does the trick - my FormGroup got populated correctly. Pushed a PR with that.
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.
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.
@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. π
Hello !
I have been unsuccessfully trying for 2 days to implement reactive form in Nativescript.
I have just written a simple component :
export class HeroDetailComponent {
name = new FormControl();
}
with a simple template :
<Label text="Hero Detail"></Label>
<TextField [formControl]="name"></TextField>
<Label text="{{ name.value | json }}"></Label>
<Label text="{{ name.status | json }}"></Label>
-> I have the error "Error: No value accessor for form control with unspecified name attribute"
if I change the textfield row to add ngDefaultControl :
<TextField [formControl]="name" ngDefaultControl></TextField>
it works BUT there is no synchronisation, if I fill the form on app, {{ name.value }} still displays null
Did I miss something ?? Do you have some working code ?
Thanks ! serge
I've been using it since 2.5--but only with FormBuilder. Your class would be like:
export class HeroDetailComponent {
public heroForm: FormGroup;
constructor(private fb: FormBuilder){
this.heroForm = this.fb.group({
"name": ["", [Validators.required]]
});
}
}
Then your template would be:
<StackLayout [formGroup]="heroForm">
<TextField formControlName="name"></TextField>
</StackLayout>
Edit to fix formatting.
Looks identical to the versions that I use. Like I said, I've never tried with just a form control, I've always done a FormGroup (obviously with the [formGroup]= attribute set), and I haven't had any issues.
And you used the exact code I posted?
Hi,
I restarted from scratch to be sure not to have missed anything ! Start by lauching commands:
tns create form-test --template nativescript-template-ng-tutorial
cd form-test
tns run android
-> lauch app, everything fine
create file app/hero-detail.component.ts with code:
import { Component } from "@angular/core";
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: "hero-detail",
template: `
<StackLayout [formGroup]="heroForm">
<TextField formControlName="name"></TextField>
</StackLayout>
`
})
export class HeroDetailComponent {
public heroForm: FormGroup;
constructor(private fb: FormBuilder){
this.heroForm = this.fb.group({
"name": ["", [Validators.required]]
});
}
}
change my app.module.ts (add ReactiveFormsModule and HeroDetailComponent) to:
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from "./app.component";
import { HeroDetailComponent } from './hero-detail.component';
@NgModule({
declarations: [AppComponent, HeroDetailComponent],
bootstrap: [AppComponent],
imports: [NativeScriptModule, ReactiveFormsModule],
schemas: [NO_ERRORS_SCHEMA],
})
export class AppModule {}
and my app.component.ts to:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
template: `
<ActionBar title="My App"></ActionBar>
<hero-detail></hero-detail>
`
})
export class AppComponent {
// Your TypeScript logic goes here
}
my package.json file look like :
"nativescript": {
"id": "org.nativescript.formtest",
"tns-android": {
"version": "2.5.0"
}
},
"dependencies": {
"@angular/common": "2.4.3",
"@angular/compiler": "2.4.3",
"@angular/core": "2.4.3",
"@angular/forms": "2.4.3",
"@angular/http": "2.4.3",
"@angular/platform-browser": "2.4.3",
"@angular/platform-browser-dynamic": "2.4.3",
"@angular/router": "3.4.3",
"nativescript-angular": "1.4.0",
"nativescript-theme-core": "~1.0.2",
"reflect-metadata": "~0.1.8",
"rxjs": "~5.0.1",
"tns-core-modules": "2.5.0"
},
still have the error:
Error: No value accessor for form control with name: 'name'
@SD-Lab missing import of NativeScriptFormsModule
Thanks !!!! works now ... π very hard to find this basic error with debug message ...
I've done all of the above steps but it's still not working.. I get no errors but the value of the form doesn't change when the input value does. I've described this over on the forums: https://discourse.nativescript.org/t/unable-to-get-reactive-forms-working/929
@chrillewoodz I have created a simple demo on this. You can find it in Github below: https://github.com/skywidesoft/ns-formcontrol-demo Hope this help Clarence
@clarenceh I don't see how that is any different from what I've got: https://github.com/andresfleat/native-app/tree/sprint1
@chrillewoodz You are using the versions:
@clarenceh Is it the nativescript-cli that I have to update to get the latest?
@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?
@chrillewoodz Yes, it's the first steps. The high level steps are as follows:
npm install -g nativescript
tns info
to check what update is availabletns update
to update NS packagesnpm install
to update the npm packages@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?
@clarenceh I also tried the exact same code which you use and that doesn't work as well. With the same versions on everything.
@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: https://github.com/NativeScript/nativescript-angular/issues/735 Something behind the scenes must be happening causing it to break.
@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.
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?
@codeback focus and blur event are being implemented on core-modules so after that i think touched state can be implemented ref: #3889
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.
@sis0k0 can you take a look at this ?
Discussion moved to #804
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