Setting default item of select box using angularjs - angularjs

I'm trying to set the default item of a select box on load using angularjs.
I load both select boxes from 2 json's, so the second select box, named 'city' relies off the first select box 'country':
<label>Country:</label>
<select name="country" ng-model="form.country"
ng-options="c.n for c in countryList"
ng-change="countryChanged()" required></select>
<label>City:</label>
<select name="city" ng-model="form.city"
ng-options="c for c in cityList" required></select>
PLUNKER
http://plnkr.co/edit/hKZLbMbwGfmaa8CtSy0H?p=preview
It loads the select boxes using $http.get. It loads all well and good if i default it to the first option. But lets say, I want to specify a certain option to be selected on load, but I can only send it a particular value from the json, how would I do this? In the code below, the commented line is what I've tried, but all it does is load the correct city list, but leave the country select box unselected.
countries.json
[
{"c":"au","n":"Australia","g":"1"},
{"c":"fr","n":"France","g":"2"},
{"c":"ge","n":"Germany","g":"2"}
]
Controller:
$http.get('countries.json')
.success(function (data) {
$scope.countryList = data;
$scope.form.country = data[0];
// $scope.form.country.c = 'fr'; <<<--- *trying to set default*
$scope.countryChanged();
});
$scope.countryChanged = function() {
$http.get($scope.form.country.c + '-cities.json')
.success(function (data) {
$scope.cityList = data;
$scope.form.city = data[0];
});
}
Also, if there is a better way to achieve this, please post it.
Note: I can't join the json up. I split it because in the real world, there could be 100 countries each with 100 cities each and the json would be quite massive.

Not sure, but does this satisfy the requirement?
http://plnkr.co/edit/rBDVzg7iXfaHu4XmiVsb?p=preview
var selectCountry = function( data, code ) {
for ( var i = 0; i < data.length; i++ ) {
var country = data[ i ];
if ( country.c !== code ) { continue; }
return country
}
};
$http.get('countries.json')
.success(function (data) {
$scope.countryList = data;
$scope.form.country = selectCountry( data, 'fr');
$scope.countryChanged();
});

Just set inside your controller at line 12:
$scope.form.country = data[1];
It sets France as default, Hope I understood your question.

Related

Using angularjs uib-typeahead to show viewvalue different from ng-model

I have a uib-typeahead input.
I need to use a async call to populate it.
I´d like to set ng-model to "CODIGO", but I need the viewvalue showing
"DESCRICAO".
My problem is that after I select a item, ng-model is correct but the viewvalue is not the "DESCRICAO". It is the "CODIGO" as well.
getCBOEspecialidadesByDesc is a async service returning:
[{CODIGO:1, DESCRICAO:'TESTE1'},
{CODIGO:2, DESCRICAO:'TESTE2'},
{CODIGO:3, DESCRICAO:'TESTE3'}
....
]
//controller
$scope.getAllProfissoes=function(val){
return dataService.getCBOEspecialidadesByDesc(val).then((response)=> {
return response.data.results
}, (erro)=> {
console.log(erro)
}
)}
//markup
<input name="usuarioProfissional.prof" type="text" ng-model="profissional.COD_CBO_3"
uib-typeahead="item.CODIGO as item.DESCRICAO for item in getAllProfissoes($viewValue)"
typeahead-editable="false"
class="form-control">
Mysql tables:
CREATE TABLE STAFF (
ID BIGINT AUTO_INCREMENT NOT NULL
, ATIVO BOOLEAN NOT NULL
, NOME VARCHAR( 100 ) NOT NULL
, COD_CBO_3 VARCHAR( 10 )
, CONSTRAINT PK_STAFF_NH
PRIMARY KEY ( ID )
)ENGINE=INNODB;
//used to fill COD_CBO_3 in staff table
CREATE TABLE CBO_ESPECIALIDADES (
ID BIGINT AUTO_INCREMENT NOT NULL
, CODIGO VARCHAR( 10 )
, DESCRICAO VARCHAR( 255 )
, CONSTRAINT PK_ESPEC_NH
PRIMARY KEY ( ID )
)ENGINE=INNODB;
//angular service
angular.module("clinang").service('dataService', ['$http','config', function ($http,config) {
var urlBase = config.baseUrl;
this.getCBOEspecialidadesByDesc = function (sel) {
return $http.get(urlBase+'/cbo_especialidades/ByDesc/'+sel);
};
}]);
//server router
'use strict';
const express = require('express');
const router = express.Router();
const callback=function(err,data,res){
console.log(data)
if (err) return res.status(500).json(err);
return res.status(200).send(data);
}
//used by getCBOEspecialidadesByDesc angular service
router.get('/ByDesc/:id',function(req,res,next){
const searchString=req.params.id||'';
var params = ['%'+searchString+'%'];
console.log(params);
req.getConnection(function (err, connection) {
var ret
connection.query('select * from CBO_ESPECIALIDADES where descricao like ?',params, function (error, results, fields) {
if (error){
ret={success:false, results:error}
}
else {
ret={success:true, results:results}
}
callback(error,ret,res)
});
});
});
This is the way uib-typeahead works.
You can use two tricks to perform what you want.
1) Save the entire object as model
// markup
<input name="usuarioProfissional.prof" type="text" ng-model="profissional.COD_CBO_3"
uib-typeahead="item as item.DESCRICAO for item in getAllProfissoes($viewValue)"
typeahead-editable="false"
class="form-control">
profissional.COD_CBO_3 will contains the whole object. {CODIGO:1, DESCRICAO:'TESTE1'} you have to take it into account when manipulating it.
2) Keep the CODIGO - DESCRICAO mapping and use a formatter
// JS
$scope.formatter = function(model) {
return $scope.mappings.get(model);
}
$scope.mappings = new Map();
$scope.getAllProfissoes=function(val){
return dataService.getCBOEspecialidadesByDesc(val).then((response)=> {
response.data.results.forEach((result) => {$scope.mappings.set(result.CODIGO, result.DESCRICAO);})
return response.data.results
}, (erro)=> {
console.log(erro)
}
)}
// Markup
<input name="usuarioProfissional.prof" type="text" ng-model="profissional.COD_CBO_3" typeahead-input-formatter="formatter($model)"
uib-typeahead="item.CODIGO as item.DESCRICAO for item in getAllProfissoes($viewValue)"
typeahead-editable="false"
class="form-control">
You can view here an example with this solution (Asynchronous results part).
Wich solution to use
The solution depends of your use case. If you need to repopulate the field somewhere (edit form by example) you should consider the first one.
If you don't need to repopulate it you can use the second one.

