Input field not updated in ajax function - c#

I'll try to explain the issue I'm facing the best way
I've got a view, and inside it a partial view which basically displays an input field and a button. This partial view would look like this
<fieldset>
#Html.HiddenFor(model => model.AuctionId)
#Html.HiddenFor(model => model.AuctionEventId)
<div class="lotdetail-maxbid-row">
#Html.TextBoxFor(model => model.Amount, new { #class = "radius2 text-box single-line valid" })
#Html.ValidationMessageFor(model => model.Amount)
</div>
<input type="submit" id="autobidButton" value="Increase Max bid" class="btn btn-level2 btn-maxbid #disableButton" />
</fieldset>
And inside this partial view, I've put this script
<script type="text/javascript">
$(document).ready(function () {
$('#autobidButton').click(function () {
$.ajax({
url: "/Lot/AutobidConfirmationPartial",
data: {
amount: $("#Amount").val(),
auctionEventId: $("#AuctionEventId").val(),
auctionId: $("#AuctionId").val()
},
success: function (result) {
$("#autobidConfirmation").empty().append(result);
},
type: "POST"
});
return false;
});
});
</script>
With the intention of load the result, which is a partial view in a div in the parent page.
The problem is that amount is always 0 (default value), and never gets updated when calling the function inside the script.
Any idea of what to do or look?
Thanks,
Update: This is the generated html and controller method
<fieldset>
<input id="AuctionId" type="hidden" value="3" name="AuctionId">
<input id="AuctionEventId" type="hidden" value="1" name="AuctionEventId">
<div class="lotdetail-maxbid-row">
<input id="Amount" class="radius2 text-box single-line valid" type="text" value="0" name="Amount">
</div>
<input id="autobidButton" class="btn btn-level2 btn-maxbid " type="submit" value="Increase Max bid">
</fieldset>
public ActionResult AutobidConfirmationPartial(int auctionEventId, int auctionId, decimal amount)
{
var incorrectAmount = false;
var correctedAmount = amount;
if (!CheckMaxBidFitsIncrementTier(amount, auctionEventId))
{
incorrectAmount = true;
correctedAmount = CalculateNextBidAmountForWrongMaxAmount(amount, auctionEventId); ;
}
var model = new BidOnAuctionViewModel
{
AuctionEventId = auctionEventId,
AuctionId = auctionId,
Amount = correctedAmount,
IncorrectAmount = incorrectAmount,
};
//TotalPriceBreakdown(ref model, null);
return PartialView("BidConfirmationPartial", model);
}

Related

How do you change view by changing dropdownlist?

