I would like to know if there is a simple way of parsing different array to a single *ngfor table. I have the below codes:
.html
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="date" (click)="valid()" />
<label class="form-check-label">Valid</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="date" (click)="invalid()"/>
<label class="form-check-label">Invalid</label>
</div>
</div>
<tr *ngFor="let myAccount of Account | filterBy: accountFilter | paginate: { itemsPerPage: count, currentPage: p }; let i = index">
<td>{{ (p - 1) * count + i + 1 }}</td>
<td>{{myAccount.name}}</td>
<td>{{myAccount.startDate}}</td>
<td>{{myAccount.endDate}}</td>
</tr>
.ts
Account = [];
radioAccount = [];
currentDate = '';
ngOnInit() {
showAll();
}
showAll() {
return this.acctService.getAccount().subscribe(data => this.Account = data);
}
valid() {
this.currentDate = this.datePipe.transform(new Date(),"yyyy-MM-dd");
this.radioAccount = this.Account.filter(data => {
return data.startDate < this.currentDate && data.endDate > this.currentDate});
}
invalid() {
this.currentDate = this.datePipe.transform(new Date(),"yyyy-MM-dd");
this.radioAccount = this.Account.filter(data => {
return data.startDate < this.currentDate && data.endDate <= this.currentDate});
}
You can see that I have two arrays, how do I display content of "radioAccount" array when a radio button is clicked? That is, the possibility of swiching between "Account" content and "radioAccount" content. I don't think repeating the *ngfor code with *ngif is a solution.
You can create an array which will not be filtered, e.g., AccountSource and then you can assign original values (AccountSource) to Account:
Account = [];
AccountSource= [];
showAll() {
return this.acctService.getAccount()
.subscribe(data => {
this.Account = data;
this.AccountSource = data;
});
}
valid() {
this.currentDate = this.datePipe.transform(new Date(),"yyyy-MM-dd");
this.Account = this.Account.filter(data => {
return data.startDate < this.currentDate && data.endDate > this.currentDate});
}
invalid() {
this.currentDate = this.datePipe.transform(new Date(),"yyyy-MM-dd");
this.Account = this.Account.filter(data => {
return data.startDate < this.currentDate && data.endDate <= this.currentDate});
}
setSourceData() {
this.Account = this.AccountSource;
}
and call setSourceData() method whenever you want to see original values.
Related
I am working on angularjs , where I am loading dropdowns from database in angularjs controller. I am facing an intermittent issue that sometimes dropdown values load and sometimes don't . Its working on my local but when I upload on server this intermittent issue is coming.
I have even tried to use ng-init on html and then put login there in that function but still this issue is there.
here is html
<div class="x_panel" ng-init="loadDropDownData()">
<div class="x_title">
<h2 id="EditjobTitle" style="display:none">Edit Job<small></small></h2>
<button class="btn col-md-offset-9" id="btnBack" style="display:none" ng-click="Cancel()">Back</button>
<h2 id="NewjobTitle">New Engagement<small></small></h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<br>
<form name="JobForm" id="demo-form2" data-parsley-validate="" class="form-horizontal form-label-left" novalidate="">
<div class="form-group">
<div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-3 save-buttons">
<button type="submit" class="btn btn-success" ng-click="JobForm.$valid && save()">Save</button>
<button class="btn" ng-click="Cancel()">Cancel</button>
</div>
</div>
<h5>Job Data</h5>
<input type="hidden" id="JobID" ng_value="{{Job.JobNum}}">
<div class="form-group">
#Html.Label("Job Name", new { #class = "control-label control-label-j col-md-2 col-sm-3 col-xs-12" })
<div class="col-md-3 col-sm-3 col-xs-12">
<input type="text" name="JobName" ng-model="Job.JobName" ng-minlength="4" id="txtJobName" class="form-control col-md-7 col-xs-12" required="" maxlength=25>
</div>
#Html.Label("EngType", new { #class = "control-label control-label-j col-md-2 col-sm-3 col-xs-12" })
<div class="col-md-3 col-sm-3 col-xs-12">
<select name="EngType" ng-model="Job.EngType" ng-options="s.ID as s.EngTypes for s in Job.lstEngType" class="form-control col-md-7 col-xs-12" required="">
<option value="">-- Select EngType --</option>
</select>
</div>
</div>
</form>
</div>
</div>
and Js file is as below
app.controller('AddJobController', function ($scope, $location, $filter, ShareData, jobService, $compile) {
$scope.phoneNumbr = /^\+?\d{3}[- ]?\d{3}[- ]?\d{4}$/;
$scope.datePattern = /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/i
$scope.regEx = "/^[0-9]{10,10}$/;";
$scope.listOfStatus = [];
$scope.showStatusError = false;
$scope.statusText = "";
$scope.loadDropDownData = function() {
loadJobInitdata();
}
$(document).ready(function () {
$("#txtCloseDate").datepicker({ format: 'mm/dd/yyyy' });
$("#txtDraft_Date").datepicker({ format: 'mm/dd/yyyy' });
$("#txtFinal_Date").datepicker({ format: 'mm/dd/yyyy' });
$("#txtOpenDate").datepicker({ format: 'mm/dd/yyyy' });
$("#txtFinalSent").datepicker({ format: 'mm/dd/yyyy' });
$('body').off('click', '.remove-record').on('click', '.remove-record', function () {
removeSpan = "";
var addButton = "<div class='col-md-3 col-sm-3 col-xs-12'>\
<input type='button' class='btn btnAddDeadline' value='Add Deadline' />\
</div>";
var ifAdd = false;
if ($(this).parent().find('.btnAddDeadline').length == 1) {
ifAdd = true;
}
if ($scope.Job.JobNum != null && $scope.Job.JobNum != undefined) {
var ID = $(this).parent().find('.deadline-datepicker').attr('id')
ID = ID.replace("Date", "");
var removeSpanElement = $(this);
if (ID != "txtDeadlines") {
var promiseDeleteDeadline = jobService.DeleteDeadline(ID)
promiseDeleteDeadline.then(function () {
removeSpanElement.parent().remove();
if (ifAdd) {
PopulateDeadline(null, addButton, removeSpan);
$('.deadline-datepicker').datepicker({
ignoreReadonly: true,
startDate: new Date()
});
}
})
}
else {
$(this).parent().remove();
if (ifAdd) {
PopulateDeadline(null, addButton, removeSpan);
$('.deadline-datepicker').datepicker({
ignoreReadonly: true,
startDate: new Date()
});
}
}
}
else {
$(this).parent().remove();
if (ifAdd) {
PopulateDeadline(null, addButton, removeSpan);
$('.deadline-datepicker').datepicker({
ignoreReadonly: true,
startDate: new Date()
});
}
}
});
})
if (ShareData.value == 0) {
//loadJobInitdata();
}
else {
Edit();
}
$scope.maxlength = 3;
$scope.Job = [];
function Edit() {
if (!ShareData.createAsNewJob) {
$('#NewjobTitle').hide();
$('#EditjobTitle').show();
$('#btnBack').show();
}
//loadJobInitdata();
var promiseEditjobData = jobService.EditJob(ShareData.value);
promiseEditjobData.then(function (jobdata) {
GetDeadlinesbyJobID(ShareData.value);
getStatusCommentsJobId(ShareData.value);
$scope.Job = jobdata.data;
var CloseDate = $scope.Job.CloseDate = (jobdata.data.CloseDate != null && jobdata.data.CloseDate != undefined) ? $filter('date')(new Date(jobdata.data.CloseDate), 'MM/dd/yyyy') : null
var OpenDate = $scope.Job.OpenDate = jobdata.data.OpenDate = (jobdata.data.OpenDate != null && jobdata.data.OpenDate != undefined) ? $filter('date')(new Date(jobdata.data.OpenDate), 'MM/dd/yyyy') : null
var Draft_Date = $scope.Job.Draft_Date = jobdata.data.Draft_Date = (jobdata.data.Draft_Date != null && jobdata.data.Draft_Date != undefined) ? $filter('date')(new Date(jobdata.data.Draft_Date), 'MM/dd/yyyy') : null
var Final_Date = $scope.Job.Final_Date = jobdata.data.Final_Date = (jobdata.data.Final_Date != null && jobdata.data.Final_Date != undefined) ? $filter('date')(new Date(jobdata.data.Final_Date), 'MM/dd/yyyy') : null
$scope.Job.Deadlines = jobdata.data.Deadlines = (jobdata.data.Deadlines != null && jobdata.data.Deadlines != undefined) ? $filter('date')(new Date(jobdata.data.Deadlines), 'MM/dd/yyyy') : null
console.log(new Date(CloseDate));
var myDate = new Date(1978, 2, 11)
if (CloseDate != null) { $("#txtCloseDate").datepicker("update", new Date(CloseDate)); }
if (OpenDate != null) { $("#txtOpenDate").datepicker("update", new Date(OpenDate)); }
if (Draft_Date != null) { $("#txtDraft_Date").datepicker("update", new Date(Draft_Date)); }
if (Final_Date != null) { $("#txtFinal_Date").datepicker("update", new Date(Final_Date)); }
ShareData.value = 0;
if (ShareData.createAsNewJob == true) {
$scope.Job.JobNum = null;
ShareData.createAsNewJob = false;
}
},
function (errorPl) {
$scope.error = errorPl;
ShareData.value = 0;
alert($scope.error);
});
}
function loadJobInitdata() {
var promiseLoadDLLs = jobService.GetJobInitData();
promiseLoadDLLs.then(function (pl) {
//$scope.Job = pl.data
$scope.Job.lstEngType = pl.data.lstEngType,
$scope.Job.lstWorkProduct = pl.data.lstWorkProduct,
$scope.Job.lstNAICSCode = pl.data.lstNAICSCode,
$scope.Job.lstSubject = pl.data.lstSubject,
$scope.Job.lstManager = pl.data.lstManager,
$scope.Job.lstClientType = pl.data.lstClientType,
$scope.Job.lstFeeBasis = pl.data.lstFeeBasis,
$scope.Job.lstBillingCycle = pl.data.lstBillingCycle,
$scope.Job.lstExpenses = pl.data.lstExpenses,
$scope.Job.lstSalesperson = pl.data.lstSalesperson,
$scope.Job.lstPriority = pl.data.lstPriority,
$scope.Job.lstStaff = pl.data.lstStaff,
$scope.Job.lstLogo_in_Client_Logo_File = pl.data.lstLogo_in_Client_Logo_File,
$scope.Job.lstTombstone_Status = pl.data.lstTombstone_Status
},
function (errorPl) {
$scope.error = errorPl;
alert($scope.error);
});
}
$scope.Cancel = function () {
$location.path(ShareData.page);
}
$scope.AddDeadline = AddDeadline;
});
I'm trying to update the table view depending on select option. The table view is updating only once, when i select the option second time the view is not updating, I'm not getting what's the problem. please help me solve this..
here is app.js
$scope.User = {};
$scope.arr = [];
$scope.loaddata = function(User) {
$scope.User.site = layouts;
AllServices.teamAllDataFunction1(User)
.then(function(response) {
$scope.User.data=response.data;
});
};
$scope.getdatalayoutwise = function(User) {
var total = 0;
var total1 = 0;
for (var i = 0; i < ($scope.User.data).length; i++) {
if($scope.User.data[i].Layout == $scope.User.selectedSite) {
total += parseInt($scope.User.data[i].dp_inst_pending);
$scope.arr.push($scope.User.data[i]);
}
}
for (var j = 0; j < ($scope.User.data1).length; j++) {
if($scope.User.data1[j].Layout == $scope.User.selectedSite) {
total1 += parseInt($scope.User.data1[j].DP_Inst_Pending);
}
}
$scope.User.teamTotal = total;
$scope.User.personalTotal = total1;
$scope.data = [$scope.User.teamTotal, $scope.User.personalTotal];
$scope.totamnt = parseInt($scope.User.personalTotal) + parseInt($scope.User.teamTotal);
$scope.User.totalamount = $filter('translate')('totalpending') + ": " + $filter('currency')($scope.totamnt, "");
$scope.User.data = $scope.arr;
};
here is html
<select name="site" ng-model="User.selectedSite" ng-change="getdatalayoutwise(User)">
<option value="">--{{'selectsite_message' | translate}}--</option>
<option ng-repeat= "option in User.site" value="{{option.Layout}}">{{option.Layout}}</option>
</select>
<table ng-table>
<tr>
<th>advisor_name</th>
<th>totalpending</th>
</tr>
<tr ng-repeat="data in User.data | filter : {Layout: User.selectedSite}: true" ng-if="data.dp_inst_pending">
<td class="ui-helper-center"><a ng-click="advisorDetails($index, data, User)">{{data.AdvisorName}}</a></td>
<td>{{data.dp_inst_pending | currency:"₹":0}}</td>
</tr>
</table>
you need to use $scope.$apply() :
$scope.getdatalayoutwise = function(User) {
$scope.$apply(function () {
var total = 0;
var total1 = 0;
for (var i = 0; i < ($scope.User.data).length; i++) {
if($scope.User.data[i].Layout == $scope.User.selectedSite) {
total += parseInt($scope.User.data[i].dp_inst_pending);
$scope.arr.push($scope.User.data[i]);
}
}
...
});
}
https://www.grafikart.fr/formations/angularjs/apply-watch-digest
Change your function to this
$scope.loaddata = function(User) {
$scope.User.data = [];
$scope.User.site = layouts;
AllServices.teamAllDataFunction1(User)
.then(function(response) {
$scope.User.data=response.data;
});
and add a ng-if
<table ng-table ng-if="User.data.length">
<tr>
<th>advisor_name</th>
<th>totalpending</th>
</tr>
<tr ng-repeat="data in User.data | filter : {Layout: User.selectedSite}: true" ng-if="data.dp_inst_pending">
<td class="ui-helper-center"><a ng-click="advisorDetails($index, data, User)">{{data.AdvisorName}}</a></td>
<td>{{data.dp_inst_pending | currency:"₹":0}}</td>
</tr>
</table>
Add this as the first line in getdatalayoutwise () function:
$scope.arr = [];
got it working by just doing following
$scope.safeApply = function(fn) {
var phase = this.$root.$$phase;
if(phase == '$apply' || phase == '$digest') {
if(fn && (typeof(fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
$scope.getdatalayoutwise = function(User) {
var total = 0;
var total1 = 0;
for (var i = 0; i < ($scope.User.data).length; i++) {
if($scope.User.data[i].Layout == $scope.User.selectedSite) {
total += parseInt($scope.User.data[i].dp_inst_pending);
$scope.arr.push($scope.User.data[i]);
}
}
...
$scope.safeApply (function () {
$scope.User.data = $scope.arr;
});
};
I have a below JSON:
[{"brand":"abc"},{"brand":"xyz"},{"brand":"abc"},{"brand":"abc"},{"brand":"por"},{"brand":"xyz"}]
Using ng-repeat, How can I display like -
Brand Occurances
abc (3)
xyz (2)
por (1)
i.e. brand name (number of duplicate occurrences of same brand name)?
You can create a custom function which will be returning the count from the existing array with the repeatvie values (occurances)
Along with the filter to show the unique values from the JSON:
$scope.getCount = function(i) {
var iCount = iCount || 0;
for (var j = 0; j < $scope.brands.length; j++) {
if ($scope.brands[j].brand == i) {
iCount++;
}
}
return iCount;
}
AND a filter will look like this:
app.filter('unique', function() {
return function (arr, field) {
var o = {}, i, l = arr.length, r = [];
for(i=0; i<l;i+=1) {
o[arr[i][field]] = arr[i];
}
for(i in o) {
r.push(o[i]);
}
return r;
};
})
Working Plunkr
To get unique items from an array you could write a custom filter, in AngularJS filters are used to modify the data to be displayed to the user and in order to get the count of the duplicate items from an array you can write a function on the controller's scope and call it in the view.
Check the below code snippet on how to achieve it.
angular
.module('demo', [])
.controller('DefaultController', DefaultController)
.filter('unique', unique);
function DefaultController() {
var vm = this;
vm.items = [
{
"brand":"abc"
},
{
"brand":"xyz"
},
{
"brand":"abc"
},
{
"brand":"abc"
},
{
"brand":"por"
},
{
"brand":"xyz"
}
];
vm.getBrandCount = getBrandCount;
function getBrandCount(brand) {
var count = 0;
if (brand !== undefined && brand !== null && brand.length > 0) {
for (var i = 0; i < vm.items.length; i++) {
if (vm.items[i].brand === brand) {
count++;
}
}
}
return count;
}
}
function unique() {
return function(array, key) {
if (angular.isArray(array) && array.length > 0 && key !== undefined && key !== null && key.length > 0) {
var arr = [], keys = [];
for (var i = 0; i < array.length; i++) {
if (keys.indexOf(array[i][key]) === -1) {
keys.push(array[i][key]);
arr.push(array[i]);
}
}
return arr;
}
return array;
}
}
.brandcount:before {
content: '('
}
.brandcount:after {
content: ')'
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<table>
<thead>
<tr>
<th>Brand</th>
<th>Occurances</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in ctrl.items | unique: 'brand'">
<td>
<span ng-bind="item.brand"></span>
</td>
<td>
<span class="brandcount" ng-bind="ctrl.getBrandCount(item.brand)"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
You need to first process your data before passing to ng-repeat like this:
var app = angular.module("sa", []);
app.controller("FooController", function($scope) {
var data = [{
"brand": "abc"
}, {
"brand": "xyz"
}, {
"brand": "abc"
}, {
"brand": "abc"
}, {
"brand": "por"
}, {
"brand": "xyz"
}];
$scope.processedData = [];
// Group the raw data based on the brand name and store the count
function groupData() {
angular.forEach(data, function(item) {
// Check https://github.com/sagrawal14/angular-extras/blob/master/src/extras/array.js for this utility "find" method
var existingBrand = $scope.processedData.find("brand", item.brand);
if (!existingBrand) {
existingBrand = item;
existingBrand.count = 0;
$scope.processedData.push(existingBrand);
}
existingBrand.count++;
});
}
groupData();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://rawgit.com/sagrawal14/angular-extras/master/src/extras/array.js"></script>
<div ng-app="sa" ng-controller="FooController">
<table>
<tr ng-repeat="data in processedData">
<td>{{data.brand}}</td>
<td>{{data.count}}</td>
</tr>
</table>
<br><br>Processed/grouped data: {{processedData | json}}
</div>
I've been facing an issue since couple of hours. My view template looks like-
<div class="row" ng-repeat="row in CampaignsService.getRows().subItems track by $index">
<div class="col-sm-2">
<select class="form-control dropDownPercent" ng-model="CampaignsService.dropDownPercent[{{CampaignsService.selectCounter}}]" ng-change="CampaignsService.wow(CampaignsService.dropDownPercent, $index)" ng-options="o as o for o in CampaignsService.showPercentDropDown().values">
</select>
</div>
<div class="col-sm-2" style="line-height: 32px">
of visitors send to
</div>
<div class="col-sm-4">
<select class="form-control" ng-model="campaignSelect" ng-options="campaign.Campaign.id as campaign.Campaign.title for campaign in CampaignsService.getRows().items">
<option value=""> Please select </option>
</select>
</div>
<div class="col-sm-4">
<a class="btn btn-default" target="_blank" href="">Show campaign</a>
</div>
Variable CampaignsService.selectCounter is a counter variable and declared in service but when I'm going to use ng-model="CampaignsService.dropDownPercent[{{CampaignsService.selectCounter}}]" it gives me error -
Error: [$parse:syntax] Syntax Error: Token '{' invalid key at column 35 of the expression [CampaignsService.dropDownPercent[{{CampaignsService.selectCounter}}]] starting at [{CampaignsService.selectCounter}}]]
And when I use ng-model="CampaignsService.dropDownPercent['{{CampaignsService.selectCounter}}']" it does not give any error but it takes this variable as string.
My question is how could I create a model array and get model's array values in my service ?? I read many questions in stack community and none of the trick work for me. My service under my script, is
.service('CampaignsService', ['$rootScope', 'AjaxRequests', function ($rootScope, AjaxRequests) {
this.dropDownPercent = [];
this.selectCounter = 0;
var gareeb = [];
this.showPercentDefault = 100;
// this.campaignsData = [];
this.$rowsData = {
items: [], //array of objects
current: [], //array of objects
subItems: [] //array of objects
};
this.getRows = function () {
return this.$rowsData;
}
this.addNewRow = function () {
var wowRow = {}; //add a new object
this.getRows().subItems.push(wowRow);
this.selectCounter++;
gareeb.push(0);
}
this.calculatePercentages = function (index) {
angular.forEach(this.getRows().current, function (data, key) {
if (key == index) {
console.log(data);
}
})
}
this.showPercentDropDown = function ($index) {
var balle = 0;
var start;
angular.forEach(gareeb, function (aha, keywa) {
balle += aha;
})
var last = 100 - balle;
var final = [];
for (start = 0; start <= last; start += 10) {
final.push(start);
}
return this.values = {
values: final,
};
}
this.wow = function (valueWa, keyWa) {
console.log(this.dropDownPercent);
gareeb[keyWa] = valueWa;
this.changePercentDropDown();
}
this.changePercentDropDown = function () {
var angElement = angular.element(document.querySelector('.dropDownPercent'));
angular.forEach(angElement, function (data, key) {
console.log(data);
})
}
}])
Target model structure should be
ng-model="CampaignsService.dropDownPercent[1]"
ng-model="CampaignsService.dropDownPercent[2]"
ng-model="CampaignsService.dropDownPercent[3]"
A big thanks in advance.
Since you are in context of the Angular expression, you don't need interpolation tags {{...}}. So ngModel directive should look like this:
ng-model="CampaignsService.dropDownPercent[CampaignsService.selectCounter]"
I'm trying to create a tree structure in the select element. I make indention by filter. As a result this indentation trims after output. Is that possible to disable trimming?
<select id="cat">
<option value="{{category.id}}" ng-repeat="category in categories">{{category | intent}}</option>
</select>
app.filter('intent', function() {
return function(category) {
var INTENT_SIZE = 4;
if (category == null) {
return '';
}
var result = "";
for (var i = 0; i < category.intent * INTENT_SIZE; i++) {
result += " ";
}
result += category.name;
return result;
};
})
For angular 2+ I use this pipe to 'untrim' template spaces :
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'untrim'
})
export class UntrimPipe implements PipeTransform {
transform(value: any, args?: any): any {
return typeof value === 'string' ? value.replace(/\s/g, ' ') : value;
}
}
Related:
Add space to <select> with ng-options
var app = angular.module('app', []);
app.filter('intent', function() {
return function(category) {
var INTENT_SIZE = 4;
if (category == null) {
return '';
}
var result = "";
for (var i = 0, len = category.intent * INTENT_SIZE; i < len; i++) {
result += String.fromCharCode(160);
}
result += category.name;
return result;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
<div ng-init="categories = [{id: 0, name:'bob', intent: 0},
{id: 1, name:'chris', intent: 1},
{id: 2, name:'mike', intent: 2}]"></div>
<select id="cat">
<option value="{{category.id}}" ng-repeat="category in categories">
{{ category | intent }}
</option>
</select>
</div>
You need to use the HTML character to render a space that will not be ignored by the browser.
But then you need to make sure that Angular "trusts" the HTML you are trying to use.
You can accomplish that by changing your markup to:
<select id="cat">
<option value="{{category.id}}" ng-repeat="category in categories" ng-bind-html="category | intent"></option>
</select>
Then change your filter code to:
app.filter('intent', function($sce) {
return function(category) {
var INTENT_SIZE = 4;
if (category == null) {
return '';
}
var result = "";
for (var i = 0; i < category.intent * INTENT_SIZE; i++) {
result += " ";
}
result += category.name;
return $sce.trustAsHtml(result);
};
});
Working Plunkr
NB: I only tested this in Chrome version 41. I'm not sure if all browsers allow having s in the option text.
To get space characters in your options use ng-bind-html to render the space.
<select id="cat">
<option value="{{category.id}}" ng-repeat="category in categories" ng-bind-html="category | intent"></option>
</select>
In your Filter:
app.filter('intent', function($sce) {
return function(category) {
var INTENT_SIZE = 4;
if (category == null) {
return '';
}
var result = "";
for (var i = 0; i < category.intent * INTENT_SIZE; i++) {
result += " ";
}
result += category.name;
return $sce.trustAsHtml(result);
};
});
DEMO