Dropdown value in angular2 - angular2-routing

I want to display value after selecting dropdown and radio button. I have a dropdown of employee that consists of value 5, 10, 15,20, 25. For that I wrote in component.ts like this:
employees = [{value: 5}, {value: 10}, {value: 15}, {value: 20}, {value: 25} ]
and called that in component.html as
<select>
<option *ngFor='let a of employees'>{{a.value}} </option>
</select>
Now I have a radio button of onemonth, twomonth. like this
<input type="radio" value="month" (click)= "pclick()"> Month
<input type="radio" value="year" (click)= "pclick()"> Year
Now what I want is If I will select number of employee as 5 and radiobutton month it should display value 50, then if I will select dropdown of employee 10 and radio button year it should display value as 120.
employee = [{value: "5"}, {value: "10"}, {value: "15"}, {value: "25"}, {value: "75"} ]
employee = {value: " "}
pay= 'monthly'
rupees = 10
amount = 0
calculateAmount(employee, pay, rupees) {
if (pay == 'Year') {
this.amount = rupees * 12 * employee
}else if (pay == 'Quarter') {
this.amount = rupees * 3 * employee
} else {
this.amount = rupees* employee
}
}
Could anyone please help me I am new in angular2. Thanks.

In your template
<select [(ngModel)]="employee">
<option *ngFor='let a of employees' value=a.value>{{a.value}} </option>
</select>
<input type="radio" [(ngModel)]="monthly">
<input type="radio" [(ngModel)]="yearly">
<input type="radio" [(ngModel)]="quarterly">
<input type="button" value="Calculate" (click)="calculate()">
In your component
import { Component } from '#angular/core';
#Component({
selector: 'employee',
templateUrl: './employee.component.html'
})
export class EmployeeComponent{
private employee:number=0;
private monthly:any;
private yearly:any;
private quarterly:any;
private rupees:number = 10
private amount:number = 0
private pay:string= 'monthly';
private employees = [{value: "5"}, {value: "10"}, {value: "15"}, {value: "25"}, {value: "75"} ] ;
calculateAmount() {
if (this.yearly.checked) {
this.amount = this.rupees * 12 * this.employee
}else if (this.monthly.checked) {
this.amount = this.rupees * 3 * this.employee
} else {
this.amount = this.rupees * this.employee
}
}
}

Related

How to hide selected option in Autocomplete using reactjs

I want to hide the selected option in the Dropdown, the option should not appear in the next dropdown. For an example, there are 2 dropdowns, in the first dropdown - i have selected "Hockey" then "hockey" should not be shown in the second dropdown, It should show only "Baseball and badminton".
My JSON data will be appearing in this way:
"details": [
{ "id": "12wer1", "name": "ABC", "age": 15, "game": "badminton" },
{ "id": "78hbg5", "name": "FRE", "age": 21, "game": "Hockey" }
]
Here is the sample Code:
let games = [{ game: "Baseball"}, { game: "Hockey"}, { game: "badminton" }];
class Field extends React.Component {
constructor(props) {
super(props);
this.state = {
details: [{id: '', name: '', age: '', game: ''}]
}
}
...
...
render() {
return (
...
...
{this.state.details.map((y) => (
<Autocomplete
style={{ witdth: 200 }}
options={games}
getOptionLabel={(option) => option.game}
onChange={(value) =>this.onGameChange(value, y.id)}
value={games.filter(i=> i.game=== y.game)}
renderInput={(params) =>
<TextField {...params} label="Games" margin="normal" />
}
/>))}
...
...
)
}
}
onGameChange = (e, id)=> {
let games = this.state.details;
let data = games.find(i => i.id === id);
if (data) {
data.game = value.game;
}
this.setState({ details: games });
}
I have no idea, how to hide the selected option, can anyone help me in this query?
Thanks! in advance.
A possible solution would be to
create an array and store the values in an array when the user selects autocomplete
while passing options, filter the values that have been passed to other autocompletes.
const ary = [111,222,333];
let obj = [{id: 111},{id: 222}];
const i = 1; // this is your index in loop
const ary2 = ary.slice()
ary2.splice(i,1);
console.log(obj.filter((o) => !ary.includes(o.name))); // this should be given to our options list in autocomplete
you can hide this is in CSS easily no need to do anything in ReactJS
autocomplete renders as an unordered list so something like this
.panel > ul > li:first-child {
display:none;
}

