Nativescrit TexField focus - nativescript

I'm battling to make the textfield when selected to be above the keyboard:
Tried this code:
HTML:
<StackLayout class="input-field">
<Label text="Postal Code" class="label font-weight-bold m-b-5"
</Label>
<TextField #postalCode id="postalCode" (tap)="onFocus()"
[(ngModel)]="model.address.postal_code" class="input" ></TextField>
</StackLayout>
TS:
onFocus() {
let postalCode = <TextField> this.postalCode.nativeElement;
console.log(postalCode.focus());
}

If you want to push the textfield up when the keyboard is selected, open App_Resources/Android/AndroidManifest.xml and add this to the <activity: android:windowSoftInputMode="stateHidden|adjustResize".

Related

NativeScript - Change Label into TextView/TextField with a Button

I am learning to make an app in NativeScript (Angular 2). In my item page, I want to have a button so that when I press it, I can change Label into TextView/TextField for editing the information of the item.
I know that I can use editable in TextView but I still want to know if it is feasible to have the button with that functionality. Thank you !!
item.component.html:
<StackLayout>
<Label class="h3" text="Name: {{ item.get_name() }}" textWrap="true">
</Label>
<Label class="h3" text="Credit: {{ item.get_credit() }}"></Label>
<Button class="btn" text="Edit" (tap)="change()"></Button>
</StackLayout>
<!-- After pressing the button -->
<StackLayout>
<TextView class="h3" [text]="item.get_name()" textWrap="true">
</TextView>
<TextView class="h3" [text]="item.get_credit()"></TextView>
<Button class="btn" text="Save" (tap)="change()"></Button>
</StackLayout>
This can be done in many ways, but one common way is by changing visibility of control and binding it to a variable / property in the code behind.
in your component html:
Then on your component ts or code-behind you can handle it in the change method:
class MyComponentSample {
isLabelMode: boolean = true; // Set to true if you want label to show by default or false if TextView as default
change() {
this.isLabelMode = !isLabelMode; // Basically you are toggling the mode here.
}
}

Different colors for text on same label using string format

I have a xaml code as below:
<Label Text="{Binding Id,StringFormat='{0} *'}" HorizontalOptions="StartAndExpand" HorizontalTextAlignment="Center">
here,is this possible to get Id is in one color and * is in another color?
You can use a FormattedText, like this:
<Label HorizontalTextAlignment="Center">
<Label.FormattedText>
<FormattedString>
<Span Text="" TextColor="Red"/>
<Span Text="" TextColor="Blue"/>
</FormattedString>
</Label.FormattedText>
</Label>
The problem with this is that it doesn't support bindings. However, you can set the text from the page code behind. If it doesn't work for you, simply use two labels within a horizontal StackLayout.
UPDATE:
Now spans are bindable! https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/label#formatted-text
In Xamarin.IOS
Use Like this,
var attributedText = new NSMutableAttributedString("Complete it in " + HowManySecondsString + " to reach");
var range = attributedText.MutableString.LocalizedStandardRangeOfString(new NSString(HowManySecondsString));
attributedText.AddAttribute(UIStringAttributeKey.ForegroundColor, UIColor.Red, range);
label.AttributedText = attributedText;

NativeScript/Angular - Reactive form not working when using actionbar

First I implemented the code below.
app.component.html
<StackLayout [formGroup]="form">
<label text="Name"></label>
<TextField formControlName="Name"></TextField>
<label text="Last Name"></label>
<TextField formControlName="LastName"></TextField>
<button text="save" (tap)="save()"></button>
</StackLayout>
app.component.ts
public form: FormGroup;
constructor(private fb: FormBuilder){
this.form = this.fb.group({
"Name": ["", [Validators.required]],
"LastName": ["", [Validators.required]]
});
}
public save(){
console.log(JSON.stringify(this.form.value));
}
When I run the code above, it's everything alright. I get name and lastname correctly.
The problem occurs when I try to add an action bar to this code.
app.component.html
<ActionBar title="New" class="action-bar">
<ActionItem text="save" (tap)="save()"></ActionItem>
</ActionBar>
<StackLayout [formGroup]="form">
<label text="Name"></label>
<TextField formControlName="Name"></TextField>
<label text="Last Name"></label>
<TextField formControlName="LastName"></TextField>
<button text="save" (tap)="save()"></button>
</StackLayout>
The app.component.ts remains the same.
When I run this code and tap the button inside stacklayout I get name and lastname correctly but when I tap the ActionItem I get an empty string for both name and lastname. Am I missing something?
Your code looks just fine - in fact I have re=-tested it with this test application and everything works as expected on my side.
Side note: If testing on iOS keep in mind that subsequent console logs can be printed only once if they are identical. (this) so it might be that it appears that the log is not printed when in fact the action is done.

Nativescript Listview with header and scroll entire page

