grails 3 gsp using domain object constraints failing - grails

In grails 2 we were able to reference the domain object constraints in a gsp as to keep the html 5 configration dry. On grails 3 (tried both 3.1.10 and 3.2.0.RC1) I get an error for code I tested in grails 2 successfully. I am trying to reference the constraint matches in the attribute phone and use that for the HTML 5 pattern. The scaffolding use to generate this code but for Grails 3 the scaffolding generates use the fields plugin so I cannot see that code. Any ideas?
Here is the domain object code:
class Disruption {
static constraints = {
phone(matches:/^[0-9]{10}$/, nullable:true)
email(email:true, nullable:false)
}
String name
String phone
String email
Here is the gsp code:
<div class="form-group ${hasErrors(bean: disruption, field: 'phone', 'error')}">
<label for="phone" class="control-label col-sm-3">
Phone
</label>
<div class="col-sm-2">
<g:textField name="phone" style="width: 7em" class="form-control" title="Phone 10 digits" pattern="${disruption.constraints.phone.matches}" maxlength="10" placeholder="##########" value="${disruption.phone}"/>
</div>
</div>
Here is the exception:
URI
/disruption/create
Class
java.lang.NullPointerException
Message
Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error processing GroovyPageView: [views/disruption/create.gsp:92] Error executing tag : Error evaluating expression [disruption.constraints.phone.matches] on line [58]: Cannot get property 'phone' on null object
Caused by
Cannot get property 'phone' on null object

Domain Objects need to use the constrainedProperties and Command Object need to use the constraintsMap see examples below.
<g:textField name="phone" style="width: 7em" class="form-control" title="Phone 10 digits" pattern="${disruption.constrainedProperties.phone.matches}" maxlength="10" placeholder="##########" value="${disruption?.phone}"/>
OR for Command Objects
<g:textField name="phone" style="width: 7em" class="form-control" title="Phone 10 digits" pattern="${searchCommand.constraintsMap.phone.matches}" maxlength="10" placeholder="##########" value="${searchCommand?.phone}"/>

Related

Template Parse Errors not matching HTML

I have been using mdTooltip and was running into issues so I am in the process of using MatTooltip in my project. When I run my app tho, I keep getting the following error
core.js:1449 ERROR Error: Uncaught (in promise): Error: Template parse errors:
Can't bind to 'mdTooltip' since it isn't a known property of 'input'. ("ass="form-control" (blur)="submitAnswer(item.$key, updatedata.value)"
[ERROR ->][mdTooltip]="item.desc"
mdTooltipPosition="right">
"): ng:///OwnershipCostModule/OwnershipAdminComponent.html#133:29
but when I go to where it tells me to I have the following
<div class="row">
<div class="col-12">
<div class="input-prepend input-group">
<span class="input-group-addon">$</span>
<input type="number" #updatedata [placeholder]="item.amount" [value]="item.amount" id="default" name="default" class="form-control" (blur)="submitAnswer(item.$key, updatedata.value)">
</div>
</div>
</div> -- line 133
I'm not sure why I'm getting the error as I replaced all instances of mdTooltip in my project.
Edit: This is what the submitAnswer function looks like
submitAnswer(key: string, answer: number) {
if (answer) {
this.answerdata.update(key, { amount: answer });
}
}
answerdata is a FirebaselistObservable
I realized that I was looking at the wrong component, and was able to get rid of the template parse error.

Grails, Joda-Time plugin, TimePicker nullable not working

I have a domain class with the attributes start + end, both of them are LocalTime (Joda-Time plugin). I want the end Time to be nullable. For this purpose I used the following constraint: end nullable: true. Scaffolding is realized through the Joda template and it's working pretty good. The only problem is that selecting nothing with the timepicker for the end property results in: Cant populate a class org.joda.time.LocalTime without a hour.
This is the generated code in the view:
<div class="fieldcontain ${hasErrors(bean: dailyBookingInstance, field: 'end', 'error')} ">
<label for="end">
<g:message code="dailyBooking.end.label" default="End" />
</label>
<joda:timePicker name="end" value="${dailyBookingInstance?.end}" default="none" noSelection="['': '']"></joda:timePicker>
</div>
This is a binding error - Joda Time Plugin - Fields nullable?
One work around is--
Change field name in the view, say time
<joda:timePicker name="time" value="${myDomainInstance?.end}" default="none" noSelection="['': '']"/>
and only populate this in your domain instance if data exists, like this
def save(MyDomain myDomainInstance) {
if(params.time_minute && params.time_hour){
myDomainInstance.end = new LocalTime(params.int('time_hour'), params.int('time_minute'))
myDomainInstance.validate()
}
//Other save code
}
Hope this helps..,.

Unclosed GSP expression: Grails GSP engine does not resolve nested GSP expression

I need to create a custom gsp whose domain model is designed as follows
class Question {
SortedSet<Choice> choiceCollection;
static hasMany = [choiceCollection:Choice]
static mappping = {
choiceCollection(joinTable:false)
}
}
Each Question object has five Choices. So, i create the following snippet of code
create.gsp
<g:each var="i" in="${(1..5)}">
<div class="fieldcontain required">
<label for="description">
Option ${i}.
<span class="required-indicator">*</span>
</label>
<g:textArea name="choiceCollection[${i}].description" cols="40" rows="5" maxlength="2000" value="${questionInstance?.choiceCollection[${i}]?.description}"/>
</div>
</g:each>
Although Grails GSP engine complains Unclosed GSP expression which is not true - g:textArea is closed as you can see above -, i believe the real problem is the expression
${questionInstance?.choiceCollection[${i}]?.description}
which involves nested GSP expressions.
Question: am i missing some feature ? If so, what should i do to overcome my obstacle ?
Grails version: 2.1.1
Shouldn't
${questionInstance?.choiceCollection[${i}]?.description}
be
${questionInstance?.choiceCollection[ i ]?.description}
The set bit:
Try something like:
<g:each var="choice" status="i" in="${questionInstance?.choiceCollection}">
So i still contains your index, but choice contains what you were trying to get with questionInstance?.choiceCollection[${i}]

AngularJS how to bind maps

Here is my HTML:
<div ng-app="angularApp">
<div ng-controller="testCtrl">
testKey = {{testKey}}<br />
Test 1: <input type="text" ng-model="test.myKey" />{{test[testKey]}}<br />
Test 2: <input type="text" ng-model="test[testKey]" />{{test[testKey]}}
</div>
</div>
Here is the js:
angular.module('angularApp', []);
function testCtrl($scope)
{
$scope.testKey = "myKey";
}​
I setup and example here
Why does Test 1 work but Test 2 not work? Are "[" not allowed in the ng-model directive?
Here a working example. The problem is very simple, test.[testKey] isn't valid, you want test[testKey]. And you need to define test as an object on the controller because you cannot set a property of an undefined variable.

Grails <field type="number" ...> not working ...?

first post to this forum ...
The Grails 2.0.1 < field type="number" > doesn't seem to be working out of the box, but perhaps my usage is incorrect, so I'm looking here for a sanity check.
Here's the field in my domain entity:
Long locationId
static constraints = {
locationId(blank: false)
}
Here's the resulting field in the scaffolded-template generated _form.gsp:
<g:field type="number" name="locationId" required="" value="${fieldValue(bean: myEntityInstance, field: 'locationId')}"/>
But here's the result in the html, as per "view source":
<input type="number" name="locationId" required="" value="" id="locationId" />
And my problem is that the form blanks out the existing value of that field, as per: value="".
The other fields (all strings) are populated correctly.
Is the Grails 2.0.1 "number" gsp field working correctly for other people?
Regards
Rob
Try:
<g:field type="number" name="locationId" required="" value="${myEntityInstance.locationId}"/>
If you have any value of 4 or more figures like 1000, fieldValue tries to display it 1,000
Check the actual value of ${fieldValue(bean: myEntityInstance, field: 'locationId')}
Print it out
<%
System.out.println fieldValue(bean: myEntityInstance, field: 'locationId')
%>
i've not had a problem with the 'number' type, it works for me exactly as you have used it

Resources