I use a lot of input validation on objects in YellowGrass. These work great when editing objects using a straightforward edit form. More frequently, however, I create objects in more customized ways. For example YellowGrass offers a text box on an issue page, to quickly tag an issue with either an existing, or a new tag. Here is a simplified version of the code:

var tagName : String := "" form { input(tagName) action("+", addTag(tagName, i)) } action addTag(tagName : String, i : Issue) { i.addTag(tag(tagName, i.project)); return issue(i); } ... other actions ...

The drawback of this code is that any validation that I have set on tag names is ignored, as it is a local string which is input, not a tag name. A solution to consider is adding a declaration of a new tag at the top of the page and using input(newTag.name) instead. Unfortunately, this has the risk of accidentally saving unused (and dangling) tags, through other actions. Besides, I want to use my 'tag(...,...)' function to create tag, as it does additional checking. Another solution would be to add validation to the input box:

input(t) { validate(t.length() > 1 && /[a-z0-9\.-_@!]*/.match(t), "Tags need to have at least two characters and may consist of: a-z 0-9 . _ @ ! -") }

However, this duplicates the validation code. Surely, I can extract validation functions to counter this, but it would make a mess of input validation messages and the validation code, which is now nicely centralized around the data model. Therefore my question: Do you know a way to solve this? Or could you perhaps add a solution, like being able to cal upon the validation of properties, without having to input such properties explicitly?

Submitted by Sander Vermolen on 7 February 2011 at 12:28

On 7 February 2011 at 12:37 Sander Vermolen commented:

I am trying to get the latter solution to work, as a temporary workaround, but I realize now, that it does not actually solve the problem: I have an ajax call whenever the input box is changed, to show tag completions. Consequently, whenever I type something, the input validation is triggered. Hence when typing one character, it already gives me the error that my tag needs to be longer. I therefore now realize, that I in fact need to trigger the input validation on the + action somehow, not on any other action. Is this possible?


On 7 February 2011 at 22:20 Danny Groenewegen commented:

"The drawback of this code is that any validation that I have set on tag names is ignored"

That sounds like a bug, data model invariants should also be checked at the end of an action.

"Unfortunately, this has the risk of accidentally saving unused (and dangling) tags, through other actions."

I guess you are referring to setting inverse properties which causes entities to be saved?

"Do you know a way to solve this? Or could you perhaps add a solution, like being able to cal upon the validation of properties, without having to input such properties explicitly?"

Data model validations are provided as methods of the entity, here is an example of calling property validation without direct input:

  entity Foo{
    s :: String
    validate(s.length()>5,"too short")
    validate(/[0-9]*/.match(s),"only numbers")
  }

  define page root(){
    var s := "123"
    form{
      input(s)[onkeyup=check()]
      placeholder vmes message([""])
    }    
    action check(){
      var f := Foo{ s := s }; 
      var list := f.validateS(); //call validation for property s
      replace(vmes,message([ve.message | ve:ValidationException in list.exceptions]));
    }
  }
  
  define ajax message(list:List<String>){
    for(s:String in list){
      output(s)
    } separated-by { ", " }
  }

Can you give some example code for the question in the comment?


On 8 February 2011 at 10:36 Sander Vermolen closed this issue.

On 8 February 2011 at 10:36 Sander Vermolen commented:

Ok, nice, those validation functions was exactly what I was looking for. It does not quite work yet, but it is going in the right direction. As for the other points:

"That sounds like a bug, data model invariants should also be checked at the end of an action."
If they are supposed to be checked then indeed it is a bug. I will report it separately.

"I guess you are referring to setting inverse properties which causes entities to be saved?"
Rather the automatic saving of objects at the end of each action. Especially the cascading save is easily missed when programming, so I'd rather work around it.

Log in to post comments