saving dropdown selection in cookie - javascript

I am totally new to Bootstrap and angularjs world and I am stuck at this.
I have a simple select like this below
<div class="pull-left margin-left-20">
<select id="ddlPageSize" class="form-control form-ddl-adj"
ng-model="params.settings().countSelected"
ng-options="item.value as item.text for item in params.settings().countOptions"
ng-change="params.count(params.settings().countSelected)"></select>
</div>
In the controller, I have select values like this
var pageSizeList = [
{ value: 5, text: "5" },
{ value: 10, text: "10" },
{ value: 25, text: "25" },
{ value: 50, text: "50" },
{ value: 100, text: "100" }
];
5 is the option by default. Can some one tell me how to save user selection (say 10) in a cookie so that next time 10 should be the pagesize

You can use ngCookies module of AngularJS. You'll have to include angular-cookies.js in your code: https://code.angularjs.org/1.4.3/angular-cookies.min.js
Include ngCookies in your module declaration:
angular.module('testApp', ['ngCookies'])
Then you can save a cookie as:
$cookies.put('someKey', 'someVal');
You can retrieve a cookie as:
$cookies.get('someKey')
Updated:
Check this fiddle: http://jsfiddle.net/3xyf1bzo/

You can do this with ng-cookies
dropdown selection code html :
<div class="custom-param" ng-controller="themectrl">
<label id="default-lang" class="label">Default Theme:</label>
<select ng-change="themeChange(theme)" ng-model="theme" ng-options="theme.url as theme.name for theme in themes">
</select>
</div>
angularJS code :
var app = angular.module('themectrl', ['pascalprecht.translate','ngCookies'] );
app.controller('themeCtrl', function( $scope , $cookies ) {
$scope.theme = 'theme1.value';
// create the list of bootswatches
$scope.themes = [
{ name: 'Theme 1', url: 'theme1.value' },
{ name: 'Theme 2', url: 'theme2.value' }
];
// on dropdown change function
$scope.themeChange = function($selectedTheme) {
$cookies.put('ppcdfavtheme', $selectedTheme);
$scope.theme = $selectedTheme;
}
});

You can use Persistence Using local storage to save your data if you want I leave a link with working example Good luckAngularJS: Real Time Model Persistence Using Local Storage

Related

angularjs select depending on number of options in model

I currently have a select in an angular app :
http://jsfiddle.net/4qKyx/251/
And I'm trying to manage my select depending on the number of result.
HTML
<div ng-controller="MyCtrl">
<select ng-model="form.type" required="required" ng-options="option.value as option.name for option in typeOptions" >
</select>
</div>
JS
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.typeOptions = [
{ name: 'Feature', value: 'feature' },
{ name: 'Bug', value: 'bug' },
{ name: 'Enhancement', value: 'enhancement' }
];
if($scope.typeOptions.length == 1){
$scope.form = {type : $scope.typeOptions[0].value};
}else{
// first option set to "select an option" and null -> won't work with required
}
}
If I have only one element in my typeOptions, i want the only option to be pre-selected. Now if I have more than one element, I want an option saying "Select an option" but which can't be let selected in a required select. Thank you in advance for any help !
Can you try you controller code as like below,
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.form = {};
$scope.typeOptions = [
{ name: 'Feature', value: 'feature' },
{ name: 'Bug', value: 'bug' },
{ name: 'Enhancement', value: 'enhancement' }
];
$scope.form.type=($scope.typeOptions.length===1) ? $scope.typeOptions[0].value : '';
}
also updated your jsfiddler
The code you've provided on SO works.
Your issue is only on the fiddler with the line
<option style="display:none" value="">select a type</option>
if you want your "placeholder" inside the select, you can do it like that :
if($scope.typeOptions.length == 1){
$scope.form = {type : $scope.typeOptions[0].value};
}else{
$scope.typeOptions.unshift( { name: 'Select a value', value: '' });
}
you can add option element to your select to be like
<select ng-model="" required
ng-options="option.value for option in typeOptions">
<option value=''>- Please Choose -</option>
</select>
and just do the check in you controller if the options.length equals 1 then set the ng-model the good thing is the required validation still works.
here is jsfiddle
if you removed the comment it show select option

How to load template from dropdown menu Angular

