I was following this SO Post on creating an Enter keypress directive.
Here is my JS, in which I simulate the same functionality:
JavaScript
var app = angular.module('myApp', []);
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
app.directive('myEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 13) {
scope.$apply(function (){
scope.$eval(attrs.myEnter);
});
event.preventDefault();
}
});
};
});
function callServerWithSong(){
alert("calling!");
}
HTML
<div id="search" ng-app="myApp" ng-controller="MainCtrl">
<input type="text" id="search" my-enter="calServerWithSong()">
</div>
The problem is that when I select the input box, type a string and press enter, it doesn't report an error or execute the alert() which tells me that my directive must not be properly set up to fire when I keypress that element.
You had a typo of method name while passing through a directive attribute. Also the method should be there in $scope of controller.
HTML
<div id="search" ng-app="myApp" ng-controller="MainCtrl">
<input type="text" id="search" my-enter="callServerWithSong()">
</div>
Code
function callServerWithSong(){
alert("calling!");
}
$scope.callServerWithSong = callServerWithSong;
Related
I got weird problem with binding data in angular, I have an input file and if file is selected then his title should display in input below. It's displaying, but only if I click on this input. It should be displayed automatically after I select file from file input form, here is some code:
.html:
<div class="md-button md-raised md-primary raised-button">
<label class="ng-binding" for="image-file">UPLOAD FILE</label>
</div>
<md-input-container>
<div class="raised">
<input id="image_file_name" type="text" ng-model="vm.filename"></input>
</div>
</md-input-container>
<input ng-model="vm.filename" style="display: none" id="image-file" type="file"
on-upload="uploadFile"/>
controller:
app.controller('imageController', function($scope, fileService) {
$('.intro-for-image').show(2000);
$scope.uploadFile = function(event){
$scope.event = event;
fileService.uploadFile($scope);
};
});
directive:
app.directive('onUpload', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var onChangeFunc = scope.$eval(attrs.onUpload);
element.bind('change', onChangeFunc);
}
};
});
service:
angular.module('app')
.service('fileService', function ($http, validationService) {
this.uploadFile = function ($scope) {
var event = $scope.event;
var file = event.target.files[0];
name = file.name;
$scope.vm = {
file: file,
filename: name,
};
};
});
I'm not sure about this directive, I found it somewhere after I googled my earlier problem.
This code shows how to use a directive to submit a form by hitting 'enter' while in a textarea. However, I would like to be able to shift+enter and go to the next line and submit the result as it is. Whenever the submission is made, it shows up in the same line. How do I submit and show the submitted text in the next line as the user intends.
<div ng-app="testApp" ng-controller="MyController">
<textarea ng-model="foo" enter-submit="submit()"></textarea><br/>
Last submitted text: {{ lastSubmitted }}<br/>
</div>
The AngularJS code:
var app = angular.module('testApp', []);
function MyController($scope) {
$scope.foo = ""
$scope.lastSubmitted = ""
$scope.submit = function() {
$scope.lastSubmitted = $scope.foo;
}
}
app.directive('enterSubmit', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
elem.bind('keydown', function(event) {
var code = event.keyCode || event.which;
if (code === 13) {
if (!event.shiftKey) {
event.preventDefault();
scope.$apply(attrs.enterSubmit);
}
}
});
}
}
});
What should I do?
It looks like you need to convert \n\r into <br/> then use ng-bind-html to sanitize the string.
Here is a code example
You will also have to include the angularjs sanitize js file:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-sanitize.js"></script>
I'm trying to $watch the $error or the $valid value of a control. This is the control:
<form id="myForm" name="myForm">
<input name="myInput" ng-model="myInputMdl" business-validation/>
</form>
business-validation is a custom directive that alters the validity of the control. I've attempted the following approaches (using either $valid or $error) based on what I've read at AngularJS directive watch validity:
This does not work since $valid does not exist on myForm.myInput.
$scope.$watch('myForm.myInput.$valid', function (isValid) {
$scope.usefulVariable = step3.CreditCardNumber.$valid;
},true);
This does not work since validity.valid apparently cannot be watched.
$scope.$watch('myForm.myInput.validity.valid', function (isValid) {
$scope.usefulVariable = step3.CreditCardNumber.$valid;
},true);
This does not work since $scope.myInputMdl is not watched on every change.
$scope.$watch('$scope.myInputMdl', function (isValid) {
$scope.usefulVariable = step3.CreditCardNumber.$valid;
},true);
Can't the validity be watched from a controller?
EDIT
I'm not trying to write or edit business-validation directive. What I'm trying is to $watch $valid or $error from form's controller.
EDIT 2
Controller's code is:
app.controller('WizardBusinessActionCtrl',
function ($scope, $http, $parse, $filter, wizardBusinessActionService, $timeout) {
//controller code
}
);
I don't see any reason why your first variant shouldn't work.
HTML:
<div ng-app="myApp">
<div data-ng-controller="MainController">
<form name="myForm">
<input name="myInput" ng-model="myInputMdl" business-validation />
</form>
</div>
</div>
Controller and directive:
var myApp = angular.module('myApp', []);
myApp.controller('MainController', function ($scope) {
$scope.$watch('myForm.myInput.$valid', function (validity) {
console.log('valid', validity);
});
});
myApp.directive('businessValidation', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attr, ctrl) {
function validate (input) {
return input === 'hello';
}
ctrl.$parsers.unshift(function (value) {
var valid = validate(value);
ctrl.$setValidity('businessValidation', valid);
return valid ? value : undefined;
});
ctrl.$formatters.unshift(function (value) {
ctrl.$setValidity('businessValidation', validate(value));
return value;
});
}
};
});
$valid property value will change when myInput validity changes, and $watch callback will be fired.
See example: http://jsfiddle.net/Lzgts/287/
Try the code below. Working Plunker
HTML
<div ng-controller="ExampleController">
<form name="userForm" novalidate >
Name:
<input type="text" name="userName" ng-model="firstName" required />
</form>
<div>{{firstName}}</div>
<input type = 'button' value = 'Submit' ng-click ='validateInput()'/>
</div>
JavaScript
angular.module('getterSetterExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.validateInput = function(){
$scope.$watch($scope.userForm.userName.$valid, function() {
if($scope.userForm.userName.$valid){
alert('Value is True');
}
else{
alert('Value is False');
}
});
}
}]);
I have an input field and when people press enter I'd like the field to be emptied and its value printed below with an 'x' icon to delete it afterwards just like the 'search' field on angel.co: https://angel.co/jobs
Here is my HTML:
<form ng-submit="searchAds(searchInput)">
<input id="search-field" type="search" placeholder="Start typing your search..." ng-change="searchRequest()" ng-model="searchInput"/>
</form>
<div id="search-tags"></div>
And my JS in my controller:
$scope.searchAds = function(item){
if (item === "") return;
$scope.searchInput = "";
$('#search-tags').append('<div ng-show="showDetails">' + item + '<div ng-click="showDetails = ! showDetails"> (my DVG icon here) </div></div>');
}
I have 2 problems here:
1 - I believe the code is not compiled when printed so the 'ng-show' and 'ng-click' are so working - how can I make this work?
2 - How can I make sure that when there are several tags, when clicking on my delete icon it hide only this specific tag?
Many thanks
Why not angular instead of jQuery?
You can add a directive to manage the "enter" key:
angular.module('yourModule').directive(
'ngEnter',
function () {
'use strict';
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 13) {
scope.$apply(function (){
scope.$eval(attrs.ngEnter);
});
event.preventDefault();
}
});
};
});
And then change a bit your code:
<form ng-submit="searchAds(searchInput)">
<input type="search" placeholder="Start typing your search..." ng-enter="add(searchInput)" ng-model="searchInput"/>
</form>
<div ng-repeat="tag in tags">
<div>{{tag}}<div ng-click="delete(tag)">(my DVG icon here)</div></div>
</div>
Your controller:
$scope.add = function(item) {
$scope.tags.push(item);
$scope.searchInput = "";
}
$scope.delete = function(item) {
var index = $scope.tags.indexOf(item);
$scope.tags.splice(index, 1);
}
I am running into some problems using the keypress as follows-
<div ng-controller="GBNController">
...
<input id="search-field" type="text" placeholder="JSON Query" ng-model="queryText" ui-keypress="{enter: foo()}"/>
...
</div>
and my javascript has -
var AngApp = angular.module('gbn', ['ui']);
var GBNController = function($scope) {
$scope.queryText = '';
$scope.foo = function() {
alert('test');
}
};
Now this function foo is called only when the document is loaded and then after that, the return keypress event in the text field is never handled.
I am using the current head of the master branch.
Am I doing something wrong here, or is this broken??
You need to put foo() in quotes.
<input ui-keypress="{enter: 'foo()'}">
You could easily just roll your own keypress directive
Here's a plunker to demo
And the code:
app.directive('zKeypress', function(){
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('keypress', function(){
scope.$apply(function(s) {
s.$eval(attr.zKeypress);
});
});
}
};
});
HTML
<input type="text" z-keypress="foo()"/>