sharing data between templates in angular, how to? - javascript

I have 2 template, in 1st template I use the function and after its successful implementation,i want to get data in a 2nd template. How can I do it? Both template using the same controller
My 1st template:
<form ng-submot='vm.search(q)' class="header-search">
<input class="header-search-input" ng-model='q' placeholder="Search">
<button type="button" class="btn btn-default ic-search" aria-label="Left Align" ng-click='vm.search(q)'>
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</button>
</form>
My 2nd template:
<h3>Результат поиска по запросу: {{q}}</h3>
<ul ng-repeat='item in items'>
<li>{{item.name}}</li>
</ul>
controller:
(function() {
'use strict';
angular
.module('beo.layout.controllers')
.controller('NavbarController', NavbarController);
NavbarController.$inject = ['$scope', '$http', '$location'];
function NavbarController($scope, $http, $location) {
var vm = this;
vm.logout = logout;
vm.search = search;
function search(q) {
$http.post('/api/v1/search/', {
q: q
}).success(function(data) {
$location.path('/search/')
$scope.q = q;
$scope.items = data;
})
}
})();

I would suggest you use cache for best practice. While you are using two templates and when you load your another template it's also going to reload your controller. If you are done with your search in first template then you can save result in cache and then when you redirect to template then just look into that if there is any result then just show it.

Setting $scope equal to the value of the input field should allow you to pass the data from the 1st template to the 2nd template.

Use ng-if to switch between two piece of HTMl snippets. By the way, template is a special term in Angular, indicating something like template in a directive.
For example:
<div ng-if="!items">
<form ng-submot='vm.search(q)' class="header-search">
<input class="header-search-input" ng-model='q' placeholder="Search">
<button type="button" class="btn btn-default ic-search" aria-label="Left Align" ng-click='vm.search(q)'>
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</button>
</form>
</div>
<div ng-if="items">
<h3>Результат поиска по запросу: {{q}}</h3>
<ul ng-repeat='item in items'>
<li>{{item.name}}</li>
</ul>
</div>
After you have retrived the data successfully, i.e., the variable items is true, Angular will switch to the 2nd template for you.
NOTE: you are using vm (this) and $scope on the controller at them same time, which is not encouraged.

To do it "The angular way" you should use directives. Within directives you can require controllers of other directives so you can share data as you need. An example is here: How to require a controller in an angularjs directive

You can get data after a user clicks on the search button, in your code i.e. through vm.search function in the controller which should be used to get data through an api call check this below example.
angular
.module('demo', [])
.controller('DefaultController', DefaultController);
function DefaultController() {
var vm = this;
vm.items = [];
vm.search = search;
function search(searchTerm) {
// perform ajax call and set data here on vm.items property
vm.items = data;
}
}
var data = [
{ name: 'Audi' },
{ name: 'Lamborghini' },
{ name: 'Jaguar' }
];
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<form name="searchForm" novalidate="novalidate" ng-submit="searchForm.$valid && ctrl.search(ctrl.searchTerm)">
<label for="searchBox">Search</label>
<input type="text" name="searchBox" ng-model="ctrl.searchTerm" ng-required="true">
<button ng-click="isSubmitted = true">Submit</button>
<span style="color: red;" ng-show="isSubmitted && searchForm.searchBox.$invalid">Search term is required</span>
</form>
<label ng-show="ctrl.items.length">Items matching your search</label>
<div ng-repeat="item in ctrl.items">
{{item.name}}
</div>
</div>
</div>

Related

How to make href in button inside collapse

I have a collapsed model which show more information about client, and insid it, I have a button, when I click, I don't get the informations of the specific client, I get data of all clients
<ion-list ng-repeat="x in names">
<a class="item item-icon-left " >
<i class="icon ion-android-arrow-dropdown-circle" ng-model="collapsed" ng-click="collapsed=!collapsed"></i>
{{x.Marque}}
</a>
<div ng-show="collapsed">
<table>
<thead >
<td>
<label> Code: </label> {{x.CodeClient}} <br/>
<label> Nom: </label> {{x.NomClient}} <br/>
<a class="button button-info" ui-sref="modifClient({CodeClient: x})" >
Enregistrer
</a>
...
app.js
$stateProvider.state('modifClient', {
url: '/modifClient',
templateUrl: 'templates/modifClient.html',
params: {CodeClient: null},
controller: 'ConsultClientCtrl'
});
app.controller("ConsultClientCtrl", function($scope, $http) {
$scope.loadClient = function(){
$http.get("http://localhost/deb/debut.php")
.success(function(data){
$scope.names = data;
});
}
});
modifClient.html
<ion-content class="padding" ng-controller="ConsultClientCtrl" ng-repeat="x in names | filter: {CodeClient: thisX}" >
<ion-list ng-repeat="x in names | filter: {CodeClient: thisX}: true">
<div class="item item-divider center-text" ng-model="CodeClient"> {{x.CodeClient}} </div>
......
You have to use the framework's href: ngHref or ng-click
<a class="button button-info" ng-href="/modifClient"> ...
LE: I've created a pen for this case. The problem is that you have an <a> in <a> and when you click it then it get's confused.
So I've changed the <a ng-show="collapsed"> to <div ng-show="collapsed"> and now works as expected (see pen too).
If you are using Angular ui-router and modifClient is a state in your router, you better use the Angular ui-sref attribute instead of HTML href.
Your code would be :
<a class="button button-info" ui-sref="modifClient">
Edit:
If you want to pass an object param in the ui-sref you can do it like this:
<a class="button button-info" ui-sref="modifClient({CodeClient: x.CodeClient})">
And change your state settings to include a params object:
$stateProvider.state('modifClient', {
url: '/modifClient',
templateUrl: 'templates/modifClient.html',
params: {CodeClient: null},
controller: 'ConsultClientCtrl'
});
Note:
Note that you should also update your ConsultClientCtrl controller with a $scope.CodeClient variable so it can be updated from the ui-sref.
You can read How to pass parameters using ui-sref in ui-router to controller for further options.
Edit 2:
After reading your last Edit, I can see that you don't have a CodeClient variable in your controller, so update it like this:
app.controller("ConsultClientCtrl", function($scope, $http) {
$scope.CodeClient = null;
$scope.loadClient = function(){
$http.get("http://localhost/deb/debut.php")
.success(function(data){
$scope.names = data;
});
}
});
And in your HTML just use:
<div class="item item-divider center-text"> {{CodeClient}} </div>
Without <ion-list ng-repeat ...> and the filter part as we already got the CodeClient variable in the Controller.
Thanks for every one,This is the solution I found:
change the code of the button:
<a class="button button-info" ng-href="#/modifClient/{{x.CodeClient}}" >
Enregistrer </a>
And in app.js, I had to use $state:
app.controller("ConsultClientCtrl", function($scope, $http,$state) {
$scope.loadClient = function(){
$http.get("http://localhost/deb/selectClient.php")
.success(function(data){
$scope.thisX = $state.params.CodeClient;
$scope.names = data;
});
}
});
And changing the state provider to this:
$stateProvider.state('modifClient', {
url: '/modifClient/:CodeClient',
templateUrl: 'templates/modifClient.html',
controller: 'ConsultClientCtrl'
});

How to populate data in browser window?

I have a data (list of files) in $scope.data from searchFactory , Now i want to display files in browser window. How can i achieve this task ?
ctrl.js
$scope.serverFiles = function (){
$window.open($scope.data = angular.copy(searchFactory.getDitLogs()));
console.log("got function working",$scope.data);
};
main.html
<button
type="button"
class="btn btn-info btn-lg"
ng-click="serverFiles()"
style="margin-left: 10px">
<span class="glyphicon glyphicon-folder-close"></span>
</button>
declare $scope.data = [] ; then bind it to your view , so any changes it will reflect the changes . that is like this below
angular.module("app", [])
.controller('main', function($scope){
$scope.data = [];
$scope.serverFiles = function(){
//dummy record
for(i=0;i<10; i++)
$scope.data.push({sn:(i+1),name:'name of file'+i, file:'file info'+i});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="main">
<ul>
<li ng-repeat = "info in data"><strong>{{info.sn}}</strong> {{info.name}} </li>
</ul>
<button ng-click="serverFiles()">Fetch Record</button>
</div>
</div>
anytime you manipulate the $scope.data the view would be updated

ng-repeat throwing invalid Expression

I'm a total angular noob and trying to create a simple test app where. I'd like to read out some userdata in a partial. The user data is in my event controller. I assign the event controller to a form in my new.html partial after navigating to #/new via a route controller.
The error I get when trying to loop through the users in my partial is "Error: ngRepeat:iexp Invalid Expression". I can't figure out how to ng-repeat through those users.
Any thoughts?
My index.html:
<div class="container" style="width: 500px; margin: 0 auto;">
<ul class="nav nav-pills" ng-controller="NavigationController as navigationCtrl">
<li ng-class="{active: navigationCtrl.isActive(1)}">
Home
</li>
<li ng-class="{active: navigationCtrl.isActive(2)}">
Nieuw
</li>
<li ng-class="{active: navigationCtrl.isActive(3)}">
Nog een
</li>
</ul>
<div ng-view></div>
</div>
My new.html partial
<form action="" ng-controller="EventController as event">
<div ng-repeat="users as user">
<label>Name</label>
<input type="text" class="form-control" name="name" ng-model="user.name">
<br>
<label>Emailaddress</label>
<input type="email" class="form-control" name="email" ng-model="user.email">
<br>
<input class="btn btn-default" type="submit" ng-click="event.addEvent($event)" value="Klik">
</div>
</form>
And last: My angular code
(function () {
var app = angular.module('testApp', ['ngRoute']);
app.controller('NavigationController', ['$scope', '$route', function ($scope, $route) {
$scope.$route = $route;
this.activeTab = 1;
this.setActiveTab = function (tab) {
this.activeTab = tab;
};
this.isActive = function (tab) {
if ($route.current && $route.current.activeTab) {
return $route.current.activeTab === tab;
}
return false;
};
}]);
app.controller('EventController', ['$scope', '$controller', function ($scope, $controller) {
this.users = [
{name: 'aa'},
{name: 'bb'}
];
this.addEvent = function (e) {
e.preventDefault();
console.log(this);
};
}]);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/new', {
templateUrl: 'partials/new.html',
controller: 'NavigationController',
activeTab: 2
}).
when('/another', {
templateUrl: 'partials/another.html',
controller: 'NavigationController',
activeTab: 3
}).
otherwise({
redirectTo: '/',
controller: 'NavigationController',
activeTab: 1
});
}]);
})();
I've tried changing this for $scope to no avail.
You write ng-repeat in wrong way in your new.html partial page
it should be like
new.html
<div ng-repeat="user in users">
Correct syntax for ng-repeat is
<element ng-repeat="item in [1,2,3]">
Also you can use things like track by $index if you have duplicated values in your collection like [1,1,1].
Ref. https://docs.angularjs.org/api/ng/directive/ngRepeat
There are few issues in your code. Please change all this references to $scope and then quickly fix below html code:
<div ng-repeat="user in users">
It should work but update me otherwise also.
Working demo for your reference (route codes excluded for demo purpose only)
thanks,
Ashok
you have not written ng-repeat in right way change it to:
<div ng-repeat="user in users">

