sefirosu
sefirosu

Reputation: 2648

CQ, custom widget for text, link, checkbox in multifield

please see the image below, this is the component i am trying to build. a custom widget with text, link and checkbox.

enter image description here

so far, i can manage to get interface party showing up correctly, as you can see in the image. but, soon as i click 'ok' it will throw me a 'Uncaught TypeError: undefined is not a function' as showed in red underline in image...so obviously it wont be able to pass any object data into JSP layer for me to use later....

so, basically, it complaining about that 'vt' is undefined.... i dont have a clud why it is happening... here is my code for generating the widget

/**
 * @class MapLinks.CustomWidget
 * @extends CQ.form.CompositeField
 * This is a custom widget based on {@link CQ.form.CompositeField}.
 * @constructor
 * Creates a new CustomWidget.
 * @param {Object} config The config object
 */
CQ.form.KeyValueLinkSelection = CQ.Ext.extend(CQ.form.CompositeField, {

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    hiddenField: null,

    /**
     * @private
     * @type CQ.Ext.form.Label
     */
    textLabel: null,

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    textField: null,

    /**
     * @private
     * @type CQ.Ext.form.Label
     */
    pathLabel: null,

    /**
     * @private
     * @type CQ.form.PathField
     */
    pathField: null,

    /**
     * @private
     * @type CQ.Ext.form.Label
     */
    checkboxLabel: null,

    /**
     * @private
     * @type CQ.Ext.form.Checkbox
     */
    checkbox: null,

    constructor: function(config) {
        config = config || { };
        var defaults = {
            "border": false,
            "layout": "table",
            "columns": 6
        };
        config = CQ.Util.applyDefaults(config, defaults);
        CQ.form.KeyValueLinkSelection.superclass.constructor.call(this, config);
    },

    // overriding CQ.Ext.Component#initComponent
    initComponent: function() {

        CQ.form.KeyValueLinkSelection.superclass.initComponent.call(this);


        this.hiddenField = new CQ.Ext.form.Hidden({
            name: this.name
        });
        this.add(this.hiddenField);

        this.textLabel = new CQ.Ext.form.Label({
            cls:"keyvaluelinkselection-1",
            text:"Text:",
            style:"font-size: 12px; font-family: Arial, Verdana, sans-serif; vertical-align:text-bottom; padding-bottom:0px; padding-right:5px; padding-left:10px;"
        });
        this.add(this.textLabel);

        this.textField = new CQ.Ext.form.TextField({
            cls:"keyvaluelinkselection-2",
            listeners: {
                change: {
                    scope:this,
                    fn:this.updateHidden
                }
            }
        });
        this.add(this.textField);

        this.pathLabel = new CQ.Ext.form.Label({
            cls:"keyvaluelinkselection-3",
            text:"Link:",
            style:"font-size: 12px; font-family: Arial, Verdana, sans-serif; vertical-align:text-bottom; padding-bottom:0px; padding-right:5px; padding-left:15px;"
        });
        this.add(this.pathLabel);

        this.pathField = new CQ.form.PathField({
            cls:"keyvaluelinkselection-4",
            width:"150",
            listeners: {
                change: {
                    scope:this,
                    fn:this.updateHidden
                },
                dialogselect: {
                    scope:this,
                    fn:this.updateHidden
                }
            }
        });
        this.add(this.pathField);

        this.checkboxLabel = new CQ.Ext.form.Label({
                cls:"keyvaluelinkselection-5",
                text:"open in new tab:",
                style:"font-size: 12px; font-family: Arial, Verdana, sans-serif; vertical-align:text-bottom; padding-bottom:0px; padding-right:5px; padding-left:20px;"
            });
        this.add(this.checkboxLabel);

        this.checkbox = new CQ.Ext.form.Checkbox({
            cls:"keyvaluelinkselection-6",
            width:"30",
            listeners: {
                change: {
                    scope:this,
                    fn:this.updateHidden
                },
                dialogselect: {
                    scope:this,
                    fn:this.updateHidden
                }
            }
        });
        this.add(this.checkbox);
    },

    // overriding CQ.form.CompositeField#processPath
    processPath: function(path) {
        this.textField.processPath(path);
    },

    // overriding CQ.form.CompositeField#processRecord
    processRecord: function(record, path) {
        this.textField.processRecord(record, path);
    },

    // overriding CQ.form.CompositeField#setValue
    setValue: function(value) {
        var parts = value.split("}={");
        this.textField.setValue(parts[0]);
        this.pathField.setValue(parts[1]);
        this.checkbox.setValue(parts[2]);
        this.hiddenField.setValue(value);
    },

    // overriding CQ.form.CompositeField#getValue
    getValue: function() {
        return this.getRawValue();
    },

    // overriding CQ.form.CompositeField#getRawValue
    getRawValue: function() {
        return this.textField.getValue() + "}={" +
            this.pathField.getValue()  + "}={" +
            this.checkbox.getValue();
    },

    // private
    updateHidden: function() {
        this.hiddenField.setValue(this.getValue());
    }

});

// register xtype
CQ.Ext.reg('keyvaluelinkselection', CQ.form.KeyValueLinkSelection);

bascially, i was flowing the tutorial giving by adobe -> http://helpx.adobe.com/experience-manager/using/dynamically-updating-aem-custom-xtype.html

