I would like to filter object picker data not just by another field/object, but by a property of that object.
I have two objects"TradeFair" and “Hotel”, both of which have a property “City”. “City” is not a string property, it’s a relation, because “City” is an object, too.
Now in my form I want the user to select a TradeFair and then a Hotel, both using the object picker control. For obvious reasons I only want to present a list of hotels from the same city that the fair is in.
I tried to use something like filterBy="TradeFair.city" filterByField="city"
but, that does not seem to work. How should I go about this, please?
Thank you!
In your city object, you can have a one-to-many
relationship to the trade fair object
property name="trade_fairs" relatedTo="trade_fair" relationship="one-to-many" relationshipKey="city";
In your form, you can filter the hotel by city$trade_fairs.id
<field name="trade_fair" control="objectPicker" object="trade_fair" />
<field name="hotel" control="objectPicker" object="hotel" filterBy="trade_fair" filterByField="city$trade_fairs.id" />
The hotel object filter will look like this
filter[ "city$trade_fairs.id" ] = "selected-trade-fair-id";
Hi @choontat, thanks for your suggestion. Unfortunately I cannot do it like this, because my data model obviously is a lot more complex than the little segment I was showing here.
I have solved it now like this:
- add a hidden field for the city to the form
<field name="tradefair_city" control="hidden" />
- Filter the hotel field by the hidden field
<field binding="Booking.hotel" ... filterBy="tradefair_city" filterByField="city" />
Unfortunately, hidden fields don’t create change events per default, so I had to work around that by
- Adding an onchange event to the tradefair field
<field binding="Booking.tradefair" ... attribnames="onchange" attribvalues="setTradefairCity()" />
- create a corresponding JS function, that reads the value of the tradefair field, retrieves the corresponing city, writes it to the hidden field, and triggers a change event on that hidden field. (I know I could have created the onchange handler with JS as well, I just didn’t want with any handler that was created by the Preside core js).
The critical point is triggering the change event on the hidden field:
const cityField = document.getElementById( "tradefair_city" );
const changeEvent = new Event( "change" );
cityField.dispatchEvent( changeEvent );
- add that script to Sticker and include it in your handler in
preRenderAddRecordForm()
private void function preRenderAddRecordForm( event, rc, prc, args={} ){
event.include( "js-tradefair-city );
}
In the end it’s not the most elegant solution, but, one that works for my needs. 