Results 1 to 5 of 5

Thread: Ext.ux.form.TriCheckbox

  1. #1
    Ext User
    Join Date
    Jul 2007
    Posts
    9
    Vote Rating
    0
      0  

    Default Ext.ux.form.TriCheckbox

    Hi,

    Thought this may be of use to someone - it's a three-state checkbox field. It can be set to inherited (inherits either on or off) or set to on or off. The checkbox states are indicated by images.

    The setInheritedValue() method sets whether the control is inheriting on or off.
    Applying setValue(null) means the control will use the inherited state.
    Returns blank, zero or one on submit to indicate 'inherited', 'off' or 'on'.

    I've attached the images I use as well as the css and js. Could do with some lovin' but it works well for what I needed. Any/all feedback welcome, if it needs more explanation just post it here.

    Cheers,

    Scott


    Code:
    /**
     * Ext.ux.form.TriCheckbox - Tri-state checkbox
     *
     * @license Ext.ux.form.TriCheckbox is licensed under the terms of
     * the Open Source LGPL 3.0 license.  Commercial use is permitted to the extent
     * that the code/component(s) do NOT become part of another Open Source or Commercially
     * licensed development library or toolkit without explicit permission.
     * 
     * License details: http://www.gnu.org/licenses/lgpl.html
     */
    
    /**
      * 
      * Default css:
      * .tricheckbox-wrap {
      *     line-height: 18px;
      *     padding-top:2px;
      * }
      * .tricheckbox-wrap a {
      *     display:block;
      *     width:16px;
      *     height:16px;
      *     float:left;
      * }
      * .x-toolbar .tricheckbox-wrap {
      *     padding: 0 0 2px 0;
      * }
      * .tricheckbox-on {
      *     background:transparent url(./ext/resources/images/default/menu/checked.gif) no-repeat 0 0;
      * }
      * .tricheckbox-off {
      *     background:transparent url(./ext/resources/images/default/menu/unchecked.gif) no-repeat 0 0;
      * }
      * .tricheckbox-inherit-on {
      *     background:transparent url(./ext/resources/images/default/menu/checked.gif) no-repeat 0 0;
      * }
      * .tricheckbox-inherit-off {
      *     background:transparent url(./ext/resources/images/default/menu/unchecked.gif) no-repeat 0 0;
      * }
      * .tricheckbox-disabled {
      *     opacity: 0.5;
      *     -moz-opacity: 0.5;
      *     filter: alpha(opacity=50);
      *     cursor:default;
      * }
      *
      * @class Ext.ux.TriCheckbox
      * @extends Ext.form.Checkbox
      */
    Ext.ns('Ext.ux.form');
    Ext.ux.form.TriCheckbox = Ext.extend(Ext.form.Checkbox, {
         offCls:'tricheckbox-off'
        ,onCls:'tricheckbox-on'
        ,inheritOnCls:'tricheckbox-inherit-on'
        ,inheritOffCls:'tricheckbox-inherit-off'
    	 
        ,disabledClass:'tricheckbox-disabled'
        ,submitOffValue:'false'
        ,submitOnValue:'true'
    	 ,submitInheritedValue:''
    	 ,inheritedValue: false //Iherited checkbox state is checked or not
        ,chk: null //Default to inherited
    	 ,allowInherited: true //Toggles the inherited/standard behaviour
    
        ,onRender:function(ct) {
            // call parent
            Ext.ux.form.TriCheckbox.superclass.onRender.apply(this, arguments);
    
    	//Set the initial value
    	if(Ext.isEmpty(this.chk)) {
    		this.chk = (this.allowInherited ? null : false);
    	}
    
            // save tabIndex remove & re-create this.el
            var tabIndex = this.el.dom.tabIndex;
            var id = this.el.dom.id;
            this.el.remove();
            this.el = ct.createChild({tag:'input', type:'hidden', name:this.name, id:id});
    
            // update value of hidden field
            this.updateHidden();
    
            // adjust wrap class and create link with bg image to click on
            this.wrap.replaceClass('x-form-check-wrap', 'tricheckbox-wrap');
            this.cbEl = this.wrap.createChild({
    								tag:'a',
    								href:'#',
    								cls: ((this.chk == null && this.allowInherited)
    										 ? (this.inheritedValue ? this.inheritOnCls : this.inheritOffCls)
    										 : (this.chk ? this.onCls : this.offCls)
    										 )
    								});
    
            // reposition boxLabel if any
            var boxLabel = this.wrap.down('label');
            if(boxLabel) {
                this.wrap.appendChild(boxLabel);
            }
    
            // support tooltip
            if(this.tooltip) {
                this.cbEl.set({qtip:this.tooltip});
            }
    
            // install event handlers
            this.wrap.on({click:{scope:this, fn:this.onClick, delegate:'a'}});
            this.wrap.on({keyup:{scope:this, fn:this.onClick, delegate:'a'}});
    
            // restore tabIndex
            this.cbEl.dom.tabIndex = tabIndex;
        } // eo function onRender
    
        ,onClick:function(e) {
            if(this.disabled || this.readOnly) {
                return;
            }
            if(!e.isNavKeyPress()) {
    				switch (this.chk) {
    				case null: this.setValue(false); break;					
    				case false: this.setValue(true); break;
    				case true: (this.allowInherited ? this.setValue(null) : this.setValue(false)); break;
    				}
            }
        } // eo function onClick
    
        ,onDisable:function() {
            this.cbEl.addClass(this.disabledClass);
            this.el.dom.disabled = true;
        } // eo function onDisable
    
        ,onEnable:function() {
            this.cbEl.removeClass(this.disabledClass);
            this.el.dom.disabled = false;
        } // eo function onEnable
    
    	 ,setInheritedValue: function(val) {
    		if (val == null) { //Inherited
    			this.inheritedValue = (this.allowInherited ? null : false);
    		} else { //Match to a boolean
    			this.inheritedValue = !(!val);
    		}
    
    		//Redraw the checkbox
    		this.redraw();
    	 }
        ,setValue:function(val) {
    
    			if (val == null) { //Inherited
    				this.chk = (this.allowInherited ? null : false);
    			} else if('string' == typeof val) { //Match to the submit value
                this.chk = val === this.submitOnValue;
    			} else { //Match to a boolean
                this.chk = !(!val);
             }
    
    			//Redraw the checkbox
    			this.redraw();
    			
    			//Notify that the state was changed
            this.fireEvent('check', this, this.chk);
    
        } // eo function setValue
    	 
    	 ,redraw: function() {
    
            if(this.rendered && this.cbEl) {
                this.updateHidden();
                this.cbEl.removeClass([this.offCls, this.onCls, this.inheritOffCls, this.inheritOnCls]);
                this.cbEl.addClass(
    										 ((this.chk == null && this.allowInherited)
    										 ? (this.inheritedValue ? this.inheritOnCls : this.inheritOffCls)
    										 : (this.chk ? this.onCls : this.offCls)
    										 )
    									);
            }
    	 }
    
        ,updateHidden:function() {
            this.el.dom.value = (
    									  (this.chk == null && this.allowInherited)
    									  ? this.submitInheritedValue
    									  : (this.chk ? this.submitOnValue : this.submitOffValue)
    									);
        } // eo function updateHidden
    
        ,getValue:function() {
            return this.chk;
        } // eo function getValue
    
    }); // eo extend
    
    // register xtype
    Ext.reg('tricheckbox', Ext.ux.form.TriCheckbox);
    Attached Files Attached Files
    Last edited by scottpederick; 1 Sep 2009 at 3:55 AM. Reason: Updated code with Zolcsi's fix

  2. #2
    Sencha Premium User
    Join Date
    Oct 2007
    Location
    Berlin, Germany
    Posts
    891
    Vote Rating
    12
      0  

    Default

    Nice code. Based on sakis XCheckbox i guess?. Only the design of the boxes should fit more to the standard Ext theme for my taste.

    i changed css to use the default checkboxes from "resources/images/default/menu/" folder of ext distribution. (checked.gif and unchecked.gif) and a third gif with checked and darker background will look more perfect to me.

  3. #3
    Ext User
    Join Date
    Jul 2007
    Posts
    9
    Vote Rating
    0
      0  

    Default

    Ah yes - I meant to give credit to XCheckbox (http://extjs.com/forum/showthread.php?t=25924) without which this wouldn't have been written. Many thanks to jsakalos for all his fine work. It's just a small mod on top.

    The big, shiny checkboxes sit in line with some other pieces and thought I'd share them around. If you need to use the full inherited featureset, you'd have to create two 'inherited' (greyed) images - one checked and the other unchecked.

  4. #4
    Sencha User
    Join Date
    Dec 2007
    Location
    Budapest, Hungary
    Posts
    125
    Vote Rating
    7
      0  

    Default

    I had one small little problem with this component.
    If I set the value before it was rendered, then the value just gets ignored.
    Here is my fix:

    Instead of this: (line 70)
    Code:
    this.chk = (this.allowInherited ? null : false);
    I use this:
    Code:
    if(Ext.isEmpty(this.chk)) {
    	this.chk = (this.allowInherited ? null : false);
    }
    Hope this helps somebody.
    And thanks for this component!

  5. #5
    Ext User
    Join Date
    Jul 2007
    Posts
    9
    Vote Rating
    0
      0  

    Default

    Thanks for the fix

    I've updated the first thread code and zip.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •