I have a problem: I Have created a UserControl A, A has its own controller in order to reuse Usercontrol actions in every view added, UserControl A expects a model UserControlModel, what I want to do is to update the model of the view that contains the UserControl A.
How can I pass value from the UserControl to main view or any view containg the user control in order to persist this value?
Some Code :
UserControl Controller
public class ColorBlockUserControlController : Controller
{
/// <summary>
/// Callback method for ColorBlockUserControl's AJAX form.
/// </summary>
/// <param name="model">ColorModel</param>
/// <returns>HTML string to be dispalyed within target DIV tag.</returns>
[HttpPost]
public ActionResult DrawColor(ColorModel model)
{
if (ModelState.IsValid)
{
return Content(ColorManager.GetGradientDiv(model.RGBColor, model.Width, model.Height));
}
else
{
return Redirect("/");
}
}
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult Sumar(int Height, int Width)
{
return Json(true);
}
}
UserControl HTML :
<script type="text/javascript">
$(document).ready(function () {
var Valores = {
'Height': 30,
'Width': 30
};
$("#btnSumar").click(function () {
var targetDiv = "#TargetResult";
$.post(
'/ColorBlockUserControl/Sumar',
Valores,
function (data) {
if (data === true) {
debugger;
$(targetDiv).html('Sumado');
}
else {
alert('Failed to save the user');
}
},
'json'
);
});
});
</script>
#using (Ajax.BeginForm("DrawColor", "ColorBlockUserControl", new AjaxOptions { UpdateTargetId = "color-" + Model.Id }))
{
<div>RGB (example: FFAA00)</div>
<div class="formLine">
#Html.EditorFor(x => x.RGBColor)
</div>
#Html.ValidationMessageFor(x => x.RGBColor)
<div>Width</div>
<div class="formLine">
#Html.EditorFor(x => x.Width)
</div>
<div>Height</div>
<div class="formLine">
#Html.EditorFor(x => x.Height)
</div>
<div id="btnSumar" style="cursor:pointer;">This is a Test</div>
<p><input type="submit" value="Color Me!" /></p>
<div id="color-#Model.Id"><!-- Will be populated by AJAX method --></div>
}
View with UserControl:
#model MVCColorUserControl.Models.HomeModel
#using MVCColorUserControl.Models
#{
ViewBag.Title = "Color Demo";
}
<h2>#Model.WelcomeText</h2>
<p>
A Partial Control</p>
#Html.Partial("UserControls/ColorBlockUserControl", new ColorModel())
<hr />
#*<p>
A Partial Control that is initialized on Server-Side</p>
#{
Html.RenderAction("InitializeUserControl");
}*#
#Html.ActionLink("Ir a Test View", "Test")
#Html.ActionLink("Usando otro controller", "InNewController")
To answer your question about the FormCollection:
in your Controller you can do this:
[HttpPost]
public ActionResult GetMeSomeValues(FormCollection formCollection)
{
string text = formCollection.Get("Name of the input or whatever you have in your form");
//same goes for int values which you will need to convert from a string.
//Now if you want to pass the value to a Model simply create a new Model in here
//and add it.
var model = new Model();
model.Value = text;
return View(model);
}
Related
I have a sort of Master-Detail Edit form and I'm trying to follow this post: Using Ajax... to get the partial view to postback.
My Edit form has a partial view that has a list of sub items, and another partial create view in it to add new items. I'd like the partial create view to post back and update the list without refreshing the whole page if possible.
Here's what I have so far:
MyController.cs -
public ActionResult Edit(int? id)
{
//...
ViewBag.CustomFormId = id;
using (var _db = new MkpContext())
{
//...
return View(profileEdit);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomForm editForm)
{
//...
if (!ModelState.IsValid) return View(editForm);
using (var _db = new MkpContext())
{
var form = _db.CustomForms.Find(editForm.CustomFormId);
//...
_db.Entry(form).State = EntityState.Modified;
_db.SaveChanges(User.ProfileId);
return RedirectToAction("Index");
}
}
public ActionResult _CustomFieldList(int id)
{
ViewBag.CustomFormId = id;
using (var _db = new MkpContext())
{
var formCustomFields = (from cf in _db.CustomFields
where cf.CustomFormId == id
select cf);
return PartialView(formCustomFields.ToList());
}
}
// Nested in _CustomFieldList
public ActionResult _CustomFieldCreate(int id)
{
var newField = new CustomField
{
CustomFormId = id
};
return PartialView(newField);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _CustomFieldCreate(CustomField addField)
{
ViewBag.CustomFormId = addField.CustomFormId;
if (ModelState.IsValid)
{
using (var _db = new MkpContext())
{
_db.CustomFields.Add(addField);
_db.SaveChanges();
}
var newField = new CustomField
{
CustomFormId = addField.CustomFormId
};
return PartialView(newField); // Probably need to change this somehow
}
return PartialView(addField);
}
And the views:
Edit.cshtml -
#model PublicationSystem.Model.CustomForm
#{
ViewBag.Title = "Edit Custom Form";
Layout = "~/Views/Shared/_LayoutSmBanner.cshtml";
}
<div class="form-horizontal">
<div class="row">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#* Fields for this form *#
}
<div id="CustomFields" class="col-md-6">
#Html.Action("_CustomFieldCreate", new { id = ViewBag.CustomFormId })
</div>
</div>
</div>
<script>
$(function () {
$("#createFieldForm").on("submit", function (e) {
e.preventDefault(); //This prevent the regular form submit
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$("#CustomFields").html(result);
}
});
return false;
});
});
</script>
_CustomFieldCreate.cshtml -
#model PublicationSystem.Model.CustomField
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div id="result"></div>
<div class="form-horizontal">
<h4>CustomField</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model =>model.CustomFormId)
<div class="row">
#* Fields for the form *#
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div id="customFieldList">
#Html.Action("_CustomFieldList", new { id = ViewBag.CustomFormId })
</div>
_CustomFieldList.cshtml
#model System.Collections.Generic.IEnumerable<PublicationSystem.Model.CustomField>
<table class="table">
#* List table code *#
</table>
Edit: I rewrote the pages so that the list is part of the create partial view. What happens now is, if you enter data for _CustomFieldCreate and press submit, the first time, it refreshes just that view (including the nested list view). However the second time, it redirects to the view, probably because the first refresh didn't rebind the javascript to the submit button. Also, the Create view doesn't clear out the fields, but persists the originally entered data.
You will need a form in your partial view whose submit action binds to a javascript function that posts to your controller.
For example if your form id is MyForm:
$('#MyForm').on('submit', function (e) {
e.preventDefault(); //This prevent the regular form submit
$.ajax({
url: $(this).action, // This will submit the post to whatever action your form goes to
type: "POST", // This tells it that it is a post
data: $(this).serialize(), // This sends the data in the form to the controller
success: function (data) {
// do some javascript on success
},
error: function (xhr, ajaxOptions, thrownError) {
// do some javascript on error
}
});
});
This javascript overrides the default form submit and does an ajax post to your controller and then returns with success or error where you can do anything you want.
Here is some jquery ajax documentation:
http://api.jquery.com/jquery.ajax/
You should look into using AJAX. That should accomplish what I think you are describing. You'll want to create a javascript function that handles the submit event on the form, then post the form data to some create action in your MVC app using AJAX. If you are using jQuery, the library makes it pretty simple.
http://api.jquery.com/jquery.ajax/
I have a form in MVC 4 which contains several fields and, depending on the value of a combo, I need to open a modal dialog form and load into that one 3 additional fields that will impact against the same entity that I'm creating/editing in the main form.
For this modal dialog I'm using the one from jQuery UI.
Now, what I need to do is to validate (Required) the fields within the modal dialog in order to allow the user to retain the entered values which will be submited later by the main form.
My problem is how to perform the validation of those 3 fields from within the modal form (because they wouldn't be able to submit the main form until dialog is closed).
Any hints or ideas?
Regards,
Cesar.
You could use AJAX to submit the form modal to the server. The modal form will have of course a separate view model associated with it. Let's exemplify:
Main view model:
public class MyViewModel
{
[DisplayName("select a value")]
public string SelectedValue { get; set; }
public IEnumerable<SelectListItem> Values { get; set; }
public string SomeOtherProperty { get; set; }
}
Modal dialog view model:
public class DialogViewModel
{
[Required]
public string Prop1 { get; set; }
[Required]
public string Prop2 { get; set; }
[Required]
public string Prop3 { get; set; }
}
Then you could have a controller containing 4 actions:
public class HomeController : Controller
{
// Renders the main form
public ActionResult Index()
{
var model = new MyViewModel
{
Values = new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
}
};
return View(model);
}
// Processes the submission of the main form
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return Content(
string.Format(
"Thanks for filling out the form. You selected value: \"{0}\" and other property: \"{1}\"",
model.SelectedValue,
model.SomeOtherProperty
)
);
}
// Renders the partial view which will be shown in a modal
public ActionResult Modal(string selectedValue)
{
var model = new DialogViewModel
{
Prop1 = selectedValue
};
return PartialView(model);
}
// Processes the submission of the modal
[HttpPost]
public ActionResult Modal(DialogViewModel model)
{
if (ModelState.IsValid)
{
// validation of the modal view model succeeded =>
// we return a JSON result containing some precalculated value
return Json(new
{
value = string.Format("{0} - {1} - {2}", model.Prop1, model.Prop2, model.Prop3)
});
}
// Validation failed => we need to redisplay the modal form
// and give the user the possibility to fix his errors
return PartialView(model);
}
}
Next you could have a main view (~/Views/Home/Index.cshtml):
#model MyViewModel
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.SelectedValue)
#Html.DropDownListFor(x => x.SelectedValue, Model.Values, new { id = "ddl" })
</div>
<div>
#Html.LabelFor(x => x.SomeOtherProperty)
#Html.TextBoxFor(x => x.SomeOtherProperty, new { id = "otherProperty" })
#Html.ActionLink(
"click here to open a modal and help you fill the value",
"Modal",
"Home",
null,
new { id = "showModal" }
)
</div>
<button type="submit">OK</button>
}
<div id="modal"></div>
and a partial view to contain the modal form (~/Views/Home/Modal.cshtml):
#model DialogViewModel
#using (Ajax.BeginForm(new AjaxOptions { OnSuccess = "handleModalSubmit" }))
{
<div>
#Html.LabelFor(x => x.Prop1)
#Html.EditorFor(x => x.Prop1)
#Html.ValidationMessageFor(x => x.Prop1)
</div>
<div>
#Html.LabelFor(x => x.Prop2)
#Html.EditorFor(x => x.Prop2)
#Html.ValidationMessageFor(x => x.Prop2)
</div>
<div>
#Html.LabelFor(x => x.Prop3)
#Html.EditorFor(x => x.Prop3)
#Html.ValidationMessageFor(x => x.Prop3)
</div>
<button type="submit">OK</button>
}
OK, now all that's left is write some javascript to make the whole thing alive. We start by making sure that we have included all the required scripts first:
<script src="#Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.20.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
and then write our own:
$(function () {
$('#showModal').click(function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
data: { selectedValue: $('#ddl').val() },
success: function (result) {
$('#modal').html(result).dialog('open');
}
});
return false;
});
$('#modal').dialog({
autoOpen: false,
modal: true
});
});
function handleModalSubmit(result) {
if (result.value) {
// JSON returned => validation succeeded =>
// close the modal and update some property on the main form
$('#modal').dialog('close');
$('#otherProperty').val(result.value);
} else {
// validation failed => refresh the modal to display the errors
$('#modal').html(result);
}
}
I am interested in creating an AJAX form submit in a jQuery overlay. I am not sure how to approach this, do I just toss a partial view into the overlay?
I want to pass to the server the data in the form of a model so I can save it the the data base, I need to be able to create some sort of indication as to whether or not the request succeed. Can anyone guide me through this?
I am kinda new with AJax.
You could use jQuery UI Dialog. For example let's suppose that you have a view model:
public class MyViewModel
{
public string Foo { get; set; }
[Required]
public string Bar { get; set; }
}
and a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Modal()
{
return PartialView(new MyViewModel());
}
[HttpPost]
public ActionResult Modal(MyViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
return Json(new { success = true });
}
}
In this example the Index action will serve the main view which will simply contain a link allowing to show the form as a modal dialog.
Here's the Index.cshtml view:
#Ajax.ActionLink(
"show form in modal",
"modal",
new AjaxOptions { OnSuccess = "onModalLoad" }
)
<div id="modal"></div>
and the Modal.cshtml partial which will contain the form:
#model MyViewModel
#using (Ajax.BeginForm(new AjaxOptions { OnSuccess = "onSubmitSuccess" }))
{
<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>
<button type="submit">OK</button>
}
The last step is to wire everything using javascript. Here are the 2 callbacks used:
var onModalLoad = function (result) {
$('#modal').html(result).dialog();
}
var onSubmitSuccess = function (result) {
if (!result.success) {
$('#modal').html(result);
} else {
alert('thanks for submitting');
$('#modal').dialog('close');
}
};
and that's it.
Don't forget to reference the jquery-ui and jquery.unobtrusive-ajax scripts to your page:
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
I am very new to JQuery and MVC. In my application i am opening a JQuery modal dialog on button click. I am rendering a partial view on this dialog using controller action method which is something like:
public ActionResult Create()
{
return PartialView("Create");
}
Partial view contains some textboxes and "create" button. On create button i am trying to save data in database. But before that i do some validation like if entered name already exist then show that message to user.
I did this using following code:
return PartialView("Create", model);
this is showing the message properly but it render only partial view in browser and modal dialog gets disappeared.
Please let me know how can i show the same modal dialog with error.
You will need to use AJAX submit of the form. Here's how to proceed. As always start with a view model which will represent the information for the dialog form:
public class MyViewModel
{
public string Foo { get; set; }
[Required(ErrorMessage = "The bar is absolutely required")]
public string Bar { get; set; }
}
then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Create()
{
return PartialView("Create");
}
[HttpPost]
public ActionResult Create(MyViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView(model);
}
// TODO: the model is valid => do some processing with it
// and return a JSON result confirming the success
return Json(new { success = true });
}
}
and a main view (~/Views/Home/Index.cshtml):
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script>
<script type="text/javascript">
// Remark: all this javascript could be placed in a separate js file
// to avoid cluttering the views
$(function () {
$('#modalLink').click(function () {
$('#dialog').load(this.href, function () {
$(this).dialog();
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) {
alert('thanks for submitting');
$('#dialog').dialog('close');
} else {
$('#dialog').html(result);
bindForm();
}
}
});
return false;
});
}
</script>
#Html.ActionLink("open modal", "create", null, null, new { id = "modalLink" })
<div id="dialog"></div>
and a partial view (~/Views/Home/Create.cshtml) which will contain the form shown in the modal:
#model MyViewModel
#using (Html.BeginForm())
{
<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>
<input type="submit" value="OK" />
}
I am using three partialview on a single view, I have a submit button on clicking of which I want to send information to database, I have to retrieve data from all the partialview.
Can You please provide me correct information to do it.
Darin I m using L2S so when I drag my stored procedure, I get code some thing like this in
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="SP_Name")]
public int SP_Name(
[global::System.Data.Linq.Mapping.ParameterAttribute(Name="EmployeeID", DbType="Int")] System.Nullable<int> EmployeeID
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), EmployeeID);
encounterID = ((System.Nullable<int>)(result.GetParameterValue(293)));
return ((int)(result.ReturnValue));
}
}
Updated
<script language="javascript" type="text/javascript">
$(function () {
$('#Form1').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (data) {
var message = data.Result;
$('#Result').html(message);
}
});
return false;
});
});
</script>
In my Controller I am using
public ActionResult Index(FormCollection frm)
{
My Code ---------------------
return Json(new { Result = "Success" });
}
When I return this I m getting a file in post back and it ask me to save it.
I have checked using flidder, in URL it shows me that the path as / only
where as If I fill any particular partialview It shows something like /Controller Name/Partialview
Can You help me with this problem
Well, sending data to a controller action is usually done by performing an HTTP request to this controller action. There are different ways of performing an HTTP request:
Use a <form> tag pointing to this action
Use AJAX
So if you go with the first approach you could have a single <form> wrapping all the partials which would have multiple submit buttons (with different names). Then when you click on one submit buttons all the input fields will be sent to the controller action and then inside the controller action you could process the data based on which submit button was clicked.
If you use the second option, well, then simply harvest the values you need to be sent uipon button click and send them along the AJAX request.
UPDATE:
As requested in the comments section here's how the first technique could be put into action. It uses two partials instead of three but it could be easily extrapolated.
As always you start by defining a view model which will represent the data you would like to work with on this particular view:
public class MyViewModel
{
public Partial1ViewModel Model1 { get; set; }
public Partial2ViewModel Model2 { get; set; }
}
public class Partial1ViewModel
{
public string Foo { get; set; }
}
public class Partial2ViewModel
{
public string Bar { get; set; }
}
Then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Model1 = new Partial1ViewModel { Foo = "foo" },
Model2 = new Partial2ViewModel { Bar = "bar" },
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// Here you have access to model.Model1.Foo and model.Model2.Bar =>
var button = "";
if (!string.IsNullOrEmpty(Request["submit1"]))
{
// submit1 button was used
button = "submit1";
}
else if (!string.IsNullOrEmpty(Request["submit2"]))
{
// submit2 button was used
button = "submit2";
}
var result = string.Format("thanks for submitting using {0}", button);
return Content(result, "text/plain");
}
}
and then a main view (~/Views/Home/Index.cshtml):
#model MyViewModel
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.Model1)
#Html.EditorFor(x => x.Model2)
}
and the two corresponding editor templates (or partials if you will):
~/Views/Home/EditorTemplates/Partial1ViewModel.cshtml:
#model Partial1ViewModel
<h2>Partial 1</h2>
<div>
#Html.LabelFor(x => x.Foo)
#Html.EditorFor(x => x.Foo)
<input type="submit" value="Submit me!" name="submit1" />
</div>
~/Views/Home/EditorTemplates/Partial2ViewModel.cshtml:
#model Partial2ViewModel
<h2>Partial 2</h2>
<div>
#Html.LabelFor(x => x.Bar)
#Html.EditorFor(x => x.Bar)
<input type="submit" value="Submit me!" name="submit2" />
</div>