using Grails 2.43 currently. I have two domain classes (State and County), and two Select dropdowns for State and County.
Is there a way with a GORM finder to have a dynamic query that will return the specific counties in a state, when that state is selected. Thereby excluding all other counties that are not in the selected State?
Form elements:
<g:select name="locationState" class="form-control" from="${....State.list().sort{it.orderNumber}}">
<g:select name="locationCounty" class="form-control" from="${...State.FindByName(it.orderNumber).counties}">
Here are the example classes:
class State {
static hasMany = [county:County]
String name
String value
int orderNumber = 0
static constraints = {
name nullable:false, maxSize:50, blank:false
value nullable:false, maxSize:100, blank:false
}
String toString(){
"$value"
}
static mapping = {
table 'state'
cache: 'read-write'
columns{
id column:'id'
name column:'name'
value column:'value'
orderNumber column:'order_number'
}
id generator: 'assigned'
}
}
class County {
State state
String county
static constraints = {
state nullable:false
county nullable:false, maxSize:100, blank:false
}
String toString(){
"${state.name} - $county"
}
static mapping = {
table 'county'
cache: 'read-write'
columns{
id column:'id'
county column:'county'
state column:'state_id'
}
id generator: 'assigned'
}
}
It depends on how you've associated your domain classes. If State hasMany County(ies) and/or County belongs to State, you can use the dynamic finders. For example:
// All Counties
County.list()
// All States
State.list()
//All Counties in State Vermont
State.findByName("Vermont").counties
//State for a county
County.findByName("Chittenden").state
If you're trying to make a somewhat dynamic form, you could show your State dropdown first and have the County dropdown inactive until the State is chosen. Then you can make an asynchronous call to get the counties for the State or if the full objects are already loaded, you could just populate the County select box with selectedState.counties.
See GORM Object Relational Mapping: http://grails.org/doc/latest/guide/GORM.html#domainClasses
Related
I don't know if this is something that is possible or not, but I'm having trouble finding the correct words to search for answers.
Let's say I have a "Location" model with these two properties. City corresponds to a column in the table with a foreign key to a lookup table of all cities in the local area. CityOther is a free-text field that allows users to enter any city name they want.
public int? City { get; set; }
public string CityOther { get; set; }
I have a Kendo ComboBox that's configured something like this:
#(Html.Kendo().ComboBoxFor(m => m.CityOther)
.DataTextField("Text")
.DataValueField("Value")
.Placeholder("Select City")
.Filter(FilterType.Contains)
//.DataSource(d => ...)
)
When I serialize the form, I see two inputs with the names CityOther and CityOther_input.
When an existing city from the picklist is chosen, the values look like this:
{ name: 'CityOther' , value: '3' }
{ name: 'CityOther_input', value: 'Springfield' }
When a free-text city (one not from the list) is entered, the values then look like this:
{ name: 'CityOther' , value: 'Orlando' }
{ name: 'CityOther_input', value: 'Orlando' }
I would like to configure it so that:
a value selected from the existing list would end up in the City field (which means I would change it to .ComboBoxFor(m => m.City)).
a free-text value entered would end up in the CityOther field, rather than XYZ_input.
Is this possible?
Would model binding fail if the value in City (a nullable int property) was a string value?
There is a class
class Trip {
static constraints = {
sTrip(blank: true, nullable: true)
}
static hasMany = [trip: Trip]
static belongsTo = [sTrip: Trip]
String name
String toString() {
return this.name
}
}
I need to add an optional field in which I can select the data already available for this class.
That is, many-to-many relationships with the class itself
I did this:
static hasMany = [trip: Trip]
static belongsTo = [sTrip: Trip]
But from displays only a drop-down list
How can I submit a multiple list?
You need to add the multiple="true" attribute to your select e.g.
<g:select multiple="true" name="item" id="item" from="['item1', 'item2', 'item3']" />
Then in your controller/service:
params.list( 'item' ).each {
println it
}
I want to use grails hibernate filter plugin to add a filter on of my domain class.
http://grails.org/plugin/hibernate-filter
Domain classes:
class Movie {
String name
String genre
String yearOfRelease
boolean deleted
}
class EditRequest {
String reason
String requester
Date requestDate
String status //can be 'PENDING', 'ONHOLD', OR 'COMPLETE'
static belongsTo = [
movie: Movie,
requester: User
]
}
There could be multiple edit request for a movie.
I have an API where I need to display all edit requests for all non-deleted movies.
How do I add hibernateFilter for non-deleted movies in my EditRequest domain class
I tried below in my EditRequest class, but non of them works.
1.
static hibernateFilters = {
deletedMovieFilter(condition:'deleted=false', default:true)
deletedMovieFilter(collection:'movie', default: true)
}
2.
static hibernateFilters = {
deletedMovieFilter(condition: 'deleted = false')
deletedMovieFilter(collection: 'movie', joinTable: true)
}
In Grails using GORM, I'd like to retrieve two possible values for a form dropdown. This particular instance is to only have two possible countries in a dropdown. I've set them in my Config.groovy
The GORM statement in this that I've done only returns USA and I'd like to return Canada also - so I have the findAll statement slightly incorrect. Can someone help me?
Country<g:select name="Country" from="${....country.findAllById("100225","100038").sort{it.orderNumber}}" value="otherstuff" class="form-control" required="" aria-labelledby="country-label"/>
Config.groovy:
country.usa=100225
country.canada=100038
Domain class:
class country {
String name
String value
int orderNumber = 0
static constraints = {
name nullable:false, maxSize:50, blank:false
value nullable:false, maxSize:100, blank:false
}
String toString(){
"$name - $value"
}
static mapping = {
table 'country'
cache: 'read-write'
columns{
id column:'id'
name column:'name'
value column:'value'
orderNumber column:'order_number'
}
id generator: 'assigned'
}
}
you should rather use findAllByIdInList(["100225","100038"]).
Also consider not writing such code within the view. Make it part of your model and prepare it in the controller.
Let's say I have the following domains:
class Store {
String name
static hasMany = [ products: StoreProduct ]
}
class Product {
String name
static hasMany = [ stores: StoreProduct ]
}
class StoreProduct {
BigDecimal discount
static belongsTo = [ store: Store, product: Product ]
static mapping = {
id composite: ['store', 'product']
}
In other words, there is a many-to-many relationship between Store and Product with an intermediate StoreProduct domain class to track the individual discount per store.
Grails has built-in support for one-to-many relationships, so you can pass in a list of IDs with the proper field name and the controller will automatically resolve the IDs to a list of entities. However, in this case it's a many-to-many with an intermediate domain class.
I've tried the following code in the Store edit view to allow a user to select a list of products:
<g:each in="${products}" var="product" status="i">
<label class="checkbox">
<input type="checkbox" name="products" value="${product.id}"/>
${product.name}
</label>
</g:each>
But Grails throws various errors depending what I use for the name attribute. I've also tried the following for the input name:
products
products.product
products.product.id
product[0].product
product[0].product.id
But none of them work properly.
My question is, is there any built-in support for this kind of relationship in Grails, particularly when it comes to the view?
Change your domain structure as follows:
class Store {
String name
Set<Product> getProducts() {
StoreProduct.findAllByStore(this)*.product
}
}
class Product {
String name
Set<Store> getStores() {
StoreProduct.findAllByProduct(this)*.store
}
}
import org.apache.commons.lang.builder.HashCodeBuilder
class StoreProduct implements Serializable {
BigDecimal discount
Store store
Product product
static mapping = {
id composite: ['store', 'product']
version false
}
boolean equals(other) {
if (!(other instanceof StoreProduct)) {
return false
}
other.store?.id == store?.id &&
other.product?.id == product?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (store) builder.append(store.id)
if (product) builder.append(product.id)
builder.toHashCode()
}
}
From the domain classes above:-
Either one of the domain (Store or Product) has to take the onus of the relationship by having a belongsTo. Refer API for details.
Domain class (StoreProduct) with composite primary key should implement Serializable.
Please also provide a stacktrace to debug if available.