Select first value from select box by default - AngularJS

I have two select boxes. The second select box populates from first select box.
I have applied a filter for the second select box to populate as per the options selected in first select box. The second select box populates from an array var outputformats = [];
This is my code
HTML
<select name="reporttype"id="reporttype"
ng-init="reporttype='1115'"
ng-model="reporttype">
<option value="1115">Previous Day Composite Report</option>
<option value="1114">ACH Receive</option>
</select>
<select name="outputformat" id="outputformat"
ng-model="outputformat"
ng-options="format for format in outputformats | outputformatfilter: reporttype:this">
</select> Value : {{outputformat}}
Filter
angular.module('myApp.outputformatfilter',[])
.filter('outputformatfilter', function () {
return function (input,selectedreport,scope) {
var outputFormatReport = {"1115":"HTML,PDF","1114":"CSV,EXCEL"};
var outputformats = outputFormatReport[selectedreport].split(',');
return outputformats;
};
});
Now what I want is whenever the options in second select box changes, its first option should be selected by default, that is the first option from the array should be selected by default.
UPDATE:
Updated fiddle, added ng-if= reporttype !== '' to second select box
FIDDLE
On your controller, watch the filtered options and act on that:
function myController ($scope) {
// watch the filtered output formats
$scope.$watchCollection("filteredOutputFormats", function(val) {
// select the first one when it changes
$scope.outputformat = val[0];
});
}
Make sure you assign the filtered results to a $scope variable:
<select name="outputformat" id="outputformat"
ng-model="outputformat"
ng-options="format for format in filteredOutputFormats = (outputformats | outputformatfilter: reporttype:this)">
</select>
JSFIDDLE
Try this:-
var myApp = angular.module('myApp',['myApp.outputformatfilter']);
myApp.controller('mainController',function($scope,$filter){
var outputformats = [];
$scope.outputFormatReport = {"1115":"HTML,PDF,CSV,EXCEL","1114":"PHP,HTML,PDF","default":"CSV,HTML"};
$scope.$watch('reporttype', function (newValue, oldValue, scope) {
outputformats = $scope.outputFormatReport[newValue].split(',');
$scope.outputformat=outputformats[0]
});
});
angular.module('myApp.outputformatfilter',[]).filter('outputformatfilter', function () {
return function (input,selectedreport,scope) {
console.log('input is '+input+' \nReport is '+selectedreport);
console.log(scope.outputFormatReport);
if(selectedreport!= undefined){
var outputformats =
console.log( scope.outputFormatReport[selectedreport]);
outputformats = scope.outputFormatReport[selectedreport].split(',');
console.log(outputformats);
}else{
return {};
}
return outputformats;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="mainController">
<select name="reporttype"id="reporttype" ng-init="reporttype='1115'" ng-model="reporttype">
<option value="1115">Previous Day Composite Report</option>
<option value="1114">ACH Receive</option>
</select>
<select name="outputformat" id="outputformat" ng-model="outputformat" ng-options="format for format in outputformats | outputformatfilter: reporttype:this">
</select> Value : {{outputformat}}
</div>
</body>

Multiple dropdown selection in ag-grid (link Attached)

I need to have a column in ag-grid where i can select multiple values from dropdown. I just googled online to see if it is already implemented but i could find only one link.
https://gist.github.com/gaborsomogyi/00f46f3c0ee989b73c92
Can someone let me know how to implement it. show the full code as an example please.
Here is the code shared over there.
function agDropDownEditor(params, optionsName, optionsList) {
_.set(params.$scope, optionsName+'.optionsList', optionsList);
var html = '<span style="width:100%; display:inline-block" ng-show="!'+optionsName+'.editing" ng-click="'+optionsName+'.startEditing()">{{data.'+params.colDef.field+'}}</span> ' +
'<select style="width:100%" ng-blur="'+optionsName+'.editing=false" ng-change="'+optionsName+'.editing=false" ng-show="'+optionsName+'.editing" ng-options="item for item in '+optionsName+'.optionsList" ng-model="data.'+params.colDef.field+'">';
// we could return the html as a string, however we want to add a 'onfocus' listener, which is not possible in AngularJS
var domElement = document.createElement("span");
domElement.innerHTML = html;
_.set(params.$scope, optionsName+'.startEditing', function() {
_.set(params.$scope, optionsName+'.editing', true); // set to true, to show dropdown
// put this into $timeout, so it happens AFTER the digest cycle,
// otherwise the item we are trying to focus is not visible
$timeout(function () {
var select = domElement.querySelector('select');
select.focus();
}, 0);
});
return domElement;
}
Hope this helps, this is just a snippet of my code what i'm doing is I'm fetching from an array using map and then creating my object which is col and returning it and this will repeat till the last index of that array.
var col = {};
col.field = "fieldName";
col.headerName = "colName";
col.headerCellTemplate = function() {
var eCell = document.createElement('span');
eCell.field = obj.expr;
eCell.headerName = obj.colName;
eCell.innerHTML = "<select>"+"<option>"+
'Abc'+"</option>" +"<option>"+
'Xyz'+"</option>" +"</select>"
//$scope.dropDownTemplate;
var eselect = eCell.querySelector('select');
eselect.focus();
return eCell;
};
return col ;
}));

