1

I want to ensure that one of two form fields representing a boolean value is checked. But there is no appropriate constraint to do this. nullable: false does not work.

class Organisation {

    Boolean selfInspecting

    static constraints = {
        selfInspecting(nullable: false)
    }

}

How can I check whether one of the two fields is checked or not?

Jay Prall
  • 5,295
  • 5
  • 49
  • 79
deamon
  • 89,107
  • 111
  • 320
  • 448

3 Answers3

3

Perhaps the simplest approach is to use a form that ensures a value is picked. As such, creating a radio buttons rather than checkboxes is a better solution. It would directly represent your intent as well.

mfloryan
  • 7,667
  • 4
  • 31
  • 44
  • In addition, checkboxes represent multiple boolean values. Per your example, I would only expect to see a single checkbox or a radio group with yes/no options. You can also set selfInspecting = true | false in your domain so that it has a default other than null no matter what. Or use the primitive boolean which defaults to false. – Gregg Nov 18 '10 at 16:45
  • I want to use radio buttons, but I don't want to preselect one, because users could accidentally accept my the preselection. – deamon Nov 18 '10 at 16:53
3

You can also check this in the Controller, e.g.

if (params.checkBox1 != 'on' && params.checkBox2 != 'on')
  flash.error = 'At least one value must be checked.'
  return ...
Jörg Brenninkmeyer
  • 3,304
  • 2
  • 35
  • 50
1

you can write your own custom validator.

something like

selfInspecting(validator: {val, obj -> /*test selfInspecting here*/})

EDIT -- in response to the other answer -- you can handle this on the form, but you should also handle it on the server.

ANOTHER EDIT -- It was suggested in a comment that you might want to validate one of two fields on your Domain class. This is also easily accomplished with a custom validator. With the signature above for the custom validator closure, the val is the value selfInspecting, and obj is the domain object instance. So you could have

{ val, obj ->

    if (val == null) return false // if you want to ensure selfInspecting is not null
    else return true

    ... or ...

    // if you want to check that at least 1 of two fields is not null
    def oneOrTheOther = false
    if (obj.field1 != null || obj.field2 != null) 
       oneOrTheOther = true
    return oneOrTheOther

}
hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
  • If you set selfInspecting to a default value or use the primitive boolean, there is no need for custom validation. – Gregg Nov 18 '10 at 16:52
  • @gregg, controllers/service code can't (accidently) null out the value? – hvgotcodes Nov 18 '10 at 17:04
  • I suppose they can, if using the Boolean object, and not the primitive. But that can also happen after validation, so testing is the key here. ;) – Gregg Nov 18 '10 at 17:33
  • @gregg i believe all save/update methods validate when they are fired. Besides, in less lines of code than we have written talking about this, the validator could be implemented and tested. – hvgotcodes Nov 18 '10 at 17:35
  • The poster also wants to check that one of two fields is checked i.e. a | b == true. The validator is definitely needed on the server side to ensure this. – leebutts Nov 18 '10 at 19:02
  • @hygotcodes you might want to add an example where you can use the obj parameter to compare the current value of selfInspecting with the other boolean field they are talking about (but haven't shown in their code) – leebutts Nov 18 '10 at 19:03
  • @leebutts, from what i read he wants to make sure that 'one of two form fields' is checked. but the form fields can by in one parameter on the domain object. But you are correct that it would be easy to check if one or the other of 2 fields on the domain object is correct. I will update. – hvgotcodes Nov 18 '10 at 19:09
  • The second variant can be simplified to: `return obj.field1 != null || obj.field2 != null` – deamon Nov 22 '10 at 09:33
  • @deamon true. I just write code this way because I think it is more readable. Having the def oneOrTheOther puts some meaning into the variables -- I feel it makes the code more readable. – hvgotcodes Nov 22 '10 at 15:19