I am fairly new to angular and am working with a client that wants a dropdown allowing users to select their neighborhood which is then saved in a cookie to load upon return. I am able to save cookie but am having trouble getting dropdown selected neighborhood to load proper template.
Here is the html:
<select id="mNeighborhood" ng-model="mNeighborhood" ng-options="neighborhood.id as neighborhood.name for neighborhood in neighborhoods" ng-change="saveCookie()"></select>
And then, I have added the following in html:
<div ng-view=""></div>
Here is the app.js code:
var app = angular.module('uSarasota', ['ngCookies', 'ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
template: '<div><h1 style="margin: 200px;">This is our main page</h1></div>'
})
.when('/downtown', {
templateUrl: "templates/downtown.html"
})
.otherwise({
template: '<div><h1 style="margin: 200px;""><strong>NOTHING TO SEE HERE</strong></h1></div>'
})
});
//Select Neighborhood
app.controller('myNeighborhood', ['$scope', '$cookies', function($scope, $cookies) {
$scope.neighborhoods = [{
name: "My Neighborhood",
id: 0
}, {
name: "All of Sarasota",
id: 1
}, {
name: "Downtown",
url: "/downtown",
id: 2,
}, {
name: "North Sarasota",
id: 3
}, {
name: "Lakewood Ranch",
id: 4
}, {
name: "Longboat Key",
id: 5
}, {
name: "St. Armands Circle",
id: 6
}, {
name: "Southside Village",
id: 7
}, {
name: "Siesta Key",
id: 8
}, {
name: "Gulf Gate",
id: 9
}];
//Set Cookie so when user returns to site, it will be on their neighborhood
$scope.mNeighborhood = parseInt($cookies.get('sNeighborhood')) || 0;
$scope.saveCookie = function() {
$cookies.put('sNeighborhood', $scope.mNeighborhood);
};
}]);
This all works fine to save and load user selection, but am having trouble finding solution to get template based on selection. So, should I add url to the array for each neighborhood and if so, how do I get the link?
Basically you need to change the URL programatically on selection of dropdown. For achieving this thing you need to first change you ng-options to return object on selection. And then using that object get url property from it to load particular template.
Markup
<select id="mNeighborhood"
ng-model="mNeighborhood"
ng-options="neighborhood.name for neighborhood in neighborhoods"
ng-change="saveCookie()">
</select>
Code
$scope.saveCookie = function() {
var mNeighborhood = $scope.mNeighborhood;
$cookies.put('sNeighborhood', mNeighborhood.id);
//do add $location dependency in controller function before using it.
$location.path(mNeighborhood.url);
};
Update
On initial Load the value should be set as object as per new implementation.
$scope.mNeighborhood = {}; //at the starting of controller
//the other code as is
//below code will get the object from the neighborhoods array.
$scope.mNeighborhood = $filter('filter')($scope.neighborhoods, parseInt($cookies.get('sNeighborhood')) || 0, true)[0];
$scope.saveCookie = function() {
var mNeighborhood = $scope.mNeighborhood;
$cookies.put('sNeighborhood', mNeighborhood.id);
//do add $location dependency in controller function before using it.
$location.path(mNeighborhood.url);
};

Angular change default value of select from filter

I have a select box which is populated with some data from my controller. When an input value changes the contents of the select box should be filtered and a default value should be assigned based on the is default property of the data object.
Is there any way this can be done using angular directives or would it need to be done as a custom filter function doing something along the lines of
angular.forEach(vm.data,function(item){
if (vm.q == item.someId && item.isDefault) {
vm.result = item.value;
}
});
My html looks something like
<div ng-app="myApp" ng-controller="ctrl as vm">
<input type="text" ng-model="vm.q">
<select ng-options="item.value as item.description for item in vm.data | filter:{someId:vm.q}" ng-model="vm.result"></select>
</div>
and my controller looks like:
(function(){
angular.module('myApp',[]);
angular
.module('myApp')
.controller('ctrl',ctrl);
function ctrl()
{
var vm = this;
vm.data = [
{
someId: '1',
description: 'test1',
value: 100,
isDefault: true
},
{
someId: '2',
description: 'test2',
value: 200,
isDefault: false
},
{
someId: '3',
description: 'test3',
value: 100,
isDefault: true
},
];
}
})();
See my plunkr demo here: http://plnkr.co/edit/RDhQWQcHFMQJvwOyHI4r?p=preview
Desired behaviour:
1) Enter 1 into text box
2) List should be filtered to 2 items
3) Select box should pre-select item 1 based on property isDefault set to true
Thanks in advance
I'd suggest you include some 3rd party library, like lodash, into your project to make working with arrays/collections that much easier.
After that you could add ng-change directive for your input.
<input type="text" ng-model="vm.q" ng-change="vm.onChange(vm.q)">
And the actual onChange function in the controller
vm.onChange = function(id) {
var item = _.findWhere(vm.data, { someId: id, isDefault: true });
vm.result = item ? item.value : null;
};
And there you have it.

