AngularJS Binding an object - javascript

In my controller I have this:
$scope.participants = [
{
name: "Alan",
birthday: new Date("1991/01/21"),
takePart: true,
},
{
name: "Leandro",
birthday: new Date("1991/01/21"),
takePart: true,
},
{
name: "Alejandro",
birthday: new Date("1991/03/21"),
takePart: true,
}
]
And I'm showing them in my View doing this:
<select name="" id="">
<option ng-repeat="p in participants">{{ p.name }}</option>
</select>
I want to show each one information in some place when I select one of them in the select html element. Is there a way to bind the object?

Use ng-options on your select box, and give it a ng-model. When the select is changed the model will hold the object represented by the selected item.
After that just use the model to display
<select ng-model="currentItem"
ng-options="participant.name for participant in participants">
</select>
<div>
{{currentItem.name}}<br/>
{{currentItem.birthday}}<br/>
{{currentItem.takePart}} </div>
</div>
Demo
var app = angular.module("test",[]);
app.controller("Test",function($scope){
$scope.participants = [
{
name: "Alan",
birthday: new Date("1991/01/21"),
takePart: true,
},
{
name: "Leandro",
birthday: new Date("1991/01/21"),
takePart: true,
},
{
name: "Alejandro",
birthday: new Date("1991/03/21"),
takePart: true,
}
];
$scope.currentItem = $scope.participants[0];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="Test">
<select ng-model="currentItem" ng-options="participant.name for participant in participants">
</select>
<div>
{{currentItem.name}}<br/>
{{currentItem.birthday}}<br/>
{{currentItem.takePart}} </div>
</div>

While ng-options is better, this is your way:
HTML:
<select name="" ng-model="test" ng-change="hello()" id="">
<option ng-repeat="p in participants">{{ p.name }}</option>
</select>
<p>{{pt.name}} - {{pt.birthday}} - {{pt.takePart}}</p>
JS:
$scope.participants = [
{
name: "Alan",
birthday: new Date("1991/01/21"),
takePart: true,
},
{
name: "Leandro",
birthday: new Date("1991/01/21"),
takePart: true,
},
{
name: "Alejandro",
birthday: new Date("1991/03/21"),
takePart: true,
}
]
$scope.test=$scope.participants[0].name;
$scope.pt=$scope.participants[0];
$scope.hello = function(){
angular.forEach($scope.participants, function(item){
if(item.name==$scope.test){
$scope.pt = item;
}
})
};
Fiddle Here
(Sorry for the variable names ;))

Related

vuejs select default option does not work

I have a json data that i've been loading into the <select>
This is a sample json data that I have:
let plans = [{id: 20, name: "test", default: 0},
{id: 19, name: "haha", default: 0},
{id: 18, name: "okok", default: 1}];
This is my select html/vue.
<select id="plans" class="form-control" v-model="company.plan_id">
<option v-for="plan in plans" :value="plan.id" :selected="plan.default">{{plan.name}}</option>
</select>
It seems it doesn't select the "okok" value even if the default is 1.
Those plans data are coming from my database which is loaded using ajax.
I'm new to VueJS, any help is greatly appreciated!
Thanks.
selected attribute no longer makes sense when you using v-model.
You can't use selected attribute if you are using v-model on the <select>, Set the v-model value to the default value instead:
<template>
<div id="app">
<select id="plans" class="form-control" v-model="company.plan_id">
<option v-for="plan in plans" :value="plan.id" :key="plan.id" :selected="plan.default">{{plan.name}}</option>
</select>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
company: {
plan_id: 18
},
plans: [
{ id: 20, name: "test" },
{ id: 19, name: "haha" },
{ id: 18, name: "okok" }
]
};
}
};
</script>
Demo here: https://codesandbox.io/s/beautiful-sound-gxmzu?file=/src/App.vue

Select default value in dynamic dropdown in Angular JS

