I'm trying to initialise/select a particular radio button within a group. I want to pass in an index number to an attribute called "selected-item".
HTML
<div class="top">
<radio-buttons model="colour" selected-item="1" items='colours'></radio-buttons>
<div>{{colour}}</div>
</div>
<div class="center">
<radio-buttons model="day" selected-item="2" items='days'></radio-buttons>
<div>{{day}}</div>
</div>
<div class="bottom">
<radio-buttons model="phone" selected-item="3" items="phones"></radio-buttons>
<div>{{phone}}</div>
</div>
Directive:
directives.directive('radioButtons', function () {
return {
restrict: 'E',
scope: {
model: '=',
items: '=',
selectedItem: '#'
},
templateUrl: 'template/radio-group.html',
link: function(scope) {
console.log(scope.selectedItem);
scope.onItemChange = function(item) {
console.log(item);
scope.model = item;
};
}
};
});
Template: radio-group.html:
<div ng-repeat='item in items'>
<input
type="radio"
name="{{item.group}}"
ng-value="{{item.value}}"
ng-model="model"
ng-change="onItemChange(item)"/>
{{item.text}}
</div>
Controller
$scope.colours= [ {
text: "Pink",
value: 5,
group: "colourGroup",
img: 'app/img/icon.jpg'
}, {
text: "Yellow",
value: 6,
group: "colourGroup",
img: 'app/img/icon.jpg'
}, {
text: "Blue",
value: 7,
group: "colourGroup",
img: 'app/img/icon.jpg'
}, {
text: "Green",
value: 8,
group: "colourGroup",
img: 'app/img/icon.jpg'
}
];
$scope.days = [ {
text: "Monday",
value: 9,
group: "dayGroup"
}, {
text: "Tuesday",
value: 10,
group: "dayGroup"
}, {
text: "Wednesday",
value: 11,
group: "dayGroup"
}, {
text: "Thursday",
value: 12,
group: "dayGroup"
}
];
$scope.phones = [ {
text: "Android",
group: "phoneGroup",
value: 13
}, {
text: "iOS",
group: "phoneGroup",
value: 14
}, {
text: "Blackberry",
group: "phoneGroup",
value: 15
}];
Any help would be fantastic!
Cheers.
Try changing ng-value="{{item.value}}" to value="{{item.value}}".
Then add ng-checked="$index == (selectedItem - 1)" to the input in the template.
Alternatively: ng-checked="$index == (selectedItem - 1) || $first" or with $last, if you want it to select something if you try an index that is out of range.
Without using value, here is another solution:
link: function(scope) {
scope.model = angular.copy(scope.items[scope.selectedItem -1]);
var setSelected = function(v) {
var i = 0;
for(; i < scope.items.length;i++) {
if(scope.items[i].value === v) {
return scope.items[i];
}
}
}
scope.$watch('model.value',function(v) {
//because the value is out of sync with the model, have to reset the model
scope.model = angular.copy(setSelected(v));
});
}
Note that ng-value has to be a string, and therefore ng-model. scope.model is only exposed as scope in your directive, so am using scope.model.value
<div ng-repeat='item in items'>
<input
type="radio"
name="{{item.group}}"
ng-value="{{item.value}}"
ng-model="model.value" />
{{item.text}}
</div>
Related
I created a custom directive.
angular.module('menu',[])
.directive('Menu',function(){
return{
restrict:'E',
replace:'true',
scope:{
menuList:'=',
id:'#',
parentId:'#'
},
controller:function($scope){
},
template: `
<div ng-repeat="menuItem in menuList">
<a>{{menuItem.longDescription}}</a>
<div ng-if="menuItem.child.size() > 0 ">
<menu menu-list="menuItem.child"
id="menuItem.optionGroupId"
parent-id="menuItem.parentOptionGroupId">
</menu>
</div>
</div>
`
}
})
Menu items can have child list and if child list exist it should make menu recursively, but recursion is not happening.
(function() {
angular.module("menuTest", [])
.controller('testCtrl', function($scope) {
$scope.menu = [{
id: 1,
children: [{
id: 3
}]
},
{
id: 2,
children: [{
id: 4
},
{
id: 5
}
]
}
];
})
.directive("menu", function() {
return {
restrict: "E",
replace: true,
scope: {
menuList: '='
},
template: '<div ng-repeat="menuItem in menuList">{{menuItem.id}}<div ng-if="menuItem.children && menuItem.children.length>0" ><menu menu-list="menuItem.children"></menu></div><div>'
}
})
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="menuTest" ng-controller="testCtrl">
<menu menu-list="menu"></menu>
</div>
I am new in angular js i want to put filter in ng-repeat i have json like this
var data = [
{name:test1,b1:{lastValue:0},b2:{lastValue:6},b3:{lastValue:6},b4:{lastValue:0}}
{name:test2,b1:{lastValue:6},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}}
{name:test3,b1:{lastValue:6},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}}
]
I want to put filter on lastValue i tested like this
ng-repeat = "d in data | filter:{*.lastValue:filterStatus}"
filterStatus // contain value of filter which user selected but its not working
I don't know how to do this i tried google but nothing found please help me
<input ng-model="filterStatus" type="text">
your filterStatus should hold model value
ng-repeat = "d in data | filter:filterStatus"
var app = angular.module("Profile", []);
app.controller("ProfileCtrl", function($scope) {
$scope.filter_val = {}
$scope.data = [{
name: 'test1',
b1: {
lastValue: 0
},
index: 'b1'
}, {
name: 'test2',
b2: {
lastValue: 6
},
index: 'b2'
}, {
name: 'test3',
b3: {
lastValue: 6
},
index: 'b3'
}, {
name: 'test4',
b4: {
lastValue: 0
},
index: 'b4'
}, {
name: 'test5',
b5: {
lastValue: 89
},
index: 'b5'
}, {
name: 'test6',
b6: {
lastValue: 68
},
index: 'b6'
}]
$scope.own_filter = function(val) {
if (!$scope.filter_val.value)
return true;
else {
return (String(val[val['index']]['lastValue'] || '').indexOf($scope.filter_val.value) != -1)
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="Profile" ng-controller="ProfileCtrl">
<input type="text" ng-model="filter_val.value" placeholder="Enter Last Value">
<div class="row" ng-repeat="event in data |filter:own_filter track by $index ">
<h4>{{'Name : ' + event.name}}------{{'Last Value : '+event[event['index']]['lastValue']}}</h4>
</div>
</body>
Use {$:filterStatus} construction:
angular.module('app', []).controller('ctrl',function($scope){
$scope.data = [
{name:'test1',b1:{lastValue:1},b2:{lastValue:6},b3:{lastValue:6},b4:{lastValue:0}},
{name:'test2',b1:{lastValue:2},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}},
{name:'test3',b1:{lastValue:3},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}}
]
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<div ng-app='app' ng-controller='ctrl'>
<input type='number' ng-model='filterStatus' ng-init='filterStatus=1'>
<ul>
<li ng-repeat='item in data | filter: {$:filterStatus}'>{{item.name}}</li>
</ul>
</div>
I am trying to do a pagination using filters.
There is a list with names and countries.
I am trying to filter them by country and also alphabetical range, and then generate the pagination by numbers. I am really stuck with it. any help will be really appreciate it
The alphabetical filter will retrieve the names that start with the the range of letters. For example if you select the first option [A - M] will return the person that their name start within that range of letters
Here is my code. The html is over there. Thanks
http://jsbin.com/cifowatuzu/edit?html,js,output
angular.module('app',['angular.filter'])
.controller('MainController', function($scope) {
$scope.selectedCountry = '';
$scope.currentPage = 1;
$scope.pageSize = 3;
$scope.pages = [];
//This should store {StartFrom and To from selected Range}
$scope.selectedRange = '';
$scope.AlphabethicalRange = [
{StartFrom: 'A', To: 'M'},
{StartFrom: 'N', To: 'Z'}
];
$scope.Countries = [
{ Name : 'USA'},
{ Name : 'Japan'},
{ Name : 'France'},
{ Name : 'Canada'},
{ Name : 'China'},
];
$scope.People = [
{ Id: 1, Name: 'Will', Country: 'USA'},
{ Id: 2, Name: 'Ed', Country: 'USA' },
{ Id: 3, Name: 'Peter', Country: 'China'},
{ Id: 4, Name: 'John', Country: 'Japan'},
{ Id: 5, Name: 'Alex', Country: 'France'},
{ Id: 6, Name: 'Jim', Country: 'France'},
{ Id: 7, Name: 'Austin', Country: 'Italy'},
{ Id: 8, Name: 'Men', Country: 'France'},
{ Id: 9, Name: 'Zike', Country: 'Canada'},
];
$scope.numberPages = Math.ceil($scope.People.length / $scope.pageSize);
$scope.init = function () {
for (i = 1; i < $scope.numberPages; i++) {
$scope.pages.push(i);
}
};
$scope.init();
});
I create a custom filter to filter the range that you want.
Here's a snippet working:
var app = angular.module('app', ['angular.filter']);
app.controller('mainCtrl', function ($scope) {
$scope.currentPage = 1;
$scope.pageSize = 3;
$scope.pages = [];
$scope.AlphabethicalRange = [
{
"StartFrom":"A",
"To":"M"
},
{
"StartFrom":"N",
"To":"Z"
}
];
$scope.Countries = [
{
"Name":"USA"
},
{
"Name":"Japan"
},
{
"Name":"France"
},
{
"Name":"Canada"
},
{
"Name":"China"
}
];
$scope.People = [
{
"Id":1,
"Name":"Will",
"Country":"USA"
},
{
"Id":2,
"Name":"Ed",
"Country":"USA"
},
{
"Id":3,
"Name":"Peter",
"Country":"China"
},
{
"Id":4,
"Name":"John",
"Country":"Japan"
},
{
"Id":5,
"Name":"Alex",
"Country":"France"
},
{
"Id":6,
"Name":"Jim",
"Country":"France"
},
{
"Id":7,
"Name":"Austin",
"Country":"Italy"
},
{
"Id":8,
"Name":"Men",
"Country":"France"
},
{
"Id":9,
"Name":"Zike",
"Country":"Canada"
}
];
$scope.numberPages = Math.ceil($scope.People.length / $scope.pageSize);
$scope.init = function() {
for (i = 1; i < $scope.numberPages; i++) {
$scope.pages.push(i);
}
};
$scope.init();
});
app.filter('rangeAlphaFilter', function() {
return function(items, search) {
if (!search || search == ' - ') {
return items;
}
return items.filter(function(element) {
return new RegExp('[' + search.replace(/ /g, '') + ']', 'i').test(element.Name[0]);
});
}
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.8/angular-filter.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<div>
<span>Country Filter</span>
<select name="countriesSelect" ng-options="c as c.Name for c in Countries" ng-model="selectedCountry">
<option value="">-- Select a country --</option>
</select>
<br>
<span>Alphabetical Filter</span>
<select name="AlphabeticalSelect" ng-options="a as a.StartFrom +' - '+ a.To for a in AlphabethicalRange" ng-model="selectedRange">
<option value="">-- Select a range --</option>
</select>
<ul>
<li ng-repeat="person in People | filter: { Country: selectedCountry.Name } | rangeAlphaFilter: selectedRange.StartFrom +' - '+ selectedRange.To" ng-bind="person.Name"></li>
</ul>
<span>Pagination Numbers</span>
{{page}}
</div>
</body>
</html>
PS: To control the pagination, I extremely don't recommend you to do it manually, it gives a lot of work. I recommend you to see my answer in this another question, it's like a "mini" tutorial of how to use the angularUtils-pagination. Check it.
I hope it helps.
I'm showing 8 checkboxes using ng-repeat and filtering the data by getting only checked values and showing them in comma separated list using another ng-repeat. But I need to show the exact filtered comma separated string in a textbox and update just as it is getting updated inside ng-repeat.
<div class="col-md-7">
<label class="checkbox" ng-repeat="tooth in teeth">
<input type="checkbox" ng-model="tooth.checked" ng-change="upperRight()" /> {{tooth.id}}
</label>
</div>
<div class="col-md-3">
<span ng-repeat="toothObj in teeth | filter:{ checked: true }">{{toothObj.id}}{{$last ? '' : ', '}}</span>
<input type="text" ng-model="selectedTeeth" />
</div>
Controller
$scope.teeth = [
{ id: 1, checked: false },
{ id: 2, checked: false },
{ id: 3, checked: false },
{ id: 4, checked: false },
{ id: 5, checked: false },
{ id: 6, checked: false },
{ id: 7, checked: false },
{ id: 8, checked: false }
];
Here I added it in plunker for better understanding Plunker URL
I just did it in following way
My controller
$scope.teethUR = [{ id: 1, checked: false }, { id: 2, checked: false }, { id: 3, checked: false }, { id: 4, checked: false }, { id: 5, checked: false }, { id: 6, checked: false }, { id: 7, checked: false }, { id: 8, checked: false }];
$scope.upperRight = function () {
$scope.URSelected = "";
for (var i = 0; i < $scope.teethUR.length; i++) {
if ($scope.teethUR[i].checked == true) {
if ($scope.URSelected == "") {
$scope.URSelected = $scope.teethUR[i].id;
} else {
$scope.URSelected = $scope.URSelected + ", " + $scope.teethUR[i].id;
}
}
}
}
And HTML
<div class="col-md-7">
<label class="checkbox" ng-repeat="tooth in teethUR">
<input type="checkbox" ng-model="tooth.checked" ng-change="upperRight()" /> {{tooth.id}}
</label>
</div>
<div class="col-md-3">
<input type="text" ng-model="URSelected" class="form-control" />
</div>
Have a look at the working code here PLUNKER DEMO
Demo
You can set up two-way binding between the textbox and the checkboxes. When you click the checkboxes, the text box is updated, and when you update the text box, the check boxes are updated.
First, setup two watches: one that watches teeth, and another that watches selectedTeeth:
$scope.$watch ('teeth', function(newVal) {
$scope.selectedTeeth = [];
for(var i = 0; i < newVal.length; ++i) {
if (newVal[i].checked)
$scope.selectedTeeth.push(newVal[i].id);
}
}, true);
$scope.$watch('selectedTeeth', function(newVal) {
for (var j = 0; j < $scope.teeth.length; ++j) {
var tooth = $scope.teeth[j];
if (newVal.indexOf(tooth.id) >= 0) {
tooth.checked = true;
}
else {
tooth.checked = false;
}
}
}, true);
Next set up a ngModel directive, that provides a formatter and a parser to marshal between the 'teeth' and 'selectedTeeth' and vice versa:
app.directive ('teethTextBox', function() {
return {
restrict: 'A',
require: 'ngModel',
scope: { ngModel: '=' },
link:function(scope, element, attr, ngModelController) {
ngModelController.$formatters.push(function(value) {
return value;
});
ngModelController.$parsers.push(function(value) {
var numbers = [];
var tmp = value.split(',');
for (var i = 0; i < tmp.length; ++i) {
numbers.push(parseInt(tmp[i]))
}
return numbers;
});
}
}
});
Hook up the directives in the HTML:
<body ng-controller="MainCtrl">
<div class="col-md-7">
<label class="checkbox" ng-repeat="tooth in teeth">
<input type="checkbox" ng-model="tooth.checked" ng-change="upperRight()" /> {{tooth.id}}
</label>
</div>
<div class="col-md-3">
<input type="text" ng-model="selectedTeeth" teeth-text-box />
</div>
</body>
Working from the KO example found here: http://knockoutjs.com/examples/grid.html,
I want to add a drop-down to select different page sizes (e.g. 4, 8, 12 items per page) and update the page grid upon changing the drop-down.
tried a bunch of things and I know I am missing something to get this to work. Thanks in advance for any help or a link to an existing solution.
What I sort of have now:
=== View ===
<div data-bind='simpleGrid: gridViewModel'> </div>
<select class="form-control" name="displayCount" id="displayCount" data-bind="value: valueDisplayCount;">
<option value="4">4</option><option value="8">8</option><option value="16">16</option>
</select>
<button data-bind='click: addItem'>
Add item
</button>
<button data-bind='click: sortByName'>
Sort by name
</button>
<button data-bind='click: jumpToFirstPage, enable: gridViewModel.currentPageIndex'>
Jump to first page
</button>
==== View Model =====
$( document ).ready(function(){
var initialData = [
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
{ name: "Furious Lizard", sales: 152, price: 25.00 },
{ name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ name: "Brooding Dragon", sales: 0, price: 6350 },
{ name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ name: "Optimistic Snail", sales: 420, price: 1.50 }
];
var PagedGridModel = function(items) {
this.items = ko.observableArray(items);
this.valueDisplayCount = ko.observable(4);
this.sortByName = function() {
this.items.sort(function(a, b) {
return a.name < b.name ? -1 : 1;
});
};
this.jumpToFirstPage = function() {
this.gridViewModel.currentPageIndex(0);
};
this.valUpdDisplayCount= function(){
alert($('#displayCount').val());
this.gridViewModel.pageSize(6);
};
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
],
pageSize: this.valueDisplayCount
});
};
ko.applyBindings(new PagedGridModel(initialData));
});
JSFiddle:
http://jsfiddle.net/RNunc/1/
You would need to tweak the simplegrid code to look for an observable for pageSize. The updates could look like:
ko.simpleGrid = {
// Defines a view model class you can use to populate a grid
viewModel: function (configuration) {
this.data = configuration.data;
this.currentPageIndex = ko.observable(0);
this.pageSize = configuration.pageSize || ko.observable(5);
// If you don't specify columns configuration, we'll use scaffolding
this.columns = configuration.columns || getColumnsForScaffolding(ko.unwrap(this.data));
this.itemsOnCurrentPage = ko.computed(function () {
var size = ko.unwrap(this.pageSize);
var startIndex = size * this.currentPageIndex();
return ko.unwrap(this.data).slice(startIndex, startIndex + size);
}, this);
this.maxPageIndex = ko.computed(function () {
return Math.ceil(ko.unwrap(this.data).length / ko.unwrap(this.pageSize)) - 1;
}, this);
}
};
The simplegrid code is here: http://knockoutjs.com/examples/resources/knockout.simpleGrid.3.0.js
http://jsfiddle.net/rniemeyer/82MAR/