MVC update partial view onchange drop down list - javascript

I want to update a partial view when user changes the current value of my drop down list.
With my onchange submit, the partial view does not load in div but replaces the whole page.
How can I fix it?
view:
#using (Ajax.BeginForm("GetEnvironment", new RouteValueDictionary { { "Environment", Model.Environnements } }, new AjaxOptions() { UpdateTargetId = "ExportDiv" }))
{
#Html.DropDownListForEnum(x => x.Environnements, new { onchange = "this.form.submit();" })
}
<div id="ExportDiv">
#Html.Partial("Export")
</div>
Controller :
public PartialViewResult GetEnvironment(ExampleDto model)
{
return PartialView("Export", model);
}
Export.cshtml

It looks like triggering submit on the form causes whole page to be posted instead of AJAX behavior. Try this:
#using (Ajax.BeginForm("GetEnvironment", new RouteValueDictionary { { "Environment", Model.Environnements } }, new AjaxOptions() { UpdateTargetId = "ExportDiv" },new {id = "ajaxForm"))
{
#Html.DropDownListForEnum(x => x.Environnements, new { onchange = "submitAjaxForm()" })
}
<div id="ExportDiv">
#Html.Partial("Export")
</div>
<script type="text/javascript">
$('form#ajaxForm').submit(function(event) {
eval($(this).attr('onsubmit')); return false;
});
window.submitAjaxForm = function(){
$('form#ajaxForm').submit();
}
</script>
You need to include the scripts in thier own section if you are using it.

The result should be the same than what Ufuk suggested, but did you try simply adding return false; after this.form.submit(); ?

Related

AJAX not updating partial view

I'm currently having difficulty using Ajax to update a partial view without having to refresh the whole page. I'm using MVC and entity framework to scaffold views.
I'll try and include as much as possible to help explain myself:
I have a div which is going to be used to hold a list view of all my comments
<div id="ContainAnnouncementComments"> </div>
This div gets populated using the following:
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Custom_Scripts/BuildAnnouncement.js"></script>
#Scripts.Render("~/bundles/jqueryval")
$(document).ready(function () {
$.ajax({
url: '/Comments/BuildAnnouncementComment',
data: { AnnouncementId: #Model.AnnouncementId},
success: function (result) {
$('#ContainAnnouncementComments').html(result);
}
});
});
Which calls the BuildAnnouncementComment() method in my controller:
public ActionResult BuildAnnouncementComment(int? AnnouncementId)
{
return PartialView("_AnnouncementComment", db.Comments.ToList().Where(x => x.AnnouncementId == AnnouncementId));
}
I then have a second div container which is used to hold a text box for a user to enter some information which 'should' then update the ContainAnnouncementComments using Ajax replace call:
<div id="ContainAnnouncementCommentCreate">
#using (Ajax.BeginForm("AJAXCreate", "Comments", new { announcementId = Model.AnnouncementId }, new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "ContainAnnouncementComments"
}))
{
<div class="form-group">
#Html.AntiForgeryToken()
<div class="col-md-10">
#Html.EditorFor(model => model.Message, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Message, "", new { #class = "text-danger" })
</div>
</div>
}
</div>
The Ajax method calls the AJAXCreate method in the controller:
public ActionResult AJAXCreate(int announcementId, [Bind(Include = "CommentId, Message")] Comment comment)
{
if (ModelState.IsValid)
{
comment.UserId = User.Identity.GetUserId();
comment.AnnouncementId = announcementId;
db.Comments.Add(comment);
db.SaveChanges();
}
return PartialView("_AnnouncementComment", db.Comments.ToList());
}
From here, when running, I try to create a new comment, but when submitted, instead of the partialView being updated, all that is being displayed is the partialview.
Not sure if I've explained this properly so if i'm missing any information please let me know and i'll update accordingly.
After 3 hours of staring at my code I realised that nothing was actually wrong with the implementation and all that was wrong was I hadn't installed AJAX through the NuGet manager.
Joys.

Populate second model in same view in MVC : Prevent postback

