angularjs form built with ng-repeat field + select option + $http.get - angularjs

I have the code like this:
<form ng-controller="MyCtrl" ng-submit="save()>
<div ng-repeat="f in fields">
<label for="theInput">{{ f.label }}</label>
<select ng-model="f.value" ng-init="f.value = f.id" ng-options="item.id as item.name for item in f.items"></select>
</div>
</form>
<script>
var Mod = angular.module('myApp', []);
function MyCtrl($scope, $http) {
var categories = [];
$http.get(BASE_URL + 'task/listCategory').success(function(data) {
categories = data;
});
$scope.fields = [
{ label: 'Category', value: 'items', items: categories }
];
}
</script>
why angular select doesnot working like charm?
thanks for your help

you might want to do
var Mod = angular.module('myApp', []);
function MyCtrl($scope, $http) {
var categories = [];
$http.get(BASE_URL + 'task/listCategory').success(function(data) {
categories = data;
$scope.fields = [{ label: 'Category', value: 'items', items: categories }];
});
}

Related

AngularJS - Watch filtered list for changes

Within angular I have a filtered list of people that takes the filter criteria from a predicate function. I want to watch a variable of the filtered list (called filteredPeople) every time the filtered list changes. But I am unable to see when that variable changes.
My code is below:
HTML:
<ul>
<li ng-repeat="person in ($ctrl.filteredPeople = ($ctrl.people | filter: $ctrl.filter))">
...
</li>
</ul>
JS:
controller: ['$scope',
function ($scope) {
var $ctrl = this;
$ctrl.people = {...}
$ctrl.filteredPeople = [];
$scope.$watch($ctrl.filteredPeople, function () {
console.log("called"); //not being called
});
$ctrl.filter = function (p) {
//custom filter function for each item in the array of people
}
}]
I can answer any questions of provide more code if needed
angular.module('app', []).controller('ctrl', function($scope) {
var vm = this;
vm.items = [
{ name: 'Sam' },
{ name: 'Max' },
{ name: 'Tom' },
{ name: 'Henry' },
{ name: 'Jack' },
{ name: 'Kate' }
]
var counter = 1;
$scope.$watchCollection('vm.filtered', function(){
console.log('Changed' + counter++);
})
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<div ng-app='app' ng-controller='ctrl as vm'>
<input type='text' ng-model='vm.filter' />
<ul>
<li ng-repeat='item in vm.filtered = (vm.items | filter : vm.filter)'>{{item}}</li>
</ul>
</div>

how to get the value from selected checkbox in angularjs

onhstrong text:
When i click checkbox table id based column name shown in the right side using json data
JS
var app = angular.module('plunker', ['ui']);
app.controller('MyCtrl', function($scope) {
$scope.records = [ { "Id": 1 }, { "Id": 2 }, { "Id": 3 } ];
$scope.selected = {};
$scope.ShowSelected = function() {
$scope.records = $.grep($scope.records, function( record ) {
return $scope.selected[ record.Id ];
});
};
});
HTML
<div data-ng-controller="MyCtrl">
<ul>
<li data-ng-repeat="record in records">
<input type="checkbox" ng-model="selected[record.Id]"> {{record.Id}}
</li>
</ul>
Show Selected
</div>

Displaying data in ng-grid by clicking on an <a> element in the sidebar

I have a view in an angularjs application with a sidebar, where I can choose my insurers. By clicking on an insurer, I want my ng-grid show me some insurer's data. Now I can select the insurer, and see the <div class="well well-sm"> changes.
Here is my angular controller:
app.controller('ReportsInsurerPaymentsCtrl', ['$scope', '$http', '$filter', 'toaster', '$state', '$modal', function ($scope, $http, $filter, toaster, $state, $modal) {
$scope.insurer_payments = [];
$scope.insurer_payments = [];
$scope.insurer_payment = {};
$scope.gridOptions = {
data: "insurer_payment",
rowTemplate: '<div ng-style="{\'cursor\': row.cursor, \'z-index\': col.zIndex() }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}} " ng-cell></div>',
columnDefs: [
{
field: "date",
displayName: "Date",
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>',
width: 100
},
{
field: "amount",
displayName: "Amount",
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>'
},
{
field: 'comment',
displayName: 'Comment',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>',
}
],
$scope.refresh = function () {
var p = {
name: $scope.filterOptions.filterText,
pageNumber: (allPages >= $scope.pagingOptions.currentPage) ? $scope.pagingOptions.currentPage : $scope.pagingOptions.currentPage = 1,
pageSize: $scope.pagingOptions.pageSize,
sortInfo: sb.join("")
};
$http({
url: "reports/insurer_payments.json",
method: "GET",
params: p
}).success(function (data, insurer_payment) {
$scope.totalServerItems = data.insurerPaymentsCount;
$scope.insurer_payments_count = data.total_insurer_payments_count;
$scope.insurer_payments = data.insurer_payments;
$scope.insurer_payment = data.insurer_payment;
if (insurer_payment) {
$scope.insurer_payment = $filter('orderBy')($scope.insurer_payments, 'name')[0];
} else {
$scope.insurer_payment = $filter('filter')($scope.insurer_payments, {name: insurer_payment.name})[0];
}
if ($scope.insurer_payments) $scope.insurer_payment.selected = true;
$scope.showContent = true;
if ($scope.gridOptions.ngGrid) {
$scope.gridOptions.ngGrid.buildColumns();
}
}).error(function () {
});
}, 100);
};
$scope.selectInsurerPayment = function(item){
angular.forEach($scope.insurer_payments, function(item) {
item.selected = false;
});
$scope.insurer_payment = item;
$scope.insurer_payment.selected = true;
};
$scope.refresh();
}]);
A part of a view:
<a ng-repeat="insurer_payment in insurer_payments | orderBy:'name'"
class="list-group-item m-l"
ng-class="{'select m-l-none': insurer_payment.selected }"
ng-click="selectInsurerPayment(insurer_payment)">
<span class="block text-ellipsis m-l-n text-md" ng-class="{'m-l-none': insurer_payment.selected }">
{{ insurer_payment.name }}
</span>
</a>
<div class="well well-sm">
<div class="row">
<div class="col-sm-4">
<strong>Commission: {{insurer_payment.commission}}</strong>
</div>
<div class="col-sm-4">
<strong>Insurer Ppayment: {{insurer_payment.insurer_payment}}</strong>
</div>
<div class="col-sm-4">
<strong>Inequality: {{insurer_payment.commission - insurer_payment.insurer_payment}}</strong>
</div>
</div>
</div>
<div class="table-responsive">
<div ng-grid="gridOptions" class="gridStyle">
</div>
</div>
And a part of a rails controller:
def index
insurer_payments = current_company.insurers.map do |insurer|
{
commission: insurer.contracts.pluck(:commission).sum.to_f,
name: insurer.name,
insurer_payment: insurer.insurer_payments.pluck(:amount).sum.to_f,
id: insurer.id
}
end
insurer_payment = current_company.insurers.map do |insurer|
{
amount: insurer.insurer_payments.pluck(:amount).map { |x| x.to_f },
comment: insurer.insurer_payments.pluck(:comment),
date: insurer.insurer_payments.pluck(:date),
id: insurer.id
}
end
total_insurer_payments_count = current_company.insurers.map do |insurer|
insurer.insurer_payments.count
end
insurer_payments_count = current_company.insurer_payments.count
respond_to do |format|
format.json { render json: { insurer_payments: insurer_payments, insurer_payment: insurer_payment,
total_insurer_payments_count: total_insurer_payments_count,
insurerPaymentsCount: insurer_payments_count } }
end
end
So, how it can be done, by selecting an insurer to see the corresponding data?
I am not sure on this, since I don't have all of your code, but you may want to try some of the changes I have below.
Because ng-repeat has it's own scope, iterating through insurer_payment in insurer_payments is conflicting with insurer_payment on scope. When you loop through the insurer_payments, you are modifying the value of insurer_payment each time.
I would change
$scope.gridOptions = {
data: "insurer_payment",
to
$scope.gridOptions = {
data: [];
Since the data is an array, not a string.
Within the success callback of $http, you need to set gridOptions.data (unless this is elsewhere, I don't see where the grid is)
.success(function (data, insurer_payment) {
$scope.gridOptions.data = data;
...
}
And the selectInsurerPayment function:
$scope.selectInsurerPayment = function(item){
angular.forEach($scope.insurer_payments, function(item) {
item.selected = false;
});
$scope.selectedInsurerPayment = item;
$scope.insurer_payment.selected = true;
};
And finally, in the well in your HTML, change references to insurer_payment to selectedInsurerPayment, ex:
<strong>Commission: {{selectedInsurerPayment.commission}}</strong>
Old Solution
In ng-repeat:
ng-click="selectInsurerPayment(insurer_payment)"
to
ng-click="selection.insurer_payment = insurer_payment"
In the well,
<div class="well well-sm">
to
<div class="well well-sm" ng-if="selection.insurer_payment">
and change the references to insurer_payment to selection.insurer_payment.{variable}, example:
<strong>Commission: {{selection.insurer_payment.commission}}</strong>

ng-select with lazy population

It's an edit form with parent record first populated then dependent select list is populated, and then it's expected the value from parent record pre-select the combo box.
html
<select ng-model="data.trackId" >
<option ng-repeat="track in tracks" value="{{track.id}}">{{track.name}}</option>
initial result once parent record is pulled.
if(data) {
this.$scope.data.id = data.id;
this.$scope.data.name = data.name;
this.$scope.data.room = data.room;
this.$scope.data.start = data.start;
this.$scope.data.end = data.end;
this.$scope.data.dayId = data.day_id;
this.$scope.data.trackId = data.track_id;
this.$scope.data.color = data.color;
this.$scope.data.description = data.description;
this.$scope.$apply();
this.$element[0].removeAttribute("style");
}
//later track results were pulled
trackResult: function(data, status, headers, config) {
for(var i=0; i<data.length; i++) {
this.$scope.tracks.push(data[i]);
}
this.$scope.$apply();
},
Problem:
List gets populated from the second call trackResult but default value from the $scope.trackId never sets the combo box to a value.
Edit: Controller Body
controller: function($scope, $element) {
var self = this;
this.$scope = $scope;
this.$element = $element;
this.$scope.data = {};
this.$scope.days = [];
this.$scope.tracks = [];
this.$scope.submit = function() {self.submit()};
this.$scope.cancel = function() {self.cancel()};
},
Edit : Updated with setting the data from outside the scope (OP request)
Use ng-options & ng-model
this is how i think it should be done in angularjs.
use the built in databinding capabilities to simplify your code and make it less complicated
for binding a list into a <select> and controlling the selected item, this snippet below should do the trick.
http://jsfiddle.net/72em40j4/
js
var myapp = angular.module('myapp', []);
myapp.controller('Ctrl', function ($scope) {
$scope.options = [];
$scope.selectedOption = null;
});
html
<script>
function clickFromOutside() {
var controllerElement = document.getElementById('container');
var controllerScope = angular.element(controllerElement).scope();
var firstTrack = {
id: 1,
first: 'First',
last: 'Track'
};
var secondTrack = {
id: 2,
first: 'Second',
last: 'Track'
};
controllerScope.options.push(firstTrack);
controllerScope.options.push(secondTrack);
controllerScope.selectedOption = secondTrack;
controllerScope.$apply();
}
</script>
<button onclick="clickFromOutside();">outside</button>
<div ng-app="myapp">
<fieldset id="container" ng-controller="Ctrl">
<select ng-options="p.first + ' ' + p.last for p in options" ng-model="selectedOption"></select> <pre>{{ selectedOption }}</pre>
</fieldset>
</div>

Show element only if value matches in JSON array

i am trying to display element only if the uid exist in JSON array:
i've tried it so far:
var app = agular.module('myApp', []);
app.controller('myCtrl', function () {
$scope.uid = '10';
$scope.datas = [{
'id': '1',
'name': 'abc'
}, {
'id': '2',
'name': 'xyz'
}];
});
<p ng-if="datas.length | filter:{id: uid}">ID exist in array</p>
DEMO FIDDLE
you can define function on scope that would that for u (and use filter service inside)
i.e.
<div ng-app="mod">
<div ng-controller='MCtrl'>
<p ng-show="exists(1)">ID exist in array</p>
</div>
</div>
mod.controller('MCtrl', function($scope, $filter){
var items = [123,2,1]
$scope.exists = function(val){
return $filter('filter')(items, val).length > 0;;;
}
});
if you'd like to do it in view
<p ng-show="(items|filter:1:true).length > 0">ID exist in array</p>
btw, true means it should be exact match
Hi please see here: fiddle
<div ng-app="app">
<div ng-controller="myCtrl">
<p ng-show="check()">ID exist in array</p>
<p ng-hide="check()">ID NOT exist in array</p>
</div>
</div>
JS:
var app = angular.module('app', []);
app.controller('myCtrl', function ($scope) {
$scope.uid = '2';
$scope.datas = [{
'id': '1',
'name': 'abc'
}, {
'id': '2',
'name': 'xyz'
}];
$scope.check = function () {
var ifExist = false;
angular.forEach($scope.datas, function (data) {
if (data.id == $scope.uid)
ifExist = true;
});
return ifExist;
}
});

Resources