I have a bootstrap modal instance that i have opened from parent controller , now i have added method on checkbox checkedValue that i am trying to invoke from child controller but i am getting error Cannot read property 'attuid' of undefined at ChildScope.$scope.checkedValue (newUserModal.controller.js:22) Any idea how can i invoke method in child controller ?
newUserModal.html
<tr ng-repeat="user in userList track by $index">
<td st-ratio="20">{{user.attuid}}</td>
<td st-ratio="30">{{user.firstName}} {{user.lastName}}</td>
<td st-ratio="15" ng-bind-html="user.type"></td>
<td st-ratio="15">{{user.email}}</td>
<td><input type="checkbox" ng-model="user.selected" ng-click="checkedValue(user)"> </td>
<!--<td st-ratio="20" class="text-right">
<button type="button" ng-click="editUser($index, user)" class="btn btn-primary">
Approve
</button>
</td>-->
</tr>
parent.controller.js
$scope.newUserListModal = function () {
$scope.modalInstance = $uibModal.open({
templateUrl: 'app/access/accessModal/newUserModal.html',
controller: 'AccessModalCtrl',
size: 'lg'
});
$scope.modalInstance.rendered.then(function () {
$rootScope.$broadcast('show-user-list',$scope.userList);
});
/*$scope.modalInstance.result.then(function(selectedUsers) {
console.log(selectedUsers);
});*/
}
child.controller.js
angular.module('angularModelerApp')
.controller('AccessModalCtrl', function ($scope,$uibModalInstance,toastr) {
var selectedUsers = [];
$scope.$on('show-user-list',function(e,data){
$scope.userList = data;
});
$scope.checkedValue = function(user){
$scope.selectedUsers = $scope.selectedUsers || [];
if(user.selected){
$scope.selectedUsers.push({ attuid: $scope.user.attuid,
firstName: $scope.user.firstName,
lastName: $scope.user.lastName,
email:$scope.user.email
});
console.log($scope.selectedUsers);
}
};
});
Related
i am trying to save number of students at the time,i wrote the following code but i did not know where to go further. any more info or links to resources regarding this topic would be much appreciated
what i have done so far :
<div ng-controller="MainCtrl">
<fieldset data-ng-repeat="student in students">
<input type="text" ng-model="student.class" name="" placeholder="Class Name ">
<input type="text" ng-model="student.firstname" name="" placeholder="First Name ">
<input type="text" ng-model="student.lastname" name="" placeholder="Last Name ">
<button class="btn btn-danger" ng-show="$last" ng-click="removeStudent()">-</button>
</fieldset>
<button class="btn btn-primary" ng-click="addNewStudent()">New Student</button>
<button class="btn btn-primary" ng-click="save()">Save</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
the controller is:
app.controller('MainCtrl', function($scope, $modalInstance, $students) {
$scope.students = [];
$scope.addNewStudent = function() {
$scope.students.push({
classname: "",
firstname: "",
lastname: ""
});
};
$scope.removeStudent = function() {
var lastItem = $scope.students.length - 1;
$scope.students.splice(lastItem);
};
$scope.save = function() {
$modalInstance.close($scope.students);
};
$scope.delete = function() {
$scope.students['deleted'] = 1;
$modalInstance.close($scope.students);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});
in the view i can write the infos of students but when i click save button it only save the first student
modal instance:
$scope.openStudent = function (student) {
var modalInstance = $modal.open({
templateUrl: 'modalStudent.html',
controller: 'mainCTRL',
windowClass:'app-modal-window',
resolve: {
students: function () {
var students= {};
if (student !== undefined){
students['classname'] = student.classname;
students['firstname'] = student.firstname ;
students['lastname'] = student.lastname;
students['nachname'] = student.nachname;
}
console.log("studinfo",students);
return students;
}
}
});
modalInstance.result.then(function (students) {
if (students.deleted === undefined || students.deleted == 0) {
oStudent = { classname: students.classname,
firstname: students.firstname,
lastname: students.lastname,
delete_time:"0000-00-00 00:00:00"
};
saveStudent( $indexedDB,Student).then( function(id) {
$scope.buildMenu();
});
} else {
oStudent = { id: students.id,
delete_time:new Date().toISOString()
};
deleteStudent( $indexedDB, $scope, students.id).then( function(id) {
saveStudent( $indexedDB, Student, $scope.selectedUser.id ).then( function(id) {
$scope.buildMenu();
});
});
}
}, function () {
//console.log('Modal Student dismissed at: ' + new Date());
});
}
In case its a modal where you are passing the existing students objects, your controller code should be modified as:
Also you should use two separate views in this case for add and edit to avoid code cluttering. Because in case of addition students will be an array of objects and in case of edit it will be a single object where you cannot use ng-repeat as it wont work
app.controller('MainCtrl', function($scope, $modalInstance, students) {
//students variable contains information about the student to be edited, so your code should be something like this
if(students.classname !== undefined){
$scope.students = students;
}else{
$scope.students = [];
}
// rather than re-initializing each time modal gets opened you should retain value from students that you are passing
$scope.addNewStudent = function() {
$scope.students.push({
classname: "",
firstname: "",
lastname: ""
});
};
$scope.removeStudent = function() {
var lastItem = $scope.students.length - 1;
$scope.students.splice(lastItem);
};
$scope.save = function() {
$modalInstance.close($scope.students);
//make sure to save this when modal closes in the variable you are returning students from when modal is triggered
};
$scope.delete = function() {
$scope.info['deleted'] = 1;
$modalInstance.close($scope.students);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});
Iam new to AngularJS and now facing an issue with uirouter multiple views. Searched for various examples,but couldn’t find a solution. Hope you will help.
I have a submit function inside controller in nested view. When a user clicks on submit, the subt_click() has to be invoked and an url has to be created based on the date provided and should call data from that url and display in a table.
<div ng-controller="MyController as ctrl">
<form class="form-horizontal">
<div class="form-group">
<div class="col-sm-5">
<p class="input-group">
<input type="text" class="form-control" datetime-picker="yyyy-MM-dd HH:mm" ng-model="dates.date3" is-open="ctrl.open.date3" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="ctrl.openCalendar($event, 'date3')"><i class="fa fa-calendar"></i></button>
</span>
</p>
</div>
</div>
</form>
<a ui-sref=".submit" class="btn btn-info" ng-click="subt_click()">Submit</a>
</div>
Below is how I have declared states and called the subt_click().
app.js:
var wc = angular.module('wc', ['ui.router','ui.bootstrap', 'ui.bootstrap.datetimepicker']);
wc.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/posts');
$stateProvider
.state('tab', {
url: '/tab1',
templateUrl: 'tab.html'
})
.state('tab.submit', {
url: '/submit',
templateUrl: 'tab-submit.html',
//controller: 'MyController'
})
.state('tabs', {
url: '/tabs',
templateUrl: 'tabs.html',
});
});
wc.controller('MyController', function ($scope, $http, $location, $filter) {
var that = this;
var in10Days = new Date();
in10Days.setDate(in10Days.getDate() + 10);
$scope.dates = {
date3: " ",
date4: " "
};
this.dates = {
date3: new Date(),
date4: new Date(),
};
this.open = {
date3: false,
date4: false,
};
// Disable weekend selection
this.disabled = function (date, mode) {
return (mode === 'day' && (new Date().toDateString() == date.toDateString()));
};
this.dateOptions = {
showWeeks: false,
startingDay: 1
};
this.timeOptions = {
readonlyInput: false,
showMeridian: false
};
this.dateModeOptions = {
minMode: 'year',
maxMode: 'year'
};
this.openCalendar = function (e, date) {
that.open[date] = true;
};
$scope.format = 'yyyy-MM-dd%20HH:mm';
debugger;
$scope.subt_click = function () {
var date = $filter("date")($scope.dates.date3, $scope.format);
$http.get("URLpartA"+date+"URLpartB")
.success( function(response) {
debugger
$scope.condition = response.Table
console.log(response)
});
};
});
tab-submit.html:
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in condition">
<td>{{x.ID}}</td>
<td>{{x.Name}}</td>
</tr>
</tbody>
</table>
Here is a plunk to check the code: plunker:http://plnkr.co/edit/3Iyao5aOt2tY7Ze104dp?p=preview.
the displayed table is empty and not the data from url(URL am using is from local host).There are no errors on console and from console.log(response) I could see the array objects from url.
Am not sure where this has went wrong. Will be really grateful if anyone can help!!
Check this plunker. I've added a controller, a dummy service to fetch data and used the service in resolve to inject data into the controller.
I built a sample MVC application in which I tried to implement functionality to insert a record using angular js.
Here is the index cshtml page.
#{
ViewBag.Title = "Add User";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section adduser
{
#*Index.html*#
<div class="container-fluid" ng-app='MyData' ng-controller='DataController'>
<table class="table table-striped table-bordered table-responsive">
<tr>
<td>
<label class="text-primary">User Name:</label>
</td>
<td>
<input type="text" id="txtUserName" class="text-primary" required="required" ng-model="newUser" />
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" id="btnSubmit" class="btn btn-success" ng-click="AddUser()" />
</td>
</tr>
</table>
</div>
}
Here is the Model js code
var myData = angular.module('MyData', []);
Here is the controller JS code
myData.controller("DataController", function($scope) {
$scope.newUser = "";
$scope.addUser = function() {
$http.post("/Home/AddUser/", { newUser: $scope.newUser }).success(function (result) {
alert(result.success);
}).error(function(data) {
console.log(data);
});
};
});
Here is the post method inside controller which i am calling through angular js
[HttpPost]
public JsonResult AddUser(string name)
{
var db = new SchedulerEntities();
db.Users.Add(new User {Name = name});
db.SaveChanges();
return null;
}
I am adding an entry into DB from controller method but nothing is happening...
I think you need to declare $http in the function:
myData.controller("DataController", function($scope, $http) {
$scope.newUser = "";
$scope.addUser = function() {
$http.post("/Home/AddUser/", { newUser: $scope.newUser })
.success(function (result) {
alert(result.success);
}).error(function(data) {
console.log(data);
});
};
});
I am trying to use a Angular/bootstrap modal to edit MVC ApplicationUser scaffolded views. I have a found a few examples, they are mostly jquery. I found one that works well using jquery-ui. I want to be consistent with my modals so I need to make it work with angular-ui or plain bootstrap. I am not sure how this is calling the MVC controller for the data binding.
Working Jquery-ui example
<script type="text/javascript">
$(document).ready(function () {
$.ajaxSetup({ cache: false });
$(".editDialog").live("click", function (e) {
var url = $(this).attr('href');
$("#dialog-edit").dialog({
title: 'Edit Customer',
autoOpen: false,
resizable: false,
height: 355,
width: 400,
show: { effect: 'drop', direction: "up" },
modal: true,
draggable: true,
open: function (event, ui) {
$(this).load(url);
},
});
$("#dialog-edit").dialog('open');
return false;
});
});
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FullName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { #class = "editDialog" })|
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
</td>
</tr>
}
</tbody>
<div id="dialog-edit" style="display: none"> </div>
Here is how I use angular to open a modal with a api call.
$scope.editLocation = function (id) {
$scope.close();
var deferred = $q.defer();
$http({ method: 'get', url: '/api/Locations/' + id })
.success(function (model) {
deferred.resolve(model);
$scope.model = model;
}).error(function (error) {
deferred.reject(error);
}).then(function () {
$modal.open({
templateUrl: "EditLocationModal.html",
controller: 'ModalInstanceController',
resolve: {
model: function () {
return $scope.model;
}
}
});
})
return deferred.promise;
}
UPDATE
$scope.editUser = function (id) {
$modal.open({
templateUrl: "Modals/ApplicationUserModal.html",
controller: 'ModalInstanceController',
resolve: {
model: function () {
return $scope.model;
}
}
});
};
View
<div class="card-body card-padding" ng-controller="ApplicationUserController">
<div class="table-responsive">
<table class="table table-striped table-vmiddle">
<thead>
<tr>
<th>Full Name</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FullName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", null, new { ng_click = "editUser(item.Id)" })
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
UPDATE 2
This syntax
#Html.ActionLink("Edit", "Edit", null, new { ng_click = "editUser(" + item.Id + ")" })
is throwing this error.
Error: [$parse:syntax] Syntax Error: Token 'bc05f5' is unexpected, expecting [)] at column 12 of the expression [editUser(87bc05f5-35c2-4278-a528-b7e237922d4e)] starting at [bc05f5-35c2-4278-a528-b7e237922d4e)].
http://errors.angularjs.org/1.3.15/$parse/syntax?p0=bc05f5&p1=is%20unexpected%2C%20expecting%20%5B)%5D&p2=12&p3=editUser(87bc05f5-35c2-4278-a528-b7e237922d4e)&p4=bc05f5-35c2-4278-a528-b7e237922d4e)
I am not sure how this is calling the MVC controller for the data
binding.
Just to clue you in on the interesting parts
// 1. here it binds a "click" event to all elements with class "editDialog"
$(".editDialog").live("click", function (e) {
// 2. here it fetches the HREF attribute of that element
var url = $(this).attr('href');
$("#dialog-edit").dialog({
title: 'Edit Customer',
autoOpen: false,
resizable: false,
height: 355,
width: 400,
show: { effect: 'drop', direction: "up" },
modal: true,
draggable: true,
open: function (event, ui) {
// 3. And here it loads that HREF attribute in the modal
$(this).load(url);
},
});
$("#dialog-edit").dialog('open');
return false;
});
That's basically all of the "data binding" going on in the jquery version. As you can see it's really not anything fancy.
You'd probably like to do something more elegant, like setting up an angular directive for your editDialog or somesuch.
EDIT:
I re-read how you init your modal and if I understood everything correctly you should be able to do something like this (not razor-savvy enough to be 100% on the syntax but you get the idea)
#Html.ActionLink("Edit", "Edit",
new { id = item.Id },
new { ng_click = "editUser('" + #item.Id + "')" })
Also, you might or might not need to scope editUser inside ng-click.
This code to show bootstrap popup
<script type="text/javascript">
$(document).ready(function () {
$.ajaxSetup({ cache: false });
$(".editDialog").live("click", function (e) {
$('#myModalContent').load(this.href,function(){
$('#myModal').modal({
keyboard: true
},'show');
bindForm(this);
});
return false;
});
function bindForm(dialog){
$('form',dialog).submit(function(){
$.ajax({
url:this.action,
type:this.method,
data:$(this).serialize(),
success: function(result){
if(result.success)
{
$('#myModal').modal('hide');
$('#YourFormId').load(result.url);
}
else
{
$('#myModalContent').html(result);
bindForm(dialog);
}
}
});
return false;
)};
</script>
In your parent view:
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
</div>
</div>
In Edit in popup build the code into
<div class="modal-content">
<div class="modal-header">
//Your heading
<div class="modal-body">
//your body content
</div>
<div class="modal-footer">
//your footer
</div>
</div>
Example for delete with bootstrap modal and mvc model:(asp.net mvc6)
html page :
<div ng-controller="CustomersCtrl">
//template for modal with bootstrap
<div class="modal-header" style="background-color:#54a0fc !important;">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" ng-click="cancel()"><span aria-hidden="true">×</span></button>
<h3>Delete</h3>
</div>
<div class="modal-body">
<table class="table">
<thead>
</thead>
<tbody>
<tr>
<td>Last Name : </td>
<td>{{customer.LastName}}</td>
</tr>
<tr>
<td>First Name : </td>
<td>{{customer.FirstName}}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer" style="background-color:#54a0fc !important;">
<button ng-click="delete(customer.CustomerID)" class="btn btn-danger btn-lg">Delete</button>
<button ng-click="cancel()" class="btn btn-default btn-lg">Cancel</button>
</div>
in your controller think to add ['ui.bootstrap'] in your app.js:
CustomersCtrl.$inject = ['$scope', '$http', '$location', '$modal'];
function CustomersCtrl($scope, $http, $location, $modal) {
//function to open Delete modal
$scope.openDelete = function (id) {
var modalInstance = $modal.open({
templateUrl: 'Modals/Customers/delete.html',
controller: $scope.modalDelete,
//matches of the id of your item to recover object model in the controller of the modal
resolve: {
id: function () {
return id
}
}
});
}
//controller of the modal. Inside you can recover your object with ajax request
$scope.modalDelete = function ($scope, $modalInstance, id) {
if (angular.isDefined(id)) {
var reqGetCustomer = $http({ url: '/api/Customers/' + id, method: 'GET' });
reqGetCustomer.success(function (dataResult) {
$scope.customer = dataResult;
});
} else { alert('id is undefined'); }
//function to close modal
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
}
}
$scope.delete = function (id) {
var customer = getCustomer(id);
var reqDeleteCustomer = $http({ url: '/api/customers/' + id, method: 'DELETE' });
reqDeleteCustomer.success(function (dataResult) {
$scope.cancel();
});
$scope.customers = getListCustomers();
}
}
I hope this will help you
I'm trying to create a sigle-page app that contains shop list, in every shop card is the link to another view that contains table with products.
A shop looks like:
shop = {
id: 1,
name: "foo",
description: 'bar',
products: [item1, itemn];
};
app.js:
angular
.module('lightpointTestApp', [
'ngCookies',
'ngRoute',
'ui.sortable'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutCtrl'
})
.when('/products/:shopID', {
templateUrl: 'views/products.html',
controller: 'ProductsCtrl'
})
.otherwise({
redirectTo: '/'
});
});
Main.html view where are shop list:
<h3>Shop list</h3>
<div class="row shopsContainer" ui-sortable ng-model="shops">
<div class="col-lg-3 shopCard" ng-repeat="shop in shops">
<button class="btn close cardClose" ng-click="removeShop($index)">×</button>
<div class="cardNumber">{{ shops.indexOf(shop) + 1 }}</div>
<div class="cardHeader">{{ shop.name }}</div>
<div class="cardBody">
{{ shop.address }}<br />
{{ shop.hours }}<br />
View {{ shop.products.length }} products
</div>
</div>
</div>
<div class="row">
<input type="text" ng-model="newShop.name" placeholder="Shop name" class="col-lg-3" />
<input type="text" ng-model="newShop.address" placeholder="Shop address" class="col-lg-3" />
<input type="text" ng-model="newShop.hours" placeholder="Shop hours" class="col-lg-3" />
<button class="btn btn-primary col-lg-3" type="button" ng-disabled="!newShop.name || !newShop.address || !newShop.hours" ng-click="addShop()">Add Shop</button>
</div>
</span>
</div>
</div>
products.js - controller for products page
angular.module('lightpointTestApp')
.controller('ProductsCtrl', function ($scope, $routeParams, shops) {
$scope.shopList = shops;
$scope.shop = {};
$scope.getShop = function (id) {
for (var i = 0; i < $scope.shopList.length; i++) {
if ($scope.shopList[i].id === id) {
return $scope.shopList[i];
}
}
return null;
};
var shopID = $routeParams.shopID;
$scope.shop = $scope.getShop(shopID);
})
products.html where is the table with products
<h2>{{ shop.name }}</h2>
<table class="table table-hover">
<tr>
<th>Product Name</th>
<th>Product Description</th>
</tr>
<tr ng-repeat="product in shop.products">
<td> {{ product.name }} </td>
<td> {{ product.description }} </td>
</tr>
</table>
The problem is that products.html doesn't bind with products.js and show something like {{shop.name}} and an empty table.
P.S. I think that products.js isn't correct, but I tried everything to do it well.
Thanks.
You have a parameter shops in ProductsCtrl, but there is nothing that will pass a value for it, so it is going to be null. You set the value of $scope.shopList to it, and then try to iterate over a NULL array, so you get an exception.
You can store the values of shops in a service, and then pass them around your app via injection. You can initialize their values within main.js, or within the service itself, and then the values will be available if you inject them into ProductsCtrl, something like
angular.module('lightpointTestApp')
.controller('ProductsCtrl', ['$scope', '$routeParams', 'shopsService',
function ($scope, $routeParams, shopsService) {
$scope.shopList = shopService;
$scope.shop = {};
$scope.getShop = function (id) {
for (var i = 0; i < $scope.shopList.length; i++) {
if ($scope.shopList[i].id === id) {
return $scope.shopList[i];
}
}
return null;
};
var shopID = $routeParams.shopID;
$scope.shop = $scope.getShop(shopID);
}]);
shopsService could look something like
angular.module('lightpointTestApp')
.service('shopsService', function() {
return [
// add whatever fields you need here from code in main.js
{ name: 'shop1', address: 'addr1' },
{ name: 'shop2', address: 'addr2' }
];
});
Where are your shop objects coming from? You are passing in shop, in products.js but not referencing it in the code. You should also use $q to use promises for async data. Also use the filter() function rather than a for loop to find the shop by shopId.
Are you hitting an API with shops or storing a local json for now?
With angular, you should separate your data logic manipulation in a factory or service as such:
productService.js
angular.module('lightpointTestApp')
.factory('shopService',function($http, $q){
var shops = [];
return {
getShops: function () {
var deferred = $q.defer();
$http.get('<path to product.json or api>').success(function(data){
shops = data;
deferred.resolve(data);
})
return deferred.promise;
},
getShopById: function(shopID) {
var deferred = $q.defer();
deferred.resolve(shops.filter(function(chain){
return chain.id === shopID;
})[0]);
return deferred.promise;
}
}
});
product.js
angular.module('lightpointTestApp')
.controller('ProductsCtrl', function ($scope, $routeParams, $q,shopService) {
$scope.shopList = [];
$scope.shop = {};
var shopID = $routeParams.shopID;
shopService.getShops.then(function(shops){
$scope.shopList = data;
})
$scope.getShopById = function(shopID) {
shopService.getShopById(shopID).then(function(shop){
$scope.shop = shop;
});
}
});