How to apply ng-focus and ng-change on same input field? - javascript

Trying to call a function A when user focuses on input field using ng-focus event, and to call function B when the user starts writing and want to capture this event using ng-change event.
<input type="text" ng-focus="functionA()" ng-change="functionB()">

What is the problem with this? Seems to be working fine for me. The only thing I see a problem is that you haven't added ng-model. It is required for the ng-change to work.
var app = angular.module("sa", []);
app.controller("FooController", function($scope) {
$scope.functionA = function() {
console.log("Input is focused");
};
$scope.functionB = function() {
console.log("changing");
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="sa" ng-controller="FooController">
<input type="text" ng-focus="functionA()" ng-change="functionB()" ng-model="myValue" />
</div>

Related

Selecting another HTML element from an ng-click attribute

I am attempting to pass a file into a function, where the file is originated from an input type of file. My code looks something like this.
<input type="file" id="scvFileUploadId"/>
<button id="uploadFilesubmit" ng-click"ctrl.uploadFile()">Upload</button>
In short, I would like to take the file that has been added to the input and pass it into the parameter of the function of the ng-click attribute that is fired when the button is clicked. I think this may be simple, but I cannot wrap my head around it at the moment.
I'm trying to do something like this.
<input type="file" id="scvFileUploadId"/>
<button id="uploadFilesubmit" ng-click"ctrl.uploadFile(#scvFileUploadId.file)">Upload</button>
My solution was to use Angular's element selector to point to the input element holding the file, and then pass the result of that as the parameter into the function, like so:
<input type="file" id="scvFileUploadId" />
<button id="uploadFilesubmit" onclick="angular.element(this).controller().uploadFile(angular.element(document.querySelector('#csvFileUploadID'))[0].files[0])">Upload</button>
I'm not sure if this solution is the most 'Angular' way of doing it, but there were existing workarounds for some lack of support with Angular input file uploading being done on this part of the application that forced me to interact with DOM, so this does suffice in my scenario.
I highly recommend using existing directives created by the community;
https://github.com/nervgh/angular-file-upload
https://github.com/danialfarid/ng-file-upload
But if you are restricted and want to avoid 3rd parties you can see this implementation:
ng-model for <input type="file"/>
<input type="file" fileread="vm.uploadme" />
<button id="uploadFilesubmit" ng-click"ctrl.uploadFile(vm.uploadme)">Upload</button>
You can use a simple directive with NgModelController to add ngModel support for the input type='file' like:
angular.module('myApp', [])
.controller('TestUploadController', ['$scope', function ($scope) {
var ctrl = this;
ctrl.imageFile = null;
ctrl.clearFile = clearFile;
ctrl.uploadFile = uploadFile;
function clearFile() {
ctrl.imageFile = null;
}
function uploadFile(file) {
if (file) {
console.log('Upload: ', file);
}
}
}])
.directive('fileUpload', [function () {
return {
require: "ngModel",
restrict: 'A',
link: function ($scope, el, attrs, ngModel) {
function onChange (event) {
//update bindings with $applyAsync
$scope.$applyAsync(function(){
ngModel.$setViewValue(event.target.files[0]);
});
}
//change event handler
el.on('change', onChange);
//set up a $watch for the ngModel.$viewValue
$scope.$watch(function () {
return ngModel.$viewValue;
}, function (value) {
//clear input value if model was cleared
if (!value) {
el.val("");
}
});
//remove change event handler on $destroy
$scope.$on('$destroy', function(){
el.off('change', onChange);
});
}
};
}]);
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.angularjs.org/1.6.2/angular.js"></script>
<div ng-app="myApp">
<div ng-controller="TestUploadController as $ctrl">
<input type="file" file-upload ng-model="$ctrl.imageFile" />
<input type="button" ng-click="$ctrl.uploadFile($ctrl.imageFile)" value="Upload" />
<input type="button" ng-click="$ctrl.clearFile()" value="Reset" />
<div ng-if="$ctrl.imageFile">
{{$ctrl.imageFile.name}}<br />
{{$ctrl.imageFile.size}} byte(s)<br/>
{{$ctrl.imageFile.type}}
</div>
</div>
</div>

Get the new value from an input with AngularJS

I am trying to convert a JQuery website to AngularJS, but I can't figure this one out.
In JQuery I used:
$('.bet').change(function(e) {
// Do someting
};
I tried to do multiple things with AngularJS but no success.
At the moment I have this in my HTML and I have nothing related in my Angular file
index.php
<input type="number" class="form-control" id="bet" name="bet" placeholder="Your bet" ng-model="bet" ng-change="bet( {{bet}} )"/>
How to do this in AngularJS?
From the documentation:
Evaluate the given expression when the user changes the input. The expression is evaluated immediately, unlike the JavaScript onchange event which only triggers at the end of a change (usually, when the user leaves the form element or presses the return key).
So basically you need to bind a function to a ng-change attribute, like this way:
<input type="number" name="bet" placeholder="Your bet" ng-model="bet" ng-change="betChanged(bet)"/>
and the listener in your controller:
$scope.betChanged = function(bet){
//do something...
console.log(bet);
}
Like this, betChanged will be called every time bet will change, much like the native javascript input function.
var myApp = angular.module('myApp',[]);
myApp.controller('myCtrl', ['$scope', function($scope) {
$scope.bet = "";
$scope.onBetChanged = function () {
alert($scope.bet);
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<input type="number" class="form-control" id="bet" name="bet" placeholder="Your bet" ng-model="bet" ng-change="onBetChanged()"/>
</div>
what about $watch
<div ng-app="myApp" ng-controller="myCtrl">
First Name:
<input type="text" ng-model="firstName"><br>
Full Name: {{firstName }}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope, $window) {
$scope.$watch('firstName', function (newValue, oldValue) {
console.log('oldValue=' + oldValue);
console.log('newValue=' + newValue);
//do something
$window.alert("Event fired");
});
});
</script>

Angular checkbox input ng-click never called

In my Angular app, I have a form with checkbox inputs:
<div ng-repeat="partner in type.partners">
<label class="checkbox-inline">
<input type="checkbox" value="partner"
ng-checked="report.participatingPartners[$parent.$index].indexOf(partner) !== -1"
ng-click="toggleSelection($parent.$index, $index);">
<p><span></span>{{partner.name}}<p>
</label>
</div>
And in my controller, just to test this setup:
var vm = this;
vm.toggleSelection = toggleSelection;
...
function toggleSelection(typeId, partnerId) {
console.log("toggleSelection called");
console.log(typeId, partnerId);
}
This function never gets called when I click the checkbox or its label. Why is that?
I know it's not the controllerAs syntax because other functions are working fine.
The attribute you probably want to use is ng-change. The angular input directive does not have ng-clicked or ng-checked.
See docs.
By putting the function that you are trying to reference in the ng-click onto $scope rather than onto this the click event should bind as desired.
On the controller...
$scope.toggleSelection = toggleSelection;
function toggleSelection(typeId, partnerId) {
...
}
On your html...
<input type="checkbox" value="partner"
ng-click="toggleSelection($parent.$index, $index);">
Here is a simple Fiddle of it working.
You have written below code:
ng-checked="vm.toggleSelection($parent.$index, $index);"
But it should be:
ng-checked="toggleSelection($parent.$index, $index);"
Just remove "vm"

How do I reset a form in angularjs?

See Fiddle: http://jsfiddle.net/hejado/7bqjqc2w/
I'm trying to form.reset() my form using angular.
HTML:
<div ng-controller="formCtrl">
<form name="resetme" id="resetme">
<input ng-model="text" type="text" />
<input file-model="file" type="file" />
<button type="button" ng-click="resetForm()">reset</button>
</form>
</div>
JS:
.controller('formCtrl', function($scope) {
$scope.resetForm = function() {
//$scope.resetme.reset();
document.getElementById('resetme').reset();
};
});
Please note: I'm using this kind of form to ajax-upload a file. The page is not refreshing and I don't want to use any reset-buttons. (I'm using one in the fiddle for simplicity.) I want to call the reset-function after the fileupload is finished (via http success).
I'm using
<input type="file" />
so I can't reassign empty values to all my inputs, because file inputs are readonly.
Calling the reset() function on the DOM element works, but I was told talking to the DOM in angular would be evil, so...
I'd like to know, how this would be done the angular way. I tried naming the form and referencing it via $scope.formname but I'm not able to call Web API functions... (commented line)
How can I achieve this?
UPDATE
After reading some of the answers, I should make clear, that I am using ngModel and a custom directive fileModel to get a hold of the file-object.
Some of the solutions worked in resetting the value of the input field, but the model is not cleared (neither file, nor text). Custom directives are the answer to that, but this kinda exceeds the scope of this question.
I wrote about this topic a couple years ago. I don't know if the Angular team has yet implemented a native form reset directive but you can do so yourself. There are a couple caveats to this implementation: it only works for one model (if you need to support more see the followup post) and the issue of when to initialize the original values. Also, I never tested this with file inputs so I am not sure it would work with those.
There was an issue for this but it was closed due to inactivity. :/
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', ['$scope',
function($scope) {
$scope.myModel = {
foo: 'Boop',
bar: 'Beep'
};
$scope.myModelCopy = angular.copy($scope.myModel);
}
]);
myApp.directive('resetDirective', ['$parse',
function($parse) {
return function(scope, element, attr) {
var fn = $parse(attr.resetDirective);
var masterModel = angular.copy(fn(scope));
// Error check to see if expression returned a model
if (!fn.assign) {
throw Error('Expression is required to be a model: ' + attr.resetDirective);
}
element.bind('reset', function(event) {
scope.$apply(function() {
fn.assign(scope, angular.copy(masterModel));
scope.form.$setPristine();
});
// TODO: memoize prevention method
if (event.preventDefault) {
return event.preventDefault();
} else {
return false;
}
});
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
<form reset-directive="myModel" name="form">
<input type="text" ng-model="myModel.foo" />
<input type="text" ng-model="myModel.bar" />
<input type="reset" value="Reset" />
<pre>myModel: {{ myModel | json }}</pre>
<pre>myModelCopy: {{ myModelCopy | json }}</pre>
<pre>form pristine: {{ form.$pristine }}</pre>
</form>
</div>
</body>
You can try :
reset
$scope.resetForm = function(form) {
//Even when you use form = {} it does not work
form.fieldA = null;
form.fieldB = null;
///more fields
}
Or
$scope.resetForm = function(form) {
//Even when you use form = {} it does not work
angular.copy({},form);
}
See Demo
You'd want to attach ng-model to each of your input fields then null them out via $scope. Either that or make a custom directive
I've just had a similar problem with forms not resetting. Here's what I would do:
In your resetform() function, I would include statements that set both of your ng-models in your input to "". For example:
**HTML**
<input ng-model="text" type="text" />
<input file-model="file" type="file" />
**JS**
.controller('formCtrl', function($scope) {
$scope.resetForm = function() {
$scope.text = "";
$scope.file = null;
};
});
Not certain if this will work for file-models but I'm certain it will remove the text. Best of luck!
If you don't want to use ng-model and proper reset type of button you can use this code, however this is not proper angular way to reset the form but it will work
$scope.reset = function(){
$('form').children('*').each(function(){
$(this).val('');
});
}
Here's the Plunker
To reset the form data use following code :
$scope.resetEmployeeData = function() {
$scope.employeeCred.userName = '';
$scope.employeeCred.employeeNo = '';
$scope.employeeCred.sapNo = '';
$scope.employeeCred.emailD = '';
$scope.employeeCred.mobileNo = '';
**this**.createEmployee.$setPristine();
**this**.createEmployee.$setUntouched();
};
use this rather than $scope.

ng-model doesn't change value when field contains user input

I'm still fairly new to angular.js. This seems like it should be very simple, but I'm stumped.
I have an input field:
<input type="text" placeholder="Search" ng-model="search.txt">
And I have a button that calls this function in my controller on ng-click:
$scope.clearSearch = function() {
$scope.search = {txt:"qqqqq"};
}
Clicking the button behaves as expected - the input value on the page becomes "qqqqq". So the data binding seems correct.
However, if I type anything into the field first and then press the button, the input value does not change on the page - the input field keeps the value I typed. Why is that?
What I'm really trying to do is clear the field, I'm just using "qqqqq" for illustration - setting the value to null has the same behavior.
It works:
Script:
angular.module('myapp',[])
.controller('myctrl',function($scope){
$scope.search = {text:'some input'};
$scope.clearSearch = function () {
$scope.search={text:null};
}
});
Markup:
<div ng-app="myapp" ng-controller="myctrl">
<input type="text" ng-model="search.text"/>
<button ng-click="clearSearch()">clear</button>
</div>
In plunker

Categories

Resources