how to check data model values changed angular? - angularjs

I have an online Web form using angular.js. When the user edits the information and clicks back it loses the unsaved data. How can I check whether the data model values have changed and warn the user that they have unsaved information that needs to be saved before navigating away?
I have forked this example: plunker
angular.module('formExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.master = {};
$scope.update = function(user) {
$scope.master = angular.copy(user);
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
}]);

I have used this directive to warn unsaved data when user leaves from the page inject this directive and change the messages
<html ng-app="myApp">
<head>
<script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
<script type="text/javascript">
function Ctrl($scope) {
var initial = {text: 'initial value'};
$scope.mySample = angular.copy(initial);
}
angular.module("myApp", []).directive('confirmOnExit', function() {
return {
link: function($scope, elem, attrs) {
window.onbeforeunload = function(){
if ($scope.myForm.$dirty) {
return "The form is dirty, do you want to stay on the page?";
}
}
$scope.$on('$locationChangeStart', function(event, next, current) {
if ($scope.myForm.$dirty) {
if(!confirm("The form is dirty, do you want to stay on the page?")) {
event.preventDefault();
}
}
});
}
};
});
</script>
</head>
<body>
<form name="myForm" ng-controller="Ctrl" confirm-on-exit>
Text: <input name="input" ng-model="mySample.text">
<p>mySample = {{mySample.text}}</p>
</form>
</body>
</html>

Related

How to get the URL for the file selected in File Explorer using AngularJS

I need to click on the Choose file and select the file from the file explorer, then I need to get the URL for the selected file and store it in variable.Can you please look in to the below code and guide me since i am new to AnularJS...Thanks in Advance.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body >
<div ng-app = "myApp" ng-controller="myControl">
<input type="file" file-model="myFile" ng-module = "file_name" ng-click = "file_name()"><br>
<h1>{{file_name()}}</h1>
</div>
<script>
var app= angular.module("myApp",[]);
app.controller("myControl",function($scope){
$scope.file_name = function(){
return $scope.file_name;
};
});
</script>
</body>
</html>
You can create url directive. Inside controller you should use $watch method to catch the moment, when file_name property will be assigned. At this example you can select picture file and it will be shown:
angular.module('app', [])
.controller('ctrl', ['$scope', function($scope) {
$scope.$watch('file_url', function(newVal, oldVal) {
if (newVal != oldVal)
console.log(newVal);
}, true)
}])
.directive('url', function() {
return {
restrict: 'A',
scope: {
url: '='
},
link: function(scope, element) {
element.on('change', function(event) {
var reader = new FileReader();
reader.onloadend = function() {
scope.$apply(function() {
scope.url = reader.result;
});
}
var file = element[0].files[0];
if (file)
reader.readAsDataURL(file);
})
}
}
})
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<div ng-app='app' ng-controller="ctrl">
<img src="{{file_url}}" height="150" alt="Image preview...">
<input type="file" url='file_url'>
</div>

how to access function in factory outside controller

