ng-show ng-hide using controller - angularjs

I am trying to edit a field and convert label into text field on click of a button and change it back to label on keypress event (ng-keypress).
I am changing the ng-show variable through controller but it is not working.
HTML:
<div ng-app>
<div ng-controller="showCrtl">
<form>
<label ng-hide="editMode" >{{field}}</label>
<input ng-show="editMode" ng-keypress="changemode($event) " ng-model="field" >
<span class="pull-right" >
<button ng-click="editMode=true" class="btn-lg btn-warning" >edit </button> </span>
</form>
</div>
</div>
JS:
function showCrtl($scope){
$scope.field="Chanel";
$scope.changemode=function(event){
if(event.charCode==13){
$scope.editMode = false;
}
}
}
My updated JS-Fiddle link: http://jsfiddle.net/8Yz7S/281/

Use ng-blur instead of ng-keypress,
<input ng-show="editMode" ng-blur="changemode() " >
DEMO
EDIT:
Use the following directive to handle the enter key event,
app.directive('ngEnter', function() {
return function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
if (event.which === 13) {
scope.$apply(function() {
scope.$eval(attrs.ngEnter);
});
event.preventDefault();
}
});
};
});
DEMO

Can you try the below solution.
<input ng-show="editMode" ng-keypress="changemode($event) " >
Added interval to update the view
function showCrtl($scope, $timeout){
$scope.changemode=function(event){
if(event.charCode==13){
$timeout(function() {
$scope.editMode = false;
}, 500);
}
}
}
http://jsfiddle.net/gsjsfiddle/hcu5mkhm/3/

The reason its not working for you is that, you are not preventing the default behavior of Enter key. So After changemode function is executed and editmode is set to false, click event of Edit button is also getting executed, setting editmode back to true.
All you need to do is call event.preventDefault(); as shown below:
function showCrtl($scope){
$scope.field="Chanel";
$scope.changemode=function(event){
if(event.charCode==13){
$scope.editMode = false;
event.preventDefault(); // <<<<<<<
}
}
}
To verify this behavior you can check this fiddle: http://jsfiddle.net/vnathalye/8Yz7S/301/
Try it after commenting the line event.preventDefault(); and check the console.

You want to obfuscate as much logic as possible from the view. So as he suggested, use
<input ng-show="editMode" ng-keypress="changemode($event)">
Then, do all your logic inside the changemode() function:
$scope.changemode = function(evt) {
$timeout(function() {$scope.editMode = false;},100);
}
http://jsfiddle.net/8Yz7S/293/

Related

onclick button get the value of selected (checkbox) value

<div class="chks" ng-repeat="request in pendingRequest">
<input type="checkbox" name="chk" ng-model="pendingRequest" id="chk1" ng-click="pendingUser(request.user_id)">
<label for="chk1">{{request.first_name}} {{request.last_name}}</label>
</div>
<button type="button" ng-click="checkVal()" class="btn btn-default next-step"><span class="next-step">Resend Linking Request</span></button>
var selectUser = '';
$scope.pendingUser = function(user) {
selectUser = user;
}
$scope.checkVal = function() {
if (selectUser) {
alert(selectUser);
} else {
alert("CheckBox is not checked.");
}
}
How can I check on click checkVal button function has user_id.
on bases checkbox click get the user_id in Angularjs.
Use an array to push the value entries from the checkbox.
$scope.nameSelected= [];
Give a single value for the checkbox. I'm assuming that to be the first name.
$scope.getAllSelected = function(){
angular.forEach($scope.first_name,function(key,value){
if(key)
$scope.nameSelected.push(value)
});
console.log($scope.nameSelected)
}
Remove the unwanted ng-click from the checkbox input entry. getAllSelected can be done in the ng-click on the submit button you've there.
<div class="chks" ng-repeat="request in pendingRequest">
<input type="checkbox" name="chk" ng-model="pendingRequest" id="chk1" ng-click="pendingUser(request.user_id)">
<label for="chk1">{{request.first_name}} {{request.last_name}}
</label>
</div>
Why would you ng-repeat over the same model than your checkbox is ? Can you provide a plunker or something.
$scope.checkVal = function(){
if (selectUser) {
alert(selectUser);
} else {
alert("CheckBox is not checked.");
}
}
The selectUser is undefined there, is it supposed to be a single user (and you should pass it in params then), or the whole array pendingRequest ?
If you want to check if each request is selected then you could just bind your checkbox to request.selected and return in the check request.selected
Which would be something like that :
$scope.checkVal = function(){
angular.forEach($scope.pendingRequest, function(request) {
if (request.selected)
alert(request)
else
alert("Not selected")
})
}

Ng-submit with textarea

