ExtJS superselect combobox selected values disappear from time to time,but why

Hi there,

I’m developing custom Extra based on MODX 2.8.5, in short, there are several entities (location, subcategory, menu) related to each other. For each of them I have Grid each line has ability(through the context right click menu) to edit it.

Location Menu _ Demo - Google Chrome 2023-04-26 012

Adding/editing happens as usual inside Window, where I have two linked (through listen “onchange”) custom superselect comboboxes, principle here is to select some locations, after which these values will be passed as a parameter to the second list and it will also be updated with submenus. Selected values are saved.

I have no creation problems, but if I want to edit saved data, selected values behave strangely - if I refresh the page or open / close the Window for same item, then selected values(some of them or all, for one selector or another) can spontaneously disappear, instead of them there are only “crosses”. Please see screenshots.

Location Menu _ Demo - Google Chrome 2023-04-26 015

Can you please tell me what rendering parameters can affect this? Is it possible to always get the correct display without selected values disappearing?
I can provide all the code that you need, answer any counter questions. I checked a lot, all ideas ended (well, ExtJs is also such a kind of spherical horse in vacuum :slight_smile: )

Thanks in advance,
Anton

That looks like a limit issue in the getlist processor. It occurs, when the selected values are not found on the first page. Please make sure, that the getlist processor returns one value when an id (or valuesqry and query) property is set.

Some example code from:

        $valuesQuery = $this->getProperty('valuesqry');
        $id = (!$valuesQuery) ? $this->getProperty('id') : $this->getProperty('query');
        if (!empty($id)) {
            $c->where([
                $this->classKey . '.id:IN' => array_map('intval', explode('|', $id))
            ]);
        }

Thanks @jako for your comment. I’ve checked my code, well, nothing special but I’ve extended it with everything I could find on page you provided…Unfortunately issue is the same.

It seems to me that the problem lies in a slightly different plane … perhaps there is something about updating the contents of the window, unique IDs or an enhanced update/reset of any data … look, I just call the window “refresh” / “close” several times for the same product. And each time different results in the lists.

Location Menu _ Demo - Google Chrome 2023-04-26 188