<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp">
<div ng-controller="FirstCtrl">
firstname:<input type="text" ng-model="data.firstName">
lastname:<input type="text" ng-model="data.lastName">
<br>name is : <strong>{{data.firstName}} {{data.lastName}}</strong>
</div>
<div ng-controller="SecondCtrl">
name in 2nd controller: {{data.firstName}} {{data.lastName}}
<button ng-click="updateData('kv','a')">click</button>
</div>
<button onclick = "ChangeEvn()"/>
</div>
<script>
var myApp = angular.module("myApp", []);
myApp.factory('MyService', function(){
return {
data: {
firstName: '',
lastName: ''
},
update: function(first, last) {
this.data.firstName = first;
this.data.lastName = last;
}
};
});
myApp.controller('FirstCtrl', function($scope, MyService){
$scope.data = MyService.data;
});
myApp.controller('SecondCtrl', function($scope, MyService){
$scope.data = MyService.data;
$scope.updateData = function(first, last) {
MyService.update(first, last);
}
});
function ChangeEvn()
{
alert("Ok");
myApp.factory.update("Hello", ".....");//doesn't work
}
</script>
</body>
</html>
In the above code value is passed between two controllers using factory .Now i want to update first name and lastname using button click. button click function is outside the controller(i require that) . Now how to access the update outside controller myApp.factory.update("Hello", "....."); this statement doesn't work
Please read the Angular documentation of services:
To use an Angular service, you add it as a dependency for the component (controller, service, filter or directive) that depends on the service. Angular's dependency injection subsystem takes care of the rest.
You are trying to access the service method outside of an angular component. That is not at all recommended, if possible at all. If you are using angular, try to do everything "inside Angular subsystem". Trying to bypass the angular context will only cause problems, and it's not needed at all.
If you want to use a service method, then create a MainController, inject the service in it, attach the controller to some HTML element, and put your update button as a child of that element.
<body>
<div ng-app="myApp">
<div ng-controller="MainCtrl">
<button onclick="updateData('FirstName', 'LastName')" />
</div>
</div>
<script>
var myApp = angular.module("myApp", []);
myApp.factory('MyService', function () {
return {
data: {
firstName: '',
lastName: ''
},
update: function (first, last) {
this.data.firstName = first;
this.data.lastName = last;
}
};
});
myApp.controller('MainCtrl', function($scope, MyService) {
$scope.updateData = MyService.update;
});
</script>
</body>

how to make custom directive?

I am new to angularjs ,building my first angular app now i want to display the data which i displayed right now in a table using a customized directive.
can anyone tell me how can i do this?
i just want to have a custom directive and all data should be displayed using that directive.
is customized directive should placed in a separate file?
please guide me how can i do it?
here is my controller:
'use strict';
app.controller('myAppCtrl', function ($scope, $http) {
$scope.names = []
$http.get('https://www.reddit.com/r/worldnews/new.json')
.success(function (response) {
$scope.names = response.data.children;
})
});
https://jsfiddle.net/rr6q0umb/4/
You should go through some resources online to study about angular directives .
https://docs.angularjs.org/guide/directive
http://www.tutorialspoint.com/angularjs/angularjs_custom_directives.htm
Simple directive approach for beginners
//Controller
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
//Directive
app.directive('simpleDemo',function(){
var newtemplate = function(){
var template = '<i class="glyphicon glyphicon-remove"><i>';
return template;
}
return {
restrict: 'E',
template: newtemplate
}
})
//html
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<button><simple-demo></simple-demo></button>
It might help you!
<html>
<head>
<title>Angular JS Custom Directives</title>
</head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var mainApp = angular.module("mainApp", []);
mainApp.directive('student', function() {
var directive = {};
directive.restrict = 'E';
directive.template = "Student: <b>{{student.name}}</b> , Roll No: <b>{{student.rollno}}</b>";
directive.scope = {
student : "=name"
}
directive.compile = function(element, attributes) {
element.css("border", "1px solid #cccccc");
var linkFunction = function($scope, element, attributes) {
element.html("Student: <b>"+$scope.student.name +"</b> , Roll No: <b>"+$scope.student.rollno+"</b><br/>");
element.css("background-color", "#ff00ff");
}
return linkFunction;
}
return directive;
});
mainApp.controller('StudentController', function($scope) {
$scope.Mahesh = {};
$scope.Mahesh.name = "Mahesh Parashar";
$scope.Mahesh.rollno = 1;
$scope.Piyush = {};
$scope.Piyush.name = "Piyush Parashar";
$scope.Piyush.rollno = 2;
});
</script>
<body>
<h2>AngularJS Sample Application</h2>
<div ng-app="mainApp" ng-controller="StudentController">
<student name="Mahesh"></student><br/>
<student name="Piyush"></student>
</div>
</body>
</html>
Reference URLs:
https://www.airpair.com/angularjs/posts/creating-components-p3-angular2-directives
http://tutorials.jenkov.com/angularjs/custom-directives.html
http://www.sitepoint.com/practical-guide-angularjs-directives/

