1. #1
    Sencha Premium Member
    Join Date
    Oct 2012
    Posts
    209
    Vote Rating
    -1
    vkeswani can only hope to improve

      0  

    Default Unanswered: Gird filtering issue on BigDecimal Column values

    Unanswered: Gird filtering issue on BigDecimal Column values


    I have implemented grid filtering using simple example as shown in gxt explorer FilterGrid.
    I have applied NumericFilter on a value returning an amount value which is BigDecimal.
    Everything works as expected - the filter shows up on the column header with >,< and = , however while > and < work as expected the "=" operator doesn't work and returns no values.

    Please suggest.

  2. #2
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,734
    Vote Rating
    90
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    As each numeric type has different ways of checking, and as developers haven't been thrilled with the prospect of a dozen different filter objects for each possible comparable type, we have a default implementation to compare them. It turns out that java.lang.Number doesn't implement java.lang.Comparable, and the >, <, >=, <= operators don't work on BigDecimal or some other non-primitive Number classes.

    We could add a compare method into the NumberPropertyEditor and subclasses, but that would come at the cost of causing changes in other projects. Instead, NumericField has two methods designed to be overriden in cases such as yours - greaterThan(V,V), and equals(V,V). In both cases, V is the numeric type you are working with.

    We're open to thoughts and suggestions on how this api can be improved to be as flexible as possible, but try starting with these and seeing where you can get.

  3. #3
    Sencha Premium Member
    Join Date
    Oct 2012
    Posts
    209
    Vote Rating
    -1
    vkeswani can only hope to improve

      1  

    Default


    Thanks Colin.

    Yes I did a small test with compareto instead of "equals" and that works well with BigDecimal. Overriding could be the workaround.

  4. #4
    Sencha User
    Join Date
    Jul 2011
    Posts
    139
    Vote Rating
    14
    Answers
    3
    Andreas Samjeske will become famous soon enough

      0  

    Default


    Quote Originally Posted by Colin Alworth View Post
    As each numeric type has different ways of checking, and as developers haven't been thrilled with the prospect of a dozen different filter objects for each possible comparable type, we have a default implementation to compare them. It turns out that java.lang.Number doesn't implement java.lang.Comparable, and the >, <, >=, <= operators don't work on BigDecimal or some other non-primitive Number classes.

    We could add a compare method into the NumberPropertyEditor and subclasses, but that would come at the cost of causing changes in other projects. Instead, NumericField has two methods designed to be overriden in cases such as yours - greaterThan(V,V), and equals(V,V). In both cases, V is the numeric type you are working with.

    We're open to thoughts and suggestions on how this api can be improved to be as flexible as possible, but try starting with these and seeing where you can get.
    Colin,

    it not just broken for BigDecimal, but for Integer too!
    Taken from NumericFilter in GXT 3.0.0b
    Code:
     ...
       * @return true if the two values should be considered to be equal for the
       *         purposes of filtering
       */
      protected boolean equals(V a, V b) {
        return a.equals(b.doubleValue());
      }
    Fails, cause equals(obj) of Class Integer alsways returns false, if obj is not instanceof Integer:
    Code:
        public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
        }
    I don't know, if NumericFilter got smater in a more recent version. But IMHO its behavior in GXT 3.0.0b is buggy.

  5. #5
    Sencha User
    Join Date
    Jul 2011
    Posts
    139
    Vote Rating
    14
    Answers
    3
    Andreas Samjeske will become famous soon enough

      0  

    Default


    Oh, and Colin, it seemed like I totally missed the part "yeah, we know, NumericFilter is crap, it only works for double" in the guide!

  6. #6
    Sencha User
    Join Date
    Jul 2011
    Posts
    139
    Vote Rating
    14
    Answers
    3
    Andreas Samjeske will become famous soon enough

      0  

    Default


    Hmm, now the guide suggests BigInteger and Integer are working for GXT 3.0.4+

    And still NumericFilter states
    Code:
    Filter class for numeric fields. by default, converts data to double before comparing, but this behavior can be change by overriding equals(Number, Number) and greaterThan(Number, Number). See Filter for more information.
    U should say much clearer: You have to implement your own equals and greaterThan if Number != Double!

    U can at least do something like this:
    Code:
        protected boolean equals(V a, V b) {
            if (a instanceof Comparable<?>) {
                return ((Comparable<V>) a).compareTo(b) == 0;
            }
            return a.equals(b.doubleValue());
          }
    
        protected boolean greaterThan(V a, V b) {
            if (a instanceof Comparable<?>) {
                return ((Comparable<V>) a).compareTo(b) >= 0;
            }
    
            return Double.compare(a.doubleValue(), b.doubleValue()) >= 0;
          }
    At least for Comparable Filters would work then.

  7. #7
    Ext JS Premium Member
    Join Date
    Feb 2008
    Posts
    22
    Vote Rating
    0
    arcsight-gui is on a distinguished road

      0  

    Default


    Here is the behavior I have seen when dealing with Integers:

    1. When you enter an Integer, X, into the < filter field, it checks greaterThan(cellNumber, X) and filters out the rows whose cellNumber made this call return true. Thus if you enter 0 in the filter, for any row with a cellNumber = 0, the call returns false and the row is shown (not filtered).

    So your row with cellNumber = 0 shows up when you filter by < 0!

    2. When you enter an Integer, X, into the > filter field, it checks greaterThan(X, cellNumber) and, again, filters out the rows whose cellNumber made this call return true. Thus if you enter 0 in the filter, for any row with a cellNumber = 0, the call returns false and the row is shown (not filtered). If you enter 1 in the filter, for any row with a cellNumber = 1, the call returns false and the row is shown (not filtered).

    So your row with cellNumber = 0 shows up when you filter by > 0!
    And your row with cellNumber = 1 shows up when you filter by > 1!

    If you override and implement greaterThan(a, b) as returning true if a >= b, then its invocation as greaterThan(cellNumber, X) will return false where cellNumber < X and exactly your expected rows will show for the < filter field.

    This also means that its invocation as greaterThan(X, cellNumber) will return true when X >= cellNumber, and this is the invocation is uses when you enter 0 into the > filter field. When cellNumber = 0 and your filter is "> 0" it will return true because 0 >= 0 is true, and correctly filter your rows.

    So my two overrides here seemed to be a successful workaround for this bug:

    Code:
    		@Override
    		protected boolean equals(Integer a, Integer b) {
    			return a.equals(b);
    		}
    		@Override
    		protected boolean greaterThan(Integer a, Integer b) {
    			return (a.compareTo(b) > 0) || a.equals(b);
    		}