I have a page in MVC, where i need to display the details of the records.
The records needed to be fetched from 2 tables for which i have Model separately.
Now, for this page needing both the models, I have created another model which have those 2 model referred.
[Please note, following nomenclature's are only for example purposes.]
public class CombinedModel
{
public Model1 objModel1 { get; set; }
public Model2 objModel2 { get; set; }
}
In the view [Details.cshtml], I have following code:
#model Application.Web.Models.CombinedModel
<div>
#Html.Label("Label text: ", htmlAttributes: new { #class = "control-label" })
#Html.DisplayFor(model => model.objModel1.Property1, new { htmlAttributes = new { #class = "form-control" } })
</div>
And a popup code
<div id="Modal">
<div>
#Html.Label("Popup label text:", htmlAttributes: new { #class = "control-label" })
#Html.DisplayFor(vmodel => vmodel.objModel2.Property2, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
The page loads with the data in from the first model successfully from controller action.
I needed Data in the popup code, only when user clicks on particular record, from where View will send ID and will display record for that particular ID from the second model.
In Controller:
public class ControllerNameController : Controller
{
[HttpGet]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
[ValidateInput(false)]
public ActionResult Details(int? Id, string strType, string strVersionID)
{
var Details1 = db.Table1.FirstOrDefault(rd => rd.SomeID == Id);
CombinedModel modelCombined = new CombinedModel();
Model1 objectM1 = new Model1();
objectM1.Property1 = Details1.Column1;
var VersionDetails = db.Table2.FirstOrDefault(rvd => rvd.somePrimaryKeyID == Convert.ToInt32(strVersionID));
if (VersionDetails != null)
{
Model2 objectM2 = new Model2();
objectM2.vCreatedOn = VersionDetails.Property2;
modelCombined.objModel2 = objectM2;
ViewBag.VersionID = VersionDetails.VersionID;
}
modelCombined.objModel1 = objectM1;
return View(rmodel);
}
}
The page landing URL is:
function JavascriptFunctionInParentView(IDToPass, strTypeToPass)
{
top.location.href = "#Url.Action("Details", "ControllerName")"
+ "?Id=" + IDToPass
+ "&strType='" + strTypeToPass + "'"
+ "&strVersionID='0'";
}
SO, when first time page loads, we have strVersionID as Zero. So, it will not enter in VersionDetails block and fill only Model1 data.
Now, when we are Details page, there is a grid, from which, I need to populate the version details in the popup, for which I have working code as following:
function recordDoubleClickRuleVersion(args) {
top.location.href = "#Url.Action("Details", "ControllerName")"
+ "?Id=" + #Url.RequestContext.HttpContext.Request.QueryString["Id"]
+ "&strType=" + '#Url.RequestContext.HttpContext.Request.QueryString["strType"]'
+ "&strVersionID=" + args.data.VersionID;
}
// ....
$(function () {
if ('#(ViewBag.VersionID)' == "") {
$("#Modal").ejDialog("close");
}
if ('#(ViewBag.VersionID)' != "") {
$("#Modal").ejDialog(
{ enableModal: true, enableResize: false, close: "onDialogClose", width: "60%" });
$("#Modal").ejDialog("open");
}
})
My problem is, when i call this Version details popup, page postbacks and then data comes.. I know i have given #Url.Action to it so it is behaving like this way.
I needed it to be by complete Client-side code and I tried following code as well. It open's popup but doesn't fill value in it.
$.ajax({
type: "GET",
data: ({
"Id": #Url.RequestContext.HttpContext.Request.QueryString["Id"],
"strType": '#Url.RequestContext.HttpContext.Request.QueryString["strType"]',
"strVersionID": args.data.VersionID }),
url: '#Url.Action("RuleDetails", "Rules")',
})
.done(function (RuleVersionDetails) {
// 1. Set popup
$("#Modal").ejDialog(
{ enableModal: true, enableResize: false, close: "onDialogClose", width: "60%" });
// 2. Open popup
$("#Modal").ejDialog("open");
});
Can you please tell me the solution for this ?
You can change you Details() Action to return a Json object, and then fill the dialog with it.
$.ajax({
type: "GET",
data: ({
"Id": #Url.RequestContext.HttpContext.Request.QueryString["Id"],
"strType": '#Url.RequestContext.HttpContext.Request.QueryString["strType"]',
"strVersionID": args.data.VersionID }),
url: '#Url.Action("RuleDetails", "Rules")',
})
.done(function (jsonData) {
// **TODO: file dialog with properties of jsonData**
// 1. Set popup
$("#Modal").ejDialog(
{ enableModal: true, enableResize: false, close: "onDialogClose", width: "60%" });
// 2. Open popup
$("#Modal").ejDialog("open");
});
The best approach for your case is using bootstrap modal.Go here and check its documentation and how to config. If you aren't familiar with bootstrap or modal, it really worth to learn.
But remember when you want sent data to modal section, make it dynamic based on your item id in grid.

ASP.net MVC Success Alert After Form submit

I want to display success Alert pop-up or alert message after form submited and action succeded
In this example I want to show "successfully add" :
Create Action :
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(TAUX taux)
{
if (ModelState.IsValid)
{
db.TAUX.Add(taux);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CAT_ID = new SelectList(db.CATEGORIE, "CAT_ID", "LIBELLE", taux.CAT_ID);
ViewBag.C_GARANT = new SelectList(db.GARANTIE, "C_GARANT", "LIB_ABREGE", taux.C_GARANT);
return PartialView("_Create", taux);
}
Index Action :
public ActionResult Index()
{
var taux = db.TAUX.Include(t => t.CATEGORIE).Include(t => t.GARANTIE);
return View(taux.ToList());
}
What should I add to do this ?
It's possible, for sure, but implementation details might change from technologies and app structure.
One of the most common ways for doing this (and the one I'm currently using with great success) is to receive whater-you-need-to-receive and return a JSON object with the status and/or error message, which will be used by some script on your view.
For example:
[Route(""), HttpPost]
public JsonResult DoSomethingOnTheServer(DoSomethingViewModel vm)
{
try
{
if (DoSomething(vm)) return Success();
else return Error("The server wasn't able to do something right now.");
}
catch (Exception err)
{
return Error(err.Message);
}
}
public JsonResult Success() { return Json(new { Success = true, Message = "" }); }
public JsonResult Error(string message) { return Json(new { Success = false, Message = message }); }
This way, you can do something like:
<script>
$.ajax({
url: "/",
method: "POST",
data: getMyData(),
success: function(json) {
if (json.Success) {
alert("Wow, everything was fine!");
} else {
alert(json.Message);
}
},
// This will be trigered whenever your ajax call fails (broken ISP link, etc).
error: function() {
alert("Something went wrong. Maybe the server is offline?");
}
});
</script>
Being honest with you, it's possible to submit the form (regular submit, I mean) and on the page refresh, display whatever you want.
This will, however, force you to load something extra with your view model, like an extra <script> tag or some extra <div> tags and to check for that every time.
From a usability/design point-of-view, it's a no-go. Avoid page refresh whenever possible because they give a feeling for the user that the app is either going away or that he/she is now moving outsinde the app.
Also, from a performance point-of-view, "full round-trips" to the server, consisting of sending the form data and retrieving a whole new page (with the whole layout, scripts, razor rendering/parse and all) is a massive problem just to show "success/fail" for the end-user so, again: avoid it whenever possible.
IMHO, returning either a view or a partial view only to display a message to the end-user is just wasting both yours and your end-users' link.
I used to make Ajax Form and in the OnSuccess fucntion i show message :
#using (Ajax.BeginForm("Edit1", "Availability", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.InsertBefore, UpdateTargetId = "formAddAvailabilityContainer", OnSuccess = "AddAvailabilitySuccess" }, new { #class = "AjaxForm", #id = "formAvailability_" + Model.Id }))
{
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model => model.UserId)
#Html.EditorFor(model => model.StartTime)
#Html.MyValidationMessageFor(model => model.StartTime)
#Html.EditorFor(model => model.EndTime)
#Html.MyValidationMessageFor(model => model.EndTime)
#Html.EditorFor(model => model.RecurrenceFreq)
#Html.MyValidationMessageFor(model => model.RecurrenceFreq)
#Html.TextBoxFor(model => model.EndsAfterValue, new {id="txtBoxEndsAfterValue" })
#Html.MyValidationMessageFor(model => model.EndsAfterValue)
#Html.EditorFor(model => model.EndsByDate)
<input type="submit" class="btn btn-primary" value="Save" id="btnsubmit" />
<input type="button" class="btn btn-primary btnCancelAvailability" id="0" value="Cancel">
}
<script>
function AddAvailabilitySuccess()
{
alert("Record updated successfully!");
}
</script>
I have a way to do this, using the ViewBag.
In your controller you must add:
if (ModelState.IsValid)
{
db.TAUX.Add(taux);
db.SaveChanges();
ViewBag.SuccessMsg = "successfully added";
return RedirectToAction("Index");
}
Then in the Index view:
#{
var message = ViewBag.SuccessMsg;
}
<script type="text/javascript">
var message = '#message';
if(message){
alert(message);
}
</script>
in the end you use JavaScript mixed with the MVC ViewBag :)

