Today I've spent an hour trying to figure out how to use custom filtering on a JForm field. I knew that it was possible, but I just didn't know how. Searching on google also didn't help much. The question was asked a year ago on stackoverflow and nobody has answered it yet.
So, I decided that I'll have to look in the code and figure this on my own. Why would you want to do custom filtering? In my case users had to submit percentages in a field. The values were stored in the database as double, so I had to make sure that values submitted for example with comma, were properly saved in the database. What I've done in the past (and I'm ashamed to acknowledge this) is overriding the controller's save function, making the changes to the form data and passing the modified data to back to JForm. Well, it works, but in this project I wanted to save time & finally do it the correct way.
Here is how our form field looks like:
<field name="verwaltungskosten" type="text" class="form-control" size="40" label="Verwaltungskosten" labelclass="col-sm-2 compojoom-control-label"
filter="MyComponentFilterDouble::filter" required="true"/>
As you can see we have a filter. We've specified MyComponentFilterDouble as class and filter as a method of this class. If you have a look at libraries/joomla/form/form.php in the FilterField function toward the end you'll see that the code will try to execute our custom filter. Now here comes the tricky part. How does Joomla know where our filters are located? Well, it doesn't! We have to load our filters in advance. JForm doesn't come with a utility class that could load a custom filter. I've decided to load our Filters in our model in the getForm function. As you know each model that extends from JModelAdmin should have a getForm function. This function makes sure that we are loading the correct form from a .xml file. So in this function just before I load the form I did:
JLoader::discover('MyComponentFilter', JPATH_ADMINISTRATOR . '/components/com_mycomponent/models/forms/filters');
The discover method will make sure to auto load our class when we need it. This way it will be available to our form.
And there we go! Now when our model validates the form. It actually always first performs filtering on the data. Now in our custom filter we can modify the data and pass it back for validation. It's that easy!
This is what I could find by looking at the code. If you know a better way, don't hesitate to share it in the comments below! Happy coding!