Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Custom validator question

    I need to create a custom validator to compare one field to another field in the same datasource and only allow fieldA to be less than fieldB (both date fields in my case, but I can see similar needs for other field types). The datasource is edited via a reusable component and I want to avoid having custom code in the UI to deal with this so I'd like to define the validator in the ds.xml, similar to the matchesField validator.

    Could someone please provide an example of a custom validator implemented in this way?

    #2
    Is there any way to do this?

    Comment


      #3
      Take a look at the new validator.serverCondition in 2.1 - you can do this with something like "value.getTime() == record.otherField.getTime()"

      Comment


        #4
        Is there any documentation or example I can refer to. All I've been able to find is a few bullet points in the javadocs. Where do I put the velocity code? In the ds.xml? Do I need to create a server side class and hook it in via serverConstructor? Sorry if I'm being dense, but it is far from clear how this is meant to work.

        Comment


          #5
          OK. I take it back. It is as simple as it should be after all.

          Code:
          <validators>	
          	<validator type="serverCustom"
          	serverCondition="value.getTime() &lt; record.otherField.getTime()" 				
          	errorMessage="Start date must be less than end date."/>
          </validators>
          Thanks for the enhancement!

          Comment


            #6
            So the basic implementation is now clear, but I'm running in to a velocity template issue that I don't understand or know how to debug. The following error message appears on the console.

            'serverCustom' validation specified a VTL expression of 'value.getTime() > record.TZCDDSD01.getTime()', which does not evaluate to a boolean value. Assuming false

            The fields in the data source look like this.
            Code:
            <field name="TZCDDSD01" title="Standard time begins" type="date" useTextField="true" detail="true"/>
            <field name="TZCDDSD02" title="Daylight savings time begins" type="date" useTextField="true" detail="true">
            	<validators>	
            		<validator type="serverCustom"
            			serverCondition="value.getTime() &gt; record.TZCDDSD01.getTime()" 				
            			errorMessage="Daylight savings time must start after standard time."/>
            	</validators>
            </field>
            The syntax seems correct. What am I missing?

            Comment


              #7
              Sorry, the sample for this did not quite make the 2.1 release.

              It should look like:
              Code:
              <field name="TZCDDSD02" title="Daylight savings time begins" type="date" useTextField="true" detail="true">
              	<validators>	
              		<validator type="serverCustom"
              			serverCondition="#if(value.getTime() &gt; record.TZCDDSD01.getTime()) true #else false #end" 				
              			errorMessage="Daylight savings time must start after standard time."/>
              	</validators>
              </field>
              We also plan to add a Velocity macro to clean up that syntax in a future release.

              Comment


                #8
                Thanks. I just had to add the $ prefix to the variables $value and $record and it worked.

                serverCondition="#if($value.getTime() &gt; $record.TZCDDSD01.getTime()) true #else false #end"

                This is a terrific new feature. Thanks for adding it.

                I only have one more question regarding the dataSources context variable. I can imagine how to use the other context variables, but what can you do with a reference to other data sources? Can you suggest a scenario where that would be useful? Can you perform operations on other data sources?

                Comment


                  #9
                  Yes, dataSource.dataSourceId gives you an instance of a DataSource, so dataSource.dataSourceId.fetch() is calling DataSource.fetch(). You can use this to eg check things on related records (even if the two DataSoirce use different persistence, eg, SQL vs custom code.

                  Examples to show all this off are on the way.

                  Comment

                  Working...
                  X