AngularJS Dynamic Template with indexed scope variable arrays

I'm using AngularJS and trying to create a form where I can dynamically add new inputs, similar to this fiddle: http://jsfiddle.net/V4BqE/ (Main HTML below, working code in fiddle).
<div ng-app="myApp" ng-controller="MyCtrl">
<div add-input>
<button>add input</button>
</div>
</div>
I would like to be able to use a HTML template for my form since the input I'm adding is ~300 lines long. My issue is I cannot figure out how to index the scope variable containing the data when used in a template. I've tried to make my own modified version of the above code on plnkr http://plnkr.co/edit/4zeaFoDeX0sGTuBMCQP2?p=info . However, when I click the button no form elements appear.
Online (plnkr) I get a 404 not found for my template.html, but I think that is just a plnkr limitation. On my machine with a Python HttpServer I get an Error: [$parse:syntax] for the $templateRequest and a TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. when using the $http.get method.
Any advice for getting the indexed scope variable array to work with an external html file?
Thanks, JR
Edit: Update plnkr link
You can do it without directive & external template
what you are trying to do does not require a directive (it actually much simple with the basic angularjs tools)
http://plnkr.co/edit/LVzGN8D2WSL2nR1W7vJB?p=preview
html
<body>
<div class="container" ng-app="myApp" ng-controller="MyCtrl">
<button class="btn btn-primary" type="button" ng-click="addPhoneInput()">add input</button>
<form>
<div ng-repeat="item in telephoneNumbers">
<hr>
<input type="text" ng-model="item.phone">
</div>
</form>
<hr>
<div class="well">
<h4>Phone Numbers,</h4>
<p ng-repeat="item in telephoneNumbers">{{item.phone}}</p>
</div>
</div>
</body>
js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function($scope) {
// Define $scope.telephone as an array
$scope.telephoneNumbers = [];
$scope.addPhoneInput = function() {
$scope.telephoneNumbers.push({});
};
// This is just so you can see the array values changing and working! Check your console as you're typing in the inputs :)
$scope.$watch('telephoneNumbers', function(value) {
console.log(value);
}, true);
}]);
If you insist using a directive,
http://plnkr.co/edit/BGLqqTez2k9lUO0HZ5g1?p=preview
phone-number.template.html
<div>
<hr>
<input type="text" ng-model="ngModel" >
</div>
html
<body>
<div class="container" ng-app="myApp" ng-controller="MyCtrl">
<button class="btn btn-primary" type="button" ng-click="addPhoneInput()">add input</button>
<form>
<phone-number ng-repeat="item in telephoneNumbers" ng-model="item.phone"></phone-number>
</form>
<hr>
<div class="well">
<h4>Phone Numbers,</h4>
<p ng-repeat="item in telephoneNumbers">{{item.phone}}</p>
</div>
</div>
</body>
js
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function($scope) {
// Define $scope.telephone as an array
$scope.telephoneNumbers = [];
$scope.addPhoneInput = function() {
$scope.telephoneNumbers.push({});
};
// This is just so you can see the array values changing and working! Check your console as you're typing in the inputs :)
$scope.$watch('telephoneNumbers', function(value) {
console.log(value);
}, true);
}]);
app.directive('phoneNumber', function(){
return {
replace:true,
scope: {
ngModel: '=',
},
templateUrl: "phone-number.template.html"
}
});

