ng-click not executing controller function - angularjs

I have a very simple function in one of my angular controllers
$scope.search = function () {
alert("Search");
};
and from my view I have
<button type="button" data-ng-click="search()"><i class="fa fa-search"></i></button>
The function is never executed when the button is clicked, but the rest of the code in my controller is executed as expected. Is there any reason why the ng-click directive will not fire my function?
I have similar controllers all working as expected.
Update
The button is within a bootstrap 3 modal, when the button is moved out of the modal, the click event works. Any reason for this happening?
Update
The button is within scope of the controller, here is my controller and view for clarity
(function () {
var module = angular.module("crest");
var brokerGridController = function ($scope, readEndpoint, readBroker) {
$scope.endpoint = "";
$scope.isBusy = false;
$scope.havebroker = false;
$scope.brokers = [];
$scope.searchCriteria = "";
$scope.exception = "";
var setEndpoint = function (response) {
$scope.endpoint = response.Endpoint;
};
readEndpoint.read("BusinessLogicAPI").then(setEndpoint);
var onSuccess = function (response) {
if (response.Message.MessageType == 1) {
onError();
}
$scope.havebrokers = response.brokers.length > 0;
angular.copy(response.brokers, $scope.brokers);
angular.copy(response.Message.body, $scope.exception);
};
var onError = function () {
$("#errorMessageModal").modal("show");
};
$scope.search = function () {
alert("Search");
};
};
module.controller("brokerGridController", ["$scope", "readEndpoint", "readBroker", brokerGridController]);
}());
and the view
<div data-ng-controller="brokerGridController">
<div>
<div class="col-md-4">
<div class="contacts">
<div class="form-group multiple-form-group input-group">
<div id="searchBrokerDropdown" class="input-group-btn input-group-select">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="concept">Broker Name</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Broker Name</li>
</ul>
<input type="hidden" class="input-group-select-val" name="contacts['type'][]" value="phone">
</div>
<input type="text" name="contacts['value'][]" class="form-control" data-ng-model="searchPhrase">
<span class="input-group-btn searchButton">
<button type="button" class="btn btn-success btn-add" data-ng-click="$parent.search()"><i class="fa fa-search"></i></button>
</span>
</div>
</div>
</div>
</div>
<div>
<div class="col-md-12">
#Html.Partial("_Loading", new LoadingViewModel() { DisplayText = "Loading brokers..." })
<div data-ng-show="!isBusy && !haveBrokers">
<h3>No brokers found.</h3>
</div>
<div class="panel" data-ng-show="!isBusy && haveBrokers">
<div class="panel-heading">
<h4 class="panel-title">Brokers</h4>
<div class="pull-right">
<span class="clickable filter" data-toggle="tooltip" title="Filter Brokers" data-container="body">
<i class="fa fa-filter"></i>
</span>
</div>
</div>
<div class="panel-body">
<input type="text" class="form-control" id="task-table-filter" data-action="filter" data-filters="#task-table" placeholder="Filter Tasks" />
</div>
<table class="table table-hover" id="task-table">
<thead>
<tr>
<th>Broker Name</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="broker in brokers">
<td>{{ broker.Name }}</td>
<td data-ng-show="searchCriteria != 'PolicyNumberLike'"><i class="fa fa-search"></i> View Policies</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

You have to check 2 things in that situation:
Check if your button is in the front (rise his z-index or check is :hover is working), maybe it is not on top so it can't be clickable.
Check if that buttont dont have own $scope (it is crated in subdirective, or in ng-repeat for example), in taht situation check:
<button type="button" data-ng-click="$parent.search()"><i class="fa fa-search"></i></button>
If that 2 things dosen't work check if any command ex. console.log('test_mode') will fire after click.

It's most likely that the button is outside of controller scope, if you provide model with a specific controller you should put search function inside said controller, if you want to keep it in parent controller specify it like this:
$scope.modalFunctions = {
search: function () {
//do something
}
}
then use ng-click="modalFunctions.search"

Ok, I finally found the problem. My angular view is within a bootstrap wizard component (within a bootstrap modal) that I copied from Bootsnipp. The problem was with the javascript that was supplied,
wizardContent.html(currStep.html());
this piece of code replaced the wizard content with the HTML of the correct step. I modified the javascript to hide and show the correct steps instead of copying the HTML of the correct step to the div displayed to the user, which resolved the issue.

Related

Pass table data into a method in angular

