how to pass MVC model to a UI-bootstrap modal - javascript

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

Related

AngularJS Bootstrap modal freezes on full calendar event onclick

I have a very strange error. Whenever I click an event on my full calendar, a modal is supposed to appear except, it freezes the entire page before opening up.
frozen modal
in the link above, the thin grey line at the top is the modal.
Bootstrap Modal popping up but has a "tinted" page and can't interact
I tried the following solution but it did not seem to make a difference in my case. Can anyone suggest a fix/faced a similar issue before?
directive.js
myApp.directive('msResourceCalendarDirective', function ($window, $timeout, $http) {
return {
restrict: 'AE',
templateUrl: '/client/resourceCalendarDirective/view.html?v=1',
controller: function($scope, $element, $attrs, $uibModal) {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
// Open modal from modal
$scope.alertOnEventClick = function (eventObj) {
console.log('Opening modal...');
var modalInstance = $uibModal.open({
animation: true,
templateUrl: '/client/resourceCalendarDirective/modal.html',
backdrop: false,
keyboard: true,
resolve: {
event: function () {
return eventObj;
}
}
});
// Scope apply here to make modal show up
$scope.$evalAsync(function() {
modalInstance.result.then(
function (event) {
console.log('Modal closed at: ' + new Date());
console.log(event);
//$scope.events.push(event);
},
function () {
console.log('Modal dismissed at: ' + new Date());
}
);
});
};
// empty array of events
$scope.events = [];
$scope.myevents = function(start, end, timezone, callback) {
$http.get('/api/v1/sample').then(function(response) {
//var events = [];
angular.forEach(response.data, function(event,key){
$scope.events.push({
id: event._id,
title: event.title,
start: event.startDateTime,
end: event.endDateTime
});
});
callback($scope.events);
});
};
/* config calendar object */
$scope.uiConfig = {
calendar: {
height: 650,
editable: true,
header: {
left: 'month basicWeek basicDay',
center: 'title',
right: 'today prev, next'
},
eventClick: $scope.alertOnEventClick
// eventDrop: $scope.alertOnDrop,
// eventResize: $scope.alertOnSize
}
};
// linking event array to calendar to be displayed
$scope.eventSources = [$scope.myevents];
}
}
});
modal.html
<!-- Update Modal -->
<div class="modal" id="calendarModal.html" >
<div class="modal-dialog">
<div class="modal-content" >
<div class="modal-header">
<h3>Edit Resource</h3>
</div>
<div class="modal-body">
<div class="form-group row">
<div class="col-xs-6">
<label for="resourceTitle">Title</label>
<input id="resourceTitle" class="form-control" type="text" name="title" ng-model="sample.title">
</div>
</div>
<div class="form-group">
<ms-date-time-picker ng-model="sample.startDateTime" placeholder="From" id="dateFrom"></ms-date-time-picker>
</div>
<div class="form-group">
<ms-date-time-picker ng-model="sample.endDateTime" placeholder="To" id="dateTo"></ms-date-time-picker>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="updateResource()" >Update Resource</button>
<button class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Maybe you should try to increase z-index property of modal?
Try
<div class="modal-dialog" id="my-modal">
And then from resolve:
event: function () {
return eventObj;
}
showModal: () {
setTimeout(function () {
$('#my-modal').parent().css('z-index', '10000')
}, 5000);
}
Dirty solution, but may be a solution in your case. Timeout is added to allow everything to render (#my-modal) has to be initialized and visible.

Calling Httpget() in Multiviews/Nested states of UIRouter in AngularJS

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.

How to create dynamic ng-grid inside jquery dialog box

I have situation where i have to create my grid inside jquery dialog and the complete ng-grid will create dynamically below is what i have done for this.
HTML :
<input id="btnShow" type="button" value="Show grid" />
<div id="dialog" style="display: none">
<div id="dvMap" style="height: 380px; width: 580px;"></div>
</div>
JS :
$("#btnShow").click(function () {
$("#dialog").dialog({
modal: true,
title: "Alarm Configuration",
width: 600,
hright: 450,
buttons: {
Close: function () {
$(this).dialog('close');
}
},
open: function () {
//here is a code for populate angular grid dynamically
stack = new Array();
stack.push("<div ng-app='myApp' ng-controller='myGrid'>");
stack.push("<div class='gridStyle' ng-grid='gridOptions'> </div>");
stack.push("</div>");
$("#dvMap").html(stack.join(""));
var app = angular.module('myApp', ['ngGrid']);
app.controller('myGrid', function ($scope, $http) {
$http.get("http://www.w3schools.com/angular/customers.php")
.success(function (response) {
$scope.myData = response.records;
});
$scope.gridOptions = {
data: 'myData'
}
}
}
});
});

Bootstrap/Angular modal no longer works after opening and closing once

I have a page which opens a modal that asks for user confirmation when making an edit to something on the page. If the user chooses "Cancel" button in the modal, the modal closes fine, but then refuses to re-open with the same link. The following error gets thrown if the modal link is clicked again:
TypeError: fn is not a function
at $parseFunctionCall (https://localhost:44310/js/angular.js:12346:15)
at ngEventDirectives.(anonymous function).compile.element.on.callback (https://localhost:44310/js/angular.js:21438:17)
at Scope.$get.Scope.$eval (https://localhost:44310/js/angular.js:14401:28)
at Scope.$get.Scope.$apply (https://localhost:44310/js/angular.js:14500:23)
at HTMLAnchorElement.<anonymous> (https://localhost:44310/js/angular.js:21443:23)
at HTMLAnchorElement.n.event.dispatch (https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.min.js:3:6466)
at HTMLAnchorElement.n.event.add.r.handle (https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.min.js:3:3241)
Here is the controller for the modal, very simple:
(function (angular, undefined) {
"use strict";
angular
.module("app.edit")
.controller("App.EditController", [
"$modalInstance", "$scope", "editList",
function ($modalInstance, $scope, editList) {
$scope.thingsToEdit = editList;
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss("cancel");
};
}
]);
})(angular);
The editList is used to display a list in the confirmation modal, the html of the page.
And the HTML for the modal is:
<div class="modal-header">
<h3>Edit</h3>
</div>
<div class="modal-body">
<p>Please confirm the following edits: </p>
<ul>
<li ng-repeat="thing in thingsToEdit">{{thing}}</li>
</ul>
</div>
<div class="modal-footer">
<div class="form">
<div class="form-group">
<button class="btn btn-primary" type="submit" ng-click="ok()">Confirm Edit</button>
<button class="btn btn-danger" ng-click="cancel()">Cancel</button>
</div>
</div>
</div>
And in the JavaScript for the original page that opens the modal is:
$scope.edit = function (things) {
$scope.editList = things;
$scope.thingsToEdit = things;
var editModal = $modal.open({
animation: true,
templateUrl: "edit.html",
controller: "App.EditController",
resolve: {
editList: function () {
return $scope.thingsToEdit;
}
}
});
editModal.result.then(function () {
var editUrl = //a valid url
$http.post(editUrl, { cache: true })
.success(function () {
console.log("edit successful");
})
.error(function () {
console.log("edit failed");
})
}, function() {
console.log("edit canceled");
});
};

Close icon doesn't work on Bootstrap Modal using AngularJs

I am using Twitter-Bootstrap Modal. I set a close icon on Modal header. I need to active this icon to close the Modal.
<div class="modal-content json-modal-body" id="full-width" ng-controller="projectdetailsController" close="CloseModal()">
<div class="modal-header modal-header-confirm">
<h4 class="modal-title ng-binding">
<span class="glyphicon glyphicon-indent-left"></span>{{modalOptions.headerText}}
<a type="button" title="Close" data-dismiss="modal"><i ng-click="CloseModal()" class="glyphicon glyphicon-remove icon-arrow-right pull-right"></i></a>
</h4>
</div>
<div class="modal-body">
<pre class="Modal-pre" ng-bind-html="modalOptions.bodyText"></pre>
</div>
</div>
Controller:
var modalInstance=$scope.showJSON = function(){
var modalOptions = {
headerText: ' JSON Schema View',
bodyText: 'jsonSchema'
};
var modalDefaults = {
templateUrl: 'app/partials/jsonModal.html'
};
modalService.showModal(modalDefaults, modalOptions).then(function (result) {
});
}
$scope.CloseModal = function () {
$modalInstance.close();
}
I am using ng-click="CloseModal()" to close the modal. I also declared close="CloseModal()" on the parent div. How can I solve this?
I have an AngularJs controller for this modal. Can I use the controller?
You have to declare the function CloseModal() in your controller
If you use angular-ui bootstrap it should look like this:
['$scope', '$modalInstance', function($scope, $modalInstance){
...
$scope.CloseModal = function () {
$modalInstance.close();
}
Follow these steps:
var app = angular.module('myApp',['ui.bootstrap']);
//controller for modal
app.controller('modalCtrl',['$scope','$modalInstance', function ($scope,$modalInstance) {
'use strict';
$scope.cancel = function () {
$modalInstance.dismiss();
};
Second controller:
app.controller('Ctrl',['$scope','$modal', function ($scope,$modal) {
$scope.openModal= function () {
$modal.open({
backdrop: true,
keyboard: false,
backdropClick: false,
templateUrl: "path of your modal HTML",
dialogClass: "modal-content",
controller: 'modalCtrl',
});
}

Categories

Resources