Dynamic Mobile QBE Filter
Overview
Server-side keywords like SYSDAY, SYSDATE, and &PERSONID& work perfectly when querying the Maximo server through REST API. However, in mobile disconnected mode, these keywords cannot be processed because there’s no server connection. This guide shows how to replace these keywords with dynamic values that work in offline mode.
Use Cases:
- Filtering work orders by current date in mobile offline mode
- Using dynamic user information in mobile queries
- Creating date-based filters that work offline
- Implementing time-sensitive filters for mobile apps
Prerequisites:
- Understanding of datasources
- Knowledge of mobile QBE filters
- Familiarity with lifecycle events
Important Note:
Mobile QBE filters only work on data already downloaded to the device. They filter the local database, not the server.
Implementation
Step 1: Identify the server keyword to replace
Common server keywords that need replacement:
SYSDAY- Current date (no time component)SYSDATE- Current date and time&PERSONID&- Current user’s person ID&USERID&- Current user ID&SITEID&- Current site ID
Example server query:
<!-- This works on server but NOT in mobile offline mode --><maximo-datasource id="todayWorkDS"where="schedstart <= SYSDAY"mobile-qbe-filter="{{'schedstart': '<=SYSDAY'}}"/>
Step 2: Replace with dynamic value using state
Option A: Using Application State
XML Configuration:
<maximo-datasource id="todayWorkDS"object-structure="MXAPIWODETAIL"where="schedstart <= SYSDAY"mobile-qbe-filter="{{'schedstart': '<='+app.state.currentDate}}"><schema><attribute name="wonum" searchable="true" id="attr_001"/><attribute name="schedstart" id="attr_002"/><attribute name="description" id="attr_003"/></schema>
AppCustomizations.js:
/*** Custom Application Logic*/const TAG = 'DynamicFilter';class AppCustomizations {/*** Initialize application* @param {Application} app - The application instance
Step 3: Alternative - Update datasource query directly
Option B: Direct Query Update
AppCustomizations.js:
const TAG = 'DynamicFilter';class AppCustomizations {applicationInitialized(app) {this.app = app;}/*** Update datasource query with dynamic values
Complete Examples
Example 1: Filter by Date Range
const TAG = 'DateRangeFilter';class AppCustomizations {applicationInitialized(app) {this.app = app;}/*** Set up date range filter for mobile
Example 2: Filter by Current User
const TAG = 'UserFilter';class AppCustomizations {applicationInitialized(app) {this.app = app;}/*** Filter by current user's labor code
Example 3: Multiple Dynamic Filters
const TAG = 'MultiFilter';class AppCustomizations {applicationInitialized(app) {this.app = app;}/*** Set up multiple dynamic filters
Example 4: Refreshing Filter on Page Resume
const TAG = 'RefreshFilter';class AppCustomizations {applicationInitialized(app) {this.app = app;}/*** Refresh date filter when page resumes
Validation & Testing
How to verify:
Test in connected mode:
- Verify server-side where clause works
- Check data loads correctly
Test in offline mode:
- Enable airplane mode or disconnect network
- Navigate to the page with filtered datasource
- Verify data filters correctly using local database
Test date boundaries:
- Change device date/time
- Verify filter updates appropriately
- Test edge cases (midnight, timezone changes)
Check logs:
?_graphite_logLevel=debugLook for your TAG messages in console
Common Issues:
Issue: Filter doesn’t work in mobile offline mode
- Cause: Using server keywords (SYSDAY) in mobile-qbe-filter
- Solution: Replace with dynamic values as shown above
Issue: Date format doesn’t match
- Cause: Incorrect date format for mobile QBE
- Solution: Use
app.dataFormatter.convertDatetoISO()
Issue: Filter works on first load but not after
- Cause: Filter not refreshed when data changes
- Solution: Update filter in pageResumed or when needed
Issue: Nested attributes don’t filter
- Cause: Mobile QBE only filters top-level object
- Solution: Use aliases for nested properties
Best Practices
✅ Do:
- Use
app.dataFormatter.convertDatetoISO()for date formatting - Store dynamic values in application state for reusability
- Log filter values for debugging
- Test both connected and offline modes
- Refresh filters when page resumes (for date-based filters)
- Handle missing user information gracefully
❌ Don’t:
- Use server keywords (SYSDAY, &PERSONID&) in mobile-qbe-filter
- Hardcode dates or user information
- Forget to test in offline mode
- Assume nested properties work in mobile QBE
- Use complex expressions that work on server but not mobile
Performance Considerations:
- Mobile QBE filters are applied client-side (fast)
- Filters only affect already-downloaded data
- Complex filters may impact performance on large datasets
- Consider pre-filtering with saved queries to reduce data download
Mobile-Specific Notes:
- Mobile QBE filters only work on local database
- Cannot filter on nested object properties directly
- Use aliases for nested properties you need to filter
- Filters are case-sensitive
Date Formatting Reference
// Get current date/timeconst now = new Date();// Convert to ISO format for mobile QBEconst isoDate = app.dataFormatter.convertDatetoISO(now);// Result: "2026-01-13T00:00:00+00:00"// Get date only (no time)const dateOnly = app.dataFormatter.convertDatetoISO(new Date(now.setHours(0,0,0,0)));
Comparison: Server vs Mobile Filtering
| Aspect | Server (where clause) | Mobile (QBE filter) |
|---|---|---|
| Keywords | SYSDAY, &PERSONID& work | Must use dynamic values |
| Processing | Server-side | Client-side (local DB) |
| Data Scope | All data in Maximo | Only downloaded data |
| Performance | Depends on server | Fast (local) |
| Nested Properties | Supported | Limited (use aliases) |
| When to Use | Connected mode | Offline mode |
Related Resources
Prerequisites:
- Datasources Guide - Understanding datasources
- FAQ - How to filter with datasource
- Basic Concepts - Event Lifecycle
Related Practices:
- Client-side Datasource Filtering - In-memory filtering
- Modify Default Queries - Saved queries
Next Steps:
- Restrict Complete Status - Complex validation
- Additional Logic - Extending methods
External Documentation:
Additional Notes
Timezone Considerations:
Mobile devices may be in different timezones. Consider using UTC:
// Get UTC dateconst utcDate = new Date();const utcISO = app.dataFormatter.convertDatetoISO(new Date(utcDate.getTime() + utcDate.getTimezoneOffset() * 60000));
Debugging Mobile Filters:
Enable detailed logging to see filter application:
onDatasourceInitialized(datasource, owner, app) {if (datasource.name === 'myDS') {const filter = {/* your filter */};// Log before applyingthis.app.log.d(TAG, `Applying filter: ${JSON.stringify(filter)}`);datasource.updateBaseQuery({"mobileQbeFilter": filter});
Testing Offline Mode:
- Load data while connected
- Enable airplane mode
- Navigate to filtered page
- Verify filter works on local data
- Check console for any errors