How to get a Popup Window with Partial View in MVC 5 - c#

There seems to be a couple ways to do it. I really wanted this video to work for me. https://www.youtube.com/watch?v=oHWEs8XWA2U
Searching the web, I found it hard to find this question being asked recently, so I am wondering if newer and improved (easier) ways have been implemented.
Here is my Home controller
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult PartialViewTest()
{
return PartialView();
}
[HttpPost]
public ActionResult PartialViewTest(Person person)
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}
Here is my view I want the pop up on
#{
ViewBag.Title = "Contact";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="btn-block" style="width:225px">Modal </button>
<div class="modal fade" id="myModal" role="dialog" data-url='#Url.Action("PartialViewTest","Home")'></div>
<script type="text/javascript">
$(document).ready(function () {
$('.btn-block').click(function () {
var url = $('#myModal').data('url');
$.get(url, function (data) {
$("#myModal").html(data);
$("#myModal").modal('show');
});
});
});
</script>
Here is my partial view
<div class="container">
<div class="row">
<div class="col-sm-4"></div>
<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="myModal-label">Bootstrap Dialog</h4>
<div>
<div class="modal-body">
<div class="form-group">
<input type="text" placeholder="enter name" class="form-control" id="text" name="text" />
</div>
<div class="form-group">
<input type="text" placeholder="enter name id" class="form-control" id="text" name="text" />
</div>
<div class="form-group">
<input type="text" placeholder="adress" class="form-control" id="text" name="text" />
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" id="btnOK" onclick="">OK</button>
<button class="btn btn-default" data-dismiss="modal" id="btnCancel">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
When I click the button as seen in the image above. Nothing happens. Why doesn't the popup view appear?
If this is not the best way to go about it, could you provide a link to a tutorial for the most professional, proper, and easiest way to accomplish this?

If this is Bootstrap then your partial view's modal HTML is broken. modal-body and modal-footer are under modal-header. I'm pretty sure modal-header, modal-body and modal-footer needs to be direct children of modal-content and that needs to child of modal-dialog and that needs to be child of modal and you have those container divs there wrapping them.
Edit:
Your problem is that you are loading your jquery and bootstrap after you try to use them. That <script> is run before your scripts are loaded. You need to put that into scripts section.
Camilo Terevinto notice you need remove jQuery script tag from your view. You already have jQuery in a bundle.

"When I click the button as seen in the image above. Nothing happens. " -> I have just tried your code and it works, modal is openning. Has Camilo Terevinto comment you should press 12 in chrome, and check for errors in console tab.
After modal open, what is missing in your code?
Use "Person" model in modal, create a post form and set button ok to submit
#model Person //Should contain person model namespace
#Html.BeginForm("PartialViewTest", "Home", FormMethod.Post)
{
<div class="container">
<div class="row">
<div class="col-sm-4"></div>
<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="myModal-label">Bootstrap Dialog</h4>
<div>
<div class="modal-body">
<div class="form-group">
#Html.TextBoxFor(p => p.name)
</div>
<div class="form-group">
#Html.TextBoxFor(p => p.adress)
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" id="btnOK" onclick="">OK</button>
<button class="btn btn-default" data-dismiss="modal" id="btnCancel">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
}
Your post action should redirect to Index.
[HttpPost]
public ActionResult PartialViewTest(Person person)
{
/* do things */
return RedirectToAction("Index");
}

Related

I've created a modal component and that doesn't work

