Question

I am using Sencha Touch 1.1 and have run into an aggravating little bug in my UI for which I've not been able to find the correct way to address in Sencha.

The symptom is that in my search panel containing two lists, it seems that the second list is folding directly under the first list, so in my example case the first list being one row is covering up the first row of the second list.

This is a fairly long code snippet, sorry if I got a little out of control. I just wanted to provide my exact test case (minus the sencha base code).

I've watered the app down to provide this example.

If you take the time to load it you will find that if you go into the "Job Export Search" option and enter 2 into the job order field and click "Check It!" the results will show.

I am putting a little job order info in the first list that returns one row. the second list containing many rows has export history details. Pull down on that second list and you see the first row has been tucked behind the first list.

moving doLayout() around the app has done nothing and the layout "fit" config option seems work fine except for the ui relationship between these two lists. I am assuming the ui just doesn't know the first list is taking up any space at render, but am unsure.

I'll just go ahead and say thanks for your time here at the top, you might not make it to the bottom.

rich

My Models:

Ext.regModel('JobModel', {
    idProperty: 'id'
    ,fields: [
        {type: 'int', name: 'id', field: 'id'}
        ,{type: 'string', name: 'market', field: 'market'}
        ,{type: 'string', name: 'client', field: 'client'}
        ,{type: 'string', name: 'title', field: 'title'}
        ,{type: 'string', name: 'owner', field: 'owner'}
    ]
});

Ext.regModel('ExportHistoryModel', {
    idProperty: 'id'
    ,fields: [
        {type: 'int', name: 'id', field: 'id'}
        ,{type: 'string', name: 'date_exported', field: 'date_exported'}
        ,{type: 'int', name: 'rank', field: 'rank'}
        ,{type: 'string', name: 'careersite', field: 'careersite'}
        ,{type: 'int', name: 'job_id', field: 'job_id'}
    ]
});

Ext.regModel('MenuModel', {
    idProperty: 'id',
    fields: [
        { name: 'id', type: 'int' }
        ,{ name: 'title', type: 'string' }
        ,{ name: 'target', type: 'string' }
    ]
});

My Stores:

