HTML button and controller not connecting - javascript

Trying to delete a list with an ng-click but the html and controller do not appear to communicate.
<div class="list-group">
<span ng-repeat="list in vm.lists"
class="list-group-item">
<a class="btn btn-primary pull-right" ng-click="vm.elim(list)">
<i class="glyphicon glyphicon-trash"></i>
</a>
<a class="btn btn-primary pull-right" ui-sref=
"lists.view({ listId:list._id })">
<i class="glyphicon glyphicon-edit"></i>
</a>
<h4 class="list-group-item-heading" ng-bind="list.name"></h4>
</span>
</div>
function elim(list) {
alert("works");
if ($window.confirm('Are you sure you want to delete?')) {
vm.list.$remove($state.go('lists.list'));
}
}
There should at least be an alert when the icon is clicked, but nothing happens. Suggestions?

Like Esteban said,Your elem function should be a part of scope variable like
$scope.vm.elem = function(){};

It looks like your function is not inside the $scope variable. Using
$scope.vm.elim = function(list){
...
}
should be enough.

Does your controller has below lines of code?
var vm = this;
vm.elm = function (list) {
alert("works");
if ($window.confirm('Are you sure you want to delete?')) {
vm.list.$remove($state.go('lists.list'));
}
};
If possible show us your controller code.

Here is a working example with ng-click:
<html >
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="obj in objs">
{{obj.name}}
<button ng-click="click(obj.id)">Delete</button>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script>
var app = angular.module('app', []);
app.controller('ctrl', function($scope){
$scope.objs = [{id: 1, name:"Darin"},{id: 2, name:"Jake"},{id: 3, name:"Todd"}]
$scope.click = function(id){
alert(id);
}
});
</script>
</html>