I'm new in coding with ASP.NET Core. I created a CRUD functions in my application and then i decided to change some rules like Create New do not navigate to another tab it will be navigated to a component modal. So I did the steps that it shown in a tutorial but I didn't get a result .
Here's the page :
This is the code in index.cshtml:
#model IEnumerable<PermissionManagement.MVC.Models.Segment>
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="PlaceHolderHere"></div>
<button type="button" class="btn btn-primary" data-toggle="ajax-modal" data-target="#addSegment" asp-action="_SegmentModelPartial" data-url="#Url.Action("Create")"> Create </button>
And this is the code wrote it in SegmentModelPartial:
#model Segment
<div class="modal fade" id="addSegment">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addSegmentLabel">Modal title</h5>
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close">
<span>x</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="SName" class="control-label">Nom</label>
<input asp-for="SName" class="form-control" />
<span asp-validation-for="SName" class="text-danger"></span>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group ">
<label asp-for="SRang" class="control-label">Rang</label>
<input asp-for="SRang" class="form-control" />
<span asp-validation-for="SRang" class="text-danger"></span>
</div>
</div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" data-save="modal">Save changes</button>
</div>
</div>
</div>
</div>
This is my code in site.js:
$(function () {
var PlaceHolderElement = $('#PlaceHolderHere');
$('button[data-toggle="ajax-modal"]').click(function (event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
PlaceHolderElement.html(data);
PlaceHolderElement.find('.modal').modal('show');
})
})
PlaceHolderElement.on('click', '[data-save="modal"]', function (event) {
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = form.serialize();
$.post(actionUrl, sendData).done(function (data)){
PlaceHolderElement.find('.modal').modal('hide');
})
})
})
And finally this is the controller:
[HttpGet]
public IActionResult Create()
{
Segment seg = new Segment();
return PartialView("_SegmentModelPartial", seg);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Segment segment)
{
_context.Add(segment);
await _context.SaveChangesAsync();
return PartialView("_SegmentModelPartial", segment);
}

Refresh PartialView in MVC Controller

I'm trying to refresh my Partial View after submitting a form which will be processed in my controller. The problem is that whenever I try to refresh it form my controller, I get redirected to a blank page with content from the Partial View.
Partial View
#model Smarty.Viewmodels.BugViewModel
<div class="modal fade" id="bugModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Bug Reporting Tool</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span>×</span>
</button>
</div>
<form asp-controller="Smarty" asp-action="SendBugReport" enctype="multipart/form-data">
#if (!string.IsNullOrWhiteSpace(ViewBag.message))
{
if (!ViewBag.IsError)
{
<span class="border border-success text-success">#ViewBag.message</span>
}
else
{
<span class="border border-danger text-danger">#ViewBag.message</span>
}
}
<div class="modal-body">
<label asp-for="Description" class="control-label"></label>
<textarea asp-for="Description" class="form-control"></textarea>
<span asp-validation-for="Description" class="text-danger"></span>
<label asp-for="FormFile" class="control-label"></label><br />
<input asp-for="FormFile" type="file" />
<span asp-validation-for="FormFile" class="text-danger"></span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Schliessen</button>
<button type="submit" id="BugReportBtn" class="btn btn-success">Bug Report senden</button>
</div>
</form>
</div>
</div>
</div>
Controller
public async Task<IActionResult> SendBugReport(BugViewModel viewModel)
{
//Process Form
return PartialView("BugModal", viewModel);
}
Thanks in advance!
I get redirected to a blank page with content from the Partial View.
That is expected because you use return PartialView() which will return the simple partial html to render it into the view.
I want to refresh the Partial View with content like Error Messages, Success messages etc
You could not get #ViewBag.message from the SendBugReport action, it is passed from the action of main page.
As the comment has said that, first of all, you could use ajax to submit the form to SendBugReport action.Then the action return message and isError json data to ajax success function. Finally, you render message on the view based on the value of isError:
1.Partial View (Views/Shared/BugModal.cshtml)
#model BugViewModel
<div class="modal fade" id="bugModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Bug Reporting Tool</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span>×</span>
</button>
</div>
<form id="myForm" asp-controller="Smarty" asp-action="SendBugReport" enctype="multipart/form-data">
<div id="result"></div>
<div class="modal-body">
<label asp-for="Description" class="control-label"></label>
<textarea asp-for="Description" class="form-control"></textarea>
<span asp-validation-for="Description" class="text-danger"></span>
<label asp-for="FormFile" class="control-label"></label><br />
<input asp-for="FormFile" id="FormFile" name="FormFile" type="file" />
<span asp-validation-for="FormFile" class="text-danger"></span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Schliessen</button>
<button type="button" id="BugReportBtn" class="btn btn-success">Bug Report senden</button>
</div>
</form>
</div>
</div>
</div>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script>
$('#BugReportBtn').on('click', function (event) {
var url = "/Smarty/SendBugReport";
var description = document.getElementById("Description").value;
var fileInput = $('#FormFile')[0];
var formFile = fileInput.files[0];
var formData = new FormData();
formData.append("Description", description);
formData.append("FormFile", formFile);
$.ajax({
type: "POST",
url: url,
data: formData,
dataType: "json",
processData:false,
contentType: false,
success: function (data) {
if (!data.isError) {
$("#result").html("<span class='border border-success text-success'>" + data.message + "</span>");
} else {
$("#result").html("<span class='border border-danger text-danger'>" + data.message + "</span>");
}
$('#bugModal').modal('show');
}
});
});
</script>
2.Action
[HttpPost]
public async Task<JsonResult> SendBugReport(BugViewModel viewModel)
{
//Process Form
string message;
bool isError;
//set data to message and isError
return Json(new { message, isError });
}