space is shown when selecting the dropsdown option - angularjs

I have created an application in AngularJS with a drop down with space in option using a filter. The application is working fine with the options in drop down with indentation space before the values but the problem is when a select an option which is having a space, the space is also shown in the view like as shown below
actually I want the indentation space within the drop-down options but only thing is that I don't want that space to be get displayed when selection shown above
can anyone please tell me some solution to prevent the space to display when selection
My code is as given below
JSFiddle
<select>
<option ng-repeat="(key, value) in headers">{{value | space}}
</option>
</select>
<select ng-model="selectedValue" ng-change="selVal = selectedValue.trim(); selectedValue=selVal">
<option ng-if="selVal">{{selVal}}</option>
<option ng-repeat="(key, value) in headers" ng-if="selVal != value.value">
{{value | space}}
</option>
</select>
This is as close as it gets without jquery, temporarily changing the view state of the option when it's chosen. If that doesn't satisfy you and you still want it to be shown indented when the dropdown menu is open, check out this question on how to detect the state of the select component and update the display function accordingly. Alternatively, you can create your own select directive and manage the details within that, but I doubt that's worth the trouble if you're not using it in many places.
var app = angular.module('myApp', []);
app.controller('ArrayController', function ($scope) {
$scope.headers = [{
value: 'value 1'
}, {
value: 'value 2',
mainId: 12
}, {
value: 'value 3'
}, {
value: 'value 4',
mainId: 14
}, {
value: 'value 5'
}, {
value: 'value 6',
mainId: 18
}];
$scope.chosen = $scope.headers[0].value;
$scope.display = function(header) {
var chosenObject = _.find($scope.headers, {value: $scope.chosen});
if (!_.isUndefined(header.mainId) && header !== chosenObject) {
return '\u00A0\u00A0' + header.value;
} else {
return header.value;
}
}
});
HTML here:
<div ng-app='myApp' ng-controller="ArrayController">
<br></br>
SELECT:
<select ng-model="chosen" ng-options="header.value as display(header) for header in headers">
</select>
</div>
There's yet another alternative with CSS and ng-class, fiddle here:
var app = angular.module('myApp', []);
app.controller('ArrayController', function ($scope) {
$scope.headers = [{
value: 'value 1'
}, {
value: 'value 2',
mainId: 12
}, {
value: 'value 3'
}, {
value: 'value 4',
mainId: 14
}, {
value: 'value 5'
}, {
value: 'value 6',
mainId: 18
}];
$scope.chosen = $scope.headers[0].value;
$scope.isIndented = function(header) {
var chosenObject = _.find($scope.headers, {value: header});
return !_.isUndefined(chosenObject.mainId);
};
});
app.filter('space', function() {
return function(text) {
if(_.isUndefined(text.mainId))
{
console.log('entered mainId');
return text.value;
}
else
{
console.log('entered');
return '\u00A0\u00A0' + text.value;
}
};
});
HTML:
<div ng-app='myApp' ng-controller="ArrayController">
<br></br>
SELECT:
<select ng-model="chosen" ng-options="header.value as (header | space) for header in headers" ng-class="{'indented-value': isIndented(chosen)}">
</select>
</div>
CSS:
.indented-value {
text-indent: -9px;
}
First off, this was a great question. I've unfortunately spent way too much time trying to come up with a solution to this. I've tried everything from CSS, to using ngModelController $formatters, to the solution (which isn't optimal as you'll see) I've posted below. Note, I do not think my solution deserves to be selected as the answer. It just "sorta" works, but like other solutions, it has a fatal flaw.
However, since your question was:
can anyone please tell me some solution to prevent the space to
display when selection
My official answer is:
No
There is no cross-browser way to get this working. No amount of CSS, jQuery, or Angular magic will make this work. While it may be disappointing, I think that is going to be the only correct answer to your question.
No one is going to be able to give you a solution that prevents the space from being displayed in the select box while maintaining it in the options that works reliably across browsers. Chrome and Firefox allow some amount of styling of elements in the select, options, and optgroup family, but nothing is consistent and works everywhere.
My best run at it is in this Plunk
It uses the fact that optgroup will do indentations for you, but it comes with terrible differences in how different browsers handle it. With some you can style away the problem, but others do not work (and never will). I'm posting it so maybe someone will be inspired and figure out a way to prove me wrong.
<body ng-app="app">
<div ng-app='myApp' ng-controller="ArrayController">
<div>{{selectedValue}}</div>
SELECT:
<select ng-model="selectedValue" >
<option indented="item.mainId" ng-repeat="item in headers">{{item.value}}</option>
</select>
</div>
</body>
(function() {
var app = angular.module('app', []);
app.controller('ArrayController', function($scope, $timeout) {
$scope.headers = [{
value: 'value 1'
}, {
value: 'value 2',
mainId: 12
}, {
value: 'value 3'
}, {
value: 'value 4',
mainId: 14
}, {
value: 'value 5'
}, {
value: 'value 6',
mainId: 18
}];
});
app.directive('indented', function($parse) {
return {
link:function(scope, element, attr){
if($parse(attr.indented)(scope)) {
var opt = angular.element('<optgroup></optgroup>');
element.after(opt).detach();
opt.append(element);
}
}
};
});
})();
If you opened the question up and allowed the implementation of a directive that mimicked the behavior of select but was instead built with li elements, then this would be trivial. But you simply can't do it with select.
Given your code, you can add one helper directive, to remove space in link function, once your option got selected.
As an example, add an id to your select, and directive
<select id="mySelect" option-without-space>
<option ng-repeat="(key, value) in headers">{{value | space}}
</option>
</select>
And directive might look like,
app.directive('optionWithoutSpace', () => {
return {
restrict: 'A',
link: function(scope, elem, attributes) {
var selectedOptionWithoutSpace = function () {
var selectedOption = $('#mySelect option:selected');
var optionText = selectedOption.text();
selectedOption.text(optionText.trim())
return false;
};
$(elem).on('change', selectedOptionWithoutSpace);
}
}
})
This is with a little help of jQuery, but I assume it is not a big problem.
Here is a fiddle.
Try this...
Change select box html following
<select ng-model="selectedOption" ng-options="item.value for item in headers"></select>
var app = angular.module('myApp', []);
app.controller('ArrayController', function ($scope) {
$scope.headers = [{
value: 'value 1'
}, {
value:'value 2',
mainId: 12
}, {
value: 'value 3'
}, {
value: 'value 4',
mainId: 14
}, {
value: 'value 5'
}, {
value: 'value 6',
mainId: 18
}];
$scope.selectedOption = $scope.headers[0]; //Add this line
});
app.filter('space', function() {
return function(text) {
if(_.isUndefined(text.mainId))
{
console.log('entered mainId');
return text.value;
}
else
{
console.log('entered');
return '\u00A0\u00A0' + text.value;
}
};
});

