I am trying to call a view as modal dialog using RenderAction method. I have to pass some data from the view to the modal dialog's View. How can I achive this?
Below is my code (trimmed as per required) so far.
<table class="table">
<tr>
<th>Project No</th>
<th>Drawing No</th>
<th>Revision</th>
<th>Fabrication</th>
</tr>
#foreach (var irn in Model)
{
<tr>
<td class="projno">#irn.PROJECTNO</td>
<td class="drawingno">#irn.DRAWINGNO</td>
<td class="revno">#irn.REVNO</td>
<td>
<button class="button" type="button" class="btn btn-sm" data-toggle="modal">Add</button>
</td>
</tr>
}
Here is the modal dialog using RenderAction to call another view
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<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="myModalLabel">Enter Fabrication Information</h4>
</div>
<div class="modal-body">
<div>
#{Html.RenderAction("Create", "Fabrication");}
</div>
</div>
</div>
</div>
Here are two ways I have tried to invoke the modal dialog
<script type="text/jscript">
$(document).ready(function ()
{
$('button').click(function ()
{
var $row = $(this).closest("tr") // Finds the closest row <tr>
var $projectNo = $row.find(".projno") // Gets a descendent with class="nr"
.text(); // Retrieves the text within <td>
var link = '#Url.Action("Create", "Fabrication")'
// Method 1 -
$('#myModal').modal('show');
//Method 2
$.ajax({
type: "GET",
url: link,
error: function (data)
{ },
success: function (data)
{
$("#myModal.modal-body").html(data);
$('#myModal').modal('show');
},
// in method 2, when I close the dialog, the screen becomes tinted and freezes while it works ok in method 1. why is that?
});
});
});
Here is the Fabrication/Create Conroller method
public ActionResult Create(string projectNo, string drawingNo, string revisionNo)
{
ViewBag.ProjectNo = projectNo;
ViewBag.DrawingNo = drawingNo;
ViewBag.RevisionNo = revisionNo;
return PartialView("Create");
}
When user click Add button, modal dialog should appear carrying ProjectNo information from parent View.
You need to pass the data when invoking controller action.
via JavaScript
When you're sending AJAX request via jQuery, you can use data option property, like in the example below.
If you're sending GET requst, jQuery will automagically append this object to the URL, like so: /Fabrication/Create?projectNo=123&drawingNo=456&revisionNo=789.
Hovewer, if you're sending POST request, URL will not be changed and the data object will be passed inside a request body.
$.ajax({
type: "GET",
url: link,
data: {
projectNo: 123,
drawingNo: 456,
revisionNo: 789
}
error: function (data)
{ },
success: function (data)
{
$("#myModal .modal-body").html(data); // Note that you missed a space between selectors
$('#myModal').modal('show');
},
// in method 2, when I close the dialog, the screen becomes tinted and freezes while it works ok in method 1. why is that?
});
via Razor
You can also use one of the parameter of Html.RenderAction or Url.Action to pass any additional data using anonymous object. This object is always the last function argument, no matter how many arguments you pass before (controller and area names are optional). Note that it's more of a fun fact, because you can't access JavaScript variables directly when using Server-Side methods. It'd be good when rendering default state of your form.
#* Pass custom parameters to controller's action and render it *#
#Html.RenderAction("Create", "Fabrication", new {
projectNo = 123,
drawingNo = 456,
revisionNo = 789
})
#* Create an URL to a controller's action with custom parameters *#
#Url.Action("Create", "Fabrication", new {
projectNo = 123,
drawingNo = 456,
revisionNo = 789
})
Related
I am very new to js and html - trying to make a basic front end for a C# web api.
I'm making a simple app for tracking bugs. I have a panel for the list of bugs, where I can click "Details" to see more info on each bug (I would post an image, but my reputation is too low). Then a new panel opens with with the details of the bug, including a button to close the bug, ie change set the status to "closed". It's with this button that I have the problem.
I have this in my Index.cshtml:
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Bugs</h2>
</div>
<div class="panel-body">
<ul class="list-unstyled" data-bind="foreach: bugs">
<li>
<strong><span data-bind="text: Title"></span></strong>: <span data-bind="text: Description"></span>
<small>Details</small>
</li>
</ul>
</div>
</div>
<div class="alert alert-danger" data-bind="visible: error"><p data-bind="text: error">
</p></div>
<!-- ko if:detail() -->
#* Bug Detail with Close Button *#
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Detail</h2>
</div>
<table class="table">
<tr><td>Title</td><td data-bind="text: detail().Title"></td></tr>
<tr><td>Description</td><td data-bind="text: detail().Description"></td></tr>
<tr><td>Status</td><td data-bind="text: detail().Status"></td></tr>
<tr><td>Created</td><td data-bind="text: detail().Created"></td></tr>
<tr><td>Owner</td><td data-bind="text: detail().Owner"></td></tr>
</table>
<div class="panel-body">
<form class="form-horizontal" data-bind="submit: closeBug(detail())">
<button type="submit" class="btn btn-default">Close bug</button>
</form>
</div>
</div>
</div>
<!-- /ko -->
Then this is the relevant stuff in app.js:
var ViewModel = function () {
var self = this;
self.bugs = ko.observableArray();
self.error = ko.observable();
self.detail = ko.observable();
self.getBugDetail = function (item) {
ajaxHelper(bugsUri + item.Id, 'GET').done(function (data) {
self.detail(data);
});
}
var bugsUri = '/api/bugs/';
function ajaxHelper(uri, method, data) {
self.error(''); // Clear error message
return $.ajax({
type: method,
url: uri,
dataType: 'json',
contentType: 'application/json',
data: data ? JSON.stringify(data) : null
}).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
// get open bugs
function getAllBugs() {
ajaxHelper(bugsUri, 'GET').done(function (data) {
self.bugs(data);
});
}
// Fetch the initial data.
getAllBugs();
//close bug
self.closeBug = function (localDetail) {
var closedBug = {
OwnerId: self.localDetail.OwnerId,
Description: self.localDetail.Description,
Status: "closed",
Title: self.localDetail.Title,
Created: self.localDetail.Created
};
ajaxHelper(bugsUri + self.localDetail.Id, 'DELETE', self.localDetail.Id);
ajaxHelper(bugsUri, 'POST', closedBug).done(function (item) {
self.bugs.push(item);
});
}
};
To update the status of a bug, I want to take the Id of the bug currently open in the detail panel and create an identical bug except with Status set to "closed". The trouble is that there's always a problem access self.localDetail in the new variable closedBug. I've tried it here by parameterizing the closeBug method, but I've also tried accessing self.Detail, but it's done no good, so I'm here. My next step, if this fails, is to create a separate panel entirely with a form for bugId which closes the bug when you submit, but it would be better to be in the bug details window.
you're already passing localDetail as the param in the closeBug fn, so you don't need to refer to it by adding self. Try this (removed all references to self.):
//close bug
self.closeBug = function (localDetail) {
var closedBug = {
OwnerId: localDetail.OwnerId,
Description: localDetail.Description,
Status: "closed",
Title: localDetail.Title,
Created: localDetail.Created
};
ajaxHelper(bugsUri + localDetail.Id, 'DELETE', localDetail.Id);
ajaxHelper(bugsUri, 'POST', closedBug).done(function (item) {
self.bugs.push(item);
});
}
Your first issue is in your submit binding itself. It's being called as soon as it's rendered, not on submit. You want to pass the function object (optionally with bound arguments) instead of calling it in your html.
Explicit Bound Arguments
<form class="form-horizontal" data-bind="submit: closeBug.bind(null, detail)">
<button type="submit" class="btn btn-default">Close bug</button>
</form>
which will bind null as the this value of the function and pass the detail observable as the first argument. With this, your closeBug looks like
self.closeBug = function (localDetail) {
var closedBug = {
OwnerId: localDetail().OwnerId
}
}
Note, you want to unwrap it in the handler, not the html so you get the latest value and not the initial value.
Binding Context as this
Alternatively (and in more idiomatic knockout fashion) you can bind to the function object and it will be called with the binding context as this (the same as explicitly using closeBug.bind($data)).
<form class="form-horizontal" data-bind="submit: closeBug">
<button type="submit" class="btn btn-default">Close bug</button>
</form>
self.closeBug = function () {
var closedBug = {
OwnerId: this.localDetail().OwnerId
}
}
Aside: this may be helpful for better understanding this, self, and function.bind
I've got a modal pop up on a page:
...
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="companySearchModal" aria-hidden="true" id="companySearchModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div id="companySearchModalContent"></div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
...
That I pop up:
...
$('#companySearchModalContent').html(data);
$('#companySearchModal').modal(options);
$('#companySearchModal').modal('show');
...
On that modal dialog I display a list of companies with this PagedListPager on the bottom setup like this:
<div>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
<div id="companySearchPager">
#Html.PagedListPager(
Model,
page => Url.Action("CompanySearch",
"Admin",
new
{
sortOrder = ViewBag.CurrentSort,
currentFilter = ViewBag.CurrentFilter,
page = page
}),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "companySearchModalContent"
}
)
)
</div>
</div>
When I click on a given page element rendered by the PagedListPager control it does call the the Action "CompanySearch" from the Controller "Admin" as specified in the Url.Action but it renders the PartialView that is returned all by itself on the whole page instead of injecting the partial view into the "#companySearchModalContent" Div I've set as the UpdateTargetId in the AjaxOptions of the PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing call.
I figured the PagedListPager would do this. I added some jQuery code to call the appropriate ajax injection "$('#companySearchModalContent').html(data);" but I don't have a way to get the page number, search and sort parameters to come along with that the user clicked on from the pager control and don't know how to set the url and data appropriately in the .ajax code block.
$('#companySearchPager').click(function (e) {
e.preventDefault();
$.ajax({
type: 'GET',
// How to get the page value the user clicked on?
// data: {"page": #},
// How to get the url? This would work if I could get the page #.
// url: '#Url.Action("CompanySearch", "Admin")',
success: function (data) {
debugger;
$('#companySearchModalContent').html(data);
},
error: function () {
showAlert("Employer content load failed.", "warning", 5000);
}
});
return false;
});
I would expect the PageListPager to make that "$('#companySearchModalContent').html(data);" call for me given that I've set the UpdateTargetId in the AjaxOptions of the PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing call.
Thanks for any help...
Fixed the newel post!
Added
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
at the top of the page.
I am new in Prestashop (1.6.1.16).
I work in default prestashop theme (default-bootstrap).
What I did:
I put content in /themes/default-bootstrap/product.tpl:
right after top comments (those about LICENSE and others):
<script type="text/javascript" src="modules/ask_bid/js/ask.js">
</script>
<button onclick="take_asks({$product->id})">See asks</button>
<input type="hidden" id="product-id" value="{$product->id}" />
<input type="hidden" id="customer-id" value="{$id_customer}" />
<!-- Modal -->
<div id="modal" class="modal fade">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-
dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"
data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Where {$product->id} comes from
/controllers/front/ProductController.php<br>
and {$id_customer} comes from
/override/controllers/front/ProductController.php
I created /modules/ask_bid/js/ask.js where I put next content:
function isJSON(data) {
var ret = true;
try {
JSON.parse(data);
}catch(e) {
ret = false;
}
return ret;
}
function take_asks (id_product) {
$.ajax({
type: 'POST',
url: baseDir + 'modules/ask_bid/ajax.php',
data: 'method=take_asks&id_product='+id_product,
dataType: 'text',
success: function(json) {
if(isJSON(json)) {
var json = JSON.parse(json);
//alert("json: " + json[0].comment);
}
},
error: function() {
alert("error");
}
});
}
Also the modal doesn't act like one
My modal is displayed (not hidden) and that is not normal.
It is right after button instead being "in the air" (I hope you know what I mean).
And I have js error:
The /modules/ask_bid/js/ask.js is loaded (I see this also in INSPECT->f12/Network), but the take_asks() is not seen.
I get next console error (when I press 'Take asks' button):
Uncaught ReferenceError: take_asks is not defined
at HTMLButtonElement.onclick (index.php?
id_product=6&controller=product&id_lang=1:413)
What I tried
-I deleted class_index.php
-I deleted cache (with CTRL-f5)
-I tried to add js file from /override/controllers/front/ProductController.php
but doesn't work and i also don't get errors:
public function setMedia()
{
$this->addJS('modules/ask_bid/js/ask.js');
parent::setMedia();
}
...or...
function init () {
$this->context->controller->addJS('modules/ask_bid/js/ask.js');
parent::init()
}
What do you think I can do?
You should create a hookheader in your module:
public function hookHeader($params)
{
$this->context->controller->addJS(($this->_path).'js/ask.js');
}
You can add it only on product pages with:
public function hookHeader($params)
{
if (!isset($this->context->controller->php_self) || $this->context->controller->php_self != 'product')
return;
$this->context->controller->addJS(($this->_path).'js/ask.js');
}
and in your module install hook to header with
$this->registerHook('header'))
To add content to the product page without changing the themes tpls (as mentioned in comments) you can use the displayFooterProduct that "Add new blocks under the product description.".
public function hookDisplayFooterProduct($params)
{
return "code you want to insert";
}
Inside this hook you can access the following parameters:
$params = array('product' => Product, 'category' => Category)
Also, remember to hook it on install with $this->registerHook('displayFooterProduct')) and if the module is already installed, reset it or manually hook it.
I built a plugin that's supposed to transform any button into a modal style form, given a url where the form can be fetched.
It works fine with only one element, but when the selector returns multiple elements, all buttons use the last element's data when the get & post methods are called inside the plugin.
I've tried several answered question in SO, but haven't been able to locate and fix the bug. Looks like I'm missing something.
Here's the complete code. You'll see some {% django tags %} and {{ django context variables }} but just ignore them.
Thanks!
A.
EDIT: typo; EDIT2: added html; EDIT3: removed django tags and context vars.
<div class="modal fade" id="modal-1234" data-uuid="1234">
<div class="modal-dialog">
<div class="modal-content">
<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="title-1234">Title</h4>
</div>
<div class="modal-body" id="body-1234">Body</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="cancel-1234">Close</button>
<button type="button" class="btn btn-primary" id="confirm-1234">Save changes</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
(function($){
// define the modalform class
function ModalForm($button){
/*
You can use ModalForm to automate the ajax-form-modal process with TB3.
Usage:
var mf = new ModaForm($('#my-button')); // that's it
*/
self = this;
self.$button = $button;
self.$modal = $('#modal-1234');
// get vars
self.target = self.$button.attr('data-target');
self.uuid = self.$modal.attr('data-uuid');
self.$modal_title = $('#title-' + self.uuid);
self.$modal_body = $('#body-' + self.uuid);
self.$modal_confirm = $('#confirm-' + self.uuid);
self.modal_confirm_original_text = self.$modal_confirm.html()
self.$modal_cancel = $('#cancel-' + self.uuid);
self.$alerts = $('[data-exsutils=push-alerts]').first();
self.$spinner = $('<p class="center"><i class="ace-icon fa fa-spinner fa-spin orange bigger-300"></i></p>');
// bind button click to _get
self.$button.on('click', function(e){
e.preventDefault();
self._get();
});
}
ModalForm.prototype._get = function(){
/*
Issue a get request to fetch form and either render form or push alert when complete.
*/
var self = this;
// show modal, push spinner and change title
self.$modal.modal('show');
self.$modal_body.html(self.$spinner);
self.title = typeof(
self.$button.attr('data-title')) !== 'undefined' ?
self.$button.attr('data-title') : 'Modal form';
self.$modal_title.html(self.title);
// get content
$.ajax({
type: 'GET',
url: self.target,
statusCode: {
403: function(data){
// close modal
// forbidden => close modal & push alert
setTimeout(function(){
self.$modal.modal('hide');
self.$alerts.html(data.responseText);
}, 500);
},
200: function(data){
// success => push form
// note that we will assign self.$form
var $response = $(data);
self.$form = $response.filter('form').first();
self.$modal_body.html($response);
self.$modal_confirm.click(function(e){
e.preventDefault();
self._submit(self.$form);
});
}
},
error: function(data){
console.log(data);
}
});
}
ModalForm.prototype._submit = function(){
/*
Post this.$form data and rerender form or push alert when complete.
*/
var self = this;
// change submit button to loading state
self.$modal_confirm.addClass('disabled').html('Loading...');
// issue pot request
// cleanup
// rebind if rerender or push alerts
$.ajax({
type: 'POST',
url: self.$form.attr('action'),
data: self.$form.serialize(),
statusCode: {
200: function(data){
// this is a form error
// so we must rerender and rebind form
// else we need to rerender and rebind
self.$form.remove();
var $response = $(data);
self.$form = $response.filter('form').first();
self.$modal_body.html($response);
self.$modal_confirm.on('click', function(e){
e.preventDefault();
self._submit(self.$form);
});
},
201: function(data){
// this means object was created
// so we must push an alert and clean up
self.$form.remove();
delete self.$form;
self.$modal.modal('hide');
self.$modal_body.html('');
// we will push alerts only if there is no 201 callback
var callback_201 = self.$button.attr('data-callback-201');
if (typeof(window[callback_201]) !== 'undefined') {
window[callback_201](data);
} else {
self.$alerts.prepend(data);
};
},
403: function(data){
// this means request was forbidden => clean up and push alert
self.$form.remove();
delete self.$form;
self.$modal.modal('hide');
self.$modal_body.html('');
self.$alerts.prepend(data.responseText);
}
},
complete: function(){
// reset button
self.$modal_confirm.removeClass('disabled').html(
self.modal_confirm_original_text);
}
});
}
window.ModalForm = ModalForm;
// define plugin
$.fn.modalForm = function(){
var self = this;
return self.each(function(){
var el = this;
var _ = new window.ModalForm($(el));
$.data(el, 'modalform', _);
});
}
// run plugin
$('[data-exsutils=modal-form]').modalForm();
})(jQuery);
</script>
Edit by #Daniel Arant:
A jsFiddle with a simplified, working version of the plugin code can be found here
Note by me: Please read the selected answer. This jsfiddle + adding var self = this will give you a complete picture of the problem and a good way around it.
The source of your problem is the line self = this in the ModalForm constructor. Since you did not use the keyword var before self, the JavaScripts interpreter thinks that self is a property of the global window object and declares it as such. Therefore, each time the ModalForm constructor is invoked, self takes on a new value, and all of the references to self in the event handlers created by the constructor for previous buttons then point to the new, most recent instance of ModalForm which has been assigned to the global self property.
In order to fix this particular problem, simply add the keyword var before self = this. This makes self a local variable rather than a global one, and the click event callback functions will point to their very own instance of ModalForm instead of the last instance that was assigned to self.
I created a working jsFiddle based on your code, which can be found here
I stripped down the plugin code to eliminate the ajax calls for the sake of simplicity. I also eliminated all of the uuid references. Once you get a reference to the modal as a jQuery object, you can use jQuery's .find() method to obtain references to the various components of the modal.
If you have any questions about my quick and dirty revision of your plugin
I am still very new to MVC, JavaScript, and jQuery so please bear with me.
I have a webgrid that contains different terms and their translations. The list of terms is dependent on the 'VMID' chosen from the drop down list above the grid. (Or at least it would be, if it were working correctly.)
The left-most column has an edit link for each term that leads to a Boostrap modal, which is populated with all the values assigned to the ID chosen in that drop down list. I need the terms in the grid to also depend on the value chosen from that list.
The approach I am currently trying goes like this (only pasting the bits relevant to the question) -
Main view (strongly typed with model reference, not included):
<div class="container-fluid">
<div style=" margin-bottom: 1.4%;">
<table>
<tr>
<td style="font-size: medium; margin-bottom: 5px">
#Model.lblVMID:
</td>
<td>
#Html.DropDownListFor(model => model.VMID, new System.Web.Mvc.SelectList(Model.locations, "Key", "Value"), new { #class = "form-control", id = "ddlVMID", onchange = "RepopGrid()" })
</td>
</tr>
</table>
</div>
<div class="table-scrollable well" id="termGrid">
#{Html.RenderPartial("_TermGrid", Model);}
</div>
</div>
<script type="text/javascript">
function RepopGrid() {
VMID = $("#ddlVMID").val();
ShowLoadingDialog();
$.ajax({
url: URLPrefix() + "/Terminology/RepopGrid/" + VMID,
type: "POST",
success: function () {
HideLoadingDialog();
},
error: function (jqXHR, textStatus, errorThrown) {
HideLoadingDialog();
ShowAlert(false, 'Failed to change location\r\n' + errorThrown);
}
})
}
</script>
Partial view (strongly typed with model reference, not included. Same model that the main view uses):
#Model.grid.GetHtml(columns: Model.columns, alternatingRowStyle: "info", nextText: "Next",
previousText: "Previous", tableStyle: "table")
Controller:
public ActionResult Index()
{
TerminologyModel model = new TerminologyModel(clsUtils.PreferredVMID());
return View(model);
}
[HttpPost]
public ActionResult RepopGrid(int VMID)
{
TerminologyModel model = new TerminologyModel(VMID);
return PartialView("_TermGrid", model);
}
The model accepts an 'int VMID' and uses that to retrieve the list of terms from the database, then a foreach runs through each term and assigns them to the grid. This works fine, so I didn't feel a need to post it here (it's a bit long, because there are some special columns that need extra work to get set up).
We have a route configuration file that maps URLS to their corresponding actions in the controllers, in this case:
routes.MapRoute(
name: "TerminologyRepopGrid",
url: "Terminology/{action}/{VMID}",
defaults: new { controller = "Terminology", action = "RepopGrid", VMID = UrlParameter.Optional }
);
I'm not familiar with Ajax, so I'm probably using it completely wrong.
This approach is based on a few places where I've read to put the grid in a partial view, so that's what I've done here.
After I choose a new option, I can see that a whole new grid is being returned in Chrome's element inspector, but that grid is not being applied on top of the existing one.
Again, I have been searching and trying and reading and experimenting and I just can't figure out why mine won't work.
I moved the drop down list to the partial view where the grid is, wrapped everything in an Ajax Form, removed the "RepopGrid" JavaScript and controller actions, and added a parameter to the Index action for a VMID. If the VMID is null or empty (when the page is first loaded or refreshed), it uses the default VMID to generate the model. If a valid VMID is received, then it uses that number to generate the model instead.
Here is the new code for those who might be looking for a similar solution (like last time, only the relevant parts):
Index.cshtml -
<div class="table-scrollable well" id="termGrid">
#Html.Partial("_TermGrid", Model)
</div>
<div class="modal fade" id="editTerm" tabindex="-1" role="dialog" aria-labelledby="editTerm-label" aria-hidden="true">
<div class="modal-dialog" style="width: 290px">
<div class="modal-content" style="width: 290px">
<div class="modal-header" style="border-bottom: none; padding-bottom: 0px;">
<h4 id="lblParamName" align="center"></h4>
</div>
<div class="modal-body" id="editTermBody" style="padding: 8px">
</div>
</div>
</div>
</div>
Partial View -
#{
var ajaxOptions = new AjaxOptions()
{
OnSuccess = "OnSuccess",
OnFailure = "OnFailure",
OnBegin = "OnBegin",
HttpMethod = "Post"
};
using (Ajax.BeginForm("Index", "Terminology", ajaxOptions))
{
<div class="container-fluid" id="termGrid">
<div style=" margin-bottom: 1.4%;">
<table>
<tr>
<td style="font-size: medium; margin-bottom: 5px">
#Model.lblVMID<label>: </label>
</td>
<td>
#Html.DropDownListFor(model => model.VMID, new System.Web.Mvc.SelectList(Model.locations, "Key", "Value"), new { #class = "form-control", id = "ddlVMID", onchange = "this.form.submit()" })
</td>
</tr>
</table>
</div>
</div>
}
}
#Model.grid.GetHtml(columns: Model.columns, alternatingRowStyle: "info", nextText: "Next",
previousText: "Previous", tableStyle: "table")
<script type="text/javascript">
function OnSuccess(data, textStatus, jqXHR) {
HideLoadingDialog();
}
function OnFailure(data, textStatus, jqXHR) {
HideLoadingDialog();
ShowAlert(false, "Oops! Something went wrong. :(");
}
function OnBegin() {
ShowLoadingDialog();
VMID = $("#ddlVMID").val()
ShowLoadingDialog();
$.ajax({
url: URLPrefix() + "/Terminology/Index/" + VMID,
type: "POST",
success: function () {
HideLoadingDialog();
},
error: function (jqXHR, textStatus, errorThrown) {
HideLoadingDialog();
ShowAlert(false, 'Failed to change location\r\n' + errorThrown);
}
})
}
</script>
Controller -
public ActionResult Index(string VMID)
{
if (string.IsNullOrEmpty(VMID))
{
TerminologyModel model = new TerminologyModel(clsUtils.PreferredVMID());
return View(model);
}
else
{
TerminologyModel model = new TerminologyModel(int.Parse(VMID));
return View(model);
}
}
The model's code has not changed since the question was originally asked.