I have created a shared component for Model popup and using #ref attribute while registering the component. I am not getting any error but my model popup is not showing.
Below the code for CofirmationBox
#inherits ConfirmModelBoxBase
#if (ShowConfirmationBox)
{
<div class="modal fade show d-block" id="exampleModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Confirm Delete</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Are you sure want to delete the record?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
}
public class ConfirmModelBoxBase : ComponentBase
{
[Parameter] public bool ShowConfirmationBox { get; set; }
[Parameter] public EventCallback<bool> CoonfirmationChanged { get; set; }
public void Show()
{
ShowConfirmationBox = true;
StateHasChanged();
}
}
Registering the Component on My employee list page
<ConfirmModelBoxBase #ref="DeleteConfirmation">
</ConfirmModelBoxBase>
Server side call to show the popup
[Parameter] public ConfirmModelBoxBase DeleteConfirmation { get; set; }
protected void btnDelete_Click()
{
DeleteConfirmation.Show();
}
According to your HTML code, you use bootstrap modal.
You don't need a #ref to open it but some JSInterop:
Add a scripts tags in your _Host.html or index.hmtl to load bootstrap js and its dependency. Bootstrap js required JQuery and Popper.js.
<head>
...
<script src="//code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
Add a js interop file in your wwwroot folder
bootstrapInteropt.js
window.bootstrapInteropt = {
showModal: id => {
$(`#${id}`).modal('show');
},
hideModal: id => {
$(`#${id}`).modal('hide');
}
};
Add a script tag to load this js in your _Host.html or index.hmtl
<body>
<app>
</app>
<script src="bootstrapInteropt.js"></script>
...
</body>
Call the js fonction to show the popup
#inject IJSRuntime _jsRuntime
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" data-backdrop="false">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Confirm Delete</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Are you sure want to delete the record?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
#code {
[Parameter] public EventCallback<bool> CoonfirmationChanged { get; set; }
public Task Show()
{
return _jsRuntime.InvokeVoidAsync("bootstrapInteropt.showModal", "exampleModal");
}
public Task Hide()
{
return _jsRuntime.InvokeVoidAsync("bootstrapInteropt.hideModal", "exampleModal");
}
}
I believe the pattern is to use the property + "Changed" for the EventCallback.
[Parameter] public bool ShowConfirmationBox { get; set; }
[Parameter] public EventCallback<bool> ShowConfirmationBoxChanged { get; set; }
I created a simplified version of this code at https://blazorfiddle.com/s/hd6sbj44
You can user JSInterop, agua from mars was showing in the answer. If you want to avoid JSInterop you can try this
public class ConfirmModelBoxBase : ComponentBase
{
//[Parameter] // You don't need because you are not passing the argument with Component you are updating using Show function
public bool ShowConfirmationBox { get; set; }
//[Parameter] // You don't need
//public EventCallback<bool> ShowConfirmationBoxChanged { get; set; }
public void Show()
{
ShowConfirmationBox = true;
StateHasChanged();
}
}
ConfirmDelete.razor which will inherit ConfirmModelBoxBase
#*ConfirmDelete.razor*#
#inherits ConfirmModelBoxBase
#if (ShowConfirmationBox)
{
<div class="modal fade show d-block" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirm Delete</h4>
<button type="button" class="close" #onclick="OnCanceled">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Are you sure want to delete the recored?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" #onclick="OnCanceled">Cancel</button>
<button type="button" class="btn btn-secondary" #onclick="OnSaved">Save Changed</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop fade show"></div>
}
#code {
private void OnCanceled(MouseEventArgs e)
{
ShowConfirmationBox = false;
}
private void OnSaved(MouseEventArgs e)
{
ShowConfirmationBox = false;
//Save changes
}
}
Sample.razor
<ConfirmDelete #ref="_confirm">
</ConfirmDelete>
<button #onclick="OnClicked">Click</button>
#code{
private ConfirmModelBoxBase _confirm;
private void OnClicked()
{
_confirm.Show();
}
}
Related
I am trying to learn web development with asp.net 6 and I'm trying to update a category that I created .I've written a get and a post method but it just doesn't working in Edit action and it is adding a new row in database instead of updating.
this is my edit action in category controller
//GET
public IActionResult Edit(int? id)
{
if(id == null || id == 0)
{
return NotFound();
}
var CategoryFromDb = _db.Categories.Find(id);
if (CategoryFromDb == null)
{
return NotFound();
}
return View(CategoryFromDb);
}
//POST
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Category obj)
{
if (obj.Name == obj.DisplayOrder.ToString())
{
ModelState.AddModelError("name", "The DisplayOrder cannot exactly match the Name.");
}
if (ModelState.IsValid)
{
_db.Categories.Update(obj);
_db.SaveChanges();
return RedirectToAction("Index", "Category");
}
return View(obj);
}
}
this is my Edit.cshtml
#model Category
<form method="post" asp-action="Edit">
<div class="border p-3 mt-4">
<div class="row pb-2">
<h2 class="text-primary">Edit Category</h2>
<hr/>
<div asp-validation-summary="All"></div>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="Name"></label>
<input style="width: 100%;clear: both;" asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-bg-danger"></span>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="DisplayOrder"></label>
<input style="width: 100%;clear: both;" asp-for="DisplayOrder" class="form-control" />
<span asp-validation-for="DisplayOrder" class="text-bg-danger"></span>
</div>
<button type="submit" class="btn btn-primary" style="width:150px;">Update</button>
<a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width:150px">Back to List</a>
</div>
</form>
and this is my category model
public class Category
{
[Key]
public int? CategoryID { get; set; }
[Required]
public string Name { get; set; }
[DisplayName("Display Order")]
[Range (1,100,ErrorMessage ="Not in Range of Display Order")]
public int DisplayOrder { get; set; }
public DateTime CreatedDateTime { get; set; } = DateTime.Now;
}
and this is my index view part that I created Edit button
<div class="w-75 btn-group" role="group">
<a asp-controller="Category" asp-action="Edit" asp-route-id ="#obj.CategoryID" ><i class="bi bi-pencil"></i>Edit</a>
</div>
and it's adding a new row to database instead of updating the database based on the primary key
please help me...
thanks
Your main issue is that you're not filling in the model correctly - namely, your View doesn't fill in the CategoryID, so the controller doesn't "know" which Category to update. You need to modify your View similar to this (I've added the line right below <form>):
#model Category
<form method="post" asp-action="Edit">
#Html.HiddenFor(m => m.CategoryID)
<div class="border p-3 mt-4">
<div class="row pb-2">
<h2 class="text-primary">Edit Category</h2>
<hr/>
<div asp-validation-summary="All"></div>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="Name"></label>
<input style="width: 100%;clear: both;" asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-bg-danger"></span>
</div>
<div class="mb-3" style=" width: 500px;clear: both;">
<label asp-for="DisplayOrder"></label>
<input style="width: 100%;clear: both;" asp-for="DisplayOrder" class="form-control" />
<span asp-validation-for="DisplayOrder" class="text-bg-danger"></span>
</div>
<button type="submit" class="btn btn-primary" style="width:150px;">Update</button>
<a asp-controller="Category" asp-action="Index" class="btn btn-secondary" style="width:150px">Back to List</a>
</div>
</form>
I want to delete the record from the table with modal but the partial view is not displayed in modal ...
How can I solve this problem !?
And that I can not use onClick !!!
this action for delete in controller:
public IActionResult DelPlatform(int? id)
{
if (id == null)
{
return NotFound();
}
PR_Platform platformModel = _Iunit.PlatformsRepository.GenGetById(id);
if (platformModel == null)
{
return NotFound();
}
return View(platformModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult DelPlatform(int id)
{
_Iunit.PlatformsRepository.GenDeleteById(id);
return RedirectToAction(nameof(PlatformList));
}
this delete button in index view:
<a asp-controller="Platform" asp-action="DelPlatform" asp-route-id="#item.PlatformId" class="btn btn-danger btn-sm waves-effect waves-light" data-toggle="modal" data-target="#delete-modal"><i class="mdi mdi-delete" data-toggle="tooltip" data-placement="top" title="حذف"></i></a>
this script for delete:
<script>
(function ($) {
function Delete() {
var $this = this;
function initilizeModel() {
$("#delete-modal").on('show.bs.modal', function (e) {
}).on('hidden.bs.modal', function (e) {
$(this).removeData('bs.modal');
});
}
$this.init = function () {
initilizeModel();
}
}
$(function () {
var self = new Delete();
self.init();
})
}(jQuery))
</script>
this modal (in shared folder):
<div class="modal fade bs-example-modal-center" tabindex="-1" role="dialog" id="delete-modal" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header text-danger">
<h5 class="modal-title mt-0 text-white"><strong>حذف از پایگاه داده</strong></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-footer mr-auto">
<button type="submit" class="btn btn-primary waves-effect waves-light">حذف شود</button>
</div>
</div>
</div>
this delete action view (for get record name):
#model PR_Platform
#{
Layout = null;
}
<form asp-controller="Platform" asp-action="DelPlatform" method="post">
<div class="modal-body" id="delete-modal">
<p><strong>آیا از حذف <em>"#Model.PlatformName"</em> مطمئن هستید؟</strong></p>
<p class="mb-0"><small>#Model.PlatformName از پایگاه داده حذف خواهد شد</small></p>
</div>
</form>
Please try this:
View:
#{
ViewData["Title"] = "Home Page";
}
<div class="modal fade bs-example-modal-center" tabindex="-1" role="dialog" id="delete-modal" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header text-danger">
<h5 class="modal-title mt-0 text-white"><strong>حذف از پایگاه داده</strong></h5>
<form asp-controller="Platform" asp-action="DelPlatform" method="post">
<div class="modal-body" id="delete-modal">
#*<em>"#Model.PlatformName"</em> <small>#Model.PlatformName از پایگاه داده حذف خواهد شد</small>*#
<p><strong>آیا از حذف مطمئن هستید؟</strong></p>
<p class="mb-0"></p>
</div>
<button type="submit">Click if you are sure to Delete</button>
</form>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
#*<div class="modal-footer mr-auto">
<button type="submit" class="btn btn-primary waves-effect waves-light">حذف شود</button>
</div>*#
</div>
</div>
</div>
#*asp-controller="Home" asp-action="DelPlatform" asp-route-id="#item.PlatformId"*#
<a class="btn btn-danger btn-sm waves-effect waves-light" data-toggle="modal" data-target="#delete-modal">Click to Delete<i class="mdi mdi-delete" data-toggle="tooltip" data-placement="top" title="حذف"></i></a>
Here is a whole working demo you could follow:
Model:
public class PR_Platform
{
public int PlatformId { get; set; }
public string PlatformName { get; set; }
}
Main View(Index.cshtml):
Add data-id in the anchor tag for getting the clicked value.
#model IEnumerable<PR_Platform>
#foreach(var item in Model)
{
<a asp-controller="Platform" asp-action="DelPlatform" asp-route-id="#item.PlatformId" data-id="#item.PlatformId" class="btn btn-danger btn-sm waves-effect waves-light" data-toggle="modal" data-target="#delete-modal"><i class="mdi mdi-delete" data-toggle="tooltip" data-placement="top" title="حذف"></i></a>
<a asp-controller="Platform" asp-action="DelPlatform" asp-route-id="#item.PlatformId" data-id="#item.PlatformId" class="btn btn-danger btn-sm waves-effect waves-light" data-toggle="modal" data-target="#delete-modal"><i class="mdi mdi-delete" data-toggle="tooltip" data-placement="top" title="حذف"></i></a>
}
<div class="modal fade bs-example-modal-center" tabindex="-1" role="dialog" id="delete-modal" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header text-danger">
<h5 class="modal-title mt-0 text-white"><strong>حذف از پایگاه داده</strong></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
//add this......
</div>
<div class="modal-footer mr-auto">
<button type="submit" class="btn btn-primary waves-effect waves-light">حذف شود</button>
</div>
</div>
</div>
</div>
JS in main view:
#section Scripts
{
<script>
(function ($) {
function Delete() {
var $this = this;
function initilizeModel() {
$("#delete-modal").on('show.bs.modal', function (e) {
var $button = $(e.relatedTarget); //Button that triggered the modal
var id = $button.data("id"); //get the id
alert(id);
$.ajax({
type: "GET",
url: "/Platform/DelPlatform/"+id,
contentType: "application/json",
success: function (data) {
$(".modal-body").html(data);//load the response html code to the modal
},
error: function (e) {
alert('Error');
}
})
}).on('hidden.bs.modal', function (e) {
$(this).removeData('bs.modal');
});
}
$this.init = function () {
initilizeModel();
}
}
$(function () {
var self = new Delete();
self.init();
})
}(jQuery))
</script>
}
Controller:
public IActionResult DelPlatform(int? id)
{
if (id == null)
{
return NotFound();
}
PR_Platform platformModel = _Iunit.PlatformsRepository.GenGetById(id);
if (platformModel == null)
{
return NotFound();
}
return View(platformModel);
}
I have to generate file depending on input (checkboxes) and download it:
[HttpGet]
public FileResult GenerateFormatSettingsFile(IEnumerable<string> values)
{
var content = FileSettingsGenerator.Generate(values);
MemoryStream memoryStream = new MemoryStream();
TextWriter tw = new StreamWriter(memoryStream);
tw.WriteLine(content);
tw.Flush();
tw.Close();
return File(memoryStream.GetBuffer(), "text/plain", "file.txt");
}
And on my view this:
<button id="GenetateFormatSettingsFile" class="btn btn-primary" data-dismiss="modal" style="margin-right: 1500px">Generate</button>
$(document).ready(function() {
$("#GenetateFormatSettingsFile").click(function() {
var f = {};
var checkboxes = [];
$('input:checked').each(function() {
checkboxes.push($(this).attr("value"));
});
f.url = '#Url.Action("GenerateFormatSettingsFile", "Home")';
f.type = "GET";
f.dataType = "text";
f.data = { values: checkboxes},
f.traditional = true;
f.success = function(response) {
};
f.error = function(jqxhr, status, exception) {
alert(exception);
};
$.ajax(f);
});
});
</script>
The problem is the download doesn't start. How could I fix it?
If I do it with Html.ActionLink, the download starts, but I can't pass the values of checkboxes which is done by my ajax function above
Thanks!
Edit - that's how my check-boxes looks like:
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="modal" id="formatterSettings" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Settings</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="defaultG">To default view</label>
<input class="form-control" type="checkbox" value="Default" id="defaultG">
</div>
<div class="form-group">
<label for="extendedG">To extended view</label>
<input class="form-control" type="checkbox" value="Extended" id="extendedG">
</div>
/div>
</form>
</div>
<div class="modal-footer">
<div class="col-md-6">
<button id="GenetateFormatSettingsFile" class="btn btn-primary" data-dismiss="modal" style="margin-right: 1500px">Generate</button>
#Html.ActionLink("Generate!", "GenerateFormatSettingsFile")
</div>
<div class="col-md-6">
<a class="btn btn-primary" data-dismiss="modal" >Generate From Code</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Put a submit button in your form and POST your form synchronously (without ajax).
when a form is posted, values of all input elements (TextBoxes, CheckBoxes, ...) are sent to the server (with the request) and you don't need to do anything.
I´ve got a modal boostrap. I want to show the error of validation on boostrap modal. But when I leave the model empty and click on submit button Its just viewed as a standalone page.
Partial view:
#model WebApplication1.Models.Book
<form asp-controller="Home" asp-action="AddBook"
data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#frmaddbook">
<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="myModalLabel">Header of Modal</h4>
</div>
<div class="modal-body form-horizontal" id="frmaddbook ">
<span class="alert-danger">
#Html.ValidationSummary()
</span>
<div class="row">
<div class="form-group">
<label asp-for="BookName" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="BookName" class="form-control" />
<span asp-validation-for="BookName" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="BookDescription" class="col-lg-3 col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="BookDescription" class="form-control" />
<span asp-validation-for="BookDescription" class="text-danger"></span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
Index View :
<div class="panel panel-primary">
<div class="panel-body">
<div class="btn-group">
<a class="btn btn-primary marginbutoon" id="showBookgroup" data-toggle="modal" asp-action="AddBook"
data-target="#modal-book">
<i class="glyphicon glyphicon-plus"></i>
Add Book
</a>
</div>
</div>
i use this libraries at top of index view:
jquery.unobtrusive-ajax.min.js
jquery.validate.unobtrusive.min.js
and use at the bottom of index view:
<script src="~/js/book-index.js"></script>
book-index.js:
(function ($) {
function Home() {
var $this = this;
function initilizeModel() {
$("#modal-book").on('loaded.bs.modal', function (e) {
}).on('hidden.bs.modal', function (e) {
$(this).removeData('bs.modal');
});
}
$this.init = function () {
initilizeModel();
}
}
$(function () {
var self = new Home();
self.init();
})
}(jQuery))
Controller:
[HttpGet]
public IActionResult AddBook()
{
var b = new Book();
return PartialView("_AddBook", b);
}
[HttpPost]
[ValidateAntiForgeryToken]
//[HandleError]//not in core
public IActionResult AddBook(Book model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index");
}
return PartialView("_AddBook", model);
}
Model :
public class Book
{
[Key]
public int BookId { get; set; }
[Display(Name = "Book Name :")]
[Required(ErrorMessage = "Enter Book Name Please ")]
public string BookName { get; set; }
[Display(Name = "Book Description")]
[Required(ErrorMessage = "Enter Book Description Please ")]
public string BookDescription { get; set; }
}
My code is shown above. How can i show validation error in modal partial view ?
You can set the Id of form as the data-ajax-update property value of the form , which is ajaxified. This value will be used as the jQuery selector when the result is received from the ajax call.
#model Book
<form asp-controller="Home" asp-action="AddBook" id="myform"
data-ajax="true" data-ajax-method="POST"
data-ajax-mode="replace" data-ajax-update="#myform">
<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="myModalLabel">Add Book</h4>
</div>
<div class="modal-body form-horizontal" id="frmaddbook ">
<span class="alert-danger">
#Html.ValidationSummary()
</span>
<div class="row">
<div class="form-group">
<label asp-for="BookName" class="col-sm-3 control-label"></label>
<div class="col-lg-6">
<input asp-for="BookName" class="form-control" />
<span asp-validation-for="BookName" class="text-danger"></span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
</form>
Now when you submit the form and model state validation fails, the action method code will return the partial view result with the validation error messages (generated by the validation helpers) and the jquery.unobtrusive-ajax.js library code will replace (because we specified that with data-ajax-mode="replace") the content of the result of the jquery selector #data-ajax-update (the form tag and it's inner contents) with the response coming back from the server.
Using Bootstrap in my Razor page, I am opening a modal window:
<div class="container-fluid">
<div class="navbar navbar-fixed-top navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target=".navbar-offcanvas" data-canvas="body">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand pull-right" href="#">
<img src="assets/img/logo-header.png" alt="Alternate Text for Image">
</a>
</div>
<div class="navbar-offcanvas offcanvas navmenu-fixed-left">
<a class="navmenu-brand" href="#">eServices</a>
<ul class="nav nav-justified">
<li>New Here?</li>
<li>Services</li>
<li>Sign In</li>
</ul>
</div>
</div>
</div>
<div class="modal fade" id="modalLogin" 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" aria-label="Close"><span aria-hidden="true">×</span></button>
<p>
<h3 class="modal-title" id="myModalLabel">Login to MyApplication</h3>
</p>
</div>
#using (Html.BeginForm("index", "home", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { role = "form", #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
<div class="form-group #Html.ValidationErrorFor(m => m.Username, "has-error has-feedback")">
<div class="col-sm-12">
#Html.FormTextBoxFor(p => p.Username, new { #class = "form-control" })
#if (!Html.IsValid(m => m.Username))
{
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
}
#Html.ValidationMessageFor(m => m.Username, null, new { #class = "help-block" })
</div>
</div>
<div class="form-group #Html.ValidationErrorFor(m => m.Password, "has-error has-feedback")">
<div class="col-sm-12">
#Html.FormPasswordFor(p => p.Password, new { #class = "form-control" })
#if (!Html.IsValid(m => m.Password))
{
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
}
#Html.ValidationMessageFor(m => m.Password, null, new { #class = "help-block" })
</div>
</div>
#Html.ValidationSummary(true, string.Empty, new { #class = "test" }, "span")
<div class=" pull-right">
<p>
<button type="submit" class="btn btn-default">#Forms.ButtonSignin</button>
</p>
<br />
<p>
#Html.ActionLink("Forgot your username?", "ForgotUsername")
</p>
<p>
#Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>
</div>
}
</div>
</div>
</div>
The issue I have is that, for example, I entered an incorrect username/password combination, the form validates, but the modal window closes. Is there a way to re-open the modal window after the form has posted if the validation triggered an error?
You could add a property named IsModalShown i.e.
public class AModel
{
public bool IsModalShown { get; set; }
}
Render this as a hidden for in your view i.e.
#Html.HiddenFor(m => m.IsModalShown)
When the modal is opened set the hidden value to true, this will enable the modal state to be posted back to the controller action i.e.
$('#modalLogin').on('show.bs.modal', function (e) {
$('#IsModalShown').val(true);
})
Please note the above will depend on the version of bootstrap you are using but there are other docs on the official site
Then add the following to your view that automatically pops it up
$(function(){
#if(Model.IsModalShown)
{
$('#signin_modal').modal('show');
}
});
I had a similar problem, but didn't have a model in view. Posting my solution, in case it would help someone. I wanted to show an error message stored in TempData (in case of wrong login/password combination, on which Batuta was asking).
Controller:
public ActionResult SignIn(string login, string password)
{
if (Membership.ValidateUser(login, password))
{
// something
}
else
{
TempData["message-error"] = "Wrong combination";
}
return RedirectToAction("Index", "Home");
}
Showing the message in modal window:
#if (TempData["message-error"] != null)
{
#TempData["message-error"]
}
Opening modal in index:
#if (TempData["message-error"] != null)
{
<script type="text/javascript">
$('#myModal').modal('show');
</script>
}
Maybe not that clean, but works for me.