What are Partial Views? - model-view-controller

I've been using Codeigniter in order to get accustomed to the Model-View-Controller architecture, and to try and speed up the process of making and implementing sites.
I keep seeing references to "Partial Views" but can't find a definition for the term.
Can anyone tell me what a partial view is, and where it is used?

A partial view is just a sub-view that you can include in a parent view. Let's take a look at a common example:
// Controller:
$data['myvar'] = array('element1', 'element2', 'element3');
$this->load->view('myview', $data);
// Myview:
<ul>
foreach ($myvar as $var) {
$this->load->view('partialview', array('var', $var));
}
</ul>
// Partialview:
<li><?= $var ?></li>
This is useful to repeat content according to a list.
Note that nothing differs between a view and a partialview, it's just the way you include it that defines the term.

The best way to describe a "partial view" is to think of it as a template, it displays a chunk of html with Model data passed to it.
Good examples of where to use one would be where you plan on displaying the same html over and over, like a menu or a page header or even better yet use them to display content requested using ajax.
Basically you call an action on the controller that returns the partial view from lets say jQuery and then put the returned markup into a select or div tag. Here is an example of doing that from my blog easy ajax with aspnet mvc and jquery, yes I know it asp.net mvc not php and codeigniter, but the principal is the same.

Related

Update template inside a view rendered from another controller