I have a form with only a text area. Is it possible to execute ng-submit when a user hits enter in the textarea? I'm able to accomplish this using ng-keyup but was wondering if there was a better solution.
<form ng-show="messages.conversation" ng-submit="messages.reply()">
<textarea class="msg-textarea" ng-model="messages.replyText"
ng-keyup="$event.keyCode == 13 ? messages.reply() : null">
</textarea>
<button type="submit" value="submit" class="btn-primary btn-sm btn-block"
ng-click="messages.reply()">Reply
</button>
</form>
#EpokK once solved the problem with the following code:
How to use a keypress event in AngularJS?
You need to add a directive, like this:
Javascript:
app.directive('ngEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 13) {
scope.$apply(function (){
scope.$eval(attrs.ngEnter);
});
event.preventDefault();
}
});
};
});
HTML:
<div ng-app="" ng-controller="MainCtrl">
<input type="text" ng-enter="doSomething()">
</div>

AngularJs - element.on('submit') is not working in my directive

I am attempting to use an ng-submit call to fire a submit event to my custom directive, but it isn't firing.
Here is a plunk that illustrates my problem.
<div ng-controller="MyCtrl">
<form name="loginForm" ng-submit="login()" novalidate="">
<input type="submit" class='please-wait' value="Submit Me" />
</form>
</div>
js code:
app.directive('pleaseWait', function () {
return {
restrict: "C",
compile: function (element) {
element.on('submit', function (e) {
alert('Submit called');
});
element.on('click', function (e) {
alert('Click called');
});
}
};
});
http://plnkr.co/edit/lwHPVJI75q8bvVoSX1WP?p=preview
What am I doing wrong?
"submit" is not an event on the input element but is an event on the form so the directive is listening for an event it won't receive.

Validate Input fields only on submit angularjs

I am trying to show a Validation Summary, a Div on top of the page with all the Validation error messages in angularjs, on form submit.
I am using the below logic to show/ hide the top div with validation messages,
<div class="alert alert-error" ng-show="submitted && myForm.$invalid">
</div>
I am setting the variable submitted to true on save button click. It's working Okay the first time, but after the first submission, if enter the value for the input field(required field) and clear it, it's kicking off the validation(the top div shows).
Is there a way to show the validation div, only on the submit of the form and not when the user clears the input field ?
UPDATE
$scope.save = function (myForm) {
$scope.submitted = true;
if (myForm.$invalid) {
return;
}
$scope.submitted = false;
}
Thanks !
Hmm one way to do it would be to watch the FormController's property $dirty and $setPristine() method, and use a variable hasError to show the error or not.
See this plunker as an example
JAVASCRIPT
controller('AppController', ['$scope', function($scope) {
$scope.hasError = false;
$scope.$watch('theForm.$dirty', function() {
$scope.hasError = false;
$scope.theForm.$setPristine();
});
$scope.save = function() {
$scope.hasError = $scope.theForm.$invalid;
if($scope.hasError) {
// perform error routine
} else {
// perform save routine
}
};
}]);
HTML
<body ng-controller="AppController">
<div class="error" ng-show="hasError">This is an error</div>
<form name="theForm" ng-submit="save()" novalidate>
<input type="text" name="text1" ng-model="text1" required>
<input type="text" name="text2" ng-model="text2" required>
<button type="submit">Submit</button>
</form>
</body>
Make sure you are setting submitted to false upon display of your validation div else it'll show up after each additional validation call.
$scope.save = function (myForm) {
$scope.submitted = true;
if (myForm.$invalid) {
$scope.submitted = false;
return;
}
}

Submit form on pressing Enter with AngularJS

