What widget constraints are valid for Grails domain classes? - grails

Can you tell me the list of valid values for the widget constraint below (some-widget), e.g.:
static constraints = {
someField(widget: 'some-widget')
}
The documentation seems to be missing. Related, do you know of any plugins that can work directly with this constraint?

You can have a look there
It's an old list, but it's still valid, I think

From what I can tell, the widget property is only used for scaffolding and is referenced in the renderEditor.template. In that file, it appears that the widget property has some pretty narrow uses depending on the type of object you are scaffolding.
The good news, however, is that you can supply your own renderEditor.template file and edit it to work however you want. Just create a file at ${basedir}/src/templates/scaffolding/renderEditor.template and Grails will pick it up when you generate the views.
(See DefaultGrailsTemplateGenerator for more information.)

Related

Grails 3.3.2 accessing custom meta constraints

In a grails 2.4.4 project, I was able to define my own custom constraint (called 'supportsToUrl') on a domain property and use it as a tag to control rendering logic in my GSP.
GSP rendering code:
if(domainClass.constraints[p.name].getMetaConstraintValue('supportsToUrl'))
Domain class constraint:
static constraints = {
embedCode(nullable:true, blank:true, unique:false, display:true, supportsToUrl:true)
}
In Upgrading from Grails 3.2.x in section "Grails Validator and ConstrainedProperty API Deprecated" there is discussion about how this functionality has been moved. However, I did not see anything in the new API that refers to meta constraints.
My question is: How do I access custom constraints in Grails 3.3.2?
You could access meta constraints still in Grails 3.3.*
From Validateable trait getConstraintsMap().
Example list of all properties which supports url (supportsToUrl: true)
Set<String> supportsUrlProperties = new HashSet<>()
Map<String, Constrained> constraints = domainObject.getConstraintsMap()
if(constraints) {
constraints.values().each { Constrained constrained ->
DefaultConstrainedProperty propertyToCheck = constrained.properties?.property as DefaultConstrainedProperty
if(propertyToCheck) {
def supportsToUrlConstraint = propertyToCheck.getMetaConstraintValue('supportsToUrl')
if (supportsToUrlConstraint != null && BooleanUtils.isTrue(supportsToUrlConstraint as Boolean)) {
supportsUrlProperties.add(propertyToCheck.getPropertyName())
}
}
}
}
Be aware, that it sees only constraints from domain/entity (abstract or not) which are marked with this Validateable trait. Class hierarchy won't apply - when root/super class implements it, then top class's constraints still are not visible, until you mark it also as Validateable.
So based on the ConstrainedDelegate class, I think the short answer is that it's not possible. ConstrainedDelegate does not expose the metaConstraints map or the attributes map of DefaultConstrainedProperty. I will leave the question open though in the hopes that someone more knowledgeable with the Grails architecture roadmap can explain why.
In the meantime, I was able to hack together a solution by re-purposing the format constraint and comparing the format against my predefined tags. Although I'd love to hear other ideas on how to achieve my original goal as this is pretty clearly not how format was intended to be used.

Determining available runtime attributes for a UI element in Interface Builder

I've been playing around with a button in my storyboard, and had a hard time getting a border around it, until I found a page where it showed how to add a User Defined Runtime Attribute. I was able to make the button look as I wanted, but I wanted to know if there was a way for me to view the list of available attributes for a particular Object.
Clicking the "+" to add a new attribute doesn't provide any kind of auto-complete to show the available ones, and looking through my project code doesn't seem to reveal anything either, not surprisingly. Is there somewhere I can find all of the available attributes for all/any Objects in Xcode? Searches here on SO and in general have not shown any useful results so far.
You can achieve the same thing from code, so just check the properties of UIButton (which is available in the documentation and with autocomplete) and you're good.
You also have to make sure you are checking the properties on an UIButton instance and not the class properties.
User defined runtime attribute is a list of key paths that NIB loading subsystem uses through unarchived process. After initialisation message -setValue:forKeyPath: will be send to your unarchiving object for each key path from this list. So available attributes are not more than set union of all methods with selector sort of -setAttribute: and ivars with "_attribute" or "attribute" name.
All that public attributes you may find at public headers or documentation.
There's also possible to set private attributes, but it's not good practice. For instance, you may find all ivars by breakpoint execution inside any method and look inside "self".

