How do you connect a POST to a different razor page loaded via AJAX into a modal popup? - ajax

Edit: Have marked up where the error in the original code was stopping this from working.
I can find plenty of info and examples of this on MVC, but doesn't seem to apply for Razor Pages?
Simple scenario: I have a page (FooList) showing a list of Foo items. Each has an Edit button. This opens a modal popup with the layout (and data) coming from a second page (FooEdit).
The Edit form appears and populates fine, but I can't work out how to get it to post the data back to the FooEdit code behind?
List page, FooList.cshtml
#page
#model Pages.FooListModel
<table>
#foreach (var item in Model.FooListVM)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a onclick="openModal(#item.ID);">Edit</a>
</td>
</tr>
}
</table>
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header border-bottom-0">
<h5 class="modal-title" id="exampleModalLabel">Edit Foo</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form> <---- Edit: ** This shouldn't be here **
<div class="modal-body">
</div>
</form> <---- Edit
</div>
</div>
</div>
<script>
function openModal(i) {
$.get("FooEdit?id="+i,
null,
data => {
$("#editModal").modal("show");
$("#editModal .modal-body").html(data);
});
};
</script>
Code behind, FooList.cshtml.cs
public class FooListModel : PageModel
{
public IList<FooListVM> FooListVM { get; set; }
public void OnGet()
{
FooListVM = new List<FooListVM>
{
new FooListVM { ID = 1, Name = "Foo 1" },
new FooListVM { ID = 2, Name = "Foo2" }
};
}
}
public class FooListVM
{
public int ID { get; set; }
public string Name { get; set; }
}
Second page for the popup, FooEdit.cshtml
#page
#model Pages.FooEditModel
#(Layout=null)
<form method="post">
<input asp-for="FooEditVM.Name" class="form-control" /><br />
<input asp-for="FooEditVM.Stuff1" class="form-control" /><br />
<input asp-for="FooEditVM.Stuff2" class="form-control" /><br />
<input type="submit" value="Save"/>
</form>
And the code behind for the popup, FooEdit.cshtml.cs
public class FooEditModel : PageModel
{
[BindProperty]
public FooEditVM FooEditVM { get; set; }
public void OnGet(int id)
{
FooEditVM = new FooEditVM
{
Name = $"This is item {id}",
Stuff1 = "Stuff1",
Stuff2 = "Stuff2"
};
}
public void OnPost(int id)
{
// How do we get to here???
var a = FooEditVM.Name;
}
}
public class FooEditVM
{
public string Name { get; set; }
public string Stuff1 { get; set; }
public string Stuff2 { get; set; }
}
I've been through all the MS Tutorial stuff on Asp.net Core 2.2, but it doesn't seem to cover this.
Also as a side question, although it works, is there a "ASP helper tag" way of doing the ajax bit?

Have realised the problem was the 'form' tag in the Modal Dialog markup that was clashing the 'form' tag from the partial page. Removing it fixed everything using:
In FooEdit.cshtml
<form id="editForm" asp-page="FooEdit">
. . .
</form>
In FooEdit.cshtml.cs
public void OnPost()
{
// Fires in here
}

I'm pretty sure the fooedit page is going to need some jQuery to handle this.
See below for what I would do in the fooedit page.
#page
#model Pages.FooEditModel
#(Layout=null)
<form id=fooedit method="post" action="FooEdit">
<input asp-for="FooEditVM.Name" class="form-control" /><br />
<input asp-for="FooEditVM.Stuff1" class="form-control" /><br />
<input asp-for="FooEditVM.Stuff2" class="form-control" /><br />
<input type="submit" value="Save"/>
</form>
<SCRIPT language="JavaScript" type="text/Javascript">
<!--
$(document).ready(function(e) {
$("#fooedit").submit(function(e) {
e.preventDefault();
var form_data = $(this).serialize();
var form_url = $(this).attr("action");
var form_method = $(this).attr("method").toUpperCase();
$.ajax({
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
$("#editModal.modal-body").html(returnhtml);
}
});
});
});
</SCRIPT>

Related

ajax post data null in mvc core controller method

