Nativescript Delete button not showing in RadListView with swipecell - nativescript

Well going through {N} tutorial I want to achieve this :
But I have trouble showing this delete button.
There is no problem with the image it shows well somewhere else and I also tried putting a Label instead but same result.
Rad Listview component :
<RadListView row="1" [items]="groceryList"
swipeActions="true" (itemSwipeProgressStarted)="onSwipeCellStarted($event)">
<ng-template let-item="item">
<Label [text]="item.name" class="p-15"></Label>
</ng-template>
<GridLayout *tkListItemSwipeTemplate columns="*, auto">
<StackLayout id="delete-view" col="1" (tap)="delete($event)" class="delete-view">
<Image src="~/images/delete.png" ></Image>
</StackLayout>
</GridLayout>
</RadListView>
CSS :
.delete-view {
background-color: #CB1D00;
padding: 20;
}
.delete-view Image {
color: white;
height: 25;
}
TS
onSwipeCellStarted(args: ListViewEventData) {
var swipeLimits = args.data.swipeLimits;
var swipeView = args.object;
var rightItem = swipeView.getViewById<View>("delete-view");
swipeLimits.right = rightItem.getMeasuredWidth();
swipeLimits.left = 0;
swipeLimits.threshold = rightItem.getMeasuredWidth() / 2;
}
delete(args: ListViewEventData) {
let grocery = <Grocery>args.object.bindingContext;
this.groceryService.delete(grocery.id)
.subscribe(() => {
let index = this.groceryList.indexOf(grocery);
this.groceryList.splice(index, 1);
});
}
Deletion feature works well but all what i am getting when swiping is this :
What am I getting wrong here ?

I spent several days earlier this month wrestling with similar issues with RadListView, especially on iOS. It seems to defy logic. I ended up using a negative padding to get to where I could see my labels and icons. If that doesn't help, try removing height: from your css.

Related

Force view to redraw after setting platform specific attributes

I have the following hack that draws drop shadows for the various elements that I have:
<template>
<Page>
<TabView>
<TabViewItem title="Tab 1">
<StackLayout #loaded="addShadow">
<Label text="This box does have a shadow." />
</StackLayout>
</TabViewItem>
<TabViewItem title="Tab 2">
<StackLayout>
<Label text="This box doesn't have a shadow." />
</StackLayout>
</TabViewItem>
</TabView>
</Page>
</template>
<script>
export default {
methods: {
addShadow(event) {
if (event.object.ios) {
event.object.ios.layer.masksToBounds = false;
event.object.ios.layer.shadowOpacity = 0.5;
event.object.ios.layer.shadowRadius = 5.0;
event.object.ios.layer.shadowColor = new Color('#000000').ios.CGColor;
event.object.ios.layer.shadowOffset = CGSizeMake(0.0, 2.0);
}
}
}
}
</script>
<style scoped>
StackLayout {
background: #ffffff;
padding: 16;
margin: 16;
}
</style>
However, while the shadow looks perfect, it does not initially appear when the tab is first accessed. I have to first visit the second tab, and only after returning to the first tab, does the drop shadow get drawn.
I assume this is because I need to invoke something to redraw the layer after adding the shadow, but I cannot figure out how to do that. I've tried event.object.ios.layer.setNeedsDisplay() but it has no effect.
How can I ensure the shadow displays on the first tab render?

Radio Buttons in Nativescript

