Okay, I have an Angular powered CRUD system here, and for the most part everything seems to be working right except for the dropdown. This was originally written for SQL but I have an all JSON version here http://codepen.io/StuffieStephie/pen/QEaGPY
JSON is formatted as such
$scope.names = [
{
"id": "26",
"name": "Lena Oxton",
"email": "tracer#overwatch.com",
"phone": "8003005000",
"status": "BANNED",
"created": "2016-07-12 03:42:50",
"unix": "1468294848273"
}, {//MORE objects...
}];
I have a function called 'readOne' which puts the values of the JSON object I want to edit in a modal form.
$scope.readOne = function(item){
$scope.entry = item;
$scope.entry.name = item.name;
$scope.entry.email = item.email;
$scope.entry.phone = item.phone;
$scope.entry.status = item.status;
// show modal
$('#modal-volunteer-form').openModal();
}; // END READ ONE
This all works fine EXCEPT for the status (a dropdown) which doesn't get put into the form.
Here's the select
<!-- STATUS SELECT FOR CREATE / UPDATE MODAL FORM -->
<select name="status" ng-model="entry.status">
<option ng-selected="{{option.value == entry.status}}" ng-repeat="option in options" value="{{option.value}}">{{option.displayName}}</option>
</select>
Here's the options array
$scope.entry = { };
$scope.entry.status = 'APPLIED';
$scope.options = [{
value: 'APPLIED',
displayName: 'APPLIED'
}, {
value: 'APPROVED',
displayName: 'APPROVED'
}, {
value: 'WITHDRAWN',
displayName: 'WITHDRAWN'
}, {
value: 'DISMISSED',
displayName: 'DISMISSED'
}, {
value: 'BANNED',
displayName: 'BANNED'
}];
You'll notice that I successfully set the status to 'APPLIED' in the controller, but I can't seem to set it again. Am I using ng-selected correctly?
Related
I've created a kendo grid, and need to insert kendo drop down into one of the columns. I need to get the data for the drop down from another data source. It kind of works, however, the problem is when I have chosen a value from the drop down and the drop down closes, instead of displaying that value it goes into editable mode. Only when I click outside of the dropdown, it displays the correct value. Here is a gif of the issue:
https://media2.giphy.com/media/KyMGB7FmFQMVTChFA7/giphy.gif
How could this issue be solved?
I have successfully created a kendo grid with a drop down list already. The only difference seems to be that there only one data source is used, but here two are used. Here is some of the code for the drop down:
title: "Type",
field: "productType.name", //this property is from the data source used for grid
template: "<kendo-drop-down-list k-value=\"dataItem.productType.id\"
k-options=\"productTypeOptions\" ng-change=\"productTypeChanged(dataItem, 'productType')\"
ng-model=\"dataItem.productType.id\"></kendo-drop-down-list>"
}...];
$scope.productTypes = {
data: [{ name: "Value 1", id: "1" }, { name: "Value 2", id: "2" }]
}
$scope.productTypeDataSource = new kendo.data.DataSource({
schema: {
data: "data",
model: {
fields: {
id: { type: "number" },
name: { type: "string" }
}
}
},
data: $scope.productTypes,
serverPaging: true,
serverSorting: true,
serverFiltering: true
});
$scope.productTypeOptions = {
dataSource: $scope.productTypeDataSource,
dataTextField: "name",
dataValueField: "id"
};
$scope.productTChanged = function (dataItem, field, productArray, dataSource) {
var index = dataSource.indexOf(dataItem);
var c = productArray.data[index];
if (c == null) return;
c[field] = dataItem[field];
return c;
};
$scope.productTypeChanged = function (dataItem, field) {
$scope.productTChanged(dataItem, field, $scope.products, $scope.productDataSource);
};```
1).I have three names Bert,Charles,Denise.
with their observable Indexes(Used current.observableIndex).
0: Bert , 1: Charles , 2: Denise
Their Current Status shown in-front of their names(Used current.data.status)
2).Each an every name has drop down and submit button.(Used oj-bind-for-each)
3).I can select value from the drop-down and submit(It will catch the selected value from the drop down)
Action
Initial Page View
Suppose I have selected
0: Bert and drop-down value as Firefox
1: Charles and drop-down value as Safari
2: Denise and drop-down value as Opera
Then I click the Submit button which is from the 0: Bert
Problem
The Submit Button Catches the Opera which I selected last from 2: Denise
Expectation
I want to get the Firefox for the 0: Bert submit button Click.
How Could I achieve this?
Code
dashboard.html
<div>
<oj-bind-for-each data="[[dataProvider]]">
<template>
<li>
<oj-bind-text value="[[$current.data.status]]"></oj-bind-text>
<oj-bind-text value="[[$current.observableIndex]]"></oj-bind-text> : <oj-bind-text value="[[$current.data.name]]"></oj-bind-text>
<oj-button class='oj-button-sm' on-oj-action= "[[saveData]]">
Submit
</oj-button>
<oj-select-one id="[[uniquieId]]"
on-value-changed="[[selectedValue]]" options="[[browsers]]"
value="{{$current.data.status}}" style="max-width:20em">
</oj-select-one>
</li>
</template>
</oj-bind-for-each>
</div>
dashboard.js
define(['accUtils', 'knockout', 'ojs/ojarraydataprovider', 'ojs/ojknockout', 'ojs/ojbutton', 'ojs/ojselectcombobox'],
function (accUtils, ko, ArrayDataProvider) {
function DashboardViewModel() {
var self = this;
self.uniquieId = ko.observable();
var users = ko.observableArray([
{id: "1", name: "Bert", status: "Internet Explorer"},
{id: "2", name: "Charles", status: "Chrome"},
{id: "3", name: "Denise", status: "Safari"}
]);
self.dataProvider = new ArrayDataProvider(users, {keyAttributes: 'id'});
self.selectVal = ko.observable('Chrome');
self.selected = ko.observable();
self.browsers = ko.observableArray([
{value: 'Internet Explorer', label: 'Internet Explorer'},
{value: 'Firefox', label: 'Firefox'},
{value: 'Chrome', label: 'Chrome'},
{value: 'Opera', label: 'Opera'},
{value: 'Safari', label: 'Safari'}
]);
self.selectedValue = function (event, current) {
var optionValue = event.detail;
self.selected(optionValue.value);
console.log(self.selected());
console.log(optionValue);
};
self.saveData = function (event, current) {
self.uniquieId(current.observableIndex());
console.log(self.uniquieId());
console.log(self.selected());
};
}
return DashboardViewModel;
}
);
There are 2 fixes to be made:
In the oj-select-one component you are binding the selected value to "{{$current.data.status}}". But for this to work correctly, $current.data.status has to be capable of getting its value updated and then reflecting the latest value. This is not possible when you make 'status' a simple string.
Instead, they should be observables:
var users = ko.observableArray([
{id: "1", name: "Bert", status: ko.observable("Internet Explorer")},
{id: "2", name: "Charles", status: ko.observable("Chrome")}),
{id: "3", name: "Denise", status: ko.observable("Safari")}
]);
In other words, any value bound between the View and Viewmodel that has to be updated through user interaction should be an observable.
There is no use of the selected observable, because the selectedValue function simply updates selected to whatever was selected last. Instead, you can use your other variable uniquieId to get the correct data because your saveData function updates uniquieId with the index of the row you just clicked Submit on.
So change your saveData function to this:
self.saveData = function (event, current) {
self.uniquieId(current.observableIndex());
console.log(self.uniquieId());
console.log(users()[self.uniquieId()].status());
};
I have two select controls.
One is dependent on the other. For a simple example, let's assume the first displays a list of cities, while the other displays a list of streets in each city.
When the page initially loads, the select control displaying the streets is showing all the available streets. However, once the user chooses a city in the first select, the second select is filtered to display streets belonging to the selected city only.
This works OK when using the options binding, however, I need the ability to generate optgroups and options binding does not support it, so I have to use the foreach binding.
The result is that whenever a city is selected, two unintended consequences occur:
The second select (the filtered list of streets) appear to have the first street of the selected city chosen, even though I'm using valueAllowUnset: true. This is not reflected in the view model
When actually choosing a street in the second select and then choosing a different city in the first select, the second select updates properly to reflect the changes in the list, but the view model does not, thereby still retaining the previously selected value (even though it's not in the list anymore). Even If I remove valueAllowUnset: true from the second select, the issue still remains.
Is there any workaround to this issue? I really have to use the foreach binding instead of the options binding.
JSFiddle: https://jsfiddle.net/jfxovLna/13/
var ViewModel = function() {
var self = this;
var regionAndCityArray = [{
regionName: "Europe",
cities: [{
cityName: "London",
additionalUnimportantInformation: 100
}, {
cityName: "Paris",
additionalUnimportantInformation: 200
}]
}, {
regionName: "North America",
cities: [{
cityName: "New York",
additionalUnimportantInformation: 45
}]
}];
var cityAndStreetArray = [{
cityName: "London",
streets: [{
streetName: "Parker",
streetLength: 5
}, {
streetName: "Macklin",
streetLength: 10
}, ]
}, {
cityName: "New York",
streets: [{
streetName: "5th Avenue",
streetLength: 3
}, {
streetName: "Park Ave",
streetLength: 12
}]
}, {
cityName: "Paris",
streets: [{
streetName: "Rue de Turbigo",
streetLength: 11
}, {
streetName: "Rue aux Ours",
streetLength: 12
}]
}];
var getAvailableStreets = function() {
var availableStreets = cityAndStreetArray;
var selectedCity = self.selectedCity();
var selectedRegion = _.find(regionAndCityArray,
function(region) {
return _.find(region.cities,
function(city) {
return city.cityName === selectedCity;
});
});
if (selectedRegion == undefined) {
return availableStreets;
}
var filteredStreets = _.filter(cityAndStreetArray,
function(city) {
return city.cityName === selectedCity;
});
return filteredStreets;
}
self.availableCities = ko.observableArray(regionAndCityArray);
self.selectedCity = ko.observable();
self.availbleStreets = ko.computed(getAvailableStreets);
self.selectedStreet = ko.observable();
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
First, add an empty option to your select input.
<option value="">Select Street</option>
Now subscribe to the selectedCity property of your view model.
Whenever it changes, programmatically set the selectedStreet to ''.
viewModel.selectedCity.subscribe(function() {
viewModel.selectedStreet('');
}, viewModel);
This way you can solve both your issues.
Made the changes in your fiddle and it works. tries to update it.
Here is a fiddle - https://jsfiddle.net/Shabi_669/w1vcjbjo/
I am working with angular and semantic ui. I am trying to make a selection of Y and N through a select option. Basically i just want the first item was selected when the page show up. Tried many ways but i couldn't make it works.
Please take a look at this plunker.
angular.module('myapp', [])
.controller('testctrl', function ($scope){
$scope.add = {};
$scope.Consigns = [{value: 'N',label: 'N'}, {value: 'Y',label: 'Y'}];
$scope.add.consign = $scope.Consigns[0].label;
})
.controller('testctrl1', function ($scope){
$scope.add = {};
$scope.Consigns1 = [{value: 'N',label: 'N'}, {value: 'Y',label: 'Y'}];
$scope.add.consign1 = $scope.Consigns1[0].label;
});
https://plnkr.co/edit/cHcLd14xKFxLMS4uy0BM?p=preview
Print the model value in default placeholder. Rather than sending the label value in $scope.add.consign you could send the whole object and print whats required.
Working plunker: https://plnkr.co/edit/XeuiS7p3K1OOx5nHL9c5?p=preview
javascript:
$scope.ListOrder =
[
{ Name: "price", Id: 1 },
{ Name: "exist", Id: 2 },
{ Name: "Sale", Id: 3 },
{ Name: "New", Id: 4 }
];
$scope.Order = { Name: "exist", Id: 1 };
HTML:
<select ng-model="Order" ng-options="obj.Name for obj in ListOrder"></select>
Remove
<script>
$('.ui.dropdown').dropdown();
</script>
and also change select tag to this
<select ng-model="add.consign" class="ui fluid dropdown" ng-options="x.label as x.label for x in Consigns">
<option value=""></option>
</select>
I am using AngularJS directive and I need to set a selected option of a dropdown list in my template.
<select id="energySource" ng-options="o.name for o in energyOptions" ng-model="energy" ng-selected="energy" ng-change="energyChange();"></select>
The content of the optionlist depends on resources send by a server when the page is loaded.
var energyChosen = "All";
angular.element(document).ready(function () {
$.get('/Dashboard/GetResources', function (data) {
scope.Resources = data;
scope.energyOptions = [{ name: scope.Resources.Electricity, id: "Electricity" }, { name: scope.Resources.Gas, id: "Gas" },
{ name: scope.Resources.Water, id: "Water" }, { name: scope.Resources.Solar, id: "Solar" }];
scope.energy = scope.energyOptions[0];
energyChosen = scope.energy.id;
scope.$apply();
});
It works except that a blank option is preselected which disappears when i select an option
I would like to be able to preselect one option. I thought that
scope.energy = scope.energyOptions[0];
would do the trick but it didn't. How can i preselect an option in this case ?
The way you are doing your ng-options it will store the name of the option in scope.energy not the whole option. You were on the right track when you did:
scope.energy = scope.energyOptions[0];
But it won't work because it expects scope.energy to be the name and not the whole option. What you want to do in your ng-options is something like:
<select id="energySource" ng-options="o as on.name for o in energyOptions" ng-model="energy" ng-selected="energy" ng-change="energyChange();"></select>
The important change is the addition of the o as o.name. The 'o' on the left is what will actually be selected and stored in your scope.energy, while the as o.name is the text that will be displayed on your pull down.
Make sure the scope.energy is outside your initialization.
$scope.energyOptions = [
{ name: "test1", id: "Electricity" },
{ name: "test2", id: "Gas" },
{ name: "test3", id: "Water" },
{ name: "test4", id: "Solar" }];
$scope.energy = $scope.energyOptions[2];