I have a dropdown list in a View. And if I change the selection, I want to change immediately the values in the View. The textbox of Type and Description.
How do you do that?
#Model GenreModel
#using (Html.BeginForm("EditGenre", "Home", FormMethod.Post))
{
#model GenreModel
<div class="text-center">
<h1 class="display-4">Edit genre</h1>
<p> <input type="submit" value="submit" name="Save" /></p>
<p>
<label>Select genre: </label>
#Html.DropDownListFor(Model => Model.Description, new SelectList(ViewBag.GenreList, "Description", "Description"), new { onchange = "onChangeSelection(this.value);" });
</p>
<p>
<label>Type</label>#Html.TextBoxFor(Model => Model.Type)
</p>
<p>
<label>Description</label>#Html.TextBoxFor(Model => Model.Description)
</p>
</div>
}
This is the method in the Controller.
[HttpPost]
public IActionResult EditGenre(string description)
{
var dto = _genreService.GetGenreByName(description);
var model = _mapper.Map<GenreDto, GenreModel>(dto);
ViewBag.GenreList = _genreService.GetAllGenres().OrderBy(g => g.Description);
return View(model);
}
and finally:
<script>
function onChangeSelection(val) {
{
$.ajax({
url: #Url.Action("EditGenre", "Home"),
//type: "POST",
data: { description: val },
success: function (data) {
// put result of action into element with class "result"
$('.result').html(data);
},
error: function () {
alert(val + ' not found.');
}});
}
</script>
Change the DropDownList like this:
#Html.DropDownListFor(Model => Model.Description, new SelectList(ViewBag.GenreList, "Description", "Description"));
And submit the form in the onchange function:
<script>
$("#Description").on("change", function () {
$(this).closest("form").submit();
})
</script>
It seems my DropDownList didn't fire a Submit. I leave the javascript and using a hidden field.
And this solution works fine.
<p>
<label>Select genre: </label>
#Html.Hidden("#Discription")
#Html.DropDownListFor(Model => Model.Description, new SelectList(ViewBag.GenreList, "Description", "Description"), new { onchange = "this.form.submit();" });
</p>

HTM BeginCollectionItem returns only first item of collection

I have the following problem:
A collection of "Gifts" gets passed as a parameter to a view.
Each item inside this collection is a object from the Model class "Gift".
There are only two properties inside this class: name and price.
I put the class inside the controller for the sake of simplicity.
This is the action method:
// GET: Order/CreateGift
[HttpGet]
public ActionResult CreateGift()
{
var initialData = new[]
{
new Gift{ Name = "Tricycle", Price = 69.95 },
new Gift{ Name = "PS4 game", Price = 29.99 },
new Gift{ Name = "Lazergun", Price = 49.99}
};
return View(initialData);
}
On the view I can dynamically add new items to the collection, thanks to the BeginCollectionItem Html helper.
This is my View:
#model IEnumerable<DemoWebShop.Controllers.Gift>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#addItem").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#editorRows").append(html); }
});
return false;
});
}); // end document.ready function
</script>
<h2>Gift List</h2>
What do you want for your birthday?
#using (Html.BeginForm())
{
<div class="form-horizontal">
<div id="editorRows">
#foreach (var item in Model)
{
Html.RenderPartial("GiftEditorRow", item);
}
</div>
#Html.ActionLink("Add another...", "BlankEditorRow", null, new { id = "addItem" })
<input type="submit" value="Finished" />
#*<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Aanmaken" class="btn btn-default" />
</div>
</div>*#
</div>
}
This is the partial view called "GiftEditorRow" :
#using HtmlHelpers.BeginCollectionItem
#model DemoWebShop.Controllers.Gift
#{
Layout = null;
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="editorRow">
#using (Html.BeginCollectionItem("gifts"))
{
<label>Name: </label>
#Html.TextBoxFor(x => x.Name);
<label>Price: </label>
#Html.TextBoxFor(x => x.Price, new { size = 4 });
<br />
}
</div>
}
Inside my controller I also have this actionmethod:
public ViewResult BlankEditorRow()
{
return View("GiftEditorRow", new Gift());
}
Only the First item that already existed inside the collection, gets passed to the HTTP Post method in my controller.
I found my mistake.
The partial view "GiftEditorRow" still contains the following:
#using (Html.BeginForm()){.....}
If you remove this, it should work.
This is my partial view now:
#using (Html.BeginCollectionItem("gifts"))
{
<label>Name: </label>
#Html.TextBoxFor(Model => Model.Name);
<label>Price: </label>
#Html.TextBoxFor(Model => Model.Price, new { size = 4 });
<br />
}
Now I get all items instead of just the first one.

Passing and handling of varibles to a function with AJAX in MVC

