This seems like it should be simple but nothing is in ASP.NET Core MVC. I would simply like to present the results of a query in a table inside a modal popup. The modal is opening but the table is empty. Not just that but the table is getting created before I even click the button to show the modal. I'm hoping some kind person out there can help me.
This is the controller action method:
public async Task<IActionResult> GetStudies(int id)
{
var results2 = (from s in _context.Studies
join sn in _context.StudyNodes on s.Id equals sn.StudyId
where sn.NodeId == id
select new BundleNodeViewModel
{
StudyId = s.Id,
StudyName = s.Name
}).ToList();
return Ok(results2);
}
This is the function calling the action:
getStudies = (url, id) => {
$.ajax({
type: 'GET',
url: url,
data: {
'id': id
},
success: function (res) {
console.log(res);
$("#formModal").find(".modal-body").html(res.Name);
$("#formModal").find(".modal-title");
$("#formModal").modal('show');
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
console.log(response);
alert("error");
}
})
};
And this is the modal popup:
<div id="formModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="close_" style="background-color:transparent; color:aquamarine; border-style:none">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Assigned Studies</h4>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col-md-4">
<form asp-action="Bind" asp-controller="Studies">
<div class="form-group">
<table class="table table-hover" style="height: 300px">
<thead>
<tr class="position-sticky" style="color:aliceblue; background-color:#126E75">
<th class="text-start">
Study
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr class=" table-light">
<td class="text-start">
#item.StudyName
</td>
</tr>
}
</tbody>
</table>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="button" id="btnClosePopup" value="Close" data-dismiss="modal" class="btn btn-danger" />
</div>
</div>
</div>
</div>
I'm really confused about the order in which things are happening. For some reason the code in the modal runs when the parent page is loaded and not when you click the button on the parent page to open the modal. So the model in the foreach() statement is not the model I need it to be. When I click on the open modal button I expect it to go to the controller, get the data and return it to the modal where I can loop through the object and create a table.
Any ideas anyone?
I didn't understand your question but I have tried to do what you might want to do.
we have created dummy data which should you get from the ajax.
If you don not want to open the modal on page load please remove the Document Ready part.
try to place the 'getStudies' function body to your ajax's success block.
$(document).ready(()=>{
getStudies();
});
var data = [
{ 'StudyId': 1,'Name':"STD 10"},
{'StudyId' : 2,'Name':"STD 11"}
];
let getStudies = (url, id) => {
$("#formModal").find("tbody").html('');
$.each(data,(index,val) =>
{
let tr=`<tr class="table-light"><td class="text-start">${val.Name}</td></tr>`;
$("#formModal").find("tbody").append(tr);
});
$("#formModal").modal('show');
};
<html>
<head>
<title>kaushal</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body> <button onClick="getStudies()">open modal</button>
<div id="formModal" style="width:100%;border:1px solid red;" class="modal fade in" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="close_" style="background-color:transparent; color:aquamarine; border-style:none">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Assigned Studies</h4>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col-md-4">
<form asp-action="Bind" asp-controller="Studies">
<div class="form-group">
<table class="table table-hover" style="height: 300px">
<thead>
<tr class="position-sticky" style="color:aliceblue; background-color:#126E75">
<th class="text-start">
Study
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="button" id="btnClosePopup" value="Close" data-dismiss="modal" class="btn btn-danger" />
</div>
</div>
</div>
</div>
</body>
</html>
Related
I am trying to render partial view from controller on button click event to view the details. But unfortunately its not working.
My Controller Action
OwnerController.cs
public IActionResult ShowpopUp(int id) {
var venue = _context.Venues.FirstOrDefault(x=>x.Id==id);
return PartialView(venue);
}
My View All.cshtml
#model List<Venue>
<table class="table table-hover">
<thead>
<th> Property Name </th>
<th colspan="2">Action</th>
</thead>
<tbody>
#foreach(var x in Model)
{
<tr>
<td>
#x.Name
</td>
<td>
<a class="btn btn-default btn-sm" id="#x.Id" onclick="Details(this.id)">Show</a>
</td>
</tr>
}
</tbody>
</table>
<script>
function Details(id)
{
$.get("#Url.Action("ShowpopUp","Owner")/"+id,
function(data) {$('.modal-body').html(data);})
$("#myModal").modal("show");
}
$('#myModal').on('hidden.bs.modal', function(e){
$('.modal-body').html("");
})
}
</script>
myModal
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Details</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
The following example should help achieve your requirement of rendering partial view as modal popup using jQuery Ajax, please check it.
All.cshtml
#model IEnumerable<Venue>
#{
ViewData["Title"] = "All";
}
<h1>All</h1>
<table class="table table-hover">
<thead>
<th> Property Name </th>
<th colspan="2">Action</th>
</thead>
<tbody>
#foreach (var x in Model)
{
<tr>
<td>
#x.Name
</td>
<td>
<a class="btn btn-default btn-sm" id="#x.Id" onclick="Details(this.id)">Show</a>
</td>
</tr>
}
</tbody>
</table>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Details</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
#section scripts{
<script>
function Details(id) {
$.get("#Url.Action("ShowpopUp","Owner")/" + id,
function (data) {
$('.modal-body').html(data);
});
$("#myModal").modal("show");
}
</script>
}
ShowpopUp action
public IActionResult ShowpopUp(int id)
{
var venue = _context.Venues.FirstOrDefault(x => x.Id == id);
//specify the name or path of the partial view
return PartialView("_VenueDetail", venue);
}
_VenueDetail.cshtml (partial view under Views/Shared folder)
#model Venue
<h1>Venue Details</h1>
<h2>Id: #Model.Id</h2>
<h2>Name: #Model.Name</h2>
Test Result
I'm trying to get to grips with ViewComponents but having trouble trying to get the ViewComponent to reload on a button click. Whats the correct way to handle this?
Initially on the page loading it looks OK like this
In my controller I have
public IActionResult ReloadViewComponent(int characterRegionId, int materialTypeId)
{
return ViewComponent("MarketOrderComponent", new { characterRegionId, materialTypeId});
}
and in my razor view I'm passing parameters to the ReloadViewComponent method
<td><button class="btn btn-sm btn-outline-primary" value="#material.MaterialTypeID" onclick="location.href='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'">View</button></td>
full razor view
<body>
<div class="row" style="margin-top:5px;">
<div class="col-lg-4 col-md-12">
<div class="card" style="margin-bottom:0; ">
<div class="header" style="margin-bottom:55px;">
<h2 class="text-primary">Blueprint Breakdown</h2>
</div>
<div class="body">
<div>
<h5 class="text-center">#Model.BlueprintName</h5>
</div>
<div class="row text-center">
<div class="col-6 border-right pb-4 pt-4" style="padding-top:0px !important; padding-bottom:0px !important;">
<img src="#Model.ImageUrl" alt="#Model.BlueprintName">
</div>
<div class="col-6 pb-4 pt-4" style="padding-top:0px !important; padding-bottom:0px !important;">
<img src="#Model.ProductImageUrl" alt="#Model.BlueprintName">
</div>
</div>
<div class="text-center" style="margin-top:5px;">
<text style="font-size:small;">Material Quantity Based on Manufacturing Efficiency</text>
<br />
<text style="font-size:small;">Price Based on Lowest Region Market Sell Orders</text>
<br />
<text style="font-size:small;">Current Region is <span class="text-green">#Model.CharacterRegionName</span></text>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover table-custom spacing5">
<thead>
<tr>
<th></th>
<th>Material</th>
<th>Quantity</th>
<th>Price</th>
<th>Market</th>
</tr>
</thead>
<tbody>
#foreach (var material in Model.RequiredMaterials)
{
<tr class="text-cente" style="font-size:small;">
<td><img src="#(String.Format("{0}{1}{2}", "https://imageserver.eveonline.com/Type/", material.MaterialTypeID, "_32.png"))" /></td>
<td>#material.TypeName</td>
<td>#material.Quantity</td>
<td>#material.MaterialCost</td>
<td><button class="btn btn-sm btn-outline-primary" value="#material.MaterialTypeID" onclick="location.href='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'">View</button></td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
</div>
but when clicking the view button to reload the ViewComponent it is rendered like this.
Note by using the ViewComponent() controller method, your client only gets the component part of the view. So instead of changing the browser's current location, you should send an ajax request and dynamically replace the right side content.
Add an id='MarketOrderComponent'attribute so that we can reference this element later:
<div id='MarketOrderComponent' class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
And change the button click event handler to send an ajax request. For example, in order to reload the market order component, you can change your code as below:
<script>
function reload(url){
return $.ajax({
method:"get",
url:url,
success:function(resp){ $('#MarketOrderComponent').html(resp);},
});
}
</script>
<div class="card" style="margin-bottom:0; ">
...
</div>
<div class="table-responsive">
...
<tbody>
#foreach (var material in Model.RequiredMaterials)
{
<tr class="text-cente" style="font-size:small;">
<td><img src="#(String.Format("{0}{1}{2}", "https://imageserver.eveonline.com/Type/", material.MaterialTypeID, "_32.png"))" /></td>
<td>#material.TypeName</td>
<td>#material.Quantity</td>
<td>#material.MaterialCost</td>
<td>
<button class="btn btn-sm btn-outline-primary"
value="#material.MaterialTypeID"
onclick="var link='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'; event.preventDefault(); reload(link)"
>
View
</button>
</td>
</tr>
}
</tbody>
...
</div>
<div id='MarketOrderComponent' class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
After clicking "Advanced search" button i want to open a modal from a partial view where i can apply custom search
Here is my Index.cshtml page for showing data table
#model SmartAdmission.Web.Areas.Admin.Models.InstituteViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
}
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">Program Level List</h3>
</div>
<div class="box-body">
#if (TempData["Message"] != null)
{
<div class="alert alert-#TempData["alertType"]">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
#TempData["Message"]
</div>
}
#*<input type="hidden" id="hiddenProvinceId" />*#
<table id="instituteTable" class="table table-bordered table-striped">
<thead>
<tr>
<th>
<button type="button"
class="btn btn-default btn-md" data-toggle="modal"
data-target="#advancedSearchModal"
id="advancedsearch-button">
<span class="glyphicon glyphicon-search"
aria-hidden="true"></span> Advanced Search
</button>
</th>
</tr>
<tr>
<th>Institute Name</th>
<th>Province</th>
<th>Course Name</th>
<th>Program Level</th>
<th>Tution Fee</th>
<th>Ielts</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#{
foreach (var institute in Model.Institutes)
{
<tr>
<td>
#Html.DisplayFor(m => institute.InstituteName)
</td>
<td>
#Html.DisplayFor(m => institute.Province.Name)
</td>
#foreach (var discipline in institute.Disciplines)
{
foreach (var course in discipline.Courses)
{
<td>
#Html.DisplayFor(m => course.CourseName)
</td>
<td>
#Html.DisplayFor(m => course.ProgramLevel.Name)
</td>
<td>
#Html.DisplayFor(m => course.TutionFeePerYear)
</td>
<td>
#Html.DisplayFor(m => course.IeltsMinRequirement)
</td>
}
}
<td>
<a href="#Url.Action("EditInstitute", "Institute" , new { id = institute.Id }, null)" class="btn">
<i class="glyphicon glyphicon-edit"></i>
</a>
<i class="glyphicon glyphicon-trash"></i>
</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form action="/Admin/Institute/DeleteInstitute" method="post">
<div class="modal-header">
<h5 class="modal-title">Delete Item</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Do you want to delete this record?</p>
<input type="hidden" id="id" name="id" value="" />
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-danger">Yes, Delete!</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>
</form>
</div>
</div>
</div>
#section scripts
{
<script>
$(document).ready(function () {
$('#instituteTable').DataTable()
});
$(function () {
$("#mydialog").dialog({
modal: true,
width: "800px",
autoOpen: false
});
});
function ConfirmDelete(id) {
$("#id").val(id);
$('.modal').modal('show');
}
</script>
}
This is my partial view
#model SmartAdmission.Web.Areas.Admin.Models.AdvanceSearchModel
<div id="advancedSearchModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form action="/Admin/Institute/GetCustomInstitute" method="post">
<div class="modal-header">
<h5 class="modal-title">Advance Search</h5>
#*<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>*#
</div>
<div class="modal-body">
#Html.TextBoxFor(m=>m.InstituteName)
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-danger">Yes, Delete!</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>
</form>
</div>
</div>
</div>
i have tried ajax call on button click and refer the url to the action which return a partial view but that didn't work for me.
I have readed a lot of blogs and articles about showing MVC partial views using Boostrap modals. It seems that I have exactly what I'm seen on the material consulted but still it doesn't show the modal. I just need to show the partial view with the Album details in a modal. The controller is working fine when I load the URL through the browser.
This is the Index HTML code where the modal is shown:
<tbody>
#foreach( var album in Model.Albums)
{
<tr data-toggle="modal" data-target="#albumModal" data-url="#Url.Action("Album", new { id = album.Id })">
<td>#album.Title</td>
<td>#album.Artist</td>
<td>#album.Genre</td>
<td>#album.Year</td>
</tr>
}
</tbody>
Partial View
<div class="modal fade" id="albumModal" tabindex="-1" role="dialog" aria-labelledby="albumModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="albumModalLabel">Album Details</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4">
<div class="row">
<label>Album<input class="form-control" type="text" id="title" /></label>
</div>
<div class="row">
<label>Artist <input class="form-control" type="text" id="artist" /></label>
</div>
<div class="row">
<label>Genre <input class="form-control" type="text" id="genre" /></label>
</div>
<div class="row">
<label>Year <input class="form-control" type="text" id="year" /></label>
</div>
</div>
<div class="col-md-8">
<table class="table table-condensed table-striped">
<thead>
<tr>
<th>Track</th>
<th>Song Title</th>
<th>Length</th>
</tr>
</thead>
<tbody class="tracks"></tbody>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
HomeController
[HttpGet]
public ActionResult Album(int? id)
{
if (id == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var albumInfo = _service.GetAlbumInfo((int) id);
if (albumInfo == null) return HttpNotFound();
return PartialView("_Album", albumInfo);
}
Script
$(document).ready(function() {
$('.list-element').click(function () {
debugger;
var $buttonClicked = $(this);
var url = $buttonClicked.attr('data-url');
$.get(url, function (data) {
$('#albumContainer').html(data);
$('#albumModal').modal('show');
});
});
});
In almost all of the SO questions counsulted, they wasn't using data-target but I am. What do I need to modify to achieve that the modal shows?
VIEW
#model ShowModal
<table>
<tbody>
<tr data-toggle="modal" data-target="#albumModal" data-url="#Url.Action("Album", new { id = album.Id })">
<td>#album.Title</td>
<td>#album.Artist</td>
<td>#album.Genre</td>
<td>#album.Year</td>
</tr>
</tbody>
</table>
<!-- Modal -->
<div class="modal" id="albumModal" tabindex="-1" role="dialog" aria-labelledby="albumModal">
#Html.Partial("_albumPartial", Model)
</div>
CONTROLLER
[HttpGet]
public ActionResult Album(int? id)
{
ShowModal modal = new ShowModal();
var albumInfo = _service.GetAlbumInfo((int) id);
modal.Info1 = albumInfo.Info1;//and other fields
return PartialView("_albumPartial", modal);
}
SCRIPT
<script>
$(document).ready(function () {
$("#albumModal").on("show.bs.modal", function (e) {
var button = $(event.relatedTarget) // Button that triggered the modal
var url = button.data('url') // or button.attr("data-url") or get here just the id and create the URL here
$.get(url, function (data) {
$('#albumModal').html(data);
$('#albumModal').modal('show');
});
});
});
</script>
I have two bootstrap modals which is a modal within a modal. Modal 2 contains search list. Which means, there is a search box for user to input a name. There is also a table to display the retrieved list. I would like to put a select button in the table. So when I clicked the select button, modal 2 closed. Only modal1 is left with data from selected rows. The first problem I have is in modal2 on how to submit the search word and retrieve the list of result in table. I tried the code below but it keeps refeshing my page in which I have top re-open the modal to see the result. The search button worked since it displays the data. I want to submit the search word without refreshing my page. At the same time, the content in my modal should be updated.
<div class="modal fade" id="modal1" role="dialog" >
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Modal 1</h4>
</div>
<div class="modal-body">
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#modal2">Open second modal</button>
<div class="modal-footer">
</div>
</div>
</div>
</div>
<div class="modal fade in" id="modal2" role="dialog" >
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="modal2">Modal 2</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form" method="get"
<div Class="form-group">
<Label Class="control-label col-md-2">Name</Label>
<div Class="col-sm-4">
<input type="text" name="strName" Class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" id="btnSearch" value="search" class="btn btn-default">Search</button>
</div>
</div>
</form>
<div class="panel-body">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="example">
<thead>
<tr>
<th class="col-md-1" style="text-align:center">ID</th>
<th class="col-md-8" style="text-align:center">Name</th>
</tr>
</thead>
<tbody>
#for Each Item In Model
#<tr>
<td class="col-md-8">#Html.DisplayFor(Function(modelItem) Item.name)</td>
</tr>
Next
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<Button type="button" Class="btn btn-primary" data-dismiss="modal">Close</Button>
</div>
</div>
</div>
</div>