Here is my code:
<body ng-app="intranet_App" ng-controller="myCtrl">
<div class="container">
<div class="modal" id="deleteProject">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body" id="confirmMessage">
Are you sure do you want to delete this project??
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="confirmOk" ng-click="deleteProject(x.Id)">Ok</button>
<button type="button" class="btn btn-default" id="confirmCancel" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<div class="col-xs-12 margin20 padding table-responsive">
<table class="col-xs-12 table table-hover table-bordered" id="projectList">
<thead class="colorBlue">
<tr><th>Project Name</th><th>Client</th><th>Client Co-ordinator</th><th>Action</th></tr>
</thead>
<tbody id="projectListTBody" >
<tr ng-repeat="x in projectList | filter:ProjectName">
<td>{{ x.ProjectName}}</td>
<td>{{ x.Client}}</td>
<td>{{ x.OnsiteCoordinator}}</td>
<td>
<i class="fa fa-user-plus fa-2x" ng-click="addResource()"></i>
<i class="fa fa-edit fa-2x" ng-click="editProj(x.Id)"></i>
<i class="fa fa-trash fa-2x" data-toggle="modal" data-target="#deleteProject"></i>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
<script>
var app = angular
.module("intranet_App", [])
.controller("myCtrl", function ($scope, $http) {
$scope.projDetails = [];
$http.post('/Project/getProjectsList')
.then(function (response) {
console.log(response)
$scope.projectList = response.data;
})
$scope.deleteProject = function (id) {
alert(id)
}
});
</script>
Here when I click delete icon in a table, I am displaying one bootstrap popup modal.In that modal I need to pass x.Id inside deleteProject method on the on click on ok button.But I am unable to hit the method,how to pass it?
In HTML code, add ng-click to delete button
<i class="fa fa-trash fa-2x" data-toggle="modal" data-target="#deleteProject" ng-click="delete(x.id)"></i>
In controller add following method
$scope.delete = function (id) {
$scope.deleteId = id;
}
Using that in deleteProject method
$scope.deleteProject = function () {
//use $scope.deleteId here
alert($scope.deleteId);
}
You're trying to access the x var outside of the ng-repeat in which it is defined it, so naturally, it won't know what x is. This is why you're getting undefined.
Here's the quickest solution I could come up with, there should be a better way, though:
<i class="fa fa-trash fa-2x"
data-toggle="modal"
data-target="#deleteProject"
ng-click="current = x"></i>
Which will assign the last clicked x into current. Then, you should refer to current inside the modal:
<button type="button"
class="btn btn-default"
id="confirmOk"
ng-click="deleteProject(current.Id)">
Ok
</button>

x-editable nested editable-select not submitting

I have a editable-select nested inside other, when I submit the nested editable-select changes, it does not call the onaftersave assigned function ('vm.addOperation()'), it also shows the outter editable-select edit form.
I want it just to show the nested edit form and the function call to work.
My html code:
<div editable-select="vm.selectedUser"
e-ng-options="user.objectId as user.displayName for user in vm.users"
onshow="vm.getUsers()"
onaftersave="vm.addUser()">
<div class="container" ng-repeat="u in entity.authorizedUsers">
<div class="row">
<div class="col-xs-2">
{{u.id}}
</div>
<div class="col-xs-4">
<div editable-select="vm.selectedOperation"
e-ng-options="operation.id as operation.name for operation in vm.operations"
onshow="vm.getOperations()"
onaftersave="vm.addOperation()">
<div class="container" ng-repeat="op in u.authorizedOperations">
<div class="row">
<div class="col-xs-3">
{{op.name}}
</div>
<div class="col-xs-push-2">
<button class="btn btn-xs btn-danger"
ng-click="vm.removeOperation(entity.id, u.id, op.id)">
<i class="fa fa-trash-o"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-push-4">
<button class="btn btn-xs btn-warning pull-left"
ng-click="vm.removeuser(entity.id, u.id)">
<i class="fa fa-trash-o"></i>
</button>
</div>
</div>
</div>
</div>
I've manage to fix the problem with the following code. It's an ugly workaround tho, please if someone has a more elegant solution I'd very much appreciate it.
in html:
<div editable-select="vm.selectedOperation"
e-form ="nestedForm"
onshow="vm.getOperations()"
ng-click="nestedForm.$show(); vm.xEditableNestedFormFix(nestedForm); $event.stopPropagation()"
e-ng-options="operation.id as operation.name for operation in vm.operations"
onaftersave="vm.addOperation()">
in js:
vm.xEditableNestedFormFix = function (form) {
var editorElement = form.$editables[0].controlsEl[0].firstChild;
editorElement.onclick = function (event) {
event.stopPropagation();
}
var submitButton = form.$editables[0].buttonsEl[0].firstChild
submitButton.onclick = function (event) {
form.$submit();
event.stopPropagation();
}
var cancelButton = form.$editables[0].buttonsEl[0].lastChild
cancelButton.onclick = function (event) {
event.stopPropagation();
}
}

