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.
Related
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.
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 trying to hide clicked row after changing status in angularjs. Here is my coding and please let me know how to do it?
table.table
tr(data-ng-repeat="application in job.applications", ng-hide="application.hideApplication")
td.status
div.bold #{getMessage('Change Status:')}
div.normal
a(ng-class="app_status === 'shortlist' ? 'admin_edit_bold' : 'admin_edit_normal'", ng-click="changeApplicationStatus(application.id, 'shortlist', application)") #{getMessage('Shortlist')}
td.rating
div(ng-init='rating = application.app_rating')
.star-rating(star-rating='', rating-value='rating', data-max='5', on-rating-selected='rateFunction(application.id, rating)')
Here is controllerjs.
$scope.changeApplicationStatus = function (appId, app_status, application) {
return jobsService.changeApplicationStatus(appId, app_status).then(
function () {
application.hideApplication = false;
}
);
};
Put this attribute on whichever element you're wanting to show/hide
ng-hide="application.hideApplication"
Edit subsequent to comment:
That attribute wouldn't work on the same element as the ng-repeat, I don't think the application variable would be in scope...
Instead, you could change your repeat to:
application in job.applications | filter: { hideApplication : false }
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.
I have an angular-bootstrap modal dialog with the following template (jade syntax):
div.modal-body
select(ng-model="chosenProject" id="chosenProject", ng-options="c.value as c.name for c in selectItems")
div.modal-footer
button.btn.btn-primary(ng-click="ok()") Change project
button.btn.btn-warning(ng-click="cancel()") Cancel
The pre-filling of the array works just fine. Dialog is configured with its controller that defines trivial ok() function, below is the excepmt from controller's body:
$scope.chosenProject = 0; // needed to have selected initial item with value=-1 in the select
$scope.ok = function () {
console.log("OK clicked, chosenProject " + $scope.chosenProject);
$modalInstance.close($scope.chosenProject);
};
The functions work fine. Accodring to console.log, $scope.chosenProject remains the same regardiless of what I chose in select and simply returns whatever I preset in line "$scope.chosenProject = 0;". I appreciate an advice how to fix this.
The issue occurs because of a transclusion scope that exists between your controller and the modal template.
Try this instead - In the controller for the modal, replace:
$scope.chosenProject = 0;
with
$scope.chosenProject = {
value: 0
};
And the modal template, replace
select(ng-model="chosenProject" id="chosenProject"
ng-options="c.value as c.name for c in selectItems")
with
select(ng-model="chosenProject.value" id="chosenProject"
ng-options="c.value as c.name for c in selectItems")
The selected project should then be captured properly.
You need to pass chosenProject back in
modalInstance.result.then(function(result) {
});
This is a very good simpler dialog service to use if you need a couple more dialog in one page.