I'm having trouble passing a variable into a function in my view. I'm fairly new to MVC and not sure how I save and pass information.
#model Models.Schedule.SheduleModel
#{
Layout = null;
}
<div>
<div class="tableRow">
<p>Make a schedule reminder.</p>
</div>
<div class="tableRow tableRowHeading">
<div class="row" style="width: 210px">Name</div>
<div class="row" style="width: 210px">Number</div>
</div>
#foreach (var shedule in Model.ScheduleList)
{
<div class="tableRow">
#using (Html.BeginForm("UpdateSchedule", "Schedule", FormMethod.Post))
{
<div class="cell" style="width: 210px">
#Html.HiddenFor(model => schedule.Id)
#Html.TextBoxFor(model => schedule.Name, new { #class = "inputFieldText" })
#Html.ValidationMessageFor(model => schedule.Name)
</div>
<div class="cell" style="width: 210px">
#Html.TextBoxFor(model => agent.ContactNumber, new { #class = "inputFieldText" })
#Html.ValidationMessageFor(model => agent.ContactNumber)
</div>
<div class="cell">
<button name="Update" type="submit" value="Update" class="button" title="Update details">
<span class="text">Update</span>
</button>
</div>
<div class="cell">
<button class="button" type="button" onclick="deleteFromSchedule();" value="Delete">
<span class="text">Delete</span>
</button>
</div>
}
</div>
}
</div>
#Scripts.Render("~/bundles/jqueryval")
<script>
function deleteFromSchedule() {
$.ajax(
{
type: 'POST',
url: urlBase + 'Schedule/UpdateSchedule/' + Id,
data:
{
Id: Id
},
success: function (data) {
console.log(data);
},
error: function () {
var errorMessage = 'Error occurred while sending message';
console.log(errorMessage);
}
});
}
}
</script>
I'm trying to pass the schedule Id in HiddenFor into the delete function but everything I try doesn't work, i'm also curious on how to handle the information gotten from the text box in a later unwritten div, I'd like to produce text on the screen saying
User #Model.Name and number #Model.Number will be notified of schedule change but I keep displaying blank spaces. an I use the form I'm creating for this information, what would the syntax be?. My method in the schedule controller is very straight forward.
[HttpPost]
public void UpdateSchedule(int Id)
{
////do stuff here
}
The simplest way is to add your id from the schedule into the inline function call (using razor), and add an id param into your javascript delete function:
<div class="cell">
<button class="button" type="button" onclick="deleteFromSchedule(#schedule.Id);" value="Delete">
<span class="text">Delete</span>
</button>
</div>
<script>
function deleteFromSchedule(id) {
$.ajax(
{
type: 'POST',
url: urlBase + 'Schedule/UpdateSchedule/' + id,
data:
{
Id: id
},
success: function (data) {
console.log(data);
},
error: function () {
var errorMessage = 'Error occurred while sending message';
console.log(errorMessage);
}
});
}
}
</script>

MVC 4 Edit modal form using Bootstrap

