I have moved following code from my view to partial view and getting error
My view code is:
function renderSeason() {
$('#visSeasonbut').click(function() { $('#p2').load(this.href); return false; });
}
function renderGame() {
$('#visGamebut').click(function() { $('#p2').load(this.href); return false; });
}
<div id="game">
<%= Html.ActionLink("Game 1", "PitcherTitles", "Test", null, new { id = "visGamebut" })%> </div>
LiveGame.Models.Baseball.Player visPlayer1 = ViewData.Model.GetCurrentTeamPlayer(false);
if (visPlayer1 != null)
{
LiveGame.Models.Baseball.Player rosterPlayer = ViewData.Model.GetTeam(0).RosterDictProp.GetPlayer(visPlayer1.Player_IdProp);
if (ViewData.Model.InningHalfProp == true)
{ %>
show Pitcher Stats here
<%
}
else
{
%>
Show PitchTitles here
<%
}
}
and partial views are like this :
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
Wins
Losses
ERA
second one is :
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
IP
H
R
ER
BB
SO
HR
ERA
When I click links, I get error , "rosterPlayer" not found, Please suggest solution. Thanks
When you render this partial make sure you are passing a model:
<% Html.RenderPartial("SomePartialName", Model); %>
And of course don't forget to strongly type your partial to the model:
<%# Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.SomeModelType>"
%>
Also from the comment you posted it looks like you aren't passing any model to your views. So change this and ensure a model is passed or you cannot use the Model property:
public ActionResult PitcherStats()
{
Game currentGame = new Game();
return View(currentGame);
}
public ActionResult PitchTitles()
{
Game currentGame = new Game();
return View(currentGame);
}
Related
I have a view that is outputting a list of questions(yesno and multiple choice). For the Multiple Choice questions, I want to also pass the possible multiple choice answers but I can not figure out how to pass 2 queries. Is there a way to do this or is it better handled another way?
Controller Code:
public ActionResult Test(int id)
{
var listofquestions = from m in db.vQuestionnaireQuestions
where m.Questionnaire_ID.Equals(id)
select m;
return View("Test", listofquestions.ToList());
}
View Code:
<% foreach (var item in Model)
{ %>
<br />
<%: item.Question_Text %>
<%if (item.Question_Type_ID == 1) //Yes-No Question
{ %>
//Yes-No Stuffs
<% }
else if (item.Question_Type_ID == 2) //Multiple Choice
{ %>
//Can I access a Linq query again here?
//I have Question_ID to use, but I don't think
//I can have 2 Models
<% }
else //All Else
{ %>
//All Else Stuffs
<% }
} %>
EDIT
I've created a view model class
View Model Class Code:
public IEnumerable<vQuestionnaireQuestion> FindAllQuestionnaireQuestionsTest()
{
return db.vQuestionnaireQuestions;
}
public vQuestionnaireQuestion GetQuestionnaireQuestionsTest(int id)
{
return db.vQuestionnaireQuestions.FirstOrDefault(q => q.Questionnaire_ID == id);
}
public IEnumerable<Multiple_Choice_Answers> FindAllMultipleChoiceAnswersTest()
{
return db.Multiple_Choice_Answers;
}
public Multiple_Choice_Answers GetMultipleChoiceAnswersTest(int id)
{
return db.Multiple_Choice_Answers.FirstOrDefault(q => q.Question_ID == id);
}
and added it to the inherits of my view:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<QuestionnaireApp.Models.Questionnaire>>" %>
The model information does not seem to be making it as now all my item.fieldname's are coming back as not having a definition. Am I over complicating this?
Try wrapping the results in a view model class and pass that to View
class SomeClassName {
IEnumerable<Question> ListOfQuestions;
IEnumerable<Answer> ListOfAnswers;
}
Many people create a class specifically for the purpose fo passing data between controller and view. That way you can define whatever properties you need, and an instance of your class can easily have one or more LINQ result sets in it.
I would like to create this url blah.com/preview?h=yes
so i can do this
<% if request.querystring("h") = "yes" then %>
jquery stuff
<% else %>
don't do jquery stuff
<% end if %>
You could use an HTML helper:
<%= Html.ActionLink(
"some text",
"someaction",
"somecontroller",
new { h = "yes" },
null
) %>
Assuming default routes this will generate the following link:
some text
Or if you want to generate only the link you could use the Url helper:
<%= Url.Action(
"someaction",
"somecontroller",
new { h = "yes" }
) %>
Set a property on your view model that you can inspect.
E.g. ViewModel
public class SomeActionViewModel
{
public bool DoJquery { get; set; }
}
Action (called via http://www.myawesomesite.com/somecontroller/someaction?h=yes)
public ActionResult SomeAction(string h)
{
var viewModel = new SomeActionViewModel();
if (!string.IsNullOrWhiteSpace(h) && (h.ToLower() == "yes"))
viewModel.DoJquery = true;
return View(viewModel);
}
View
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<SomeActionViewModel>" %>
<% if (ViewModel.DoJquery) { %>
<!-- Do jQuery -->
<% } else { %>
<!-- Don't do jQuery -->
<% } %>
HTHs,
Charles
Are you sure you need to be doing it like that from the server.
You could instead follow an Unobtrusive Javascript/Progressive Enhancement approach.
Decided to learn ASP.NET MVC and instantly got stuck on something simple.
In Web Forms user controls allowed to separate application into components based on functionality and facilitated reuse. It seems partial views are supposed to do something similar in ASP.NET MVC, but either I am getting this wrong, or each visible page is handled by single controller and it is not possible to delegate certain page portions to separate controllers without hard-coding these controller relationships.
RenderAction can render a partial view and insert resulting HTML in the page, but if we want this view to be refreshed when the user clicks on some link within this view together with the entire page, we need all the partial view links to refer to the parent controller?
For example:
Home\Index.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">Home</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
...
<% Html.RenderAction("Index", "Posts"); %>
...
Posts\Index.aspx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BlogEngine.Models.PostsViewModel>" %>
<% foreach(var item in Model.Posts){ %>
<p class="postMeta"><%: string.Format("{0} {1}", item.CreatedAt, item.CreatedBy) %></p>
<h1><%: item.Title %></h1>
<div><%: item.Content %></div>
<% } %>
<% if (Model.CurrentPage > 0){ %>
<%: Html.ActionLink("Newer posts", "Index", "Home", new { page=Model.CurrentPage - 1}, null) %>
<%} %>
<% if (Model.CurrentPage + 1 < Model.TotalPages) { %>
<%: Html.ActionLink("Older posts", "Index", "Home", new { page=Model.CurrentPage + 1}, null) %>
<% } %>
PostsController:
public class PostsController : Controller
{
private const int PostsPerPage = 2;
private readonly IPostRepository _postRepository;
public PostsController()
{
...
}
public ActionResult Index(int page = 0)
{
var model = new PostsViewModel();
int totalPages = 1;
model.CurrentPage = page;
model.Posts = _postRepository.GetPosts(page, PostsPerPage, out totalPages);
model.TotalPages = totalPages;
return PartialView(model);
}
}
There's got to be a better way than this?
I don't know if I understand correctly but you could load this Partial View in a using Ajax (by jQuery), and when you need to refresh only this part of content you reload the element. Something like this:
In Javascript:
function LoadComments(page) {
//It'll return a partial view
$("#comments").load("<%=Url.Action("Posts", "Index")%>?page=" + page);
}
$(document).ready(function() {
LoadComments(0);
});
Inside of yoru PartialView you need to render a javascript code to call the "reload" of the next (page) content, so call LoadComments(index-page)...
Look the Ajax APi of jQuery: http://api.jquery.com/category/ajax/
Cheers
I have started doing asp.net mvc programming and like it more everyday.
Most of the examples I have seen use separate views for viewing and editing details of a specific entity.
E.g. - table of music albums linking to separate 'detail' and 'update' views
[Action] | Title | Artist
detail, update | Uuuh Baby | Barry White
detail, update | Mr Mojo | Barry White
With mvc how can I achieve a design where the R and the U (CRUD) are represented in a single view, and furthermore where the user can edit separate parts of the view, thus limiting the amount of data the user can edit before saving?
Example mockup - editing album detials:
I have achieved such a design with ajax calls, but Im curious how to do this without ajax.
Parts of my own take on this can be seen below. I use a flag (enum EditCode)
indicating which part of the view, if any, that has to render a form. Is such a design in accordance with the framework, could it be done more elegantly?
AlbumController
public class AlbumController : Controller
{
public ActionResult Index()
{
var albumDetails = from ManageVM in state.AlbumState.ToList()
select ManageVM.Value.Detail;
return View(albumDetails);
}
public ActionResult Manage(int albumId, EditCode editCode)
{
(state.AlbumState[albumId] as ManageVM).EditCode = (EditCode)editCode;
ViewData["albumId"] = albumId;
return View(state.AlbumState[albumId]);
}
[HttpGet]
public ActionResult Edit(int albumId, EditCode editCode)
{
return RedirectToAction("Manage", new { albumId = albumId, editCode = editCode });
}
// edit album details
[HttpPost]
public ActionResult EditDetail(int albumId, Detail details)
{
(state.AlbumState[albumId] as ManageVM).Detail = details;
return RedirectToAction("Manage", new { albumId = albumId, editCode = EditCode.NoEdit });// zero being standard
}
// edit album thought
[HttpPost]
public ActionResult EditThoughts(int albumId, List<Thought> thoughts)
{
(state.AlbumState[albumId] as ManageVM).Thoughts = thoughts;
return RedirectToAction("Manage", new { albumId = albumId, editCode = EditCode.NoEdit });// zero being standard
}
Flag - EditCode
public enum EditCode
{
NoEdit,
Details,
Genres,
Thoughts
}
Mangae view
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Controllers.ManageVM>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Manage
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Manage</h2>
<% if(Model.EditCode == MvcApplication1.Controllers.EditCode.Details)
{%>
<% Html.RenderPartial("_EditDetails", Model.Detail); %>
<% }else{%>
<% Html.RenderPartial("_ShowDetails", Model.Detail); %>
<% } %>
<hr />
<% if(Model.EditCode == MvcApplication1.Controllers.EditCode.Thoughts)
{%>
<% Html.RenderPartial("_EditThoughts", Model.Thoughts); %>
<% }else{%>
<% Html.RenderPartial("_ShowThoughts", Model.Thoughts); %>
<% } %>
The last part feels messy to me. I would recommend wrapping those with Html Helpers to clean up your view.
<h2>Manage</h2>
<% Html.RenderDetailsPartial(Model.EditCode) %>
<hr />
<% Html.RenderThoughtsPartial(Model.EditCode) %>
Let the HTMLHelper determine which view to use based on the EditCode.
having a problem passing ViewData.Model to the partial views. It always is defaulting to null even if I equate it to a result query. I cannot access the strongly typed data because the Model is null. My current code is this,
ViewPage
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("header", this.ViewData.Model); %>
<% Html.RenderPartial("test", this.ViewData.Model); %>
<div id="userControls">
</div>
</asp:Content>
UserControl - header
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<testMVCProject.Models.information>" %>
<h2>
ACReport</h2>
<p>
id:
<%= Html.Encode(Model.id) %>
</p>
<p>
type:
<%= Html.Encode(Model.type) %>
</p>
UserControl - test
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<testMVCProject.Models.information>" %>
<% using (Ajax.BeginForm(
"pressureV2",
"Home",
new { id = ViewData.Model.id },
new AjaxOptions
{
UpdateTargetId = "userControls",
HttpMethod = "GET"
},
new { #id = "genInfoLinkForm" }))
{%>
<%= Html.SubmitButton("hey", "Lol") %>
<%} %>
Controller
public ActionResult header(int id)
{
var headerResults = from c in db.information
where c.id == id
select new information
{
id = c.id,
type = c.type
};
ViewData.Model = headerResults.FirstOrDefault();
return View(ViewData.Model);
}
public ActionResult pressureV2(int id)
{
var pressureVResults = from c in db.pressure_volume_tests
where c.id == id
select new pressureVT
{
bottomCVP = c.bottom_CVP,
topCVP = c.top_CVP
};
ViewData.Model = pressureVResults.FirstOrDefault();
return View(ViewData.Model);
}
In the comments you have said that the view is not strongly typed. Because of that:
<% Html.RenderPartial("header", this.ViewData.Model); %>
<% Html.RenderPartial("test", this.ViewData.Model); %>
will not work. If you strongly type your view to testMVCProject.Models.information and then pass an instance of that type from your constructor it will work.
Controller:
public ActionResult ShowAView()
{
Return View("WhateverYourViewIsCalled", new information());
}
You have a misunderstanding of the use of Html.RenderPartial helper.
When you use the RenderPartial you will show the view without requesting the model from the controller.
So you have to refactor your ViewPage and pass the good Model to your usercontrols:
Exemple:
Controller:
ActionResult MainView()
{
var mainviewobj = new MainViewObject();
var headerResults = from c in db.information
where c.id == id
select new information
{
id = c.id,
type = c.type
};
mainviewobj.info = headerResults.FirstOrDefault();
return view(mainviewobj);
}
View Code:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("header", this.ViewData.Model.info); %>
<% Html.RenderPartial("test", this.ViewData.Model.info); %>
<div id="userControls">
</div>
</asp:Content>
View Code Behind
public partial class MainView : ViewPage<MainViewObject>
{
}
Now the Model will not be null in your usercontrol.
But remember the usercontrol rendering partially dun execute the code in the controller
So you dun need the public ActionResult header(int id) in your Controller
Hope this helps.
Have you tried making the ViewPage generic as well?
The Controller doesn't get called when you RenderPartial - it is bypassed and the view is rendered directly. So whatever you want to pass in as a model needs to be done from the calling View.
I found this worked for me, reference the partial as you do, like so.
...form
#Html.Partial("_AboutYou", Model.AboutYou);
..end form
within the partial view at the top...
#model <namespace1>.<namespace2>.<namespace3>.CustomerInfo.AboutYou
#{
ViewData.TemplateInfo.HtmlFieldPrefix = "AboutYou";
if (this.ViewContext.FormContext == null)
{
this.ViewContext.FormContext = new FormContext();
}
}
I believe the problem might be that you're missing an element in the form with the name "id" so the parameter of the Action method is never populated with a value?
That way the query would always return null with the FirstOrDefault, hence the null Model.
Just my guess...