display the value entered in table - angular5

creating table and displaying value on clicking submit button. The value to be displayed on submitting data
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app1';
private fieldArray: Array<any> = [];
private newAttribute: any = {};
addFieldValue() {
this.fieldArray.push(this.newAttribute)
this.newAttribute = {};
}
/* ngOnInit(){
console.log(this.fieldArray);
} */
}

You can maintain a recentlyAddedProducts list in the component class and push the newly added data in this list. Then render that list in the template like this:
Component class:
recenltyAddedProducts: Array<any> = [];
private fieldArray: Array<any> = [];
private newAttribute: any = {};
addFieldValue() {
this.fieldArray.push(this.newAttribute)
this.recenltyAddedProducts.push(this.newAttribute);
this.newAttribute = {};
}
Have your template setup like this:
<h3 style="color:darkmagenta" >Recently added products:</h3>
<div *ngFor="let p of recenltyAddedProducts">
<span>
{{p.productName}}
</span>
<span>
{{p.quantity}}
</span>
See the stackblitz showing the demo:
https://stackblitz.com/edit/angular-jvfmfe?file=app/button-overview-example.ts
You can update your code to show only last 3 recently added products.
EDIT
To show only one recent product do the following change:
Component class:
recenltyAddedProduct;
private fieldArray: Array<any> = [];
private newAttribute: any = {};
addFieldValue() {
this.fieldArray.push(this.newAttribute)
this.recenltyAddedProduct = this.newAttribute;
this.newAttribute = {};
}
Have a template like this:
<h3 style="color:darkmagenta" >Recently added products:</h3>
<span>
{{recenltyAddedProduct?.productName}}
</span>
<span>
{{recenltyAddedProduct?.quantity}}
</span>
To show in h3 tag have a template like this:
<h3 style="color:darkmagenta" >Recently added products: <span>
{{recenltyAddedProduct?.productName}}
</span>
<span>
{{recenltyAddedProduct?.quantity}}
</span></h3>

Use an ngIf that tests for the existence of the a selected product and databind the product name to the heading. Create a recentlySelected property on the component and onclick set the recentlySelected property to that value of the clicked product or product name.
<h3 style="color:darkmagenta" *ngIf="recentlySelected" >Recently added products:{{recentlySelected}}</h3>
Here is an example:
https://stackblitz.com/edit/angular-ngif-click-zdb9ng?file=app/app.component.html

Related

Vuejs :class not working as expected in template

The class binding is not working as expected using a template, as the image below shows:
I have a array with many categories and when the user click it has to filter, this i already did, for whose category he wants. My problem is that once i click in other category, the ones before stills on.
The template receives a array such as:
categories: ["todos", "beer", "eco-bag", "paper-bag", "suplementos", "chas", "doces", "chocolates", "dieteticos"]
Here is the template:
<template id="category-box">
<span :class="{active: currentFilter == category}" #click="setFilter(category)">
{{category}}
</span>
</template>
The call inside the #app element:
<div id="category">
<category v-for="category in categories" :category="category"></category>
</div>
The code that handles it:
const Category = Vue.component("category", {
template: "#category-box",
props: {
"category": String,
},
data: function() {
return {
currentFilter: "todos"
}
},
methods: {
setFilter: function(filter) {
this.currentFilter = filter;
this.$parent.$emit('filteredCategory', filter);
}
}
});
It looks like currentFilter is scoped to the individual Category component. Each time you set it you are setting it for that component. Move it to the parent scope so that there is only one currentFilter for all of your categories.

angular4 kendo-numerictextbox ngModel two way data binding

