I am trying to reload my Partial View _Home when I close my dropdown. Currently I can get that dropdown value to call another method and do the logic that will change the model then send the model back to the index. However, I cannot get my _Home Partial View to reload and actually take in this new model. I cannot seem to be able to actually call the public ActionResult _Home(Model model) method. I am wondering how to pass in this new model and refresh the partial view.
I have tried to pass in the model to the partial view but this seems to have no effect, having no model being passed in does not change anything either. I have seen a few examples online of how to refresh partial views but none of them pass in any parameters.
JavaScript
function OnClose() {
var chart = $("#safetyIncident-chart").data("kendoChart");
var chart2 = $("#qualityError-chart").data("kendoChart");
chart.dataSource.read();
chart2.dataSource.read();
var selectProductionLine = $("#productionLine-dropdown").data("kendoDropDownList").value();
$.ajax({
url: '#Url.Action("UpdateView", "Home")', //Updates model and then calls Index
type: 'post',
dataType: "json",
data: { "selectProductionLine": JSON.stringify(selectProductionLine) }, //Passes in DropDownValue correctly
success: function (data) {
$("#partial").html(result);
$("#Dashboard").load("/Home/_Home"); //Trying to reload the partial view
}
});
}
View
<div id="Dashboard">
#Html.Partial("~/Views/Home/_Home.cshtml")
</div>
Controller
[HttpGet]
public ActionResult Index()
{
DisplayViewModel dvm = (DisplayViewModel)TempData["dvm"];
if(dvm != null)
{
return View(dvm);
}
//Initializes new dvm if previous was null
return View(dvm);
}
I am trying to refresh my partial view once DropDown closes and the ViewModel is refreshed.
EDIT:
UpdateView method in Controller
[HttpPost]
public ActionResult UpdateView(string selectProductionLine)
{
if(selectProductionLine == null)
{
selectProductionLine = _productionLineService.Collection().FirstOrDefault().Id;
}
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(selectProductionLine, typeof(string));
DisplayViewModel dvm = new DisplayViewModel();
ProductionLine pl = _productionLineService.Find(jsondata);
dvm.ProdLine = new ProductionLineViewModel
{
Id = pl.Id,
CreatedAt = pl.CreatedAt,
Name = pl.Name,
ActiveLine = pl.ActiveLine,
ComputerName = pl.ComputerName,
UPE = pl.UPE
};
TempData["dvm"] = dvm;
return Index();
//PartialView("~/Home/_Home.cshtml", dvm);
}
Related
I've been stumped for days.
I have an index page that contains a renderpartial view. A viewmodel is passed to the index page from its controller, then passed from inside the index.cshtml to the renderpartial view as an extension. The renderpartial view is automatically updated every 10 seconds (via jquery function to the controller from the index page) to update its content, which works fine. The index page contains several checkboxfor's that filter out the contents of the renderpartial view. The problem arises when the initial renderpartial view is called when the time period has elapsed, the controller for the renderpartial view does not have the correct model data the controller for the index had prior. Boolean values in the model which were set to true while in the index controller now are false when we get to the renderpartial view. Lets begin...
My Index View:
#model SelfServe_Test2.Models.NGTransCertViewModel
...
<div class="Services_StatusTable" id="refreshme">
#{
Html.RenderPartial("_Data", Model);
}
</div>
...
#Html.CheckBoxFor(m => m.NGTransServicesModel.filter_NJDVSVR24, new { onclick = "test(id)" }) #Html.Label("NJDVSVR24", new { })
...
<script src="~/Scripts/jquery-1.12.4.js"></script>
<script type="text/javascript">
$(function () {
setInterval(function () { $('#refreshme').load('/NGTransCertServices/Data'); }, 10000); // every 10 seconds
function test(filter) {
alert(filter);
var serviceChecked = document.getElementById(filter).checked;
$.ajax({
type: "POST",
url: "/NGTransCertServices/ToggleVisibleService",
data: { 'filterOnService': filter, 'serviceChecked': serviceChecked, 'model': #Model },
//success: function (result) {
// if (result === "True")
// alert("yup");
// else
// alert("nope");
//}
});
}
</script>
The PartialView _Data.cshtml:
#model SelfServe_Test2.Models.NGTransCertViewModel
...
<table>
foreach (var item in Model.NGTransServicesList)
{
if (Model.NGTransServicesModel.filter_EBT == true)
{
if (item.Description.Contains("EBT"))
{
}
}
}
</table>
My ViewModel:
namespace SelfServe_Test2.Models
{
public class NGTransCertViewModel
{
public NGTransCertViewModel()
{
NGTransServicesModel = new NGTransCertServicesModel();
NGTransServicesList = new List<NGTransCertServicesList>();
NGTransServices = new NGTransCertServices();
}
public NGTransCertServicesModel NGTransServicesModel { get; set; }
public List<NGTransCertServicesList> NGTransServicesList { get; set; }
public NGTransCertServices NGTransServices { get; set; }
}
}
The Controller:
public class NGTransCertServicesController : Controller
{
NGTransCertViewModel NGT_VM = new NGTransCertViewModel();
NGTransCertServicesModel certServicesModel = new NGTransCertServicesModel();
public ActionResult Index()
{
NGTransCertServices certServices = new NGTransCertServices();
NGT_VM.NGTransServicesModel = certServices.InitServiceTypeCheckBoxes(certServicesModel); // sets all checkboxes to true initially.
return View(NGT_VM);
}
[OutputCache(NoStore = true, Location = System.Web.UI.OutputCacheLocation.Client, Duration = 10)] // in seconds
public ActionResult Data()
{
NGTransCertDBHandle certDBHandle = new NGTransCertDBHandle();
List<NGTransCertServicesList> List_certServices = certDBHandle.GetService();
return PartialView("_Data", NGT_VM);
}
}
Finally, the model where the values are lost:
public class NGTransCertServicesModel
{
...
public bool filter_NJDVSVR24 { get; set; }
...
}
Now then, when the Index.cshtml page is called, i run the InitServiceTypeCheckBoxes method that sets the checkbox values to true, pass the viewmodel to the index page and pass that same model to the renderpartial. All is happy until the 10s timeout is reached and _Data.cshtml is rendered. The checkbox values are now all false.
Let me add a visual element. Below is the model when returning from the controller to the index view with the Boolean set to true as desired. (stepping through)
Below is the model when the index view
Again, in the _Data.cshtml partial view
Now with a breakpoint in the Data action in the controller, that same bool value is now false
The bool does not have the true value even before the first line of code in the Data action.
NGTransCertDBHandle certDBHandle = new NGTransCertDBHandle();
I think the issue is that you're not populating your view model correctly in the Data method of your controller.
In both methods you're sending the NGT_VM property to the view, but you only populate some of the data in the Index method - this data will not be persisted or created by default when you call the Data method.
Each time a request hits a controller method, that controller is created afresh, and only the constructor and requested method are called. In the case of a request to Data the controller is created, the NGT_VM property is set back to the default NGTransCertViewModel object, with a default NGTransCertServicesModel object (the boolean property filter_NJDVSVR24 will default to false). You then create and ignore a variable List_certServices, but at no point have you updated the NGTransServicesModel property on the view model to match the values you had from the Index method.
You should probably assign the NGTransServicesList variable to the NGT_VM.NGTransServicesList after you populate it:
[OutputCache(NoStore = true,
Location = System.Web.UI.OutputCacheLocation.Client,
Duration = 10)]
public ActionResult Data()
{
NGTransCertDBHandle certDBHandle = new NGTransCertDBHandle();
List<NGTransCertServicesList> List_certServices = certDBHandle.GetService();
NGT_VM.NGTransServicesList = List_certServices;
return PartialView("_Data", NGT_VM);
}
You could either call same methods to update the NGTransServicesModel as required in the Data method, but I'm not sure that's really the behaviour you're after?
I want to get model's specific value in ajax success. I can not use Json result in here because I also need to load the model value in div container with partial view.
Here is my model
public class ProductModel
{
public int ProductId { get; set; }
public decimal? Cost { get; set; }
public string Description { get; set; }
public bool IsCostUpdated { get; set; }
}
I want to get the value of IsCostUpdated in ajax success only. In controller I have to returned strongly typed partial view.
Here is the code
[HttpPost]
public ActionResult CheckProductCost(ProductModel model)
{
ModelState.Clear();
using (var db = DataContext.Db)
{
model.IsCostUpdated = model.CheckUpdate(db);
}
return PartialView("ProductDataTable", model);
}
this is my ajax call code
$.ajax({
url: productCostUrl,
dataType: 'html',
type: 'POST',
data: $('body').find('.productTable').closest('.dataComponent').find(':input').serialize(),
success: function (d) {
var isSuccess = d.IsCostUpdated; [I want this value]
$('body').find('.productTable').html(d)
}
});
You can return a JsonResult in your current ActionResult. Just check if the request being made is an ajax request. Your ActionResult would become something like this:
[HttpPost]
public ActionResult CheckProductCost(ProductModel model)
{
ModelState.Clear();
using (var db = DataContext.Db)
{
model.IsCostUpdated = model.CheckUpdate(db);
}
if (Request.IsAjaxRequest()) // THIS IS AVAILABLE INSIDE THE SYSTEM.WEB.MVC ASSEMBLY
return Json(new { IsCostUpdated = model.IsCostUpdated });
return PartialView("ProductDataTable", model);
}
you can return both the view and the data needed with json like below
return Json(new
{
view = RenderRazorViewToString(ControllerContext, "ProductDataTable", model),
IsCostUpdated = model.IsCostUpdated
});
// Render Razor view as string to populate dom
public static string RenderRazorViewToString(ControllerContext controllerContext, string viewName, object model)
{
controllerContext.Controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
var ViewResult = ViewEngines.Engines.FindPartialView(controllerContext, viewName);
var ViewContext = new ViewContext(controllerContext, ViewResult.View, controllerContext.Controller.ViewData, controllerContext.Controller.TempData, sw);
ViewResult.View.Render(ViewContext, sw);
ViewResult.ViewEngine.ReleaseView(controllerContext, ViewResult.View);
return sw.GetStringBuilder().ToString();
}
}
// Razor View - Ajax call Success
success: function (data) {
$('body').find('.productTable').html(data.view);
var isSuccess = data.IsCostUpdated;
}
Inside that AJAX Success callback you have acces to the data object, the one that you call "d" in your callback.
Try to console.log(d) and you will see that the d object has a responseJSON property. That is what you need to access your property.
Instead of doing: var isSuccess = d.IsCostUpdated; [I want this value] try var isSuccess = d.responseJSON.IsCostUpdated;
Another important thing, if you want to pass data from your controller to your ajax call, try to do: return Ok(model) instead of returning a partial view. If you return a partial view, the html of that page will be passed as response data to your data object in Ajax Success callback.
I have a simple list view where I'm loading my data.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Your application description page.";
IList<Product> products;
using (ISession session = NHibernateSession.OpenSession()) // Open a session to conect to the database
{
products = session.Query<Product>().ToList(); // Querying to get all the books
}
return View(products);
}
}
View is a simple list view from template.
Now, I need to load data to list view just after button click.
So as I understand I need to render partial view.
I've add this to view:
<button id="Load">Load data</button>
<script type="text/javascript">
var url = '#Url.Action("LoadData", "Home")';
$('#Load').click(function() {
var keyWord = $('#Keyword').val();
$('#result').load(url);
})
</script>
<div id="result"></div>
And add controller action:
public ActionResult LoadData()
{
// here will be model creation and passing view
return PartialView();
}
But controller action doesn't get called.
What should I do?
This is now I would do it.
We create an action method which return JSON on http gets
public class SomeController : Controller
[HttpGet]
public ActionResult LoadData()
{
using (ISession session = NHibernateSession.OpenSession()) // Open a session to conect to the database
{
products = session.Query<Product>().ToList(); // Querying to get all the books
}
return Json(new {data=product},
JsonRequestBehavior.AllowGet);
}
Inside your view we do a ajax request to get the data by calling LoadData
$.ajax({
type: 'get',
dataType: 'json',
url: 'SomeController/LoadData',
success: function (data) {
//Render data to view maybe using jquery etc
},
error: function(data) {
//Notify user of error
}
});
Hope this helps man
my UI has a text box and a button, everytime I add a new element I need to show the list in the same view. I'm using partial view so I need to keep loading this partial view everytime I add a new element to my list. how can I modify my code to achieve that?
View
#Html.TextBoxFor(m => m.emailsAdded, new { #class = "form-control wide", placeholder = "Email ID", type = "email", Name = "txtEmail" }
<button id="thisButton">Add</button>
<div id="content"></div>
<script>
$(document).ready(function() {
$("#thisButton").on("click", function () {
var val = $('#emailsAdded').val();
$.ajax({
url: "/Admin/UpdateEmailList?email="+val,
type: "GET"
})
.done(function(partialViewResult) {
$("#content").html(partialViewResult);
});
});
});
</script>
Model
public class ABC
{
public IEnumerable<string> emailsAdded { get; set; }
}
Controller
[HttpGet]
public ActionResult UpdateEmailList(string email)
{
if (Session["emails"] == null)
{
List<string> aux1 = new List<string>();
aux1.Add(email);
Session["emails"] = aux1;
}
else
{
List<string> aux2 = new List<string>();
aux2 = (List<string>)Session["emails"];
aux2.Add(email);
Session["emails"] = aux2;
}
var abc = new ABC
{
emailsAdded = (List<string>)Session["emails"]
};
return PartialView("_EmailsListPartialView", abc);
}
Partial view
#using project.Models
#model project.Models.ABC
<table class="tblEmails">
#foreach (var emails in Model.emailsAdded)
{
<tr><td>#emails.ToString()</td></tr>
}
</table>
With my code I'm able to reload my div and add the new element, when doesn't work for the second time....how can I modify my code so I can keep adding stuff?
SOLUTION:
I updated my controller to show how I resolved this issue. Not really sure if it is the best way to do it, but at least helped me to resolve.
I'm storing the list of emails in Session["emails"] and every time I add a new email to the list, I just update it a pass it to a new list with all the records and at the end return the partial view.
I choose from dropdown menu an item and click add => ajax call a method which return JsonResult this is all ok. Then this data should be send to another function PartialViewResult on server side: public PartialViewResult _SkupinaRow(skupinaRow skupinaRow), which generate a new tr with some textbox and labels. My problem is that no binding is made. I get Null when debuggin in _SkupinaRow(skupinaRow skupinaRow)
I have the following domain model defined:
public class skupinaRow
{
public BONUSMALUS bonusmalus { get; set; } //items
public KOLEDAR koledar { get; set; } //calendar
}
Partial View:
#model ObracunPlac.ViewModel.skupinaRow
#Html.HiddenFor(x => x.bonusmalus.bon_id)
.....
Partial view code:
public PartialViewResult _SkupinaRow(skupinaRow skupinaRow)
{
return PartialView("_SkupinaRow", skupinaRow);
}
Ajax Call:
$("#addItemPrihodki").live("click", function () {
var id = $("#prihodkidodaj option:selected").val()
var skupinaRow = {
bonusmalus:{},
koledar:{}
}
jQuery.getJSON("/Placa/getBonusMalus/?id=" + id, function (data) {
console.log("JSON Data: " + data.koledar.kol_id);
skupinaRow.koledar.kol_id = data.koledar.kol_id, //ok
skupinaRow.bonusmalus.bon_id = data.bonusmalus.bon_id, //ok
//alert(JSON.stringify(GetBonusMalusModel($("#bonusdodaj option:selected").val())));
alert(JSON.stringify(data));
// alert(skupinaRow.serialize());
$.ajax({
url: "../_skupinaRow",
cache: false,
data: JSON.stringify(skupinaRow),
//data: JSON.stringify(data),
datatype: JSON,
success: function (html) {
$("#editorRowPrihodki table tr#dodajNov").before(html);
}
,
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('error'+"+++"+textStatus+"--- "+errorThrown);
},
});
});
return false;
});
public JsonResult getBonusMalus(int id)
{
KOLEDAR koledar = db.KOLEDAR.Single(r => r.kol_id == KoledarID);
BONUSMALUS bm = db.BONUSMALUS.Single(r => r.bon_id == id);
skupinaRow model = new skupinaRow
{
koledar =koledar,
bonusmalus = bm
};
// return Json result using LINQ to SQL
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = model
};
}
Debug picture: https://www.dropbox.com/s/189q080irp0ny77/1.jpg
This worked when i had one model bonusmalus but now I ned two so I created modelView.
How can I bind ViewModel-SkupinaRow to Partial View with strong type SkupinaRow ?
If you are using AJAX only to convert he value to json? then you can use this approach
Set the form with normal post back to Action in controller
use jQuery in your view and on submit of form write this.
$("form").submit(function(){
$("#DropDown_Items").val(JSON.stringify(data));
});
Now you can use this in your Action Method.