/**** SOLVED ****/
I had tried create a dynamic modal with result from a partial view using a modal of bootstrap script, but I not get success with it. This is not equals to the questions in 1 and 2.
This is my html PartialView (simple modal pattern)
#model Dictionary<int?, Tuple<string,string>>
<div class="modal fade" id="#ViewBag.IdModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Selecione o item desejado</h4>
</div>
<div class="modal-body">
<table id="tabPesquisa" class="table table-condensed">
<thead>
<tr><th>Código</th><th>Descrição</th></tr>
</thead>
<tbody>
#foreach (KeyValuePair<int?,Tuple<string,string>> item in Model)
{
var valores = item.Value;
<tr data-idreg="#item.Key"><td>#valores.Item1</td> <td>#valores.Item2</td></tr>
}
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Fechar</button>
<button type="button" class="btn btn-primary" id="btnSelecao"><span class="glyphicon glyphicon-check"></span> Pronto!</button>
</div>
</div><!-- /.modal-content -->
It is a generic view and receives various data dynamically. (obvious)
On my main html, I have more buttons to get differents datas for the partial view. Example:
<button class="btn btn-primary" data-toggle="modal" data-target="#modalLayout" data-inputs="#hdnIdLayout,#txtCodLayout,#txtDescLayout" data-urlsearch="#Url.Action("ListaPesquisar", "Exame")"><span class="glyphicon glyphicon-search"></span></button>
On my main javascript file I have the code:
Sistema.AbrirModal = function (urlSearch, target, fields) {
var arrayFields = fields.split(",");
var target = target.slice(1, target.length);
var objModal;
$.get(urlSearch, { idModal: target }, function (data) {
objModal = $.parseHTML(data);
console.log(objModal);
$("body").append(objModal);
$(objModal).modal(); //ERROR: Uncaught TypeError: Object [object Object] has no method 'modal'
});
};
$(document).ready(function () {
if($('[data-toggle="modal"]').length > 0) {
$('[data-toggle="modal"]').on("click", function () {
var target = $(this).data("target"); //#modalLayout"
var fields = $(this).data("fields"); //#htnIdLayout,#txtCodLayout,#txtDescLayout"
var urlSearch = $(this).data("urlsearch")//"#Url.Action("ListaPesquisar", "Exame")"
Sistema.AbrirModal(urlSearch, target, fields);
});
}
}
Well, if I use $(objModal).modal([show, hide, none]); get a error (comented in the line above), if not use it, nothing occurs.
Does anyone have an idea how to solve this issue so I do not need to create several for each modal window on my main page?
Thanks everyone.
Related
I hava a list of objects in my view. In a table, with some conditions I create rows and add a button. I want to pass that row's data to my controller when button of modal-footer is pressed. I tried ajax request and forms but I could not manage that up. What is coming to my controller is always the first element of list.
My view:
<table class="table border-bottom dataTable" id="dataTable" width="100%" cellspacing="0" role="grid" aria-describedby="dataTable_info" style="width: 100%;">
<thead>
<tr><th rowspan="1">Saat</th><th rowspan="1">Durum</th></tr>
</thead>
#{int i = 0; }
#foreach (var v in Model)
{
<tbody>
<tr>
#if (v.IsActive == 1)
{
<td>#v.Hour.ToString():#v.Minute.ToString().ElementAt(0)0</td>
<td><p class="blckpassive">Dolu</p></td>
}
else
{
<td>#v.Hour.ToString():#v.Minute.ToString().ElementAt(0)0</td>
<td><p class="blckactive">Boş</p></td>
<td><button type="button" class="btn btn-info" data-toggle="modal" data-target="#exampleModal">Randevu Al</button></td>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Emin Misiniz?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Seçtiğiniz Randevuyu Almak İstiyor Musunuz?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">İptal</button>
<a type="button" href="/Appointment/AddAppointment?hour=#v.Hour" class="btn btn-primary">Evet</a>
</div>
</div>
</div>
</div>
}
</tr>
</tbody>
i++;
}
</table>
Controller:
public IActionResult AddAppointment(int hour)
{
return null;
}
Objects in list has hour and minute variables which are int and sorted as "9:00,9:30,10:00,10:30...16:00".
What is coming to my controller is always the first element of list.
You put the code of popup modal dialog in a foreach loop, if you check the html source code, you can find that multiple button(s) with same value #exampleModal of data-target attribute, and target modal(s) with same value exampleModal of id attribute, which cause the above issue.
To resolve this issue and make modal popup works well, you can modify the code as below to make the data-target attribute of button trigger and id attribute of modal unique within the HTML document.
<td><button type="button" class="btn btn-info" data-toggle="modal" data-target=#("#exampleModal"+i)>Randevu Al</button></td>
<div class="modal fade" id=#("exampleModal"+i) tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
Test Result
I want to delete a record from table and I sent CategoryId with this code:
Main view :
<a data-toggle="modal" data-target="#Deletemodal" onclick="Func_LoadPv('#item.CategoryId')" class="btn btn-danger btn-xs">delete</a>
function Func_LoadPv(Cid) {
$.get("/AdminPanel/Category/ShowPartialView?CategoryId=" + Cid, function (res) {
$("div.modal-body").append(res);
});
}
Controller :
public IActionResult ShowPartialView(Guid CategoryId)
{
return PartialView("_DeleteMainCategory", CategoryId);
}
How can I get this value that is sent from the controller to the partial Modal?
And the problem I have is that the modal only opens once ?
How can I get this value that is sent from the controller to the partial Modal?
You can specify a model for your partial view _DeleteMainCategory.cshtml, like below.
#model Guid
<h1>DeleteMainCategory Partial View</h1>
#*content here*#
<h2>#Model</h2>
the problem I have is that the modal only opens once
The following sample with testing data work well for me, you can check and compare it with yours.
<table>
<tbody>
#foreach (var item in Model)
{
<tr>
<td> #rowCount</td>
<td>#item.CategoryTitle</td>
<td>#item.IconCategory</td>
<td>
<a data-toggle="modal" data-target="#Deletemodal" title="delete"
class="btn btn-danger btn-xs" onclick="Func_LoadPv('#item.CategoryId')">delete</a>
</td>
</tr>
}
</tbody>
</table>
<div id="Deletemodal" class="modal fade" role="dialog">
<div class="modal-dialog">
<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">
#*modal body here*#
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
#section scripts{
<script>
function Func_LoadPv(Cid) {
$.get("/AdminPanel/Category/ShowPartialView?CategoryId=" + Cid, function (res) {
$("div.modal-body").html(res);
});
}
</script>
}
Test Result
I solved
Modal :
<div id="deletemodal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">delete category</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div id="bodyModal" class="modal-body">
</div>
</div>
</div>
JQuery :
function DeleteCategory(id) {
$.ajax({
url: "/AdminPanel/Category/DeleteCategory/" + id,
type: "Get",
data: {}
}).done(function (result) {
$('#deletemodal').modal('show');
$('#bodyModal').html(result);
});
}
Controller :
public IActionResult DeleteCategory(Guid? id)
{
return View();
}
[HttpPost]
public IActionResult DeleteCategory(Guid id)
{
_admin.DeleteMainCategory(id);
return RedirectToAction("ShowMainCategory", "Category");
}
Partial View :
<form asp-action="DeleteCategory" class="form-padding">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<h5 class="text-center">Are You Sure ?</h5>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-info waves-effect">delete</button>
<button type="button" class="btn btn-danger waves-effect"
data-dismiss="modal">
cancel
</button>
</div>
i am trying to populate modals with different data, i create the modals buttons using a foreach loop and then i want to apply the relevant data to the right modal.
The problem i have is that the modal is showing the same data for each modal button. How can i make this unique? When its doing its loop its actually placing the correct info but when the page loads its only showing one type of data for every modal.
#foreach (DataRow row in Model.Tables[0].Rows)
{
<tr>
<td>#row["SerialNumber"]</td>
<td>#row["DtTmGenerated"]</td>
<td>
<button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="#myModal">View Error</button>
</td>
</tr>
}
</thead>
<tbody></tbody>
</table>
#if (Model.Tables[0].Rows.Count != 0)
{
<script type='text/javascript'>
window.onload = function() {
document.getElementById("cssClass").style.display = 'none';
}
</script>
}
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title justify-content-center">Panda Error information</h4>
</div>
<div class="modal-body">
#foreach (DataRow row in Model.Tables[0].Rows)
{
var test = Convert.ToString(row["FriendlyError"]);
if (test != "No Error" )
{
<p>#row["FriendlyError"]</p>
}
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
</html>
I'm a bit late but I had the same problem today and I managed to fix it :D
The problem is the ID of the modal. In each new loop pass your modal is created with the same ID.
In other words: Your values, which come into the modal always change, but because the ID is static, all further modals get the same values as in the first one, because all have the same ID. Try this:
Add this code right after your model (#model ...)
#{
int ModalId = 0;
}
Then change the ID in the button that opens your modal:
data-target="##ModalId"
In the line before you close your foreach, add this
#(ModalId++)
Change your modal to this and put it into your foreach so that it looks like this:
#foreach (DataRow row in Model.Tables[0].Rows)
{
<tr>
<td>#row["SerialNumber"]</td>
<td>#row["DtTmGenerated"]</td>
<td>
<button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="##ModalId">View Error</button>
<!-- Modal -->
<div id="#ModalId" aria-labelledby="#ModalId" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title justify-content-center">Panda Error information</h4>
</div>
<div class="modal-body">
#foreach (DataRow row in Model.Tables[0].Rows)
{
var test = Convert.ToString(row["FriendlyError"]);
if (test != "No Error")
{
<p>#row["FriendlyError"]</p>
}
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</td>
</tr>
#(ModalId++)
}
</thead>
<tbody>
</tbody></table>
#if (Model.Tables[0].Rows.Count != 0)
{
<script type='text/javascript'>
window.onload = function() {
document.getElementById("cssClass").style.display = 'none';
}
</script>
}
</body>
</html>
In summary: Wherever you had "myModal" as ID, you must replace it with #ModalId
I have a table that has dynamic buttons which bring up a modal with info. Within the modal i want to add a new row to a table when i click a button.
I display the modal from within my main view, then call a partial to show the info inside the table in the modal.
From within the partial I've tried using append but doesn't seem to work, I thought jQuery could add to the table and I wouldn't have to invoke any kind of refresh.
My question is: how can I refresh my table from inside the partial?
I believe that jQuery is adding to the td but its just not being updated
EditApplication.cshmtl main view
<form method="POST">
<div class="modal fade" id="editAppModal" tabindex="-1" role="dialog" aria-labelledby="editAppModal" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editAppModal">Edit Application</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<input type="text" id="appName">
<input type="text" id="appShortName" style="width:15%">
<hr>
<table id="modalServerTB" style="border-collapse: separate; border-spacing: 5px 15px;">
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" asp-page-handler="UpdateApplication">Update Application</button>
</div>
</div>
</div>
</div>
</form>
jQuery in main view
<script>
$(document).ready(function(){
$(".selectRow").click(function(e)
{
e.preventDefault();
var row = $(this).closest("tr"),
tds = row.find("td:nth-child(1)").first(); //get row closest to click then grab first column info
var textval = $.trim(tds.text()); //tons of whitespace around the text, needs to be removed
$.ajax({
url: "EditApplication?handler=GetRowInfo",
type: "POST",
dataType: "json",
data: { textval },
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
complete: function (result) {
$("#appName").val(textval);
$("#appShortName").val(result.responseJSON);
$('#modalServerTB').load('/EditApplication?handler=ServerPartial');
$('#editAppModal').modal('show');
}
})
});
});
</script>
partial view
<tbody id="tableBody">
#foreach(var s in Model.serverUrl)
{
<tr style="border-bottom: 0.3px outset whitesmoke" >
<td style="width:40%">
<input type="text" value="#s.Key">
</td>
<td>
#foreach(var u in s.Value)
{
#Html.DropDownListFor(a=>u.Urlid, Model.urls, new{style = "width:50%", #class = "selectedURL"})
<br>
}
</td>
<td class="newURLS" style="border:solid 1px">
</td>
<button class="AddURLBtn"> + </button>
<br>
</tr>
}
</tbody>
<div>
<button type="button" class="btn btn-dark btn-sm" id="AddServerBtn">Add Server </button>
</div>
#Html.DropDownList("selectedURL",Model.urls, "Select URL" , new {style = "width:50%; display:none;", #class = "selectedURL", id="urlDDL"})
<script>
$(document).ready(function(){
$(".AddURLBtn").click(function(e)
{
e.preventDefault();
console.log("inaddurl");
$(".newURLS").append('sgagfsafsafsf');
});
});
</script>
As of right now i was just testing to see if i can add just text to the td but it doesn't seem to work
I am also passing a view model to my partial
Turns out you need a table tag for this to all work. With just TBody the div was not being created therefore my jquery function had no target
<table>
<tbody id="tableBody">
#foreach(var s in Model.serverUrl)
{
<tr style="border-bottom: 0.3px outset whitesmoke" >
<td style="width:40%">
<input type="text" value="#s.Key">
</td>
<td class="urlsTD">
#foreach(var u in s.Value)
{
#Html.DropDownListFor(a=>u.Urlid, Model.urls, new{style = "width:50%", #class = "selectedURL"})
<br>
}
</td>
<td>
<button class="AddURLBtn"> + </button>
</td>
</tr>
}
</tbody>
<div>
<button type="button" class="btn btn-dark btn-sm" id="AddServerBtn">Add Server </button>
</div>
</table>
Can please someone help me here?! Thank you!
I have a view that displays a list of products along with an "Add Product" button for each. I am calling the CreateNewProduct method for each "Add Product" click to find the status of the product. Depending on the status, either I need to stay on the same view or I need to call a modal popup. I am able to do this by creating a modal popup in a different view. But I want to call the modal popup div (also pass the modal) from the same view where it displays a list of products. Is this possible?
public ActionResult CreateNewProduct(int productId)
{
var sharedProduct = _productTemplateService.GetSharedProducts(productId);
var _finalSharedProducts = (sharedProduct.Any(t => t.productId != productId));
if (_finalSharedProducts)
{
var sharedProdctTemplate = _productTemplateService.GetSharedProduct(productId);
return View("ModalView", new SharedModel
{
SharedProduct = sharedProdctTemplate
});
}
else
{
_productTemplateService.CreateNewProduct(productId);
return RedirectToAction("Details", "ProductTemplate");
}
}
Model View Code
<div class="modal fade" id="myModal" role="dialog">
<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">Shared Product</h4>
</div>
<div class="modal-body">
<div class="flex-row">
<div class="col-6">
<div class="d-flex flex-row">
<div class="p-2">Product ID</div>
<div class="p-2">Product Types</div>
<div class="p-2">Status</div>
</div>
#foreach (var productTemplate in Model.SharedProduct )
{
<div class="d-flex flex-row">
<div class="p-2">#productTemplate.ProductId</div>
<div class="p-2">#productTemplate.ProductType</div>
<div class="p-2">#productTemplate.StatusCode</div>
</div>
}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<p>
#Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
#Html.ActionLink("Back to List", "Index")
</p>
<script type="text/javascript">
$(document).ready(function () {
$('#myModal').modal('show');
});
</script>
UPDATE:
I made it working. This is what I did. At the end, I have mentioned issues I am facing.
Link, modal and script in my main view - Detail View (called from ProductTemplate Controller)
<td>Add New Product</td>
<div class="modal fade" id="mymodel" role="dialog" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Shared Products</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body" id="mymodelbody">
</div>
</div>
</div>
<script>
var loadModal = function (productId, customerId) {
$.ajax({
type: 'GET',
url: '/NewProductTemplate/CreateNewProduct',
cache: false,
data: {
productId: productId,
customerId: customerId
},
dataType: 'html',
success: function (data) {;
$("#mymodelbody").html(data);
$("#mymodel").modal("show");
}
});
}
</script>
NewProductTemplateController Code
public ActionResult CreateNewProduct(Guid productId, Guid customerId)
{
var sharedProduct = _productTemplateService.GetSharedProducts(productId);
var _finalSharedProducts = (sharedProduct.Any(t => t.productId != productId));
if (_finalSharedProducts)
{
var sharedProdctTemplate = _productTemplateService.GetSharedProduct(productId);
return PartialView("_shared", new SharedModel
{
SharedProduct = sharedProdctTemplate
});
}
else
{
_productTemplateService.CreateNewProduct(productId);
return RedirectToAction("Details", "ProductTemplate");
}
}
Partial view _shared.view code
#model SharedModel
#using (Html.BeginForm("ShareProduct", "NewProductTemplate", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="flex-row">
<div class="col-6">
<div class="d-flex flex-row">
<div class="p-2">Product ID</div>
<div class="p-2">Product Types</div>
<div class="p-2">Status</div>
</div>
#for (var i = 0; i < Model.SharedProducts.Count(); i++)
{
#Html.HiddenFor(model => model.SharedProducts.ElementAt(i).ProductId)
#Html.HiddenFor(model => model.SharedProducts.ElementAt(i).CustomerId)
#Html.HiddenFor(model => model.SharedProducts.ElementAt(i).ProductType)
#Html.HiddenFor(model => model.SharedProducts.ElementAt(i).StatusCode)
#Html.HiddenFor(model => model.SharedProducts.ElementAt(i).IsShared)
<div class="d-flex flex-row">
<div class="p-2">#Html.DisplayFor(model => model.SharedProducts.ElementAt(i).ProductId)</div>
<div class="p-2">#Html.DisplayFor(model => model.SharedProducts.ElementAt(i).ProductType)</div>
<div class="p-2">#Html.DisplayFor(model => model.SharedProducts.ElementAt(i).StatusCode)</div>
#if (Model.SharedProducts.ElementAt(i).StatusCode == VersionStatus.PUBLISHED)
{
<div class="p-2">#Html.EditorFor(m => m.SharedProducts.ElementAt(i).IsShared)</div>
}
</div>
}
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-sm btn-primary" />
<button type="button" class="btn btn-sm btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
PROBLEM:
1) When I save submit button in modal pop-up (partial view), it calls ShareProduct method from NewProductTemplate controller. For some reason, model SharedModel's SharedProducts property is null when it gets to controller code. Can you please help me here why it gets null?
public ActionResult ShareProduct (SharedModel shareModel)
{
//Access ShareProducts from shareModel
return RedirectToAction("Details", "ProductTemplate");
}
PROBLEM:
2) I want to load popup only if the product is shared, otherwise I just want to redirect to Detail view as mentioned in NewProductTemplate controller's CreateNewProduct method. Problem is that it loads Detail view also in popup if product is not shared since that's what my script is doing. Is there any way that I can check data in Success function before showing modal popup? If data/html contains Shared text, I would like to load the normal Detail view. I am just assuming. I tried to do so but with no success.
Detail method in ProductTemplate Controller
public ActionResult Details()
{
var productTemplate = _productTemplateService.GetAllProducts(User);
return View(new DetailsModel
{
ProductTemplate = productTemplate,
});
}
(This is for Bootstrap 3.3.7 Hopefully it's relevant for the version you're on)
I handle this by popping open the modal on the client side from my main view. The link that pops the modal contains the URL to the controller method that will render the actual contents (list of products, in your case). This controller method should return a partial view.
Modal in my main view:
<div class="modal fade name-of-my-modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content"></div>
</div>
</div>
Link in my main view:
<a class="btn btn-default btn-xs" data-toggle="modal" data-target=".name-of-my-modal" role="button" href="/SomeController/SomeMethodThatReturnsPartialView/234">Show Modal</a>
My controller method for the partial view:
public ActionResult SomeMethodThatReturnsPartialView(int id)
{
var model = GetProducts();
return PartialView("_IndexPartial", model);
}
My partial view that will populate the actual modal contents:
<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">Title goes here</h4>
</div>
<form class="form-horizontal" id="SomeId" name="SomeName" role="form">
<div class="modal-body">
<div>Product 1</div>
<div>Product 2</div>
<div>Product 3</div>
<div>Product 4</div>
</div>
</form>
Also, if the contents of the modal change frequently, or are variable based upon the ID you pass to the partial controller method, then you'll want to clear the modal contents when closing it. From your main view:
$(document).on('hidden.bs.modal', '.modal', function (e) {
// Handles the event thrown when a modal is hidden
$(this).removeData('bs.modal');
$(this).find(".modal-content").empty();
});
Let me know if this helps, and whether anything needs to be clarified.
Problem 2 you could return a JSON result and put the HTML in a string as shown here:
https://www.codemag.com/article/1312081/Rendering-ASP.NET-MVC-Razor-Views-to-String
you could also set a boolean on the returned JSON for whether to redirect.
If it is a redirect do that in Javascript on the success using
window.location