Below one is just sample. I need to multiple calculations dynamically.
Total value is not updating if I change values in units/price text boxes. How can I calculate using ngModel? Should we use valueChange event? Angular 4 don't update automatically?
JSON:
items:[{units:10;price:20, total:0},
{units:20;price:23, total:0}]
Controller:
pageLoad(){
for(var i=0; i<items.length; i++){
items[i].total = items[i].units*items[i].price
}
}
HTML:
<div *ngFor="let item of items; let i=index">
<kendo-numerictextbox [(ngModel)]="item.units" />
<kendo-numerictextbox [(ngModel)]="item.price" />
<kendo-numerictextbox [readOnly]="true" [(ngModel)]="item.total" />
</div>
Here is working Plunkr.
Code:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<div *ngFor="let item of items; let i=index">
<div>{{item | json}}</div>
<div>
<kendo-numerictextbox [(ngModel)]="item.units"></kendo-numerictextbox>
<kendo-numerictextbox [(ngModel)]="item.price"></kendo-numerictextbox>
<kendo-numerictextbox [readonly]="true" [value]="getTotal(item)"></kendo-numerictextbox>
</div>
</div>
`
})
export class AppComponent
{
public items = [{units:10,price:20},{units:20,price:23}];
public getTotal(item)
{
return item.units*item.price;
}
}

Angular5 - use key/value pair for select option

I've started working with angular5 and I'm trying to get the value of a select option and it's assigned ID onChange.
Component
import { Component, OnInit, EventEmitter } from '#angular/core';
// Services
import { LookupDataService } from '../../../service/lookup-data.service';
#Component({
selector: 'diversity-dropdown',
templateUrl: './diversity-dropdown.component.html',
providers: [LookupDataService]
})
export class DiversityDropdownComponent implements OnInit {
diversityForm: IDiversityForm[];
title = 'Lookup data';
selectedDiversity = '';
constructor(private readonly lookupDataService: LookupDataService) { }
ngOnInit() {
this.lookupDataService.getDiversityForm().subscribe((diversityForm: IDiversityForm[]) => {
this.diversityForm = diversityForm;
console.log(diversityForm);
}
);
}
onChange($event) {
console.log($event);
}
}
View
<div *ngFor='let section of diversityForm'>
<span class="label label-default">{{section.labelText}}</span>
<select (change)="onChange($event)" ng-model="">
<<option *ngFor='let dropdown of section.lookupDropdowns' id="{{dropdown.labelText}}" value="{{dropdown.value}} {{dropdown.labelText}}">{{dropdown.value}}</option>
</select>
<br />
</div>
Data
I've tried $event.target.id but in the console it's an empty string. $event.target.value works however.
Is there an easy way of doing what I am trying to do?
Stackblitz demo here
You should use select in this way:
HTML:
<select [(ngModel)]="newGovId.first_id_type" (change)="function($event)">
<option [ngValue]="null">Select something</option>
<option *ngFor="let option of options"
[ngValue]="option.value" [innerHtml]="option.text"></option>
</select>
The context of each option should be in the variable you're looping.

Ng-click and ng-change aren't being fired when using component and template angular 1.6

I am trying to fire a function when something is typed into the input. For some reason, it is not working when I use a template and component. Can anyone help me figure out why this is happening? I am new to Angular by the way.
Component
When the button is clicked or when something is typed into the input, the ng-click and ng-change functions should fire but they are not.
(function(angular) {
'use strict';
angular
.module('app')
.component('coinSearch', {
controller: CoinSearchController,
controllarAs: 'coin',
templateUrl: 'src/coinSearch.html'
});
function CoinSearchController(CryptoService) {
var coin = this;
var list = [];
coin.jank="something weird";
coin.savedCoins = [];
coin.searchedCoin = '';
function getCrypto() { //pulls data from API
CryptoService
.retrieve()
.then(function(response) {
coin.list = response;
});
}
coin.click = function() {
console.log('HELLOOO');
};
coin.showSearch = function() {
console.log('hello');
return coin.searchedCoin === '';
};
getCrypto();
}
})(angular);
Template
Template for the component above. There are some console.logs for testing purposes.
<div class="container">
<form class="search-form">
<button ng-click="coin.click()">{{coin.jank}} </button> //testing
<input
type="text"
class="search"
placeholder="Search Crypto"
ng-model="coin.searchedCoin"
ng-change="coin.showSearch()">
<ul class="suggestions">
<li ng-hide="coin.showSearch()" ng-repeat="coins in coin.list |
filter:coin.searchedCoin">
<span>{{coins.name}} ({{coins.symbol}})</span>
<span>${{coins.price_usd}}</span>
<span><button ng-
click="coin.addToList(coins);">Add</button></span>
</li>
</ul>
</form>
<coin-list></coin-list>
</div>
If you look at your controllerAs statement, you have it spelled as controllarAs. That would explain why nothing is listening in the template when you use coin.

Two way binding not working on bootstrap-select with aurelia

I have managed to create a custom element to use the boostrap-select element. However, I can pass/bind values to it from the main view (parent) but I am unable to get the selection out from the element when I use two-way binding.
My custom element is:
import {inject, customElement, bindable} from 'aurelia-framework';
import * as selectpicker from 'bootstrap-select'
#customElement('select-picker')
export class BootStrapSelectPicker {
#bindable selectableValues = null;
#bindable newValue = null;
#bindable selectedValue = 10;
constructor(){
}
attached(){
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
this.selectedValue = selected;
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue); <-- the selection here is correct
$('.selectpicker').selectpicker('refresh');
}
}
The corresponding view is:
<template>
<select class="selectpicker">
<option repeat.for="p of selectableValues">${p}</option>
</select>
</template>
My containing view that uses the custom element is:
<template>
<require from="./select-picker"></require>
<ul class="list-group">
<li class="list-group-item" repeat.for="p of messageProperties">
<div if.bind="p.propertyType == 'string'">
<div class="form-group">
<label for="ln">Name: ${p.propertyName}</label>
<input type="text" value.bind="p.propertyValue" class="form-control" id="ln" >
</div>
</div>
<div if.bind="p.propertyType == 'integer'">
<div class="form-group">
<label for="ln">Name: ${p.propertyName}</label>
<input type="text" value.bind="p.selectedValue" class="form-control" id="ln" >
<select-picker selectable-values.bind="p.selectableValues"
selected-value.two-way="p.selectedValue"></select-picker>
</div>
</div>
</li>
</ul>
</template>
I expected p.selectedValue to change once a selection is made with the select control as shown here with the two-way command:
selected-value.two-way="p.selectedValue"
However, p.selectedValue is not changing.
Any ideas why this is not working?
Turns out to be a simple scope issue:
attached(){
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
this.selectedValue = selected; // <-- This here doesn't refer to the VM any more
// if you look at the line above you are wrapping $(this) with jq, this works
// because 'this' is now in the scope of the calling element but
// doesn't refer to the aurelia viewmodel
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue);
$('.selectpicker').selectpicker('refresh');
}
Simple fix is:
attached(){
var self = this; // <--- Create a ref to the VM
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
// Change this to self
self.selectedValue = selected; // <--- Correct object gets the value now - binding works
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue);
$('.selectpicker').selectpicker('refresh');
}
I'm not sure how this will actually be handled in ES6/7 - I'm sure I read somewhere about how this will change, but since you are transpiling to ES5 it's definitely something to watch out for
The following code works for me, in case anyone has the same issue:
import {inject, customElement, bindable} from 'aurelia-framework';
import 'bootstrap-select'
#customElement('select-picker')
#inject(Element)
export class BootStrapSelectPicker {
#bindable name: string;
#bindable selectableValues;
#bindable selectedValue;
constructor(private element) {
}
attached() {
var self = this;
var $: any = jQuery;
var $elm = $(self.element).find('select');
if ($elm.length > 0) {
$elm.selectpicker();
$elm.on('change', function () {
self.selectedValue = $(this).find("option:selected").val();
});
this.refreshPicker($elm);
}
}
selectedValueChanged(newValue, oldValue) {
var $: any = jQuery;
var $elm = $(this.element).find('select');
this.refreshPicker($elm);
}
private refreshPicker = ($elm) => {
$elm.val(this.selectedValue);
$elm.selectpicker('refresh');
}
}