how to pass Kendoui drop down selected value to controller

how to bind Kendo ui dropdownlist with model and how to send that selected value to controller with a button Click
for other operations....
could you please explain be in detail...am a fresher...
thanks in advance
View:
#model Contract
#{
var vendors = ViewData["Lookups"] as List<Vendor>;
}
#using (Html.BeginForm("Create", "Contract", FormMethod.Post, new { id = "contractDetailsForm" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Contract</legend>
<div>
#{
Html.Kendo().DropDownListFor(model => model.VendorId).Name("VendorId")
.BindTo(new SelectList(vendors, "ID", "DisplayName", "Nothing Selected"))
.HtmlAttributes(new { #style = "width:250px;" })
.Value(Model.VendorId.ToString())
.Render();
}
</div>
<div>
<button type="submit" class="k-button k-button-icontext">
<span class="k-icon k-insert"></span>Create Contract</button>
</div>
</fieldset>
}
Controller:
[HttpPost]
public ActionResult Create(Contract contract)
{
if (ModelState.IsValid)
{
contract.ID = Guid.NewGuid();
_repository.Add(contract);
_repository.SaveChanges();
//return or redirect to another View ...
}
return View("Create", contract);
}
write select event for the dropdown list like
function onSelect(e) {
var DropDownval = $("#QuestionType").val();
}
put this value in the session or in a variable and pass it to the controller.

