I have two grails domain classes
Class MultipleChoiceQuestion {
String question
static constraints = {
...
}
static hasMany = [options:MultipleChoiceOption]
}
and
class MultipleChoiceOption{
String answerOption
boolean correctOption
MultipleChoiceQuestion question
static constraints = {
...
}
}
I want my users to be able to create a question then add atleast 3 options without navigating/clicking on different screens.
My first question is must I generate view and start editing code?
And if the answer to question above is yes then my second question is, what's the best way to save a question along with multiple options in one form submit?
The generated code will have something like following for each option.
<g:textField name="answerOption" value="${answerOptionInstance?.answerOption}"/>
<g:checkBox name="correctOption" value="${answerOptionInstance?.correctOption}"/>
how can I have multiple such elements in one page?
Please see the wireframe to get an idea of what I want to achieve, my apologies for poorly created wire frame.
Click on the link for opening the image in your browser
http://cynosuredev.com/wf.png
maybe this site will help you
http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/
You don't have to use Grails scaffolding if you don't want to. Since this is a pretty specialized form, you should construct the HTML yourself. I've created a test project at github that shows a good design for this problem. Check it out.
Related
Most of the good references for MVC on web strongly suggest "views must be dumb". It should not contain any logic. This does not seems valid when I try to implement it.
Some of my views display only first name of student and some of them display only last name and some of them display full name. My database (and POCO and DTO) store name in separate components. I see best place to format the name is view.
My view changes on some actions on client side without hitting server. Example, on clicking some button, it hides some part of view and shows other and disable some controls. Or another button opens new window and takes some inputs and validates it. This input is never sent to server; it is only useful for some client side activities.
I have validations on server side. But just to save the hit to server, I also validate on client side.
Data binding with KnockoutJS.
Based on data (start and end date) received from server, I generate table on client side to display sections of that period slicing 1 hour each. This is something scheduling like GUI. I need to do date and time calculations in view to achieve this. When I was in stone age (ASP.NET WebForms), I was generating this table on server side; I know you are shocked. I shifted it to JS for performance.
In SPA, view hold most of the logic by fetching only necessary data from server through AJAX.
I can put many other similar examples here those force me to put some logic in view. Considering that view still holds logic and use of JS is increasing day by day, can we still say "views must be dumb" is a correct statement?
Some details explaining the same with respect to points above will help.
Notes:
Though my question is based on ASP.NET, I am expecting answers referencing to ONLY MVC as a design pattern; no matter what technology I use. So please do not suggest what is another way to do validations. Points above are just to note some of the cases where logic is necessary in view.
There might be something wrong in how I am implementing above points. But My only point is that, use of JS (and putting logic in views as a result) is increasing.
Everyone is welcome to contradict above points in case I am implementing it wrong way; just do not redirect entire discussion that way.
Edit 1:
#kayess: Yes, I have Models as well as ViewModels and this is obvious in MVC. Server logic that is strongly related to specific view and cannot be reused is put in ViewModels. Major part of domain logic which is reusable is put in Models. Even after having ViewModels, there are many things those I will prefer to do on client side. About narrowing the question, the basic answer to this question will be "Yes" or "No". Other details will be just to support the answer. I do not think this will attract opinions as there must be something about MVC views that I have not fully understood. The one answering the question just need to point that out to me.
I think generally by "views must be dumb" means specifically the server side part of the views. Having TypeScript/JS in a view is perfectly normal. I wouldn't however expect to have dozens of lines of C# in the view that is fetching records from a database.
However, having some very simple logic such as the following is pretty common:
#{
if(user.IsLoggedIn)
{
<span>You have new messages!</span>
}
else
{
<span>You need to login to view messages.</span>
}
}
However server side view code shouldn't get much more complicated than that because that breaks down the whole point of separation concerns and having appropriate abstractions and design patterns etc, and just becomes unmaintainable.
See also: Microsoft documentation on "Adding a View"
May it be any technology there are set of theories supporting different concepts, like you said view should be dumb there are advocates of model should be dumb.
Idea here is let your view model take care of the manipulation if any needed, and let your view refer to view model. So that change is centric.
And I believe you are alredy doing that.
Although this is an old question and has an accepted answer, I want to add some points not covered in any answers.
I think you are overlooking cases where more logic can be pushed to your domain model. For example, you mention the concept of "Name" and that you must use conditional logic in your views to decide whether to show first, last or full name. I have a class called Name in my domain model. It incorporates the logic of FirstName, LastName and FullName like so:
public class Name
{
public Name(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; }
public string LastName { get; }
public string FullName
{
get { return $"{this.FirstName} {this.LastName}"; }
}
}
In my UI I have have ViewModels with the whatever name property I need. When I convert my domain models to view models my conversion logic tells the ViewModel which property to use. If I need FullName I use Name.FullName. If I just need FirstName, I use Name.Firstname. At no point do I need to put conditional logic about names in my views.
In addition, you can use custom helpers, formatters and extensions to encapsulate reusable logic for views. For example, I have utilities to format phone numbers, addresses etc, so that I do not have to put this logic in every view that needs it. I also have a paging module in my UI that encapsulates paging so that I do not have to have paging logic in my views other than to call the pager.
Partial views are also helpful. For example, from the accepted answer, I would put the following in a partial view and just call it in each view, rather than repeating the conditional logic it in every view:
#{
if(user.IsLoggedIn)
{
<span>You have new messages!</span>
}
else
{
<span>You need to login to view messages.</span>
}
}
My point is there is a lot you can do to move logic out of views to keep them dumb.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I m working in MVC and some one recently has reviewed my code. On some places in my controller actions I was returning to other views, for example in below code in Index action I m returning to List view:
public virtual ActionResult Index(Student student)
{
// Logic
return View("List", student);
}
Why it is not a good practice ? I did not get any idea why this is wrong. Kindly guide me so I can correct this.
There is nothing wrong with returning a different view to the default action view. The only thing I can think that might be unsettling to some is it does not following the MVC paradigm of convention over configuration.
This may make it difficult to follow someones code if they have lots of actions with names that are different to their corresponding view names i.e:
public ActionResult Index(int id)
{
//logic
return View("StupidName");
}
Convention would have you think the index action would return the Index view, although it doesn't and now the programmer has to go look for the StupidName view. This may seem harmless for one action but if someone has written multiple actions that return differently named views it can be difficult to follow the flow of the project.
Alternatively you could ask the code reviewer why he thinks it is a bad practice. Communication is key in a team.
Personally I see nothing wrong with this as long as the logic for compiling the input for the view isn't duplicated.
If you have to copy a lot of code to ensure that the model for the view is correct, and this isn't really the responsibility of your action, you'd rather redirect to the action instead of calling the view directly.
If this is not the case, or there is a very specific situation, I don't see why this is a problem.
Consider these examples:
You have a error dialog view. If the model just consists of a single property defining the message, it is no problem to call the view directly;
If you have the same dialog, but in order to create the model you have to fetch some general information from the database, have some custom logic, etc., then it is probably best to call the (or create an) action doing this all for you. Also, the number of calls to that view may matter in your decision.
Try this :
public virtual ActionResult Index(Student student)
{
// Logic
return RedirectToAction("List");
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Can someone point me in the right direction of the correct feature in Grails to implement dynamically changing attributes in my views? For example, when an instance of a domain class is in a particular workflow step, I want certain field prompts, button labels, and data modify-ability to be specific for that step. I will probably store these attributes in another domain class, but I am not sure how to apply them when I am executing, say, the edit method on the instance of data. Is that were custom tags come in, or do I just replace all those attributes in my views with variable tags and pass the values in from the controller? A search term to get me started is fine. Thanks.
Within a controller action you can return a model (Map). The data from this model can be read within views:
class MyController {
def test() {
return [myData: 'hello', myOtherData: 42]
}
}
Within the view you can access the model in the following way:
...
<h1>${ myData }</h1>
<g:if test="${ myOtherData == 42}">
<p>${ myOtherData }</p>
</g:if>
...
If you want to return another view with a model from a controller you can use the render method:
render view: 'myview', model: [myData: 42]
See the section Models and Views from the grails documentation for more details.
Thanks for your reply #micha. Specifically, I am wondering what the best practice is for dynamically changing the visual aspects of a page(view). I think I answered my question by looking at the views from a dynamically scaffolded domain. For example, field prompts are all in the form:
<label for="last">
<g:message code="employee.last.label" default="Last" />
</label>
So you can calculate what all the prompts need to be in your controller/service, or query them from a database, and pass them in along with the data that goes into the fields. I was just checking if Grails anticipated this need and made it easier through some specific aspect of the architecture.
I am trying to build a controller that will enable the user to add/remove subcontent to an item.
Think of it like a document where you can add different types of sections, like headlines, paragraphs, images etc. (they each have their own attributes so they are in seperate tables in the SQL)
My question is where should I put the code to handle the different types of subsections within this "document controller"?
They are all attached to this "document"/entity through database relations, but should I make a "crudl" controller for each type or should I do a base kinda crudl and then let them all inherit this?
I've looked into "Models" and "service layers" - is that the right way to do it?
I am still rather new with MVC, using C# and ASP.net I was hoping for someone to give me a hint in the right direction.
Nb. please let me know if I should rephrase the question. Didn't know what to ask to get the right answer here.
Specs: I use EF 4.x and MVC3 will upgrade to latest when available, if needed.
In hope of some clever answers or guidance. Thanks in advance people. And yes, I have tried to Google too. Don't know what to search for, so I come here.
where should I put the code to handle the different types of subsections within this "documentcontroller"?
The code for this would ultimately go into a controller action which you then handle and update the database accordingly. There are multiple ways of doing this, you could be generic e.g.
[HttpPost]
public ActionResult AddSection(string type)
{
switch (type)
{
case "HEADING":
// add new heading to database
case "PARAGRAPH":
// add new paragraph to database
}
return View(type);
}
Or you could be specific e.g.
[HttpPost]
public ActionResult AddHeadingSection()
{
// add to db
return View("Heading");
}
[HttpPost]
public ActionResult AddParagraphSection()
{
// add to db
return View("Parapgraph");
}
The above is just really pseudo code to give you a rough idea of how you could do it with minimal effort. IN a real life situation you will probably be posting extra information along with it e.g. AddHeadingSection(HeadingModel model). It's really up to you how you go about implementing this.
Also, you might want to consider using AJAX over full postbacks it would make your app a bit slicker.
I have something like this:
Class person {
string name
string status
boolean working
boolean vacation
}
static constraints = {
name()
status(inList: ["Active","Inactive"])
}
What I need is to show the working and vacation fields in the create and edit views, only if Active is selected in status.
I searched and read alot but can't find a way, maybe I'm missing something since I'm new to grails. Any help is appreciated.
Thank you
This can not easily be done with Dynamic scaffolding. You will need to edit the generated views to add the logic in. See the GSP tag refference for if at
http://grails.org/doc/latest/ref/Tags/if.html
In your case something like
<g:if test="$person.active ==true">
Insert GSP code to edit data here.
</g:if>