This is my code what's wrong in this
<select name="countryName" class="form-control" ng-model="twoFAData.country" style="height:35px">
<option ng-repeat="country in contriesWithCode" value="{{country[2]}}" ng-selected="accountDetailsRes.country == country[2]">{{country[1]}} ({{country[0]}})</option>
</select>
In the JS I defined this
$scope.defaultCountry = "USA";
$rootScope.accountDetailsRes = {country: $scope.defaultCountry, state: "selectstate"}; // its default country
Thanks In advance
To start, I would recommend you to use ng-options instead of ng-repeat when having many dropdown options as it performs better.
<select ng-options="country[0] as country[0].concat(' ('+country[1]+')') for
country in contriesWithCode" ng-model="twoFAData.country"
name="countryName" class="form-control" style="height:35px">
</select>
Then, if you want a default value just set $scope.twoFAData.country = 'USA' or $scope.twoFAData.country = $scope.defaultCountry.
app.controller('BaseController', function($scope) {
$scope.defaultCountry = "USA";
$scope.twoFAData = {};
$scope.twoFAData.country = $scope.defaultCountry;
$scope.contriesWithCode = [['USA', 'United States'], ['ARG', 'Argentina']];
});
var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function ($scope) {
$scope.formData = {
people : 2
}
$scope.people = [
{ id: 1, first: 'John', last: 'Rambo', actor: 'Silvester' },
{ id: 2, first: 'Rocky', last: 'Balboa', actor: 'Silvester' },
{ id: 3, first: 'John', last: 'Kimble', actor: 'Arnold' },
{ id: 4, first: 'Ben', last: 'Richards', actor: 'Arnold' }
];
});
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"/>
<div ng-app="myapp">
<fieldset ng-controller="FirstCtrl">
<select
ng-model="formData['people']">
<option ng-repeat="item in people" value="{{item['id']}}">{{item['first']}}</option>
</select>
{{people[formData['people']]['first']}} {{people[formData['people']]['last']}} - {{people[formData['people']]['actor']}}
</fieldset>
</div>

Vue v-for after condition using vuex

