Hi,
Unfortunately, the filter is still coupled to JPQL, so you’ll probably need to implement filtering by yourself. I can show you a workaround that might be useful, depending on your case.
Let’s assume you want to load non-persistent persons from a 3rd party datastore with name
and email
properties.
- I would suggest implementing a service with a method that fetches your data and has a parameter that can contain filter conditions.
- On the screen I’d recommend installing load delegate to your data loader and in this delegate, I’d invoke the service. Please note that you can get some information about screen load parameters from the
LoadContext
class (like query parameters) and filter
component (like max result to load).
You can add custom properties to your filter:
<filter id="filter"
applyTo="personsTable"
dataLoader="personsDl">
<custom name="Name" caption="Name" paramClass="java.lang.String">
{E}.name = ?
</custom>
<custom name="Email" caption="Email" paramClass="java.lang.String">
{E}.email = ?
</custom>
</filter>
Your service interface may look like this:
public interface PersonsService {
List<Person> fetchPersons(Map<String, Object> params);
}
In the PersonsServiceBean
class you need to implement the logic of fetching data based on the params values.
Then in the browser screen you may have the empty data loader:
<data readOnly="true">
<collection id="personsDc"
class="com.company.filtering.entity.Person">
<view extends="_local">
<property name="name"/>
<property name="email"/>
</view>
<loader id="personsDl"/>
</collection>
</data>
and in the controller you have the loader algorithm overridden:
@Install(to = "personsDl", target = Target.DATA_LOADER)
private List<Person> personsDlLoadDelegate(LoadContext<Person> loadContext) {
Map<String, Object> params = new HashMap<>();
params.putAll(loadContext.getQuery().getParameters());
return personsService.fetchPersons(params);
}
Now every time you update the filter, the data will be reloaded by the screen automatically. This approach makes the data loading process “seamless” for the screen, it does not care where entities are coming from. And you will have enough flexibility in terms of data loading - there is only one entry point for loading data: loader delegate.
The issue here is that filter parameter names are different from what you have defined in the XML screen markup. So, in the params map in the service, you can have param names like filter_Name8743
or filter_Email9173
, because these names are defined in the runtime and redefined each time when the screen is opened.
Please have a look at the documentation on data loader and filter component, there are more examples of using data loaders in the screens that you may adapt to your case.
Also I’ve created a very basic prototype that can select persons by their names - the service contains static list of these. Hope this will help. filtering.zip (83.2 KB)
Just a reminder, it is a workaround. But using services and overriding data loader instead of direct adding items to the container is a good practice.