Bread crumbs In grails - grails

I want to know the usage and implementation of the bread crumbs in grails.
i have some gsp(view) pages ,Home page is default i have 6 categories and in that 6 sub pages i need to show the navigation path in my pageslike
home/grocery/sub grocery....
home/finance/subfinance...
i need to show the page navigation.
<div id="heder_content">
<g:if test="${session.user }">
<div id="bread_crumbs"style="position:absolute;top:0px;left:474px;height:80px;width:800px">
</div>
</div>
</g:if>

What would you like to achieve exactly? You can try creating a taglib where you read the controller name and the action, and passing some parameters you can display the name of your product for example.
I mean something like this:
<g:breadcrumb title="${product.name}" />
and in your taglib file:
class BreadCrumbTagLib {
def breadcrumb = { attrs ->
def title=attrs.remove('title')
out << '''<div id="bread_crumbs"style="position:absolute;top:0px;left:474px;height:80px;width:800px">${controllerName} / ${actionName} / ${title} </div>'''
}
}
My example is very simple, but I hope you get the idea! If you need something more complex, I suggest you to get a look at: http://adityakalia.wordpress.com/2011/01/10/breadcrumbs-framework-for-grails/

Related

Grails Field Plugin: Select tag for one-to-many relationships

I'm using Grails 2.2.3 and Fields plugin 1.3.
I want to customize fields to manage one-to-many relationships using select tag.
In views/_fields/oneToMany/_input.gsp I have:
<g:select name="${property}.id" from="${type.list()}" optionKey="id" value="${value}" class="form-control one-to-many" noSelection="['null': "${label}"]" />
But type is a set, so I can't use list function.
How can I retrieve target domain class?
As long as you use a Map to declare the relationship, for example:
static hasMany = [ books: Book ]
You can get the list of the referenced domain, which is the key from the hasMany property of the bean, so the from attribute should change to
from="${bean.hasMany[property].list()}"
Alternatively you can pass the list to the _input.gsp template prefixing the variable name with input-, e.g.
<f:field property="books" input-domainList="${bookInstaceList}" />
In the _input.gsp template you can use the variable as follows:
from="${domainList}"
or mixing both methods:
from"${domainList ?: bean.hasMany[property].list()}"
I found this solution for the problem, this code work fine with one to many and one to one
<div class="input-group">
<g:select name="${persistentProperty.toString().contains('one-to-many')?property:property+'.id'}" value="${value?.id}" required="${required}"
noSelection="${['null':'Escriba...']}" class="select2 col-md-6"
multiple="${persistentProperty.toString().contains('one-to-many')?true:false}" from="${grailsApplication.getDomainClass(persistentProperty.properties['associatedEntity'].toString()).clazz.list()}"
optionKey="id"></g:select>
</div>
This solution can be helpful. I found in the documentacion of Fields Plugin, the persistentProperty is a class type DomainProperty but their methods doesn't works and I found the correct class is org.grails.datastore.mapping.model.MappingFactory
you can use .toArray() method on your Set instead of .list().
ale
You can use the code below to identify the Element of your collection
def className = bean.hasMany[property].properties.typeName
See my "views/_fields/oneToMany/_input.gsp" implementation:
<%# page defaultCodec="html" %>
<%
def className = bean.hasMany[property].properties.typeName
def simpleName = Class.forName(className).simpleName
def beanSimpleName = bean.class.simpleName
def createUri = "/${simpleName.toLowerCase()}/create?${beanSimpleName.toLowerCase()}.id=${bean.id}"
%>
<a id="add${simpleName}" name="add${simpleName}" href="${createLink(uri: "${createUri}")}">
Add ${simpleName}
</a>
<ul>
<g:each var="item" in="${value}">
<li>
${item}
</li>
</g:each>
</ul>

Controller is there, but showing "Error code 404 page not found" in grails

