I my below code i am calling partial view with ajax but when i click on the link of product Name the description of that product is not retrieved through ajax and error of ajax executes. I am retrieving the details of items selected by user on the same page but it is not retrieved. Please give any suggestion where is the issue arising because i am new to MVC. thanks...
Create.cshtml
#model List<PartialView.Models.tbl_product>
<!DOCTYPE html>
<html>
<head>
<title>Create</title>
<script src="#Url.Content("~/Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('.msg').click(function () {
var id = this.id;
$.ajax({
url: "/Category/Display",
data: { data: id },
success: function (mydata) {
$("#link").empty().append(mydata);
},
error: function (mydata) { alert("error"); },
type: "POST"
});
return false;
});
});
</script>
</head>
<body>
#foreach (var item in Model)
{
<a class="msg" href="#" id="#item.ProductId">#item.ProductName</a>
}
<div id="link">
</div>
</body>
</html>
ClicksUs.cshtml (PartialView)
#model List<PartialView.Models.tbl_product>
#foreach(var items in Model)
{
#items.ProductDesc
}
CategoryController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PartialView.Models;
namespace PartialView.Controllers
{
public class CategoryController : Controller
{
dbEntities dbentity = new dbEntities();
public ActionResult Create()
{
return View(dbentity.tbl_product.ToList());
}
public ActionResult Display(int data)
{
var query = dbentity.tbl_product.First(c => c.ProductId == data);
return PartialView("ClicksUC", query);
}
}
}
Your Details controller action selects a single element here (because you are calling .First()):
public ActionResult Display(int data)
{
var query = dbentity.tbl_product.First(c => c.ProductId == data);
return PartialView("ClicksUC", query);
}
So the type of the query variable is tbl_product and not List<tbl_product>.
On the other hand your partial's model is List<PartialView.Models.tbl_product> which is obviously wrong.
Your partial's model should be a single tbl_product:
#model PartialView.Models.tbl_product
#Model.ProductDesc
Oh and what others said about the typo in your partial view name.
there are three issues in the code that you could address.
One is a typo (the partialview is called ClicksUS, NOT ClicksUC),
the other is related to the way you return the data
the third is that you use the type: "POST", you should change this to type: "GET".
try changing the code to:
public ActionResult Display(int data)
{
// using First() would have caused you an error in the view if not found
// still not perfect below, but a step closer
var query = dbentity.tbl_product.FirstOrDefault(c => c.ProductId == data);
// You had ClicksUC, rather than ClicksUS
return PartialView("ClicksUS", query);
}
I'd also strongly suggest that you create a ViewModel for your data, rather than passing the objects from the database as this will allow you to control exactly the data that should be viewed and how it should be formatted etc.
[edit]
Also, as Darin says, based on a single row being retruned, you should change your partial view model type to:
#model PartialView.Models.tbl_product
Related
I am new to the web side of things and I am currently struggling with Razor Pages. Can someone explain the ways I can get a value from control in this case.
How can I extract the content of the selected and pass it to a variable to the code behind;
#page
#model ViewToVM.Pages.IndexModel
#{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<section id="cityList">
<select id="selectedCity">
#using Model;
#foreach(City city in Model.Cities)
{
<option>#city.SelectedCity</option>
}
</select>
</section>
with this code behind
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Collections.Generic;
using ViewToVM.Model;
namespace ViewToVM.Pages
{
public class IndexModel : PageModel
{
public List<City> Cities = new List<City>()
{
new City("Sofia"),
new City("Plovdiv"),
new City("Velingrad")
};
public string selectedCities = string.Empty;
public void OnGet()
{
}
}
}
The City class just contains a single string for demo purposes. I know this is probably a pretty bad way to do the code behind but It help me illustrate the problem better.
you can use Javascript/Jquery and add an onchange event listener that can make a Ajax call and pass it's value to the controller. similar to the code below:
<script type="text/javascript">
// assuming you're using jQuery
$("#selectedCity").change( function (event) {
$.ajax({
url: "Controller/PostDropdown/",
data: { id = $(this).val() },
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
// do something
}
});
});
You should wrap select with form. When form was submitted, it will call your controller.
see this:
Submitting form and pass data to controller method of type FileStreamResult
Using jquery.ajax, I am trying to return a view, that has a nested partial view to display a datatable. The initial view is returning, but the datatable is not showing or rendering.
AJAX
$.ajax({
type: "GET",
url: "/Controller/Action,
data: {
custNum: custNum
},
success: function (data) {
$('#DivToRenderResults').html(data);
}
Controller
public ActionResult Action(string custNum)
{
Model ReturnModel = GetData(custNum)
if (Request.IsAjaxRequest())
{
return PartialView(ReturnModel);
}
return View(ReturnModel );
}
Model
public class Model
{
public FirstViewsModel FirstViewsModel {get;set;)
public IEnumerable<DataTableModel> DataTableModel {get;set}
}
I ultimately want to use ajax to dynamically load different tabs that all will have nested datatables in partial views, but I am unable to get this first one to work. Please help, & thank you!
Target View
<div id="DivToRenderResults">
<\div>
// Inside the div
#model Model
<div>
// FirstViewModelInfo
<div>
// This one is not rendering in the return
#Html.Partial("_DataTableView", Model)
</div>
</div>
I'm working MVC 5 on c#,
My problem about run partial view.
codes,
Controller:
MiyosContext db= new MiyosContext();
public ActionResult Index(int id)
{
ViewBag.IndexId = id;
return View();
}
public PartialViewResult FirmaList(int id)
{
var firmalar = (from b in db.Firmalar
where b.Id == id
select b).ToList();
return PartialView(firmalar);
}
View:
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_LayoutGenel.cshtml";
}
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var firmaId = document.getElementById("gelenId").value;
$('#firmaBilgileri').load("../Firma/FirmaList/" + firmaId);
});
</script>
<input type="hidden" value="#ViewBag.FirmaId" id="gelenId" />
<div id="firmaBilgileri">
</div>
Partial View not working with "int id".
If i change controller like this, there is no problem:
public ActionResult Index()
{
ViewBag.IndexId = 2;
return View();
}
I erased "int id" and view opening without post. Now it is working. Why using "int id" blocking partial view?
Note: it is not about url post function.
Because is needs the id from the resource URL:
GET /Firma/Index/2
You can leave as the former and type this in the browser:
http://localhost:portNumber/Firmar/Index/2
It should work with the id parameter.
So, all you need to do is add a query string to the load() request:
$('#firmaBilgileri').load("/Firma/FirmaList?id=" + firmaId);
Make sure the request actually hits the MVC controller.
I have a server-generated object that I need to convert to a JSON object for JavaScript to consume. I prefer to render this JSON object directly into a JS variable when the view renders to prevent an additional HTTP request.
This is in my controller:
public virtual JsonResult GetTheThings()
{
return Json(new
{
foo = "hello world",
bar = 3,
}, JsonRequestBehavior.AllowGet);
}
I can access this directly at http://localhost:32243/MyController/GetTheThings and I get the following rendered in my browser.
{"foo":"hello world", "bar":3}. Perfect!
So, now I basically just want to render the result of this view into a string. How do I do this? What I have below does not work, but hopefully it give you the idea.
This is my attempt
<script>
var myObj = #Html.RenderPartial(MVC.MyController.GetTheThings());
</script>
Note that I am also using T4 Templates.
In the end, this is what I want to be rendered in the view.
<script>
var myObj = {"foo":"hello world", "bar":3};
</script>
Since you only want the object to be rendered when the view is rendered (and not from an AJAX call), your best bet is probably to make it part of your model. Create a string property and save the JSON as a string, then use JSON.parse in your View to convert it to an object.
Example:
<script>
var myObj = JSON.parse("#Html.Raw(Model.JsonString)");
</script>
Much cleaner that way, and there really isn't any good reason to have your controller doing this since you aren't requesting the object via AJAX.
You could create an HtmlHelper extension like so and instead of using a JsonResult, use a strongly-typed view (assuming using JSON.Net):
public static class HtmlHelperEx
{
public static string ToJson(this HtmlHelper html, object obj)
{
return JsonConvert.SerializeObject(obj);
}
}
Controller Action:
public ActionResult Index()
{
return View(new ModelToSerialize());
}
Then use it in your view like:
#model ModelToSerialize
<script type="text/javascript">
var myObj = #Html.ToJson(Model)
</script>
You would theoritically be able to do it like this:
<script>
var myObj = json.parse('#Html.RenderPartial(MVC.MyController.GetTheThings());');
</script>
Although, GetTheThings() will not actually fire here, it's just a T4MVC placeholder. You should probably store your value into a view model, and get it into javascript like below. If you want to make a separate call to a controller to get this value, it will need to be an ajax call.
public class MyController
{
public ActionResult MyView(){
var vm = new MyViewModel();
vm.MyObjectAsJsonString = GetMyJsonString();
return View(vm);
}
public string GetMyJsonString(){
return ""; //get your json
}
}
public class MyViewModel
{
public string MyObjectAsJsonString{ get; set; }
}
#model MyViewModel
<script>
var myObj = json.parse('#Model.MyObjectAsJsonString');
</script>
To do it via ajax:
<script>
$.ajax({
url: '#Url.Action(MVC.MyController.GetTheThings())',
type: 'get',
}).done(function (result){
var myObj = result;
});
</script>
<script>
var myObj = '#Html.RenderPartial("Getthethings","controller name");'
</script>
Use the #Html.Raw(...) wrapper.
In my own project, I do refer to the existing model coming down in from the controller itself, but there's no reason you can't get the same effect as a partial...it's just not really the core purpose of using async calls...which you should be using instead of relying on the html rendering engine to do your 'dirty' work.
how can i render multiple different actions in one call to a speccific controller?
Html.RenderAction() / Html.Action() only handles one controller&action.
But what if i want in one call to render different views on the screen?
thanks in advance,
Sagiv
EDIT:
Hi again.
I'm not sure you understood my question.
this is the cshtml:
<div id="menu">#using (Ajax.ActionLink("click me", "SomeAction","SomeController", new AjaxOptions() { HttpMethod = "POST", OnSuccess = "showMsg", OnFailure = "showError" }))</div>
<div id="div1">bla bla content</div>
....
<div id="div2">bla bla content</div>
and this is the controller:
public class SomeController : Controller
{
public ActionResult SomeAction()
{
return View("somethingfordiv1", ModelForDiv1);
return View("somethingfordiv2", ModelForDiv2); //i want also return another view here
}
}
in this ajax call on the controller, i want to return 2 different views for 2 different divs.
thanks again :)
Here's one way you could proceed. You could aggregate the two view models into a unique view model and then have the controller action return a view containing javascript which will inject the two view results into the different divs.
As always start with the view models:
public class Model1 { }
public class Model2 { }
public class AggregatedModel
{
public Model1 Model1 { get; set; }
public Model2 Model2 { get; set; }
}
Then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult SomeAction()
{
var model = new AggregatedModel
{
Model1 = new Model1(),
Model2 = new Model2()
};
Response.ContentType = "text/javascript";
return PartialView(model);
}
}
Then the corresponding ~/Views/Home/Index.cshtml view:
<div id="menu">
#Html.ActionLink("click me", "SomeAction", "Home", new { id = "clickme" })
</div>
<div id="div1">bla bla content</div>
<div id="div2">bla bla content</div>
<script type="text/javascript">
$('#clickme').click(function () {
$.getScript(this.href);
return false;
});
</script>
Next the ~/Views/Home/SomeAction.cshtml view:
#model AggregatedModel
$('#div1').html(#Html.Raw(Json.Encode(Html.Partial("Model1", Model.Model1).ToHtmlString())));
$('#div2').html(#Html.Raw(Json.Encode(Html.Partial("Model2", Model.Model2).ToHtmlString())));
and finally the two ~/Views/Home/Model1.cshtml and ~/Views/Home/Model2.cshtml views:
#model Model1
<span>This is the contents for model1</span>
and:
#model Model2
<span>This is the contents for model2</span>
If you want to render different views on the screen return a model which represents the data for those views, then you can use RenderPartial and pass the part of the model data required to each view.
You can also use viewdata to separately have this available.
Html.RenderAction is also available but simulates another full request
For your ajax request you can return a html chunk from the rendering of a partial view and this can be determined by Request.IsAjaxRequest. Then your javascript can set the result into the document.
This is in your action
if (Request.IsAjaxRequest())
{
return View("PartialViewName", partialModel);
}
return View("NormalView", normalModel);
And the client side example (using jquery)
function hijack(form) {
$("div#SearchResults").html("");
$("div#SearchResults").addClass('loading');
$.ajax({
url: form.action,
type: form.method,
dataType: "html",
data: $(form).serialize(),
success: function(data) {
$("div#SearchResults").removeClass('loading');
$("div#SearchResults").html(data);
}
});
}