I am using ListView with Header portion on top of it like below,
<StackLayout>
<StackLayout height="200">
<Label text="Header content goes in this section"></Label>
<StackLayout>
<ListView [items]='posts'>
<!-- template items goes here -->
</ListView>
</StackLayout>
When we scroll to list the header is sticky in this case.
Is there a option that scroll overrides header also ?.I mean that header also part of scroll.
Fr Angular-2 application you can now use tkTemplateKey deirective and create your own headers, footers, groups and other custom list-view elements.
Example can be found here
Here is the code for a list-view with header and groups.
page.component.html
<ListView [items]="countries" [itemTemplateSelector]="templateSelector" (itemTap)="onItemTapFirstList($event)" class="list-group" separatorColor="white">
<ng-template nsTemplateKey="header" let-header="item">
<Label [text]="header.name" class="list-group-item h3 bg-primary" isUserInteractionEnabled="false" color="white" fontSize="24"></Label>
</ng-template>
<ng-template nsTemplateKey="footer" let-footer="item">
<Label [text]="footer.name" class="list-group-item" backgroundColor="gray"></Label>
</ng-template>
<ng-template nsTemplateKey="cell" let-country="item">
<StackLayout class="list-group-item">
<Label [text]="country.name" class="list-group-item-heading"></Label>
<Label [text]="country.desc" class="list-group-item-text" textWrap="true"></Label>
</StackLayout>
</ng-template>
</ListView>
page.component.ts
#Component({
moduleId: module.id,
templateUrl: "./multi-line-grouped.component.html",
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MultiLineGroupedListViewExampleComponent implements OnInit {
public countries: Array<any> = [];
public templateSelector = (item: any, index: number, items: any) => {
return item.type || "cell";
}
ngOnInit() {
for (let i = 0; i < mockedCounties.length; i++) {
this.countries.push(mockedCounties[i]);
}
}
onItemTapFirstList(args: ItemEventData) {
console.log(args.index);
}
}
Not sure if there's another way, but one way could be moving the header inside the listview. For that to work it needs to be in the posts Array, so you may want to transform that into some sort of wrapping class that can contain eiter a header or item row. Then create two templates inside the listview that depending on the template key render a header or an item.
For details on templates, see https://docs.nativescript.org/cookbook/ui/list-view#define-multiple-item-templates-and-an-item-template-selector-in-xml
You can use *ngFor creating the list.Here is the sample code for doing this.
<ScrollView>
<StackLayout>
//define your header over here
<Label text="hey header"></Label>
<StackLayout *ngFor="let item of <Array>">
<GridLayout columns="4*,*" rows="*,">
<Label row="0" col="0" text="hey label"></Label>
</GridLayout>
<StackLayout>
<StackLayout>
</ScollView>

Is it possible to get children in custom component?

Is it possible to get children in custom component?
<myCustomComponent>
<Label #id1 text="ID 1"></Label>
<Label #id2 text="ID 2"></Label>
</myCustomComponent>
Is there a way to get the reference of these two Lable to get them positioned in a GridLayout in my custom component?
Apart from the option with getViewById() there are several options to see the a layout's children or their index and also to add, remove, insert and reset children.
e.g.
page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<StackLayout id="st" class="p-20">
<Label id="lbl-title" text="Tap the button" class="h1 text-center"/>
<Button text="TAP" tap="{{ onTap }}" class="btn btn-primary btn-active"/>
<Label text="{{ message }}" class="h2 text-center" textWrap="true"/>
</StackLayout>
</Page>
page.ts
let page = <Page>args.object;
let stack = <StackLayout>page.getViewById("st");
let label = <Label>page.getViewById("lbl-title");
console.log("page.content: " + page.content); // page.content: StackLayout<st>#file:///app/main-page.xml:19:5;
console.log("stack.getChildrenCount(): " + stack.getChildrenCount()) // 3
console.log("stack.getChildAt(1): " + stack.getChildAt(1)); // stack.getChildAt(1): Button(5)#file:///app/main-page.xml:21:9;
console.log("stack.getChildIndex(label): " + stack.getChildIndex(label)); // 0
console.log("stack.parent: " + stack.parent); // stack.parent: Page(1)#file:///app/main-page.xml:7:1;
var newlabel = new Label();
newlabel.text = "new Label";
stack.addChild(newlabel);
More about all supported methods here
The view class has a getViewById() method for this purpose.
In my-component.xml:
<StackLayout loaded="onLoaded">
<Label id="label1" text="ID 1" mycustomattribute="Hi there."></Label>
<Label id="label2" text="ID 2"></Label>
</StackLayout>
In my-component.js:
exports.onLoaded = function(args) {
let view = args.object;
let label1 = view.getViewById('label1');
console.log(label1.mycustomattribute);
// > "Hi there."
};

Resources