Okey, please be patience. I only know jquery and I heard that use AngularJS is something that I should try.
So, what I need to to is visit a page on my local host "../asp/fases/fases-controler.asp"
parse the json that this page shows me ( that is something like this: { "fasekind": [ "AAA", "BBB", "CCC" ] } ) and then mount on client side a list like this:
<ul>
<li><input type="checkbox" /> <label>AAA</label></li>
<li><input type="checkbox" /> <label>BBB</label></li>
<li><input type="checkbox" /> <label>CCC</label></li>
</ul>
I do need a help with this. I only know the jQuery way. I have seen so many tutorials but I don't get it. I receive always Uncaught ReferenceError: $http is not defined and other erros messages.
I don't want someone to do that for me, I just need to figure out how it works.
js controller that I try... it does not work at all.
var app = angular.module("app", []);
app.controller("AppCtrl", function ($http) {
var app = this;
$http.get("../asp/fases/fases-controler.asp")
.success(function (data) {
app.fases = data;
})
})
CONTROLLER
var app = angular.module("app", []);
app.controller("AppCtrl", function ($scope, $http) {
$http.get("../asp/fases/fases-controler.asp")
.success(function (data) {
$scope.fases = data;
});
});
HTML
<div class="grid-12-12" ng-app='currentApp' ng-controller='ACtrl'>
<label>Fases <em class="formee-req">*</em>
</label>
<ul class="formee-list">
<li ng-repeat="list in fases">
<input name="checkbox-01" type="checkbox" />
<label>{{list}}</label>
</li>
</ul>
</div>
JSFIDDLE
I found an answer here, it was missing the JSON parse I guess. This is what I did:
JSON
{
"fasekind": [
"AAA",
"BBB",
"CCC"
]
}
CONTROLLER
function FetchCtrl($scope, $http) {
$scope.url = 'fases/fases-controler.asp';
$http.get($scope.url).success(function (data, status) {
$scope.fasekind = data.fasekind;
}).error(function (data, status) {
$scope.response = 'Request failed';
});
}
HTML
<div class="grid-12-12" ng-controller='FetchCtrl'>
<label>Fases <em class="formee-req">*</em>
</label>
<ul class="formee-list">
<li ng-repeat="foo in fasekind">
<input name="checkbox-01" type="checkbox" />
<label>{{foo}}</label>
</li>
</ul>
</div>
Related
i tried to make login form with angular js
i have list of user in json file but i can't comapre with the input text from login form
User.json :
[{
"username": "user1",
"password": "pass1"
}, {
"username": "user2",
"password": "pass2"
}, {
"username": "user3",
"password": "pass3"
}, {
"username": "user4",
"password": "pass4"
}]
script.js
var app1 = angular.module('app1', []);
var app2 = angular.module('app2', []);
var app = angular.module('app', ['app1', 'app2']);
app1.controller('jsonCtrl', function($scope, $http) {
$http.get('data.json')
.then(function(res) {
$scope.users = res.data;
});
});
app2.controller('formCtrl', function($scope) {
$scope.login = function() {
if ($scope.username == 'test' && $scope.password == 'test') {
alert('valid username/password ' + $scope.username);
alert('user from json ' + $scope.users);
} else {
alert('invalid username/password ' + $scope.username);
}
};
});
index.html
<!DOCTYPE html>
<html lang="en">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="script.js"></script>
<body ng-app="app">
<div ng-controller="formCtrl">
<form name="form">
First Name:<br>
<input type="text" ng-model="username"><br>
Last Name:<br>
<input type="text" ng-model="password">
<br><br>
<button ng-click="login()">LOGIN</button>
</form>
</div>
<div ng-controller="jsonCtrl">
<ul>
<li ng-repeat="user in users">
{{user.username}} / {{user.password}}
</li>
</ul>
</div>
</body>
</html>
the problem is replace if ($scope.username == 'test' && $scope.password == 'test') with anything compare with json
this my code : Plunker
You were using two different scopes across application. I moved all your markup under the same controller, so that is more simple manage the bindings.
Take a look at this plnkr
var app = angular.module('app', []);
app.controller('formCtrl', function($scope, $http) {
$http.get('data.json')
.then(function(res) {
$scope.users = res.data;
});
$scope.login = function() {
var u = $scope.users.filter((item) => {
return item.username == $scope.username;
});
if (u[0] && u[0].password == $scope.password) {
alert('correct');
} else {
alert('wr0ng');
}
};
});
<div>
<form name="form">
First Name:
<br>
<input type="text" ng-model="username">
<br> Last Name:
<br>
<input type="text" ng-model="password">
<br>
<br>
<button ng-click="login()">LOGIN</button>
</form>
</div>
<div>
<ul>
<li ng-repeat="user in users">
{{user.username}} / {{user.password}}
</li>
</ul>
</div>
First of all, you should not authenticate user using clear text like that. Your server should do it with hashing table without knowing what is the real password.
Http.get is not synchronous which means that your application will continue its path without waiting for your data. In your plunker your formCtrl doesnt have access to jsonCtrl scope.
You should load your data in a service because it is initialised only once compared to the controller who are initialised everytime you load the page.
Finally you should start by looking at ui.router resolve, it allow you to load your data to your service before the page is displayed which will allow you to compare later.
I have a parent controller with some children controllers, and I want them all to share the same data that I retrieve from an Api service.
Controllers:
var app = angular.module('mymodule',[]);
app.controller('main', ['$scope', 'Api', function($scope, Api) {
var getList1 = Api.getList1()
.then(function(resp) {
$scope.list1 = resp.data;
});
var getList2 = Api.getList2()
.then(function(resp) {
$scope.list2 = resp.data;
});
}]);
app.controller('child1', ['$scope', function($scope) {
$scope.list1 = ?
$scope.list2 = ?
}]);
app.controller('child2', ['$scope', function($scope) {
$scope.list1 = ?
}]);
View:
<div ng-controller="main">
<ul>
<li ng-repeat="list in list1">
{{list.item}}
</li>
</ul>
<div ng-controller="child1">
<ul>
<li ng-repeat="list in list1">
{{list.item}}
</li>
</ul>
<ul>
<li ng-repeat="list in list2">
{{list.item}}
</li>
</ul>
</div>
<div ng-controller="child1">
<ul>
<li ng-repeat="list in list1">
{{list.item}}
</li>
</ul>
</div>
</div>
I tried to use this solution with Angular’s events mechanism ($on, $emit).
The problem was that I had to figure out which child controller is active and send the data when the promise has resolved. It ends with ugly spaghetti code...
Well, the best way is to use a service to have your API handling atomar placed inside your application. This fiddle shows you how you could achieve what you try to. By using AngularJS services you will be able to share the same data, objects and functions between controllers and let them interact with eachother. This is undepending on the amount of your controllers inside your application.
The following example is a full working API service with real HTTP-Requests and a real AngularJS service handling. It will help you by implement such logic inside your application. Please dont forget to check out the fiddle demo.
View
<div ng-controller="MyCtrl">
<h1>
MyCtrl
</h1>
<button ng-click="clearData()">
Clear data by using MyCtrl
</button>
<div ng-repeat="user in users">
<p>
Username: {{ user.name }}
</p>
</div>
</div>
<br /><br />
<div ng-controller="MyOtherCtrl">
<h1>
MyOtherController
</h1>
<button ng-click="clearData()">
Clear data by using MyOtherController
</button>
<div ng-repeat="user in users">
<p>
Username: {{ user.name }}
</p>
</div>
</div>
AngularJS Application
var myApp = angular.module('myApp',[]);;
myApp.controller('MyCtrl', function ($scope, apiService) {
$scope.users = apiService.getResponseData();
$scope.$watch(function () { return apiService.getResponseData()}, function (newValue, oldValue) {
$scope.users = newValue
});
$scope.clearData = function () {
apiService.reset();
}
});
myApp.controller('MyOtherCtrl', function ($scope, apiService) {
apiService.loadData();
$scope.$watch(function () { return apiService.getResponseData()}, function (newValue, oldValue) {
$scope.users = newValue
});
$scope.clearData = function () {
apiService.reset();
}
})
myApp.service('apiService', function ($http) {
var responseData = null;
return {
loadData: function () {
return $http({
url: 'https://jsonplaceholder.typicode.com/users',
method: 'GET'
}).then(function (response) {
responseData = response.data
});
},
getResponseData: function () {
return responseData
},
reset: function () {
responseData = null;
}
}
});
As your data is in the scope of the parent controller, you can access it in children controllers with $scope.$parent:
app.controller('child1', ['$scope', function($scope) {
$scope.list1 = $scope.$parent.list1;
$scope.list2 = $scope.$parent.list2;
}]);
Write your children as directives, and then you can inject data on the scope.
yourModule.directive('child1', function() {
return {
scope: {list1:'=',
controller: function (scope) {
//not sure you even need a controller, but it might look like this
scope.doSomething = function() {
//access scope.list1 here
}
},
template: '<ul><li ng-repeat="list in list1">{{list.item}}<li><ul>'
}
}
Usage:
<child1 list1="list1"></child1>
Explanation :
I created a header directive for my angular application. By using this directive we are loading template by using templateUrl property of attribute based on some conditions.
html :
<div header></div>
directive :
app.directive('header', ['LS', function(LS) {
'use strict';
var user = LS.getData() === 'true' ? true : false;
return {
restrict: 'A',
replace: true,
templateUrl: user ? 'withlogin-header.html' : 'withoutlogin-header.html',
controller: ['$scope', 'LS', function ($scope,LS) {
$scope.login = function() {
return LS.setData(true);
}
$scope.logout = function() {
return LS.setData(false);
}
}]
}
}]);
withlogin-header.html :
<div>
User is logged in !!!
<input type="button" ng-click="logout()" value="Logout"/>
</div>
withoutlogin-header.html :
<div>
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
Requirement :
We have to display different headers based on the user roles.i.e if user was not login then we have to display normal header with login button and if user already login then we have to display different header with logout button.
Challenge we are facing :
header directive is not working properly. when we click on the login button from withoutlogin-header.html it not loading another template withlogin-header.html based on the defined condition in the templateUrl property of the directive.
I tried so far :
Plnkr : http://plnkr.co/edit/w7AyUjSNA1o5NJp6tD1p?p=preview
Any immediate help will be highly appreciable. Thanks
Checkout this plunker i have created an amazing directive for fetching dynamic header template from server.
I have made some little changes to your code as well.
Hope it will help you surely...
http://plnkr.co/edit/GWIozm?p=preview
You could put the templates into a single directive:
html:
<div ng-if="!isLoggedIn">
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
<div ng-if="isLoggedIn">
Hey buddy, log in !!!
<input type="button" ng-click="login()" value="Login"/>
</div>
directive:
app.directive('header', function() {
'use strict';
return {
restrict: 'A',
replace: true,
templateUrl: 'withlogin-header.html',
controller: ['$scope', 'LS', function ($scope,LS) {
$scope.isLoggedIn = false;
$scope.login = function() {
LS.setData(true);
$scope.isLoggedIn = LS.getData() === 'true';
}
$scope.logout = function() {
LS.setData(false);
$scope.isLoggedIn = LS.getData() === 'true';
}
}]
}
});
EDIT: or if you want to stick to separate template files, you could use ng-include as #Stepan Kasyanenko mentioned.
I have a similar situation in that I display a certain list of URLS for anonymous users and a different list once the user is logged in. I approached this solution by adding a $watch on the user's logged in property as well as the user's selected language at login (coding for multiple countries)
$scope.$watch(function () {
return User.language;
}, function (newVal, oldVal) {
if (newVal === undefined) {
newVal = "english";
}
navBarCtrl.AnonymousUrls = [];
navBarCtrl.AuthenticatedUrls = [];
$http.get('http://localhost:#####/Urls/' + newVal)
.success(function (data) {
navBarCtrl.sortAllUrlLists(data, navBarCtrl.AnonymousUrls, navBarCtrl.AuthenticatedUrls);
});//end of http get
}, true);
$scope.$watch(function () {
return User.isAuthenticated;
}, function (newVal, oldVal) {
navBarCtrl.isUserAuthenticated = newVal;
}, true);
These two properties are set when the user logs in using the following
this.submit = function () {
var data = angular.toJson(submitForm.credentials);
$http.post("/submitLogin", data)
.success(function (data, status, headers, config) {
submitForm.user.isAuthenticated = true;
submitForm.user.username = data.username;
submitForm.user.location = data.location;
submitForm.user.dsn = data.dsn;
submitForm.user.language = data.language;
$location.path(User.intededPath);
})
.error(function (data, status, headers, config) {
submitForm.user.isAuthenticated = false;
alert("fail");
}); // end of $http.post
} // end of submit
Finally in the view I have the following to display the correct list based on whether or not the user is logged in
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li ng-class="{'dropdown':urlList.length>1}" ng-show="!navBarCtrl.isUserAuthenticated" ng-repeat="urlList in navBarCtrl.AnonymousUrls">
{{urlList[0].Label}}
<ul class="dropdown-menu" ng-if="urlList.length>1">
<li ng-repeat="url in urlList" ng-if="$index > 0">
{{url.Label}}
</li>
</ul>
{{urlList[0].Label}}
</li>
<li ng-class="{'dropdown':urlList.length>1}" ng-show="navBarCtrl.isUserAuthenticated" ng-repeat="urlList in navBarCtrl.AuthenticatedUrls">
{{urlList[0].Label}} <b class="caret"></b>
<ul class="dropdown-menu" ng-if="urlList.length>1">
<li ng-repeat="url in urlList" ng-if="$index > 0">
{{url.Label}}
</li>
</ul>
{{urlList[0].Label}}
</li>
</ul>
</div>
Hopefully that might give you an idea on how to get yours working.
I was given the following code to use to get the data I need, but it is not working for me. What am I doing wrong here. I have tried many things from the Angular.js docs and other stack overflow posts, but nothing has worked for me.
someurl
header: Content-Type = application/json
Pass in the following json:
{
"userID": "SomeUSER",
"password": "SomePSWD"
}
Below is the code I am using and it is not working.
function getGroup($scope, $http) {
$http.get('SOMEURL?callback=JSON_CALLBACK&userID=SomeUSER&password=SomePSWD ').
success(function(data) {
$scope.group = data;
});
}
this angularjs demo app show how to use http.jsonp
var httpJsonDemoController = angular.module('HttpJsonDemo', []);
httpJsonDemoController.controller('DataController', ['$scope', '$http', function($scope, $http) {
$http.jsonp("http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Waseem%20Hero").
success(function(data) {
$scope.data = data;
$scope.name = data.name;
$scope.salutation = data.salutation;
$scope.greeting = data.greeting;
}).
error(function (data) {
$scope.data = "Request failed";
});
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>
<div id="wrapper" ng-app="HttpJsonDemo">
<div ng-controller="DataController">
<pre ng-model="data">
{{data}}
</pre>
<input ng-model='name' />
{{name}}
<input ng-model='salutation' />
{{salutation}}
<input ng-model='greeting' />
{{greeting}}
</div>
</div>
I want to use a controller on 2 seperated HTML elements, and use the $rootScope to keep the 2 lists in sync when one is edited:
HTML
<ul class="nav" ng-controller="Menu">
<li ng-repeat="item in menu">
{{item.title}}
</li>
</ul>
<div ng-controller="Menu">
<input type="text" id="newItem" value="" />
<input type="submit" ng-click="addItem()" />
<ul class="nav" ng-controller="Menu">
<li ng-repeat="item in menu">
{{item.title}}
</li>
</ul>
</div>
JS
angular.module('menuApp', ['menuServices']).
run(function($rootScope){
$rootScope.menu = [];
});
angular.module('menuServices', ['ngResource']).
factory('MenuData', function ($resource) {
return $resource(
'/tool/menu.cfc',
{
returnFormat: 'json'
},
{
getMenu: {
method: 'GET',
params: {method: 'getMenu'}
},
addItem: {
method: 'GET',
params: {method: 'addItem'}
}
}
);
});
function Menu($scope, MenuData) {
// attempt to add new item
$scope.addNewItem = function(){
var thisItem = $('#newItem').val();
MenuData.addItem({item: thisItem},function(data){
$scope.updateMenu();
});
}
$scope.updateMenu = function() {
MenuData.getMenu({},function(data){
$scope.menu = data.MENU;
});
}
// get menu data
$scope.updateMenu();
}
When the page loads, both the UL and the DIV display the correct contents from the database, but when i use the addNewItem() method only the DIV gets updated.
Is there a better way to structure my logic, or can I do something to make sure the $scope.menu in the UL gets updated at the same time?
Here's an example of something similar: http://plnkr.co/edit/2a55gq
I would suggest to use a service that holds the menu and its methods. The service will update the menu which is referenced by the controller(s).
See a working plunker here: http://plnkr.co/edit/Bzjruq
This is the sample JavaScript code:
angular
.module( 'sampleApp', [] )
.service( 'MenuService', [ '$rootScope', function( $rootScope ) {
return {
menu: [ 'item 1' ],
add: function( item ) {
this.menu.push( item );
}
};
}])
.controller( 'ControllerA', [ 'MenuService', '$scope', function( MenuService, $scope ) {
$scope.menu = MenuService.menu;
$scope.addItem = function() {
MenuService.add( $scope.newItem );
};
}]);
And the sample Html page:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="sampleApp">
<div ng-controller="ControllerA">
<ul>
<li ng-repeat="item in menu">{{item}}</li>
</ul>
<input type="text" ng-model="newItem" /><input type="submit" ng-click="addItem()" />
</div>
<div ng-controller="ControllerA">
<ul>
<li ng-repeat="item in menu">{{item}}</li>
</ul>
</div>
</body>
</html>
Edit:
Here is the updated version plunker. it works in two controller.
Main idea is using service and broadcast to sync the data with the directive.
app.service('syncSRV', function ($rootScope) {
"use strict";
this.sync = function (data) {
this.syncData = data;
$rootScope.$broadcast('updated');
};
});
app.controller('MainCtrl1', ['$scope', function ($scope) {
}])
.controller('MainCtrl2', ['$scope', function ($scope) {
}]);
app.directive('sync',function (syncSRV) {
"use strict";
return {
template: '<div><input ng-model="syncdata" type="text" /></div> ',
controller: function ($scope, $element, $attrs) {
$scope.$watch('syncdata', function (newVal, oldVal, $scope) {
syncSRV.sync(newVal);
}, true);
}
};
}).directive('dataview', function (syncSRV) {
"use strict";
return {
template: '<div>Sync data : {{data}}</div> ',
controller: function ($scope, $element, $attrs) {
$scope.$on('updated', function () {
$scope.data = syncSRV.syncData;
});
}
};
});
<div ng-controller="MainCtrl1">
<fieldset>
<legend> Controller 1</legend>
<div dataview></div>
<div sync></div>
</fieldset>
</div>
<div ng-controller="MainCtrl2">
<fieldset>
<legend> Controller 2</legend>
<div dataview></div>
<div sync></div>
</fieldset>
</div>
Here is what I would do for this case.
I will create a directive for
<ul class="nav" ng-controller="Menu">
<li ng-repeat="item in menu">
{{item.title}}
</li>
</ul>
so once item is updated, it will be updated in both directive.
small example
I just want to update and simplify the selected answer. It seems you can reduce this by deleting this line:
$rootScope.$broadcast( 'MenuService.update', this.menu );
and this chunk:
$scope.$on( 'MenuService.update', function( event, menu ) {
$scope.menu = menu;
});
The reason being, we are already using a Service, and that basically binds the two identical controllers, so no need to use $rootScope.$broadcast and add an observable.
Working plunk here:
http://plnkr.co/edit/1efEwU?p=preview
You only need to link the service, when I refactor the code I was able to reduce it to 13 lines instead of 22.