In angularjs if i change or remove image it does not make any changes. After refreshing the page it show the changed image.I am using following line to remove image
jQuery
$('#profile_image').val('')
This Sample is basic if you want to know more about AngularJs click on link
var app = angular.module("app", []);
app.controller("ctrl", [
"$scope",
function($scope) {
$scope.imgShow = true;
$scope.imgSrc = "https://www.gravatar.com/avatar/75025ad9a8cfdaa5772545e6e8f41133?s=32&d=identicon&r=PG&f=1";
$scope.display = function() {
$scope.imgShow = true;
$scope.imgSrc = "https://www.gravatar.com/avatar/75025ad9a8cfdaa5772545e6e8f41133?s=32&d=identicon&r=PG&f=1";
}
$scope.change = function() {
$scope.imgSrc = "https://www.gravatar.com/avatar/fccd71b79b3571b459cdfe40e7bf5dd8?s=32&d=identicon&r=PG&f=1";
}
$scope.remove = function() {
$scope.imgShow = false;
}
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<img ng-src="{{imgSrc}}" ng-show="imgShow">
<hr/>
<button ng-click="display()" ng-hide="imgShow">display image</button>
<button ng-click="change()">change image</button>
<button ng-click="remove()">remove image</button>
</div>
If you want to manipulate the DOM in AngularJS you should use directives for this purpose.
You should avoid using jquery inside of your controllers and simply work with your model. Below is fileUpload directive that could help you to work with <input type="file"> in a more angularjs-way:
angular.module('myApp', [])
.controller('TestController', ['$scope', function ($scope) {
var ctrl = this;
ctrl.imageFile = null;
ctrl.clearFile = clearFile;
function clearFile(){
ctrl.imageFile = null;
}
$scope.$ctrl = ctrl;
}])
.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.3.20/angular.js"></script>
<div ng-app="myApp">
<div ng-controller="TestController">
<input type="file" file-upload ng-model="$ctrl.imageFile" />
<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>
UPDATE: Also take a look at this useful reading.
I have a directive that is triggered when clicking on a button. The function inside the directive simply has to change the property value of the field. So what I try to do is to change from 'popover-trigger="blur"' to 'popover-trigger="none"'.
Here is my plunkr: http://plnkr.co/edit/L81fQgi7j1dEtf1QAZJ2?p=preview
or the code is here:
var app = angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
app.controller('PopoverDemoCtrl', function ($scope) {
$scope.dynamicPopover = {
content: 'Hello, World!',
templateUrl: 'myPopoverTemplate.html',
title: 'Title'
};
$scope.label = "Please click";
$scope.message = "ON FOCUS trigger a tooltip";
$scope.htmlPopover = "myPopoverTemplate.html";
});
app.directive("changeTrigger", function($compile){
return{
restrict: 'A',
link: function(scope, elm, attrs)
{
elm.bind('click', function(){
var t = document.getElementsByClassName('f')[0].setAttribute('popover-trigger', 'none');
$compile(t);
console.log("Click works");
});
}
}
});
html
<div ng-controller="PopoverDemoCtrl">
<br><br><br>
<p>{{message}}</p>
<input class="f" type="text" value="Click me!" uib-popover-template="htmlPopover" popover-trigger="focus" popover-popup-close-delay="1000" popover-placement="right" required>
<test-directive></test-directive>
<script type="text/ng-template" id="myPopoverTemplate.html">
<div>
<p>Click the button to stop triggering tooltip!</p>
<button change-trigger><b style="color: red">Stop tooltip</b></button>
<div class="label label-success">page</div>
</div>
</script>
</div>
You can't reconfigure the angular-bootstrap Popup element by changing uib-popup-* parameters; but you can bind a scope variable to popup-enable attribute to be able to switch the popup on/off. Add:
<input ... uib-popover-template="htmlPopover" popover-enable="enable" ...>
and
$scope.enable = true;
The problem here is that your button and the input box have different scopes. But you can fix this by retrieving the scope of the field:
var t = document.getElementsByClassName('f')[0];
var scope_ = angular.element(t).scope();
Of course, you need to use $scope.$apply for the scope to correctly handle two-way data binding:
scope_.$apply(function () {
scope_.enable = false;
});
Working Plunkr.
I'm trying to build an Angular JS form. I'd like user to be able to set the focus on a text field when they click a button. Not sure why this doesn't work? Thanks
html:
<div ng-app="" ng-controller="personController">
<p>Name: <input type="text" ng-model="name" id="question1" focus="{{focusThis}}"></p>
<p ng-bind="name"></p>
<input type="button" value="focus" ng-click="focus()">
</div>
Angular JS function:
function personController($scope)
{$scope.focus=function(){
$scope.focusThis="true";
};
};
How about some general solution ($ is jQuery):
mod.directive('nsFocusId', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs, ctrl) {
element.click(function() {
$timeout(function () { $('#' + attrs.nsFocusId).focus(); }, 0);
});
}
};
}]);
Usage:
<label data-ns-focus-id="id-of-target-element">a</label>
This directive could be used on any element and it will focus element by id that you provide.
I've used $timeout just to make it more flexible for future upgrades (but feel free to wrap it with just scope.$apply function);
https://docs.angularjs.org/api/ng/directive/ngFocus
ng-focus executes an expression when the element is focused, so it doesn't actually set the element as focused but rather respond to it being focused.
How to set focus on input field?
Check this resource or google up 'how to set an element focused' and it should direct you in the right way.
I have modified your code, check it.
<div ng-app="TestApp" ng-controller="personController">
<p>Name: <input type="text" ng-model="name" id="question1" ></p>
<p ng-bind="name"></p>
<input type="button" value="focus" ng-click="focus()">
</div>
var app = angular.module('TestApp', []);
app.controller('personController', function ($scope, $http, $log) {
$scope.focus = function () {
$("#question1").focus();
console.log($("#question1"));
}
});
How do we highlight and select all content inside a element on click using Angular JS ?.
It is easy to do using inputbox. But how do we do for element.
Help would be appreciated.
Thank you
This is what I have used so far.
HTML
<div ng-controller="appController" ng-app="app">
<input type="text" ng-model="content" ng-click="onTextClick($event)" />
</div>
JS
var app = angular.module('app', []);
app.controller('appController',
function ($scope) {
$scope.content = 'test';
$scope.onTextClick = function ($event) {
$event.target.select();
};
});
http://jsfiddle.net/onury/R63u5/
jsfiddle: http://jsfiddle.net/n63LhtcL/3/
Here is an updated directive to achieve it:
.directive('selectOnClick', function ($window) {
return {
link: function (scope, element) {
element.on('click', function () {
var selection = $window.getSelection();
var range = document.createRange();
range.selectNodeContents(element[0]);
selection.removeAllRanges();
selection.addRange(range);
});
}
}
});
Your markup:
<div select-on-click>
Some text...
<input type="text" ng-model="content" />
</div>
I have this form : http://jsfiddle.net/dfJeN/
As you can see the name value for the input is statically set :
name="username"
, the form validation works fine (add something and remove all text from the input, a text must appears).
Then I try to dynamically set the name value : http://jsfiddle.net/jNWB8/
name="{input.name}"
Then I apply this to my validation
login.{{input.name}}.$error.required
(this pattern will be used in an ng-repeat) but my form validation is broken. It is correctly interpreted in my browser (if I inspect the element I saw login.username.$error.required).
Any Idea ?
EDIT: After logging the scope in the console it appears that the
{{input.name}}
expression is not interpolate. My form as an {{input.name}} attribute but no username.
UPDATE: Since 1.3.0-rc.3 name="{{input.name}}" works as expected. Please see #1404
You can't do what you're trying to do that way.
Assuming what you're trying to do is you need to dynamically add elements to a form, with something like an ng-repeat, you need to use nested ng-form to allow validation of those individual items:
<form name="outerForm">
<div ng-repeat="item in items">
<ng-form name="innerForm">
<input type="text" name="foo" ng-model="item.foo" />
<span ng-show="innerForm.foo.$error.required">required</span>
</ng-form>
</div>
<input type="submit" ng-disabled="outerForm.$invalid" />
</form>
Sadly, it's just not a well-documented feature of Angular.
Using nested ngForm allows you to access the specific InputController from within the HTML template. However, if you wish to access it from another controller it does not help.
e.g.
<script>
function OuterController($scope) {
$scope.inputName = 'dynamicName';
$scope.doStuff = function() {
console.log($scope.formName.dynamicName); // undefined
console.log($scope.formName.staticName); // InputController
}
}
</script>
<div controller='OuterController'>
<form name='myForm'>
<input name='{{ inputName }}' />
<input name='staticName' />
</form>
<a ng-click='doStuff()'>Click</a>
</div>
I use this directive to help solve the problem:
angular.module('test').directive('dynamicName', function($compile, $parse) {
return {
restrict: 'A',
terminal: true,
priority: 100000,
link: function(scope, elem) {
var name = $parse(elem.attr('dynamic-name'))(scope);
// $interpolate() will support things like 'skill'+skill.id where parse will not
elem.removeAttr('dynamic-name');
elem.attr('name', name);
$compile(elem)(scope);
}
};
});
Now you use dynamic names wherever is needed just the 'dynamic-name' attribute instead of the 'name' attribute.
e.g.
<script>
function OuterController($scope) {
$scope.inputName = 'dynamicName';
$scope.doStuff = function() {
console.log($scope.formName.dynamicName); // InputController
console.log($scope.formName.staticName); // InputController
}
}
</script>
<div controller='OuterController'>
<form name='myForm'>
<input dynamic-name='inputName' />
<input name='staticName' />
</form>
<a ng-click='doStuff()'>Click</a>
</div>
The problem should be fixed in AngularJS 1.3, according to this discussion on Github.
Meanwhile, here's a temporary solution created by #caitp and #Thinkscape:
// Workaround for bug #1404
// https://github.com/angular/angular.js/issues/1404
// Source: http://plnkr.co/edit/hSMzWC?p=preview
app.config(['$provide', function($provide) {
$provide.decorator('ngModelDirective', function($delegate) {
var ngModel = $delegate[0], controller = ngModel.controller;
ngModel.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
});
$provide.decorator('formDirective', function($delegate) {
var form = $delegate[0], controller = form.controller;
form.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || attrs.ngForm || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
});
}]);
Demo on JSFiddle.
Nice one by #EnISeeK.... but i got it to be more elegant and less obtrusive to other directives:
.directive("dynamicName",[function(){
return {
restrict:"A",
require: ['ngModel', '^form'],
link:function(scope,element,attrs,ctrls){
ctrls[0].$name = scope.$eval(attrs.dynamicName) || attrs.dynamicName;
ctrls[1].$addControl(ctrls[0]);
}
};
}])
Just a little improvement over EnlSeek solution
angular.module('test').directive('dynamicName', ["$parse", function($parse) {
return {
restrict: 'A',
priority: 10000,
controller : ["$scope", "$element", "$attrs",
function($scope, $element, $attrs){
var name = $parse($attrs.dynamicName)($scope);
delete($attrs['dynamicName']);
$element.removeAttr('data-dynamic-name');
$element.removeAttr('dynamic-name');
$attrs.$set("name", name);
}]
};
}]);
Here is a plunker trial. Here is detailed explantion
I expand the #caitp and #Thinkscape solution a bit, to allow dynamically created nested ng-forms, like this:
<div ng-controller="ctrl">
<ng-form name="form">
<input type="text" ng-model="static" name="static"/>
<div ng-repeat="df in dynamicForms">
<ng-form name="form{{df.id}}">
<input type="text" ng-model="df.sub" name="sub"/>
<div>Dirty: <span ng-bind="form{{df.id}}.$dirty"></span></div>
</ng-form>
</div>
<div><button ng-click="consoleLog()">Console Log</button></div>
<div>Dirty: <span ng-bind="form.$dirty"></span></div>
</ng-form>
</div>
Here is my demo on JSFiddle.
I used Ben Lesh's solution and it works well for me. But one problem I faced was that when I added an inner form using ng-form, all of the form states e.g. form.$valid, form.$error etc became undefined if I was using the ng-submit directive.
So if I had this for example:
<form novalidate ng-submit="saveRecord()" name="outerForm">
<!--parts of the outer form-->
<ng-form name="inner-form">
<input name="someInput">
</ng-form>
<button type="submit">Submit</button>
</form>
And in the my controller:
$scope.saveRecord = function() {
outerForm.$valid // this is undefined
}
So I had to go back to using a regular click event for submitting the form in which case it's necessary to pass the form object:
<form novalidate name="outerForm"> <!--remove the ng-submit directive-->
<!--parts of the outer form-->
<ng-form name="inner-form">
<input name="someInput">
</ng-form>
<button type="submit" ng-click="saveRecord(outerForm)">Submit</button>
</form>
And the revised controller method:
$scope.saveRecord = function(outerForm) {
outerForm.$valid // this works
}
I'm not quite sure why this is but hopefully it helps someone.
This issue has been fixed in Angular 1.3+
This is the correct syntax for what you are trying to do:
login[input.name].$invalid
if we set dynamic name for a input like the below
<input name="{{dynamicInputName}}" />
then we have use set validation for dynamic name like the below code.
<div ng-messages="login.dynamicInputName.$error">
<div ng-message="required">
</div>
</div>