new.gsp:
<html>
<head>
</head>
<body>
<g:form name="myForm" controller="New" action="index" params="username:username">
<div>
<fieldset class="form">
<label for="name">Name:</label>
<div>
<g:textField name="username" value="${params.userName}"/>
</div>
</fieldset>
</div>
<g:submitButton name="Submit" value="Submit" />
</g:form>
</body>
<html>
NewController.groovy:
package sample
import com.sun.org.apache.bcel.internal.generic.NEW;
class NewController {
def index = {
if($params.userName){
render(view:"/login.gsp")
}
}
}
login.gsp is a simple page, having a simple welcome note.
if some body the solution please reply,
thanks in advance.
by prasanth
Change your controller name to "new" instead of New in
It will work.
Or else you can modify your "save" action in controller, so that when you click on save button new page will be rendered.
There are a few issues in the posted code that will cause you problems:
You're accessing the parameters with $params instead of params. The $ character is only necessary when you are in a GString. e.g. def foo = "your username is ${params.userName}"
Your view is named new.gsp but your action is named index. Grails will by default look for a view matching the action name in a directory named for the controller. In other words, since you don't tell it explicitly to render /new.gsp grails will look for /new/index.gsp. You can either rename the view to /new/index.gsp or tell grails to render the view new in the index action.
When attempting to render your logged in page, you're calling render(view: 'login.gsp'). The gsp extension is not necessary when calling the render tag. You're intended to use the grails view name, not the filename. render(view: 'login')
If you're using a recent version of grails (>2.0) you should be using controller methods rather than closures. e.g. def actionName() { } as apposed to def actionName() = { }. The reasoning is in the grails documentation.
Here's what it could look like with all the issues addressed:
rename new.gsp to /new/index.gsp. rename login.gsp to /new/loggedIn.gsp.
controller:
class NewController {
def index() {
if (params.userName) {
forward action: 'loggedIn'
return // render and forward don't end flow control
}
}
def loggedIn() {} // no logic, automatically renders '/new/loggedIn.gsp'
}
Add a handler to your controller named login.
def login = {}
If the view file is new.gsp then you need your action to also be new or else have a URL mapping (in UrlMappings.groovy) to do something like:
"/new" {
controller = 'new'
action = 'new'
}
Or you can set
static defaultAction = 'new'
...in your NewController.
Then Grails will find the appropriate action on your controller.
if your action is called index, you can acces the page on
localhost:8080/webapp/NewController

Open the same webpage, but with another content

Im developing a webapp that is feeded via a server. Its index presents some shops deals, having all of these deals ann id. In the .gsp, i have this code:
<div id="content">
<g:each in='${promos}' var='promo'>
<div id="up_box"></div>
<div class="deal_container">
<div class="images_container"><img src="${createLink(action:'showImage',controller:'image',id:promo.fotoPrincipal.id)}" width="120" height="105" />
</div>
<g:link controller='promotion' action='openPromo' params="[promoid:promo.id]">
<div class="oferta">${promo.name}</div>
</g:link>
<g:link controller='promotion' action='openPromo' params="[promoid:promo.id]">
<div class="flecha">
</div>
</g:link>
</div>
That means, when I click in one of the links, it will open an url like this:
app/promotion/openPromo/3
In case the deal with the id "3" is clicked. I have a "general" deal details page. I want that page to load always, and fulfill its details dinamically, depending the deal the user clicked. How can I do that?
I don't know if I have been clear in my explanation, if i haven't please ask.
Thank you!
Both links will be handled by the openPromo action in the PromotionController and will be passed the id of the promo as promoid.
You can then load the appropriate promo along with any other related offers you want the user to see and give these to the view. Eg:
class PromotionController {
def openPromo() {
Promo promo = Promo.get(params.promoid)
// Load any other relevant data or offers
render (view:'openPromo', model:[promo:promo, <any other model data here>]
}
}
You can then use the model data in your gsp.
You can do it adding that general info to a Template and then render it from the Controller like this
// render a template to the response for the specified model
def theShining = new Book(title: 'The Shining', author: 'Stephen King')
render(template: "book", model: [book: theShining])
You´ve got more info about the render in this link from the Grails documentation.
http://grails.org/doc/latest/ref/Controllers/render.html
It´s easy to do it, you can add a createLink like the first ones whith calls to an action who will render that template.
Hope it helps ;) and good luck!
I did it this way, after asking my workmate:
def openPromo() {
Promotion promo = Promotion.get(params.promoid)
[promo:promo]
}
Almost what you said David, but without rendering, if I name openPromo my gsp.
Thank you!

Rails: Rendering Multiple index.html.erb on a Single Page

I am using tabs and want to load multiple index pages into tabs. For instance:
class AnimalsController < ApplicationController
def index
#dogs = Dog.all
#cats = Cat.all
end
end
Then in my views/animals/index.html.erb
<ul class="tabs">
<li>Dogs</li>
<li>Cats</li>
</ul>
<div id="#dogs">
<%= render #dogs %>
</div>
<div id="#cats">
<%= render #cats %>
</div>
Is refactoring out into a partial the only way to achieve this?
I'd like to have them loaded statically at once and not have to resort to doing an Ajax.load() when the tab is clicked.
You have your answer in the question itself. Why don't you just use javascript to hide the two partials and call them when their respective tab is clicked? You don't need ajax for this at all :)
Since you did not mention the javascript library that you use, I will give a generic solution using jquery:
Also you need not add a # to your respective div's ids. Change it to this:
<ul class="tabs">
<li id="dogs">Dogs</li>
<li id="cats">Cats</li>
</ul>
<div id="dogs" class="subTabs">
<%= render #dogs %><hr />
</div>
<div id="cats" class="subTabs">
<%= render #cats %><hr />
</div>
$(document).ready(function() {
$('.subTabs').hide(); //Hide the subTabs as soon as the DOM is loaded.
$('li').live('click', function(e) {
$('.subTabs').hide(); //Calling this again so as to remove an already loaded
tab, if any. You can refactor this part to make it
even simpler.
$('body').find('.subTabs').attr('id',$(this).attr('id')).show();
//This finds the ".subTabs" whose id is the same as the "li" id that
was clicked and shows it. Ofcourse, even this can be made even more
compact had i known your entire DOM structure.
});
});
Edit:
You also have to make sure that you style it using CSS to make it look more like tabs if you haven't already. :)
Hope this helps. :)
You typically only want to use a partial if you are using the same or almost the same code in more than one place.
When you say "index page", do you really want to use the same code that is used in an index of another controller? If so, then a partial is the best strategy.
Don't use JavaScript to solve a layout / code organization problem.

Grails: problem with paging and ordering in a view template

How do I structure my pages and partial templates so that Ajax will play nice with <paginate> and column sorting?
I currently have a search.gsp page with a remoteField that calls a controller to update a template. This all works fine. However, the column sorting and paging actions cause my search.gsp to be completely replaced by the template view.
From my search.gsp:
<div id="searchBox">
Enter a key or phrase: <g:remoteField name="searchBox"
update="resourceSearchResultPanel" paramName="q"
url="[controller:'resourceEntry',action:'searchForResources']"
/>
</div>
<div id="resourceSearchResultPanel" />
My controller handles the search request like so:
def searchForResources = {
params.max = Math.min(params.max ? params.max.toInteger() : 10, 100)
params.offset = params.offset ? params.offset.toInteger() : 0
log.debug "Handling search post action"
def q = params.q ?: null
log.debug "Search phrase is $q"
def searchResults
if (q) {
searchResults = [
results: ResourceEntry.search(q,[offset: params.offset, max: params.max]),
resultCount: ResourceEntry.countHits(q),
q: q.encodeAsHTML()
]
}
render(template:"resourceSearchResultPanel",model:searchResults)
}
The _resourceSearchResultPanel.gsp is just a table with this <paginate> tag:
<g:paginate action="searchForResources" total="${resultCount}" params='["q":"${q}"]' />
The problem is that when the <paginate> tag calls the controller, the entire page is refreshed with the contents of the _resourceSearchResultPanel.gsp template, while I just want the _resourceSearchResultPanel.gsp itself to be refreshed inside search.gsp.
There's no update attribute like there is in the remoteField tag...
The paginate tag doesn't support generating ajax links so you'll have to write your own verison of the tag that calls remoteLink instead of link.
cheers
Lee
I would suggest to you remote pagination plugins for Grails. This would suffice your requirement. For more details please refer to following site:-
http://www.grails.org/plugin/remote-pagination
Please feel free to revert incase of any concern.

Resources