Not able to load partial view as modal when called from _Layout - c#

In my Core 2.0 project I am trying to load a partial view to modal div when called from _Layout.cshtml but nothing happens. On click of Create New User I am trying to load partial view on modal popup. Below is code-
//_Layout.cshtml
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
<li>Create New User</li>
//Index.cshtml of Home
<div class="modal fade" id="AppointmentSchedule" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header btn-primary">
<h5 class="modal-title" id="AppointmentModalLabel"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="ScheduleAppointment"></div>
</div>
</div>
</div>
//Javascript
function CreateUser() {
var url = appSetting + "Home/CreateUser";
$.ajax({
type: "GET",
contentType: "application/json",
url: url,
data: null,
dataType: "html",
async: false,
success: function (data) {
$("#ScheduleAppointment").html('');
$("#ScheduleAppointment").html(data);
$("#AppointmentSchedule").modal('show');
},
error: function (result) {
$("#divScheduleAppointment").html('');
}
})
}
//Home Controller
public ActionResult CreateUser()
{
return PartialView("_CreateUserHome");
}
On debugging I realize that after Ajax success it calls Index action method of Home controller(that should not be) and may be it is causes page refresh and popup may get close. But what is it's solution.

With your current code, when user clicks on the anchor tag, the browser do a normal link click behavior, which is navigating to the href attribute value of the clicked link element. If you want show the modal dialog instead of that, you should prevent this default behavior.
You may pass an event object to the CreateUser method
Create New User
and in your method, call the preventDefault method, which will stop the normal link click behavior(navigating to to the href value)
function CreateUser(e)
{
e.preventDefault();
var url = appSetting + "Home/CreateUser";
$.ajax({
type: "GET",
url: url,
success: function (data)
{
$("#ScheduleAppointment").html(data);
$("#AppointmentSchedule").modal('show');
},
error: function (result)
{
$("#divScheduleAppointment").html('');
}
})
}
A suggestion: If it is not a navigational link, Consider using a button instead of an anchor tag.

Quick solution is to add return false to your event handler:
<li>Create New User</li>
This will suppress default behavior.

Related

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);
}
});
});

Render Partial View in Carousel-Inner Div asp.net MVC

I'm attempting to render a partial view in a Div within the carousel i have created on the home page. The partial view is from a different controller the view code is as seen below. The partial view contains a table which i want to be shown within the carousel div. Currently nothing is being loaded into the div with the code i'm using, i'm not sure what i'm doing wrong. You help would be much appreciated.
Home Index View
#{
ViewBag.Title = "Home Page";
}
<div id="mycarousel" class="carousel slide" data-ride="carousel" style="margin-top: 30px">
<ol class="carousel-indicators">
<li data-target="#mycarousel" data-slide-to="0"></li>
<li data-target="#mycarousel" data-slide-to="1" class="active"></li>
<li data-target="#mycarousel" data-slide-to="2"></li>
</ol>
<div class="carousel-inner" role="listbox">
<div class="item active">
<div id="dvgetpvt">
</div>
</div>
<div class="item">
<p>
NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.
</p>
</div>
</div>
<a class="left carousel-control" href="#mycarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#mycarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
Within the view code i have the following to get the partial view.
<script type="text/javascript">
$.ajax({
url: "/crmPVT/GetPVT",
contentType: "application/html; charset=utf-8",
type: "GET",
dataType: "html"
})
.success(function (result) {
$('#dvgetpvt').html(result);
})
.error(function (xhr, status) {
alert(status);
})
</script>
The crmPVT controller contains the following code for the partial view
crmPVT Controller
public PartialViewResult GetPVT()
{
var all = (from e in db.crmPVT
where e.Report_ID == 1
select e);
var commnorth = (from e in db.crmPVT
where e.Report_ID == 1 &&
e.Team.Contains("Commercial North")
select e);
var team = User.Identity.Name == "*****" ? commnorth : all;
return PartialView(team);
}

How to put Partial View inside Bootstrap Modal?

