Image is not changing even i changed image - angularjs

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.

Related

How to trigger element click on angular js?

I have an input file and it is hidden. I want to trigger the input file once the button is clicked but my code is not working. What changes does it need to make it work?
HTML:
<input type="file" ng-model="data.file" id="upload" style="display:none;">
<button type="button" ng-click="browseFile()">Choose a file</button>
JavaScript:
$scope.browseFile = function () {
angular.element(document.querySelector('#upload')).triggerHandler('click');
}
In html use something like below
<img id="preview_image" src="" accept="image/*" class="upload_img" alt="">
<input id="image_upload" ng-model="file" type="file" class="upload_image_file" />
And in controller use $watch
$scope.$watch("file", function() {
readURL(angular.element("#image_upload")[0]);
});
function readURL(input) {
if (input && input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
angular.element("#preview_image").attr("src", e.target.result);
vm.base64File = e.target.result;
};
reader.readAsDataURL(input.files[0]);
}
}
For more info, read here and here
Update
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.file = '';
$scope.$watch("file", function() {
console.log($scope.file)
});
});
app.directive('fileModel', ['$parse', function($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function() {
scope.$apply(function() {
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<label class="upload_image_label" for="image_upload">
choose file
<input id="image_upload" file-model="file" type="file" style="display:none" />
</label>
<hr> <br> File: {{file}}
</div>
</body>
</html>
As adardesign said
This is due to a security restriction.
I found out that the security restriction is only when the
<input type="file"/>
is set to display:none; or is visibility:hidden.
So i tried positioning it outside the viewport by setting
position:absolute and top:-100px; and voilĂ  it works.
You can find more in this post: Jquery trigger file input

Why my angular directive doesn't work?

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.

Bind search input to ng-repeat in different controller

I am building a web application using Angular. We have a Twitter-like navigation bar up top with a search box in it. Then we have a bunch of entries below, using the ng-repeat directive. I want to be able to bind the search box with the entries below. The challenge is due to the fact that our header and our entries are in two different controllers. If they were in the same controller, then we could do this:
<input type="search" ng-model="search">
<div ng-repeat="entry in entries | filter:search">
{{ entry.text }}
</div>
But since in my application the search box is in a different controller, search isn't in scope so it's not working.
Any suggestions?
If you put the search string inside a service you can share the data between both controllers.
Here is an example.
<!doctype html>
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script>
angular.module('app', []);
angular.module('app')
.controller('Ctrl1', function($scope, ShareData) {
$scope.myData1 = ShareData;
});
angular.module('app')
.controller('Ctrl2', function($scope, ShareData) {
$scope.myData2 = ShareData;
$scope.entries = [
'1',
'2',
'3',
'11'
]
});
angular.module('app')
.service('ShareData', function(){
return {
search: "1"
}
})
</script>
</head>
<body >
<div ng-controller="Ctrl1">
<h2>Inside Ctrl 1</h2>
<input type="text" ng-model="myData1.search">
</div>
<hr>
<div ng-controller="Ctrl2">
<h2>Inside Ctrl 2</h2>
<div ng-repeat="entry in entries | filter:myData2.search">
{{entry}}
</div>
</div>
</body>
</html>
You can do one thing use $emit on rootscope and capture it in another controller:-
For example:-
<input type="search" ng-model="search">
Controller one:-
$scope.$watch('search',function(new){
$rootScope.$emit('update',new);
});
Controller Second:-
$rootScope.$on('update', function (event, data) {
$scope.search=data;
});
Secondly you can also share data from controller's via service (this one is effective)
myApp.factory('Data', function () {
var data = {
search: ''
};
return {
getSearch: function () {
return data.search;
},
setSearch: function (search) {
data.search= firstName;
}
};
});
myApp.controller('FirstCtrl', function ($scope, Data) {
$scope.firstName = '';
$scope.$watch('search', function (newValue) {
if (newValue) Data.setSearch(newValue);
});
});
myApp.controller('SecondCtrl', function ($scope, Data) {
$scope.$watch(function () { return Data.getSearch(); }, function (newValue) {
if (newValue) $scope.search = newValue;
});
});

AngularJS ckEditor, multiple instances

I will have an app with drag and drop functionality.
Also, it will be possible to drop an ckeditor in it.
How is it possible to create a new instance of an ckeditor, the Problem i have is all the instances will have the same "ng-model".
I saw an Answer with "ng-repeat" here:
jsfiddle.net/TheSharpieOne/cPTr7/
but my app does not have such an repeater.
Thank you
Had similar problem, don't know if this can help you, but solved my problem.
var app = angular.module('app', []);
app.directive('ckEditor', [function () {
return {
require: '?ngModel',
link: function ($scope, elm, attr, ngModel) {
var ck = CKEDITOR.replace(elm[0]);
ck.on('pasteState', function () {
$scope.$apply(function () {
ngModel.$setViewValue(ck.getData());
});
});
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
};
}
};
}])
function myCtrl($scope){
$scope.ckEditors = [];
$scope.post = 0;
$scope.addEditor = function(id){
$scope.ckEditors.pop();
$scope.post=id;
var rand = ""+(Math.random() * 10000);
$scope.ckEditors.push({value:rand});
}
}
<script src="http://ckeditor.com/apps/ckeditor/4.2/ckeditor.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="app" data-ng-controller="myCtrl">
<h3>Post1:</h3>
<div ng-repeat="editor in ckEditors">
<textarea ng-if="post==1" data-ng-model="editor.value" data-ck-editor></textarea>
<br />
</div>
<button ng-click="addEditor(1)">New Editor</button>
<h3>Post2:</h3>
<div ng-repeat="editor in ckEditors" >
<textarea ng-if="post==2" data-ng-model="editor.value" data-ck-editor></textarea>
<br />
</div>
<button ng-click="addEditor(2)">New Editor</button>
http://jsfiddle.net/PauloSegundo/mrLz8eba/

Angular highlight/select all content inside <div> element Angular

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>

Resources