How do I use ACE with my ASP.NET MVC application?

I want to use the ACE online code editor in my project. How do I use it in ASP.NET MVC?
I'd like to save whatever edits are made with that editor in the database. How do I do that?
Let's assume you have a strong typed model with a property called Editor with the data in it. Now use a normal <div> to load the data:
<div id="editor"><%=Model.Editor %></div>
Now you can create an ace editor in place of the div with javascript:
<script src="src/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
window.onload = function() {
var editor = ace.edit("editor");
};
</script>
Now when you want to save the data, for instance via a form post, use something like this to bind it back to the Editor property of the model:
<%=Html.HiddenFor(m=>m.Editor, new { #id = "hidden_editor" }) %>
<!-- this is jQuery, but you can use any JS framework for this -->
<script>
$("form").submit(function () {
$("#hidden_editor").val(editor.getSession().getValue());
});
</script>
In your controller you can now save the data to the database
[HttpPost]
public ActionResult Index (IndexModel model) {
var data = model.Editor;
// save data in database
}
Here is a solution using most recent technologies (Razor/MVC/Ajax) :
$(document).ready(function() {
$("#btnSave").on("click", function () {
$.ajax({
url: '#Url.Action("YourAction", "YourController")',
type: 'POST',
data: { id: #Model.ID,
html: ace.edit("editor").getValue() },
cache: false,
success: function (response) {
alert("Changes saved.");
}
});
});
});
In Controller :
[AjaxAuthorize]
[HttpPost, ValidateInput(false)]
public ActionResult YourAction(string id, string html)
{
if (id == null || String.IsNullOrEmpty(id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// do you stuff
}
This is how I ended up doing it in Razor Views
#model OfficeGx.Cms.Model.ClassName
<div class="form-group row">
<div class="col-lg-11">
#Html.HiddenFor(x => x.CascadingStylesHdn, new { #id = "hidden_cssEditor" })
#Html.LabelFor(x=>x.CascadingStyles)
<div id="cssEditor">#Model.CascadingStyles</div>
</div>
</div>
<div class="form-group row">
<div class="col-lg-11">
#Html.HiddenFor(x => x.JavaScriptHdn, new { #id = "hidden_jsEditor" })
#Html.LabelFor(x => x.JavaScript)
<div id="jsEditor">#Model.JavaScript</div>
</div>
</div>
<script>
var cssEditor;
var jsEditor;
window.onload = function() {
cssEditor = ace.edit("cssEditor");
cssEditor.getSession().setMode("ace/mode/css");
cssEditor.setTheme("ace/theme/twilight");
jsEditor = ace.edit("jsEditor");
jsEditor.getSession().setMode("ace/mode/javascript");
jsEditor.setTheme("ace/theme/xcode");
};
$("form").submit(function () {
$("#hidden_cssEditor").val(window.cssEditor.getSession().getValue());
$("#hidden_jsEditor").val(window.jsEditor.getSession().getValue());
});
</script>
<style>
#cssEditor, #jsEditor {
position: relative;
height: 400px
}
#Model.CascadingStyles
</style>
In my Controller Add/Edit Method
[HttpPost]
[ValidateInput(false)]
public ActionResult AddEdit(Article article, FormCollection formCollection)
{
article.CompanyId = OperatingUser.CompanyId;
article.CascadingStyles = article.CascadingStylesHdn;
article.JavaScript = article.JavaScriptHdn;

Categories

Resources