How can I display one attribute of a set of data just once?

I'm doing some testing with Angular to see if I can replicate what I already have in PHP more efficiently.
I have a set of data stored in JSON:
[
{
"name":"Blue Widget",
"description":"blue-widget",
"snippet":"The best blue widget around!",
"category":"Home Widgets",
"popular":true
},
{
"name":"Red Widget",
"description":"red-widget",
"snippet":"The best red widget around!",
"category":"Outdoor Widgets",
"popular":true
},
{
"name":"Green Widget",
"description":"green-widget",
"snippet":"The best green widget around!",
"category":"Work Widgets",
"popular":true
},
{
"name":"Yellow Widget",
"description":"yellow-widget",
"snippet":"The best yellow widget around!",
"category":"Home Widgets",
"popular":true
}
]
I'm grabbing this in my controller and adding it to my view in a fairly standard way (yes, I know not to use $http directly in a controller in production):
widgetApp.controller('widgetListCtrl', function($scope,$http){
$http.get('widgets/widgets.json').success(function(data){
$scope.widgets = data
})
})
If I use:
<li ng-repeat="widget in widgets">{{widget.category}}</li>
Then naturally it will just go through and list:
Home Widgets
Outdoor Widgets
Work Widgets
Home Widgets
What I'd like to do is generate a list of each widget.category but with each category only appearing once, so a user could then click on a category and be shown all the widgets in that category. How can I go about this? Sorry, I haven't got anything to go on because I pretty much have no idea where to start.
You can use the existing 'unique' filter from AngularUI.
<li ng-repeat="widget in widgets | unique: 'widget.category' ">{{widget.category}}</li>
Be sure to include a reference to the filters module in your app as well (e.g. angular.module('yourModule', ['ui', 'ui.filters']);).
You'd have to build a list of unique categories:
widgetApp.controller('widgetListCtrl', function($scope,$http){
$http.get('widgets/widgets.json').success(function(data){
$scope.uniqueCategories = [];
for (var i = 0; i < $scope.widgets.length; i++) {
if ($scope.uniqueCategories.indexOf($scope.widgets[i].category) === -1)
$scope.uniqueCategories.push($scope.widgets[i].category);
}
});
});
Make a dropdown with the model set to the category:
<select ng-model="categoryFilter" ng-options="category as category for category in uniqueCategories"></select>
And use a filter on your repeat:
<li ng-repeat="widget in widgets | filter: { category: categoryFilter }">{{widget.category}}</li>
Create a filter
app.filter('unique', function() {
return function (arr, field) {
return _.uniq(arr, function(a) { return a[field]; });
};
});
In Markup
<li ng-repeat="widget in widgets | unique:'category'">{{widget.category}}</li>
Create a distinct filiter and use it on your view:
angular.filter("distinct", function () {
return function (data, propertyName) {
if (angular.isArray(data) && angular.isString(propertyName)) {
var results = [];
var keys = {};
for (var i = 0; i < data.length; i++) {
var val = data[i][propertyName];
if (angular.isUndefined(keys[val]) && val != null) {
keys[val] = true;
results.push(val);
};
};
return results;
}
else {
return data;
}
}
})
<li ng-repeat="widget in widgets | distinct:'category'">{{widget.category}}</li>

