asp.net mvc ajax.beginform being sent as html.beginform - asp.net-mvc

I have a partial view from which I would like to display a modal dialog with updated data. User clicking the div would trigger both the display of the modal and the ajax call for the content of the modal to be updated.
<div class="nMmenuItem" >
#using (Ajax.BeginForm("editItem","nMrestaurant",new { id = Model.ID },
new AjaxOptions
{
HttpMethod = "get",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "myModalDocument"
}, new { id = "ajaxEditItem" }))
{
<div data-toggle="modal" data-target="#myModal"
onclick="$('form#ajaxEditItem').submit();">
<div class="text-center">
#Model.name
</div>
</div>
}
</div>
I have a placeholder for the modal inside the parent view:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document" id="myModalDocument">
#Html.Partial("_editItem", new nMvMmenuItem())
</div>
</div>
But while the controller action is expecting an AjaxResquest, the controller is evaluating Request.IsAjaxRequest() as false.
public async Task<ActionResult> editItem(int? id)
{
if (Request.IsAjaxRequest())
{
return PartialView("_editItem", await db.nMmenuItems.FindAsync(id));
}
return View();
}
Which refreshes the whole view and prevents the modal from working.
I am bundling the following scripts in the _Layout.cshtml page:
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-ui-{version}.js",
"~/Scripts/jquery.unobstrusive*",
"~/Scripts/jquery.validate",
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"
Thanks for your help!

Check that you've got the unobtrusive ajax client scripts installed - your bundle pattern looks like it will pick them up if they are there, but I don't believe they are installed in the default project:
Install-Package Microsoft.jQuery.Unobtrusive.Ajax
While the Ajax.BeginForm is included in the standard MVC project, the client scripts are not and these are what is responsible for loading the content without refreshing the whole page.

I found that attaching submit() to the form's onclick event would not perform an ajax request.
My solution is thus to remove Ajax.SubmitForm and instead deal with the click event in my js:
The updated view looks like this:
<div class="nMmenuItem">
<form method="get" action="#Url.Action("editItem","nMrestaurant",new { id = Model.ID })"
data-nM-ajax="true" data-nM-target="#myModalContent">
<div>
<div class="text-center">
#Model.name
</div>
</div>
</form>
In the js I will bind the form submission to the click event of the parent div:
$('.nMmenuItem').click(ajaxFormSubmit);
And the function that handles the form submission and opens the resulting modal dialog:
var ajaxFormSubmit = function () {
var $form = $(this).children('form:first');
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done(function (data) {
var $target = $($form.attr("data-nM-target"));
$target.replaceWith(data);
$("#myModal").modal(dialogOpts);
});
return false;
};

Related

Display a "Details" view as a modal popup