Ext.regStore('JobStore', {
    model: 'JobModel'
    ,sorters: [{
        property: 'id',
        direction: 'ASC'
    }]
    ,proxy: {
        type: 'localstorage',
        id: 'adsel-app-jobstore'
    }
    ,data: [
    {id: 1, market: 'Boston', client: 'Creme Co.', title: 'Baker', owner: 'rwheadon'}
    ,{id: 2, market: 'Miami', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
    ,{id: 3, market: 'Dallas', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
    ,{id: 4, market: 'Chicago', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
    ,{id: 6, market: 'Fargo', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
    ,{id: 10, market: 'Boise', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
    ,{id: 21, market: 'Miami2', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
    ,{id: 31, market: 'Dallas2', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
    ,{id: 41, market: 'Chicago2', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
    ,{id: 61, market: 'Fargo2', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
    ,{id: 101, market: 'Boise2', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
    ,{id: 22, market: 'Miami3', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
    ,{id: 32, market: 'Dallas3', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
    ,{id: 42, market: 'Chicago3', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
    ,{id: 62, market: 'Fargo3', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
    ,{id: 102, market: 'Boise3', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
    ,{id: 23, market: 'Miami4', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
    ,{id: 33, market: 'Dallas4', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
    ,{id: 43, market: 'Chicago4', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
    ,{id: 63, market: 'Fargo4', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
    ,{id: 103, market: 'Boise4', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
    ]
});

Ext.regStore('ExportHistoryStore', {
    model: 'ExportHistoryModel'
    ,sorters: [{
        property: 'rank',
        direction: 'ASC'
    },
    {property: 'job_id', direction: 'ASC'}
    ,{property: 'id', direction:'ASC'}]
    ,proxy: {
        type: 'localstorage',
        id: 'adsel-app-exporthistorystore'
    }
    ,data: [
        {id: 1, date_exported: '2012-03-26 08:53:00', rank: 1, careersite: 'Monster', job_id: 1}
        ,{id: 2, date_exported: '2012-03-26 08:53:00', rank: 2, careersite: 'Monster', job_id: 2}
        ,{id: 3, date_exported: '2012-03-26 08:53:00', rank: 3, careersite: 'Dice', job_id: 1}
        ,{id: 4, date_exported: '2012-03-26 08:53:00', rank: 4, careersite: 'Dice', job_id: 2}
       ,{id: 5, date_exported: '2012-03-26 08:53:00', rank: 5, careersite: 'Dice', job_id: 3}
       ,{id: 6, date_exported: '2012-03-26 08:53:00', rank: 6, careersite: 'Dice', job_id: 4}
       ,{id: 7, date_exported: '2012-03-26 08:53:00', rank: 7, careersite: 'Monster', job_id: 3}
       ,{id: 8, date_exported: '2012-03-26 08:53:00', rank: 8, careersite: 'Monster', job_id: 4}
       ,{id: 9, date_exported: '2012-03-26 08:53:00', rank: 9, careersite: 'Monster', job_id: 5}
       ,{id: 10, date_exported: '2012-03-26 08:53:00', rank: 10, careersite: 'Monster', job_id: 10}
        ,{id: 21, date_exported: '2012-03-26 08:53:00', rank: 2, careersite: 'Monster', job_id: 2}
        ,{id: 31, date_exported: '2012-03-26 09:53:00', rank: 3, careersite: 'Dice', job_id: 1}
        ,{id: 41, date_exported: '2012-03-26 09:53:00', rank: 4, careersite: 'Dice', job_id: 2}
       ,{id: 51, date_exported: '2012-03-26 09:53:00', rank: 5, careersite: 'Dice', job_id: 3}
       ,{id: 61, date_exported: '2012-03-26 09:53:00', rank: 6, careersite: 'Dice', job_id: 4}
       ,{id: 71, date_exported: '2012-03-26 09:53:00', rank: 7, careersite: 'Monster', job_id: 3}
       ,{id: 81, date_exported: '2012-03-26 09:53:00', rank: 8, careersite: 'Monster', job_id: 4}
       ,{id: 91, date_exported: '2012-03-26 09:53:00', rank: 9, careersite: 'Monster', job_id: 5}
       ,{id: 101, date_exported: '2012-03-26 09:53:00', rank: 10, careersite: 'Monster', job_id: 10}
        ,{id: 22, date_exported: '2012-03-26 09:53:00', rank: 2, careersite: 'Monster', job_id: 2}
        ,{id: 32, date_exported: '2012-03-26 11:53:00', rank: 3, careersite: 'Dice', job_id: 1}
        ,{id: 42, date_exported: '2012-03-26 11:53:00', rank: 4, careersite: 'Dice', job_id: 2}
       ,{id: 52, date_exported: '2012-03-26 11:53:00', rank: 5, careersite: 'Dice', job_id: 3}
       ,{id: 62, date_exported: '2012-03-26 11:53:00', rank: 6, careersite: 'Dice', job_id: 4}
       ,{id: 72, date_exported: '2012-03-26 11:53:00', rank: 7, careersite: 'Monster', job_id: 3}
       ,{id: 82, date_exported: '2012-03-26 11:53:00', rank: 8, careersite: 'Monster', job_id: 4}
       ,{id: 92, date_exported: '2012-03-26 11:53:00', rank: 9, careersite: 'Monster', job_id: 5}
       ,{id: 102, date_exported: '2012-03-26 11:53:00', rank: 10, careersite: 'Monster', job_id: 10}
        ,{id: 23, date_exported: '2012-03-26 11:53:00', rank: 2, careersite: 'Monster', job_id: 2}
        ,{id: 33, date_exported: '2012-03-26 13:53:00', rank: 3, careersite: 'Dice', job_id: 1}
        ,{id: 43, date_exported: '2012-03-26 13:53:00', rank: 4, careersite: 'Dice', job_id: 2}
       ,{id: 53, date_exported: '2012-03-26 13:53:00', rank: 5, careersite: 'Dice', job_id: 3}
       ,{id: 63, date_exported: '2012-03-26 13:53:00', rank: 6, careersite: 'Dice', job_id: 4}
       ,{id: 73, date_exported: '2012-03-26 13:53:00', rank: 7, careersite: 'Monster', job_id: 3}
       ,{id: 83, date_exported: '2012-03-26 13:53:00', rank: 8, careersite: 'Monster', job_id: 4}
       ,{id: 93, date_exported: '2012-03-26 13:53:00', rank: 9, careersite: 'Monster', job_id: 5}
       ,{id: 103, date_exported: '2012-03-26 13:53:00', rank: 10, careersite: 'Monster', job_id: 10}
        ,{id: 24, date_exported: '2012-03-26 13:53:00', rank: 2, careersite: 'Monster', job_id: 2}
        ,{id: 34, date_exported: '2012-03-26 15:53:00', rank: 3, careersite: 'Dice', job_id: 1}
        ,{id: 44, date_exported: '2012-03-26 15:53:00', rank: 4, careersite: 'Dice', job_id: 2}
       ,{id: 54, date_exported: '2012-03-26 15:53:00', rank: 5, careersite: 'Dice', job_id: 3}
       ,{id: 64, date_exported: '2012-03-26 15:53:00', rank: 6, careersite: 'Dice', job_id: 4}
       ,{id: 74, date_exported: '2012-03-26 15:53:00', rank: 7, careersite: 'Monster', job_id: 3}
       ,{id: 84, date_exported: '2012-03-26 15:53:00', rank: 8, careersite: 'Monster', job_id: 4}
       ,{id: 94, date_exported: '2012-03-26 15:53:00', rank: 9, careersite: 'Monster', job_id: 5}
       ,{id: 104, date_exported: '2012-03-26 15:53:00', rank: 10, careersite: 'Monster', job_id: 10}
        ,{id: 25, date_exported: '2012-03-26 15:53:00', rank: 2, careersite: 'Monster', job_id: 2}
        ,{id: 35, date_exported: '2012-03-26 20:53:00', rank: 3, careersite: 'Dice', job_id: 1}
        ,{id: 45, date_exported: '2012-03-26 20:53:00', rank: 4, careersite: 'Dice', job_id: 2}
       ,{id: 55, date_exported: '2012-03-26 20:53:00', rank: 5, careersite: 'Dice', job_id: 3}
       ,{id: 65, date_exported: '2012-03-26 20:53:00', rank: 6, careersite: 'Dice', job_id: 4}
       ,{id: 75, date_exported: '2012-03-26 20:53:00', rank: 7, careersite: 'Monster', job_id: 3}
       ,{id: 85, date_exported: '2012-03-26 20:53:00', rank: 8, careersite: 'Monster', job_id: 4}
       ,{id: 95, date_exported: '2012-03-26 20:53:00', rank: 9, careersite: 'Monster', job_id: 5}
       ,{id: 106, date_exported: '2012-03-26 20:53:00', rank: 10, careersite: 'Monster', job_id: 10}
       ,{id: 1116, date_exported: '2012-03-26 08:53:00', rank: 11, careersite: 'Craigslist', job_id: 10}
       ,{id: 1216, date_exported: '2012-03-26 08:53:00', rank: 12, careersite: 'Craigslist', job_id: 6}
       ,{id: 1316, date_exported: '2012-03-26 08:53:00', rank: 13, careersite: 'Craigslist', job_id: 3}
       ,{id: 1416, date_exported: '2012-03-26 08:53:00', rank: 14, careersite: 'Craigslist', job_id: 1}
       ,{id: 1516, date_exported: '2012-03-26 08:53:00', rank: 15, careersite: 'Craigslist', job_id: 4}
       ,{id: 1616, date_exported: '2012-03-26 08:53:00', rank: 16, careersite: 'Monster', job_id: 6}
    ]
});

Ext.regStore('HomeMenuStore', {
    model: 'MenuModel'
    ,sorters: [{
        property: 'title',
        direction: 'ASC'
    }]
    ,proxy: {
        type: 'localstorage',
        id: 'adsel-app-homemenustore'
    }
    ,data: [
//    {id: 1, title: 'Status', targetMenu: 'statusList'}
    {id:2, title:'Jobs', target: 'jobListPanel'}
    ,{id:3, title:'Export History', target: 'exportListPanel'}
    ,{id:4, title: 'Job Export Search', target: 'jobExportSearchPanel'}
    ]
});

overlappingListProblem.js (intitializers)

var App;

// new Ext.Application({
new Ext.Application({
    name : 'AdSel',
    useLoadMask : true,
    launch: function (){
    App = this;
//initialization
            AdSel.views.homeMenuPanel = new Ext.Panel({
                id: 'homeMenuPanel'
                ,layout: 'fit'
                ,dockedItems: [
                        AdSel.views.consoleBar
                ]
                ,items: [
                        AdSel.views.consoleList
                ]
            });

            AdSel.views.jobListPanel = new Ext.Panel({
                id: 'jobListPanel'
                ,layout: 'fit'
                ,dockedItems: [
                        AdSel.views.jobsToolbar
                ]
                ,items: [
                        AdSel.views.jobList
                ]
            });

            AdSel.views.exportListPanel = new Ext.Panel({
                id: 'exportListPanel'
                ,layout: 'fit'
                ,dockedItems: [
                        AdSel.views.exporthistoryToolbar
                ]
                ,items: [
                        AdSel.views.exporthistoryList
                ]
            });

            AdSel.views.jobExportSearchPanel = new Ext.Panel({
                id: 'jobExportSearchPanel'
                ,layout: 'fit'
                ,dockedItems: [
                        AdSel.views.jobHistoryCheckerToolbar
                        ,AdSel.views.joborderHistoryCheckForm
                        ,AdSel.views.joborderPostingHistoryHeaderInfo
                ]
                ,items: [
                        AdSel.views.joborderPostingHistoryResultList
                ]
            });

//render
            AdSel.views.viewport = new Ext.Panel({
                 fullscreen : true
                 ,layout : 'card'
                 ,cardAnimation : 'slide'
                 ,items: [

                        AdSel.views.homeMenuPanel
                        ,AdSel.views.jobListPanel
                        ,AdSel.views.exportListPanel
                        ,AdSel.views.jobExportSearchPanel
                    ]
            })
    }
});

hardwiredmenu-screens.js:

//MAIN SCREEN (HOME) AdSel.views.consoleBar = new Ext.Toolbar({ id: 'consoleBar', title: 'Job Management Console' });

AdSel.views.consoleList = new Ext.List({
    id: 'consoleList'
    ,store: 'HomeMenuStore'
,disableSelection: true
    ,itemTpl: '<div class="list-item-title">{title}</div>'
    ,onItemDisclosure: function (record) {
        var selectedNote=record;
        var theTarget = selectedNote.data.target;
        if( theTarget == 'jobExportSearchPanel') {
            Ext.getStore('JobStore').filter({property:'id', value: 0, exactMatch: true});
            Ext.getStore('ExportHistoryStore').filter({property:'job_id', value: 0, exactMatch: true});
            AdSel.views.viewport.setActiveItem(theTarget, {type: 'slide', direction: 'left'})
        } else {
            AdSel.views.viewport.setActiveItem(theTarget, {type: 'slide', direction: 'left'});              
        }


    }
});

job-screens.js

//JOBS SCREEN
AdSel.views.jobsToolbar = new Ext.Toolbar({
    id: 'jobsToolbar'
    ,ui: 'light'
    ,defaults: {
        iconMask: true
        ,ui: 'plain'
    }
    ,title: 'Jobs'
    ,items: [
        {
            iconCls: 'home',
            handler: function () {
                AdSel.views.viewport.setActiveItem('homeMenuPanel', {type: 'slide', direction: 'right'});
            }
        }
    ]
});

AdSel.views.jobList = new Ext.List({
    id: 'jobList'
    ,store: 'JobStore'
    ,disableSelection: true
    ,itemTpl: '<div class="list-item-title">{title} ({client}) in {market} entered by {owner}</div>'
});

//JOB EXPORTHISTORY SEARCH SCREEN
/*
 * *********************************************** *
 * *********************************************** *
 * *********************************************** *
 *                  JOB HISTORY                    *
 * *********************************************** *
 * *********************************************** *
 * *********************************************** *
 */
AdSel.views.jobHistoryCheckerToolbar = new Ext.Toolbar({
    id: 'jobHistoryCheckerToolbar'
    ,ui: 'light'
    ,dock: 'top'
    ,defaults: {
        iconMask: true
        ,ui: 'plain'
    }
//    ,title: 'Job Posting History'
    ,title: 'Job Export History'
    ,items: [
        {
            iconCls: 'home'
            ,id: 'jobhistorycheckerHomeBtn'
            ,handler: function(){
                AdSel.views.joborderHistoryCheckForm.reset();
                Ext.getStore('JobStore').clearFilter();
                Ext.getStore('ExportHistoryStore').clearFilter();
                AdSel.views.viewport.setActiveItem('homeMenuPanel', {type: 'slide', direction: 'right'});
            }
        }
        ,{xtype: 'spacer'}
        ,{
            text: 'Check it!'
            ,ui: 'action'
            ,handler: function () {
                    var ovrEditor = AdSel.views.joborderHistoryCheckForm;
                    var filterid = ovrEditor.getValues().joborderid;
                    var theHeaderStore = Ext.getStore('JobStore');

                    theHeaderStore.clearFilter();
                    theHeaderStore.filter({property:'id', value: filterid, exactMatch: true});

                    var theHistoryStore = Ext.getStore('ExportHistoryStore');
                    theHistoryStore.clearFilter();
                    theHistoryStore.filter({property:'job_id', value: filterid, exactMatch: true});


                    var theHeaderList = AdSel.views.joborderPostingHistoryHeaderInfo;
                    theHeaderList.refresh();
                    var theHistoryList = AdSel.views.joborderPostingHistoryResultList;
                    theHistoryList.refresh();
                    AdSel.views.jobExportSearchPanel.doLayout();
                }

        }

    ]
});

AdSel.views.joborderHistoryCheckForm = new Ext.form.FormPanel({
    id: 'joborderHistoryCheckForm'
    ,standardSubmit: false
    ,submitOnAction: false
    ,items: [
        {
            xtype: 'textfield'
            ,id: 'joborderhistorycheckform-joborderid'
            ,name: 'joborderid'
            ,label: 'JO Number'
        }
    ]
});

AdSel.views.joborderPostingHistoryHeaderInfo = new Ext.List({
    id: 'joborderPostingHistoryHeaderInfo'
    // ,layout: 'fit'
    ,store: 'JobStore'
    ,disableSelection: true
    ,itemTpl: '<div class="list-item-title-dark"><b>Job Order: </b>{id}<br/>' +
            '<b>Title: </b>{title}<br/><b>Client: </b>{client}</div>'

});

AdSel.views.joborderPostingHistoryResultList = new Ext.List({
    id: 'joborderPostingHistoryResultList'
    // ,layout: 'fit'
    ,store: 'ExportHistoryStore'
    ,disableSelection: true
    ,itemTpl: '<div class="list-item-title">Runtime: {date_exported}<br/>' +
            'Career Site: {careersite}<br/>Rank: {rank}</div>'
});

exporthistory-screens.js

//EXPORTS SCREEN
AdSel.views.exporthistoryToolbar = new Ext.Toolbar({
    id: 'jobsToolbar'
    ,ui: 'light'
    ,defaults: {
        iconMask: true
        ,ui: 'plain'
    }
    ,title: 'Export History'
    ,items: [
        {
            iconCls: 'home',
            handler: function () {
                AdSel.views.viewport.setActiveItem('homeMenuPanel', {type: 'slide', direction: 'right'});
            }
        }
    ]
});


AdSel.views.exporthistoryList = new Ext.List({
    id: 'exporthistoryList'
    ,store: 'ExportHistoryStore'
    ,disableSelection: true
    ,itemTpl: '<div class="list-item-title">{date_exported} exported job# {job_id} to {careersite} (ranked {rank})</div>'
});

I am assuming most won't need the index.html, but I might as well burn a few more bytes:

<html>
<head>
    <link rel="stylesheet" type="text/css" href="touch/1.1.1/resources/css/sencha-touch.css"/>
    <script type="text/javascript" src="touch/1.1.1/sencha-touch.js"></script>
        <script type="text/javascript" src="app/overlappingListProblem.js"></script>
    <script type="text/javascript" src="app/models/models.js"></script>
    <script type="text/javascript" src="app/models/stores.js"></script>

    <script type="text/javascript" src="app/viewers/exporthistory-screens.js"></script>
    <script type="text/javascript" src="app/viewers/hardwiredmenu-screens.js"></script>
    <script type="text/javascript" src="app/viewers/job-screens.js"></script>
    </head>
    <body>

    </body>
</html>
Was it helpful?

Solution

Posting my alternative approach where I use a form instead of stacking the two dynamic lists together in a panel:

The Form Panel

AdSel.views.joborderPostingHistoryHeaderInfoForm = new Ext.form.FormPanel({
    id: 'joborderPostingHistoryHeaderInfoForm'
    ,standardSubmit: false
    ,submitOnAction: false
    ,items: [
        {
            xtype: 'textfield'
            ,id: 'joborderPostingHistoryHeaderInfoForm-adTitle'
            ,name: 'adTitle'
            ,label: 'Job Title'
            ,listeners: {
                           afterrender: function(ele) {
                                 ele.fieldEl.dom.readOnly = true;
                            }
                    }
        }
        ,{
            xtype: 'textfield'
            ,id: 'joborderPostingHistoryHeaderInfoForm-clientName'
            ,name: 'clientName'
            ,label: 'Client'
            ,listeners: {
                           afterrender: function(ele) {
                                 ele.fieldEl.dom.readOnly = true;
                            }
                    }
        }

    ]
});

And then load the desired record into that form adding a little code to the Check It! button:

            theHeaderStore = Ext.getStore('exactMatchJobStore');

            theHeaderStore.removeAll();
            theHeaderStore.load({
                params:{id: filterid}
            });

            theHeaderStore.on('datachanged', function(){
                var selectedNote = this.first();
                AdSel.views.joborderPostingHistoryHeaderInfoForm.loadRecord(selectedNote);
            });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top