Custom TV - best way to set default state for custom variable in ext.js

Hello,

I’m developing a set of custom tv for our studio, one of them is a combo type:

<select id="tv{$tv->id}" name="tv{$tv->id}">
    {foreach from=$opts item=item}
        <option value="{$item.value}" {if $item.selected} selected="selected" {/if}>{$item.text}</option>
    {/foreach}
</select>

<script>
    // <![CDATA[
    {literal}
        Ext.onReady(function() {
            const fld = MODx.load({
            {/literal}
            xtype: 'combo'
                ,transform: 'tv{$tv->id}'
                ,id: 'tv{$tv->id}'
                ,itemId: 'tv{$tv->id}'
                ,
            triggerAction: 'all',
            width: 400,
            maxHeight: 300
                ,allowBlank: {if $params.allowBlank == 1 || $params.allowBlank == 'true'}true{else}false{/if}
                {if $params.typeAhead == 1 || $params.typeAhead == 'true'}
                    ,
                editable: true,
                typeAhead: true
                    ,typeAheadDelay: {if $params.typeAheadDelay|default && $params.typeAheadDelay|default != ''}{$params.typeAheadDelay|default}{else}250{/if}
                {else}
                    ,
                editable: false,
                typeAhead: false
                {/if}
                {if $params.title|default}
                    ,title: '{$params.title|default|escape}'
                {/if}
                {if $params.listEmptyText|default}
                    ,listEmptyText: '{$params.listEmptyText|default|escape}'
                {/if}
                ,forceSelection: {if $params.forceSelection|default && $params.forceSelection|default != 'false'}true{else}false{/if}
                ,
            msgTarget: 'under'
                {literal}
                    ,
                listeners: {
                    afterrender: {
                        fn: function(cmp) {
                            console.log('after render?')
                            setTimeout(() => {
                                var tvTabs = Ext.getCmp('modx-resource-vtabs');
                                console.log(tvTabs, "TABS")
                            }, 0);
                        },
                        scope: this
                    },
                    select: {
                        fn: function(combo, record) {
                            console.log(combo)
                            MODx.fireResourceFormChange;
                            var tvTabs = Ext.getCmp('modx-resource-vtabs');
                            if (tvTabs && tvTabs.items && tvTabs.items.keys) {
                                tvTabs.items.items.forEach((category, idx) => {
                                    if (category.title != record.data.value && category.title !=
                                        tvTabs.activeTab.title) {
                                        Ext.getCmp('modx-resource-vtabs').hideTabStripItem(
                                            category.id);

                                    } else {
                                        Ext.getCmp('modx-resource-vtabs').unhideTabStripItem(
                                            category.id);
                                    }
                                });
                            }
                        },
                        scope: this
                    },
                }
            });
            Ext.getCmp('modx-panel-resource').getForm().add(fld);
        });
    {/literal}
    // ]]>
</script>

Everything is working great so far for select listener.
However, i want to perform some action for the default “state” for this tv so i found this event “afterrender”. Basically, i want to wait until all elements have been loaded like in jQuery:

$(window).on("load", function() {
    // weave your magic here.
});

and then grab one of the component:

var tvTabs = Ext.getCmp('modx-resource-vtabs');

and play with it a bit.

The problem is that without:

    setTimeout(() => }, 0);

tvTabs is undefined - seems like its needs a tiny delay…
Is there any better way to handle this? Setting setTimeout its a bit dirty and i would love to have nice code haha :slight_smile:

Thanks guys!

I have seen the function Ext.ComponentMgr.onAvailable used in similar situations:

Maybe this works here as well. I’m not sure. You have to try it.