I am looking for the way to refresh a template inside a view rendered from another controller than the template's controller, I mean:
I got two controllers AdminController & UserController. And two gsps /admin/listUsers & /user/_searchResult.
Then a want to render view listUsers who have inside the template _searchResult and all right.
Now, i want to refresh the template _searchResult, but cant find how. I tryed calling render(view:"/admin/listUsers", template:"/user/_searchResult", model:[searchResult:result])
AdminController.groovy
#Secured(['ROLE_ADMIN'])
def listUsers(){
//...
}
UserController.groovy
#Secured(['ROLE_ADMIN'])
def search(){
//search users for the givven params and send result by chain if there's an action or update a template if it's needed
//in my case this method need to update the template _searchResult
}
#Secured(['ROLE_ADMIN'])
def searchResult(){
//...
[searchResult:result]
}
listUsers.gsp
//...
<formRemote name="searchForm" url="[action:"search", controller:"user"]">
//Some fields for the search
//I need to place here some hidden inputs to send which
//template i want to update or action to redirect
</formRemote>
<g:render template="/user/_searchResult"/>
//...
_searchResult.gsp
//Just itterate and print the search result in a table
I hope I have explained the problem correctly, thanks!
I don't think I entirely understand your question, but I think the source of your confusion is that the way you are naming things doesn't follow regular conventions and you're not using the right tools for the job. Let me explain...
The methods on Controllers are called Actions. They send some data (the Model) to a View to be rendered into HTML. Views can be composed from smaller, reusable fragments called Templates. (sorry if I sound like I'm being condescending here, but I'm just trying to make sure we're all on the same page).
Now, what you've called templateA is actually a View, not a Template. You're correct that templateA (your View) can call templateB to render some markup, but then having the templateB try to call a method on another Controller doesn't make sense. That's not how things flow.
If you have some logic that needs to be executed after you've sent your Model to the View, you want to use a Tag Library (http://grails.org/doc/latest/guide/theWebLayer.html#taglibs).
To summarise, here's a quick recap.
A request should only call one Action, which sends the model to only one view.
If you need to reuse logic between Controllers, move that code to a Service.
If you need to reuse markup between Views, move that markup to a Template.
If you have logic that you want to have executed after you've sent the Model to the View, use a Tag Library.
Hopefully this will point you in the right direction.
--- UPDATE ---
OK, with the real code I can see better what you're trying to achieve. Firstly, as you're using the <g:formRemote> tag, you should have a good read of the docs at http://grails.org/doc/latest/ref/Tags/formRemote.html to understand what it does.
What you will have here is 2 separate requests. The first will be a regular page load by your browser, which is handled by the listUsers() action. Once the page is then finished loading, the user will enter a search term and hit the submit button. This will fire off a second ajax request, which will be handled by the search() action. This action could use the _searchResult.gsp template to render a HTML table to display the search results. When the browser get this, it will insert it into the DOM where you've told it to put it using the "update" attribute of the <g:formRemote> tag.
The important thing here is that from the server's perspective, these are 2 separate requests that are completely independent. They both first call an action, then send a model (a Map containing some data) to a view, which renders/merges the data with HTML and sends it back to the browser.
The difference between the 2 is that the first is a complete page load by the browser, whereas for the second request, the browser only loads a small chunk of HTML (the search results table) and updates the page content without reloading it.
So your code would look more like this...
AdminController.groovy
#Secured(['ROLE_ADMIN'])
def listUsers() {
render(view:"/admin/listUsers")
}
listUsers.gsp
<g:formRemote name="searchForm" update="insertSearchResultsHere"
url="[controller: 'user', action:'search']">
<input name="searchTerm" type="text" />
</g:formRemote>
<div id="insertSearchResultsHere"></div>
UserController.groovy
#Secured(['ROLE_ADMIN'])
def search() {
// use the search term to get a List<User>
render(template: "/user/searchResult", model: [users: users])
}
_searchResult.gsp
<table>
<g:each var="user" in="${users}">
%{-- Iterate through your search results --}%
</g:each>
</table>
I solved it by placing the attribute update and rendering the template alone:
gsp:
<formRemote name="searchForm" url="[action:"search", controller:"user"]" update="divToUpdate">
//Some fields for the search
</formRemote>
<div id="divToUpdate">
<g:render template="/user/_searchResult"/>
</div>
Controller:
def search(){
render(template:"/user/_searchResult", model:[searchResult:result])
}
When i asked this question, i was new on Grails community and i was confused with the use of remoteFunction and tags that use it like remoteForm. But i had this confusion because of i had not read the documentation. So in my case, the solution was search for documentation about how to use remote tags and render. Thanks to #AndrewW for show me the way.

MVC3 Finding a control by its Name

I have a C#.Net web app and I am trying to access one of the HTML/ASP Text Boxes in the Controller for the Edit View of my Proposal model. In a non-MVC app, I was able to do this using Control.ControlCollection.Find(). Is there an equivalent for a MVC3 project?
You ask for an equivalent of Control.ControlCollection.Find() in MVC?
In MVC your controller is not aware of controls.
The controller just receives data via parameters and returns data via the function result.
What do you want to do with the control in your controller code?
If you want to access the value, you should bind it to a parameter:
View:
<input name="MyControl" type="text" />
Controller:
public ActionResult MyAction(string MyControl) {
// MyControl contains the value of the input with name MyControl
}
The MVC pattern was designed to keep things separated.
The View has no knowledge of the controller at all
The Controller only knows that a view exists and what kind of data that it needs. It do not know how the data is render.
Hence, you can never get information about controls/tags in the view from the controller. You need to use javascript/jQuery in the view and invoke the proper action in the controller.
In an MVC-application you don't have controls like in a webform-application.
In MVC you collect your required data in the controller and pass it to the view.
Typicaly the view is a HTML-page with embedded code.
In opposite to controls in webforms which produce HTML and handles the post-backs in MVC you have to do all this manually. So you don't have controls with properties and events wich you can access easily in the controller and you have to handle all your posts with your own code.
Thats sounds as it is a lot of more work - and indeed it could be if you implement the behaviour of complex controls - but MVC applications are much better to maintain and you have 100% influence to the produced HTML.
Well probably i am late for this but it should help others in future...u can store ur value in hidden field in view and then access that value in controller by following code..
Request.Form["hfAnswerOrder"].ToString();
Point - hfAnswerOrder is the ID of the hidden field
My Control in cshtml page..
#Html.Hidden("hfAnswerOrder", Model.Answers.ToList()[0].AnswerOrder)

.Net MVC3 Getting a Reference to the Page from a Controller

What I'd like to do seems pretty simple. I'd like to specify the page title in my #Page directive on a view, like so:
<%# Page Title="About This Site" ... %>
Then, I'd like to get that page title into the ViewData, so that it could be used in the master page, like:
<head>
<title>The Awesome Site | <%=ViewData["Title"]%></title>
And also in the View itself like:
<h1><%=ViewData["Title"]%></h1>
I am already inheriting a custom controller for all of the page controller methods. So I'm hoping that there's something I can do in the controller to transfer the Page.Title property into the ViewData (or maybe I'll use the ViewBag). I just can't seem to find any route to reference the Page from within the Controller.
Is this possible? Is there a different approach I might want to consider.
See "generic errors" post on this for a clean way to do this.
Passing data to Master Page in ASP.NET MVC
you should not be referencing anything from a "page" from a controller. The two are completely separate by design. You need to package your data and then send it to the view.
Another way (more like what you are requesting) is that you use
#{
ViewBag.Title ="my view title";
}
Then the master page uses that value wherever you want it.
I think you might be looking for Html.Title().
You can write this to any part of the page:
<title><%: Html.Title() %></title>
This will pickup the title from your view and insert it into your master page as required.

Help with understanding what goes in Controller vs. View in MVC

I'm new to MVC and I'm introducing myself through the Codeigniter framework. As a practice application I'm creating a simple blog application that gives the ability to create, view, edit, and delete posts.
For the "edit post" page, I'm using the same view file as my "create new post" and simply populating the form fields with the data I'm getting from my model when the user is editing an old post.
This seems all fine and dandy but I'm a bit confused on what logic is stored in the Controller vs. View. I obviously need some logic that tells the form to pre-populate the form fields (if I'm editing a post) or to leave everything blank (if it's a new post). There's also other things such as the view page needs to know what title to display at the top of the page: "Create New Post" or "Edit Post".
Where does this logic go? Does it go in the View? Or does it go in the Controller? and Why? I started putting all that logic inside the view file because I've read that I should keep the controller code minimal, however I now have a big php code block at the top of my view file that's dealing with variables and I'm not sure if this is the correct approach.
Any advice would be much appreciated!
I obviously need some logic that tells the form to pre-populate the form fields (if I'm editing a post) or to leave everything blank (if it's a new post).
Check out the set_value() function in the Form Helper. You can do something like this in your view:
<input type="text" name="subject" value="<?php echo set_value('subject', $subject); ?>" size="50" />
If it's a new post, pass empty string as $subject when loading the View from the Controller.
If it's editing, pass the subject of the post that is being edited as $subject.
Also, if a user submits the form and there are errors and you need to reload the form, set_value() will return what the user just posted (i.e. $_POST['subject']).
There's also other things such as the view page needs to know what title to display at the top of the page: "Create New Post" or "Edit Post".
Just pass a variable named $page_title from your Controller to your View, and set the value accordingly. This is pretty common, especially when you start building reusable templates.
Where does this logic go? Does it go in the View? Or does it go in the Controller? and Why?
There should be almost no logic in the View. Maybe simple if/else statements if you must, and loops to iterate through arrays of data.
Even Controller should not have much logic in it. It is mainly responsible for acting as a middle-man between the Models, the Views and the libraries.
I've read that I should keep the controller code minimal
That has to do with Controllers vs. Models, not the Views. It is good practice to keep Controllers smaller, and put as much of the logic as possible into the Models and the libraries. Also referred to as "Skinny Controllers, Fat Models".

In a View page within MVC, what is the preferred way to deal with empty variables

When using the MVC design pattern I usually try to make my view files as simple as possible.
Therefore in my View I try not to have lots of code like this:
if page title exists
display page title
else
display 'default page title'
end if
Instead, in my Controller I might use code like this:
if no page title is specified
page title = 'default page title'
end if
load the view (pass page title as a parameter)
Is this the best way to tackle this issue?
Keeping this if-else condition in the controller level is a better idea than moving into views. (if you can otherwise it's alright)
It will make your views look good !!!!

Resources