ExtJS 3.4 Ext.data.Store.find Bug

Let me start by saying I love ExtJS. It is such a great framework and more commercial grade than JQuery. However, today I found a bug with the find function on an Ext.data.Store.

fieldName, value, [startIndex], [anyMatch], [caseSensitive] ) 

Given a field name and a value it should return the first matching record. However I noticed by default it doesn’t search for an exact match but rather will return a record found if the value is a sub-string in the record’s field name. I noticed you can optionally pass a parameter called anyMatch that should be able to disable this default functionality. According to the documentation it states the following about anyMatch:

True to match any part of the string, not just the beginning”

However all my attempts to disable this functionality failed. Looking at the framework’s source it looks like there is an undocumented function called findExact that should be called when the parameter anyMatch is false.

As a workaround you could either call this function:

1
var index = myStore.findExact("propertyName", "valueToFind");

or use the documented function findBy like so:

1
2
3
4
5
6
var index = myStore.findBy(function (r, id) {
if (record.get("layername") == r.get("layername")) {
return true;
}
return false;
});

In either case if index is -1 no records were found.

I hope this will save someone some wasted time : ).

 

 

ExtJS 3.4 DomQuery Namespaces Hotfix

You may have noticed that in ExtJS 3.4 that you can’t use namespaces in your Ext.dataXmlReader.
So a xml reader defined like the example below does not work with the following xml:

1
2
3
4
5
6
7
var Employee = Ext.data.Record.create([
   {name: 'name', mapping: 'gml:name'},    
   {name: 'gml:occupation'}                
]);
var myReader = new Ext.data.XmlReader({
   record: "gml|row" // The repeated element with gml namespace (gml:row)
}, Employee);

The above should consume an xml file defined like so:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
 <gml:row>
   <gml:name>Bill</gml:name>
   <gml:occupation>Gardener</gml:occupation>
 </gml:row>
 <gml:row>
   <gml:name>Ben</gml:name>
   <gml:occupation>Horticulturalist</gml:occupation>
 </gml:row>
</dataset>

But it doesn’t…
That is because ExtJS 3.4 DomQuery does not support namespaces. They fixed this problem in 4 but those of you still using the 3.4 framework might find my hotfix useful. If just interested in using the files themselves I have attached them at the bottom of this post. Here are the changes I made:

Changed:

1
2
3
// tagTokenRe = /^(#)?([\w\-\*]+)/,  // Removed
tagTokenRe = /^(#)?([\w\-\*\|\\]+)/, // Added: allows vertical bars to be included
supportsColonNsSeparator,            // Added

Then Changed:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//while(!(modeMatch = path.match(modeRe))){
// var matched = false;
// for(var j = 0; j < matchersLn; j++){
//    var t = matchers[j];
//    var m = path.match(t.re);
//    if(m){
//       fn[fn.length] = t.select.replace(tplRe, function(x, i){
//return m[i];
//});
//       path = path.replace(m[0], "");
//       matched = true;
//       break;
//    }
// } 
// if(!matched){
//    throw 'Error parsing selector, parsing failed at "' + path + '"';
// }
//}
//if(modeMatch[1]){
// fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
// path = path.replace(modeMatch[1], "");
//}
while (!(modeMatch = path.match(modeRe))) {
   var matched = false;
   for (var j = 0; j < matchersLn; j++) {
      var t = matchers[j];
      var m = path.match(t.re);
      if (m) {
         fn[fn.length] = t.select.replace(tplRe, function (x, i) {
            return m[i];
         });
         path = path.replace(m[0], "");
         matched = true;
         break;
      }
   }

   if (!matched) {
      throw 'Error parsing selector, parsing failed at "' + path + '"';
   }
}
if (modeMatch[1]) {
   fn[fn.length] = 'mode="' + modeMatch[1].replace(trimRe, "") + '";';
   path = path.replace(modeMatch[1], "");
}

Hotfix:
ext-all-debug-namespaces.js
ext-all-namespaces.js