I have this code to show info about a certain product registered in my database.
Button that triggers my Details Controller:
#Html.ActionLink("Details", "Details", new { id = prod.ID }, new { #class = "btn btn-danger" }) |
Controller code
public ActionResult Details(int? id)
{
PRODUCTS pRODUCTS = db.PRODUCTS.Find(id);
if (pRODUCTS == null)
{
return HttpNotFound();
}
return View(pRODUCTOS);
}
I want to display that "Details" view in a modal popup. I tried to create my modal in the same view where i have my "Details" button, but i can't pass my product id to the controller and it only shows me an empty view.
To show data inside a modal popup, you need an action method which returns HTML markup needed for the modal popup. So the first step is to make an action method which returns a partial view result.
public ActionResult Details(int id)
{
var product = db.PRODUCTS.Find(id);
if (product== null)
{
return HttpNotFound();
}
return View(product);
}
In the above simple example, I am querying the entity and passing the entity object directly to my view using the PartialView method. If you have a view model for your view, please use that.
Now in the Details.cshtml view, we will write code to return the HTML markup needed for the modal popup. Since we are passing the PRODUCTS object to the view, we will make sure our view is also strongly typed to that type.
#model YourNamespaceHere.PRODUCTS
<div id="modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"> Details</h5>
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h2>Hello from #Model.Name</h2>
</div>
<div class="modal-footer">
<button type="button" class="btn" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
In the above example, I am simply printing the Name property value of PRODUCTS object in the modal body. You may update it to render other properties as needed.
Now we will make some changes to our HTML markup being rendered for the product. We need the click event on the details link to open the modal dialog. So let's first give some attributes to the link element, which we can later use to wireup the click event. Here I am going to add an additional CSS class to the links, modal-link.
#Html.ActionLink("Details", "Details", new { id = prod.ID },
new { #class = "btn modal-link" })
Now let's write some JavaScript code to listen to the click event on the link element with the modal-link CSS class, read the the href attribute value of the element and make an Ajax call to that URL and render the response of that call to build the modal dialog.
$(function () {
$('body').on('click', 'a.modal-link', function (e) {
e.preventDefault();
$("#modal").remove();
// Get the Details action URL
var url = $(this).attr("href");
//Make the Ajax call and render modal when response is available
$.get(url, function (data) {
$(data).modal();
});
});
});
I am using CSS class as the selector here, you can use any other selector as you wish
i think you should use jquery ajax to call action on click your button or action link and get your model as json result and return it then first clean your modal data and fill it with new result and at the end show your modal......

View call to another view in MVC

I have created a popup view(EmployeeRegistration.cshtml) using Bootstrap for registration and its Action method. But I want to get this popup view from another view(EmployeeList.cshtml). Can I do it? If yes then How? Any code please.
//EmployeeList.cshtml
#Html.ActionLink("Create New", "Registration", "Registration", new
{
#class = "openDialog",
data_dialog_id = "aboutDialog",
data_dialog_title = "Create Employee"
})
<div id="gridposition" style="width: 100%;">
#{
#grid1.GetHtml(mode: WebGridPagerModes.All,
//code to display employee list on grid
}
</div>
Below is Registration.cshtml
#using (Html.BeginForm())
{
<div class="modal fade mymodal" id="openDialogDiv">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
//code here to pop up
</div>
</div>
</div>
I want to show popup on click of ActionList as shown above
Create a a div in your EmployeeList.cshtml to hold the html returned from Registration.cshtml
<div id="result"></div>
Make your Registration.cshtml as a partial view.
Use this anchor tag.
Create New
Make an ajax request to get the popup content and onsuccess, populate the div with the returned html and open the modal popup.
<script>
function funName()
{
$.ajax({
url: 'yoururl',
type: 'GET',
dataType: 'html',
success: function(data) {
$('#info').html(data);
$('#mymodal').modal('show');
},
error: function() {}
});
}
I think There are two options :
1. Forget about Registration.cshtml and put the below code in EmployeeList.cshtml:
<button type="button" class="openDialog">Create New</button>
<form class="modal fade mymodal" id="openDialogDiv" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
//code here to pop up
</div>
</div>
</div>
</form>
then show the form using jquery:
$('.openDialog').click(function(){
$('#openDialogDiv').modal();
});
2.create new action method in your controller which returns EmployeeRegistration.cshtml as partial view, let me name it DisplayRegistration() , now you can use ajax call, to DisplayRegistration() and display EmployeeRegistration.cshtml.
Please note that I changed Html.ActionLink to <button> tag

Kendo ui MVC window modal making Ajax call with paramters to controller

I am new to Kendo and I am having a very hard time trying to do this. I followed this demo.
here and got it to work up the part that I wanted to have a text box and a send button in the window modal that the user would have to fill in and click send.
I am able to use Ajax to make the call to my controller but I can't get the information in the modal window to pass to the controller via FormCollection. Here's my window modal template:
<script type="text/x-kendo-template" id="template">
<div id="details-container">
<h5 data-idtest="1">#= Id #</h5>
<h2>#= TitleDisplay # - #= ArtistDisplay #</h2>
Input The Day:<input id="TheDayTextBox" name="TheDay" type="text" />
#using (Ajax.BeginForm("TheAction", "Search", new AjaxOptions { UpdateTargetId = "#=Id" }))
{
<button class="btn btn-inversea" title="Log outa" type="submit">Log Offsdfsaf</button>
}
</div>
Controller:
public ActionResult TheAction(string id, FormCollection form)
{
....
}
So how does Kendo pass data to controller inside a modal?
Try putting your input inside of the actual form:
<script type="text/x-kendo-template" id="template">
<div id="details-container">
<h5 data-idtest="1">#= Id #</h5>
<h2>#= TitleDisplay # - #= ArtistDisplay #</h2>
#using (Ajax.BeginForm("TheAction", "Search", new AjaxOptions { UpdateTargetId = "#=Id" }))
{
Input The Day:<input id="TheDayTextBox" name="TheDay" type="text" />
<button class="btn btn-inversea" title="Log outa" type="submit">Log Offsdfsaf</button>
}

JQuery AJAX: Update ViewModel

I have a strongly-typed MVC view that includes a form with an editor that is bound to a view model:
#model ViewModels.CommentView
#using (Ajax.BeginForm("UpdateComments", new AjaxOptions { HttpMethod="POST" }))
{
<fieldset>
<legend>Metadata</legend>
<div>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.Comment)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Comment)
#Html.ValidationMessageFor(model => model.Comment)
</div>
</div>
<p class="action clear">
<input type="submit" value="Save" />
</p>
</fieldset>
}
When the user clicks on an element in a different part of the view, a JQuery AJAX call retrieves data from the server and updates the control:
<script type="text/javascript">
$(".load-comments").focus(function () {
var Id = $("#Id").val();
var url = "#Url.Action("GetComment")/" + Id;
$.ajax({ url: url, success: DataRetrieved, type: 'POST', dataType: 'json' });
function DataRetrieved(data) {
if (data) {
$("#Comment").val(data.Comment);
}
};
});
</script>
This functionality works as expected: the control content is visually updated. However, the value of the underlying html element is not updated, and when I post the form back to the server, the view model is empty.
How do I set the form controls' value in the JQuery function so that they post back to the server?
How did you set the HTML? ASP.NET default ModelBinder looks for id that are equals object properties to build the model back in the server. Looks like your form HTML doesnot reflect the object. Inspect each element created by Html helper and create each control as the same after comment data comes from the request. Hopes its help you! You can create a custom ModelBinder to Bind your model back in the server, take a look here: Model Biding