I'm using MVC 4 and Entity Framework to develop an intranet web application. I have a list of persons which can be modify by an edit action. I wanted to make my app more dynamic by using modal forms. So I tried to put my edit view into my Bootstrap modal and I have 2 questions about it :
Should I use a simple or a partial view?
How can I perform the validation (actually it work but it redirects me to my original view so not in the modal form)
I think I have to use AJAX and/or jQuery but I'm new to these technologies. Any help would be appreciated.
EDIT : My Index View :
#model IEnumerable<BuSIMaterial.Models.Person>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<br />
<div class="group">
<input type="button" value="New person" class="btn" onclick="location.href='#Url.Action("Create")';return false;"/>
<input type="button" value="Download report" class="btn" onclick="location.href='#Url.Action("PersonReport")';return false;"/>
</div>
#using (Html.BeginForm("SelectedPersonDetails", "Person"))
{
<form class="form-search">
<input type="text" id="tbPerson" name="tbPerson" placeholder="Find an employee..." class="input-medium search-query">
<button type="submit" class="btn">Search</button>
</form>
}
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Start Date</th>
<th>End Date</th>
<th>Details</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
#foreach (BuSIMaterial.Models.Person item in ViewBag.PageOfPersons)
{
<tr>
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.StartDate.ToShortDateString()</td>
<td>
#if (item.EndDate.HasValue)
{
#item.EndDate.Value.ToShortDateString()
}
</td>
<td>
<a class="details_link" data-target-id="#item.Id_Person">Details</a>
</td>
<td>
<div>
<button class="btn btn-primary edit-person" data-id="#item.Id_Person">Edit</button>
</div>
</td>
</tr>
<tr>
<td colspan="6">
<table>
<tr>
<th>National Number</th>
<td>#item.NumNat</td>
</tr>
<tr>
<th>Vehicle Category</th>
<td>#item.ProductPackageCategory.Name</td>
</tr>
<tr>
<th>Upgrade</th><td>#item.Upgrade</td>
</tr>
<tr>
<th>House to work</th>
<td>#item.HouseToWorkKilometers.ToString("G29")</td>
</tr>
</table>
<div id="details_#item.Id_Person"></div>
</td>
</tr>
}
</tbody>
</table>
<div class="modal hide fade in" id="edit-member">
<div id="edit-person-container"></div>
</div>
#section Scripts
{
#Scripts.Render("~/bundles/jqueryui")
#Styles.Render("~/Content/themes/base/css")
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$('#tbPerson').autocomplete({
source: '#Url.Action("AutoComplete")'
});
$(".details_link").click(function () {
var id = $(this).data("target-id");
var url = '/ProductAllocation/ListByOwner/' + id;
$("#details_"+ id).load(url);
});
$('.edit-person').click(function () {
var url = "/Person/EditPerson";
var id = $(this).attr('data-id');
$.get(url + '/' + id, function (data) {
$('#edit-person-container').html(data);
$('.edit-person').modal('show');
});
});
});
</script>
}
My Partial View :
#model BuSIMaterial.Models.Person
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Edit</h3>
</div>
<div>
#using (Ajax.BeginForm("EditPerson", "Person", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "list-of-people"
}))
{
#Html.ValidationSummary()
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="editor-field">
#Html.TextBoxFor(model => model.FirstName, new { maxlength = 50 })
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.LastName, new { maxlength = 50 })
#Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<div class="modal-footer">
<button class="btn btn-inverse" type="submit">Save</button>
</div>
}
You should use partial views. I use the following approach:
Use a view model so you're not passing your domain models to your views:
public class EditPersonViewModel
{
public int Id { get; set; } // this is only used to retrieve record from Db
public string Name { get; set; }
public string Age { get; set; }
}
In your PersonController:
[HttpGet] // this action result returns the partial containing the modal
public ActionResult EditPerson(int id)
{
var viewModel = new EditPersonViewModel();
viewModel.Id = id;
return PartialView("_EditPersonPartial", viewModel);
}
[HttpPost] // this action takes the viewModel from the modal
public ActionResult EditPerson(EditPersonViewModel viewModel)
{
if (ModelState.IsValid)
{
var toUpdate = personRepo.Find(viewModel.Id);
toUpdate.Name = viewModel.Name;
toUpdate.Age = viewModel.Age;
personRepo.InsertOrUpdate(toUpdate);
personRepo.Save();
return View("Index");
}
}
Next create a partial view called _EditPersonPartial. This contains the modal header, body and footer. It also contains the Ajax form. It's strongly typed and takes in our view model.
#model Namespace.ViewModels.EditPersonViewModel
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Edit group member</h3>
</div>
<div>
#using (Ajax.BeginForm("EditPerson", "Person", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "list-of-people"
}))
{
#Html.ValidationSummary()
#Html.AntiForgeryToken()
<div class="modal-body">
#Html.Bootstrap().ControlGroup().TextBoxFor(x => x.Name)
#Html.Bootstrap().ControlGroup().TextBoxFor(x => x.Age)
</div>
<div class="modal-footer">
<button class="btn btn-inverse" type="submit">Save</button>
</div>
}
Now somewhere in your application, say another partial _peoplePartial.cshtml etc:
<div>
#foreach(var person in Model.People)
{
<button class="btn btn-primary edit-person" data-id="#person.PersonId">Edit</button>
}
</div>
// this is the modal definition
<div class="modal hide fade in" id="edit-person">
<div id="edit-person-container"></div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('.edit-person').click(function () {
var url = "/Person/EditPerson"; // the url to the controller
var id = $(this).attr('data-id'); // the id that's given to each button in the list
$.get(url + '/' + id, function (data) {
$('#edit-person-container').html(data);
$('#edit-person').modal('show');
});
});
});
</script>
I prefer to avoid using Ajax.BeginForm helper and do an Ajax call with JQuery. In my experience it is easier to maintain code written like this. So below are the details:
Models
public class ManagePeopleModel
{
public List<PersonModel> People { get; set; }
... any other properties
}
public class PersonModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
... any other properties
}
Parent View
This view contains the following things:
records of people to iterate through
an empty div that will be populated with a modal when a Person needs to be edited
some JavaScript handling all ajax calls
#model ManagePeopleModel
<h1>Manage People</h1>
#using(var table = Html.Bootstrap().Begin(new Table()))
{
foreach(var person in Model.People)
{
<tr>
<td>#person.Id</td>
<td>#Person.Name</td>
<td>#person.Age</td>
<td>#html.Bootstrap().Button().Text("Edit Person").Data(new { #id = person.Id }).Class("btn-trigger-modal")</td>
</tr>
}
}
#using (var m = Html.Bootstrap().Begin(new Modal().Id("modal-person")))
{
}
#section Scripts
{
<script type="text/javascript">
// Handle "Edit Person" button click.
// This will make an ajax call, get information for person,
// put it all in the modal and display it
$(document).on('click', '.btn-trigger-modal', function(){
var personId = $(this).data('id');
$.ajax({
url: '/[WhateverControllerName]/GetPersonInfo',
type: 'GET',
data: { id: personId },
success: function(data){
var m = $('#modal-person');
m.find('.modal-content').html(data);
m.modal('show');
}
});
});
// Handle submitting of new information for Person.
// This will attempt to save new info
// If save was successful, it will close the Modal and reload page to see updated info
// Otherwise it will only reload contents of the Modal
$(document).on('click', '#btn-person-submit', function() {
var self = $(this);
$.ajax({
url: '/[WhateverControllerName]/UpdatePersonInfo',
type: 'POST',
data: self.closest('form').serialize(),
success: function(data) {
if(data.success == true) {
$('#modal-person').modal('hide');
location.reload(false)
} else {
$('#modal-person').html(data);
}
}
});
});
</script>
}
Partial View
This view contains a modal that will be populated with information about person.
#model PersonModel
#{
// get modal helper
var modal = Html.Bootstrap().Misc().GetBuilderFor(new Modal());
}
#modal.Header("Edit Person")
#using (var f = Html.Bootstrap.Begin(new Form()))
{
using (modal.BeginBody())
{
#Html.HiddenFor(x => x.Id)
#f.ControlGroup().TextBoxFor(x => x.Name)
#f.ControlGroup().TextBoxFor(x => x.Age)
}
using (modal.BeginFooter())
{
// if needed, add here #Html.Bootstrap().ValidationSummary()
#:#Html.Bootstrap().Button().Text("Save").Id("btn-person-submit")
#Html.Bootstrap().Button().Text("Close").Data(new { dismiss = "modal" })
}
}
Controller Actions
public ActionResult GetPersonInfo(int id)
{
var model = db.GetPerson(id); // get your person however you need
return PartialView("[Partial View Name]", model)
}
public ActionResult UpdatePersonInfo(PersonModel model)
{
if(ModelState.IsValid)
{
db.UpdatePerson(model); // update person however you need
return Json(new { success = true });
}
// else
return PartialView("[Partial View Name]", model);
}
In reply to Dimitrys answer but using Ajax.BeginForm the following works at least with MVC >5 (4 not tested).
write a model as shown in the other answers,
In the "parent view" you will probably use a table to show the data.
Model should be an ienumerable. I assume, the model has an id-property. Howeverm below the template, a placeholder for the modal and corresponding javascript
<table>
#foreach (var item in Model)
{
<tr> <td id="editor-success-#item.Id">
#Html.Partial("dataRowView", item)
</td> </tr>
}
</table>
<div class="modal fade" id="editor-container" tabindex="-1"
role="dialog" aria-labelledby="editor-title">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" id="editor-content-container"></div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('.editor-container').click(function () {
var url = "/area/controller/MyEditAction";
var id = $(this).attr('data-id');
$.get(url + '/' + id, function (data) {
$('#editor-content-container').html(data);
$('#editor-container').modal('show');
});
});
});
function success(data,status,xhr) {
$('#editor-container').modal('hide');
$('#editor-content-container').html("");
}
function failure(xhr,status,error) {
$('#editor-content-container').html(xhr.responseText);
$('#editor-container').modal('show');
}
</script>
note the "editor-success-id" in data table rows.
The dataRowView is a partial containing the presentation of an model's item.
#model ModelView
#{
var item = Model;
}
<div class="row">
// some data
<button type="button" class="btn btn-danger editor-container" data-id="#item.Id">Edit</button>
</div>
Write the partial view that is called by clicking on row's button (via JS $('.editor-container').click(function () ... ).
#model Model
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="editor-title">Title</h4>
</div>
#using (Ajax.BeginForm("MyEditAction", "Controller", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "editor-success-" + #Model.Id,
OnSuccess = "success",
OnFailure = "failure",
}))
{
#Html.ValidationSummary()
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.Id)
<div class="modal-body">
<div class="form-horizontal">
// Models input fields
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
}
This is where magic happens: in AjaxOptions, UpdateTargetId will replace the data row after editing, onfailure and onsuccess will control the modal.
This is, the modal will only close when editing was successful and there have been no errors, otherwise the modal will be displayed after the ajax-posting to display error messages, e.g. the validation summary.
But how to get ajaxform to know if there is an error? This is the controller part, just change response.statuscode as below in step 5:
the corresponding controller action method for the partial edit modal
[HttpGet]
public async Task<ActionResult> EditPartData(Guid? id)
{
// Find the data row and return the edit form
Model input = await db.Models.FindAsync(id);
return PartialView("EditModel", input);
}
[HttpPost, ValidateAntiForgeryToken]
public async Task<ActionResult> MyEditAction([Bind(Include =
"Id,Fields,...")] ModelView input)
{
if (TryValidateModel(input))
{
// save changes, return new data row
// status code is something in 200-range
db.Entry(input).State = EntityState.Modified;
await db.SaveChangesAsync();
return PartialView("dataRowView", (ModelView)input);
}
// set the "error status code" that will redisplay the modal
Response.StatusCode = 400;
// and return the edit form, that will be displayed as a
// modal again - including the modelstate errors!
return PartialView("EditModel", (Model)input);
}
This way, if an error occurs while editing Model data in a modal window, the error will be displayed in the modal with validationsummary methods of MVC; but if changes were committed successfully, the modified data table will be displayed and the modal window disappears.
Note: you get ajaxoptions working, you need to tell your bundles configuration to bind jquery.unobtrusive-ajax.js (may be installed by NuGet):
bundles.Add(new ScriptBundle("~/bundles/jqueryajax").Include(
"~/Scripts/jquery.unobtrusive-ajax.js"));
In $('.editor-container').click(function (){}), shouldn't var url = "/area/controller/MyEditAction"; be var url = "/area/controller/EditPartData";?