I want to put a Partial View inside a Bootstrap Modal,
This is the JQuery code I'm using:
function CreateEmployeeModal()
{
var url = $("#btnCreateEmployeeModal").data("mine");
$.ajax({
type: 'get',
url: url
}).success(function (result) {
$(".modal-body").html(result)
$("#MyModal").modal('show')
}).error(function () {
alert("didn't work");
})
}
And this is the Modal code inside the _Layout file:
<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">Modal Header</h4>
</div>
<div class="modal-body" id="divModalBody">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
I'm firing the modal using this button from the Index page, I've created the data-mine attribute to save the url to the Action Method that is returning the PartialView:
<input type="button" class="aslink modal-link" data-toggle="modal"
data-target="#myModal" id="btnCreateEmployeeModal" value="Open Modal" data-mine="#Url.Action("CreateUsingModal")">
This is the controller action method I have to return the Partial View:
public PartialViewResult CreateUsingModal()
{
return PartialView();
}
The operation is having success in ajax, but the modal doesn't show...
I had an error..., I should use a lowercase instead of a uppercase for the id of the modal... The correct way is: $("#myModal").modal('show')
I'll assume your GET endpoint (your method) is returning raw HTML.
A better way of doing this would be for your method to return your data in JSON format and then use that data to populate your modal window:
function CreateEmployeeModal()
{
var url = $("#btnCreateEmployeeModal").data("mine");
$.ajax({
type: 'get',
url: url
}).success(function (result) {
console.log(result); //better than alert
$("#textboxCorrespondingToValue").val(result.valueCorrespondingToTextbox);
$("#MyModal").modal('show');
}).error(function () {
alert("didn't work");
})
}
This way, if you even need to change the html you don't have to change anything in your server side code

