I'm trying to show the value of year in the view that is HTML, but year values are not showing at all. Although, My other value is showing while the condition is not acivated (like credit card), but when I activate it, year values is not showing, while values are coming from the controller and is shown in the console.
Here is the view code :-
<div class="col-xs-2 innerN" style="width: 14%;">
<select ng-disabled="page.creditcard.isDisabled" class="form-control innerN" placeholder="YYYY" name="ccExpYear" ng-model="page.expyear" required style="border-left:none">
<option value="XX" selected ng-if="page.creditcard.isDisabled">XX</option>
<option ng-repeat="year in page.yearList" value="{{year}}" ng-if="!page.creditcard.isDisabled">{{year}}</option>
</select>
</div>
And Here is the controller code :-
$scope.page.monthList = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", ];
$scope.page.yearList = [];
var d = new Date();
var year = d.getFullYear();
//$scope.page.yearList.push(year);
$scope.page.expyear = year;
console.log("Pawan2", $scope.page.expyear);
for (var i = 0; i < 21; i++) {
{
$scope.page.yearList.push(year + i);
};
}
$scope.years = $scope.page.yearList;
console.log("YearListPawan", $scope.page.yearList);
$scope.page.expmonth = "01";
$scope.monthList = "01";
// watcher
$scope.$watchGroup(['page.expmonth', 'page.expyear'], function(newValues, oldValues, scope) {
//MM-YYYY
if (typeof newValues[1] == "undefined" || typeof newValues[0] == "undefined") scope.authorize.creditCard
.expirationDate = null;
else $scope.authorize.creditCard.expirationDate = newValues[1] + "-" + newValues[0];
console.log("Pawan", $scope.authorize.creditCard.expirationDate)
}, true);
I hope, I'm clear anough to get the answer for this.
PS : THnx in advance for help.
You should use ng-value instead of value:-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.page = {};
$scope.page.monthList = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", ];
$scope.page.yearList = [];
var d = new Date();
var year = d.getFullYear();
//$scope.page.yearList.push(year);
$scope.page.expyear = year;
console.log("Pawan2", $scope.page.expyear);
for (var i = 0; i < 21; i++) {
{
$scope.page.yearList.push(year + i);
};
}
$scope.years = $scope.page.yearList;
$scope.authorize = {creditCard: {expirationDate: 'date'}};
console.log("YearListPawan", $scope.page.yearList);
$scope.page.expmonth = "01";
$scope.monthList = "01";
// watcher
$scope.$watchGroup(['page.expmonth', 'page.expyear'], function(newValues, oldValues, scope) {
//MM-YYYY
if (typeof newValues[1] == "undefined" || typeof newValues[0] == "undefined")
$scope.authorize.creditCard.expirationDate = null;
else
$scope.authorize.creditCard.expirationDate = newValues[1] + "-" + newValues[0];
console.log("Pawan", $scope.authorize.creditCard.expirationDate)
}, true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="col-xs-2 innerN" style="width: 14%;">
<select ng-disabled="page.creditcard.isDisabled" class="form-control innerN" placeholder="YYYY" name="ccExpYear" ng-model="page.expyear" required style="border-left:none">
<option value="XX" selected ng-if="page.creditcard.isDisabled">XX</option>
<option ng-repeat="year in page.yearList" ng-value="year" ng-if="!page.creditcard.isDisabled">{{year}}</option>
</select>
</div>
</div>
Here is the solution that I have applied to the scenario -
And here is the controller code with few changes : -
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.page = {};
$scope.page.monthList = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", ];
$scope.page.yearList = [];
var d = new Date();
var year = d.getFullYear();
var addYears = function () {
var d = new Date();
var year = d.getFullYear();
$scope.page.yearList = [];
var i = 0;
for (i = 0; i < 40; i++) {
$scope.page.yearList.push(year.toString());
year++;
}
}
addYears();
$scope.years = $scope.page.yearList;
$scope.page.expyear = d.getFullYear();
$scope.page.expmonth = "01";
$scope.monthList = "01";
// watcher
$scope.$watchGroup(['page.expmonth', 'page.expyear'], function(newValues, oldValues, scope) {
//MM-YYYY
if(typeof newValues[1] == "undefined" || typeof newValues[0] == "undefined")
scope.authorize.creditCard.expirationDate = null;
else
$scope.authorize.creditCard.expirationDate = newValues[1] + "-" + newValues[0];
console.log("Pawan", $scope.authorize.creditCard.expirationDate)
}, true);
Here is the view code :-
<!DOCTYPE html>
<html><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div class="col-xs-2 innerN" style="width: 14%;">
<select ng-disabled="page.creditcard.isDisabled" class="form-control innerN" placeholder="YYYY" name="ccExpYear" ng-model="page.expyear" required style="border-left:none">
<option value="XX" selected ng-if="page.creditcard.isDisabled">XX</option>
<option ng-repeat="year in page.yearList" value="{{year}}" ng-if="!page.creditcard.isDisabled">{{year}}</option>
</select>
</div>
Hope, this will help to others.
Related
The pagination would not update itself as the filter applied. Data is loaded from the database using a Python script. I'm new to AngularJS. How do I change the code to solve this problem?
I tried to solve the problem by the link: Filter through pagination angular
Failed to deal :(
Corrected code ↓
<!-- language: lang-json -->
// **Listing index.json**
[{
"name": "265/70R16 112T Ice Zero",
"width": "265",
"height": "70",
"razmer": "R16",
"price": 112,
"model":"Ice Zero",
"brand":"Pirelli"
},
{
"name": "225/55R17 112T Ice Maiz",
"width": "225",
"height": "55",
"razmer": "R17",
"price": 102,
"model":"Ice Maiz",
"brand":"Continental"
},
{
"name": "205/50R16 112T PSX",
"width": "205",
"height": "50",
"razmer": "R16",
"price": 92,
"model":"PSX",
"brand":"Bridgstoun"
},
{
"name": "205/55R17 112T Brrr",
"width": "205",
"height": "55",
"razmer": "R17",
"price": 100,
"model":"Brrr",
"brand":"Toyo"
},
{
"name": "225/55R17 112T ICE WinterSport",
"width": "225",
"height": "55",
"razmer": "R17",
"price": 102,
"model":"ICE WinterSport",
"brand":"Dunlop"
},
{
"name": "255/65R18 112T Winter",
"width": "255",
"height": "65",
"razmer": "R18",
"price": 122,
"model":"Winter",
"brand":"Nokian"
},
{
"name": "225/55R17 112T Hmit 5",
"width": "225",
"height": "55",
"razmer": "R17",
"price": 102,
"model":"Hmit 5",
"brand":"Kunho"
},
{
"name": "245/45R20 112T Ice Sport",
"width": "245",
"height": "45",
"razmer": "R20",
"price": 202,
"model":"Ice Sport",
"brand":"GoodYear"
}]
// **Listing index.js**
var app = angular.module('app', [])
.factory('pagination', function ($sce) {
var currentPage = 1;
var itemsPerPage = 3;
var pageMax = 12;
var pageTo = 0;
var pageFrom = 0;
var products = [];
var click_count_next = 0;
return {
setProducts: function (newProducts) {
products = newProducts
}, /* END of setProducts */
getPageProducts: function (num) {
var num = angular.isUndefined(num) ? 0 : num;
var first = itemsPerPage * num;
var last = first + itemsPerPage;
currentPage = num;
last = last > products.length ? (products.length) : last;
return products.slice(first, last);
}, /* END of getPageProducts */
getTotalPagesNum: function () {
return Math.ceil(products.length / itemsPerPage);
}, /* END of getTotalPagesNum */
getPaginationList: function (pcn) {
var pcn = angular.isUndefined(pcn) ? 0 : pcn;
var pagesNum = this.getTotalPagesNum();
var paginationList = [];
/*document.write(pagesNum);*/
paginationList.push({
name: $sce.trustAsHtml('«'),
link: 'prev'
});
if (pageMax < pagesNum) {
if (pcn > Math.ceil(pageMax / 2) + pageFrom) {
pageFrom++;
pageTo = pageMax + pageFrom;
if (pageTo > pagesNum) {
pageTo = pagesNum;
pageFrom = pagesNum - pageMax;
}
}
if (pcn < Math.ceil(pageMax / 2) + pageFrom) {
pageTo--;
pageFrom = pageTo - pageMax;
if (pageFrom < 0) {
pageFrom = 0;
pageTo = pageMax;
}
}
if (pageTo <= pagesNum) {
for (var i = pageFrom; i < pageTo; i++) {
var name = i + 1;
paginationList.push({
name: $sce.trustAsHtml(String(name)),
link: i
});
};
}
}
else {
for (var i = 0; i < pagesNum; i++) {
var name = i + 1;
paginationList.push({
name: $sce.trustAsHtml(String(name)),
link: i
});
};
}
paginationList.push({
name: $sce.trustAsHtml('»'),
link: 'next'
});
if (pagesNum > 1) {
return paginationList;
} else {
return null;
}
}, /* END of getPaginationList */
getUpdatePagination: function () {
return this.getPaginationList(click_count_next)
},
getPrevPageProducts: function () {
var prevPageNum = currentPage - 1;
if (prevPageNum < 0) prevPageNum = 0;
this.getPageProducts(prevPageNum);
return currentPage;
}, /* END of getPrevPageProducts */
getNextPageProducts: function () {
var nextPageNum = currentPage + 1;
var pagesNum = this.getTotalPagesNum();
if (nextPageNum >= pagesNum) nextPageNum = pagesNum - 1;
this.getPageProducts(nextPageNum);
return currentPage;
}, /* END of getNextPageProducts */
getCurrentPageNum: function () {
return currentPage;
}, /* END of getCurrentPageNum */
}
}) /* END of factory-pagination */
///// CONTROLLER START
.controller('mainCtrl', function ($scope, $http, $filter, pagination) {
$http.get('https://mesnalex.com/stackoverflow/index.json')
.success(function(data){
$scope.products = $scope.ProductObj = data;
$scope.filterProducts = function () {
var chain = new filterChain($scope.ProductObj);
$scope.products = chain
.applyFilter('filter', [{ brand: $scope.brand }])
.applyFilter('filter', [{ razmer: $scope.razmer }])
.applyFilter('filter', [{ width: $scope.width }])
.applyFilter('filter', [{ height: $scope.height }])
.value;
pagination.setProducts($scope.products);
$scope.products = pagination.getPageProducts($scope.currentPage);
$scope.paginationList = pagination.getPaginationList($scope.page_click_next);
};
pagination.setProducts($scope.products);
$scope.products = pagination.getPageProducts($scope.currentPage);
$scope.paginationList = pagination.getPaginationList($scope.page_click_next);
$scope.showPage = function (page) {
if (page == 'prev') {
$scope.products = pagination.getPageProducts(page = pagination.getPrevPageProducts());
$scope.paginationList = pagination.getPaginationList(page);
}
else if (page == 'next') {
$scope.products = pagination.getPageProducts(page = pagination.getNextPageProducts());
$scope.paginationList = pagination.getPaginationList(page);
} else {
$scope.products = pagination.getPageProducts(page);
$scope.paginationList = pagination.getPaginationList(page);
}
}
$scope.currentPageNum = function () {
return pagination.getCurrentPageNum();
}
function filterChain(value) {
this.value = value;
}
filterChain.prototype.applyFilter = function (filterName, args) {
args.unshift(this.value);
this.value = $filter(filterName).apply(undefined, args)
return this;
};
});
});
///// CONTROLLER END
app.filter('unique', function () {
return function (items, filterOn) {
if (filterOn === false) {
return items;
}
if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
var hashCheck = {}, newItems = [];
var extractValueToCompare = function (item) {
if (angular.isObject(item) && angular.isString(filterOn)) {
return item[filterOn];
} else {
return item;
}
};
angular.forEach(items, function (item) {
var valueToCheck, isDuplicate = false;
for (var i = 0; i < newItems.length; i++) {
if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
newItems.push(item);
}
});
items = newItems;
}
return items;
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.23/angular.min.js"></script>
<!-- **Listing index.html** -->
<!-- some code -->
<body ng-app="app" ng-controller="mainCtrl">
<!--<div class="my_blog"><h2>My Blog</h2> -->
<!-- FILTER BOX START -->
<select ng-model="brand" ng-change="filterProducts()" style="margin-top:35px;width:210px;" autocomplete="off">
<option style="color:gray;" value="{{undefined}}">All</option>
<option ng-repeat="item in ProductObj | unique: 'brand' | orderBy: 'brand'" id="brand_Select" >{{ item.brand }}</option>
</select>
<select ng-model="height" ng-change="filterProducts()" style="float:left;margin-top:35px;width:210px;" autocomplete="off">
<option style="color:gray;" value="{{undefined}}">All</option>
<option ng-repeat="item in ProductObj | unique: 'height' | orderBy: 'height'" id="height_Select" >{{ item.height }}</option>
</select>
<!-- FILTER BOX END -->
<!-- LISTING PRODUCTS START -->
<div ng-repeat="item in products">
<div>
<h5>{{ item.brand }} {{ item.model }}</h5>
<h5>{{ item.name }}</h5>
<h5>{{ item.price }}</h5>
</div>
</div>
<!-- LISTING PRODUCTS END -->
<!-- PAGINATION START -->
<ul class="pagination">
<li class="page-item" ng-repeat="page in paginationList" ng-click="showPage(page.link)" ng-class="{'active': currentPageNum() == page.link}"><a class="page-link" ng-bind-html="page.name"></a></li>
</ul>
<!-- PAGINATION END -->
</body>
<!-- some code -->
Problem solved! :)
Changes that I made to the controller(for 4 filters):
.controller('mainCtrl', function ($scope, $http, $filter, pagination) {
$http.get('./out_data.php?action=getPosts')
.success(function(data){
$scope.products = $scope.ProductObj = data;
$scope.filterProducts = function () {
var chain = new filterChain($scope.ProductObj);
$scope.products = chain
.applyFilter('filter', [{ brand: $scope.brand }])
.applyFilter('filter', [{ razmer: $scope.razmer }])
.applyFilter('filter', [{ width: $scope.width }])
.applyFilter('filter', [{ height: $scope.height }])
.value;
pagination.setProducts($scope.products);
$scope.products = pagination.getPageProducts($scope.currentPage);
$scope.paginationList = pagination.getPaginationList($scope.page_click_next);
};
pagination.setProducts($scope.products);
$scope.products = pagination.getPageProducts($scope.currentPage);
$scope.paginationList = pagination.getPaginationList($scope.page_click_next);
function filterChain(value) {
this.value = value;
}
filterChain.prototype.applyFilter = function (filterName, args) {
args.unshift(this.value);
this.value = $filter(filterName).apply(undefined, args)
return this;
};
});
The changes I made to the getPaginationList function:
getPaginationList: function (pcn) {
var pcn = angular.isUndefined(pcn) ? 0 : pcn;
var pagesNum = this.getTotalPagesNum();
var paginationList = [];
/*document.write(pagesNum);*/
paginationList.push({
name: $sce.trustAsHtml('«'),
link: 'prev'
});
if (pageMax < pagesNum) {
if (pcn > Math.ceil(pageMax / 2) + pageFrom) {
pageFrom++;
pageTo = pageMax + pageFrom;
if (pageTo > pagesNum) {
pageTo = pagesNum;
pageFrom = pagesNum - pageMax;
}
}
if (pcn < Math.ceil(pageMax / 2) + pageFrom) {
pageTo--;
pageFrom = pageTo - pageMax;
if (pageFrom < 0) {
pageFrom = 0;
pageTo = pageMax;
}
}
if (pageTo <= pagesNum) {
for (var i = pageFrom; i < pageTo; i++) {
var name = i + 1;
paginationList.push({
name: $sce.trustAsHtml(String(name)),
link: i
});
};
}
}
else {
for (var i = 0; i < pagesNum; i++) {
var name = i + 1;
paginationList.push({
name: $sce.trustAsHtml(String(name)),
link: i
});
};
}
paginationList.push({
name: $sce.trustAsHtml('»'),
link: 'next'
});
if (pagesNum > 1) {
return paginationList;
} else {
return null;
}
}, /* END of getPaginationList */
Corrections to index.html:
<select ng-model="brand" ng-change="filterProducts()" style="margin-top:15px;width:210px;" autocomplete="off">
<option style="color:gray;" value="{{undefined}}">All</option>
<option ng-repeat="item in ProductObj | unique: 'brand' | orderBy: 'brand'" id="brand_Select" >{{ item.brand }}</option>
</select>
....
<div ng-repeat="item in products">
<div class="thumbnail">
<h5>{{ item.brand }} {{ item.model }}</h5>
<h5>{{ item.full_name }}</h5>
<h5>{{ item.roz_price }}</h5>
</div>
</div>
I am currently using a select option to generate months and years using the angular attribute ng-repeat to gather data for credit card expiration dates. I would like to return the value of the month and year after they are concatenated into one string and compare the string to today's date using momentjs. When doing this, month and year are returning as an invalid date. Please see my example below:
HTML
<select id="expMonth" class="form-control" ng-model="expMonth" ng-change="checkDate()">
<option value="" disabled>Month</option>
<option value="{{ month }}" ng-repeat="month in months">{{ month }}</option>
</select>
<select id="expYear" class="form-control" ng-model="expYear" ng-change="checkDate()">
<option value="" disabled>Year</option>
<option value="{{ year }}" ng-repeat="year in years">{{ year }}</option>
</select>
Javascript/Angular
$scope.months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
$scope.years = [];
var currentYear = new Date().getFullYear ();
for ( var i = currentYear; i <= new Date ().getFullYear () + 10; i++ ) $scope.years.push ( i );
$scope.checkDate = function() {
var expDate = $scope.expMonth.toString() + $scope.expYear.toString();
if (expDate < moment().format('MMYYYY')) {
console.log('please enter an invalid date');
} else {
console.log('this date is valid')
}
}
I believe the dates are returning as a string and I am not sure how to convert it so I can compare it with today's date using the moment.format('MMYYYY'). Any help would be awesome.
You are trying to compare if one string is less than another string which will not work. You have two options:
Compare the months and the years separately
Use moment's isBefore method to compare the dates
Separate Comparison:
$scope.months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
$scope.years = [];
var currentMonth = new Date().getMonth();
var currentYear = new Date().getFullYear();
for (var i = currentYear; i <= new Date().getFullYear() + 10; i++) $scope.years.push(i);
$scope.checkDate = function() {
if (!($scope.expMonth && $scope.expYear)) return;
if ($scope.expMonth <= currentMonth && $scope.expYear <= currentYear) {
console.log('please enter an valid date');
} else {
console.log('this date is valid');
}
}
Moment isBefore
$scope.months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
$scope.years = [];
var currentMonth = new Date().getMonth();
var currentYear = new Date().getFullYear();
for (var i = currentYear; i <= new Date().getFullYear() + 10; i++) $scope.years.push(i);
$scope.checkDate = function() {
if (!($scope.expMonth && $scope.expYear)) return;
var expDate = $scope.expMonth.toString() + $scope.expYear.toString();
if (moment(expDate, 'MMYYYY').isBefore()) {
console.log('please enter an valid date');
} else {
console.log('this date is valid');
}
}
I am trying to disable some dates (eventually via an array I provide) using the datepicker control. However, it seems that nothing useful is passed in to the dateDisabled function. When I set a breakpoint in the developer tools, the first variable (which is set to data in the documentation examples) comes across as simply the number zero.
I have verified that the option itself works, as blankly returning a true disables all dates. What must I do to get valid inputs?
Note: I just discovered we are using angular-ui-bootstrap version 0.12.1.
JS
//options object for the datepicker control
$scope.dateOptions = {
dateDisabled: disableDates,
formatYear: "yyyy"
};
// Disable weekend selection
function disableDates(date, mode) {
//return mode === 'day' && (date.getDay() === 5 || date.getDay() === 6);
//return true;
return date === new Date(2016, 6, 18);
}
//Set the calendar open
$scope.openCalendar = function (e) {
e.preventDefault();
e.stopPropagation();
$scope.vm.is_cal_open = !$scope.vm.is_cal_open;
};
$scope.hasInvalidErrorDate = function (date) {
if (!date || date <= Date.parse("1/1/1900")) {
return true;
}
return false;
};
$scope.earliestErrorDate = Date.parse("1/1/1900");
HTML
<div class="col-sm-4">
<!-- Error Date -->
<div class="form-group" ng-class="{'has-error': hasInvalidErrorDate(vm.data.adjustment.error_date) && form.$dirty}">
<label for="error_date">Error Date</label>
<p class="input-group calendar-wrapper">
<!--input disabled the input so that it forces users to use the date picker and therfore ensure good input-->
<input type="text" datepicker-popup="MM/dd/yyyy"
title="Click the calendar button"
name="error_date"
datepicker-options="dateOptions"
class="form-control"
is-open="vm.is_cal_open"
width="5"
ng-disabled="true"
ng-model="vm.data.adjustment.error_date"
min-date="dateOptions.minDate" />
<span class="input-group-btn">
<button type="button" class="btn btn-default delegate-cal-btn" ng-click="openCalendar($event)"><i class="fa fa-calendar"></i></button>
</span>
</p>
<span class="text-danger small" ng-show="hasInvalidErrorDate(vm.data.adjustment.error_date) && form.$dirty">
Please select an error date
</span>
</div>
</div>
Working absolutely fine.
$scope.today = function() {
$scope.dt = new Date();
};
$scope.today();
$scope.clear = function() {
$scope.dt = null;
};
$scope.inlineOptions = {
customClass : getDayClass,
minDate : new Date(),
showWeeks : true
};
$scope.dateOptions = {
formatYear : 'yy',
maxDate : new Date(2199, 12, 31),
minDate : new Date(),
startingDay : 1
};
$scope.toggleMin = function() {
$scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null
: new Date();
$scope.dateOptions.minDate = $scope.inlineOptions.minDate;
};
$scope.toggleMin();
$scope.open1 = function() {
$scope.popup1.opened = true;
};
/*
* $scope.open2 = function() { $scope.popup2.opened =
* true; };
*/
$scope.setDate = function(year, month, day) {
$scope.dt = new Date(year, month, day);
};
$scope.formats = [ 'dd-MMMM-yyyy', 'yyyy/MM/dd',
'dd.MM.yyyy', 'shortDate' ];
$scope.format = $scope.formats[0];
$scope.altInputFormats = [ 'M!/d!/yyyy' ];
$scope.popup1 = {
opened : false
};
$scope.dateOptions = {
dateDisabled: disabled,
formatYear: 'yy',
maxDate: new Date(2020, 5, 22),
minDate: new Date(),
startingDay: 1
};
// Disable weekend selection
function disabled(data) {
var date = data.date,
mode = data.mode;
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
}
/*
* $scope.popup2 = { opened : false };
*/
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var afterTomorrow = new Date();
afterTomorrow.setDate(tomorrow.getDate() + 1);
$scope.events = [ {
date : tomorrow,
status : 'full'
}, {
date : afterTomorrow,
status : 'partially'
} ];
function getDayClass(data) {
var date = data.date, mode = data.mode;
if (mode === 'day') {
var dayToCheck = new Date(date).setHours(0,
0, 0, 0);
for (var i = 0; i < $scope.events.length; i++) {
var currentDay = new Date(
$scope.events[i].date)
.setHours(0, 0, 0, 0);
if (dayToCheck === currentDay) {
return $scope.events[i].status;
}
}
}
return '';
}
I have checked all stackoverflow posts related to ui-grid sorted rows without any success so I am opening one more question.
SHORT : Need a way to get sorted rows following current sorting criteria.
My problem is that I have an instance of UI Grid with pagination and I can not get the sorted data after it was added using a $mdDialog modal. It is shown at the right position in the tabel, but behind, in all objects it is stored the new element is on the last position.
I call the ui-grid instance using a service to keep all stuff in one place:
// Default service for init a ui-grid instance
app.serivce('testService', function(){
var defaultGridOptions = {
enableColumnMenus: false,
enablePaginationControls: true,
paginationPageSizes: [5],
multipleSorting: false,
treeRowHeaderAlwaysVisible: false,
paginationPageSize: 5,
enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
enableVerticalScrollbar: uiGridConstants.scrollbars.NEVER
};
// Each columns sort rule
// Position 0 from columnsOrder sorts position 0 from columnDefs and so on
var defaultColSort = [{
sort: { direction: uiGridConstants.ASC, priority: 0 }
}];
this.createGridOptions = function (gridData, columnDefs, gridOpts) {
gridOpts = typeof gridOpts !== 'undefined' ? gridOpts : {};
var gridOptions = angular.extend({}, defaultGridOptions, gridOpts);
for(var i = 0; i < defaultColSort.length; i++)
columnDefs[i] = angular.extend({}, defaultColSort[i], columnDefs[i]);
gridOptions.data = gridData;
gridOptions.columnDefs = columnDefs;
return gridOptions;
};
// The metod that should move to the desired page
this.jumpToGridItem = function(api, entry) {
var idx = -1;
var page = 0;
var sortedData = null;
// NEED A WAY TO GET SORTED DATA HERE
//idx = sortedData.indexOf(entry); -> checks the position of the new added item
if (idx == -1)
return false;
// Calculate the page where the element exists
page = Math.ceil(idx/api.grid.options.paginationPageSize);
// Jump to page
api.pagination.seek(page);
};
})
Here is my controller :
app.controller('testController', ['$scope', '$mdDialog', 'testService', function($scope, $mdDialog, testService){
var columnDefs = [
{
field: 'identifier',
name: 'Identifier'
}
];
var dummyData = [{ identifier: "Item" }, { identifier: 'Item 1' }, { identifier: "Item 2" }, { identifier: "Item 3" }];
var gridOptions = $scope.gridOptions = testService.createGridOptions(dummyData, columnDefs);
gridOptions.onRegisterApi = function (gridApi) {
$scope.gridApi = gridApi;
};
$scope.add = function () {
$mdDialog.show({
controller: function($mdDialog) {
var data = $scope.identifierVal;
$mdDialog.hide(data);
},
templateUrl: 'add.html',
parent: angular.element(document.body)
}).then(function (entry) {
// Data received when the modal is hidden
$scope.gridOptions.data.push(entry);
testService.jumpToGridItem($scope.gridApi, entry);
});
};
}]);
Right now I am appending the data with push(), this could be one reason, I think.
The method I have to update is jumpToGridItem, which actually should focus the page where the item was added.
Thank you
PS : Sorry for not posting a plnkr, I will do bit later if it is needed.
I finally found a way to achieve what I initially wanted. I ve found it a day after posting the question but I was busy enough to post the answer. The code below can be also found in a plnkr. It looks for a certain entry and goes to the page where it can be found.
I wanted this to focus a dynamically added entry in a ui-grid table from a dialog (modal form):
Controller :
var app = angular.module('stefanz', ['ui.grid', 'ui.grid.pagination']);
app.controller('MyCtrl', ['$scope', 'UIGridCustom', '$http', function($scope, UIGridCustom, $http){
// A part of data copied from ui-grid demos
var data = [{"name": "Ethel Price", "gender": "female", "company": "Enersol" },{"name": "Claudine Neal", "gender": "female", "company": "Sealoud" },{"name": "Beryl Rice", "gender": "female", "company": "Velity" },{"name": "Wilder Gonzales", "gender": "male", "company": "Geekko" },{"name": "Georgina Schultz", "gender": "female", "company": "Suretech" },{"name": "Carroll Buchanan", "gender": "male", "company": "Ecosys" },{"name": "Valarie Atkinson", "gender": "female", "company": "Hopeli" },{"name": "Schroeder Mathews", "gender": "male", "company": "Polarium" },{"name": "Lynda Mendoza", "gender": "female", "company": "Dogspa" },{"name": "Sarah Massey", "gender": "female", "company": "Bisba" },{"name": "Robles Boyle", "gender": "male", "company": "Comtract" },{"name": "Evans Hickman", "gender": "male", "company": "Parleynet" },{"name": "Dawson Barber", "gender": "male", "company": "Dymi" }];
var colDefs = [{
label: "name",
name: "name"
}, {
label: "gender",
name: "gender"
}, {
label: "company",
name: "company"
}];
// Call the service for init
var gridOptions = $scope.gridOptions = UIGridCustom.createGridOptions(data, colDefs);
gridOptions.onRegisterApi = function(api) {
$scope.gridApi = api;
}
$scope.getItemPage = function(name) {
UIGridCustom.jumpToGridItem($scope.gridApi, name);
}
}]);
app.service('UIGridCustom', ['uiGridConstants', 'utils', function(uiGridConstants, utils){
var defaultGridOptions = {
enableColumnMenus: false,
enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
enableVerticalScrollbar: uiGridConstants.scrollbars.NEVER,
enablePaginationControls: false,
paginationPageSize: 5,
multipleSorting: true
};
// Each columns sort rule
// Position 0 from columnsOrder sorts position 0 from columnDefs and so on
// Could be overwritten into columnDefs
// Docs : http://ui-grid.info/docs/#/api/ui.grid.class:GridOptions
var defaultColSort = [];
//1st column default sorting
defaultColSort[{
sort: { direction: uiGridConstants.ASC, priority: 0 }
}];
// For sorting 2nd column
// defaultColSort[1] = {
// sort: { direction: uiGridConstants.ASC, priority: 0 }
// };
this.createGridOptions = function (gridData, columnDefs, stefanzGridOpts) {
// Overwrite defaults with custom passed options for grid
var stefanzGridOpts = typeof stefanzGridOpts !== 'undefined' ? stefanzGridOpts : {};
var gridOptions = angular.extend({}, defaultGridOptions, stefanzGridOpts);
// Force sorting following the default/custom column sort
for(var i = 0; i < defaultColSort.length; i++)
columnDefs[i] = angular.extend({}, defaultColSort[i], columnDefs[i]);
// Grid init
gridOptions.data = gridData;
gridOptions.columnDefs = columnDefs;
return gridOptions;
};
this.jumpToGridItem = function(api, name) {
var idx = 0;
var page = 0;
var sorting = prepareCriteria(api.grid.getColumnSorting());
var data = dataObjectSort(prepareRows(api.grid.rows), sorting);
entry = getEntryByName(data, name);
idx = data.indexOf(entry) + 1;
if (!idx)
return false;
// Calculate the page where the element exists
page = Math.ceil(idx/api.grid.options.paginationPageSize);
alert(name + 'is found on page ' + page);
// Jump to page
api.pagination.seek(page);
};
// Takes the row's entity and put in a new array as a top-level item
// Userful for further data handling
var prepareRows = function(rows) {
if (rows.length == 0)
return false;
var preparedRows = [];
rows.forEach(function(row){
// Do not need to handle the rows that are not in current filter (hidden)
if (row.visible == false)
return true;
preparedRows.push(row.entity);
});
return preparedRows;
};
// We are comparing whole enter and as a parameter we are sending a name
var getEntryByName = function(data, searchedName) {
for(var i = 0; i < data.length; i++) {
if (data[i]['name'] == searchedName)
return data[i];
}
return false;
}
var dataObjectSort = function(data, criteria) {
return data.sort(utils.dynamicSortMultiple(criteria));
};
var prepareCriteria = function(colSorting) {
var sorting = [];
var fields = [];
// Take just needed fields
colSorting.forEach(function(column){
sorting.push({
field: column.field,
direction: column.sort.direction,
priority: column.sort.priority
})
});
// Sort criterias by priority - UI grid works like this
// Reason : http://ui-grid.info/docs/#/api/ui.grid.class:GridOptions.columnDef#properties_sort
sorting.sort(function(a, b){
if (a.priority < b.priority) return -1;
else if (a.priority > b.priority) return 1;
else return 0;
});
// Prepare fields for sorting
sorting.forEach(function(sort){
// Dymanic sort (above) needs "-" sign for descendent direction
if (sort.direction != uiGridConstants.ASC)
sort.field = '-' + sort.field;
fields.push(sort.field);
});
return fields;
};
}]);
// Keep utils methods into a separate service
// Here all sorting methods will appear
app.service('utils', function(){
function getJsonValue(obj, path) {
if (!path || path == '')
return obj;
path = path.split('.');
var len = path.length;
for (var i = 0; i < len - 1; i++) {
var prop = path[i].split(/\[([^\]]+)]/); // indication[4] => [indication, 4]; indication => [indication]
if (prop.length == 1) {
obj = obj[prop[0]];
} else {
obj = obj[prop[0]][prop[1]];
}
}
var prop = path[len - 1].split(/\[([^\]]+)]/); // indication[4] => [indication, 4]; indication => [indication]
if (prop.length == 1) {
return obj[prop[0]];
} else {
if (prop.length == 2) {
return obj[prop[0]][prop[1]];
} else {
if(prop.length ==3) {
return obj[prop[0]][prop[1]]; // this is a hack!
} else {
return obj[prop[0]][prop[1]][prop[3]]; // this is a hack!
}
}
}
};
//http://stackoverflow.com/questions/1129216/sort-array-of-objects-by-string-property-value-in-javascript/4760279#4760279
function dynamicSort(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a,b) {
var aInsensitive = getJsonValue(a, property).toLowerCase();
var bInsensitive = getJsonValue(b, property).toLowerCase();
var result = (aInsensitive < bInsensitive) ? -1 : (aInsensitive > bInsensitive) ? 1 : 0;
return result * sortOrder;
}
};
function dynamicSortMultiple(props) {
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length;
while(result === 0 && i < numberOfProperties) {
result = dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
}
};
return {
getJsonValue: function(obj, path) {
return getJsonValue(obj, path);
},
dynamicSort: function(property) {
return dynamicSort(property);
},
dynamicSortMultiple: function(props) {
return dynamicSortMultiple(props);
}
}
});
HTML
<!DOCTYPE html>
<html ng-app="stefanz">
<head>
<script data-require="angularjs_1_3_15#*" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.min.js"></script>
<script data-require="angularjs_1_3_15#*" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-animate.min.js"></script>
<script data-require="angularjs_1_3_15#*" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-aria.min.js"></script>
<script data-require="jquery#*" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<link data-require="ui-grid#*" data-semver="3.0.7" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.0.7/ui-grid.css" />
<script data-require="ui-grid#*" data-semver="3.0.7" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.0.7/ui-grid.js"></script>
<script data-require="bootstrap#~3.3.5" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MyCtrl">
<div ui-grid="gridOptions" ui-grid-pagination class="grid"></div>
<div class="centerAlignedText">
<ul>
<li><a ng-click="getItemPage('Ethel Price')">Get Ethel Price</a></li>
<li><a ng-click="getItemPage('Schroeder Mathews')">Get Schroeder Mathews</a></li>
<li><a ng-click="getItemPage('Dawson Barber')">Get Dawson Barber</a></li>
<li><a ng-click="getItemPage('Sarah Massey')">Get Sarah Massey</a></li>
</ul>
</div>
<div class="centerAlignedText" ng-if="gridOptions.totalItems > 0">
<div class="paginationButtonsIcon boldText" style="width: 100px; display: inline-block;">
<md-button ng-if="gridApi.pagination.getPage() > 1" class="paginationButtons" ng-click="gridApi.pagination.previousPage()" style="width: 90px;">
<span class="notTransformedText boldText">Previous</span>
</md-button>
</div>
<div ng-repeat="n in gridApi.pagination.getTotalPages()" style="display: inline-block;">
<md-button ng-if="(gridApi.pagination.getTotalPages() < 11)
|| (gridApi.pagination.getPage() < 7 && n < 10)
|| (n > gridApi.pagination.getPage() - 7 && n < gridApi.pagination.getPage() + 4)
|| (gridApi.pagination.getPage() > gridApi.pagination.getTotalPages() - 5 && n > gridApi.pagination.getTotalPages() - 11)" class="paginationButtons md-mini md-icon-button md-primary" ng-click="gridApi.pagination.seek($index + 1)">
<span class="paginationButtonsIcon boldText" ng-if="gridApi.pagination.getPage() === $index + 1">
{{$index + 1}}
</span>
<span class="paginationButtonsIcon" ng-if="gridApi.pagination.getPage() !== $index + 1">
{{$index + 1}}
</span>
</md-button>
</div>
<div class="paginationButtonsIcon boldText" style="width: 100px; display: inline-block;">
<md-button ng-if="gridApi.pagination.getPage() < gridApi.pagination.getTotalPages()" class="paginationButtons md-icon-button md-primary" ng-click="gridApi.pagination.nextPage()" style="width: 90px;">
<span class="notTransformedText boldText">Next</span>
</md-button>
</div>
</div>
</body>
</html>
I'm trying to update a filtered dropdowns(combobox) model on click of a button. The model value is changing but dropdown still shows an empty selected option. If I remove the filter everything works as it should (without filtering of course).
Plunker: http://plnkr.co/edit/a48JSEiiATrkcQKxfJjx?p=preview
JS:
$scope.tasks = [
{name:'Task1', taskid: 1, custid: 2},
{name:'Task2', taskid: 2, custid: 2},
{name:'Task3', taskid: 3, custid: 3}
];
$scope.myinfo = {};
$scope.updateinfo = {name:'Cust Name', custid: 3, taskid: 3};
$scope.setMyinfo = function(){
$scope.myinfo = $scope.updateinfo;
};
});
app.filter('taskFilter', function() {
return function(input, criteria) {
var result = [];
for (var i = 0; i < input.length; i++) {
if(input[i].custid == criteria || input[i].custid === undefined){
result.push(input[i]);
}
}
return result;
}
HTML:
<button ng-click="setMyinfo()">Button</button>
<br> <br>
Filtered:
<select ng-model="myinfo.taskid">
<option>---</option>
<option ng-repeat="task in tasks | taskFilter:myinfo.custid" value="{{task.taskid}}">{{task.name}}</option>
</select>
Unfiltered:
<select ng-model="myinfo.taskid">
<option>---</option>
<option ng-repeat="task in tasks" value="{{task.taskid}}">{{task.name}}</option>
</select>
<br><br>
Value: {{myinfo.taskid}}
Thanks you for helping!
pre-filter the list by key and value:
<div ng-repeat="(k,v) in filterCustId(tasks)">
{{k}} {{v.pos}}
</div>
And on the Controller:
$scope.filterCustId = function(items) {
var result = {};
angular.forEach(items, function(value, key) {
if (!value.hasOwnProperty('custid')) {
result[key] = value;
}
});
return result;
}
From:
https://stackoverflow.com/a/14789258/4668696
Please update code following line
if(input[i].custid == criteria || input[i].custid === undefined){
by
if(input[i].custid == criteria || input[i].custid === undefined || criteria == undefined){