I have a custom directive for applying jQuery UI Datepicker to some inputs. I can pick a date and it updates the input. However, when i post back the results. The input(control) that was edited isn't marked dirty so the changes never get saved. See below..
<td>
<input type="text" jqdatepicker name="Delegation.StartDate" ng-model="delegation.StartDate" />
</td>
<td>
<input type="text" jqdatepicker name="Delegation.EndDate" ng-model="delegation.EndDate" />
</td>
App.directive('jqdatepicker', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
element.datepicker({
dateFormat: 'm/dd/yy',
onSelect: function (date) {
scope.date = date;
scope.$apply();
ngModelCtrl.$setDirty(); <--doesn't work
}
});
}
};});
I have tried using scope, element, ngModel and can't get the state of the control to change from pristine to dirty. On save, i scrap the rows(tr) for those that have the class ng-dirty and process them. Any thoughts on how to do this? I use the same method on about 8 other pages without issue but those do not use the directive/datepickers.
After lots of trial and error and reading. I finally got it to work! Below is the directive.
App.directive('jqdatepicker', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
element.datepicker({
dateFormat: 'm/dd/yy',
onSelect: function (date) {
console.log(ngModelCtrl);
ngModelCtrl.$setViewValue(date);
}
});
}
};
});
Related
I want to create directive which will be used for form elements like input,textarea,select...
My code:
app.directive('input', function() {
return {
restrict: 'E',
priority: -1000,
require: '^?required',
link: function (scope, element, attrs, ctrl) {
element.on('focus', function (e) {
element.addClass('validate');
});
}
};
});
When I try to use common directive it doesn't work but don't have idea why...
<input common-directive type="text" name="name" placeholder="Firstname" ng-model="profile.name" ng-minlength="2" required />
I'm new to AngularJS and still learning.
I'm trying to create a custom directive and I would like to have some conditions where requires some conditions before the customrequired kick-in. For example checkbox is ticked. Below is my sample directive and HTML. Thanks and really appreciate your response. Please let me know if you still need some information.
.directive('customrequired', function () {
return {
require: '?ngModel',
link: function (scope, elm, attr, ctrl) {
if (!ctrl) return;
//conditional approach like, requires checkbox to be checked.?
}
};
})
HTML
<input type="text" ng-model="Create.ProductName" name="ProductName" customrequired="Create.IsRequired == 1"/>
<input type="checbox" ng-model="Create.IsRequired" name="Required" />
You can do put watch on your directive value and put your logic in only if its true.
.directive('customrequired', function () {
return {
require: '?ngModel',
link: function (scope, elm, attr, ctrl) {
scope.$watch(attr.customrequired,function(value){
if(value){
//conditional approach like, requires checkbox to be checked.?
}
})
}
};
})
Why value of the ng-model is not updated with the expression. Before ng-model is defined value get updated
Value will be updated as soon as phase2 or phase3 changes
<input type="text" name="phase1" value="{{phase2 - phase3}}" ></input>
Value will not be updated
<input type="text" name="phase1" value="{{phase2 - phase3}}" ng-model="phase1"></input>
So I think of writing a directive which will evaluate the expression inside the directive and updated the output to model,
Here is html it will look like
<input type="text" name="phase1" ng-model="phase1" my-value="{{phase2 - phase3}}" my-model-value></input>
Directive:
myApp.directive('myModelValue', function(){
return {
restrict: 'A',
require: 'ngModel',
scope: {
model: '=ngModel',
value: '#myValue'
},
link: function (scope, element, attr, controller) {
scope.model = scope.value;
}
};
});
This directive evaluate only at load time, but I want to continuously update/watch as the dependent fields (phase2 & phase3) changes.
I can update value from controller but I want to do it from html. Please help me, it it possible or against the working of angular
Thanks guys I figure out what I wanted to do. Here is the my final simple but useful directive :)
app.directive('myModelValue', function () {
return {
restrict: 'A',
require: 'ngModel',
scope: {
model: '=ngModel'
},
link: function (scope, element, attr, controller) {
attr.$observe('myModelValue', function (finalValue) {
scope.model = finalValue;
});
}
};
});
Usage:
<input type="text" ng-model="phase1" my-model-value="{{phase2 - phase3}}"></input>
<input type="text" ng-model="phase1.name" my-model-value="{{valid angular expression}}"></input>
In order to continously watch the phase2/3 changes you can make use of $scope.$watch function.
Something like this will work for you:
link: function (scope, element, attr, controller) {
scope.$watchCollection('[phase1,phase2]', function() {
//whatever you want to do over here }
and in the scope pass phase1 and phase2 values as well
This will watch the value expression and update the same when value will change
myApp.directive('myModelValue', function(){
return {
restrict: 'A',
require: 'ngModel',
scope: {
model: '=ngModel',
value: '#myValue'
},
link: function (scope, element, attr, controller) {
scope.$watch('value',function(newValue){
console.log(newValue);
});
}
};
});
here value is a local scope so it will watch the expression
I am using ui-date in AngularJS.
<input name="dateofbirth" id="dateofbirth" type="text" ng-model="search.dateofbirth" ui-date="dateOptions" ui-date-format="mm/dd/yy">
When I click on the textbox, a calendar pops up, but the user cannot type in the textbox.
How can I make this textbox editable?
You can use this directive, when you click on the text field calendar should be shown.. Here is the working fiddle
http://jsfiddle.net/nabeezy/HB7LU/209/
myApp.directive('calendar', function () {
return {
require: 'ngModel',
link: function (scope, el, attr, ngModel) {
$(el).datepicker({
dateFormat: 'yy-mm-dd',
onSelect: function (dateText) {
scope.$apply(function () {
ngModel.$setViewValue(dateText);
});
}
});
}
};
})
I built two custom directives, datepicker and date-validation, and I'm having trouble with getting datepicker to include the date-validation directive. At first I had the datepicker and date validation directives as...
controls.directive('dateValidation', ['$filter', function ($filter) {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, element, attrs, ngModel) {
// validation methods here...
}
};
}]);
controls.directive('myDatepicker', [function () {
return {
restrict: 'A',
require: 'ngModel',
replace: true,
template: '<input type="text" date-validation />',
link: function (scope, element, attrs, ngModel) {
// inject date picker here...
}}
};
}]);
and this worked perfectly until I tried it in IE8. In IE8 it has a problem with the way the directive replaces the current element with the template and throws an error.
I then tried making replace equal false and took away the template. Then adding the "date-validation" attribute with jQuery and re-compiling the element using the $compile method like...
controls.directive('myDatepicker', ['$compile', function ($compile) {
return {
restrict: 'A',
require: 'ngModel',
replace: false,
link: function (scope, element, attrs, ngModel) {
element.attr({ 'date-validation': '' });
$compile(element)(scope);
// inject date picker here...
}}
};
}]);
But this didn't work either.
Also, the HTML that uses the directive looks like this...
<input type="text" ng-model="startDate" my-datepicker />
If anyone can advise me on how to include another directive inside a custom directive I would greatly appreciate it.