I faced this problem here , but I can not solve it . I searched a lot and tried every solution I found on the similar post . so if there is any help to my case . my part of my app which I found the problem in , first here is my view , I have Categories dropdown when I choose a category I will load the property of that value in a table.
#model Demo.Models.ViewModel.DeviceVM
<form method="post">
<input hidden asp-for="#Model.device.ID" />
<div class="border p-3">
#*putting the page label*#
<div class="row">
<h3 class="text-info pl-3 pb-3">Create Device</h3>
</div>
#*fifth Row => Category List*#
<div class="form-group row">
#*field Label*#
<div class="col-4">
<label asp-for="#Model.device.CategoryID"></label>
</div>
#*field Text*#
<div class="col-8">
<select asp-for="#Model.device.CategoryID" asp-items="#Model.CategoryDropDown" class="form-control"
id="CategoryList">
<option value="">-- Select Category --</option>
</select>
<span asp-validation-for="#Model.device.CategoryID" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label>Category Properties</label>
</div>
<div class="col-8">
<table class="table table-bordered table-striped">
<thead class="thead-dark">
<tr>
<th>Property</th>
<th>Value</th>
</tr>
</thead>
<tbody id="plist">
</tbody>
</table>
</div>
</div>
#*Seventh Row => Buttons*#
<div class="form-group">
<div class="col-8 offset-4 row">
#*Save Button*#
<div class="col">
<input type="submit" value="Save" asp-action="Create" class="btn btn-info w-100" />
</div>
#*Back Button*#
<div class="col">
<a class="btn btn-success w-100" asp-action="Index">Back</a>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
#section Scripts
{
<script>
$(function ()
{
$('#CategoryList').on("change", function () {
var _category = $('#CategoryList').val();
var obj = {CategoryID:_category};
AjaxCall("GetCategoryProperty", JSON.stringify(obj), 'POST').done(function (response) {
console.log(JSON.stringify(obj));
if (response.length > 0)
{
console.log("i'm here ");
}
}).fail(function (error) {
alert(error.StatusText);
});
});
});
function AjaxCall(url, data, type) {
return $.ajax({
url: url,
type: type ,
data: data ,
contentType: 'application/json; charset=utf-8',
dataType:'json'
});
}
</script>
}
here is my Category Model
public class Category
{
[Key]
public int ID { get; set; }
[Required,MaxLength(15),Display(Name ="Category Name")]
public string CatName { get; set; }
public virtual ICollection<Category_Property> categoryprperties {get;set;}
}
here is my Function in the view which always receive 0 in it's parameter
[HttpPost]
public JsonResult GetCategoryProperty([FromBody]int CategoryID)
{
DeviceVM obj = new DeviceVM();
var _CategoryProperty = (from cp in _db.Category_Property
join p in _db.Property on cp.PropertyID equals p.ID
where cp.CategoryID == CategoryID
select new { cp.CategoryID, p.Description, cp.PropertyID });
return Json(_CategoryProperty );
}
I opened the inspect in the browser I it did not reach the message inside the if block because ajax always send 0 for the category id , which I asking for a help to get work.
Two ways you can achieve your requirement.
The first way you can post the id by form like below:
1.Change JSON.stringify(obj) to obj and remove contentType: 'application/json; charset=utf-8',:
$(function ()
{
$('#CategoryList').on("change", function () {
var _category = $('#CategoryList').val();
var obj = {CategoryID:_category};
//change here...
AjaxCall("/home/GetCategoryProperty", obj, 'POST').done(function (response) {
console.log(JSON.stringify(obj));
if (response.length > 0)
{
console.log("i'm here ");
}
}).fail(function (error) {
alert(error.StatusText);
});
});
});
function AjaxCall(url, data, type) {
return $.ajax({
url: url,
type: type ,
data: data ,
//contentType: 'application/json; charset=utf-8',
dataType:'json'
});
}
2.Remove [FromBody] or add [FromForm]:
public class HomeController : Controller
{
[HttpPost]
public JsonResult GetCategoryProperty(int CategoryID)
{
//...
}
}
The second way you can post it by body, you need create a model like below then reserve your js code:
public class Test
{
public int CategoryID { get; set; }
}
Change your action:
public class HomeController : Controller
{
[HttpPost]
public JsonResult GetCategoryProperty([FromBody] TestM model)
{
//...
}
}

Custom Model Validation in ASP.Net core v3.1 MVC ajax form not seems to be working

I'm working on an ASP.Net core 3.1 MVC project in which I have to create a custom Validator, and I want it to be working for client as well as server side (e.g. Required Attribute).
I developed a simple custom validator like below just for POC -
public class ImportantAttribute : ValidationAttribute, IClientModelValidator
{
public void AddValidation(ClientModelValidationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
AttributeUtils.MergeAttribute(context.Attributes, "data-val", "true");
AttributeUtils.MergeAttribute(context.Attributes, "data-val-important", FormatErrorMessage(context.ModelMetadata.GetDisplayName()));
}
public class AttributeUtils
{
public static bool MergeAttribute(
IDictionary<string, string> attributes,
string key,
string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
string val = value.ToString();
if (val.Contains("hello"))
{
return ValidationResult.Success;
}
}
return new ValidationResult("Value not valid");
}
}
and used this attribute on a property and created a View using the same model.
Them modified the form tag to become an ajax form like -
<form asp-action="Index" role="form" data-ajax="true" data-ajax-method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" value="SGSM" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
Then I added below java script -
$(document).ready(() => {
console.log('I\'m ready bro');
$.validator.addMethod("important",
function (value, element, params) {
console.log('1', value);
return value.contains('hello');
}, "Not OK");
$.validator.unobtrusive.adapters.add("important",
['important'],
function (options) {
console.log('2', options);
options.rules["important"] = options.important;
options.messages["important"] = options.message;
});
});
When I run this by providing any value to the text box and submitting the form it don't show any error message on the page, but if I put break point in the Action Method the ModelState shows correct info.
If I make the form as regular form (i.e. non-ajax form) everything works as expected.
I have searched a lot but could not find any thing related.
Based on your code and requirement, I made some some modifications on custom client-side validation code, which works well for me, you can refer it.
<div class="row">
<div class="col-md-4">
<form asp-action="Index" method="post" role="form" data-ajax="true" data-ajax-method="post" data-ajax-complete="completed">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.js"></script>
<script>
$(document).ready(() => {
console.log('I\'m ready bro');
});
completed = () => {
alert('Request completed!');
};
$.validator.addMethod("important",
function (value, element, params) {
console.log('1', value);
return value.includes('hello');
}, "Not OK");
$.validator.unobtrusive.adapters.add("important",
['important'],
function (options) {
console.log('2', options);
var element = $(options.form).find('input#Name')[0];
options.rules["important"] = [element, ''];
options.messages["important"] = options.message;
});
</script>
}
Test Result

how to load data in table and bind the same to view Model class in .net core mvc (without refreshing the page)