If you using controller as syntax in directive or in html.
e.g. <div ng-controller="YourController as ctrl">
<!--some html code-->
</div>
Or
angular.directive('test',function test() {
return {
restrict: 'E',
template: '<button ng-click="click">{{text}}</button>',
controller: YourController,
controllerAs: 'ctrl'
}
});
then in html view you can access controller properties as
<div ng-controller="YourController as ctrl">
<p>{{ctrl.someProperty}}</p>
</div>`
If you are not using controller as syntax then just remove vm from "vm.elim(list)" and "vm.lists"
Here is the great article for the same : https://toddmotto.com/digging-into-angulars-controller-as-syntax/

Assuming you want to keep the vm pattern just add on the controller,
vm.elim = elim;
At least should alert now.

Related

Using Angular controller inside Bootstrap Modal

[html]
<div class="modal fade" id="proj-edit" tabindex="-1" role="dialog" aria-hidden="true" data-remote="update.html">
<div class="modal-dialog">
<div class="modal-content" ng-controller="UpdateProjectController"></div>
</div>
</div>
[javascript]
var ProjectApp = angular.module('ProjectApp', ["ui.bootstrap"]);
ProjectApp.controller('UpdateProjectController', ["$scope","$http", function($scope, $http){
$scope.message = 'Please enter valid case number';
$scope.UpdateProject = function(){..do something..};
}]);
[update.html]
<div class="modal-header" >
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 id="myModalLabel" class="modal-title">Update Project</h4>
</div>
<div class="modal-body">
{{message}}
</div>
<div class="modal-footer">
<button type="submit" class="btn blue-soft" ng-click="UpdateProject()">Update</button>
<button type="button" class="btn default" data-dismiss="modal">Cancel</button>
</div>
Issue: Modal is being invoked from JQuery using .modal('show') method. My intention is to render the controller whenever the modal is opened. However, it seems that the modal does not recognise the controller and no message nor function from the controller can be executed. Appreciate your help on this matter. TQ.
HI please check the example
index.html
<!doctype html>
<html ng-app="plunker">
<head>
<script src="https://code.angularjs.org/1.2.18/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<form ng-submit="submit()">
<div class="modal-body">
<label>User name</label>
<input type="text" ng-model="user.user" />
<label>Password</label>
<input type="password" ng-model="user.password" />
<label>Add some notes</label>
<textarea rows="4" cols="50" ng-model="user.notes">
</textarea>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<input type="submit" class="btn primary-btn" value="Submit" />
</div>
</form>
</script>
<button class="btn" ng-click="open()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</body>
</html>
example.js
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.user = {
user: 'name',
password: null,
notes: null
};
$scope.open = function () {
$modal.open({
templateUrl: 'myModalContent.html', // loads the template
backdrop: true, // setting backdrop allows us to close the modal window on clicking outside the modal window
windowClass: 'modal', // windowClass - additional CSS class(es) to be added to a modal window template
controller: function ($scope, $modalInstance, $log, user) {
$scope.user = user;
$scope.submit = function () {
$log.log('Submiting user info.'); // kinda console logs this statement
$log.log(user);
$modalInstance.dismiss('cancel'); // dismiss(reason) - a method that can be used to dismiss a modal, passing a reason
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
},
resolve: {
user: function () {
return $scope.user;
}
}
});//end of modal.open
}; // end of scope.open function
};
for reference http://embed.plnkr.co/As959V/
The reason is update.html is quite a massive form and preferred not to
include inside main html file. So, the modal is basically calling the
remote html file.
Your remote html file and your modal file maybe using 2 different instances of the UpdateProjectController.
As said by Martijn, you coud use ui-bootstrap for this but if you don't want to, you could solve it by using a directive.
// directive to open the modal
var app = angular.module('myApp', []);
app.directive('myModal', myModal);
myModal.$inject = [];
function myModal() {
return {
restrict: 'A',
link: link
}
function link($scope, $element, $attributes) {
$element.click(function (event) {
angular.element($attributes.modalId).modal();
});
}
}
app.controller('ModalCtrl', ModalCtrl);
ModalCtrl.$inject = [];
function ModalCtrl() {
$scope.message = 'Please enter valid case number';
$scope.UpdateProject = function(){..do something..};
}
Modal is being invoked from JQuery using .modal('show') method.
So in case you use a button to do this render the modal, you could easily include the directive as an attribute to the modal instead of ng-click()
Lastly, include the modal file in your template file
<body>
<div ng-controller="UpdateProjectController">
// So in case you use a button to do this render the modal,
// you could easily include the directive as an attribute to the modal instead of ng-click()
<a href="javascript:;" my-modal modal-id="#modalUpdateProject">
Update Project
</a>
</div>
<!-- modals -->
<div ng-controller="ModalCtrl">
<ng-include src="'path/to/modal.html'"></ng-include>
</div>
<!-- end modals -->
</body>

How to implement multiple templates in one model using angularjs?

This is my code
var app = angular.module('drinks-app', ['ui.bootstrap']);
app.controller('MainCtrl', function($scope, Drink) {
'use strict';
Drink().then(function(drinks) {
$scope.drinks = drinks;
});
$scope.deleteItem = function(item) {
console.log("deleting item " + item.name);
};
});
app.factory('Drink', function($http) {
'use strict';
return function() {
return $http.get('drinks.json').then(function(response, status) {
return response.data;
});
};
});
app.directive('ngConfirm', function($modal, $parse) {
return {
// So the link function is run before ngClick's, which has priority 0
priority: -1,
link: function(scope, element, attrs) {
element.on('click', function(e) {
// Don't run ngClick's handler
e.stopImmediatePropagation();
$modal.open({
templateUrl: 'ng-delete-template',
controller: 'ngConfirmController',
resolve: {
message: function() {
return attrs.ngConfirm;
}
}
}).result.then(function() {
// Pass original click as '$event', just like ngClick
$parse(attrs.ngClick)(scope, {$event: e});
});
});
}
};
});
app.controller('ngConfirmController', function($scope, $modalInstance, message) {
$scope.message = message;
$scope.yes = function() {
$modalInstance.close();
};
$scope.no = function() {
$modalInstance.dismiss();
};
});
<!DOCTYPE html>
<html ng-app="drinks-app">
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js"></script>
<script src="script.js"></script>
<script type="text/ng-template" id="ng-delete-template">
<div class="modal-body">
<p>{{message}}</p>
</div>
<div class="modal-footer">
<button class="btn btn-link pull-left" ng-click="no()">No</button>
<button class="btn btn-primary pull-right" ng-click="yes()">Yes</button>
</div>
</script>
<script type="text/ng-template" id="ng-add-template">
<div class="modal-body">
<select >
<option value="emp" >emplopyee</option>
</select>
</div>
<div class="modal-footer">
<button class="btn btn-link pull-left">ADD</button>
</div>
</script>
</head>
<body ng-controller="MainCtrl">
<div class="container">
<button class="btn btn-small" type="button" ng-click="deleteItem(drink)" ng-confirm="Are you sure you want to delete '{{drink.name}}'">Delete</button>
<button class="btn btn-small" type="button" ng-click="deleteItem(drink)" ng-confirm="Are you sure you want to delete '{{drink.name}}'">Add</button>
</div>
</body>
</html>
Thsi is my plunker : http://plnkr.co/edit/Gm9lFsGb099w6kCMQoVY?p=preview
In the above code use ui.bootstrap for model popup (delete), now i want to use same model popup for display another template . that means i have two dropdown display list of employees and departments. In previous popup display delete information text only and templateUrl :- assign delete.html page statically. now i want to assign dynamic path to templateUrl in AngularJs model popup
You could pass template name from directive attribute & then place it over $modal.open's templateUrl option like
<button template-path="abc.html" class="btn btn-small" type="button"
ng-click="deleteItem(drink)" ng-confirm="Are you sure you want to delete '{{drink.name}}'">
Delete
</button>
Then in directive
templateUrl: attrs.templatePath || 'ng-confirm-template',
Demo Here

How do I refresh my ng-repeat?

I have a controller (called "catalogueController") that manages my search box and my search page. I have the controller initially set the page to automatically call the search function defined in "catalogueController" when the app loads to pre-load my array of items (called Inventory) to be repeated via ng-repeat in the page.
The process runs like this:
1. I submit the search form.
2. "catalogueController" will send the search term to my factory (called "Search").
3. "Search" will have a function which will make a server call to query my database for that particular search.
4. The database will send the results of the search to the "Search" factory.
5. The "Search" factory will send the results to the "catalogueController" controller.
6. "catalogueController" will update the $scope.Inventory to be equal to the new result that I was received.
My problem is that ng-repeat does not refresh itself to display my new and updated $scope.Inventory array. $scope.Inventory definitely is updated (I have made sure of this through various console logs).
I have also tried to use $scope.$apply(). It did not work for me.
Thank you in advance for your help!
Here is my code:
HTML Template
<form role="search" class="navbar-form navbar-left" ng-controller="catalogueController" ng-submit="search(search_term)">
<div class="form-group">
<input type="text" placeholder="Search" class="form-control" ng-model="search_term">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
<main ng-view></main>
catalogue.html partial
<div id="main" class="margin-top-50 clearfix container">
<div ng-repeat="items in inventory" class="row-fluid">
<div class="col-sm-6 col-md-3">
<div class="thumbnail"><img src="image.jpg" alt="..." class="col-md-12">
<div class="caption">
<h3>{{ items.itemName }}</h3>
<p>{{ items.description }}</p>
<p>Buy <a href="#" role="button" class="btn btn-default">More Info</a></p>
</div>
</div>
</div>
</div>
"app.js" Angular App
var myApp = angular.module('qcbApp', ['ngRoute', 'ngCookies', 'appControllers']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/login', {
templateUrl: 'html/partials/login.html',
controller: 'registrationController'
}).
when('/sign-up', {
templateUrl: 'html/partials/sign-up.html',
controller: 'registrationController'
}).
when('/catalogue', {
templateUrl: 'html/partials/catalogue.html',
controller: 'catalogueController'
}).
when('/', {
templateUrl: 'html/partials/qcbhome.html'
}).
otherwise({
redirectTo: '/'
});
}]);
"catalogueController" Controller
myApp.controller('catalogueController', ['$scope', 'Search', function($scope, Search) {
var time = 0;
var searchCatalogue = function(search) {
$scope.inventory = null;
console.log("Controller -- "+search);
Search.searchCatalogue(search)
.then(function(results) {
console.log(results);
$scope.inventory = results;
});
};
if(time == 0)
{
searchCatalogue('');
time++;
}
$scope.search = function(term) {
searchCatalogue(term);
}
}]);
"Search" Factory
myApp.factory('Search', ['$http', '$q', function($http, $q) {
function searchCatalogue(term) {
var deferred = $q.defer();
console.log("Factory -- "+term);
$http.post('/catalogue_data', {term: term}, {headers: {'Content-Type': 'application/json'}})
.success(function(result) {
console.log(result[0].SKU);
deferred.resolve(result);
console.log("Factory results -- "+result);
});
return deferred.promise;
}
return {
searchCatalogue: searchCatalogue
}; //return
}]);
I think the problem is the ng-repeat can not access the inventory in scope. You have to create a div which contains both the form and the ng-repeat.
The html should be:
<div ng-controller="catalogueController">
<!-- Move the controller from the form to parent div -->
<form role="search" class="navbar-form navbar-left" ng-submit="search(search_term)">
<div class="form-group">
<input type="text" placeholder="Search" class="form-control" ng-model="search_term">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
<div id="main" class="margin-top-50 clearfix container">
<div ng-repeat="items in inventory" class="row-fluid">
<div class="col-sm-6 col-md-3">
<div class="thumbnail"><img src="image.jpg" alt="..." class="col-md-12">
<div class="caption">
<h3>{{ items.itemName }}</h3>
<p>{{ items.description }}</p>
<p>Buy <a href="#" role="button" class="btn btn-default">More Info</a></p>
</div>
</div>
</div>
</div>
</div>
I've seen the situation a few times where when you are updating a property directly on the $scope object there are interesting problems around databinding to that value (such as inventory). However if you databind to an object property of an object then the databinding works as expected. So for example use a property on $scope. I believe this is a copy by value vs copy by reference issue.
Update all your inventory references as follows
$scope.data.inventory = result;
Also don't forget to update your inventory reference in the html template:
<div ng-repeat="items in data.inventory" class="row-fluid">
Update: I made this plunk to figure it out - http://plnkr.co/edit/0ZLagR?p=preview
I think the primary problem is you have the controller specified twice. I removed it from the form and it started working.

UI Bootstrap Modal popup not working correctly with AngularJS

My code is like this
angular.module('RateRequestApp.controllers', []).controller('ReadOnlyController', [ '$scope', '$modal',
function($scope, $modal) {
var data = [];
data.push("first message");
this.openReprintModal = function() {
var modalInstance = $modal.open({
templateUrl: 'ReprintModal.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function() {
return data;
}
}
});
};
this.openReprintModal();
}
]);
angular.module('RateRequestApp.controllers').controller('ModalInstanceCtrl', function($scope, $modalInstance) {
$scope.ok = function() {
$modalInstance.close();
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});
<div id="RateRequestApp" class="content" ng-app='RateRequestApp' ng-controller="ReadOnlyController">
<script type="text/ng-template" id="ReprintModal.html">
<div class="modal-header">
<h3 class="modal-title">Check this out</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<span>{{ item }}</span>
</li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
</div>
All works Okay Except there is no message shown at the body of modal. Apparently everyhting works except `
<li ng-repeat="item in items">
<span>{{ item }}</span>
</li>`
This part is not working.Can any one point out any possible reason.
Note: I am using this one for model :http://angular-ui.github.io/bootstrap/
You have to inject items object to your ModalInstanceCtrl like this:
angular.module('RateRequestApp.controllers')
.controller('ModalInstanceCtrl', function($scope, $modalInstance, items) {
$scope.items = items;
...
});
And then you are able to access it in your view just like you have it now
<li ng-repeat="item in items">
<span>{{ item }}</span>
</li>

Create a list of items built using angularjs

I would like to create a list of items built in Directive and share through controllers.
Here is my example in plunker: Example of my code
Here is my code in js:
var app = angular.module('app', []);
app.controller("BrunchesCtrl", function ($scope, $log) {
$scope.brunches = [];
$scope.addNew = function () {
$scope.brunches.push({ address: "" });
};
$scope.$watch('brunch.address', function(value) {
$scope.address = value;
$log.info($scope.address);
});
$scope.$watch(function() { return $scope.brunches.length; }, function() {
$scope.brunches = $scope.brunches.map(function (brunch) {
return brunch;
});
});
});
app.directive('brunchesView', function ($compile) {
return {
restrict: 'E',
templateUrl: 'brunch.html',
controller: 'BrunchesCtrl',
replace: true,
link: function (scope, element, attrs, controller) {
}
};
});
app.directive('businessSubmit', function ($log, $compile, formManagerService) {
return {
restrict: 'AE',
controller: 'BrunchesCtrl',
link: function (scope, element, attrs, controller) {
formManagerService.init();
var hasError;
element.on('click', function (e) {
e.preventDefault();
$log.info("brunches: \n");
$log.info(scope.brunches);
});
}
};
});
Here is an HTML:
<!DOCTYPE html>
<div class="controls">
<a class="btn btn-danger" id="addBrunch" data-ng-click="addNew()">
<i class="icon-plus-sign"></i>
add new...
</a>
</div>
</div>
<brunches-view class="well" data-ng-repeat="brunch in brunches">{{brunch}}</brunches-view>
<br/>
<p class="well">
JSON: {{brunches | json}}
</p>
<div class="control-group">
<div class="controls">
<a class="btn btn-primary" href="#" data-business-submit>
<i class="icon-save"></i>
Save...
</a>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script src="script.js"></script>
And here is the template:
<div class="fc-border-separate">
<div class="control-group">
<label class="control-label">Address</label>
<div class="controls">
<input type="text" class="span6 m-wrap"
name="Address" data-ng-model="address"
value="{{address}}" />
</div>
</div>
</div>
The final thing I want to save the whole data inside the BusinessSubmit directive.
Help please...
Several issues with your code.
First, your ng-model for the <input> is set to address, but the object you are wanting to bind it to a brunch object that has an address property. Important to realize that ng-repeat will create a child scope for every repeated item
<input data-ng-model="brunch.address"/>
Another issue is you are assigning the parent controller to a directive as well. Important to understand that controllers are singletons so if you use controller more than once , each is a separate instance. Therefore nesting the parent controller in a directive makes no sense.
DEMO- [ng-model] fix
If you want the data shared with other controllers you should set up a service that holds the brunches data by injecting it into whatever controllers will need access

Categories