ASP.NET Core MVC - Opening a Bootstrap modal view using a hyperlink - asp.net-mvc

I am creating an ASP.NET (version 5) Core MVC application where I have a list of items. I try to make it so that when you click on an item it opens a (Bootstrap) modal view with the item's details (from another view). However, it seems like a hyperlink doesn't open the modal but instead opens the page itself (so not inside the modal). I got it working with a button, but I would like to make the user click on an item itself instead of a button.
This is the list item that I would like the user to be able to click on (the button is for testing):
I have the following page:
#model DetailsPatientFileViewModel
#section Scripts {
<script type="text/javascript">
$("#addBtn").click(function () {
$.ajax({
url: $(this).attr("formaction"),
}).done(function(res) {
$("#Modal").html(res);
$("#Modal").modal();
})
});
$("#detailCard").click(function () {
$.ajax({
url: $(this).attr("formaction"),
}).done(function(res) {
$("#Modal").html(res);
$("#Modal").modal();
})
});
</script>
}
<div class="patient-file-details-container">
<div class="title-container">
<h4>Treatments</h4>
<!-- This works just fine: -->
<button class=" btn-primary btn-primary" asp-controller="Treatment" asp-action="Create" asp-route-patientId="#Model.PatientId" data-toggle="ajax-modal" data-target="add-treatment" id="addBtn">Add</button>
</div>
<div id="component">
<!-- My list view component: -->
#await Component.InvokeAsync("TreatmentList", new { patientFileId = #Model.PatientFile.Id })
</div>
<!-- My modal: -->
<div id="Modal" class="modal fade">
</div>
</div>
The list view component (I also tested it with a button, see comment):
<ul class="card-list">
#foreach (var treatment in Model)
{
<li class="list-item-card">
<!-- Doesn't work: -->
<a asp-controller="Treatment" asp-action="Details" asp-route-id="#treatment.Id" data-toggle="ajax-modal" data-target="Modal" id="detailCard">
<h5>#treatment.Type</h5>
<p>#treatment.Date</p>
<p>#treatment.Employee.FirstName #treatment.Employee.LastName</p>
</a>
<!-- Does work: -->
<button asp-controller="Treatment" asp-action="Details" asp-route-id="#treatment.Id" data-toggle="ajax-modal" data-target="Modal" id="detailCard">Details</button>
</li>
}
</ul>
And finally the Details.cshtml (the to be opened view in the modal):
#using Core.Domain
#model Treatment
#{
Layout = null;
}
<h3>#Model.Type</h3>
<div class="modal-diaglog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="detailTreatmentLabel">Treatment details</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>#Model.Date</p>
<p>#Model.Description</p>
<p>#Model.Employee.FirstName #Model.Employee.LastName</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
Does anyone know if it is possible to open a seperate view in a modal using a hyperlink? And if not, would there be a workaround to still be able to click on the list item itself?
Thank you in advance!

You can try to call a js function when click hyperlink:
ViewComponent:
<ul class="card-list">
#foreach (var treatment in Model)
{
<li class="list-item-card">
<!-- Doesn't work: -->
<a href="javascript:Details(#treatment.Id)">
<h5>#treatment.Type</h5>
<p>#treatment.Date</p>
<p>#treatment.Employee.FirstName #treatment.Employee.LastName</p>
</a>
<!-- Does work: -->
<button asp-controller="Treatment" asp-action="Details" asp-route-id="#treatment.Id" data-toggle="ajax-modal" data-target="Modal" id="detailCard">Details</button>
</li>
}
</ul>
page js:
#section Scripts {
<script type="text/javascript">
function Details(id) {
$.ajax({
type: "GET",
url: "Treatment/Details?id="+id,
success: function (res) {
$("#Modal").html(res);
$("#Modal").modal();
}
});
}
$("#addBtn").click(function () {
$.ajax({
url: $(this).attr("formaction"),
}).done(function(res) {
$("#Modal").html(res);
$("#Modal").modal();
})
});
$("#detailCard").click(function () {
$.ajax({
url: $(this).attr("formaction"),
}).done(function(res) {
$("#Modal").html(res);
$("#Modal").modal();
})
});
</script>
}

Related

Bootstrap 5 Accordion in Partial View (ASP.NET Core) cannot collapse after expanded