angularjs multiple selected item does consist of a string and not an object

I have created a select tag with multiple to show it as a listbox and not dropdown.
I have a property which should hold the selected schoolclass which consists of multiple properties like: id, schoolclass , subject, schoolclassIdentifier and color.
When I select now an item in the listbox and press the delete button the $scope.activeStep.selectedSchoolclassCodes array contains one string like "Math10b" actually the selectedSchoolclassCodes array should contain an object created from the above properties.
Why is my selected object wrong?
HTML
<div class="col-md-6">
<select size="10" class="form-control col-md-6" multiple ng-model="activeStep.selectedSchoolclassCodes">
<option class="co-md-6" ng-repeat="item in activeStep.schoolclasses" style="background: rgb({{item.color}})" value="{{item.schoolclassCode}}">{{item.schoolclassCode}}</option>
</select>
</div>
CONTROLLER
'use strict';
angular.module('iplanmylessons').controller('EditSchoolclassCodeWizardStepController', function ($scope, wizardDataFactory, SchoolclassCodeViewModel) {
$scope.activeStep.schoolclassCodeColors = [
'255,165,0',
'255,255,0',
'145,240,140',
'0,128,0',
'170,210,230',
'255,190,200',
'240,130,240',
'100,100,255',
'210,210,210',
'255,0,0'
];
$scope.activeStep.selectedSchoolclassCodes = wizardDataFactory.schoolclassCodesAdded[0];
$scope.activeStep.newSchoolclass = "";
$scope.activeStep.newSubject = "";
$scope.activeStep.newSchoolclassIdentifier = "";
$scope.activeStep.schoolclasses = wizardDataFactory.schoolclassCodesAdded;
$scope.activeStep.schoolclassCodeColorsIsOpen = false;
$scope.activeStep.selectedSchoolclassCodeColor = null;
$scope.activeStep.deleteSchoolclassCode = function () {
for (var i = 0; i < $scope.activeStep.selectedSchoolclassCodes.length; i++) {
var index = Enumerable.from( wizardDataFactory.schoolclassCodesAdded).indexOf(function (s) {
return s.schoolclassCode === $scope.activeStep.selectedSchoolclassCodes[i].schoolclassCode;
});
wizardDataFactory.schoolclassCodesAdded.splice(index, 1);
}
$scope.activeStep.selectedSchoolclassCodes = null;
};
$scope.activeStep.schoolclassCode = function () {
return $scope.activeStep.newSubject + $scope.activeStep.newSchoolclass + $scope.activeStep.newSchoolclassIdentifier;
};
$scope.activeStep.setSchoolclassCodeColor = function (item) {
$scope.activeStep.selectedSchoolclassCodeColor = item;
$scope.activeStep.schoolclassCodeColorsIsOpen = false;
};
});
Have you try ng-options? This post has a good explanation of select/ ng-options with array of objects.
Hope it can help.

Resources