Tuesday, September 27, 2011

Extjs Fix For Firefox Text overflow.

HTML Online Editor Sample
       In the recent Extjs development i faced an issue related to the content overflow for Firefox. i was retrieving a data from the DB table which is having the CLOB field. CLOB type filed is used to store a data more than 4k. The CLOB field in My XML response have a data of around 8k. So i was not able to see the full data (8k) of that field. i was able to see only the 4k data in the Extjs text area. After doing a search i have got the following information.

        A text node in Firefox allows only 4K data. So an XML Ajax response gets split up into multiple text child nodes instead of only one node. Its fine in Internet Explorer(only up to 64k) and opera (only up to 32k). For Firefox, to get the full data you either need to use node.normalize() before you call node.firstChild or use node.textContent, or user node.wholeText both of which are Mozilla specific methods.

To fix this issue in Extjs i did the following steps.

If you are using the XmlReader then you need to override it.

/**
 * Copyright(c) 1998-2009, Sword-global.
 * 
 * The class represents a custom XML reader component for FusionSaas. Hold
 * handle to the current viewer and configuration parameters for XML Reader.
 * 
 */
my.XmlReader=Ext.extend(Ext.data.XmlReader,{
    constructor: function(meta, recordType){
         my.XmlReader.superclass.constructor.call(this, meta, (recordType || meta.fields));
    },
    /**
     * Create a data block containing Ext.data.Records from an XML document.
     * @param {Object} doc A parsed XML document.
     * @return {Object} records A data block which is used by an {@link Ext.data.Store} as
     * a cache of Ext.data.Records.
     */
    readRecords : function(doc){
        this.xmlData = doc;
        var root = doc.documentElement || doc;
        var q = Ext.DomQuery;
        var recordType = this.recordType, fields = recordType.prototype.fields;
        var sid = this.meta.idPath || this.meta.id;
        var totalRecords = 0, success = true;
        if(this.meta.totalRecords){
            totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
        }
        if(this.meta.success){
            var sv = q.selectValue(this.meta.success, root, true);
            success = sv !== false && sv !== 'false';
        }
        var records = [];
        var ns = q.select(this.meta.record, root);
        for(var i = 0, len = ns.length; i < len; i++) {
            var n = ns[i];
            var values = {};
            var id = sid ? q.selectValue(sid, n) : undefined;
            for(var j = 0, jlen = fields.length; j < jlen; j++){
                var f = fields.items[j];
                var v = this.selectMoreThan4KValue(Ext.value(f.mapping, f.name, true), n, f.defaultValue);
                v = f.convert(v, n);
                values[f.name] = v;
            }
            var record = new recordType(values, id);
            record.node = n;
            records[records.length] = record;
        }
        return {
            success : success,
            records : records,
            totalRecords : totalRecords || records.length
        };
    },
    
    selectMoreThan4KValue : function(path, root, defaultValue){
     trimRe = /^\s+|\s+$/g
        path = path.replace(trimRe, "");
        valueCache = {};
        if(!valueCache[path]){
            valueCache[path] = Ext.DomQuery.compile(path, "select");
        }
        var n = valueCache[path](root),
         v;
        n = n[0] ? n[0] : n;
        if(n && Ext.isGecko){
         v = (n && n.firstChild ? n.firstChild.wholeText : null);
        }else{
         v = (n && n.firstChild ? n.firstChild.nodeValue : null);
        }
        return ((v === null||v === undefined||v==='') ? defaultValue : v);
    }
});

No comments:

Post a Comment