I want to generate a MVC partial view with a Bootstrap 5 accordion. Here is the code:
Index.cshtml
#{
ViewData["Title"] = "Home Page";
}
<input type="button" class="load_btn" id="1" value="Load" />
<div id="pv-1"></div>
#section Scripts
{
<script type="text/javascript">
$(function () {
$(".load_btn").click(function () {
var div_id = 'pv-' + $(this).attr('id');
$.ajax({
type: "GET",
url: "/Home/PV",
success: function (response) {
$('#' + div_id).empty();
$('#' + div_id).html(response);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
</script>
}
HomeController.cs
...
namespace WebApplication4.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult PV()
{
return View("_PartialView");
}
...
}
}
_PartialView.cshtml
#{
Layout = null;
}
<link rel="stylesheet" href="~/lib/bootstrap/css/bootstrap.css" />
<div class="accordion" id="2">
<div class="accordion-item">
<h2 class="accordion-header" id="h-1">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c-1" aria-expanded="false" aria-controls="c-1">
First Button
</button>
</h2>
<div id="c-1" class="accordion-collapse collapse" aria-labelledby="h-1">
<div class="accordion-body">
TO DO
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="h-2">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c-2" aria-expanded="false" aria-controls="c-2">
Second Button
</button>
</h2>
<div id="c-2" class="accordion-collapse collapse" aria-labelledby="h-2">
<div class="accordion-body">
TO BE
</div>
</div>
</div>
</div>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/js/bootstrap.bundle.js"></script>
Click the "Load" button, I can get the Accordion successfully, and I can also expand each item, but then I cannot collapse the expanded items.
With another test, I put the accordion in the Index.cshtml directly (without using a Partial View ).
Index.cshtml
Exactly the same code with _PartialView.cshtml
And the Accordion works smoothly (can expand and collapse).
Could you help me on this strange behavior?
The css file and js files shouldn't be present in the _PartialView.cshtml file. The strange behavior (cannot collapse after expanded) was fixed after removing those files.
New code for _PartialView.cshtml
#{
Layout = null;
}
<div class="accordion" id="2">
<div class="accordion-item">
<h2 class="accordion-header" id="h-1">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c-1" aria-expanded="false" aria-controls="c-1">
First Button
</button>
</h2>
<div id="c-1" class="accordion-collapse collapse" aria-labelledby="h-1">
<div class="accordion-body">
TO DO
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="h-2">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#c-2" aria-expanded="false" aria-controls="c-2">
Second Button
</button>
</h2>
<div id="c-2" class="accordion-collapse collapse" aria-labelledby="h-2">
<div class="accordion-body">
TO BE
</div>
</div>
</div>
</div>

passing parameters <button type="button"> from view to controller

I have such a code view:
<section>
#foreach (var request in request_list)
{
<div style="display:inline">
<button class="checkbox checked" type="button" >#request.Message</button>
</div>
}
</section>
and javascript:
$('.checkbox').click(function () {
$(this).toggleClass('checked');
});
How do I get the controller if the class of the button checked?
you can use $.ajax
you find more information on http://api.jquery.com/jquery.ajax/

Bootstrap ui empty carousel

I have some strange issue. I use an carousel from bootstrap ui in a modal box from bootstrap. At the beginning is init the images for the carousel. Then i click on a button to show the modal box. This time they appear correctly. But then i reinit the carouseldata (Switch to other data) and open the carousel again and then he is empty. Is there an possible solution for this?
Here you can a example of it: http://plnkr.co/edit/YASfl9nF0cxqlytFjjI0?p=preview
Click first on click me and then you see the modal box. Close the modal box and switch from data and open it again.
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="myTalkModalLabel">Title</h4>
</div>
<div class="modal-body">
<carousel interval="myInterval">
<slide ng-repeat="slide in getImages()">
<img ng-src="slide.image" />
</slide>
</carousel>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
var app = angular.module('plunker',['ui.bootstrap']);
app.controller('MainCtrl', function($scope) {
$scope.myInterval = 2000;
$scope.images = ["http://nautisme.nc/photos.nautisme.nc/201410/o_193fo6a4ckel17ml1bvif3lo9ki.jpg","http://nautisme.nc/photos.nautisme.nc/201410/o_193fo6a4c1t8t79i15qo99l1jqlj.jpg","http://nautisme.nc/photos.nautisme.nc/201410/o_193fo6a4davv1tplqkf24f1h4vk.jpg"];
var images2 = ["http://nautisme.nc/photos.nautisme.nc/201410/o_193fo6a4dg9gqgvt6o60l8dl.jpg","http://nautisme.nc/photos.nautisme.nc/201410/o_193fo6a4d59tal51dkp1ask69nm.jpg","http://nautisme.nc/photos.nautisme.nc/201410/o_193fo6a4e6st4vcoqii8r1vpgn.jpg","http://nautisme.nc/photos.nautisme.nc/201410/o_193fo6a4e184m10d46264i4buto.jpg"];
$scope.getImages = function(){
return $scope.images;
}
$scope.showModal = function(){
$("#modal").modal("show");
}
$scope.showModal = function(){
$('#modal').modal('show');
}
$scope.switchImages = function(){
var temp = $scope.images;
$scope.images = images2;
images2 = temp;
}
});
Updated Plunker
The main issue is that you're trying to use Bootstrap's jQuery-based plugins (bootstrap.js) in your AngularJS app along with UI-Bootstrap. I swapped your modal for the UI-Bootstrap modal implementation. UI Bootstrap has no dependency on the bootstrap.js, or jQuery for that matter, so I removed both from the page <head> to avoid conflicts.
Maybe it was just a typo in the Plunker but, I also needed to fix the ng-repeat in the carousel. Where you had slide in getImages(), I removed the function and referenced $scope.images with image in images. Further, since $scope.images is an array of image urls, to access them, you just use the expression: {{image}}.
<carousel interval="myInterval">
<slide ng-repeat="image in images track by $index">
<img ng-src="{{image}}" style="width: 100%;" />
</slide>
</carousel>
APP JS:
var app = angular.module('plunker',['ui.bootstrap']);
app.controller('MainCtrl', function($scope, $modal) {
var images2 = ["http://placehold.it/500x300/009999/fff&text=Group%202:%20Image%201", "http://placehold.it/500x300/009999/fff&text=Group%202:%20Image%202", "http://placehold.it/500x300/009999/fff&text=Group%202:%20Image%203"];
$scope.myInterval = 10000;
$scope.images = ["http://placehold.it/500x300/e8117f/fff&text=Group%201:%20Image%201","http://placehold.it/500x300/e8117f/fff&text=Group%201:%20Image%202"];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
imgs: function () {
return $scope.images;
}
}
});
};
$scope.switchImages = function(){
var temp = $scope.images;
$scope.images = images2;
images2 = temp;
};
});
app.controller('ModalInstanceCtrl', function ($scope, $modalInstance, imgs) {
$scope.images = imgs;
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
MARKUP:
<button class="btn btn-primary" ng-click="open()">Launch Modal</button>
<button class="btn btn-primary" ng-click="switchImages()">Switch Image Group</button>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">Title</h3>
</div>
<div class="modal-body">
<carousel interval="myInterval">
<slide ng-repeat="image in images track by $index">
<img ng-src="{{image}}" style="width: 100%;" />
</slide>
</carousel>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
</script>

UI.bootstrap.modal wont open when using latest versions of libraries

I am trying to do this under ASP.NET MVC 5 Visual Studio 2013, with the latest nuget libraries.
AngularJS Core 1.3.8
AngularJS UI Bootstrap 0.12.0
Bootstrap 3.3.1
jQuery 2.1.3
Important files:
App.js
var deviceModule = angular.module("devicesModule", ["ui.bootstrap"]);
var app = angular.module("dxuWebApp", ["devicesModule"]);
DeviceController.js
deviceModule.controller("DevicesController", function ($scope, deviceService, $modal) {
$scope.devices = [];
function init() {
$scope.devices = deviceService.getDevices();
}
init();
$scope.addDevice = function(size) {
var modalInstance = $modal.open({
templateUrl: "newDeviceTemplate.html",
controller: "NewDeviceModelController",
size: size
});
modalInstance.opened.then(function() {
alert('yep');
});
modalInstance.result.then(function (newDevice) {
deviceService.postDevice(newDevice);
}, function () {
});
}
});
deviceModule.controller("NewDeviceModelController", function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close({ name: newDevice.name });
};
$scope.cancel = function () {
$modalInstance.dismiss("cancel");
};
});
newDeviceTemplate.html
<div class="modal-header">
<h2>New Device</h2>
</div>
<div class="modal-body">
<input type="text" data-ng-model="newDevice.name" />
</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>
Index.cshtml
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div data-ng-app="dxuWebApp" data-ng-controller="DevicesController">
<div class="row">
<div class="col-lg-12">
<h2>Devices <a data-ng-click="addDevice()"><span class="glyphicon glyphicon-plus-sign"></span></a></h2>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<ul class="list-inline">
<li data-ng-repeat="device in devices | orderBy: 'name'">
<a href="#">
<div class="device">
<div class="deviceImage">
#*<img alt="device image"/>*#
<span class="glyphicon glyphicon-phone"></span>
</div>
<div class="deviceName">
{{device.name | uppercase}}
</div>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
#section scripts
{
#Scripts.Render("~/bundles/dxuWebApp")
<script type="text/ng-template" id="newDevice.html">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2>New Device</h2>
</div>
<div class="modal-body">
<input type="text" data-ng-model="newDevice.name" />
</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>
</div>
</div>
</script>
}
The references to both ui-bootstrap and ui-bootstrap.tpls are in the _layout page.
I was hoping that when I clicked
<a data-ng-click="addDevice()"><span class="glyphicon glyphicon-plus-sign">
AngularJs magic would happen and I would get a modal on the screen, but nothing happens, no errors or anything like that.
I did put a break point on deviceController.addDevice() and it hit that point and goes through, nothing appear on the screen.
So what wrong with my code?
I had the exact same problem.
I am using MVC 5.0 with AngularJS so the reason it wasn't working ( I was getting a 404 not able to find the modal.html.) was I didn't create a route in the controller for the modal.html or map a view to the controller with the same name as the route.
After properly setting up the Controller and the View it worked.
Sorry there is no code for this since it was just a problem following the MVC process.