While I am trying to create a form I encountered this problem which I don't have any solution.
There is a Vuex data on Vehicles Make and Model of vehicle, now once the make is selected, I want the other form to loop through the selected Make and find other models... something like that.
Here is what I did so far:
cars.js - (vuex module)
const state = {
make: [
{
name: 'Audi',
carid: '1',
models: [
{
modelid: '1.1',
name: 'A7',
},
{
modelid: '1.2',
name: 'A8',
},
],
},
{
name: 'BMW',
carid: '2',
models: [
{
modelid: '2.1',
name: '5 Series',
},
{
modelid: '2.2',
name: '7 Series',
},
],
},
],
}
Cars.vue
<template>
<div class="labelos">
<div class="label-name">
<h4>Car make:</h4>
</div>
<div class="label-body">
<label for="car-make">
<select v-model="selectedType" name="carmake" required>
<option value=""></option>
<option v-for="(cars, index) in cars.make" :key="index" :value="cars.carid">{{ cars.name }}</option>
</select>
</label>
</div>
</div>
<div class="labelos">
<div class="label-name">
<h4>Car model:</h4>
</div>
<div class="label-body">
<label for="car-model">
<select>
<option value=""></option>
<option v-for="(model, index) in cars.make" :key="index" :value="cars.carid">{{ model.carid }}</option>
</select>
</label>
Model:
</div>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
name: 'cars',
data() {
return {
selectedType: '',
selectedCity: '',
};
},
methods: {
},
components: {
Headers,
Footers,
},
computed: {
...mapState([
'cities', 'cars',
]),
},
};
</script>
So as you can see on first label I am looping through makes, and once a car make is selected that carid is saved on selectedType, now how is that possible to load second dropdown according to that selection, so if carid 1 is selected, the list will load car models available on given carid (in this example carid 1)
Looking forward to hear from someone, I am stuck here.. I don't know any solution how to do this... this is so far I have done
Cheers
You should create a computed property which returns model options based on the value of the selected make type. Then you can bind to that and it will automatically update whenever the selected make changes:
models() {
if (this.selectedType) {
return this.cars.make.find((car) => car.carid === this.selectedType).models;
}
}
Here's a working example:
const store = new Vuex.Store({
state: {
cars: {
make: [{
name: 'Audi',
carid: '1',
models: [
{ modelid: '1.1', name: 'A7' },
{ modelid: '1.2', name: 'A8' },
]
}, {
name: 'BMW',
carid: '2',
models: [
{ modelid: '2.1', name: '5 Series' },
{ modelid: '2.2', name: '7 Series' }
],
}]
}
}
})
new Vue({
el: '#app',
store,
data() {
return {
selectedType: '',
};
},
computed: {
...Vuex.mapState(['cars']),
models() {
if (this.selectedType) {
return this.cars.make.find((car) => car.carid === this.selectedType).models;
}
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<div id="app">
<h4>Car make:</h4>
<select v-model="selectedType" name="carmake" required>
<option value=""></option>
<option v-for="(cars, index) in cars.make" :key="index" :value="cars.carid">{{ cars.name }}</option>
</select>
<h4>Car model:</h4>
<select>
<option value=""></option>
<option v-for="(model, index) in models" :key="index" :value="model.modelid">{{ model.name }}</option>
</select>
</div>
Working example with your data:
const state = {
make: [
{
name: 'Audi',
carid: '1',
models: [
{modelid: '1.1', name: 'A7'},
{modelid: '1.2', name: 'A8'}
]
}, {
name: 'BMW',
carid: '2',
models: [
{modelid: '2.1', name: '5 Series'},
{modelid: '2.2', name: '7 Series'}
]
}
]
}
new Vue({
el: '#app',
data: {
state: state,
selected: 0
},
computed: {
models () {
var maker = this.state.make.find(m => m.carid === this.selected)
return maker ? maker.models : []
}
}
})
<div id="app">
<select v-model="selected">
<option value="0" selected>Choose maker</option>
<option
v-for="maker in state.make"
:key="maker.carid"
:value="maker.carid"
>{{ maker.name }}</option>
</select>
<br>
<select>
<option value="0" selected>Select model</option>
<option
v-for="model in models"
:key="model.modelid"
:value="model.modelid"
>{{ model.name }}</option>
</select>
</div>
<script src="https://unpkg.com/vue#2.5.3/dist/vue.min.js"></script>
If you can, change 'modelid' to simple integers - 1, 2, etc., at least. And if you can and you know how to do it, change your data structure - divide makers and models to separate arrays/objects.
Here's a plugin for this specific task you're trying to accomplish: vue-dependon.
It hasn't been updated for 1-2years, but I think that you can check its source code and see how it works.
UPDATE:
All you need from the sourcecode is the loadOptions function and the code between L83 and L105.
You can adapt that code to your needs.

Rivets JS data-show not working

I am trying to do a simple show/hide using Rivets JS (previously using Aurelia). I thought i had the right code to do the job after looking through various sites however it doesnt seem to be working.
my HTML:
<div id="Payments">
<h1 rv-text="data.title"></h1>
<div class="col-md-4">
<select rv-value="data.selectedVal" class="form-control">
<option value="0" selected></option>
<option rv-each-country="data.countries" rv-value="country.id" rv-text="country.name"></option>
</select>
</div>
<div class="container" style="padding-top:40px;">
<div class="row">
<table class="table .table-responsive table-hover">
<tbody>
<tr rv-each-product="data.products" data-show="data.selectedVal | eq product.id" >
<td rv-text="product.title" ></td>
<td rv-text="product.id"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
my js:
var data = {
title: 'Welcome to Payments',
products: [
{
title: 'MasterCard',
id: 'CH'
},
{
title: 'Visa',
id: 'UK'
},
{
title: 'PayPal',
id: 'US'
},
{
title: 'Cheque',
id: 'UK'
},
{
title: 'Cash',
id: 'US'
}],
countries: [
{
name: 'China',
id: 1
},
{
name: 'USA',
id: 'US'
},
{
name: 'UK',
id: 'UK'
}
],
selectedVal: ''
};
rivets.formatters.eq = function (value, args) {
debugger;
return value === args;
};
rivets.bind(
document.querySelector('#Payments'), // bind to the element with id "candy- shop"
{
data: data // add the data object so we can reference it in our template
});
The List of payment should show or hide based on the selected country.
Any help would be great!
Thanks
Needed to use rv-show and not data-show. Must have read the wrong documentation.

KnockoutJS: Handling Select Boxes. Selecting a default value and removing an existing item

I am having trouble handling checkboxes in Knockout JS.
jsfiddle link: http://jsfiddle.net/wenbert/Xyuhk/72/
Note that I have provided 2 select boxes for each parent (Hero). Each one is using a different way but both are more or less "observing" the same object.
Workflow
Click on a gray box
A box with a blue dotted line should appear containing the items of the Select box.
From here, you can edit the items of the select box.
Fiddle here: http://jsfiddle.net/wenbert/Xyuhk/72/
The Problems
When I remove an item, I am not able to remove it from the Select boxes. Note that I do not want to completely remove it from the object. I just want the current item to be flagged as "isDeleted".
Select A - hides the item but it leaves an empty option in the select box.
Select B - the "ifnot: isDeleted" is not having any effect on the options.
The Question
How do I handle Select Boxes? I have rendered 2 Select Boxes in 2 different ways to try to have the ifnot: isDeleted take effect but none of them are working.
Update: With this setup, how do I do the "selected" value of the select box?
HTML
<button data-bind="click: addHero">Add Hero</button>
<ul data-bind="foreach: heroes">
<li class="parent" data-bind="ifnot: isDeleted, click: $parent.selectHero">
<input class="big-box" type="text" data-bind="value: name" />
<button class="btn-small" data-bind="click: $parent.removeHero">Remove Hero</button>
<br/>
SKILLS:
Select A) <select data-bind="foreach: skills">
<option data-bind="value: name, text: name, ifnot: isDeleted"></option>
</select>
Select B) <select data-bind="options: skills, optionsText: 'name', value: selected_skill.name, ifnot: isDeleted">
</select>
<br/>
<span class="instructions">(Step 1: Click somewhere here)</span>
</li>
</ul>
<div class="edit-panel" data-bind="if: selectedHero">
Edit Skill:<br/>
<div data-bind="with: selectedHero">
<button class="btn-small" data-bind="click: addSkill">Add Skill</button>
<ul data-bind="foreach: skills">
<li data-bind="ifnot: isDeleted">
<button class="btn-small" data-bind="click: $parent.setAsDefaultSkill">Set as default</button>
<input data-bind="value: name" />
<button class="btn-small" data-bind="click: $parent.removeSkill">Remove Skill</button>
</li>
</ul>
<span class="instructions">(Step 2: Remove a Skill, then have a look at the Select Box above.)</span>
</div>
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
Javascript
var initialData = [
{
id: '1',
name: "Batman",
isDelete: false,
selected_skill: {name: "Boxing", isDeleted: false},
skills: [
{ id: '1', name: "Karate", isDeleted: false },
{ id: '2', name: "Boxing", isDeleted: false},
{ id: '6', name: "Sonar", isDeleted: false}
]
},
{
id: '2',
name: "Hulk",
isDelete: false,
skills: [
{ id: '3', name: "MMA", isDeleted: false },
{ id: '4', name: "Rage", isDeleted: false},
{ id: '5', name: "Extra Strength", isDeleted: false}
]
},
];
function Hero(data) {
var self = this;
self.name = ko.observable(data.name);
self.selected_skill= ko.observable(data.selected_skill);
self.skills = ko.observableArray(ko.utils.arrayMap(data.skills, function(i) {
return new Skills(i);
}));
self.addSkill = function() {
self.skills.push(new Skills({name: '---', isDeleted: false}));
}
self.setAsDefaultSkill = function(item) {
self.selected_skill(item);
}
self.isDeleted = ko.observable(data.isDeleted);
self.removeSkill = function(item) {
item.isDeleted(true);
}
}
function Skills(data) {
var self = this;
self.name = ko.observable(data.name);
self.isDeleted = ko.observable(data.isDeleted);
}
function SuperheroViewModel(data) {
var self = this;
self.heroes = ko.observableArray(ko.utils.arrayMap(data, function(i){
return new Hero(i);
}));
self.selectedHero = ko.observable();
self.selectedHero.skills = ko.observableArray();
self.addHero = function() {
self.heroes.push(
new Hero({
name: 'Wolverine',
isDelete: false,
skills: [{name: 'Breathing', isDeleted: false}],
})
);
}
self.selectHero = function(item) {
self.selectedHero(item);
}
self.removeHero= function(item) {
item.isDeleted(true);
}
}
ko.applyBindings(new SuperheroViewModel(initialData ));
​
​
I hope everything is clear.
Any reply will be greatly appreciated.
THanks!
I would do the filtering in the viewmodel. So I would create a filtered collection something like availableSkills
self.availableSkills = ko.computed(function() {
return ko.utils.arrayFilter(self.skills(), function(item) {
return !item.isDeleted();
})
});
And then I would use this in the selects:
<select data-bind="foreach: availableSkills">
<option data-bind="value: name, text: name"></option>
</select>
Demo fiddle.

Categories