How To Get Data Back From Angular Directive

i hope somebody could help me with a small example, because angular is driving me crazy :(
I'm making by first time a Formular that should follow this structure:
Angular APP
mainController
---->smallController1
-------->otherElements
---->smallController2
-------->otherElements
---->Directive1 (instance 1)
---->anotherSmallController
---->Directive1 (instance 2)
The Directive1 receives many attributes, and each instance will allow the selection of many options, and the result of the user interaction should be stored in an object, and that object should be accessed from mainController for each instance separately.
Does anyone have an example that work like that?
Thanks in advance,
John
The best way to get data back from directive is to attach a model to directive's self scope.
var app = angular.module('app', []);
app.controller('mainController',
[
'$scope',
function($scope){
$scope.myObj = "Initial Value";
}
]);
app.directive('dirName', [
function(){
return {
restrict : 'A',
scope : {
obj : "=ngModel"
},
link : function(scope, element, attrs){
scope.obj = attrs.newValue;
}
};
}
]);
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-app="app" ng-controller="mainController">
<input dir-name ng-model="myObj" new-value="Final Value">
</body>
</html>
You can check this bin as well : http://jsbin.com/fuqujo/1/edit?html,js,output
Use emit to send data to parent controller.
It may be receiver because listening to event.
Read about on emit and broadcast.
In your child controller or directive use:
$scope.$emit('myEvent', object);
This sends object to all parent controllers.
In parent controller use:
$scope.$on('myEvent', function(event, obj) { console.log(obj); });
To listen to emitted object.
Try this code out, it might help you:
http://plnkr.co/edit/L1NwUnNePofyRAQ6GVIg?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.masterData = [
{
entry: 'dunno'
},
{
entry: 'stuff'
}
]
})
app.directive('vessel', function() {
return {
replace: true,
scope: {
data: '=',
speciality: '#'
},
link: function(scope) {
scope.updateData = function() {
scope.data.entry = scope.speciality;
}
},
template: '<div>{{data.entry}} <button ng-click="updateData()">update</button></div>'
}
});
And the template:
<body ng-controller="MainCtrl">
<p>Master data {{masterData | json}}</p>
<div vessel data="masterData[0]" speciality="eggs"></div>
<div vessel data="masterData[1]" speciality="bacon"></div>
</body>
So, we have separate data models for each directive which are updated on user input, fitting your requirements. Right?

Outside Angular context?

I have following HTML and JS code:
HTML:
<!doctype html>
<html ng-app="test">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="Ctrl2">
<span>{{result}}</span>
<br />
<button ng-click="a()">A</button>
<button my-button>B</button>
</div>
JS:
function Ctrl2($scope) {
$scope.result = 'Click Button to change this string';
$scope.a = function (e) {
$scope.result = 'A';
}
$scope.b = function (e) {
$scope.result = 'B';
}
}
var mod = angular.module('test', []);
mod.directive('myButton', function () {
return function (scope, element, attrs) {
//change scope.result from here works
//But not in bind functions
//scope.result = 'B';
element.bind('click', scope.b);
}
});
I bind click event to my-button and want to change $scope.result when user clicked button B (similar to ng-click:a() on button A). But the view won't update to the new $scope.result. Someone advised me to call $scope.$apply() at the bottom of your event handler.but $scope.$apply is called when variable will be outside angular context. How can I evaluate that on button "B" click event is outside angular context?
element.bind() is a low-level (jqLite) call that is not tracked by Angular. So you need to help Angular know that a change happened by calling $scope.$apply(); in the element.bind() handler.
Perhaps do:
element.bind('click', function () {
scope.$apply(function () {
scope.b();
});
});

Resources