In this particular case, what options do I have to make these inputs call a function when I press Enter?
Html:
<form>
<input type="text" ng-model="name" <!-- Press ENTER and call myFunc --> />
<br />
<input type="text" ng-model="email" <!-- Press ENTER and call myFunc --> />
</form>
// Controller //
.controller('mycontroller', ['$scope',function($scope) {
$scope.name = '';
$scope.email = '';
// Function to be called when pressing ENTER
$scope.myFunc = function() {
alert('Submitted');
};
}])
Angular supports this out of the box. Have you tried ngSubmit on your form element?
<form ng-submit="myFunc()" ng-controller="mycontroller">
<input type="text" ng-model="name" />
<br />
<input type="text" ng-model="email" />
</form>
EDIT: Per the comment regarding the submit button, see Submitting a form by pressing enter without a submit button which gives the solution of:
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
If you don't like the hidden submit button solution, you'll need to bind a controller function to the Enter keypress or keyup event. This normally requires a custom directive, but the AngularUI library has a nice keypress solution set up already. See http://angular-ui.github.com/
After adding the angularUI lib, your code would be something like:
<form ui-keypress="{13:'myFunc($event)'}">
... input fields ...
</form>
or you can bind the enter keypress to each individual field.
Also, see this SO questions for creating a simple keypres directive:
How can I detect onKeyUp in AngularJS?
EDIT (2014-08-28): At the time this answer was written, ng-keypress/ng-keyup/ng-keydown did not exist as native directives in AngularJS. In the comments below #darlan-alves has a pretty good solution with:
<input ng-keyup="$event.keyCode == 13 && myFunc()"... />
If you want to call function without form you can use my ngEnter directive:
Javascript:
angular.module('yourModuleName').directive('ngEnter', function() {
return function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
if(event.which === 13) {
scope.$apply(function(){
scope.$eval(attrs.ngEnter, {'event': event});
});
event.preventDefault();
}
});
};
});
HTML:
<div ng-app="" ng-controller="MainCtrl">
<input type="text" ng-enter="doSomething()">
</div>
I submit others awesome directives on my twitter and my gist account.
If you only have one input you can use the form tag.
<form ng-submit="myFunc()" ...>
If you have more than one input, or don't want to use the form tag, or want to attach the enter-key functionality to a specific field, you can inline it to a specific input as follows:
<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>
I wanted something a little more extensible/semantic than the given answers so I wrote a directive that takes a javascript object in a similar way to the built-in ngClass:
HTML
<input key-bind="{ enter: 'go()', esc: 'clear()' }" type="text"></input>
The values of the object are evaluated in the context of the directive's scope - ensure they are encased in single quotes otherwise all of the functions will be executed when the directive is loaded(!)
So for example:
esc : 'clear()' instead of esc : clear()
Javascript
myModule
.constant('keyCodes', {
esc: 27,
space: 32,
enter: 13,
tab: 9,
backspace: 8,
shift: 16,
ctrl: 17,
alt: 18,
capslock: 20,
numlock: 144
})
.directive('keyBind', ['keyCodes', function (keyCodes) {
function map(obj) {
var mapped = {};
for (var key in obj) {
var action = obj[key];
if (keyCodes.hasOwnProperty(key)) {
mapped[keyCodes[key]] = action;
}
}
return mapped;
}
return function (scope, element, attrs) {
var bindings = map(scope.$eval(attrs.keyBind));
element.bind("keydown keypress", function (event) {
if (bindings.hasOwnProperty(event.which)) {
scope.$apply(function() {
scope.$eval(bindings[event.which]);
});
}
});
};
}]);
Another approach would be using ng-keypress ,
<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return">
Submit an input on pressing Enter with AngularJS - jsfiddle
Very good, clean and simple directive with shift + enter support:
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);
}
}
});
}
}
});
If you want data validation too
<!-- form -->
<form name="loginForm">
...
<input type="email" ng-keyup="$loginForm.$valid && $event.keyCode == 13 && signIn()" ng-model="email"... />
<input type="password" ng-keyup="$loginForm.$valid && $event.keyCode == 13 && signIn()" ng-model="password"... />
</form>
The important addition here is $loginForm.$valid which will validate the form before executing function. You will have to add other attributes for validation which is beyond the scope of this question.
Good Luck.
Just wanted to point out that in the case of having a hidden submit button, you can just use the ngShow directive and set it to false like so:
HTML
<form ng-submit="myFunc()">
<input type="text" name="username">
<input type="submit" value="submit" ng-show="false">
</form>
Use ng-submit and just wrap both inputs in separate form tags:
<div ng-controller="mycontroller">
<form ng-submit="myFunc()">
<input type="text" ng-model="name" <!-- Press ENTER and call myFunc --> />
</form>
<br />
<form ng-submit="myFunc()">
<input type="text" ng-model="email" <!-- Press ENTER and call myFunc --> />
</form>
</div>
Wrapping each input field in its own form tag allows ENTER to invoke submit on either form. If you use one form tag for both, you will have to include a submit button.
Will be slightly neater using a CSS class instead of repeating inline styles.
CSS
input[type=submit] {
position: absolute;
left: -9999px;
}
HTML
<form ng-submit="myFunc()">
<input type="text" ng-model="name" />
<br />
<input type="text" ng-model="email" />
<input type="submit" />
</form>
FWIW - Here's a directive I've used for a basic confirm/alert bootstrap modal, without the need for a <form>
(just switch out the jQuery click action for whatever you like, and add data-easy-dismiss to your modal tag)
app.directive('easyDismiss', function() {
return {
restrict: 'A',
link: function ($scope, $element) {
var clickSubmit = function (e) {
if (e.which == 13) {
$element.find('[type="submit"]').click();
}
};
$element.on('show.bs.modal', function() {
$(document).on('keypress', clickSubmit);
});
$element.on('hide.bs.modal', function() {
$(document).off('keypress', clickSubmit);
});
}
};
});
you can simply bind #Hostlistener with the component, and rest will take care by it. It won't need binding of any method from its HTML template.
#HostListener('keydown',['$event'])
onkeydown(event:keyboardEvent){
if(event.key == 'Enter'){
// TODO do something here
// form.submit() OR API hit for any http method
}
}
The above code should work with Angular 1+ version
I focused to below row input in the table
<input ng-keydown="$event.keyCode == 13 && onPressEnter($event)" id="input_0" type="text" >
$scope.onPressEnter = function (event) {
let inputId = event.target.id;
let splited = inputId.split('_');
let newInputId = 'input' + '_' + ((+splited[1]) + 1);
if (document.getElementById(newInputId))
document.getElementById(newInputId).focus();
// else submit form
}

Resources