nativescript-ui-feedback icon indicating copy to clipboard operation
nativescript-ui-feedback copied to clipboard

[RadDataForm] Setting and Getting DataForm Entity value by accessing directly the property

Open bnbs opened this issue 8 years ago • 8 comments

Did you verify this is a real problem by searching Stack Overflow?

Yes

Tell us about the problem

I want to update some source value but it's not working

Which platform(s) does your issue occur on?

android

My code:

test.component.ts

import { Client } from './client';
import { Component, OnInit } from '@angular/core';

@Component({
    selector: "test",
    templateUrl: "test.component.html",
})

export class TestComponent implements OnInit { 

    private _client: Client;

    constructor(){

    }

    ngOnInit(){
        this._client = new Client("Will", 21, "street test");
    }

    get TestClient(){
        console.log(JSON.stringify(this._client));
        return this._client;
    }

    public changeName(){
        this._client.name = "Michael";
    }
}

test.component.html

<RadDataForm [source]="TestClient">
</RadDataForm>
<button text="Change Name" (tap)="changeName()" height="40"></button>

client.ts

export class Client{
    public name: string;
    public age: number;
    public address: string;

    constructor(
        name: string,
        age: number,
        address: string
    ){
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

app.module.ts

import { TestComponent } from './test.component';
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { AppRoutingModule } from "./app.routing";
import { AppComponent } from "./app.component";

import { NativeScriptUIDataFormModule } from "nativescript-pro-ui/dataform/angular";
import { NativeScriptFormsModule } from "nativescript-angular/forms";

@NgModule({
    bootstrap: [
        AppComponent
    ],
    imports: [
        NativeScriptUIDataFormModule,
        NativeScriptFormsModule,
        NativeScriptModule,
        AppRoutingModule
    ],
    declarations: [
        AppComponent,
        TestComponent
    ],
    providers: [
    ],
    schemas: [
        NO_ERRORS_SCHEMA
    ]
})

export class AppModule { }

package.json

{
	"description": "NativeScript Application",
	"license": "SEE LICENSE IN <your-license-filename>",
	"readme": "NativeScript Application",
	"repository": "<fill-your-repository-here>",
	"nativescript": {
		"id": "org.nativescript.testeDataForm",
		"tns-android": {
			"version": "3.2.0"
		}
	},
	"dependencies": {
		"@angular/animations": "~4.4.1",
		"@angular/common": "~4.4.1",
		"@angular/compiler": "~4.4.1",
		"@angular/core": "~4.4.1",
		"@angular/forms": "~4.4.1",
		"@angular/http": "~4.4.1",
		"@angular/platform-browser": "~4.4.1",
		"@angular/platform-browser-dynamic": "~4.4.1",
		"@angular/router": "~4.4.1",
		"nativescript-angular": "~4.4.0",
		"nativescript-pro-ui": "^3.1.4",
		"nativescript-theme-core": "~1.0.2",
		"reflect-metadata": "~0.1.8",
		"rxjs": "~5.4.2",
		"tns-core-modules": "~3.2.0",
		"zone.js": "~0.8.2"
	},
	"devDependencies": {
		"babel-traverse": "6.4.5",
		"babel-types": "6.4.5",
		"babylon": "6.4.5",
		"lazy": "1.0.11",
		"nativescript-dev-typescript": "~0.5.0",
		"typescript": "~2.4.2"
	}
}

When I tap the button the name is not changing Did I miss something?

bnbs avatar Oct 17 '17 16:10 bnbs

Hi @brunaaanayara, Thank you for contacting us. At this time changing the source by accessing directly the property is not supported. The way you could change the values is to replace the source for the RadDataForm component. For example: HTML

<StackLayout>
	<Button text="getInfo" (tap)="onTap()"></Button>
	

<RadDataForm #myCommitDataForm id="testdataform" [source]="ticketOrder" tkExampleTitle tkToggleNavButton>
	<TKEntityProperty tkDataFormProperty name="movie" displayName="Movie Name" index="0" [converter]="movieConverter" [valuesProvider]="movieNames">
		<TKPropertyEditor tkEntityPropertyEditor type="Picker"></TKPropertyEditor>
	</TKEntityProperty>
	<TKEntityProperty tkDataFormProperty name="date" index="1">
		<TKPropertyEditor tkEntityPropertyEditor type="DatePicker"></TKPropertyEditor>
	</TKEntityProperty>
	<TKEntityProperty tkDataFormProperty name="time" index="2">
		<TKPropertyEditor tkEntityPropertyEditor type="TimePicker"></TKPropertyEditor>
	</TKEntityProperty>
	<!-- >> angular-dataform-editors-html -->
	<TKEntityProperty tkDataFormProperty name="type" displayName="Type" index="3" valuesProvider="2D, 3D">
		<TKPropertyEditor tkEntityPropertyEditor type="SegmentedEditor"></TKPropertyEditor>
	</TKEntityProperty>
	<!-- << angular-dataform-editors-html -->
	<!-- >> angular-dataform-property-readonly-html -->
	<TKEntityProperty tkDataFormProperty name="price" index="4" readOnly="true">
		<TKPropertyEditor tkEntityPropertyEditor type="Decimal"></TKPropertyEditor>
	</TKEntityProperty>
	<!-- << angular-dataform-property-readonly-html -->
	<TKEntityProperty tkDataFormProperty name="numberOfTickets" displayName="Number of Tickets" index="5">
		<TKPropertyEditor tkEntityPropertyEditor type="Stepper"></TKPropertyEditor>
	</TKEntityProperty>
	<TKEntityProperty tkDataFormProperty name="contactName" displayName="Contact Name" index="6">
		<TKPropertyEditor tkEntityPropertyEditor type="Text"></TKPropertyEditor>
	</TKEntityProperty>
	<TKEntityProperty tkDataFormProperty name="contactPhone" displayName="Contact Phone" index="7">
		<TKPropertyEditor tkEntityPropertyEditor type="Phone"></TKPropertyEditor>
	</TKEntityProperty>
	<TKEntityProperty tkDataFormProperty name="contactEmail" displayName="Contact Email" index="8">
		<TKPropertyEditor tkEntityPropertyEditor type="Email"></TKPropertyEditor>
	</TKEntityProperty>
	<TKEntityProperty tkDataFormProperty name="agreeTerms" displayName="I Agree with Terms" index="9">
		<TKPropertyEditor tkEntityPropertyEditor type="Switch"></TKPropertyEditor>
	</TKEntityProperty>
</RadDataForm>
</StackLayout>

TypeScript

import { Component, OnInit, ViewChild } from "@angular/core";
import { Movie } from "../data-services/movie";
import { MovieConverter } from "../data-services/movie-converter";
import { RadDataFormComponent  } from "nativescript-pro-ui/dataform/angular";
import {  RadDataForm } from "nativescript-pro-ui/dataform/";
import {Page} from "ui/page"

@Component({
    moduleId: module.id,
    selector: "tk-dataform-editors",
    templateUrl: "dataform-editors.component.html"
})
export class DataFormEditorsComponent implements OnInit {
    private _ticketOrder: TicketOrder;
    private _movies: Array<String>;
    @ViewChild('myCommitDataForm') myCommitDataFormComp: RadDataFormComponent;
 
    constructor(private page:Page) { }
 
    ngOnInit() {
        this._ticketOrder = new TicketOrder();
        this._movies = new Array<String>();
        this._movies.push("Zootopia");
        this._movies.push("Captain America");
        this._movies.push("The Jungle Book");
    }
 
    get ticketOrder() {
        return this._ticketOrder;
    }
 
    get movies() {
        return this._movies;
    }
 
    onTap(){
        
 
        var newtick = new TicketOrder();
        newtick.contactName="test";
        this._ticketOrder = newtick
    }
}
 
export class TicketOrder {
    public movie: string = "Zootopia";
    public date: string = "2016-04-06";
    public time: string = "20:00";
    public type: string = "2D";
    public price: number = 9.50;
    public numberOfTickets: number = 2;
    public contactName: string = null;
    public contactPhone: string = null;
    public contactEmail: string = null;
    public agreeTerms: boolean = false;
 
    constructor() {
    }
}

I logged this as a new feature and we will investigate if this could be implemented for the DataForm component. You could keep track on the issue for further info.

tsonevn avatar Oct 18 '17 09:10 tsonevn

This approach is not working for me. Maybe cause I use TKPropertyGroup. But If I reload source manually with reload() function, it is working. So here is my wrapper for it.

public reloadProperties(formId: string, sourceName: string, newValues: any = null) {
    let newObject = {};
    newObject = JSON.parse(JSON.stringify(this[sourceName]));

    if (newValues) {
        for (let k in newValues) {
            newObject[k] = newValues[k];
        }
    }

    this[sourceName] = newObject;
    this[formId].dataForm.reload();
}

So you can call it for your case as

onTap() {
    
     this.reloadProperties('myCommitDataFormComp', '_ticketOrder', {
        "contactName": "test",
        "contactPhone": "54564564564564"
    });

}

manigorsh avatar Oct 23 '17 15:10 manigorsh

this is such a crucial feature, updating source loses the focus on the controller.

mhmo91 avatar Jan 30 '18 14:01 mhmo91

Can you please update the documentation on this mode of operation in the mean time? I wasted a bunch of time searching for how to do this and playing with the code to figure it out. Also please update the title to include RadDataForm so this issue can be found more readily?

lonerzzz avatar Nov 20 '18 16:11 lonerzzz

Any updated on this?

We have some computed values in the form, we ended up separating the computed values to another dataform so that we could update them based on changes in original dataform.

yalva avatar Apr 14 '20 20:04 yalva

I am using nativescript with angluar application: The proposed solution does not work because the ui blocks the user when typing and also the field loses focus. The only way for the moment is to force the source's change within a setTimeout function. Is there a solution using an observable?

agallo73 avatar Jun 01 '20 14:06 agallo73

We ended up rewriting the app in flutter, personally I found nativescript-ui controls don't work for professional level apps, very restrictive and closed source etc.

yalva avatar Jun 01 '20 14:06 yalva

This is badly needed

zeejay09 avatar Mar 10 '22 07:03 zeejay09