The data always has time to load, my browser is also fast, the first list contains less than 100 entries (by the way, why can’t paging be more than 100, this is the maximum limit, then it still paginates, what parameter affects this,speech is about superselect #2 ?), Second is divided into two pages. .but as I said, at the next boot I can see how everything is and nothing.

Maybe after closing the window (and the data of the lists) it is necessary for it to do some kind of hard reset? Any ideas will be welcome.

First combo:

menus.combo.Locations = function (config) {
    config = config || {};
    Ext.applyIf(config, {
        id: 'menus-combo-locations',
        fieldLabel: _('locationmenu_' + config.name || 'locationmenu'),
        fields: ['id', 'pagetitle', 'parents'],
        valueField: 'id',
        displayField: 'pagetitle',
        name: 'location_id',
        pageSize: 60,
        hiddenName: 'location_id',
        allowBlank: false,
        url: menus.config['connector_url'],
        baseParams: {
            action: 'mgr/locationmenu/getlocation',
            combo: true,
            id: config.value
        },
        tpl: new Ext.XTemplate('\
            <tpl for=".">\
                <div class="x-combo-list-item minishop2-product-list-item" ext:qtip="{pagetitle}">\
                    <tpl if="parents">\
                        <span class="parents">\
                            <tpl for="parents">\
                                <nobr><small>{pagetitle} / </small></nobr>\
                            </tpl>\
                        </span><br/>\
                    </tpl>\
                    <span><small>({id})</small> <b>{pagetitle}</b></span>\
                </div>\
            </tpl>', {compiled: true}
        ),
        pageSize: 60,
        emptyText: _('locationmenu_empty_list'),
        editable: false,
    });
    menus.combo.Locations.superclass.constructor.call(this, config);
};

Second combo:

menus.combo.Submenus2 = function(config, getStore) {
    config = config || {};

    Ext.applyIf(config, {
        xtype: 'superboxselect',
        name: 'categories',
        fieldLabel: config['name'] || 'categories',
        hiddenName: config['name'] || 'categories',
        originalName: config['name'] || 'categories',
        displayField: 'name',
        valueField: 'id',
        pageSize: 100,
        paging:false,
        
        store: new Ext.data.JsonStore({
            url: menus.config['connector_url'],
            baseParams: {
                action: 'mgr/category/getlist',
            },
            root: 'results',
            totalProperty: 'total',
            autoLoad: true,
            autoSave: false,
            fields: ['id', 'name'],
            value: '{categories}',
        }),
        minChars: 2,
        editable: true,
        resizable: true,
        typeAhead: false,
        allowBlank: true,
        forceFormValue: false,
        allowAddNewData: true,
        addNewDataOnBlur: true,
        forceSameValueQuery: true,
        triggerAction: 'all',
 
       
        anchor: '100%',
        extraItemCls: 'x-tag',
        clearBtnCls: 'x-form-trigger',
        expandBtnCls: 'x-form-trigger',
        listEmptyText: '<div style="padding: 7px;">No results...</div>',
        tpl: new Ext.XTemplate('\
            <tpl for="."><div class="x-combo-list-item">\
                <span>\
                    {name}\
                </span>\
            </div></tpl>',
            {compiled: true}
        ),
    });
	
items.windows.js

{
            xtype: 'menus-combo-options',
            fieldLabel: _('menus_locationmenu_locations'),
            name: 'locations',
            id: config.id + '-locations',
            anchor: '99%',
            allowBlank: true,
            allowAddNewData: true,
            pageSize: 60,
            handler: function () { 
 
            },    
            
            listeners: {
        		
        		'change': {
                    fn: function (combo, a, b) {
                        var cmp = Ext.getCmp(config['id'] + '-categories');
                        if (!!cmp) {
                            console.log(combo.getValue());
                            cmp.getStore().baseParams['locations[]'] = combo.getValue();
                            cmp.store.removeAll();
                            cmp.store.load();
                            cmp.reset();
                            cmp.setValue('');
                        }
                    },
                    scope: this,
                },
               
        	},
            
            },
            {
            xtype: 'menus-combo-submenus2',
            fieldLabel: 'Submenus',
            name: 'categories',
            id: config.id + '-categories',
            anchor: '100%',
            allowBlank: true,
            emptyText: 'Please select locations first',
            }	

The payload for the getlist processor contains a locations array and not an id property. That’s the issue. If the getlist processor filters the values by the locations array, the values should be (maybe) visible.

        $locations = $this->getProperty('locations');
        if (!empty($locations) && is_array($locations)) {
            $c->where([
                $this->classKey . '.id:IN' => $locations;
            ]);
        }

But I think, there is somehow wrong because you add a baseparam for the category getlist processor with locations[]. Try to change that to locations. The value should be already an array.

Thanks again @jako !

It seems really the key is in renaming locations[ ] to locations in baseparam. At least location superselect works for now every window load! And that’s great, but second combo is empty for now.

Location Menu _ Demo - Google Chrome 2023-04-26 227

I think this is because it looks like I added too much … before outputting from the database, I formed another array (highlighted in red below) so that the list was somehow displayed, otherwise nothing worked at all. Probably you need to remove all these superfluous things … in connection to this please specify whether the values ​​are now stored correctly in the database and in what form they need to be unloaded from the processor so that the combo box interprets them correctly?

It seems I have a problem with storing and comparing data, I’m going to rebuild these two fields at all but is it possible to work with what we have now? At least location list works perfectly with such array data, loads and stores perfectly. I just can’t get the second list to display data now. I found and commented out the following code snippet (it influenced the chaotic display of the results of the second list. I confess, I do not fully understand it purpose … but when it was used sometimes something appeared, now the list is empty all the time)

P.S. I’ve replaced locations with query, second lists values load process and load correctly from backend, so the only question how to render them in second combo.


In my Extras I try to fill the combo values with a separated list. And I submit a generated hidden field with a separated list. I will search for a sample code in in my repositories.

1 Like

Yes, @jako I’ve examined your code(speech is about SwitchTemplate), it’s quite clear and nothing in excess.I see how you save / load data, I see hidden field.

I would like to try to revive the code that I have, If possible (if not, I will have to rewrite everything even easier). Now I am passing arrays, saving and loading them.

Location Menu _ Demo - Google Chrome 2023-04-28 17

The main question is the next: while updating the product lists do not have time to load, as I said, for each of the lists there is timeout delay code (it seems this is from Collections extra), but why is it needed … and is it possible to work without it. Lists can contain dozens of positions, so there is some slowdown here. I have loaded data for each combo(similar arrays), I have stored values for them as well. First combo has enough time for load but not second one.

Ext.extend(menus.combo.Submenus, Ext.ux.form.SuperBoxSelect, {
    initValue: function (config) {
        let sbs = this;
       window.setTimeout(function () {
            if (Ext.isObject(sbs.value) || Ext.isArray(sbs.value)) {
                sbs.setValueEx(sbs.value);
                sbs.originalValue = sbs.getValue();
            } else {
                Ext.ux.form.SuperBoxSelect.superclass.initValue.call(sbs);
            }
            if (sbs.mode === 'remote') {
                sbs.setOriginal = true;
            }
        }, 1100);
    },
});

P.S. I’m ready for paid consutation if this will help us :slight_smile:

All list combos in MODX create minimum two requests to the processors: one to fill the selected value and one to list (paginated) values. (It is better to have a limit of 10-20 and a pagination instead of retrieving the full list every time because of timing issues.)

The selected values are retrieved with an id property (single select combo) or with valuesqry and query value (superboxselect combo). When the combo list can’t get a display value, the superboxselect show the empty x value as seen above. Please look into the payloads of each combo processors to narrow down the issue.