1. #1
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default [v1.1] new Ext.form field type - MiscField

    [v1.1] new Ext.form field type - MiscField


    I wanted a way to display just simple text, with or without a label, in my form layout. Second, I wanted a way to display a label, but with no associated form field. This extension solved all of my needs, and more.

    In addition to being able to accomplish the above, you can now also easily add images, buttons, etc, to your form layout.

    Examples:
    Code:
    // regular MiscField field with plain text
    new Ext.form.MiscField({
    	fieldLabel: 'MiscField',
    	id: 'miscfield',
    	width: 160,
    	value: 'blah blah blah'
    });
    
    // label with a blank field - just don't set the 'value' option
    new Ext.form.MiscField({
    	fieldLabel: 'MiscField',
    	id: 'miscfield_novalue',
    	width: 160
    })
    
    // MiscField with image and bold text
    new Ext.form.MiscField({
    	fieldLabel: 'MiscField',
    	id: 'miscfield_image',
    	width: 160,
    	value: '<img src="/path/drop-yes.gif"> image and <b>bold text</b>'
    });
    ... this produces what you see in the attached image (along with a couple TextFields for comparison).

    Any methods/functions/events/etc that are related to a form input field have been stripped out (i.e. validation, focus/blur, etc) as they are no longer necessary. Some things may work a little differently. For example, you can use HTML tags in the 'value' option. Calling 'miscfield.getRawValue()' will return the MiscField value, exactly as it is, HTML and all. However, calling 'miscfield.getValue()' returns the text only and strips out all HTML tags. Same deal for 'setValue()' and 'setRawValue()'.

    This should be obvious, but I'll mention it anyway just in case; using a MiscField is only for visual purposes - as in adding more functionality to the form layout. MiscFields do not post any data when submitting a form.

    Here is the code:
    Code:
    /**
     * @class Ext.form.MiscField
     * @extends Ext.BoxComponent
     * Base class to easily display simple text in the form layout.
     * @constructor
     * Creates a new MiscField Field
     * @param {Object} config Configuration options
     */
    Ext.form.MiscField = function(config){
        Ext.form.MiscField.superclass.constructor.call(this, config);
    };
    
    Ext.extend(Ext.form.MiscField, Ext.BoxComponent,  {
        /**
         * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
         * {tag: "div"})
         */
        defaultAutoCreate : {tag: "div"},
    
        /**
         * @cfg {String} fieldClass The default CSS class for the field (defaults to "x-form-field")
         */
        fieldClass : "x-form-field",
    
        // private
        isFormField : true,
    
        /**
         * @cfg {Mixed} value A value to initialize this field with.
         */
        value : undefined,
    
        /**
         * @cfg {Boolean} disableReset True to prevent this field from being reset when calling Ext.form.Form.reset()
         */
        disableReset: false,
    
        /**
         * @cfg {String} name The field's HTML name attribute.
         */
        /**
         * @cfg {String} cls A CSS class to apply to the field's underlying element.
         */
    
        // private ??
        initComponent : function(){
            Ext.form.MiscField.superclass.initComponent.call(this);
        },
    
        /**
         * Returns the name attribute of the field if available
         * @return {String} name The field name
         */
        getName: function(){
             return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
        },
    
        // private
        onRender : function(ct, position){
            Ext.form.MiscField.superclass.onRender.call(this, ct, position);
            if(!this.el){
                var cfg = this.getAutoCreate();
                if(!cfg.name){
                    cfg.name = this.name || this.id;
                }
                this.el = ct.createChild(cfg, position);
            }
    
            this.el.addClass([this.fieldClass, this.cls]);
            this.initValue();
        },
    
        /**
         * Apply the behaviors of this component to an existing element. <b>This is used instead of render().</b>
         * @param {String/HTMLElement/Element} el The id of the node, a DOM node or an existing Element
         * @return {Ext.form.MiscField} this
         */
        applyTo : function(target){
            this.allowDomMove = false;
            this.el = Ext.get(target);
            this.render(this.el.dom.parentNode);
            return this;
        },
    
        // private
        initValue : function(){
            if(this.value !== undefined){
                this.setRawValue(this.value);
            }else if(this.el.dom.innerHTML.length > 0){
                this.setRawValue(this.el.dom.innerHTML);
            }
        },
    
        /**
         * Returns true if this field has been changed since it was originally loaded.
         */
        isDirty : function() {
            return String(this.getRawValue()) !== String(this.originalValue);
        },
    
        // private
        afterRender : function(){
            Ext.form.MiscField.superclass.afterRender.call(this);
            this.initEvents();
        },
    
        /**
         * Resets the current field value to the originally-loaded value
         * @param {Boolean} force Force a reset even if the option disableReset is true
         */
        reset : function(force){
            if(!this.disableReset || force === true){
                this.setRawValue(this.originalValue);
            }
        },
    
        // private
        initEvents : function(){
            // reference to original value for reset
            this.originalValue = this.getRawValue();
        },
    
        /**
         * Returns whether or not the field value is currently valid
         * Always returns true, not used in MiscField.
         * @return {Boolean} True
         */
        isValid : function(){
            return true;
        },
    
        /**
         * Validates the field value
         * Always returns true, not used in MiscField.  Required for Ext.form.Form.isValid()
         * @return {Boolean} True
         */
        validate : function(){
            return true;
        },
    
        processValue : function(value){
            return value;
        },
    
        // private
        // Subclasses should provide the validation implementation by overriding this
        validateValue : function(value){
            return true;
        },
    
        /**
         * Mark this field as invalid
         * Not used in MiscField.  Required for Ext.form.Form.markInvalid()
         */
        markInvalid : function(){
            return;
        },
    
        /**
         * Clear any invalid styles/messages for this field
         * Not used in MiscField.  Required for Ext.form.Form.clearInvalid()
         */
        clearInvalid : function(){
            return;
        },
    
        /**
         * Returns the raw field value.
         * @return {Mixed} value The field value
         */
        getRawValue : function(){
            return this.el.dom.innerHTML;
        },
    
        /**
         * Returns the clean field value - plain text only, strips out HTML tags.
         * @return {Mixed} value The field value
         */
        getValue : function(){
            var f = Ext.util.Format;
            var v = f.trim(f.stripTags(this.getRawValue()));
            return v;
        },
    
        /**
         * Sets the raw field value.
         * @param {Mixed} value The value to set
         */
        setRawValue : function(v){
            this.value = v;
            if(this.rendered){
                this.el.dom.innerHTML = v;
            }
        },
    
        /**
         * Sets the clean field value - plain text only, strips out HTML tags.
         * @param {Mixed} value The value to set
         */
        setValue : function(v){
            var f = Ext.util.Format;
    	this.setRawValue(f.trim(f.stripTags(v)));
        }
    });
    ... and here is the associated CSS (this might be able to be improved on a little):
    Code:
    .x-form-miscfield {
    	height: 22px;
    	line-height: 18px;
    	vertical-align: middle;
    	overflow: hidden;
    }
    .ext-ie .x-form-miscfield {
        height: 22px; /* ie quirks */
        line-height: 18px;
    }
    .ext-strict .x-form-miscfield {
        height: 18px;
    }
    .ext-safari .x-form-miscfield {
        height: 20px; /* safari always same size */
    }
    .ext-gecko .x-form-miscfield {
        padding-top: 2px; /* FF won't center the text vertically */
        padding-bottom: 0;
    }

    UPDATE 1: Added new 'disableReset' option as proposed by devnull. When true, this field is untouched when the reset() method is called (i.e. from a form reset). Also, if 'disableReset' is true, but you would like to force a reset manually, you can do so by passing 'true' to the reset method (i.e. miscfield.reset(true);)

    UPDATE 2 (9/21/07): Refactored code to be more compatible with Ext 1.1.x (was previously based off of Ext 1.0).
    Attached Images
    Last edited by Nullity; 21 Sep 2007 at 7:51 AM. Reason: version 1.1

  2. #2
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default


    I updated the code in the first post to fix a couple bugs.

    See discussion here:
    http://extjs.com/forum/showthread.php?t=7293

  3. #3
    Ext User
    Join Date
    May 2007
    Posts
    25
    Vote Rating
    0
    cgoss is on a distinguished road

      0  

    Lightbulb Great extension - addition

    Great extension - addition


    Hey, this worked great, thanks for posting it. I added a few modifications for my application and to make it easier to change existing TextFields to MiscFields:

    In the Extend function:
    Code:
    /**
    * Returns the name attribute of the field if available
    * @return {String} name The field name
    */
    getName: function(){
         return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
    },
    And in the Constructer:
    Code:
    Ext.form.MiscField = function(config){
        config.id = config.name;
        Ext.form.MiscField.superclass.constructor.call(this, config);
    };
    These may seem like hacks, but I wanted to fill the fields dynamically, after they are already rendered like normal TextFields.

    My form fill code is now:
    Code:
    frm.add( new Ext.form.MiscField({fieldLabel: 'Author',	name: 'author'	}));
    And I later fill the data with frm.setValues(...);

    Thanks again!

  4. #4
    Ext User
    Join Date
    May 2007
    Posts
    13
    Vote Rating
    0
    mrogers is on a distinguished road

      0  

    Default


    One more addition to the js:

    Code:
    getName : function(){
    		return this.Name;
    	},

  5. #5
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default


    Oops...

    I updated the code in the first post to add the 'getName' method back in (sorry about that), and also fixed an IE bug with the CSS.

  6. #6
    Ext User dantheman's Avatar
    Join Date
    Mar 2007
    Posts
    259
    Vote Rating
    1
    dantheman is on a distinguished road

      0  

    Wink another vote for getName()

    another vote for getName()


    I must have grabbed the source before getName() was added back.
    Beware: findField will bomb for the whole form without it.

    MiscField is very useful. Thanks for posting it.
    --dan

  7. #7
    Ext JS Premium Member
    Join Date
    Jul 2007
    Posts
    218
    Vote Rating
    1
    ZooKeeper is on a distinguished road

      0  

    Default


    Thanks for an outstanding piece of code u shared with us.
    One improvement that'd be really handy is autoheight, based on the text. Something like multiline. Will be just awesome!

  8. #8
    Ext User
    Join Date
    Jun 2007
    Posts
    56
    Vote Rating
    0
    gnosis is on a distinguished road

      0  

    Default


    Quote Originally Posted by cgoss View Post
    And I later fill the data with frm.setValues(...);
    Note that when using this technique, any HTML tags will be stripped out of your value. If you want to do any HTML, you can set the MiscField separately via setRawValue();

    Useful extension!

    -G

  9. #9
    Ext User
    Join Date
    Aug 2007
    Posts
    8
    Vote Rating
    0
    hendersf is on a distinguished road

      0  

    Exclamation I'm getting a JS error :-(

    I'm getting a JS error :-(


    When I load this JavaScript extension, I'm getting a javascript error from ext-base.

    Code:
       Error: sp has no properties
       Source File: http://localhost/francois/ext-1.1/ad...xt/ext-base.js
       Line: 10

    Also as soon as I'm trying to use it, I have a second error that shows up

    Code:
       Error: Ext.form.MiscField.superclass has no properties
       Source File: http://localhost/francois/scripts/MiscField.js
       Line: 11
    Any idea?

    Thanks in advance for any input

    Francois

  10. #10
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default


    Quote Originally Posted by hendersf View Post
    When I load this JavaScript extension, I'm getting a javascript error from ext-base.

    Code:
       Error: sp has no properties
       Source File: http://localhost/francois/ext-1.1/ad...xt/ext-base.js
       Line: 10

    Also as soon as I'm trying to use it, I have a second error that shows up

    Code:
       Error: Ext.form.MiscField.superclass has no properties
       Source File: http://localhost/francois/scripts/MiscField.js
       Line: 11
    Any idea?

    Thanks in advance for any input

    Francois
    Hmm, I'm not really sure. I am also using ext-base.js and I haven't had any issues. Make sure the javascript files are being included in the correct order and the paths to each file are correct.

    Correct order:
    Code:
    <script type="text/javascript" src="/ext/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="/ext/ext-all.js"></script>
    <script type="text/javascript" src="MiscField.js"></script>
    If that's not it, you may need to post some of your code.