Getting bean properties names in Grails

I'm trying to write a tag, which will render my bean properties and corresponding values. I want the default behaviour be to render all properties from the bean. So I need somehow get all property names from passed bean.
I figured that I could use properties map, but despite bean properties, there are also other things and I'd have to manage it by hand which may be error prone.
I also thought of using DefaultGrailsDomainClass which is handy for domain classes, but is useless for command objects.
Have you ever done something similar and came up with something useful?
Like said here, there are also persistentProperties. But I believe you need GrailsDomainClass.properties - don't confuse with Groovy properties, the former are for domain class.
For rendering, GrailsDomainClassProperty.naturalName will also be useful.
I've done similar thing by using properties, no problem. My code was:
value.properties.entrySet().each { Map.Entry it ->
println "$it.key = $it.value"
}

Distinguishing between Grails domain-class fields and getBlah() methods via GrailsDomainClassProperty

I'm writing a Groovy script (as part of a Grails plugin) and I want to get a list of properties for a GrailsDomainClass that a user of my plugin might define. I can do this using domainClass.properties (where domainClass is a GrailsDomainClass).
However, suppose a user has the grails domain class:
class Example {
String name
static constraints = {
}
def getSomeNonExistingProperty(){
return "Not-a-real-property"
}
}
In this case, domainClass.properties returns a list with both name and someNoneExistingProperty
I understand that this is because of Grails is generating a read-only property on-the-fly for use where someone has a getBlah() method. That's great, but in my script I want to perform some actions with the "real" properties only (or at least non read-only properties).
That is, I would like some way of distinguishing or identifying someNonExistingProperty as a read-only property, or, alternatively, as a property generated by Grails and not entered explicitly as a field in the domainClass by the user of my plugin.
I've looked at the GrailsDomainClassProperty Class and it has a range of methods providing information about the property. However, none of them appear to tell me whether a property is read-only or not, or to allow me to distinguish between a field defined in the domainClass and a field created on-the-fly by Grails as a result of a "getSomeNonExistingProperty()" method.
Am I missing something obvious here? Is there a way of getting a list of just the explicitly user-defined fields (eg name, in the above example)?
I believe transient properties are what you are trying to exclude
I've run into this problem a few times, and instead of trying to work around it I typically just end up renaming my getX() method. It's probably the easiest option.
Edit:
Alternatively, I wonder if you could use reflection to see which methods are defined on the class, and while iterating over your properties see if the property has an explicit getter defined, and omit it. I'm not very familiar with reflection when it comes to Groovy and Grails, especially with the dynamic methods, but it's a possible route of investigation.

Grails internals : Auto mapping and Domain object creation

I am trying to make a taglib to represent an object (to read and display at the UI). When creating an object (save method in the controller), I see the domain class and association are created by the auto assignment of parameter
def Book = new Book(params)
It also maps complex types (for eg: joda time). I wonder about the naming convention necessary to facilitate this mapping. Out of curiosity, can someone also point where in the grails source code I could see how grails handles this mapping. I'm still learning Spring and probably this would be a good exercise.
Thanks,
Babu.
AFAIK the naming conventions are rather straightforward. If there's a field params.foo and the object you are binding to has a field foo, it will bind the value, assuming the type conversion works properly. If there's a params.bar.id set with an Long value and your object has a complex property of type Bar, it will lookup this instance and inject it.
If you need more control over the binding process, you might want to use bindData.
If you are interested into the details of the binding process, have a look at Java's PropertyEditor as this is what is being used in the background. I wrote a blog post on how to create and register PropertyEditors a while ago, maybe it helps you getting started with that stuff.

Resources