JQuery AJAX: Update ViewModel - asp.net-mvc

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

Related

Multiple submits to different MVC controller actions from buttons or dropdownlist changes

If I have a single form - with two submits:
From a save button - calls a form POST "Save" controller action.
From a change of a dropdown list value - calls a form POST "NoSave" controller action that returns a modified view without saving.
What's the best way of achieving this?
At the moment, I have the following - but they both call the same POST controller action. I want to call a named action for the dropdownlist update.
<form form method="POST">
<!-- dropdown list -->
<div class="row">
#Html.LabelFor(x => x.FieldName, "Field Name:")
#Html.DropDownListFor(x => x.FieldName, Model.FieldName, new { #class = "browser-default", #onchange = #"form.submit();" })
#Html.ValidationMessageFor(x => x.FieldName)
</div>
</div>
<!-- save button-->
<div class="save-button">
<input type="submit" class="btn" value="Save" />
</div>
</form>
what about using ajax request for different type of requests every type of request call different action or even different controller
[HttpPost]
public ActionResult SomeFunction(string a)
{
return Json("some data here", JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult AnotherSomeFunction(string a)
{
return Json("some data here", JsonRequestBehavior.AllowGet);
}
//by click button
$("some button name ").click(function(){
$.ajax({
url: 'home/FirstAjax',
success: function(responce){ alert(responce.data)},
error: function(responce){ alert(responce.data)}
});
});
//by click another button
$("some button name ").click(function(){
$.ajax({
url: 'home/SecoundFirstAjax',
success: function(responce){ alert(responce.data)},
error: function(responce){ alert(responce.data)}
});
});
For this you can use ajax.beginform in first parameter you have to give the name of action and then controller and then some option which are like method type and success and failure actions.
#using (Ajax.BeginForm("_LoadPartial", "Abss", new AjaxOptions { HttpMethod = "POST", OnSuccess = "OnSuccess", OnFailure = "OnFailure" }))
{
<div class="row">
#Html.LabelFor(x => x.FieldName, "Field Name:")
#Html.DropDownListFor(x => x.FieldName, Model.FieldName, new { #class = "browser-default", #onchange = #"form.submit();" })
#Html.ValidationMessageFor(x => x.FieldName)
</div>
</div>
<!-- save button-->
<div class="save-button">
<input type="submit" class="btn" value="Save" />
</div>
}
Also provide OnSuccess and Failure Javascript fucntion on the same page.
<script>
function OnSuccess(){
// some action
}
function OnFailure(){
// some action
}
</script>

how to store user input value in local variable(in view) in asp.net mvc 5?

i want to declare a local variable in my razor html form (view) and want to store user input value in that local variable.And then want to use that variable in foreach loop .in mvc 5 i am new to asp.net.
#using (Html.BeginForm("AddQuestion", "admin", new { id = ViewBag.qf_id }, FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-group">
<label>Question Statement</label>
#Html.TextBoxFor(a => a.Ques.QuestionString, new { #class = "form-control" })
#Html.ValidationMessageFor(a => a.Ques.QuestionString)
</div>
<div class="form-group">
<label>No. of option you want to add for this question </label>
<div class="col-md-4">
#{var val = #Html.TextBoxFor(a => a.counter, new { #class = "form-control" }); }
</div>
</div>
foreach(var item in val)
{
#Html.TextBoxFor(a=>a.Ans.AnswerStatement)
}
<div>
<button class="btn btn-primary" type="submit">Add</button>
</div>
}
What you are trying to do won't work unless it gets adapted to 1 of 2 solutions:
1) The only way this works is if the use enters a value in the textbox, then posts back to the controller, and the controller inputs this variable into the model, which the view then re-renders, using the number in the model, with the desired number of entries. That's the web forms way and is inefficient.
2) Using JavaScript, when a user enters a number, JavaScript can either render the markup using a templating framework, or make a request to the server, get the individual data, and return a partial view as HTML.

jquery Ui tooltip from partial view mvc

I'm wondering is it possible to have a partial view display in a tooltip. I'm trying to design a page that has a group of students and when I hover over a student some details appear about them, a list of their subjects and some other details. I know I can put the items in the title, but I can't get all the info I need from there, and my details view has the info I need. Thanks in advance
Here's my current code
IEnumerable<StudentApp.Models.Student>
#foreach (var item in Model)
{ <div class="col-md-2 col-sm-4">
<img title="#item.Name, #item.StudentNo " class="img img-responsive" src="#item.StudentPic" />
</div>
}
#section scripts
{
<script type="text/javascript">
$(document).ready(function () {
$(document).tooltip();
});
</script>
}
Here's my details view
<div class="display-label">
#Html.DisplayNameFor(model => model.Name)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.Name)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.StudentNo)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.StudentNo)
</div>
#foreach (var item in Model.Students)
{
<li>#item.Course</li>
}
You can use the content option to make the tooltip's contents whatever you need them to be. The MVC code could be placed anywhere in your page, so long as you can use jQuery to grab it (eg. in a noscript tag or some such):
$(document).tooltip({
items: ".myTooltipClass",
content: function() {
// .text() will unescape any contained HTML and render it properly;
// use .html() if your content doesn't contain additional HTML
return $("noscript#myMvcContent").text();
}
});
Here's a fiddle demo: http://jsfiddle.net/guke50uw/
As you can use $(this) inside the content function, you can make use of that with HTML data attributes to return different tooltips for the different items; depends on how your page is structured.
I would use the tooltip's open method and set the content of the tooltip object via AJAX there:
$(document).ready(function () {
$(document).tooltip({ open: function(event, ui) {
$(ui.content).load("[url for returning view contents]");
}
});
you may need to use the instance property of the tooltip or maybe via the ui parameter of the open function to retrieve your student number or other identifier to properly query your partial view, but this should help get you going.

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!

MVC3 using jquery.validate.unobtrusive.js and $("#form").submit() hijax not working

I have a basic form
#Html.ValidationSummary(true)
using (Html.BeginForm("Index", "Home", FormMethod.Post, new { #class = "form" }))
{
<div class="editor-label">
<label for="Name">#Html.LabelFor(model => model.Name)</label>
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
</div>
and so on. My Model is using data annotations and validation is turned on.
I'm hijaxing the form using some jquery:
<script type="text/javascript">
$("form[action='/']").submit(function () {
$.post($(this).attr("action"), $(this).serialize(), function (response) {
$("#contactForm").replaceWith($("#contactForm", response));
});
return false;
});
</script>
This works if I type the fields in correctly and submit. But the strange thing is if I enter an invalid value into one of the form fields and the validation code kicks in to highlight my mistake the submit event function I appended in the hijaxing script above is lost and a full post happens.
Any good ideas as to how I get around this?
I think when you add a submit handler to your form you are overwriting the submit handler that the jquery validation / data annotations adds.
To get around this you can add:
var theForm = $(this);
if ( theForm.valid() ) {
$.post($(this).attr("action"), $(this).serialize(), function (response) {
$("#contactForm").replaceWith($("#contactForm", response));
});
return false;
}
This will make sure the form is valid before making the POST.

Resources