I need live update my model when I selecting the checkboxes. But when I run this code : TypeError: Cannot read property 'map' of undefined.
After I remove the map function & added console.log(nv).
Then initially it print a empty array. Then while I selecting a checkbox it returns the object correctly. Here is my code. Looking for your help..
//my Controller
$scope.selection = [];
$scope.$watch('items|filter:{selected:true}', function (nv) {
$scope.selection = nv.map(function (item) {
return item.id;
});
}, true);
//view
<div ng-repeat="item in items | filter:global.query | orderBy: name">
<input class="tile-check" id="check-0" type="checkbox" name="delete"
ng-model="item.selected">
</div>
source : http://jsbin.com/ImAqUC/1
Solved. The problem was the $watch is called before set the item variable. So I put a if around that.
if(nv){
$scope.selection = nv.map(function (item) {
return item.id;
});
}
Related
Hi I have a datatable with id, name, etc. and have checkboxes added within the angular js
e.g.
vm.dtColumns = [
DTColumnBuilder.newColumn(null).withTitle(titleHtml).notSortable()
.renderWith(function(data, type, full, meta) {
vm.selected[full.ID] = false;
return '<input type="checkbox" class="checkedtestids" ng-model="showCase.selected[' + data.ID + ']" ng-click="showCase.toggleOne(showCase.selected)">';
}),
I have checkboxes that can select all rows from the header or individually.
I have also got a var that keeps the id and changes the boolean state from true to false depending on the checkbox being checked or not.
var vm = this;
vm.message = '';
vm.someClickHandler = someClickHandler;
vm.selected = {};
vm.selectAll = false;
vm.toggleAll = toggleAll;
vm.toggleOne = toggleOne;
My html code to display this vm.selected = {}; is as follows:
<div ng-controller="WithAjaxCtrl as showCase">
<blockquote>Please click on a row</blockquote>
<p class="text-danger">
You clicked on: <strong>{{ showCase.message }}</strong>
</p>
<table datatable="" dt-options="showCase.dtOptions"
dt-columns="showCase.dtColumns" class="row-border hover"></table>
<p class="text-danger">You selected the following rows:</p>
<p>**<pre ng-model="showCase.selected">{{ showCase.selected |json }}</pre**>
If I click on these ids :
enter image description here
Then the following is reflected below:
enter image description here
{
"2457937718692": true,
"2457985718634": false,
"2454757950532": true,
How do I send this array vm.selected that indicates checked or not to my java spring controller which will then use them for another purpose?
I have tried to use $http.post() and $http.get() without success.
You don't need to pass the ID in the ng-model to identify the selected checkboxes because the array of object is bound to the view, instead you can pass the boolean variable and use filter directive https://docs.angularjs.org/guide/filter.
Eg.:
JAVASCRIPT
vm.data = ['a','b','c'];
var selected = [];
var vm.filterSelectedData = function(){
selected = $filter('filter')(data, {checked: true});
}
HTML
<div ng-repeat="element in showCase.data">
<input type="checkbox" class="checkedtestids" ng-model="element.selected" ng-change="showCase.filterSelectedData()" />
</div>
to send the selected items to the server you just need to create a json object with the array of those selected items.
http.post('url', {selectedItems:selected})
.success(function(){ // calback function })
.error(function(){ // error function })
see plunker
https://plnkr.co/edit/iJf7onwLUKckQDzBP2pT
i have input with default value 0 , but this value not getting
my js getting error undefined ,if i enter any value it is showing .
but i want to show default value
<tr ng-repeat="r in rvm" >
<td>
<input type="text" lass="input-large" ng-value="2.00" ng-model="rvm.val1" name="val1" />
</td>
<td>
<button type="button" class="btn btn-default" ng-click="addRow1()">Add</button>
</td>
</tr>
JS
var ReceiptsApp = angular.module('ReceiptsApp', []);
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm = [{}];
$scope.addRow1 = function ( ) {
alert($scope.rvm.val1);
}
});
js bin link here
enter link description here
You can either set it inside your controller
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm.val1 = '0.00';
});
or using ng-init
<input type="text" lass="input-large" ng-init="rvm.val1='0.00'" ng-model="rvm.val1" name="val1" />
Just set a default value in the controller:
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm.val1 = 'your default value';
});
If you read this link about ngValue you will see that it's not supposed to be used with a normal input (when you've also set ng-model on it), but rather for radio inputs and option elements. Your best solution is setting the value in the controller, as you should do.
It can also be used to achieve one-way binding of a given expression to an input element such as an input[text] or a textarea, when that element does not use ngModel.
<input type="text" lass="input-large" ng-value="2.00" ng-model="rvm.val1" name="val1" />
Problem is you are using rvm.val1 where rvm is array not an object in array
Change ng-model="rvm.val1" to ng-model="r.val1"
then you will be able to keep track of each value individually.
Inorder to initialize a value
<tr ng-repeat="r in rvm" ng-init="r.val1= 2.00">
Then in
$scope.addRow1 = function (index) {
// access individual object in rvm..
alert($scope.rvm[index].val1);
// push a new object
$scope.rvm.push({});
}
JSBin
If you don't want to use ng-init
You can do this
Each time you push a new item initialize the val1
$scope.rvm.push({val1: 2.00});
JsBin
var ReceiptsApp = angular.module('ReceiptsApp', []);
ReceiptsApp.controller('ReceiptsController', function ($scope) {
$scope.rvm = [{}];
$scope.rvm.val1=0;
$scope.addRow1 = function ( ) {
if($scope.rvm.val1 == ''){
$scope.rvm.val1=0;
alert($scope.rvm.val1);
} else {
alert($scope.rvm.val1);
}
}
});
Hi i have took a if condition where i am checking if input field is blank then it will initialise $scope.rvm.val1=0; and showing in alert.
it will work
I have a simple form like so:
<form name="add-form" data-ng-submit="addToDo()">
<label for="todo-name">Add a new item:</label>
<input type="text" data-ng-model="toDoName" id="todo-name" name="todo-name" required>
<button type="submit">Add</button>
</form>
with my controller as follows:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
}
}
what I'd like to do is clear the text input after submission so I simply clear the model value:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
$scope.toDoName = "";
}
}
Except now, because the form input is 'required' I get a red border around the form input. This is the correct behaviour, but not what I want in this scenario... so instead I'd like to clear the input and then blur the input element. Which leads me to:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
$scope.toDoName = "";
$window.document.getElementById('todo-name').blur();
}
}
Now, I know that modifying the DOM from the controller like this is frowned upon in the Angular documentation - but is there a more Angular way of doing this?
When you give a name to your form it automatically gets added to the $scope.
So if you change your form name to "addForm" ('cause I don't think add-from is a valid name for angular, not sure why), you'll have a reference to $scope.addForm.
If you use angular 1.1.1 or above, you'll have a $setPristine() method on the $scope.addForm. which should recursively take care of resetting your form. or if you don't want to use the 1.1.x versions, you can look at the source and emulate it.
For those not switching over to 1.1.1 yet, here is a directive that will blur when a $scope property changes:
app.directive('blur', function () {
return function (scope, element, attrs) {
scope.$watch(attrs.blur, function () {
element[0].blur();
});
};
});
The controller must now change a property whenever a submit occurs. But at least we're not doing DOM manipulation in a controller, and we don't have to look up the element by ID:
function MainCtrl($scope) {
$scope.toDos = [];
$scope.submitToggle = true;
$scope.addToDo = function () {
if ($scope.toDoName !== "") {
$scope.toDos.push($scope.toDoName);
$scope.toDoName = "";
$scope.submitToggle = !$scope.submitToggle;
}
};
}
HTML:
<input type="text" data-ng-model="toDoName" name="todo-name" required
blur="submitToggle">
Plnkr
I have made it work it as below code.
HTML SECTION
<td ng-show="a">
<input type="text" ng-model="e.FirstName" />
</td>
Controller SECTION
e.FirstName= '';
I have input type="checkbox"
<input type="checkbox" {{action 'checkInvoice' item.number}}/>
after ember calls acttion , checkbox loses state. this is simple action code
checkInvoice:function(number){
var invoices=this.get('invoices');
var model=this.get('model');
model.forEach(function(item){
if (item.number===number) {
invoices.pushObject(item);
}
});
return;
}
How embers treats so? or may I reach the same result with ember helper (how to set parameter for action)?
{{input type="checkbox" action='checkInvoice' }}
You can define an itemController for each item in the model, bind the checked property of the checkbox to a property in the itemController and observe the property in the itemController to handle pushing the object into another array.
App.IndexController = Ember.ArrayController.extend({
invoices: [],
itemController: 'indexItem'
});
App.IndexItemController = Ember.ObjectController.extend({
isCheckedChanged: function(){
if(this.get('isChecked')) {
this.get('parentController.invoices').pushObject(this.get('content'));
} else {
this.get('parentController.invoices').removeObject(this.get('content'));
}
}.observes('isChecked')
});
In the template:
{{#each item in model}}
<li>
{{input type="checkbox" checked=item.isChecked}}
{{item.name}}
</li>
{{/each}}
Sample working jsbin .
I have done view for checkbox. use this answer Trigger an action on the change event with Ember.js checkbox input helper?
export default Ember.Checkbox.extend({
hookup: function () {
var action = this.get('action');
if (action) {
this.on('change', this, this.sendHookup);
}
}.on('init'),
sendHookup: function (ev) {
var action = this.get('action'),
controller = this.get('controller');
controller.send(action, this.$().prop('checked'));
},
cleanup: function () {
this.off('change', this, this.sendHookup);
}.on('willDestroyElement')
});
so this is my checkbox
{{view "checkbox" action='testaction' checked=item.selected }}
and after click moved value 'selected' will changed. so I can filter model with selected property. Also can send to action with params
One of the columns in my ng-repeat directive outputs the values of $$hashkey.
I have no idea how this started happening. I get data from a simple GET and inspecting that data as it gets in from the success callback shows the $$hashkey being inserted to each object. I understand the $$hashkey is used by angular but this never happened before as far as HTML view output goes.
This is on 1.2.16
HTTP GET:
$http.get('index.php/getWorkbook/'+$routeParams.workbook).success(function(data) {
console.log(data); // Has $$hashkey inserted
$scope.workbook = data;
});
HTML:
<tr ng-repeat='row in workbook'>
<td ng-repeat="key in notSorted(row)" ng-init="value = row[key]">
<input type="text" ng-model="value" ng-blur="edit(value, key, row)" />
</td>
</tr>
Here is the controller function.
$scope.notSorted = function(obj){
if (!obj) {
return [];
}
return Object.keys(obj);
}
Seems the rows don't like being ran through notSorted(). Adding angular.copy() ended up working for me.
$scope.notSorted = function(obj){
obj = angular.copy(obj);
if (!obj) {
return [];
}
return Object.keys(obj);
}
Try this change in your controller
$scope.workbook = data;
$scope.workbook = angular.fromJson(angular.toJson($scope.workbook));