PartialView is returning fullpage, only rendering the form

I'm trying to rerender the partialview ONLY in my modal, after the ajax request.
But when I get the response everything is rerendered and the only thing showing is the partialview..
PartialView:
#{
var bidModel = new BidModel();
}
<div>
<div class="row">
#if (ViewBag.Message != null)
{
<div class="alert alert-success">#ViewBag.Message</div>
}
</div>
<span class=" alert-danger">
#Html.ValidationSummary()
</span>
<div class="form-group">
<input name="Bidder" asp-for="#bidModel.Bidder" value="#User.Identity.Name" type="hidden" />
<input name="AuctionId" asp-for="#bidModel.AuctionId" type="hidden" id="auctionId" />
<label asp-for="#bidModel.Amount" />
<input name="Amount" asp-for="#bidModel.Amount" />
</div>
</div>
Controller:
public async Task<IActionResult> AddBid(BidModel Bid)
{
var result = await _bidBusinessInterface.CreateBidAsync(Bid, Bid.AuctionId);
if (result)
{
ViewBag.Message = "Bud lagt!";
}
else
{
ViewBag.Message = "Bud förlågt!";
}
return PartialView("_BidCreatorPartial");
}
And then we have the modal where i want to rerender the partialview:
<div class="modal fade" id="bidModal" tabindex="-1" role="dialog" aria-labelledby="bidModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="bidModalLabel">Lägg bud</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form asp-action="AddBid" asp-controller="Home" method="POST" data-ajax="true" data-ajax-update="frmBid">
<div id="frmBid">
<partial name="_BidCreatorPartial" model="#bidModel"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Avbryt</button>
<button type="submit" class="btn btn-primary">Spara</button>
</div>
</form>
</div>
</div>
</div>
</div>
As I said, what I want to accomplish is to rerender the form, so that the message can be shown in the modal.
What happens is it renders a whole white page with only the form and the message.
You didn't actually post your form itself, but my best guess is that you're just doing a standard old HTML form post. That's always going to cause the page to change, and then since you're only returning a partial view, and not a full view, your page gets replaced with just that snippet of HTML.
What you want requires AJAX. You need to catch the submit event on the form, and instead of letting it go as normal, you make an AJAX request with the form data serialized. Then, in the success callback of your AJAX request, you'll need to query the element you want to replace the HTML of from the DOM and change its innerHTML value to what's returned from the AJAX request.
Since an ASP.NET Core project comes with jQuery out of the box, I'm going to assume you can use that:
$('#MyForm').on('submit', function (e) {
e.preventDefault();
var $form = $(this);
$.ajax({
url: $form.attr('action'),
method: 'post',
data: $form.serialize(),
success: function (html) {
$('#frmBid').html(html);
}
});
});

MVC - Multiple Modals of Dynamyc Content?

I have a best practice question. I have a page with many chat rooms.
When you click on a chat room a modal prompts asking for a nickname and VIA post gets the information and takes you to the room.
The questions is, I have multiple rooms so I have one modal:
#using (Html.BeginForm("DebateV2", "Home", FormMethod.Post)){
#Html.AntiForgeryToken()
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content ">
<div class="modal-header modal-header-primary">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 id="modalTitle">
<span class="glyphicon glyphicon-lock pull-left"></span> #Resources.IngresoALaGrieta
</h4>
</div>
<div class="modal-body" style="padding:40px 50px;">
<form role="form">
<div class="form-group">
<label for="Nickname"><span class="glyphicon glyphicon-user"></span> #Resources.ElejiNombre</label>
<input type="text" class="form-control" id="Nickname" name="Nickname" placeholder="#Resources.ElejiNick">
</div>
<input type="hidden" id="Debate" name="Debate" />
<input type="hidden" id="Team" name="Team" />
<button type="submit" id="connect" disabled="disabled" class="btn btn-success btn-block"><span class="glyphicon glyphicon-fire"></span> #Resources.Entrar</button>
</form>
</div>
</div>
</div>
</div>
}
And when the button is clicked it appends some information about the chatroom to the modal form, like this:
$('.open-modal')
.each(function() {
var $this = $(this);
$this.on("click",
function() {
$("#Debate").val($(this).data('debate'));
$("#Team").val($(this).data('team'));
$("#modalTitle").val($(this).data('titulo'));
$('#myModal').modal('show');
});
});
Now I want to send some information via QUERYSTRING so I have in the browser address the name of the room like this:
www.debates.com/debate?debate=debate-name
what is the best practice to do that? I am really lost.

