I’m seeing a behavior change between SmartClient 12.1 and 14.0 when using DataSource.applyFilter() with AdvancedCriteria referencing dynamic fields that are not declared in the DataSource’s original fields array.
Behavior in SmartClient 12.1
When calling applyFilter() on an array of records where the criteria references a field not declared in the DataSource, the framework still attempted to evaluate the criteria against the raw property values in the records.
This worked fine as long as the property existed on the records themselves.
Example scenario:
Behavior in SmartClient 14.0
In 14.0, the same call to applyFilter() returns all records unfiltered.
What appears to be happening is that applyFilter() now performs early validation using isc.DS.getCriteriaValidator().validate().
This calls getField() on each criterion’s fieldName, and if any field is unknown, validation fails and no filtering occurs—criteriaApplies() is never invoked.
I confirmed this by patching applyFilter() and criteriaApplies() with logs; in 14.0, criteriaApplies() is never called if getField() returns undefined.
How We Add Fields Dynamically
In our application, we intentionally add fields to the DataSource dynamically at runtime as part of our design.
Currently, the only way we have found to do this is by assigning to the fields array or object, e.g.:
dataSource.fields["customField"] = { name: "customField", type: "text" };
This worked well in 12.1 because filtering continued to function even if the field was not declared at DataSource creation time.
If there is a better-supported or recommended approach to dynamically registering fields in a DataSource (so that applyFilter() will recognize them), we are very open to using it instead.
Workaround
To restore the previous behavior, I wrote a patch that extends getField() to also look in this.fields[fieldName] if the field is not found via the standard mechanism.
After applying this patch, applyFilter() and criteriaApplies() work as they did in 12.1.
Below is the minimal version of the patch without console logging and without restricting to a specific field name or DataSource:
Patch:
Questions:
Thanks in advance for any guidance on this topic.
Behavior in SmartClient 12.1
When calling applyFilter() on an array of records where the criteria references a field not declared in the DataSource, the framework still attempted to evaluate the criteria against the raw property values in the records.
This worked fine as long as the property existed on the records themselves.
Example scenario:
- Records have a property customField.
- The DataSource doesn’t declare customField.
- applyFilter() returns filtered results as expected.
Behavior in SmartClient 14.0
In 14.0, the same call to applyFilter() returns all records unfiltered.
What appears to be happening is that applyFilter() now performs early validation using isc.DS.getCriteriaValidator().validate().
This calls getField() on each criterion’s fieldName, and if any field is unknown, validation fails and no filtering occurs—criteriaApplies() is never invoked.
I confirmed this by patching applyFilter() and criteriaApplies() with logs; in 14.0, criteriaApplies() is never called if getField() returns undefined.
How We Add Fields Dynamically
In our application, we intentionally add fields to the DataSource dynamically at runtime as part of our design.
Currently, the only way we have found to do this is by assigning to the fields array or object, e.g.:
dataSource.fields["customField"] = { name: "customField", type: "text" };
This worked well in 12.1 because filtering continued to function even if the field was not declared at DataSource creation time.
If there is a better-supported or recommended approach to dynamically registering fields in a DataSource (so that applyFilter() will recognize them), we are very open to using it instead.
Workaround
To restore the previous behavior, I wrote a patch that extends getField() to also look in this.fields[fieldName] if the field is not found via the standard mechanism.
After applying this patch, applyFilter() and criteriaApplies() work as they did in 12.1.
Below is the minimal version of the patch without console logging and without restricting to a specific field name or DataSource:
Patch:
Code:
if (isc.version.indexOf("v14.0") > -1) { var proto = isc.DataSource.getPrototype(); var origGetField = proto.getField; proto.getField = function(fieldName) { var result = origGetField.call(this, fieldName); if (result) return result; // Fallback: if fields is an object, check there too if (this.fields && !isc.isAn.Array(this.fields)) { return this.fields[fieldName] || null; } return null; }; }
Questions:
- Was this stricter validation in 14.0 an intentional change in the framework?
- Is there an officially supported way to allow applyFilter() to handle dynamic fields without defining them statically in the DataSource configuration?
- Are there any recommended approaches for dynamically adding fields to a DataSource so they are recognized by getField() without requiring patches like the one above?
Thanks in advance for any guidance on this topic.
Comment