Why isn't this AngularJS populating my dropdown?

Here is my select:
<select class="dropdownInForm" ng-model="vehicle">
<option ng-repeat="vehicle in vehicles" value="vehicle.VehicleID">{{vehicle.VehicleName}}</option>
</select>
Here is how I am loading the data in my angular controller:
$http.post('VehicleEdit.aspx/GetVehicles', { vendorID: $scope.vendorID, placeID: $scope.placeID})
.then(function (response) {
$scope.vehicles = response.data;
$scope.vehicle = $scope.vehicles[0];
})
And here is what response.data contains:
"[{"VehicleID":1,"VehicleName":"test1","IsActive":false},{"VehicleID":1,"VehicleName":"test2","IsProgrammatic":true}]"
The pull from the database is working as I am debugging it in Chrome and can see that $scope.vehicles is populated with the above JSON. However, this dropdown will not populate no matter what I try.
Where am I going wrong?
EDIT --
I should have noted that I did try it this way as well, without any luck:
<select class="dropdownInForm" ng-model="vehicle" ng-options="vehicle.VehicleId as vehicle.VehicleName for vehicle in vehicles"></select>
Here is the WebMethod that retuns the JSON:
[WebMethod]
public static string GetVehicles(int placeID, int vendorID)
{
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
DataSet vehiclesData = VehicleLogic.GetListOfVehicles(placeID, vendorID);
List<Vehicle> vehicles = new List<Vehicle>();
foreach(DataRow row in vehiclesData.Tables[0].Rows)
{
Vehicle vehicle = new Vehicle()
{
VehicleID = Convert.ToInt32(row["VehicleID"]),
VehicleName = row["VehicleName"].ToString().Trim(),
IsProgrammatic = Convert.ToBoolean(row["IsProgrammatic"])
};
vehicles.Add(vehicle);
}
return jsonSerializer.Serialize(vehicles);
}
Try using ng-options
<select ng-model="vehicle" ng-options="k as k.VehicleName for k in vehicles" >
</select>
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.vehicles = [{
"VehicleID": 1,
"VehicleName": "test1",
"IsActive": false
}, {
"VehicleID": 1,
"VehicleName": "test2",
"IsProgrammatic": true
}];
$scope.vehicle = $scope.vehicles[0];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select ng-model="vehicle" ng-options="vehicle as vehicle.VehicleName for vehicle in vehicles"></select>
<div>
Selected Vehicle: {{vehicle | json}}
</div>
</div>
value is not an Angular directive so you have to use {{vehicle.VehicleID}} when setting the value for your <option> elements. However, a much better approach would be to use ng-options:
<select class="dropdownInForm" ng-model="vehicle" ng-options="vehicle.VehicleID as vehicle.VehicleName for vehicle in vehicles"></select>
try to not use same var name for ng-model=vehicle" and ng-repeat="vehicle as ...

On click a DIV apply dynamic data binding to edit the CSS using an HTML input - knockout.js