Display Image from DB in Modal Bootstrap Window

I'm using ASP.net MVC5 with Bootstrap 3
I have the following View
#model WilhanWebsite.Models.PhotoViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Gallery</h2>
<p>
#Html.ActionLink("Upload Photo", "Create")
<br/>
#for (var i = 0; i < Model.DownloadedImages.Count; i++)
{
<a data-toggle="modal" data-target="#img-thumbnail#i" class="img_modal" href="data:image/jpg;base64,#(Convert.ToBase64String(Model.DownloadedImages[i].ImageData))">
<img id="img-thumbnail#i" class="img-thumbnail" src="data:image/jpg;base64,#(Convert.ToBase64String(Model.DownloadedImages[i].ImageData))" alt="#Model.DownloadedImages[i].Description" />
</a>
}
<div id="modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Title to go here</h3>
</div>
<div class="modal-body">
<img id="modal_img_target">
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>
</p>
When I click an image from the gallery I would like it to display in a modal window.
My problem is, when I click the link, the modal window displays without the image. All the examples I've seen use images from the file system whereas my site uses images from a db via a byte array. I guess the fix may be to change the line of javascript that is assigning the source attribute on the modal image but I've tried various things here without a result. The problem can be seen at the following address: Problem page
** EDIT **
Updated view to use for loop to identify images as suggested. Problem changed, now rather than displaying a blank modal page, the image is displayed on a blank page.
** EDIT Working View **
#model WilhanWebsite.Models.PhotoViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Gallery</h2>
<p>
#Html.ActionLink("Upload Photo", "Create")
<br/>
#for (var i = 0; i < Model.DownloadedImages.Count; i++)
{
<a data-toggle="modal" data-target="#img-thumbnail#i" class="img_modal" href="data:image/jpg;base64,#(Convert.ToBase64String(Model.DownloadedImages[i].ImageData))">
<img id="img-thumbnail#i" class="img-thumbnail" src="data:image/jpg;base64,#(Convert.ToBase64String(Model.DownloadedImages[i].ImageData))" alt="#Model.DownloadedImages[i].Description" />
</a>
}
<div id="modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Title to go here</h3>
</div>
<div class="modal-body">
<img id="modal_img_target">
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>
</p>
<script type="text/javascript">
$('.img_modal').on('click', function (e) {
e.preventDefault();
$("#modal_img_target").attr("src", this);
$("#modal").removeClass("hide");
$('#modal').modal('show');
});
</script>
You need to add the toggle and target to the link:
<a ... data-toggle="modal" data-target="#img-thumbnail1"
Then add the target id to the image:
<img id="img-thumbnail1" class="img-thumbnail"
This means that you will have to add an incrementing number to the loop so that id's are unique.
You can do this like this:
#for (var i = 0; i < Model.DownloadedImages.Count; i++)
{
<a data-toggle="modal" data-target="#img-thumbnail#i" class="img_modal" href="data:image/jpg;base64,#(Convert.ToBase64String(photo.ImageData))">
<img id="img-thumbnail#i" class="img-thumbnail" src="data:image/jpg;base64,#(Convert.ToBase64String(photo.ImageData))" alt="#photo.Description" />
</a>
}
The problem is with your jquery, as you are getting the "#modal_img_target" src value correctly. Your onClick event is hiding the image.
Try this :-
<script type="text/javascript">
$('.img_modal').on('click', function (e) {
e.preventDefault();
$("#modal_img_target").attr("src", this);
$("#modal").removeClass("hide");
$('#modal').modal('show');
});
</script>

Resources