Render PartialView within View on Demand

the page has 2 DropDownLists + a Textbox + a Submit Button.
On Submit it's supposed to choose and fill a partial view depending on what value is selected in the first DropDownList. I got it somewhat working; however, it will always return the pv in a new window instead of rendering it in the main view's div.
I am using MVC 3 + Telerik.
The most Important parts of the code:
VIEW - Updated
<script type="text/javascript">
function onMainDDL1Change(e) {
var combo = $("#SubDDL1").data("tComboBox");
combo.value("");
combo.reload();
}
function onSubDDL1DataBinding(e) {
var combo = $("#MainDDL1").data("tComboBox");
e.data = $.extend({}, e.data, { mainDDL1ID: combo.value() });
}
</script>
#using (Ajax.BeginForm("PartialGrid", "DataSearch", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "result", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace }))
{
<table>
<tr>
<td>
#(Html.Telerik().ComboBox()
.Name("MainDDL1")
.AutoFill(true)
.DataBinding(binding => binding.Ajax().Select("LoadMainDDL", "DataSearch"))
.HighlightFirstMatch(true)
.ClientEvents(events => events.OnChange("onMainDDL1Change"))
)
</td>
</tr>
<tr>
<td>
#(Html.Telerik().ComboBox()
.Name("SubDDL1")
.DataBinding(binding => binding.Ajax().Select("LoadSubDDL1", "DataSearch"))
.HighlightFirstMatch(true)
.ClientEvents(events => events.OnDataBinding("onSubDDL1DataBinding"))
)
</td>
<tr>
<td>
#Html.TextBoxFor(o => o.sSearch1)
</td>
</tr>
<tr align="center">
<td colspan="4">
<input type="submit" class="t-button" value="Search" name="submit" />
</td>
</tr>
</table>
}
<div id="result">
</div>
Controller - Updated
[HttpPost]
//PartialView
public PartialViewResult PartialGrid(DataSearchModel voModel)
{
voModel.dtResultSet1 = DLA.DataSearchContext.getResultSet1(voModel.MainDDL1, voModel.SubDDL1, voModel.sSearch1);
return PartialView("_TPRCL", voModel);
}
//Initial View
public ViewResult DataSearch(string text)
{
DataSearchModel oModel = new DataSearchModel();
oModel.alMainDDL = DLA.DataSearchContext.getMainDDL();
return View(oModel);
}
PartialView
#model ISC.Utilities.GISTransactionTools.Models.DataSearchModel
#(Html.Telerik().Grid(Model.dtResultSet1)
.Name("Grid")
.Footer(false)
.Columns(columns =>
{
columns.Bound(o => o.Row[0]).Title("T_PRCL");
}))
PartialView Grid has actually more columns, this is just to make it work.
I am not using Telerik, but here is how I am doing something similar:
In the initial view I have the following code:
#using (Ajax.BeginForm("PhoneForm", "Home", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "form-lead", InsertionMode = InsertionMode.Replace, OnSuccess = "HookupValidation" })) {
#Html.ValidationSummary(false, "Please address the following items:")
<div class="phone">
<div class="field">
#Html.LabelFor(model => model.Phone1)
#Html.EditorFor(model => model.Phone1)
#Html.ValidationMessageFor(model => model.Phone1)
</div>
<div class="button">
<input type="submit" value="Get Customer" name="submit" /></div>
</div>
}
<div id="form-lead">
</div>
Basically, when the "Get Customer" button is clicked, it will call, via AJAX, the "PhoneForm" method in my "Home" controller. This method generates the partial view which is then inserted (InsertionMode = InsertionMode.Replace) into the (UpdateTargetId = "form-lead"). The OnSuccess function is just to be sure that client side validation and jQuery events are hooked up on the partial view. If you don't do this, none of the client side validation or script will work for items in the partial view.
The controller code for "PhoneForm" is as follows:
[HttpPost]
public PartialViewResult PhoneForm(string Phone1) {
HomeViewModel viewModel = new HomeViewModel();
// ... get data and set up view model here ... //
// ... also choose which partial view you want to return ... //
return PartialView("LeadInfoPartial", viewModel);
}
Hope this helps you solve your issue.
Alright got it to work in Javascript.
View
<script type="text/javascript"> $('#btnSubmit').click(function () {
var time = new Date().getTime(); // #* unique random number to workaround IE cache issue - IE will cache the ajax if you
don't use this *#
var oMainDDL1 = $('#MainDDL1').data("tComboBox");
var oSubDDL1 = $('#SubDDL1').data("tComboBox");
var sSearch1 = $("#Search1").val();
var actionURL = '#Url.Action("getGrid1", "DataSearch", new { MainDDL1
= "PLACEHOLDER" })'.replace('PLACEHOLDER', oMainDDL1.value()) + "&SubDDL1=" + oSubDDL1.value() + "&Search1=" + sSearch1 + "&time=" +
time;
if (actionURL != null) {
$.get(actionURL, function (data) {
$('#result1').fadeOut('slow', 'linear', function () { $('#result1').empty(); $('#result1').append(data); });
$('#result1').fadeIn('slow', 'linear', function () {
if ($.browser.msie) {
this.style.removeAttribute('filter'); // #* Needed to fix IE7 cleartype bug with jQuery fade, but will crap out
on FF/Chrome *#
}
});
});
}
});
}); </script>
#(Html.Telerik().ComboBox()
.Name("MainDDL1")
.AutoFill(true)
.DataBinding(binding => binding.Ajax().Select("LoadMainDDL", "DataSearch"))
.HighlightFirstMatch(true)
.ClientEvents(events => events.OnChange("onMainDDL1Change"))
)
#(Html.Telerik().ComboBox()
.Name("SubDDL1")
.DataBinding(binding => binding.Ajax().Select("LoadSubDDL1", "DataSearch"))
.HighlightFirstMatch(true)
.ClientEvents(events => events.OnDataBinding("onSubDDL1DataBinding"))
)
#Html.TextBox("Search1")
<input type="button" class="t-button button1" value="Search"
id="btnSubmit" />
<div id="result1"> </div>
Controller
public PartialViewResult getGrid1(string MainDDL1, string SubDDL1, string Search1)
{
DataSearchModel voModel = new DataSearchModel();
voModel.dtResultSet1 = DLA.DataSearchContext.getResultSet1(MainDDL1, SubDDL1, Search1);
return PartialView(MainDDL1, voModel);
}
public ViewResult DataSearch(string text)
{
DataSearchModel oModel = new DataSearchModel();
oModel.alMainDDL = DLA.DataSearchContext.getMainDDL();
return View(oModel);
}

Categories