Partial View Not Rendering Inside View

I have a partial view inside another partial view which, when first running the application loads as expected, but when you click to reload the view to push a model into it, it then renders as it's own completely separate view as if it weren't a partial.
I'm calling it inside an Ajax Form like so (On the Action link click, the _GetSearchModal method):
<div id="modelSearch">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<i class="fa fa-search"></i> Search by Model / Manufacturer
</h3>
</div>
<div class="panel-body">
#using (Ajax.BeginForm("_GetSearch", "Home", new AjaxOptions() {UpdateTargetId = "modelSearch"}))
{
#Html.AntiForgeryToken()
<div class="input-group">
#Html.TextBox("search", null, new {id = "name", #class = "form-control", placeholder = "Please enter a manufacturer or model"})
<span class="input-group-btn">
<button id="search" class="btn btn-default" type="submit"><i class="fa fa-search"></i></button>
</span>
</div>
if (Model != null)
{
<div id="searchResults" class="fade-in two">
#foreach (var s in Model)
{
<div class="result">
#switch (s.ResultType)
{
case "Man":
#s.Manufacturer
break;
case "Mod":
#Html.ActionLink(s.Manufacturer + Html.Raw(s.Model), "_GetSearchModal", "Home", new {id = s.MachineId}, new {toggle = "modal", data_target = "#MachineModal"})
<img src="~/Images/General/Tier/#(s.TierId).png" alt="Tier #s.TierId"/>
break;
}
</div>
}
</div>
}
}
</div>
</div>
</div>
<!-- Product Modal -->
<div class="modal fade" id="MachineModal" tabindex="-1" role="dialog" aria-labelledby="MachineModalLabel">
#Html.Partial("_SearchModal", new MachineModal())
</div>
And the view itself should load a different view model (MachineModal):
#model SpecCheck.Portals.Web.UI.ViewModels.MachineModal
#if (Model != null)
{
<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="MachineModalLabel">#Model.Manufacturer #Model.Model</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<img src="~/Images/#Model.Manufacturer/logo.png" alt="#Model.Manufacturer" /><br />
Wiki
</div>
<div class="col-md-6">
#Model.Catagory1 | #Model.Category2<br /><br />
<span class="modal-em">Region: </span> #Model.Region<br />
<span class="modal-em">Status: </span>#Model.Status<br />
<span class="modal-em">Spec Date: </span>#Model.SpecDate
</div>
</div>
</div>
<div class="modal-footer">
View
Quick Compare
Compare
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
}
And the action to do this in the "Home Controller" is:
public ActionResult _GetSearchModal(string machineId)
{
using (var db = new SpecCheckDbContext())
{
MachineModal machine = new MachineModal();
var searchHelper = new SearchHelper(db);
//Get Machine Details
var dbResults = searchHelper.SearchModal(Convert.ToInt32(machineId));
machine.Model = dbResults.Model;
machine.Catagory1 = dbResults.Catagory1;
machine.Category2 = dbResults.Category2;
machine.Manufacturer = dbResults.Manufacturer;
machine.Region = dbResults.Region;
machine.SpecDate = dbResults.SpecDate;
machine.Status = dbResults.Status;
machine.MachineId = dbResults.MachineId;
machine.ManufacturerId = dbResults.ManufacturerId;
var model = machine;
return PartialView("_SearchModal", model);
}
}
First thing I checked was the scripts, they're all in place when the layout page loads so it's not a script issue. Not sure what to change to even try at this point so any suggestions welcome.
In the ajax form:
_GetSearch => _GetSearchModal(name of the action)
Try to return machine to the partial view? Maybe see in the View hierarchy, is there is second _SearchModal partial view, that gets returned?

Categories