My ajax post will not stop running (C#,JQuery,Ajax)

My Ajax call works. It sends data to the database as expected.
However, after it completes this task, it will not call the success or fail function. It just keeps running. I set the timeout for the ajax call but it didn't work.
I have a form in my html page
<form class="form-horizontal" id="signupForm" role="form" method="post" name="signupForm" action="">
<div class="form-group">
<label class="col-xs-3 control-label" for="TextBoxUsername">Username:</label>
<div class="col-xs-9"><input type="text" placeholder="username" id="TextBoxUsername" class="form-control" /></div>
</div>
<div class="form-group">
<label class="col-xs-3 control-label" for="TextBoxPassword">Password:</label>
<div class="col-xs-9"><input type="text" placeholder="password" id="TextBoxPassword" class="form-control" /></div>
</div>
<div class="form-group">
<label class="col-xs-offset-5 control-label" for="selectImage" style="font-weight:bold;font-size:15px;">Choose Your Avatar</label>
</div>
<div class="content">
// I used the Image-Picker jQuery plugin here to create a selection of images and show them as thumbnails
<select name="selectImage" class="image-picker" id="selectImage" form="signupForm">
<option class="grid-item" data-img-src="img1.png" value="img1.png">Image 1</option>
<option class="grid-item" data-img-src="img2.png" value="img2.png">Image 2</option>
<option class="grid-item" data-img-src="img3.png" value="img3.png">Image 3</option>
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</form>
This is my jQuery:
// this is my main jQuery function
$(function () {
// this is my form submit function
$("form").submit(function (e) {
e.preventDefault(); // this stops the form from refreshing the page
create();
});
});
// this function creates an object to be added to the database
function create() {
user = new Object();
user.Username = $("#TextBoxUsername").val();
user.Password = $("#TextBoxPassword").val();
// here I am getting the value of the selected item from <select> div
selectedImage = document.signupForm.selectImage.options[document.signupForm.selectImage.selectedIndex].value;
// this is just to convert the image to base 64 string.
var img = new Image();
img.src = selectedImage;
// draw canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0,0);
var imageURL = canvas.toDataURL();
user.Image = imageURL;
// end base 64 string conversion
$.ajax({
type: "Post",
url: "api/signup", // this url goes to a controller, it works perfectly
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
timeout: 3000, // does not do anything!
success: function () {
// this function is not being called!
$("#lblstatus").text("User was created!");
},
error: function (jqXHR, textStatus, errorThrown) {
// this function is not being called either!
errorRoutine(jqXHR);
}
});
}; // end create function
Like I said, the database is receiving the data just fine. But for some reason, this ajax call will not stop running. If I manually stop the application from the debugger, I can check the database and everything worked. I just need this ajax call to complete.
Try changing the type to button and set an id to it <button type="button" class="btn btn-default" id="submitbtn" >Sign in</button> And handle it by jquery click function $("#submitbtn").click(function () {
create();
});
by that, the page will not refresh even if you don't have the e.preventDefault();
since your using an ajax, the form is not needed anyway. So it can work even if you don't have a form tag
I found the tiny typo culprit.
it was inside the success function. I didn't add the "#" in front of "("lblstatus"). It should have been ("#lblstatus").
silly silly mistake.
Thanks for all the suggestions. It turned out to be a typo afterall.

What's the best way to call a modal dialog in ASP.NET MVC using Twitter Bootstrap?

I'm currently using Twitter's Bootstrap toolkit on a new project and I had a question on the best way to use the modal dialog in ASP.NET MVC3.
Is the best practice to have a Partial that contains the modal's markup and then use javascript to render that onto the page or is there a better approach?
Here goes my little tutorial which demonstrates Twitter's Bootstrap (2.x) modal dialog that works with forms and partials in ASP.Net MVC 4.
To download similar project but targeting MVC 5.1 and Bootstrap 3.1.1 please visit this site.
Start with an empty MVC 4 Internet template.
Add reference to Bootstrap using NuGet
In the App_Start/BundleConfig.cs add the following lines:
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include("~/Scripts/bootstrap.js"));
bundles.Add(new StyleBundle("~/Content/bootstrap").Include(
"~/Content/bootstrap.css",
"~/Content/bootstrap-responsive.css"));
In the Views/Shared/_Layout.cshtml
modify the #styles.Render line so it will look like:
#Styles.Render("~/Content/css", "~/Content/themes/base/css", "~/Content/bootstrap")
and the #Scripts.Render line:
#Scripts.Render("~/bundles/jquery", "~/bundles/jqueryui", "~/bundles/bootstrap")
So far we have Bootstrap prepared to work with MVC 4 so let's add a simple model class MyViewModel.cs to the /Models folder:
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
public class MyViewModel
{
public string Foo { get; set; }
[Required(ErrorMessage = "The bar is absolutely required")]
public string Bar { get; set; }
}
}
In the HomeController Add the following lines:
using MvcApplication1.Models;
//...
public ActionResult Create()
{
return PartialView("_Create");
}
[HttpPost]
public ActionResult Create(MyViewModel model)
{
if (ModelState.IsValid)
{
try
{
SaveChanges(model);
return Json(new { success = true });
}
catch (Exception e)
{
ModelState.AddModelError("", e.Message);
}
}
//Something bad happened
return PartialView("_Create", model);
}
static void SaveChanges(MyViewModel model)
{
// Uncommment next line to demonstrate errors in modal
//throw new Exception("Error test");
}
Create new Partial View in the Views/Home folder and name it _Create.cshtml:
#using MvcApplication1.Models
#model MyViewModel
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Create Foo Bar</h3>
</div>
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { #class = "modal-form" }))
{
#Html.ValidationSummary()
<div class="modal-body">
<div>
#Html.LabelFor(x => x.Foo)
#Html.EditorFor(x => x.Foo)
#Html.ValidationMessageFor(x => x.Foo)
</div>
<div>
#Html.LabelFor(x => x.Bar)
#Html.EditorFor(x => x.Bar)
#Html.ValidationMessageFor(x => x.Bar)
</div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Undo</button>
<button class="btn btn-primary" type="submit">Save</button>
</div>
}
In the Home/Index.cshtml remove the default content from the template and replace it with following:
#{
ViewBag.Title = "Home Page";
}
<br />
<br />
<br />
#Html.ActionLink("Create", "Create", null, null, new { id = "btnCreate", #class = "btn btn-small btn-info" })
<div id='dialogDiv' class='modal hide fade in'>
<div id='dialogContent'></div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
//Optional: turn the chache off
$.ajaxSetup({ cache: false });
$('#btnCreate').click(function () {
$('#dialogContent').load(this.href, function () {
$('#dialogDiv').modal({
backdrop: 'static',
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) {
$('#dialogDiv').modal('hide');
// Refresh:
// location.reload();
} else {
$('#dialogContent').html(result);
bindForm();
}
}
});
return false;
});
}
</script>
}
If you run your application, a nice Bootstrap modal will appear after clicking the Create button on the Home page.
Try to uncomment the SaveChanges() //throw line in HomeController.cs to prove that your controller handled errors will appear correctly in the dialog.
I hope that my sample clarifies a bit whole process of incorporating Bootstrap and creating modals in the MVC application.
Great example, I had to modify slightly for MVC 5 and Bootstrap 3.3.7, I changed the target div tags to the following, otherwise I was just getting the grey background and no modal dialog. Hope this helps someone.
<div id='dialogDiv' class='modal fade' tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div id='dialogContent'></div>
</div>
</div>
</div>
Thanks #zjerry the solution is great but jQuery validation does not work, in order to fix you need to change the function bindForm as follow:
function bindForm(dialog) {
$.validator.unobtrusive.parse('form');
$('form', dialog).submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$('#dialogDiv').modal('hide');
// Refresh:
// location.reload();
} else {
$('#dialogContent').html(result);
bindForm();
}
}
});
return false;
});
}
Notice the first line of the function, because the form is loaded after jQuery validation was initialized.
Many thanks
This really depends on your design, but you should have a template for the modals.
On a single web app for example, you should have a template lying around that you would create a new instance from each time.
Usually on a normal website you would want to store this template inside a js creation function, so that you won't have to send the file to the user each time via http, and they can have it cached.

Categories