ng-repeat controller and parent update

I've been reading a lot on angular scopes and inheritance but I can't get my head around this problem. Here is the HTML I'm using:
<div class="sensorquery-sensor" ng-repeat="sensor in query.sensors" ng-controller="SensorsCtrl">
<select class="form-control"
ng-model="selected.sensor"
ng-options="sensor.name for sensor in parameters.sensors">
</select>
<select class="form-control"
ng-model="selected.definition"
ng-options="definition.value for definition in definitions">
</select>
<select class="form-control"
ng-model="selected.operation"
ng-options="operation for operation in operations">
</select>
</div>
As you can see, I have an ng-repeat based on query.sensors. The values stored in this query.sensors array should be simple:
{
name: 'sensor1',
type: 'temperature'
}
But I want to use a child controller: SensorsCtrl to handle more logic per sensor and hide the complexitiy of sensors. A sensor can look like:
{
name: 'sensor1',
attributes: [
'model',
'brand'
],
definitions: [
{
datatype: 'double',
value: 'temperature'
},
{
datatype: 'integer',
value: 'pressure'
},
{
datatype: 'string',
value: 'color'
}
]
}
So it's in my SensorsCtrl controller where I want to put the selection logic:
$scope.$watch('selected.sensor', function(sensor) {
$scope.definitions = sensor.template.definition;
});
$scope.$watch('selected.definition', function(definition) {
if (definition.datatype === 'string') {
$scope.operations = ['Count'];
} else {
$scope.operations = ['Max', 'Min'];
}
$scope.selected.operation = _.first($scope.operations);
});
How do I keep the link with the parent query.sensors[$index] while transforming the sensor as the user selects different sensors and definitions?
Setting up a watcher on selected and updating the query.sensors array triggers an infinite $digest loop.
I found the solution which was right before my eyes:
<div class="sensorquery-sensor" ng-repeat="sensor in query.sensors" ng-controller="SensorsCtrl">
<!-- ... -->
</div>
The sensor is a reference to the original object of the parent query.sensors. An it's created in the scope of the sub-controller.
So in my SensorsCtrl controller, I can just watch:
$scope.$watch('sensor.definition', function(definition) {
/* ... */
});
So I can put hide some complexity in this controller while maintaining a proper link to the original element.
It does not answer the question of maintaining a less complex object but it's a different question I guess.

Categories

Resources