I'm trying to edit individual elements of an array.
I have a JSON array like this:
[ {"idComponent":1,"left":"100px","top":"100px","idHTML":"name_div","width":"200px","height":"300px","value":"My name is"}
,{"idComponent":2,"left":"200px","top":"200px","idHTML":"date_div","width":"200px","height":"300px","value":"2016-Enero-12"}
,{"idComponent":3,"left":"300px","top":"300px","idHTML":"weigth_div","width":"200px","height":"300px","value":"1.5 KG"}
,{"idComponent":4,"left":"400px","top":"400px","idHTML":"talla_div","width":"200px","height":"300px","value":"23"}
,{"idComponent":5,"left":"500px","top":"500px","idHTML":"description_div","width":"300px","height":"300px","value":"The text"}
]
These are converted to observables in knockout.
Each one is binded to a DIV element to display in screen.
"left", "top", "height" and "width" are CSS attributes that are applied to each one.
When you click ones of the DIV contains with the mouse, I'm trying to bind the element to HTML inputs to edit the CSS values. You can see the idea in the next picture:
Mockup Image - Click here to see the image
The code is the next:
function convertPixelsToInches(pixels){
return pixels/96;
}
// Elemento regresados desde el servidor.
var dataFromServer =
{
"idTemplate":"1"
,"components" :
[{"idComponent":1,"left":"100px","top":"100px","idHTML":"name_div","width":"200px","height":"300px","value":"Sergio Pinto Fernandez"}
,{"idComponent":2,"left":"200px","top":"200px","idHTML":"date_div","width":"200px","height":"300px","value":"2016-Enero-12"}
,{"idComponent":3,"left":"300px","top":"300px","idHTML":"weigth_div","width":"200px","height":"300px","value":"1.5 KG"}
,{"idComponent":4,"left":"400px","top":"400px","idHTML":"talla_div","width":"200px","height":"300px","value":"23"}
,{"idComponent":5,"left":"500px","top":"500px","idHTML":"description_div","width":"300px","height":"300px","value":"Tomar dos cucharadas cada 3 hras."}
]
,"paperSize":"papersize_USLetter_portrait"
,"templateImage":{
"imageUrl":"images/SolicitudLaboratorioExpress.jpg"
,"width":"8.5in"
,"height":"11in"
,"left":"0px"
,"top":"0px"
}
};
function componentModel(dataComponent) {
if (!dataComponent) {
dataComponent = {};
}
var self = this;
self.idComponent = ko.observable(dataComponent.idComponent);
self.left = ko.observable(dataComponent.left);
self.top = ko.observable(dataComponent.top);
self.idHTML = ko.observable(dataComponent.idHTML);
self.width = ko.observable(dataComponent.width);
self.height = ko.observable(dataComponent.height);
self.value = ko.observable(dataComponent.value);
}
/**
* data Json from server.
*
*/
function templateModel(data) {
if (!data) {
data = {};
}
var self = this;
self.components = ExtractComponents(self, data.components, componentModel);
self.currentSelectedComponent = ko.observable();
self.currentSelectedComponentIndex = ko.observable(-1);
//self.currentSelectedComponentLeft = ko.observable();
self.currentSelectedComponentLeft = ko.computed(function(){
var value = self.currentSelectedComponentIndex();
console.log(typeof value);
//value=value*1;
console.log(value);
if (value ) {
return "TT";
}
// Get "200px y must save as 200"
//return self.currentSelectedComponent().left;//.substring(0,data.length-2);
return "FF";
});
self.currentSelectedComponentTop = ko.observable();
self.editComponent = function(component,index){
self.currentSelectedComponentIndex(index);
self.currentSelectedComponent(component);
// Binding the component to the editor.
// ??
};
function bindComponentToEditor() {
ko.applyBindings()
}
self.idTemplate = ko.observable(data.idTemplate);
self.paperSize = ko.observable(data.paperSize);
/* */
self.paperSizeWidth = ko.observable(convertPixelsToInches(1067));
self.paperSizeHeigth = ko.observable(convertPixelsToInches(1067));
//
self.templateImage_imageUrl = ko.observable(data.templateImage.imageUrl);
self.templateImage_width = ko.observable(data.templateImage.width);
self.templateImage_height = ko.observable(data.templateImage.height);
self.templateImage_left = ko.observable(data.templateImage.left);
self.templateImage_top = ko.observable(data.templateImage.top);
}
/**
* parent: referencia al objeto o funcion que mando a llamar esta fucnion.
*
* dataArr: Array de elementos que se desea la funcion ExtractComponents haga mapeo.
* Ejemplo de dataArr:
*
* [ {"idComponent":1,"left":"100px","top":"100px","idHTML":"name_div","width":"200px","height":"300px","value":"Sergio Pinto Fernandez"}
,{"idComponent":2,"left":"200px","top":"200px","idHTML":"date_div","width":"200px","height":"300px","value":"2016-Enero-12"}
,{"idComponent":3,"left":"300px","top":"300px","idHTML":"weigth_div","width":"200px","height":"300px","value":"1.5 KG"}
,{"idComponent":4,"left":"400px","top":"400px","idHTML":"talla_div","width":"200px","height":"300px","value":"23"}
,{"idComponent":5,"left":"500px","top":"500px","idHTML":"description_div","width":"300px","height":"300px","value":"Tomar dos cucharadas cada 3 hras."}
]
*
* modelConstructor: funcion con que se creara un nuevo componente, es decir el modelo.
*
*/
function ExtractComponents(parent, dataArr, modelConstructor) {
var components = [];
if (dataArr == null) {
return components;
}
for (var i = 0; i < dataArr.length; i++) {
var dataArrElement = dataArr[i];
var component = new modelConstructor(dataArrElement,parent);
components.push(component);
}
return components;
}
ko.applyBindings(new templateModel(dataFromServer));
I have two problems:
The Input for left and top values only accept integer values, the i need substring "200px" to 200 but alway i receive a error: ".left is undefined"
self.currentSelectedComponentLeft = ko.computed(function(){
var value = self.currentSelectedComponentIndex();
console.log(typeof value);
//value=value*1;
console.log(value);
if (value ) {
return "TT";
}
// Get "200px and save as 200"
//return self.currentSelectedComponent().left;//.substring(0,data.length-2);
return "FF";
});
The principal problem... how can I bind the DIV element when I click the element to the inputs at the right?
I think I need dynamic binding, or dynamic subscription, but can't find answer to this problem of dynamic double data binding.
This is the HTML:
<div id="mainContainer">
<div id="contentPrint_div" class="page" data-bind="css: paperSize">
<img id="template_img" data-bind="attr: {src: templateImage_imageUrl},
style: {width: templateImage_width, height: templateImage_height, left: templateImage_left, top: templateImage_top}">
<div id="fieldsArea_div" class="" data-bind="foreach: components">
<div class="field" data-bind="html: value, style: {width: width, left:left, top:top},
attr: {id: idHTML}, click: $parent.editComponent($data,$index)"></div>
</div>
</div>
<div id="toolsbar">
<div id="toolbarPanel">
ID template:<span data-bind='text: idTemplate'></span>
<div id="panelMenuInfoElements_div">
Elemento actual: <span data-bind='text: idTemplate'></span>
Posicion
X:<input type="text" class="form-control" id="" placeholder="x" min="0" step="0.01"
data-bind="attr: {max: paperSizeWidth}, value: currentSelectedComponentTop">
Y:<input type="text" class="form-control" id="" placeholder="y" min="0" step="0.01"
data-bind="attr: {max: paperSizeHeigth}, value: currentSelectedComponentLeft">
</div>
</div>
<div id="toolbarCode">
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
</div>
</div>
</div>
You posted quite some code; I'm not 100% sure if I got all your questions correctly. But I tried to create an example that I think shows how to solve your problems.
I've used a computed to create a style object that rewrites x and y observables that are numbers, to the style binding compatible: { top: 0px, left: 0px }
I've used a with binding to link your <input> elements to the last clicked block.
var Block = function(name, x, y) {
this.label = name;
this.x = ko.observable(x);
this.y = ko.observable(y);
this.style = ko.computed(function() {
return {
top: this.y() + "px",
left: this.x() + "px"
}
}, this);
}
var VM = function() {
this.blocks = [
new Block("Block 1", 100, 100),
new Block("Block 2", 200, 100),
new Block("Block 3", 300, 100),
];
this.selectedBlock = ko.observable(this.blocks[0]);
};
ko.applyBindings(new VM());
.Block {
position: absolute;
background: red;
padding: 1rem;
list-style: none;
}
.Block.is-selected { background: yellow; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="Inputs" data-bind="with: selectedBlock">
<div>
Editing <span data-bind="text: label"></span>
</div>
<div>Left:
<input type="number" data-bind="value: x">
</div>
<div>Top:
<input type="number" data-bind="value: y">
</div>
</div>
<ul data-bind="foreach: blocks">
<li class="Block" data-bind="
click: $parent.selectedBlock,
style: style,
text: label,
css: { 'is-selected': $data == $parent.selectedBlock()}"></li>
</ul>

Update one dropdown from another dropdown on a bound web form in Meteor

I have an edit form that is bound to existing data. I have two dropdowns that I would like have update each up depending on specific criteria. For example, is I set the assignedTo to blank, change the status to UnAssigned, and/or if I change the status to UnAssigned, change the AssignedTo to be blank, etc.
Status Dropdown:
<select class="form-control edit-status" id="status" name="status">
<option selected="{{equals status 'UnAssigned'}}" value="UnAssigned">UnAssigned</option>
<option selected="{{equals status 'Open w Vendor'}}" value="Open w Vendor">Ticket with Vendor</option>
<option selected="{{equals status 'Not Started'}}" value="Not Started">Not Started</option>
<option selected="{{equals status 'In Progress'}}" value="In Progress">In Progress</option>
<option selected="{{equals status 'Reopened'}}" value="Reopened">Reopened</option>
</select>
Assigned To Dropdown
<select class="form-control edit-assigned-to" id="assignedTo" name="assignedTo">
<option value="" selected="{{equals assignedTo ''}}">Select a User</option>
{{#each users}}
<option value="{{_id}}" selected="{{equals ../assignedTo _id}}">{{services.auth0.name}}</option>
{{/each}}
</select>
I already have an equality helper on each of them to pick the value that is already set when loading the form data. I was thinking of using Reactive Vars with change events, but I'm unsure how to exactly to implement that or if I'm even on the right track. T
Let's say the collection that contains the status and assignedTo fields is called myCollection:
Template.myTemplate.events({
'change #status': function(ev){
ev.stopPropagation();
var newStatus = $('#status).val();
if ( newStatus == "UnAssigned" ){ // unset the assignedTo value
myCollection.update({ _id: this._id },
{ $set: { status: newStatus}, $unset: { assignedTo: true }});
} else {
myCollection.update{ _id: this._id },{ $set: { status: newStatus}});
}
},
'change #assignedTo': function(ev){
ev.stopPropagation();
var newAssignedTo = $('#assignedTo').val();
if ( newAssignedTo != "None" ){
var userId = Meteor.users.findOne({ _id: newAssignedTo });
myCollection.update({ _id: this._id },{ $set: { assignedTo: newAssignedTo }});
} else { // unset the assignedTo
myCollection.update({ _id: this._id },
{ $set: { status: "UnAssigned" }, $unset { assignedTo: true }});
}
}
});
Note that in your template you're missing a way to select "None" as a value for the assigned user.
I ended up using some jquery in my change events.
'change .edit-status': function(event, template){
var status = event.target.value;
if (status === "UnAssigned") {
$(".edit-assigned-to").val("");
}
return false;
},
'change .edit-assigned-to': function(event, template){
var assignedTo = event.target.value;
if (!template.data.assignedTo && assignedTo !== "") {
$(".edit-status").val("Not Started");
}
if (assignedTo === "") {
$(".edit-status").val("UnAssigned");
}
return false;
}
I'm not sure if there are better approaches or pitfalls to this solution, but it seems to be meeting my needs.

Validating input data with BreezeJS / KnockoutJS / Durandal

I'm trying to validate my inputs from a form with BreezeJS / KnockoutJS / Durandal and I'm not getting any results.
This is my input inside my view:
<input data-bind="value:app_name, attr: {placeholder: resources.brand_create_placeholder_brand_name }" type="text" class="form-control input-sm" name="app_name" id="app_name" />
And this is my viewmodel:
define(['durandal/app', 'services/logger', 'plugins/router', 'knockout', 'breeze', 'toastr', 'services/resources'],
function (app, logger, router, ko, breeze, toastr, resourcesSVC) {
var vm = {
app_name: ko.observable(), //.extend({ required: true, minLength: 30, }),
...,
currency: ko.observable(),
currencies: [{ name: "Euro", value: "EUR", synbol: "€" }, { name: "Dollar", value: "USD", synbol: "$" }, { name: "Pounds Sterling", value: "GBP", synbol: "£" }],
use_smtp: ko.observable(false),
activate: activate,
title: "Create Brand",
createEntity: createEntity,
goBack: goBack,
resources: {}
}
};
Here I'm initializing my service:
var serviceName = 'breeze';
var manager = new breeze.EntityManager(serviceName);
And here I have the creation of my entity:
function createEntity() {
var DT = breeze.DataType;
var Validator = breeze.Validator;
var brand = manager.metadataStore.getEntityType("app");
/*app_name*/
var propAppName = brand.getProperty('app_name');
brand.addValidator(Validator.required(), propAppName);
brand.addValidator(Validator.maxLength({ maxLength: 30 }), propAppName);
var newBrand = brand.createEntity('app');
newBrand.app_name = vm.app_name();
...
manager.addEntity(newBrand);
manager.saveChanges()
.then(createSucceeded)
.fail(createFailed);
function createSucceeded(data) {
toastr.success("Brand created");
app.trigger('brand:changed');
router.navigate('#brands');
}
function createFailed(error) {
var msgError = "Create failed: " + getErrorMessages(error);
toastr.error(msgError);
manager.rejectChanges();
}
}
Can you please help me set validators for each field & display a custom message for each one whose values aren't correct?
Thank you!

Resources