PU$]-[KAR's

… Every drop has ability to survive .


2 Comments

Restrict the selectable date ranges in Bootstrap Datepicker control

Hi,

While dealing with bootstrap datepicker control today I came across interesting feature that to make enable only selected date ranges from datepicker control to restrict user while selecting any dates. This feature is most of the time gets used in Hotels for room booking.

Implementation:

It was difficult to implement it in earlier versions of Bootstrap-datepicker.js but earlier versions of Bootstrap-datepicker.js provides lots of functions & one of that is ‘beforeShowDay
Function ‘beforeShowDay’ is a boolean function. We can use this function to enable or disable particular day by returning true or false.

The code sample given below will explain it in detail:

JS:

var sampleDate = $('#dateRangeSample').datepicker({
beforeShowDay: function (date) {
var endDate1 = new Date(2014, 6, 18);
var startDate1 = new Date(2014, 6, 9);
var endDate2 = new Date(2014, 6, 30);
var startDate2 = new Date(2014, 6, 25);
if (date.valueOf() < endDate1.valueOf() && date.valueOf() > startDate1.valueOf()) {
return (date.valueOf() < endDate1.valueOf() && date.valueOf() > startDate1.valueOf());
} else if (date.valueOf() < endDate2.valueOf() && date.valueOf() > startDate2.valueOf()) {
return (date.valueOf() < endDate2.valueOf() && date.valueOf() > startDate2.valueOf());
} else {
return false;
}},autoclose: true})

Explanation:

Here I have enabled dates between two ranges only
1. date between 9/6/2014 to 18/6/2014
2. date between 25/6/2014 to 30/6/2014

In code ‘date.valueOf()’ represents a single date which gets compared with date range provided by us. so while loading a datepicker control for this month each date will get represented by ‘date.valueOf()’ and function will return Boolean result for that date based on comparison what we have done.
In short this code will gets executed internally for each day in that calender for that month and it will be enable if ‘beforeShowDay’ returns true if it lies within date range that we have provided otherwise it will be appear as disable.

And this resolves our aim to restrict user to select date within specified range.

For Complete demo please look at the following link:

click here

Advertisements


2 Comments

ng-grid Scroll flickering issue.

Another fix in ng-grid.js

As all rows of g-grid rendered on UI if user scrolls grid data n reached at top (or bottom) position & tried it to scroll it again in same direction, in that case grid data gets flickered. This one is again an existing issue with ng-grid JS file.
If you click on the link given below you will see the example with the same issue.
http://plnkr.co/edit/TwLKc8hZxF1ATnFZQXHu?p=preview

Cause:

This issue is generated because of the functionality provided by angularJS on ‘MouseWheel-scrolling’ in ng-grid.JS
function mousewheel() {
isMouseWheelActive = true;
if (elm.focus) { elm.focus(); }
return true;
}

If you see code line in Red (code snippet from ng-grid.js) It meant for to set focus on element when Mouse-wheel is scrolled. So when it reaches at top & if we still scroll mouse-wheel in upward direction,it tries to re focus on ‘top’ element This causes flickering of ng-grid.

Solution :

So to resolve this issue I just simply commented out that line & issue gets resolved.
function mousewheel() {
isMouseWheelActive = true;
//if (elm.focus) { elm.focus(); }
return true;
}

It might not be a perfect solution but still I managed to overcome on this issue. If any one has solution better than this. Please feel free to contact me.


1 Comment

‘ng-grid’ scrolling issue.

Hey guys

‘ng-grid’ contains one issue on scrolling with ‘up’ n ‘down’ arrow keys.

Issue:

As all rows rendered on UI if we scroll the grid using “Up/Down” arrow keys, is not able to show highlighted selected row within view able part. When scroll reaches at any end the respective record (either first or last) is not visible in grid.
This prblem even liesin the examples provided by ‘ng-grid’
To see the problem example please click on the link given below:

http://plnkr.co/edit/TwLKc8hZxF1ATnFZQXHu?p=preview

Cause:

As we went through the ng-grid js docs, found that both issues are already present on their demo site.
It uses ‘grid.$viewport.scrollTop’ function from ng-grid JS to calculate scroll position with respective of selected item and row-height with offset. So its observation that some how its goes in wrong calculation.
Even you can refer a question posted in stackOverflow:
http://stackoverflow.com/questions/19889644/ng-grid-won-t-scroll-to-last-row

Here is a code snippet present in ng-grid.js
if (offset) {
var r = items[rowIndex + offset];
if (r.beforeSelectionChange(r, evt)) {
r.continueSelection(evt);
$scope.$emit('ngGridEventDigestGridParent');
if ($scope.selectionProvider.lastClickedRow.renderedRowIndex >= $scope.renderedRows.length - EXCESS_ROWS - 2) {
grid.$viewport.scrollTop(grid.$viewport.scrollTop() + $scope.rowHeight);
}
else if ($scope.selectionProvider.lastClickedRow.renderedRowIndex <= EXCESS_ROWS + 2) {
grid.$viewport.scrollTop(grid.$viewport.scrollTop() - $scope.rowHeight);
}}}

Solution:

So currently we found that after certain scrolling using arrow keys if conditions from above code(shown in blue) gets false & it is unable to calculate exact number to scroll. That’s why it fails to scroll properly.

For this a workaround is to add following ‘else’ condition- code in red to given below:
if (offset) {
var r = items[rowIndex + offset];
if (r.beforeSelectionChange(r, evt)) {
r.continueSelection(evt);
$scope.$emit('ngGridEventDigestGridParent');
if ($scope.selectionProvider.lastClickedRow.renderedRowIndex >= $scope.renderedRows.length - EXCESS_ROWS - 2) {
grid.$viewport.scrollTop(grid.$viewport.scrollTop() + $scope.rowHeight);
}
else if ($scope.selectionProvider.lastClickedRow.renderedRowIndex <= EXCESS_ROWS + 2) {
grid.$viewport.scrollTop(grid.$viewport.scrollTop() - $scope.rowHeight);
else{
grid.$viewport.scrollTop(grid.$viewport.scrollTop() + ($scope.rowHeight * offset));
}
}}}

Really thanks to my friends Yogesh n Vijay for finding work around for it.

This might not be a best solution but if anyone has batter than this please fill free to reach me, your are always well welcome. 🙂


1 Comment

Allow input to show invalid model value in AngularJS

Continuing with validation chapter !!!

‘Input control does not show invalid model value’ is the biggest problem that angularJS ‘ng-pattern’ has. Let me illustrate it by example:
If you have input control for telephone number which is validating against ng-pattern=”/^[0-9]*$/” and it is bound to a model having alpha-numeric value say ‘90280a413’ so as it is containing alph-numeric validation it will against ‘ng-pattern’ which we have applied (numeric only). so it won’t show this value in input control. Input control will remain blank.

If we walk through the code for formatters of angularJS, $formatters & $parsers have functions in pipeline to validate n render those controls. What I observe that a function to validate control uses ‘value.match(regEx)’ & this line of code is creating a problem because if value does not match (or passed) regular expression which we have provide, it returns ‘null’ value. And in result we find empty ‘input’ control.
So as solution to solve this problem I created a directive which pushes a function in pipeline of $formatters n which will a done job for us. 🙂

Sample code:

HTML:

<br />alphabets:
<input class="my-input" type="text" ng-model="alpha" input-validation ng-pattern="/^[a-zA-Z]*$/" />
<br/>numbers:
<input class="my-input" type="text" ng-model="num" input-validation ng-pattern="/^[0-9]*$/" /><br/>
alphabets with ?:
<input class="my-input" type="text" ng-model="alphaQ" input-validation ng-pattern="/^[a-zA-Z]*?*$/" /><br/>
alpha number:
<input class="my-input" type="text" ng-model="alphaNum" input-validation ng-pattern="/^[a-zA-Z0-9]*$/" />

If you observe ‘inputValidation’ directive is created n applied it to  the input.

Directive:

angular.module('demo', [])
.directive('inputValidation', function() {
return {
require: 'ngModel',
restrict: 'A',
link: function($scope, $element, $attrs, ngModelController) {
console.log("Test")
var inputType = angular.lowercase($attrs.type);
if (!ngModelController || inputType === 'radio' ||
inputType === 'checkbox') {
return;
}ngModelController.$formatters.unshift(function(value) {
if (ngModelController.$invalid && angular.isUndefined(value)
&& typeof ngModelController.$modelValue === 'string') {
return ngModelController.$modelValue;
} else {
return value;
}});}};});

Here we have used $formatters.unshift because if you remember $formatters is an array (pipeline) of functions. so unsift adds new function to beginning. So it will invoked  every time and it will return  model value toshowin input control as invalid value.

For complete demo please click on the link below:
http://plnkr.co/edit/f54QA0HofWW4W6W1TM8K?p=preview