I'm quite new to AngularJS and had to takeover somebody else's project at work which has little to no documentation.
I have 2 kinds of check-boxes in my application, one is a "Select All" checkbox and another is a device selection checkbox. As the name suggests, the select all will select all the devices listed below it and if I uncheck the "select all" checkbox, I can check the devices individually to see them.
Here is the code of the Select all checkbox -
<input type="checkbox" data-ng-model='devCtrl.uiChoices.selectAll' value='true' data-ng-change="devCtrl.selectAll()"/><h4>Select / Deselect All</h4>
Controller:
_this.uiChoices.selectAll = true;
I can understand from above that by default, select all is checked and I can see all the devices below it checked too.
Moving onto the device check-box -
<input type="checkbox" data-ng-model='device.draw' data-ng-change="device = devCtrl.adjustVisibility(device)" />
Controller -
_this.adjustVisibility = function(draw) {
draw.marker.setVisible(draw.plot);
return draw;
}
Basically, whenvever the device is selected, it will appear on a google map. If it is unchecked, it won't appear on the map.
My question is, after I uncheck the "Select all" checkbox and then select only 2 devices in the list below and then do a page refresh, I want the select all to be disabled and show only those 2 devices to be checked and displayed on the map.
The list of devices is being pulled from a MySQL database and is updated dynamically.
Any help is appreciated.
As I said, you can do it by 3 different ways.
1 - Using $scope variable
In AngularJS you have a main Controller usually set at index.HTML body that you can access from all other controllers. You could use it to store your data on the $scope variable. See the example:
index.html:
<body ng-controller="DefaultController">
DefaultController.js:
angular.module('YourModule').controller('DefaultController', ['$scope', function ($scope) {
//Storing Your data
$scope.isChecked = true;
}]);
YourCheckBoxController.js
angular.module('YourModule').controller('YourCheckBoxController', ['$scope', function ($scope) {
//Here you gonna access the $scope variable, that does not change on page reload
$scope.accessingTheVariable= function () {
if ($scope.isChecked) {
//Select All
}
else {
//Do not Select All
}
};
$scope.onCheckBoxToggle {
$scope.isChecked = _this.uiChoices.selectAll;
//More code
};
}]);
2- Using localStorage
//The property exists
if (localStorage.hasOwnProperty("isChecked")) {
if(localStorage.isChecked) {
//Select All
}
else {
//Do not Select All
}
}
//To set localStorage.isChecked
localStorage.setItem("isChecked", _this.uiChoices.selectAll);
3 - Angular Service (Factory)
On this scenario you should create a service that could be accessed from every Controller in your project (usefull if you gonna use the data on more than 1 Controller). Look:
YourService.js
angular.module('YouModule').factory('YouService', function () {
var data =
{
IsChecked = true
};
data.buildIsChecked = function (isChecked) {
this.IsChecked = isChecked;
};
return data;
});
YourIsCheckedController.js:
angular.module('YourModule').controller('YourCheckBoxController',
['$scope', 'YouService', function ($scope, YouService) {
//Setting the service
//...
YouService.buildIsChecked(_this.uiChoices.selectAll);
//Accessing the service Information (it could be accessed from any Controller, just remember to set Service Name at begin of the module declaration)
var isChecked = MenuService.IsChecked;
}]);
You need a way of saving those checked devices.
Try localStorage. Basically, when you select a device, add it to an array, like checkedDevices and add this array to localStorage like so:
localStorage.setItem("devices", JSON.stringify(checkedDevices));
then, at the beginning of your controller, get this array from the localStorage:
var devices = JSON.parse(localStorage.getItem("devices"));
then, check if it has items, if it does, set selectAll to false:
if (devices.length > 0){
this.selectAll = false;
}else{
this.selectAll = true;
}
then, for every device, check if it is in devices array, if it is, select it.
Related
I am new to the angularJS. And recently I have been working on a angularJS project. I use the ng-template and ng-repeat to make a multiple product category tree. And I add a button to control whether the sub-category expanded or not.Here is the problem,How I can keep the category expaneded at where user left off when the user click into other pages and click back to the category page?
You could save the current tree state into the HTML5 Localstorage.
Add a unique id to each category and save them into the localstorage.
function saveCurrentState() {
const openedCategories = /* find the opened categories */;
// we injected $window in our controller.
$window.localStorage.setItem('openedCategories', openedCategories.join(','));
}
Then, when you load the page
/* to be run on the page load.*/
function retrieveOpenedCategories() {
// all the current categories, open or not.
const categories = /* get all the categories */;
// we retrive our category from the localStorage. With some code to handle if it's empty / null.
const openedCategories = ($window.localStorage.getItem('openedCategories') || "").split(',');
// check if we have categories that were opened. length of 0 will evaluate to false-y.
if(openedCategories.length) {
// we use map because we want to change every value from the original array.
categories = categories.map((category) => {
if(openedCategories.includes(category.id)) {
category.open = true;
}
return category;
});
}
}
/* we show our categories, somehow.*/
I have a custom directive which is very similar to a drop down. Items in the drop down menu are associated with file names of certain videos. A div below the drop down displays a default video file (I have done this via Videoangular).
Whenever I make a selection from the drop down menu, I am changing the default variable containing filename (String) to the one I want. But, the same is not reflected in the div.
My objective is to refresh div containing the video with appropriate video whenever a selection is made from the drop down menu.
This is my controller:
angular.module('myApp',
[
"ngSanitize",
"com.2fdevs.videogular",
"com.2fdevs.videogular.plugins.controls",
"com.2fdevs.videogular.plugins.overlayplay"
]
)
.controller('ctrl',
["$rootScope", "$scope", "$state", "$log", "Restangular",
function ($rootScope, $scope, $state, $log, Restangular) {
'use strict';
var vm = this;
//DEFAULT VIDEO FILE NAME
vm.fields = "WaterCool1";
this.config = {
sources: [
{src: "assets/data/"+vm.fields+".mp4", type: "video/mp4"}
]
};
vm.loadPage = loadPage;
vm.coolingSystemTypeSelector = {coolingSystemTypeSelector:{}};
getAll('cooling-system-type').then(
function(objs) {
$log.debug("get Cooling System Type", objs);
vm.coolingSystemTypeSelector = objs.selector;
vm.fields = "WaterCool1";
vm.coolingSystemTypeSelector.onSelect = function (selection) {
if(!selection){
return;
}
$log.debug("Cooling System Type Selection == ", selection);
if(selection.label==="ACC"){
vm.fields = "AirCool";
}else if(selection.label === "WCC-CT"){
vm.fields = "WaterCool1";
}else if(selection.label === "WCC-DC"){
vm.fields = "WaterCool2";
}
};
}
);
///.....
}
]
);
This is my HTML:
<div>
<selector form="form" columns=vm.columns target="vm.coolingSystemTypeSelector"></selector>
</div>
<hr>
<div id="refreshThisDiv">
<!--I want to refresh this div-->
<videogular vg-theme="vm.config.theme">
<!--VIDEOGULAR CODE-->
</videogular>
</div>
What you need is not to refresh the div. You need angular to refresh the div based on you modifying bound properties.
Your declaration of this.config is actually static and you are never modifying the value of this.config.sources src after instantiation. As that code is running only once it will forever remain as "assets/data/WaterCool1.mp4".
What you need to do instead at least, is to modify this value upon selection of an option in the drop-down. Something like:
// ...
var that = this;
getAll('cooling-system-type').then(
// ... inside onSelect ...
if(selection.label==="ACC") {
that.config.sources = [{src: "assets/data/AirCool.mp4", type: "video/mp4"}];
}
// ...
Even then, with this code, you might need to trigger a manual $apply as angular may not be aware of your change to the field via this onSelect event handling. Ideally you will be able to bind the event to the function directly in HTML by using ng-change and avoid the need for that.
If you provide a full sample (https://plnkr.co/edit/), it's easier to guide you to a solution and explain in without the need to rewrite your original code.
I have an app in AngularJS. There I have a table and it has 5 columns.
first three columns contain text fields where user can fill the data and next two columns contain a submit and reset button.
On the press event of the reset button I want to reset all the three models associated with the text fields.
Please suggest.
Change the reset function to use angular.copy
$scope.reset = function () {
$scope.datas = angular.copy($scope.initial);
};
If your object is like
$scope.data = { column1:"asas", column2:"asas", column3:"asadas" };
You can don it in 2 way
1.<button ng-click="data = {};"></button>
2.<button ng-click="reset();"></button>
$scope.reset = function(){
delete $scope.data;
}
I'm now developing website and there has edit note field features in ng-repeat. To edit note field, user need to click link to display form first then key-in into it and then save it as follow. Problem is i cannot hide that input after successfully saved. Coding is as follow.
index.jade
tr(data-ng-repeat="application in job.applications")
td.notes
div.bold #{getMessage('Notes:')}
div.normal
div(ng-hide='showDetails')
{{application.note}}
.br
a.admin_edit_gray(href='#', ng-click="showDetails = ! showDetails") Edit Note
div(ng-show='showDetails')
textarea.form-control.small-text-font(ng-model='editableTitle', ng-show='showDetails', maxlength="100", ng-trim="false")
div.editable
div(ng-if="editableTitle.length == 100")
| #{getMessage('max 100 symbols.')}
a.small-text-editButton(href='#', ng-click='save(application, editableTitle, application.id)') Save
| |
a.small-text-cancelButton(href='#', ng-click="showDetails = ! showDetails") close
controller.js
$scope.showDetails = false;
$scope.noteFormData = {};
$scope.save = function(application, editableTitle, appId) {
$scope.noteFormData = {
appId: appId,
note: editableTitle
};
mytestService.writeNote($scope.noteFormData).then(
function (notemessage) {
application.note = notemessage;
alert('Note is successfully saved.');
$scope.showDetails = false;
}
);
};
I've tried to hide form as $scope.showDetails = false; after successfully saved. But it does not work at all. Please help me how to solve that issue.
You are creating showDetails inside the $scope of the ngRepeat. Each iteration of the loop creates a new child $scope of the controller's $scope.
In this way, just set $scope.showDetails from the controller will not work.
In order to fix that you need to get the reference to the object that is being iterated and set the show details:
Instead of:
ng-click="showDetails=!showDetails"
Use:
ng-click="application.showDetails=!application.showDetails"
After that, when submiting, you can choose which one you would like to show or hide by using the correct reference or by iterating over all itens of the array and setting showDetails to false.
Instead of:
$scope.showDetails = false;
Use:
application.showDetails = false;
set a variable in controller and set its value false .After your save() function is executed successfully set that variable to true. And in the view page put an condition of ng-show on tr if that value that is true.
Testing out Angular ui-grid (ng-grid v.3.0). Can not for the life of me find the selected row. I just want to grab the rows or even row ID of row when a user clicks it. Found the top comment here but I think this is outdated: Getting select rows from ng-grid?
Does anyone know where the gridOptions.selectedItems is being stored in 3.0?
Is this what your are looking for ?
http://ui-grid.info/docs/#/tutorial/210_selection
Activate grid selection capabilities with the ui-grid-selection tag (and ui.grid.selection module registration in your app
register gridApi and use gridApi.selection to access getSelectedRows()
In addition to the steps above https://stackoverflow.com/a/26188783/2658127, you might have to invoke it through a ng-click event to get the actual value/object. At least that's how I had it working.
Eg:
$scope.selectRow = function(){
$scope.gridApi.selection.getSelectedRows();
};
And call selectRow() from the template.
This is for anybody who have been confused like I did, considering the fact that ui-grid does not have the best documentation (specially for this select portion).
The easiest approach is:
Register the gridApi by adding this your controller:
$scope.gridOptions.onRegisterApi = function(gridApi) {
$scope.myGridApi = gridApi;
};
Access the array of selected items:
$scope.myGridApi.selection.getSelectedRows();
With grid ui you have to use the selection.on.rowSelectionChanged to update a scope variable that store the selectedItem.
In this way you can use the value in a binding expression.
var SelectController = function($scope) {
...
$scope.selectedItem = null;
$scope.gridOptions = {
data : 'articles',
enableRowSelection : true,
multiSelect : false,
enableRowHeaderSelection : false,
...
};
$scope.gridOptions.onRegisterApi = function(gridApi) {
// set gridApi on scope
this.$scope.gridApi = gridApi;
}.bind(this);
$scope.gridOptions.onRegisterApi = function(gridApi) {
// set gridApi on scope
this.$scope.gridApi = gridApi;
this.$scope.gridApi.selection.on.rowSelectionChanged($scope,
function(row) {
this.$scope.selectedItem = row.entity;
}.bind(this));
}.bind(this);
Use a an array instead of a plain object if you need multiple selection.