I'm using Angularjs. In that I'm using jquery for datepicker; but when I'm passing the selected date value it is not fetching the selected value. I need a solution for this problem.
Find below my code:
Markup
<div class="form-group">
<label for="inputPassword3" class="col-sm-3 control-label">Project Startdate</label>
<div class="col-sm-9">
<!-- <input type="text" name="prjstartdate" id="prjstartdate" class="form-control" ng-model="vm.user.prjstartdate" required />-->
<div class="container" id="sandbox-container">
<div class="input-daterange input-group" id="datepicker" name="prjstartdate" id="prjstartdate" class="form-control" ng-model="vm.prjstartdate">
<input type="text" name="prjstartdate" id="prjstartdate" class="form-control" ng-model="vm.prjstartdate" required />
</div>
</div>
<span ng-show="form.password.$dirty && form.password.$error.required" class="help-block">Password is required</span>
</div>
</div>
Function:
function MyCntrlsave($scope,$http) {
$scope.savedetails = function() {
var vm = this;
var projectname = $scope.vm.prjname;
var cilentname = $scope.vm.clientname;
var clientstatus = $scope.vm.prjsta;
var prjstartdate = $scope.vm.prjstartdate;
var prjenddate = $scope.vm.prjenddate;
var prjurl = $scope.vm.prjurl;
alert("projectname"+projectname);
alert("cilentname"+cilentname);
alert("prjstartdate"+prjstartdate);
};
};
HTML
<input type="text" name="prjstartdate" id="prjstartdate" class="form-control" ng-model="prjstartdate" required jqdatepicker/>
In controller
var prjstartdate = $scope.prjstartdate
Use jQuery UI and add a directive
datePicker.directive('jqdatepicker', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
element.datepicker({
dateFormat: 'dd/mm/yy',
onSelect: function (date) {
scope.prjstartdate = date;
scope.$apply();
}
});
}
};
});
Demo Here
Related
The maxlength HTML5 attribute is not working properly on mobile for text input fields. If the number keypad is enabled it works, but it doesn't work when using text keypad.
Code:
<ion-content class="p-l-10 p-r-10 had-header form_page">
<form ng-submit="vm.addAdvance()">
<div class="list">
<label class="item item-input InputFormFull">
<span class="input-label">{{'note_message' | translate}}</span>
<input type="text" placeholder="{{'notes_message' | translate}}"
ng-model="vm.advance.description" id="field2" ng-change="vm.fillStarted()" size="5" maxlength="5" required>
</label>
<button class="button trans-but m-t-10" type="submit">{{'save_message' | translate}}</button>
</div>
</form>
Possible duplicate: Input maxlength does not work on Android -Ionic
Try creating your own directive:
myApp.directive('limitChar', function() {
'use strict';
return {
restrict: 'A',
scope: {
limit: '=limit',
ngModel: '=ngModel'
},
link: function(scope) {
scope.$watch('ngModel', function(newValue, oldValue) {
if (newValue) {
var length = newValue.toString().length;
if (length > scope.limit) {
scope.ngModel = oldValue;
}
}
});
}
};
})
Html:
<input type="text" limit-char limit="5">
This is my controller
function commentController($stateParams, commentFactory, $rootScope){
const ctrl = this;
ctrl.comment = {};
ctrl.decision = {};
ctrl.$onInit = function(){
ctrl.decision.replyVisible = false;
}
export {commentController}
This is my component
import {commentController} from './comment.controller'
export const commentComponent = 'commentComponent'
export const commentComponentOptions = {
bindings: {
post: '<'
},
templateUrl: 'blog/src/app/components/post/comment/comment.html',
controller: ['$stateParams', 'commentFactory', '$rootScope', commentController],
controllerAs: 'cm'
}
This is my directive
function showReply(){
return {
restrict: 'A',
scope: {
collapsed: '<'
},
link: function(scope, element, attrs){
element.on('click', ()=>{
console.log(`Trying to hide ${scope.collapsed}`);
scope.collapsed = true
console.log(`Trying to hide ${scope.collapsed}`);
})
}
}
}
function hideReply(){
return {
restrict: 'A',
scope: {
collapsed: '<'
},
link: function(scope, element, attrs){
element.on('click', ()=>{
scope.collapsed = false;
console.log(`Trying to hide scope.replyVisible is ${scope.collapsed}`);
})
}
}
}
export {showReply, hideReply}
This is my html
<div class="comment_wrapper">
<div class="comment" ng-repeat="comment in cm.post.comments">
<h3>{{comment.author.name}}</h3>
<p ng-bind-html="comment.comment"></p>
<button show-reply collapsed="cm.decision.replyVisible">Reply</button>
<div class="reply_wrapper" ng-show="cm.decision.replyVisible">
<label for="name">Name</label>
<input type="text" id="name" ng-model="cm.comment.author.name">
<label for="email">Email</label>
<input type="text" id="email" ng-model="cm.comment.author.email">
<label for="comment">Comment</label>
<textarea name="" id="comment" cols="10" rows="5" ng-model="cm.comment.comment"></textarea>
<button ng-click="cm.reply(comment._id)">Submit</button> <button hide-reply collapsed="cm.decision.replyVisible">Cancel</button>
</div>
</div>
</div>
And this is my module
import angular from 'angular'
import {showReply, hideReply} from './comment.directive'
import {commentFactory, commentFactoryFunc} from './comment.factory'
import {commentComponent, commentComponentOptions} from './comment.component'
export const comment = angular.module('comment', [uiRouter])
.factory(commentFactory, ['$http', commentFactoryFunc])
.component(commentComponent, commentComponentOptions)
.directive('showReply', showReply)
.directive('hideReply', hideReply)
.name
Here's what I am trying to do, in my html, I want to show the reply form when someone clicks on the reply button. And since there are multiple comments for with each having a reply form, I can't use the regular ng-click.
The changes made to the scope.collapsed don't get reflected on cm.decision.replyVisible
How do I make this work? I have always been confused about accessing parent controller variables from a directive.
You should use comment.decision.replyVisible instead of cm.decision.replyVisible
HTML
<div class="comment_wrapper">
<div class="comment" ng-repeat="comment in cm.post.comments">
<h3>{{comment.author.name}}</h3>
<p ng-bind-html="comment.comment"></p>
<button show-reply
collapsed="comment.decision.replyVisible">Reply</button>
<div class="reply_wrapper" ng-show="comment.decision.replyVisible">
<label for="name">Name</label>
<input type="text" id="name" ng-model="cm.comment.author.name">
<label for="email">Email</label>
<input type="text" id="email" ng-model="cm.comment.author.email">
<label for="comment">Comment</label>
<textarea name="" id="comment" cols="10" rows="5" ng-model="cm.comment.comment"></textarea>
<button ng-click="cm.reply(comment._id)">Submit</button> <button hide-reply collapsed="cm.decision.replyVisible">Cancel</button>
</div>
</div>
</div>
I am New to angularjs I am trying to achieve image preview befor its uploading with isolated scope in file browser directive.
This is my html code
<div class="content">
<div class="field">
<label for="form-bridge-logo1">Logo 1</label>
<input id="form-bridge-logo1" type="text" value="" ng-model="myFile.name" />
<button class="clear-file" ng-if="myFile.name" ng-click="clear(myFile)"></button>
<input type="file" id="browse-file-logo1" ng-model="test" name="cover" file-browser="myFile" my-file="myFile" multiple data-logo-type="primary" class="browse-file-input" accept="image/jpg, image/jpeg, image/png"/>
<label for="browse-file-logo1" class="browse-btn">Browse</label>
</div>
<span class="remove-file" ng-if="myFile.name" ng-click="clear(myFile)">Remove</span>
</div>
<div class="content">
<div class="field">
<label for="form-bridge-logo2">Logo 2</label>
<input id="form-bridge-logo2" type="text" ng-model="myFile1.name"/>
<button class="clear-file" ng-if="myFile1.name" ng-click="clear(myFile1)"></button>
<input type="file" id="browse-file-logo2" name="cover" file-browser="myFile1" multiple data-logo-type="secondary" class="browse-file-input" accept="image/jpg, image/jpeg, image/png"/>
<label for="browse-file-logo2" class="browse-btn">Browse</label>
</div>
<span class="remove-file" ng-if="myFile1.name" ng-click="clear(myFile1)">Remove</span>
</div>
and I want image preview in following div
<div class="rectangle-11">
<div ng-if="myFile.name" class="preview-container">
<img ng-src="{{imageSrcForPreview}}" alt="Logo 1" class="preview">
</div>
<div ng-if="myFile1.name" class="preview-container">
<img ng-src="{{imageSrcForPreview}}" alt="Logo 2" class="preview">
</div>
</div>
my directive is as follows
module.exports = function($log, $parse, backendService, sharedServices, fileReader) {
return {
restrict: "A",
scope: {
myFile: "="
},
link: function(scope, element, attrs, sharedServices) {
var model = $parse(attrs.fileBrowser);
var modelSetter = model.assign;
element.bind("change", function(e) {
scope.fileForImagepreview = (e.srcElement || e.target).files[0];
if (scope.fileForImagepreview.type === "image/jpeg" || scope.fileForImagepreview.type === "image/jpg" || scope.fileForImagepreview.type === "image/png") {
scope.$apply(function($scope) {
modelSetter(scope, element[0].files[0]);
});
};
var promise = fileReader.readAsDataURL(scope.fileForImagepreview, scope)
promise.then(function(result) {
scope.imageSrcForPreview = result;
});
});
}
};
};
and service contains this function.
this.readAsDataURL = function(file, scope) {
var deferred = $q.defer();
var reader = this.getReader(deferred, scope);
reader.readAsDataURL(file);
return deferred.promise;
};
Currently what I'm doing is like this for HTML,
<label class="item item-input">
<input type="text" maxlength="1" ng-model="user.name" maxlength="1" input-move-next-on-maxlength></input>
</label>
<label class="item item-input">
<input type="text" maxlength="1" ng-model="user.email" maxlength="1" input-move-next-on-maxlength></input>
</label>
and the .js looks like this
.directive("inputMoveNextOnMaxlength", function() {
return {
restrict: "A",
link: function($scope, element) {
element.on("label", function(e) {
if(element.val().length == element.attr("maxlength")) {
var $nextElement = element.next();
if($nextElement.length) {
$nextElement[0].focus();
}
}
});
}
}
})
But, the result is the auto tab is not working. I also tried removing the <label>, that worked. I'm wondering does it happen because of the input is at other class or does my code have an error.
Try with this solution, It worked for me
HTML:
<div ng-app="autofocus">
<label>Name:</label>
<input ng-model="maxLengthReach"></input>
<br/><br/>
<label>Title:</label>
<input autofocus-when></input>
</div>
Javascript:
var app = angular.module('autofocus', []);
app.directive('autofocusWhen', function () {
return function (scope, element, attrs) {
scope.$watch('maxLengthReach', function(newValue){
if (newValue.length >= 5 ) {
element[0].focus();
}
});
}
});
Adjust the length based upon your requirement
I would like to know if it is possible to send the user some kind of error message when the email already exist.
I have some directive like this. :
(function() {
angular
.module('app')
.directive('emailNotUsed',emailNotUsed);
emailNotUsed.$inject = ['$http', '$q'];
function emailNotUsed ($http, $q) {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$asyncValidators.emailNotUsed = function(modelValue, viewValue) {
return $http.post('/email',viewValue).then(function(response) {
console.log(response);
return response.data == true ? /*$q.reject(response.data.errorMessage)*/ console.log("Show Error Message"): true;
// console.log(response);
});
};
}
};
}
}());
As you can see this returns Show error in the console. But is it possible to pass this value to the register controller ? And set the value to true or false ?
(function () {
'use strict';
angular
.module('app')
.controller('RegisterController', RegisterController);
RegisterController.$inject = ['UserService', '$http','$q' ];
function RegisterController(UserService, $http,$q) {
var vm = this;
vm.register = register;
function register() {
vm.dataLoading = true;
UserService.Create(vm.user)
}
}
})();
Or could i give an error messages directly into the html.
<div class="container" ng-controller="RegisterController as vm">
<div class="col-md-6 col-md-offset-3">
<div ng-show="vm.error" class="alert alert-danger">{{vm.error}}</div>
<form name="form" ng-submit="!form.$pending && form.$valid && vm.register()" role="form">
<div>
<label for="email">Email</label>
<input type="text" name="email" id="email" class="form-control" ng-model="vm.user.email" email-not-used ng-model-options="{ debounce: 500 }" required >
</div>
<div class="form-actions">
<button type="submit" ng-disabled="form.$invalid || vm.dataLoading" class="btn btn-primary">Register</button>
Cancel
</div>
</form>
</div>
</div>
My solution
After alot of struggling today i found a solution for my problem.
I modified the emailNotUsed directive to emailValidator.
(function() {
angular
.module('app')
.directive('emailValidator',emailValidator);
emailValidator.$inject = ['$q', '$timeout','$http'];
function emailValidator ($q, $timeout,$http){
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$asyncValidators.email = function(modelValue, viewValue) {
var deferred = $q.defer();
DoesEmailExist()
function DoesEmailExist () {
$http.post('/email',viewValue).then(function(response) {
if (response.data==true) {
console.log('Email does exist')
deferred.reject();
}else {
deferred.resolve();
}
});
};
console.log(deferred.promise)
return deferred.promise;
};
}
}
}
}());
And in registration.html i added this :
<div class="form-group" ng-class="{ 'has-error': form.email.$dirty && form.email.$invalid }">
<label for="email"> Email</label>
<input type="text" ng-model="signup.email" ng-model-options="{ debounce: 500 }" name="email" id="email" class="form-control" required email-validator>
<div class="help-block" ng-messages="form.email.$error" ng-if="form.email.$dirty">
<p ng-message="required">Your name is required.</p>
<div ng-message="email" class="help-block" >email already in use</div>
</div>
Yes you can directly show error message into the HTML.
try this,
In HTML,
<form name="form" ng-submit="!form.$pending && form.$valid && vm.register()" role="form">
<div>
<label for="email">Email</label>
<input type="text" name="email" id="email" class="form-control" ng-model="vm.user.email" email-not-used ng-model-options="{ debounce: 500 }" required >
<span ng-show="form.email.$invalid && form.email.$dirty">Email is already in use!</span>
<span ng-show="form.email.$valid && form.email.$dirty">Email available!</span>
</div>
<div class="form-actions">
<button type="submit" ng-disabled="form.$invalid || vm.dataLoading" class="btn btn-primary">Register</button>
Cancel
</div>
</form>
In app.js,
var app = angular.module('app', []);
app.directive('emailNotUsed',emailNotUsed);
emailNotUsed.$inject = ['$http', '$q'];
function emailNotUsed ($http, $q) {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$asyncValidators.emailNotUsed = function(modelValue, viewValue) {
var data='';
if (viewValue=='abc#xyz.com'){
ngModel.$setValidity('valid', false);
scope.form.email.$setValidity('email', false);
}else{
ngModel.$setValidity('valid', true);
scope.form.email.$setValidity('email', true);
}
return data;
}
}
}
}
app.controller('RegisterController', RegisterController);
RegisterController.$inject = ['$scope', '$http','$q' ];
function RegisterController($scope, $http,$q) {
var vm = this;
$scope.name = 'abc#xyz.com email is already in use ';
vm.register = register;
function register() {
vm.dataLoading = true;
UserService.Create(vm.user)
}
}
Hope this helps. .
You can setup error message directly in your view. Bind to $scope.form.email.emailNotUsed.
<div>
<label for="email">Email</label>
<input type="text" name="email" id="email" class="form-control" ng-model="vm.user.email" email-not-used ng-model-options="{ debounce: 500 }" required >
<span ng-show="form.email.emailNotUsed">Email is already in use!</span>
</div>