1. #1
    Ext JS Premium Member
    Join Date
    Jul 2009
    Location
    Seattle, Washington USA
    Posts
    200
    Vote Rating
    0
    geewhizbang is on a distinguished road

      0  

    Default small-button extjs object

    small-button extjs object


    Has anyone written a small-button ExtJS object? Someone wrote a link button extending the button object, but I don't understand how the render function worked so I could modify it to my own needs. It had layout that was way too complicated using an over-elaborate table to construct the elements. I just want to use some divs for my button.

    I would like to have some buttons that are smaller than standard buttons, but it would be helpful if they are an ExtJS object.

    What i would like is a button that is built approximately like this when it is rendered:

    <div class="smallBtn" onmouseover="btnMO(this,true)" onmouseover = "btnMO(this,false)" onclick=handler(this)><div class='btnLeft'>&nbsp;</div><div class="btnText">Button Text</div><div class='btnRight'>&nbsp;</div></div>

  2. #2
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    91
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    A simple BoxComponent could do that, e.g.
    Code:
    {
      xtype: 'box',
      autoEl: {
        cls: 'smallBtn',
        children: [{
          cls: 'btnLeft',
          cn: '&#160;'
        },{
          cls: 'btnText',
          cn: 'Button Text'
        },{
          cls: 'btnRight',
          cn: '&#160;'
        }
      },
      listeners: {
        render: function(c){
          var el = c.getEl();
          el.on({
            mouseover: btnMO.createCallback(el.dom, true),
            mouseout: btnMO.createCallback(el.dom, false),
            click: handler.createCallback(el.dom)
          });
        }
      }
    }

  3. #3
    Ext JS Premium Member
    Join Date
    Jul 2009
    Location
    Seattle, Washington USA
    Posts
    200
    Vote Rating
    0
    geewhizbang is on a distinguished road

      0  

    Default


    That is helpful. But I also want it to inherit from button to have all of the useful states, and the ability to use the handler events with the button.

    The example you just posted makes it clearer how to attach functions to an object, which is new to me.

  4. #4
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,503
    Vote Rating
    49
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Use a Button:

    Code:
    new Ext.Button({
        template: new Ext.Template(
            '<div class="smallBtn">',
                '<div class="btnLeft">&#160;</div>',
                '<div class="btnText"></div>',
                '<div class="btnRight">&#160;</div>',
            '</div>'),
        buttonSelector: '.btnText',
        text: 'My Button',
        renderTo: document.body,
        handler: function() {
            alert("You clicked?");
        }
    });

  5. #5
    Ext JS Premium Member
    Join Date
    Jul 2009
    Location
    Seattle, Washington USA
    Posts
    200
    Vote Rating
    0
    geewhizbang is on a distinguished road

      0  

    Default


    Code:
     
    // a little helper function to write the modified button:
    $KB.XButton = function (params) 
    {
        params.template = new Ext.Template
        (
            '<div class="' + $KB.FixNull(params.cls, "SD_Btn") + '">', 
            '<div class="SD_L"> </div>',
             '<div class="SD_Text"></div>', '<div class="SD_R"> </div>',
             '</div>'
        );
        params.buttonSelector = 'SD_Text';
        return new Ext.Button(params);
    };
    Using the button in some code where a standard button was too big, but otherwise worked OK:
    Code:
    kbForum.btnForumManage = $KB.XButton
    (
        {
            text: 'Forum Management',
            handler: kbForum.Manage,
            id: 'btnForumManage'
        }
    );
    var c = Ext.getCmp('forumButtonBar');
    c.add(kbForum.btnForumManage);
    //fails here:
    c.doLayout();
    Extjs code. I'm not sure which object this is from, since we have munged all the code together in one big file:
    Code:
    // internal function for auto removal of assigned event handlers on destruction
    mon: function (item, ename, fn, scope, opt) {
       this.createMons();
       if (Ext.isObject(ename)) {
           var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
           var o = ename;
           for (var e in o) {
               if (propRe.test(e)) {
                   continue;
               }
               if (Ext.isFunction(o[e])) {
                   // shared options
                   this.mons.push({
                       item: item,
                       ename: e,
                       fn: o[e],
                       scope: o.scope
                   });
                    item.on(e, o[e], o.scope, o);  //this line: o.scope is not defined
               } else {
                   // individual options
                   this.mons.push({
                       item: item,
                       ename: e,
                       fn: o[e],
                       scope: o.scope
                   });
                   item.on(e, o[e]);
               }
           }
           return;
       }
       this.mons.push({
           item: item,
           ename: ename,
           fn: fn,
           scope: scope
       });
       item.on(ename, fn, scope, opt);
    },
    My guess is that we need to pass scope somehow, but I have never needed to do that anywhere else as the default scope was fine. So I'm not exactly sure what scope needs to be passed for this to work.

    Using a helper function to create the button for me is a bit easier to comprehend. I know that we should probably be using Ext.Extend to build this, but every attempt to do try tat so far has resulted in non-functional code.

    BTW I don't see how this code passes the Button state to the html/CSS objects, BTW. If there are parameters that have to be included in the template for that to happen, I need to do that too.

  6. #6
    Ext JS Premium Member
    Join Date
    Jul 2009
    Location
    Seattle, Washington USA
    Posts
    200
    Vote Rating
    0
    geewhizbang is on a distinguished road

      0  

    Default


    The scope issue happens even if I don't use the helper function.

  7. #7
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,503
    Vote Rating
    49
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Then use the documented way of telling the handler what scope to use!

  8. #8
    Ext JS Premium Member
    Join Date
    Jul 2009
    Location
    Seattle, Washington USA
    Posts
    200
    Vote Rating
    0
    geewhizbang is on a distinguished road

      0  

    Default


    I guess I will have to move my question to the premium area, where I get answers instead of insults.

    I posted this here in the first place because I thought it would be of general use to develop a more easily skinned, simpler button object.

    If I knew the answer to this I wouldn't be asking the questions. I am fairly familiar with the documentation by now, but there is still an ongoing problem of a lack of specific examples to make very complex concepts clear.

    In this case, for example, why do I need to pass a scope? Why isn't it using the default scope for this object? Could this be a bug? Or is the button object overly dependent on the complex default format and barfs on this simpler one? The object name is "o" which also isn't very helpful to help me determine what scope to pass.

    If Animal could take a few moments to answer the question with an example, then there would be a searchable answer to be found.

  9. #9
    Ext JS Premium Member
    Join Date
    Jul 2009
    Location
    Seattle, Washington USA
    Posts
    200
    Vote Rating
    0
    geewhizbang is on a distinguished road

      0  

    Default


    Going back to the original reply by condor, i made this:
    Code:
     
    Ext.ux.sButton = Ext.extend(
    Ext.BoxComponent, {
        initComponent: function () {
            Ext.apply(
            this, {
                autoEl: {
                    cls: $KB.FixNull(this.initialConfig.cls, 'SD_btn'),
                    children: [{
                        cls: 'SD_L',
                        cn: ' '
                    },
                    {
                        cls: 'SD_Text',
                        cn: this.initialConfig.text
                    },
                    {
                        cls: 'SD_R',
                        cn: ' '
                    }]
                }
            });
            Ext.ux.sButton.superclass.initComponent.apply(this, arguments);
        },
        onRender: function () {
            Ext.ux.sButton.superclass.onRender.apply(this, arguments);
            var el = this.getEl();
            el.on({
                mouseover: btnMO.createCallback(el.dom, true),
                mouseout: btnMO.createCallback(el.dom, false),
               click: this.initialConfig.handler.createCallback(el.dom)
            })
        }
    });
    Ext.reg('sbutton', Ext.ux.sButton);
    how it gets used
    Code:
     
    if ($KB.LoggedIn) {
        kbForum.btnForumManage = new Ext.ux.sButton({
            text: 'Forum Management',
            handler: kbForum.Manage,
            id: 'btnForumManage'
        });
        var c = Ext.getCmp('forumButtonBar');
        c.add(kbForum.btnForumManage);
        c.doLayout();
    }
    This runs just fine now, but I want to add facilities to disable this button similar to a regular button. To do this it would be helpful to know how to make the btnMO handler code internal to this new object, and to have methods that enable/disable the button as well.

    Currently the btnMO code just handles the mouseover by changing the style of the outer element to append "_mo" to the class name. The disable code needs to append "_dis" to the class name.
    Last edited by geewhizbang; 21 Dec 2009 at 12:13 PM. Reason: fixed typo

  10. #10
    Ext JS Premium Member
    Join Date
    Jul 2009
    Location
    Seattle, Washington USA
    Posts
    200
    Vote Rating
    0
    geewhizbang is on a distinguished road

      0  

    Default


    The remaining issue is how to apply margins to my object.
    Code:
    /*
     * nGenera Knowledgebase
     * Copyright(c) 2006-20010 nGenera, Inc.
     */
    Ext.ux.btnMO = function (objOrId, bMO) {
        var objBtn = $g(objOrId);
        InitBtn(objBtn);
        if (objBtn.disabled) return;
        if (objBtn.moData == "") return;
        if (IsImgBtn(objBtn)) {
            objBtn.src = objBtn.moData + (bMO ? "_mo" : "") + objBtn.moExt;
        } else {
            objBtn.className = objBtn.moData + (bMO ? "_mo" : "");
        }
        objBtn.style.cursor = (bMO ? (Ext.isIE ? "hand" : "pointer") : "default");
        function InitBtn(objBtn) {
            if (typeof(objBtn.moData) != "undefined" && objBtn.moData != null) return;
            var moData;
            var aT;
            if (IsImgBtn(objBtn)) {
                var src = objBtn.src;
                aT = src.split(".");
                objBtn.moExt = "." + aT[aT.length - 1];
                moData = src.substr(0, src.length - objBtn.moExt.length);
            } else {
                moData = objBtn.className;
            }
            aT = moData.split("_");
            objBtn.disabled = (aT.length > 1) && (aT[aT.length - 1].toLowerCase() == "dis");
            objBtn.moData = (objBtn.disabled ? moData.substr(0, moData.length - 5) : moData);
        }
        function IsImgBtn(objBtn) {
            if (typeof(objBtn.IsImg) != "undefined") return objBtn.IsImg;
            var tn = objBtn.tagName.toUpperCase();
            objBtn.IsImg = ((tn == "IMG") || ((tn == "INPUT") && (objBtn.type.toUpperCase() == "IMAGE")))
            return objBtn.IsImg;
        }
    };
    Ext.ux.sButton = Ext.extend(
    Ext.BoxComponent, {
        initComponent: function () {
            Ext.apply(
            this, {
                margins: this.initialConfig.margins,
                autoEl: {
                    cls: $KB.FixNull(this.initialConfig.cls, 'SD_btn'),
                    children: [{
                        cls: 'SD_L',
                        cn: '&#160;'
                    },
                    {
                        cls: 'SD_Text',
                        cn: this.initialConfig.text
                    },
                    {
                        cls: 'SD_R',
                        cn: '&#160;'
                    }]
                }
            });
            Ext.ux.sButton.superclass.initComponent.apply(this, arguments);
        },
        onRender: function () {
            Ext.ux.sButton.superclass.onRender.apply(this, arguments);
            var el = this.getEl();
            el.on({
                mouseover: Ext.ux.btnMO.createCallback(el.dom, true),
                mouseout: Ext.ux.btnMO.createCallback(el.dom, false),
                click: this.initialConfig.handler.createCallback(el.dom)
            })
        },
        onDisable: function () {
            var c = this.getEl().dom;
            c.disabled = true;
            c.className = $KB.FixNull(this.initialConfig.cls, 'SD_btn') + "_dis";
        },
        onEnable: function () {
            var c = this.getEl().dom;
            c.disabled = false;
            c.className = $KB.FixNull(this.initialConfig.cls, 'SD_btn');
        }
    });
    Ext.reg('sbutton', Ext.ux.sButton);

Thread Participants: 2