pass model from view to controller with html.actionlink

I am trying to get the model data from a strongly typed view to a controller.
Using the submit button is ok, I can get the data. Now I want to achieve the same with html.actionlink.
This is what I have:
View:
#model WordAutomation.Models.Document
#{
ViewBag.Title = "Document";
}
<script type="text/javascript">
$(function () {
$("#dialog").dialog();
});
</script>
<h2>Document</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Document</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ClientTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientTitle)
#Html.ValidationMessageFor(model => model.ClientTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ClientFullName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientFullName)
#Html.ValidationMessageFor(model => model.ClientFullName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ClientCustomSSN)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientCustomSSN)
#Html.ValidationMessageFor(model => model.ClientCustomSSN)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Preview", "PreviewWordDocument", "Home", null, new { id = "previewLink" })
</div>
<div id="dialogcontainer">
<div id="dialogcontent"><input type="submit" value="Create" /> </div>
</div>
#section Scripts {
<script type="text/javascript">
$(document).ready(function() {
$("#dialogcontainer").dialog({
width: 400,
autoOpen:false,
resizable: false,
title: 'Test dialog',
open: function (event, ui) {
$("#dialogcontent").load("#Url.Action("PreviewWordDocument", "Home")");
},
buttons: {
"Close": function () {
$(this).dialog("close");
}
}
});
$("#previewLink").click(function(e) {
e.preventDefault();
$("#dialogcontainer").dialog('open');
});
});
</script>
}
Controller:
public ActionResult Document()
{
return View();
}
[HttpPost]
public ActionResult Document(WordAutomation.Models.Document model)
{
Models.Utility.EditWord word = new Models.Utility.EditWord();
word.EditWordDoc(model);
return View("Display", model);
}
public ActionResult PreviewWordDocument()
{
var image = Url.Content("~/Content/preview.jpeg");
return PartialView((object)image);
}
The document actionresult can get the model, but I want to know how can I get the values from the actionlink which will trigger the PreviewWordDocument action.
Thanks in advance, Laziale
The form can only be posted using the submit button to the URL given by its action attribute.
You can however send the form data to a different URL using the jQuery post method, manually validating the form before it is sent.
That way you can send the form data to the PreviewWordDocument controller method and handle the response in order to show the preview in the desired div.
(It will be helpful if you give an id to the form, so you can easily find it using jQuery)
So your click event handler for the preview link will look like this:
$("#previewLink").click(function(e) {
e.preventDefault();
if($("#YourFormId").valid()){
$("#dialogcontainer").dialog('open');
}
});
In the open function of the dialog you will post the form (which was already validated) to the preview controller method, using the jQuery ajax function. The response will be loaded into the dialogContent div:
$.ajax({
type: "POST",
url: $("#previewLink").attr("href"), //the preview controller method
data: $("#YourFormId").serialize(),
success: function (data) {
//load ajax response into the dialogContent div
$("#dialogcontent").html(data);
},
error: function(xhr, error) {
$("#YourFormId").prepend('<div id="ajaxErrors"></div>')
.html(xhr.responseText);
}
});
Now you will now be able to receive the whole document in the PreviewWordDocument action:
public ActionResult PreviewWordDocument(WordAutomation.Models.Document model)
{
var image = Url.Content("~/Content/preview.jpeg");
return PartialView((object)image);
}
in a HTML page when you click on a submit button all the input elements inside the form which the submit button resides in will posted to server, but when you click on a anchor (<a> tag ). you only send a request with a Get method and without posting any value.but if you want to send particular value to the server with this approach you can do it by query string.you have used following to make a request :
#Html.ActionLink("Preview", "PreviewWordDocument", "Home", null,
new { id = "previewLink" })
this will produce :
<a id="previewLink" href="/Home/PreviewWordDocument"> Preview </a>
which is incorrect.to pass any value to the server with ActionLink use 4th parameter like this :
#Html.ActionLink("Preview", "PreviewWordDocument", "Home",
new { id = "previewLink" }, null)
the result from this code would be :
Preview
cheers!

Resources