I'm trying to add data in table via server but unable to succeed. I tried many things but nothing worked. I'm getting the data from the server but unable to populate that in table.. can someone please help me out?
I'm getting this :
"DataTables warning: table id=particlarsTable - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1"
Let me explain my code first:
(In View)
When I click on "Add New Particular" button, bootstrap modal will popup with input fields, those fields will send to the server then again back to view and populate the table with the same data without refreshing the whole page.
I'm stuck on the last stage, I'm getting the data on UI/View in ajax success handler but unable to load that data in table.
here is my view :
<form class="form-horizontal" method="post" id="createAdHocForm">
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label>Select Flat</label>
<select asp-for="AdHocInvoice.FlatRid" asp-items="#(new SelectList(Model.Flats,"FlatRid","FlatNumber"))" class="form-control form-control-sm selectpicker" data-live-search="true">
<option selected disabled value="">Select One</option>
</select>
</div>
</div>
</div>
<table class="table table-sm table-responsive-md nowrap w-100" id="particlarsTable">
<thead class="thead-light">
<tr>
<th>Particulars</th>
<th>Amount</th>
<th></th>
</tr>
</thead>
<tbody class="bg-white">
#foreach (var item in Model.AdHocInvoice.FlatInvoiceItems)
{
<tr>
<td>#item.Particular</td>
<td>#item.Amount</td>
<td></td>
</tr>
}
</tbody>
</table>
<button class="btn btn-sm btn-outline-info" type="button" onclick="showParticularForm()">Add New Particular</button>
<hr />
<div class="row text-center">
<button class="btn btn-sm btn-outline-success mx-auto" type="submit">Submit</button>
</div>
</form>
bootstrap modal to fill the table :
<div class="modal fade" id="particularWindow">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Invoice Items</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<form class="form-horizontal" method="post" id="particularForm">
<div class="row">
<div class="col-md-5">
<div class="form-group">
<label>Enter Particular</label>
<input id="particularName" name="particular" class="form-control form-control-sm" required />
</div>
</div>
<div class="col-md-5">
<label>Amount</label>
<input id="particularAmount" name="amount" class="form-control form-control-sm" required />
</div>
<div class="col-md-2">
<button class="btn btn-sm btn-outline-success mt-4" id="btnParticularSubmit" type="button" onclick="addParticular()">Add</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
Scripts:
<link rel="stylesheet" href="~/DataTables/datatables.min.css" />
<script type="text/javascript" src="~/DataTables/datatables.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#particlarsTable').DataTable();
});
function showParticularForm() {
$('#particularWindow').modal('show');
}
function addParticular() {
var particular = $('#particularName').val();
var amount = $('#particularAmount').val();
$.ajax({
url: '/FlatInvoice/AddParticular',
data: 'particular=' + particular + '&amount=' + amount,
success: function (response) {
$('#particlarsTable').DataTable().ajax.reload()
}
});
}
</script>
Action Method on controller:
public JsonResult AddParticular(string particular, decimal amount)
{
_flatInvoiceViewModel.AdHocInvoice.FlatInvoiceItems.Add(new FlatInvoiceItem { Particular = particular, Amount = amount });
return Json(_flatInvoiceViewModel);
}
Class/Model:
public class FlatInvoiceItem
{
public Guid FlatInvoiceItemRid { get; set; }
public Guid FlatInvoiceRid { get; set; }
public Guid FundRuleRid { get; set; }
public string Particular { get; set; }
public decimal Amount { get; set; }
}
NOTE: this code is in initial phase, I need that input data on server for further process(will add code later) so don't want to use $.('#table_body_id').append("<tr>..</tr>"); type of code.
1.Firstly,reload() is used to send request back to the method which display the DataTable initially(e.g. name this method Test).
2.Secondly,From your AddParticular method,you just add a data to the list but the lifetime is just one request,so when you reload to Test method,the list still contains the initial data without new data.
Conclusion: I suggest that you could save data to database.And get data from database.
Here is a working demo about how to use DataTabale:
1.Model:
public class Test
{
public int Id { get; set; }
public AdHocInvoice AdHocInvoice { get; set; }
}
public class AdHocInvoice
{
public int Id { get; set; }
public string Name { get; set; }
public List<FlatInvoiceItem> FlatInvoiceItems { get; set; }
}
public class FlatInvoiceItem
{
public int Id { get; set; }
public Guid FlatInvoiceItemRid { get; set; }
public Guid FlatInvoiceRid { get; set; }
public Guid FundRuleRid { get; set; }
public string Particular { get; set; }
public decimal Amount { get; set; }
}
public class ViewModel
{
public string Particular { get; set; }
public decimal Amount { get; set; }
}
2.View:
<form class="form-horizontal" method="post" id="createAdHocForm">
<table class="table table-sm table-responsive-md nowrap w-100" id="particlarsTable">
<thead class="thead-light">
<tr>
<th>Particulars</th>
<th>Amount</th>
<th></th>
</tr>
</thead>
#*<tbody class="bg-white">
#foreach (var item in Model.AdHocInvoice.FlatInvoiceItems)
{
<tr>
<td id="particular">#item.Particular</td>
<td id="amount">#item.Amount</td>
<td></td>
</tr>
}
</tbody>*# //DataTable no need to add this tbody
</table>
<button class="btn btn-sm btn-outline-info" type="button" onclick="showParticularForm()">Add New Particular</button>
<hr />
<div class="row text-center">
<button class="btn btn-sm btn-outline-success mx-auto" type="submit">Submit</button>
</div>
</form>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script>
<script>
$(document).ready(function () {
//$('#particlarsTable').DataTable();
$('#particlarsTable').DataTable({
ajax: {
type: 'GET',
dataType: 'JSON',
url: '#Url.Action("Test", "Home")',
},
columns: [
{ 'data': 'particular' },
{ 'data': 'amount' }
]
})
});
function showParticularForm() {
$('#particularWindow').modal('show');
}
function addParticular() {
var particular = $('#particularName').val();
var amount = $('#particularAmount').val();
$.ajax({
url: '/Home/AddParticular',
data: 'particular=' + particular + '&amount=' + amount
}).done(function (data) {
$('#particularWindow').modal('hide');
$('#particlarsTable').DataTable().ajax.reload();
});
}
</script>
3.Controller:
public class HomeController : Controller
{
private readonly MyDbContext _context;
public HomeController(MyDbContext context)
{
_context = context;
}
public IActionResult Index()
{
return View();
}
public JsonResult Test()
{
var _flatInvoiceViewModel = _context.Test.Include(i=>i.AdHocInvoice)
.ThenInclude(a=>a.FlatInvoiceItems).Where(i => i.Id == 1).FirstOrDefault();
var list = new List<ViewModel>();
foreach (var item in _flatInvoiceViewModel.AdHocInvoice.FlatInvoiceItems)
{
var model = new ViewModel() { Amount = item.Amount, Particular = item.Particular };
list.Add(model);
}
return Json(new { data = list });
}
public void AddParticular(string particular, decimal amount)
{
var _flatInvoiceViewModel = _context.Test.Include(i => i.AdHocInvoice)
.ThenInclude(a => a.FlatInvoiceItems).Where(i => i.Id == 1).FirstOrDefault();
_flatInvoiceViewModel.AdHocInvoice.FlatInvoiceItems.Add(new FlatInvoiceItem { Particular = particular, Amount = amount });
_context.SaveChanges();
}
4.Result:
Reference:
https://datatables.net/examples/data_sources/ajax.html
https://stackoverflow.com/a/59449895/11398810

Validation error message not displayed in Asp.Net Core 2 MVC partial view

I have an index page with a list of "workbooks" titles and for each workbook, there is a "share" button. When pressing the button a bootstrap model (i.e. dialog) appears which displays the title of the workbook and a textarea allowing the user to type in a sharees email addresses.
When the user presses on the "share" button, I am calling a javascript function which calls a controller action that returns a partial view containing the modal dialog with a form inside it. The problem is that after pressing the submit button (i.e. "Share") there are no validation errors being shown to the user and I am not sure why that is. Could anyone provide some ideas, please?
That is my main (index.cshtml) page:
#model DNAAnalysisCore.Models.WorkBookModel
#{
}
#section BodyFill
{
<script type="text/javascript">
function showSharingView(title) {
var url = "#Url.Action("ShowShareDialog", "Home")" + "?workbookTitle=" + encodeURI(title);
$('#shareFormContainer').load(url,
function() {
$('#shareFormModal').modal("show");
});
}
function hideSharingView() {
$('#shareFormModal').modal("hide");
}
</script>
<div id="shareFormContainer" >
<!--PLACEHOLDER FOR SHARE DIALOG -->
</div>
<div class="workbook-container">
<table class="table">
<tbody>
#foreach (var workbook in Model.Workbooks)
{
<tr>
<td>#Html.ActionLink(workbook.Name, "Open", "OpenAnalytics", new {id = Model.Id, workbook = workbook.Name})</td>
<td>
<button title="Share" class="share-button" onclick='showSharingView("#workbook.Name")'> </button>
</td>
</tr>
}
</tbody>
</table>
</div>
}
That is my Controller:
public class HomeController : Controller
{
[HttpGet]
public IActionResult ShowShareDialog(string workbookTitle)
{
var shareModel = new ShareModel
{
Title = workbookTitle
};
return PartialView("_ShareView", shareModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ShareWorkbook(string emails, string title)
{
var share = new ShareModel
{
Emails = emails
};
// TODO EMAIL THE SHARED WORKBOOK using the 'title' of the workbook and the 'email' string value
// return no content to avoid page refresh
return NoContent();
}
}
This is my partial view/modal dialog (_ShareView):
#using DNAAnalysisCore.Resources
#model DNAAnalysisCore.Models.ShareModel
<!-- Modal -->
<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - #Model.Title</h4>
</div>
#using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post))
{
<div class="modal-body">
<label>#BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="#BaseLanguage.ShareDialogPlaceholder"></textarea>
#* TODO add client-side validation using jquery.validate.unobtrusive.js. See US268276 *#
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title" />
</div>
<div class="modal-footer">
<button type="submit" onclick="hideSharingView()" class="btn btn-primary">Share</button>
<button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
#section Scripts {
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
This is my ShareModel:
public class ShareModel
{
[HiddenInput]
public string Title { get; set; }
[Required]
public string Emails { get; set; }
}
The form is not added to the page when the page loads, the unobtrusive validation will not pick it up.A simple solution is to use $.validator.unobtrusive.parse("#id-of-the-form");.Refer to here.
1.Add id to your form in _ShareView partial view:
#using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post,new { #id="partialform"}))
2.Introduce validation file _ValidationScriptsPartial.cshtml into main page(Index.cshtml) and manually register the form with the unobtrusive validation.
#section Scripts
{
#await Html.PartialAsync("_ValidationScriptsPartial")
<script type="text/javascript">
function showSharingView(title) {
var url = "#Url.Action("ShowShareDialog", "Home")" + "?workbookTitle=" + encodeURI(title);
$('#shareFormContainer').load(url,
function() {
$('#shareFormModal').modal("show");
$.validator.unobtrusive.parse("#partialform");
});
}
function hideSharingView() {
$('#shareFormModal').modal("hide");
}
</script>
}

Passing Model Data to a Bootstrap Modal on click

I'm extremely new to MVC and I don't know how to make this work-
I have a model that stores different news items based on categories:
NewsModel.cs:
public class NewsModel
{
public int ID { get; set; }
public string category { get; set; }
public String headline { get; set; }
public string source { get; set; }
public DateTime date { get; set; }
public string body { get; set; }
public string summary { get; set; }
}
I have a View that displays each of the news items as a list Item:
Sports.cshtml:
#model IEnumerable<Test.Models.NewsModel>
#foreach (var item in Model)
{
<div class="news_target-left floatleft">
<div class="image-container">
<img src="~/Content/Images/demo_img.png" alt="website template image">
<div class="top-left-text">
#item.category
</div>
</div>
<h3>#item.headline</h3>
<p> #item.summary </p>
<p class="single_cat_left_content_meta"><span>#item.source</span> | #item.date</p>
<span class="readmore">#Html.ActionLink("Read More", "NewsModal", "Home", #item)</span>
</div>
}
When the user clicks on Read More, I want to load a bootstrap modal that gets the current model object and displays the entire news data in detail. Currently, the readmore span uses an Html actionlink that does not seem to be working. I want to load the modal using Ajax but cannot figure out how to do so.
This is the bootstrap Modal that I have:
NewsModal.cshtml:
#model Test.Models.NewsModel
<div id="newsModal" 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">×</button>
<h4 class="modal-title">Leadsquared Express</h4>
</div>
<div class="modal-body">
<h2>#Model.headline</h2>
<i><small>#Model.source</small></i>
<p>#Model.body</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
The Model is in Models/NewsModel
The Sports View is in Views/Categories/
The Sports controller Action is in Controllers/Categories:Sports
The NewsModal is currently in Views/Categories/. I have tried putting this view in Shared, as well as its own folder, but I'm obviously doing something wrong.
Any help?
Edit:
I used this link to make the following changes but clicking on "Read more" does not open the modal popup.
http://www.c-sharpcorner.com/UploadFile/092589/implementing-modal-pop-up-in-mvc-application/
changed <span class="readmore">#Html.ActionLink("Read More", "NewsModal", "Home", #item)</span> in Sports.cshtml to
<a id="openmodal "href="javascript:void(0)" class="readmore" data-model="#Json.Encode(#item)">Read More</a>
and added this script:
$(document).ready(function () {
var url = "/Home/NewsModal";
var model = $("#openmodal").attr("data-model");
alert("script running- sports.html");
$.ajax({
type: 'GET',
url: '/Home/NewsModal',
data: model,
contentType: 'application/json; charset=utf-8',
success: function (data, status, settings) {
$("#openmodal").html(data);
},
error: function (ajaxrequest, ajaxOptions, thrownError) {
$("#openmodal").html('Failed to load more content');
}
});
});
Additionally, this is the Action Method I have for the Modal Popup, in HomeController:
public ActionResult NewsModal(NewsModel tempData)
{
NewsModel currentItem = new NewsModel();
currentItem = tempData;
return PartialView("NewsModal", currentItem);
}
You can do by make a click event by using Anchor tag instead ActionLink,
and in that you can do like this.
Open a Modal by jQuery
function openModal()
{
$('#newsModal').modal('show');
}
// $('#newsModal').modal('toggle');
// $('#newsModal').modal('show');
// $('#newsModal').modal('hide');
OR can do directly with data-target,
<button type="button" data-toggle="modal" data-target="#newsModal">Launch modal</button>

Resources