Edit with bootstrap modal and AngularJS

I have made bootstrap modal for edit particular data from my data-table.
I am able to open popup and able to fetch my data as well, but as i am doing some changes in modal's text box it is suddenly reflect to data-table also (data-table is in another controller).
I want to reflect it in data-table only if I am clicking Update button.
And if I click cancel button then the previous value should be there.
Here is my HTML code:
<tr ng-repeat="Filterlist in macAddressListResult" class="text-center">
<td>{{1+$index}}</td>
<td class="padding-top-8">
<span class="label" >{{Filterlist.status}}</span>
</td>
<td><span>{{Filterlist.macAddress}}</span></td>
<td>
<button ng-click="openModal(Filterlist)" class="btn btn-xs btn-primary" title="Edit">
<i class="glyphicon glyphicon-edit"></i>
</button>
<button class="btn btn-xs btn-danger" title="Delete">
<i class="glyphicon glyphicon-trash"></i>
</button>
</td>
</tr>
Here is Modal HTML code:
<div class="modal-header bg-color">
<h3 class="modal-title">Edit</h3>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-2">
MacAddress
</div>
<div class="col-md-10">:
<input type="text" ng-model="mac.macAddress" name="macAddress" >
</div>
</div>
<br>
<div class="row">
<div class="col-md-2">
status
</div>
<div class="col-md-10">:
<select type="text" ng-model="mac.status" name="macAddress" >
<option ng-repeat="p in denyAllow">{{p}}</option>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-click="ok(mac)"> Save </button>
<button class="btn btn-default" ng-click="cancel()">Cancel</button>
</div>
Here is angularJS code:
app.controller('networkModeCtrl', function($rootScope, $scope, $state, networkModeService, $modal, $timeout){
$scope.openModal = function(mac){
var modalInstance = $modal.open({
templateUrl: 'partials/settings/macAddressEdit.html',
controller: 'macAddressEditCtrl',
controllerAs: 'vm',
scope: $scope,
resolve: {
mac: function () { return mac}
}
});
}
});
app.controller('macAddressEditCtrl', function($scope, $state, $stateParams, $modalInstance, mac, networkModeService, indexService){
$scope.mac = mac;
// === Get Mac address filter mode (allow/Deny) list === //
networkModeService.denyAllow().success(function(result){
$scope.denyAllow = result;
});
// === function to save mac staus ===//
$scope.ok = function(mac) {
$modalInstance.close();
};
// === function to cancel model === //
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
So, please anyone know me where I am going wrong!!!
Thanks in advance.
This is happening because of two-way data binding, which is the core feature of AngularJS.
When you pass the Filterlist object to the modal with scope set to $scope, you are effectively letting the modal communicate with the data in datatable directly, and updating it in real time.
To achieve your requirement, you should copy the Filterlist object like this in your controller:
$scope.updateFilterlist = angular.copy($scope.Filterlist);
And pass it to the modal:
<button ng-click="openModal(updateFilterlist)" class="btn btn-xs btn-primary" title="Edit">
<i class="glyphicon glyphicon-edit"></i>
</button>
Or do it directly in the view code:
<button ng-click="openModal(angular.copy(Filterlist))" class="btn btn-xs btn-primary" title="Edit">
<i class="glyphicon glyphicon-edit"></i>
</button>
This will create two different instances of the object in memory so that changes to one in the modal do not reflect on the other in the datatable.
You can then add code to copy the changes made to updatedFilterlist to Filterlist when 'Update' button is clicked.

ng-click directive not passing desired parameter

I have the following piece of angular code: (it's a modal-popover menu which uses the following js library: http://scruffles.github.io/BootstrapModalPopover/).
<div ng-repeat="purchasedItem in purchased" class="row item_summary">
<!-- edited for brevity -->
<div id="{{purchasedItem.code}}-popover" data-product-id="{{purchasedItem.code}}" class="popover" style="display: none;">
<div class="arrow"></div>
<h3 class="popover-title" style="display: none;"></h3>
<div class="popover-content">
<div class='popover-menu-left'>
<button class="btn btn-sm btn-danger" ng-click='purchasedItems.removePurchasedItem(purchasedItem)'>Verwijderen</button><br>
</div>
<div class='popover-menu-right-template'>
<div class='number-content' style="display: none;">
<div ng-controller="numpadCtrl as numpad" class="numpad">
<!-- edited for brevity -->
<input type="button" class="btn btn-sm" value="enter" data-item-id='{{purchasedItem.code}}' ng-click="numpad.flushNumber(purchasedItem.code)"></input>
</div>
</div>
</div>
<div class='popover-menu-right-content'>
</div>
</div>
</div>
</div>
the problem lies with this particular piece of code:
<input type="button" class="btn btn-sm" value="enter" data-item-id='{{purchasedItem.code}}' ng-click="numpad.flushNumber(purchasedItem.code)"></input>
The data-item-id attribute was added just to see if I could get retrieve the code - this works just fine! But when I set a breakpoint in the flushNumber function, the parameter passed is undefined.
The code for the numpad controller is the following (it doesn't really do anything yet)
sportOaseControllers.controller('numpadCtrl', ['$scope',
function($scope) {
var parent = this;
parent.currentEntry = "";
parent.addNumber = function (number) {
parent.currentEntry = parent.currentEntry.concat(number);
console.log(parent.currentEntry);
};
parent.cancel = function() {
console.log('cancelled!');
parent.currentEntry = "";
};
parent.flushNumber = function(code) {
console.log('flushing!' + code);
}
}]);
The only thing which might be a clue is that the $scope injected into the numpad controller is null - my knowledge of angular is too minimal to do any real debugging however. Can somebody point me in the right direction?
This is a working JSFiddle, what AngularJS version do you have?
controller as was introduce since 1.2 it's not available before that.
HMTL:
<div ng-app ng-controller="FirstCtrl">
{{purchasedItem}}
<div ng-controller="numpadCtrl as numpad" class="numpad">
<!-- edited for brevity -->
<input type="button" class="btn btn-sm" value="enter" data-item-id='{{purchasedItem.code}}' ng-click="numpad.flushNumber(purchasedItem.code)"></input>
</div>
</div>
JS:
function FirstCtrl($scope) {
$scope.purchasedItem = {
code: 'hello'
};
}
function numpadCtrl($scope) {
this.flushNumber = function (code) {
console.log(code);
}
}

Angularjs xeditable - Save without edit

I am using angular x-editable to edit html table inline. The problem is I need to give the users option to save whatever data is in the table without putting it in edit mode. If I do that, then my scope value is getting wiped out in onaftersave method.
But if I first put the form in edit mode, and then hit save, everything works fine.
Here is the JSFiddle showing the problem: http://jsfiddle.net/0yvhd84o/
HTML:
<div ng-app="app" ng-controller="Ctrl" style="margin: 50px">
<form editable-form name="tableform" onaftersave="saveTable()">
<table class='table table-bordered'>
<tr style="font-weight: bold">
<td>Name</td>
</tr>
<tr>
<td>
<span editable-text="user.name" e-form="tableform" onaftersave="saveTable()">
{{ user.name || 'empty' }}
</span>
</td>
</tr>
</table>
<div class="btn-edit">
<button type="button" class="btn btn-default" ng-show="!tableform.$visible" ng-click="tableform.$show()">
edit
</button>
<button type="submit" ng-disabled="tableform.$waiting" class="btn btn-primary">save</button>
</div>
<div class="btn-form" ng-show="tableform.$visible">
<button type="button" ng-disabled="tableform.$waiting" ng-click="tableform.$cancel()" class="btn btn-default">cancel</button>
</div>
</form>
<br><br>
<div class="row">
Result is: {{result}}
</div>
</div>
AngularJS
var app = angular.module("app", ["xeditable"]);
app.run(function(editableOptions) {
editableOptions.theme = 'bs3';
});
app.controller('Ctrl', function($scope, $filter) {
$scope.user = {
name: 'awesome user',
status: 2
};
$scope.saveTable = function(){
$scope.result = $scope.user.name ;
}
$scope.result = '';
});
Is there a way to achieve this, so that users should not have to enter edit mode if they dont have to make any changes
I was able to figure this out. Here is the solution in case someone else needs it:
You need to add ng-click="tableform.$show()" to save button as well
<button type="submit" ng-disabled="tableform.$waiting" class="btn btn-primary" ng-click="tableform.$show()">save</button>
Working Example: http://jsfiddle.net/9eg11s0o/

Resources