I have created a select box bound to a model using Angularjs.
The select box options load correctly but as soon as select any single option all options disappear from the select box. What is the reason this is occuring and how do I keep my options from disappearing?
Plunker link demonstrating the issue:
http://plnkr.co/edit/DolBIN
HTML
<html xmlns="http://www.w3.org/1999/xhtml" ng-app>
<head>
<title>Angular Test Prjoect - Home</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<script type="text/javascript" src="Clinic.js"></script>
</head>
<body>
<div ng-controller="ClinicCtrl">
<select ng-options="item as item.start + '-' + item.end + ':' + item.patient.name for item in appointments" ng-model="appointments">
</select>
</div>
</body>
</html>
JavaScript
function ClinicCtrl($scope) {
$scope.appointments = [
{ start: "900", end: "930", provider: "1", patient: {name:"Allen",dob:"8/12/1977"} },
{ start: "1000", end: "1045", provider: "1", patient: { name: "Allen", dob: "8/12/1971"} },
{ start: "1030", end: "1100", provider: "2", patient: { name: "David", dob: "11/22/1973"} },
{ start: "1100", end: "1145", provider: "2", patient: { name: "Francine", dob: "3/18/1987"} },
{ start: "1230", end: "1530", provider: "3", patient: { name: "George", dob: "4/5/1997"} },
{ start: "1300", end: "1500", provider: "3", patient: { name: "Kirkman", dob: "6/28/1970"} }
];
}
The problem is that the ng-model on your select element overwrites the $scope.appointments array as soon as an item is selected. Use a different scope property for your ng-model value.
Here's an updated plunker: http://plnkr.co/edit/EAExby
The changes to your template would be:
<div ng-controller="ClinicCtrl">
<select
ng-options="item as item.start + '-' + item.end + ':' + item.patient.name for item in appointments"
ng-model="selectedAppointment"
></select>
{{selectedAppointment}} <!-- log out the value just to show it's working -->
</div>
Related
In my application i have select that i bind with options and the user selected saved data on page load.
Fiddle Link for issue
<div ng-app ng-controller="QuestionController">
<ul ng-repeat="question in Questions">
<li>
<div>{{question.Text}}</div>
<select ng-model="Answers['{{question.Name}}']" ng-options="option for option in question.Options">
</select>
<select ng-model="OptSelected" ng-options="option for option in question.Options">
</li>
</ul>
</div>
And in my angular controller
function QuestionController($scope) {
$scope.Answers = {};
$scope.Questions = [{ "Text": "Gender?", "Name": "GenderQuestion",
"Options": [{1,"Male"}, {2,"Female"}],
"OptSelected": [{1,"Male"}]},{ "Text": "Favorite color?","Name": "ColorQuestion",
"Options": [{1,"Red"}, {2, "Blue"}, { 3,"Green"}],"OptSelected": [{ 2, "Blue"}] }];
angular.forEach($scope.Questions, function(q) {
var propModel = "Answers['" + q.Name + "']";
$scope[propModel] = q.OptSelected;
})
In my application I am successful at binding data to select but i canot set the user saved value to select.
I have tried to recreate the issue with fiddle without much success but I think it will provide you all better understanding of what I am trying to do
I would recommend binding to just the Questions array and avoid the complexity of trying to bind to the corresponding question in an Answers array. You can always extract what you need from the Questions array either after a selection has been made or all together through some controller level action.
That said, part of your problem is that you don't have a well formed array of objects.
Here's a simplified, working version:
var app = angular.module('myApp', []);
app.controller('QuestionController', function($scope) {
$scope.Questions = [{
Text: "Gender?",
Name: "GenderQuestion",
Options: [{
id: 1,
desc: "Male"
}, {
id: 2,
desc: "Female"
}],
OptSelected: {
id: 1,
desc: "Male"
}
}, {
Text: "Favorite color?",
Name: "ColorQuestion",
Options: [{
id: 1,
desc: "Red"
}, {
id: 2,
desc: "Blue"
}, {
id: 3,
desc: "Green"
}],
OptSelected: {
id: 2,
desc: "Blue"
}
}];
});
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
</head>
<div ng-controller="QuestionController">
<ul ng-repeat="question in Questions">
<li>
<div>{{question.Text}}</div>
<select ng-model="question.OptSelected" ng-options="option as option.desc for option in question.Options track by option.id">
</select>
</li>
</ul>
</div>
</html>
I am trying to get selected input values into a hidden field, can any one help me on this, up to now as i am trying with below code.
Html
<select data-bind="options: packages,
optionsCaption: 'Select...',
optionsText: 'name',
value: selectedPackage">
</select>
</br>
<!-- ko with : selectedPackage -->
</br>
<select data-bind="options: locationOptions,
optionsCaption: 'Select...',
optionsText: 'location',
value: $parent.selectedLocation">
</select>
<!-- /ko -->
Display values at
<span data-bind="with: selectedPackage">
<b data-bind="text: name"></b>
<!-- ko with : $parent.selectedLocation -->
> <b data-bind="text: location"></b>
<!-- /ko -->
</span>
</td>
<td>
<span data-bind="with: selectedPackage">
<b data-bind="text: price"></b> $ +
<!-- ko with : $parent.selectedLocation -->
$<b data-bind="text: price"></b>
<!-- /ko -->
</span>
Js/Knockout code
this.packages = [
{
sku : "306",
name: "Standard delivery hours (8-4)",
description: "its nice",
price: 99,
locationOptions : []
},
{
sku : "100",
name: "Within a 4 hour window (adds $15)",
description: "its nice",
price: 100,
locationOptions : [
{ location: "6:00 AM - 10:00 AM (off hours)", price: 15},
{ location: "6:30 AM - 10:30 AM (off hours)", price: 15},
{ location: "7:00 AM - 11:00 AM (off hours)", price: 15}
]
},
{
sku : "101",
name: "Within a 2 hour window (adds $25)",
description: "its cool",
price: 100,
locationOptions : [
{ location: "8:00 AM - 10:00 AM", price: 25},
{ location: "10:00 AM - 12:00 PM", price: 25},
{ location: "12:00 AM - 02:00 PM", price: 25}
]
},
{
sku : "102",
name: "Within a 1 hour window (adds $40)",
description: "its cool",
price: 100,
locationOptions : [
{ location: " 8:00 AM - 9:00 PM", price: 40},
{ location: "9:30 AM - 10:00 PM", price: 40},
{ location: "10:00 AM - 11:00 PM", price: 40}
]
}
];
this.selectedPackage = ko.observable();
Everything is working fine, but i am trying to get the selected dependent values in to a hidden filed, but values are not rendering.
<input id="return_order_dependent" type="hidden" name="return_order_dependent" data-bind='value: selectedPackage().name' />
The problem is that selectedPackage can be null or undefined. Whenever this happens, your value data-bind throws an error:
selectedPackage().name becomes undefined.name throws Cannot read property 'name' of undefined
The undefined/null value is a result of the optionsCaption binding. Without the caption, knockout wil set your selected value to the first element in the list upon applying the select binding.
You'll need to do 2 things:
Determine how you want to indicate an unset value
Make sure the data-bind doesn't break.
Personally, I'd use a computed and manage the unset state in your viewmodel:
this.hiddenInputValue = ko.pureComputed(() => {
return (this.selectedPackage() || { name: "NOT_SET" }).name;
});
With data-bind:
<input type="hidden" data-bind='value: hiddenInputValue' />
You can also put this logic in the data-bind itself (this example defaults to null)
<input type="hidden" data-bind='value: selectedPackage() ? selectedPackage().name : null' />
Other solution directions are:
Remove the optionsCaption, always select the first value by default
Place an if or with around the hidden input (this might not work with your server related stuff)
I want to do following:
Show all the html elements on the page based on some conditions,
my understanding was i can use ng-if.
If employeeList is empty then do i need to create another copy of the inner elements to make sure it shows on the page
ng-if prints both divs and spans which only one should be printed my html is this
html:
<div class="container" ng-controller="profileController" ng-init="loadProfilesData()">
<div ng-repeat="p in profileData">
<div>{{p.company}}</div>
<div>{{p.department}}</div>
<div ng-repeat="emp in p.employeeList"></div>
<div ng-if="emp.Tag== 'Devo100'" gauge-chart class="gauge" id="Devo100-{{p.Id}}" value=p.Value*100></div>
<div ng-if="emp.Tag!= 'Devo100'" gauge-chart class="gauge" id="Devo100-{{p.Id}}" value=0></div>
<span ng-if="emp.Tag== 'Devo102'">
{{ p.Value | date: "hh:mm:ss" }}
</span>
<span ng-if="emp.Tag== 'Devo102'">
0
</span>
</div>
</div>
</div>
my json is following
profileData: [
{
ID: "1",
metricStatList: [{"Value":0.003,"Stat":{"parameter":0,"Name":"test0","Tag":"Devo100"}},
{"Value":0.004,"Stat":{"parameter":0,"Name":"test1","Tag":"Devo101"}},
{"Value":0.005,"Stat":{"parameter":0,"Name":"test2","Tag":"Devo102"}}],
comapny: "MSDFT",
department: "Sales"
},
{
ID: "2",
metricStatList: null,
comapny: "MSDFT",
department: "HR"
},
{
ID: "3",
metricStatList: [{"Value":0.003,"Stat":{"parameter":0,"Name":"test0","Tag":"Devo100"}},
{"Value":0.004,"Stat":{"parameter":0,"Name":"test1","Tag":"Devo101"}}],
comapny: "MSDFT",
department: "Development"
},
{
ID: "4",
metricStatList: [{"Value":0.1,"Stat":{"parameter":0,"Name":"test2","Tag":"Devo102"}},
{"Value":0.25,"Stat":{"parameter":0,"Name":"test1","Tag":"Devo101"}}],
comapny: "MSDFT",
department: "Finance"
},
{
ID: "5",
metricStatList: [{"Value":0.233,"Stat":{"parameter":0,"Name":"test0","Tag":"Devo100"}}],
comapny: "MSDFT",
department: "Accounts"
}
]
I render a select multiple in Ractive with a computed list of all options possible, which works great. But I could not find a proper way of preselecting values.
So far I have something like:
data = [{
type: "Person",
Name: "John",
worksFor: [
"1",
"2"
]},{
type: "department",
id: "1",
Name: "Sales"
},{
type: "department",
id: "2",
Name: "Marketing"
},{
type: "department",
id: "3",
Name: "Accounting"
}]
new Ractive({
el: '#list',
template: DataTpl,
data: {myData: data},
computed: {
DepartmentList () {
//some code
return list_of_all_Departments;
},
PersonsList () {
//some Code
return list_of_persons
});
So in my Template I tried
{{#PersonsList}}
<select multiple>
{{#DepartmentList}}
<option value="{{id}}"
{{#if _.includes(PersonsList.worksFor, id)}} selected{{/if}}>{{Name}}
</option>
{{/DepartmentList}}
</select>
{{/PersonsList}}
But this just gave me a failed to compute. Does anyone know how to get those preselects?
This is one of the things where Ractive deviates from standards. You need to put a value attribute on <select>. The selected <option>'s value becomes <select>'s value. The kind of data you'll get from <select> depends if it's multiple or not. If it's a single-select, you get a single value. If it's multiple-select, you'll get an array.
Setting a pre-selected value is simply the other way around. Assign a value from your data to <select>'s value and, assuming those values exist on the <option>s, they'll be selected. No template mangling required.
Ractive.DEBUG = false;
var data = [{
type: "Person",
Name: "John",
worksFor: [
"1",
"2"
]
}, {
type: "department",
id: "1",
Name: "Sales"
}, {
type: "department",
id: "2",
Name: "Marketing"
}, {
type: "department",
id: "3",
Name: "Accounting"
}];
new Ractive({
el: '#list',
template: '#template',
data: {
selectedDepartments: [],
myData: data
},
computed: {
DepartmentList() {
return this.get('myData').filter(v => v.type === 'department');
},
PersonsList() {
return this.get('myData').filter(v => v.type === 'Person');
}
}
});
<script src="https://unpkg.com/ractive#0.8.11/ractive.min.js"></script>
<div id="list"></div>
<script type="template/ractive" id="template">
{{#PersonsList}}
{{ Name }}
<select multiple value="{{ worksFor }}">
{{#DepartmentList}}
<option value="{{id}}">{{Name}}</option>
{{/DepartmentList}}
</select>
{{/PersonsList}}
</script>
you must give the select a value and set the value to whatever is the default value
I could not figure out why the following code doesn't work at all. Frankly, It looks alright to me. Is there any idea?
<!DOCTYPE html>
<html data-ng-app="">
<head>
<title>Using AngularJS to create a simple Controller</title>
</head>
<body>
<div data-ng-controller="simpleController">
<ul>
<li data-ng-repeat="cust in customers">{{ cust.Name | uppercase }} - {{ cust.City | lowercase }}</li>
</ul>
</div>
<script
type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js">
</script>
<script>
function simpleController($scope) {
$scope.customers = [
{ Name: "Dave Jones", City: "Phoenix" }
, { Name: "Jamie Riley", City: "Atlanta" }
, { Name: "Heedy Walhin", City: "Chandler" }
, { Name: "Thomas Winter", City: "Seattle" }
];
}
</script>
</body>
</html>
It is to do with the version of angular you are using.
Earlier versions of Angular allowed the ability to assign controller functions to the global scope like you did.
Then this ability was removed from angular.
There are still alot of tutorials around that reference this older style however.
See this demo - http://jsbin.com/fowamutoli/1/edit
I have replaced with angular legacy and your code runs.
So in the future you need to declare an angular module and register your controller against it.
i.e.
<html data-ng-app="app">
<script>
var app = angular.module('app', []).
controller('simpleController', function ($scope) {
$scope.customers = [
{ Name: "Dave Jones", City: "Phoenix" }
, { Name: "Jamie Riley", City: "Atlanta" }
, { Name: "Heedy Walhin", City: "Chandler" }
, { Name: "Thomas Winter", City: "Seattle" }
];
});
</script>
https://docs.angularjs.org/guide/controller
try replacing your data-ng-app to ng-app="myApp", see if it works. :) with the following snippet.
var myApp = angular.module('myApp',[]);
myApp.controller('simpleController', ['$scope', function($scope) {
$scope.customers = [
{ Name: "Dave Jones", City: "Phoenix" }
, { Name: "Jamie Riley", City: "Atlanta" }
, { Name: "Heedy Walhin", City: "Chandler" }
, { Name: "Thomas Winter", City: "Seattle" }
];
}]);
Try this instead:
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<title>Using AngularJS to create a simple Controller</title>
</head>
<body>
<div ng-controller="simpleController">
<ul>
<li ng-repeat="cust in customers">{{ cust.Name | uppercase }} - {{ cust.City | lowercase }}</li>
</ul>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
<script>
var myApp = angular.module( "MyApp", [] );
myApp.controller("simpleController", function( $scope )
{
$scope.customers = [
{ Name: "Dave Jones", City: "Phoenix" }
, { Name: "Jamie Riley", City: "Atlanta" }
, { Name: "Heedy Walhin", City: "Chandler" }
, { Name: "Thomas Winter", City: "Seattle" }
];
});
</script>
</body>
</html>
http://jsfiddle.net/rv7r7nv7/