any hints will be helpful, thanks

Upvotes: 0

Views: 3076

Answers (1)

sefirosu
sefirosu

Reputation: 2648

i actually figured out myself.... basically, just override validateValue: function(value)

here is the whole code example:

CQ.form.KeyValueLinkSelection = CQ.Ext.extend(CQ.form.CompositeField, {

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    hiddenField: null,

    /**
     * @private
     * @type CQ.Ext.form.Label
     */
    textLabel: null,

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    textField: null,

    /**
     * @private
     * @type CQ.Ext.form.Label
     */
    pathLabel: null,

    /**
     * @private
     * @type CQ.form.PathField
     */
    pathField: null,

    /**
     * @private
     * @type CQ.Ext.form.Label
     */
    checkboxLabel: null,

    /**
     * @private
     * @type CQ.Ext.form.Checkbox
     */
    checkbox: null,

    constructor: function(config) {
        config = config || { };
        var defaults = {
            "border": false,
            "layout": "table",
            "columns": 6
        };
        config = CQ.Util.applyDefaults(config, defaults);
        CQ.form.KeyValueLinkSelection.superclass.constructor.call(this, config);
    },

    // overriding CQ.Ext.Component#initComponent
    initComponent: function() {

        CQ.form.KeyValueLinkSelection.superclass.initComponent.call(this);


        this.hiddenField = new CQ.Ext.form.Hidden({
            name: this.name
        });
        this.add(this.hiddenField);

        this.textLabel = new CQ.Ext.form.Label({
            cls:"keyvaluelinkselection-1",
            text:"Text:",
            style:"font-size: 12px; font-family: Arial, Verdana, sans-serif; vertical-align:text-bottom; padding-bottom:0px; padding-right:5px; padding-left:10px;"
        });
        this.add(this.textLabel);

        this.textField = new CQ.Ext.form.TextField({
            cls:"keyvaluelinkselection-2",
            allowBlank: false,
            listeners: {
                change: {
                    scope:this,
                    fn:this.updateHidden
                }
            }
        });
        this.add(this.textField);

        this.pathLabel = new CQ.Ext.form.Label({
            cls:"keyvaluelinkselection-3",
            text:"Link:",
            style:"font-size: 12px; font-family: Arial, Verdana, sans-serif; vertical-align:text-bottom; padding-bottom:0px; padding-right:5px; padding-left:15px;"
        });
        this.add(this.pathLabel);

        this.pathField = new CQ.form.PathField({
            cls:"keyvaluelinkselection-4",
            width:"150",
            allowBlank: false,
            listeners: {
                change: {
                    scope:this,
                    fn:this.updateHidden
                },
                dialogselect: {
                    scope:this,
                    fn:this.updateHidden
                }
            }
        });
        this.add(this.pathField);

        this.checkboxLabel = new CQ.Ext.form.Label({
            cls:"keyvaluelinkselection-5",
            text:"open in new tab:",
            style:"font-size: 12px; font-family: Arial, Verdana, sans-serif; vertical-align:text-bottom; padding-bottom:0px; padding-right:5px; padding-left:20px;"
        });
        this.add(this.checkboxLabel);

        this.checkbox = new CQ.Ext.form.Checkbox({
            cls:"keyvaluelinkselection-6",
            width:"30",
            listeners: {
                change: {
                    scope:this,
                    fn:this.updateHidden
                },
                dialogselect: {
                    scope:this,
                    fn:this.updateHidden
                }
            }
        });
        this.add(this.checkbox);
    },

    validateValue: function(value) {
        if(value.length < 1){ // if it's blank
             if(this.allowBlank){
                 this.clearInvalid();
                 return true;
             }else{
                 this.markInvalid(this.blankText);
                 return false;
             }
        }
        if(this.vtype){
            //TO DO, may need this condition checker later on
        }
        if(typeof this.validator == "function"){
            var msg = this.validator(value);
            if(msg !== true){
                this.markInvalid(msg);
                return false;
            }
        }
        if(this.regex && !this.regex.test(value)){
            this.markInvalid(this.regexText);
            return false;
        }
        return true;
    },

    // overriding CQ.form.CompositeField#processPath
    processPath: function(path) {
        this.textField.processPath(path);
    },

    // overriding CQ.form.CompositeField#processRecord
    processRecord: function(record, path) {
        this.textField.processRecord(record, path);
    },

    // overriding CQ.form.CompositeField#setValue
    setValue: function(value) {
        var parts = value.split("|");
        this.textField.setValue(parts[0]);
        this.pathField.setValue(parts[1]);
        this.checkbox.setValue(parts[2]);
        this.hiddenField.setValue(value);
    },

    // overriding CQ.form.CompositeField#getValue
    getValue: function() {
        return this.getRawValue();
    },

    // overriding CQ.form.CompositeField#getRawValue
    getRawValue: function() {
        return this.textField.getValue() + "|" +
            this.pathField.getValue()  + "|" +
            this.checkbox.getValue();
    },

    // private
    updateHidden: function() {
        this.hiddenField.setValue(this.getValue());
    }

});

// register xtype
CQ.Ext.reg('keyvaluelinkselection', CQ.form.KeyValueLinkSelection);

and it 100% works....

Upvotes: 1

Related Questions