How to implement RadioButtons in Nativescript + Angular?
I have tried the RadioButton plugin but it has error during compile time.
I have seen a post on stackoverflow stating to use font-awesome but it seems far more difficult to group the radio buttons.
Is it that I am ignoring any other simple method to create UI for something like this :
Label => Question: Select the fruit you like the most?
Radio 1 : Mango
Radio 2 : Apple
Radio 3 : Kiwi
Radio 4 : Banana
Any help in creating such interface?
Using Nativescript 5.0
Try nativescript-checkbox plugin, setting the boxType to circle will give you radio button style. For Grouped Radio Buttons, simply uncheck other radio buttons in group when one is selected.
I am able to achieve it using the Switch property isUserInteractionEnabled.
btw, I use Nativescript-angular.
This will enable interaction with a Switch only if the selected value is different:
<Switch [checked]="selectedValue === 'Mango'" isUserInteractionEnabled="{{ selectedValue !== 'Mango' }}"></Switch>
After looking around and observing several popular ecommerce apps, I found "Dialog box with List" method suitable as common user is comfortable with it.
I have decided to follow this : https://docs.nativescript.org/angular/ui/ng-ui-widgets/dialogs
Meantime, I will be still happy to see pure radio button kind of interface for Nativescript which is good for close group apps having user base with technical background as against retail users.
After trying multiple plugins (all outdated regarding todays angular and nativescript versions). I've decided to try my own solution, which is using the Button nativescript component to emulate the radiobutton behaviour.
The style needs improving, but the basic behaviour is there.
To achieve this, I've created a generic component which I can use anywhere I need it.
Here is its code:
import { Component, Input } from "#angular/core";
import { RadioBtnChoice } from "./radio-btn-form-input.model";
#Component({
selector: "radio-btn-form-input",
templateUrl: "./radio-btn-form-input.component.html",
styleUrls: ["./radio-btn-form-input.component.scss"]
})
export class RadioBtnFormInputComponent {
#Input() choicesRadioBtns: RadioBtnChoice[];
constructor() {}
ngOnInit(): void {}
toggleSelected(choice: RadioBtnChoice): void {
this.choicesRadioBtns.forEach(choice => {
choice.isSelected = !choice.isSelected;
});
console.log(`onTapChangeValue changed value to: ${choice.name}, ${choice.value}, ${choice.isSelected} `);
}
}
.radio-btn {
padding-top: 5px;
padding-right: 20px;
padding-bottom: 5px;
padding-left: 20px;
border-width: 2px;
background-color: #ddd;
margin: 0;
}
.radio-btn.selected {
border-top-color: #555;
border-left-color: #555;
border-right-color: #CCC;
border-bottom-color: #CCC;
background-color: #bbbbbb;
}
<StackLayout orientation="horizontal">
<template *ngFor="let choice of choicesRadioBtns">
<Button text="{{choice.name}}" (tap)="toggleSelected(choice)"
class="radio-btn {{choice.isSelected ? ' selected' : ''}}">
</Button>
</template>
</StackLayout>
This is the model for the radiobuttons inputs:
export interface RadioBtnChoice {
name: string;
value: any;
isSelected: boolean;
}
And this is the form using it:
export class FormUsingRadioButtonsComponent implements OnInit {
public individual: Individual;
public SexType = SexType;
public sexChoicesRadioBtns: RadioBtnChoice[];
constructor() {
this.sexChoicesRadioBtns = [
<RadioBtnChoice> {
name: "male",
value: SexType.M,
isSelected: true
},
<RadioBtnChoice> {
name: "female",
value: SexType.F,
isSelected: false
}
];
}
}
<Scrollview orientation="vertical">
<StackLayout orientation="vertical">
<StackLayout class="input-field">
<Label text="sex" class="input-label"></Label>
<radio-btn-form-input [choicesRadioBtns]="sexChoicesRadioBtns" class="input"></radio-btn-form-input> <------------- Here it is
</StackLayout>
<StackLayout class="input-field">
<TextField class="input" hint="name" keyboardType="" autocorrect="false" autocapitalizationType="none">
</TextField>
</StackLayout>
<StackLayout class="input-field">
<TextField class="input" hint="surname" keyboardType="" autocorrect="false" autocapitalizationType="none">
</TextField>
</StackLayout>
<Button text="Add individual" class="-primary input-field"></Button>
</StackLayout>
</Scrollview>

borderColor and borderRadius styles not being applied to a StackLayout

I am trying to create a border-radius and border-color around a StackLayout but for some reason the styles doesn't get applied... I am using the Nativescript core-light theme, not sure if that can override my inline styles? Any idea what i'm doing wrong?
my code:
<StackLayout borderRadius="5px" borderColor="blue">
<Label class="body" [text]="'Description: ' + product.Description"></Label>
<Label class="body" [text]="'POS Description: ' + product.POSDescription"></Label>
<Label class="body" [text]="'POS price: R' + product.POSPrice"></Label>
<Label class="body" [text]="'Stock On Hand: ' + product.StockOnHand"></Label>
</StackLayout>
You need to set explicitly borderWidth and your code will work.
e.g.
<StackLayout borderRadius borderWidth="2" borderRadius="15" borderColor="blue">
Notice that I am using DPs (device independent pixels) instead of px which in the mobile world with different screen densities and resolutions should be the better approach.
You can also use CSS for your borders
e.g.
.borders {
border-width: 2;
border-color: red;
border-radius: 20;
}

Dynamic GridLayout in nativescript with angular 2

I'm very new to Nativescript and Angular and it's my first stab at mobile app development, so please bear with me.
I'm trying to create a basic app with Angular2 and Nativescript. What I'm trying to do, is to display 3 buttons at the bottom of the screen when the app starts (these are created dynamically on initialisation). Once you click any of these buttons, I want this row to be moved up and a second row of buttons to appear. The transition should be animated.
In the first approach I tried I couldn't add the GridLayout to my DockLayout.
The home.html file
<DockLayout #container stretchLastChild="false">
</DockLayout>
the home.component.ts file snippet
export class HomePage implements OnInit {
#ViewChild("container") container: DockLayout;
constructor(private _router: Router, private page: Page) {
var view = new View();
}
ngOnInit() {
this.page.actionBarHidden = true;
this.page.backgroundImage = this.page.ios ? "res://background_large_file.jpg" : "res://background_large_file";
console.dir(this.container);
//Create the grid layout on the page
var bottomNav = new GridLayout();
//Add the GridLayout Columns
bottomNav.addColumn(new ItemSpec(1, GridUnitType.auto));
bottomNav.addColumn(new ItemSpec(1, GridUnitType.auto));
bottomNav.addColumn(new ItemSpec(1, GridUnitType.auto));
//Add the GridLayout Row
bottomNav.addRow(new ItemSpec(1, GridUnitType.auto));
//Create the buttons
var FButton = new Button();
FButton.text = "F";
var BButton = new Button();
BButton.text = "B";
var CButton = new Button();
CButton.text= "C";
//Position the buttons
FButton.set('row', '0');
FButton.set('col', '0');
BButton.set('row', '0');
BButton.set('col', '1');
CButton.set('row', '0');
CButton.set('col', '2');
bottomNav.addChild(FButton);
bottomNav.addChild(BButton);
bottomNav.addChild(CButton);
//Attempt to add to DockLayout container
--This is the part I can't get working
}
}
The other approach I was considering would be to hardcode my template and only show the first row. On tap of one of the buttons in the first row I'd move it up and fade in the second row. I couldn't get the reference to the GridLayouts on the page to allow me to do this. I'm thinking I might need to use "let container = this.container;" but am a bit unsure on this.
The home.html file
<DockLayout #container stretchLastChild="false">
<GridLayout #second_row columns="*, *, *" rows="auto" dock="bottom" class="choices hidden">
<Button text="M" row="1" col="0"></Button>
<Button text="F" row="1" col="1"></Button>
<Button text="D" row="1" col="2"></Button>
</GridLayout>
<GridLayout #initial_row columns="*, *, *" rows="auto" dock="bottom" class="choices initial">
<Button text="F" row="0" col="0" (tap)="showF()"></Button>
<Button text="B" row="0" col="1" (tap)="showB()"></Button>
<Button text="C" row="0" col="2" (tap)="showC()"></Button>
</GridLayout>
</DockLayout>
The home.component.ts file
export class HomePage implements OnInit {
#ViewChild("container") container: DockLayout;
constructor(private _router: Router, private page: Page) {
var view = new View();
}
ngOnInit() {
this.page.actionBarHidden = true;
}
showC() {
let container = <View>this.container;
container.animate({
opacity: 1,
duration:200
});
console.log('in here');
}
}
The final layout I'm aiming for is (any taps on the new row of buttons - #second_row - will navigate off to other pages once I set up on tap events and routing):
<DockLayout #container stretchLastChild="false">
<GridLayout #second_row columns="*, *, *" rows="auto" dock="bottom" class="choices hidden">
<Button text="M" row="1" col="0"></Button>
<Button text="F" row="1" col="1"></Button>
<Button text="D" row="1" col="2"></Button>
</GridLayout>
<GridLayout #initial_row columns="*, *, *" rows="auto" dock="bottom" class="choices initial">
<Button text="F" row="0" col="0" (tap)="showF()"></Button>
<Button text="B" row="0" col="1" (tap)="showB()"></Button>
<Button text="C" row="0" col="2" (tap)="showC()"></Button>
</GridLayout>
</DockLayout>
I would appreciate any help and advice on the subject.
Thanks in advance!
I would suggested you to use NativeScript Angular translate animation. With its help you could move up the first GridLayout and to show the next one. You could review my sample project here .In regard to that you could also review below attached articles.
http://docs.nativescript.org/angular/ui/animation.html
http://docs.nativescript.org/angular/tutorial/ng-chapter-4
http://docs.nativescript.org/angular/tutorial/ng-chapter-0
For your first example to add your new gridlayout to your page:
page.content = bottomNav;
Would do the trick.

Want a textView or textField in Native Script XML without bottom border

The default textbox has a bottom border.
How can I get a textView or textField in Native Script XML without that bottom border?
Based on the suggestion by Nikolay, the following should do it in the stylesheet
background-color: transparent;
border-color: transparent;
One possible decision could be to remove textfield and textview border-bottom is to set background color. This will color up the border too. I will give you an example bellow
main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo">
<StackLayout backgroundColor="red">
<Label text="Tap the button" class="title"/>
<Button text="TAP" tap="{{ onTap }}" />
<Label text="{{ message }}" class="message" textWrap="true"/>
<TextField hint="" id="tfield" text="tests textfield"/>
<TextView hint="" id="tview" text="tests textView" editable="true" style="border-color:white; " />
</StackLayout>
</Page>
main-page.js
var main_view_model_1 = require("./main-view-model");
var color_1 = require('color');
// Event handler for Page "navigatingTo" event attached in main-page.xml
function navigatingTo(args) {
// Get the event sender
var page = args.object;
var tf = page.getViewById("tfield");
tf.borderColor = new color_1.Color("#ffffff");
tf.backgroundColor = new color_1.Color(100, 255, 0, 0);
var tv = page.getViewById("tview");
tv.borderColor = new color_1.Color("#ffffff");
tv.backgroundColor = new color_1.Color(100, 255, 0, 0);
page.bindingContext = new main_view_model_1.HelloWorldModel();
}
exports.navigatingTo = navigatingTo;

Resources