AngularJS : ng-repeat inside a directive masks the directive's controller

I have an isolated scope directive that has its own controller.
The directive's template has access to that controller, except inside an ng-repeat where the entire controller is out of scope.
I don't know how to fix it.
If you have an ng-repeat inside an ng-controller, children of the ng-repeat inherit the functions of the ng-controller.
I would have thought that would be the case with custom directives, too - children inside the ng-repeat could still see the directive's controller - but as far as I can tell, they can't.
I'm still getting up to speed with Angular, so a nudge in the right direction would be appreciated. A downright answer would be appreciated even more. Something to do with transclusion? With which is getting compiled first?
Here is the directive:
angular.module('surverApp')
.directive('surveyItems', function () {
return {
restrict: 'E',
scope: {
itemList: '=',
query: '='
},
templateUrl: 'views/directives/survey-items.html',
replace: true,
controller: 'SurveyItemsCtrl',
controllerAs: 'ctrl',
bindToController: true
};
})
.controller('SurveyItemsCtrl', function(){
var ctrl = this;
ctrl.disableEdit = true;
ctrl.disableToolbar = false;
ctrl.showForm = false;
ctrl.showDuplicate = false;
ctrl.showTrash = false;
ctrl.deleteItem = function(item) {
console.log('ctrl.item in DELETE ITEM' ,item)
.... functions removed for brevity
};
});
And here is its template. None of its functions fire.
<div>
<pre>ctrl = {{ctrl | json}}</pre> <<<<<=== THIS SHOWS THE CONTROLLER IS IN SCOPE
<div ng-repeat="item in ctrl.itemList | filter:ctrl.query" class="ubi-box container-fluid">
<pre>ctrl = {{ctrl | json}}</pre> <<<<<=== THIS SHOWS THE CONTROLLER IS NOT IN SCOPE
<standard-right-toolbar ctrl="ctrl"></standard-right-toolbar>
<h4>{{item.name}}</h4>
<div ng-show="ctrl.showForm" class="ubi-box container-fluid">
<!-- <survey-form model="item" disable-edit="ctrl.disableEdit" reset-fn="item = ctrl.resetUpdateFn(item)" submit-fn="ctrl.submitUpdateFn()" close-fn="ctrl.hideFormFn()"></survey-form> -->
<survey-form model-el="item" disable-edit-el="ctrl.disableEdit" reset-fn="ctrl.resetUpdateFn(form,model)" submit-fn="ctrl.submitUpdateFn(form)" close-fn="ctrl.hideFormFn()"></survey-form>
<pre>model = {{item | json}}</pre>
</div>
<div ng-show="ctrl.showDuplicate" class="ubi-box container-fluid">
<standard-right-close-bar close-fn="ctrl.hideDuplicateFn()"></standard-right-close-bar>
<h4 class="col-xs-12">Duplicating a survey will copy all the details and questions over to a new survey.</h4>
<h3 class="col-xs-10">Click the copy button to procede.</h3>
<button class="btn btn-lg btn-primary" type="button" ng-click="ctrl.copy(item)" title="Duplicate">
<span class="glyphicon glyphicon-duplicate"></span>
</button>
</div>
<!-- <div ng-show="ctrl.showTrash" class="ubi-box container-fluid"> -->
<div ng-show="ctrl.showTrash" class="ubi-box container-fluid">
<standard-right-close-bar close-fn="ctrl.hideTrashFn()"></standard-right-close-bar>
<h4 class="col-xs-12">Deleting a survey is a very serious matter. It will permanently remove every question and every answer in every questionnaire in every edition in the survey.</h4>
<h3 class="col-xs-10">Click the trashcan only if you are sure!</h3>
<button class="btn btn-lg btn-danger" type="button" ng-click="ctrl.deleteItem(item)" title="Delete">
<span class="glyphicon glyphicon-trash"></span>
</button>
</div>
</div>
<div>
PS I had it working fine inside an ng-controller. But then I read ng-controllers are being outlawed in Angular 2.0, so I thought I'd get in some practice using directive controllers rather than ng-controllers and I wrapped the ng-repeat in a directive instead of an ng-controller.
So far, so stumped . . .

Categories

Resources