Продолжаем писать клиент для просмотра dbf файлов на ExtJs

Работающий пример здесь: http://jobtools.ru/js/dbfshow/. Хочу предупредить, что загружать надо только dbf файл, и не слишком большого размера, так как индикатора загрузки нет и не видно что происходит и когда закончится.

Создаем главное окно нашей программы:

    Ext.require('Ext.Window', function() {
        var win = new Ext.Window({
            title : "DBFShow.On " + VERSION,
            width : 700,
            height : 410,
            layout : 'fit',
            tbar : [{// тулбар c меню
                text : 'Файл',
                // кнопка с выпадащим меню
                menu : [// само  меню
                {
                    text : 'Открыть',
                    handler : function() {

                        Ext.require('Ext.Window', function() {
                            var openFileForm = new Ext.Window({
                                title : "Открыть файл",
                                width : 510,
                                height : 110,
                                items : [openFile]
                            })
                            openFileForm.show();
                        })
                    }
                }, {
                    text : 'Закрыть'
                }]
            }, {
                text : 'О программе...',
                handler : function() {                   
                    Ext.require('Ext.Window', function() {
                        var about = new Ext.Window({
                            title : "О программе",
                            width : 510,
                            height : 310
                        })
                        about.show();
                    })
                }
            } // простая кнопка
            ],
            items : [grid]
        })
        win.show();
    });

Что мы здесь делаем:

 var win = new Ext.Window - создаём главное окно, указали заголовок окна title, размеры width, height.

Создаём меню:

            tbar : [{// тулбар c меню
                text : 'Файл',
                // кнопка с выпадащим меню
                menu : [// само  меню
                {
                    text : 'Открыть',
                    handler : function() { ....

в handler прописываем обработку события нажатия на кнопку меню, в нашем случае при нажатии на кнопку «Открыть» создаём новое окно Ext.Window с предложением пользователю выбрать файл для загрузки с единственным элементом openFile:

    var openFile = Ext.create('Ext.form.Panel', {
        width: 510,
        height: 70,
        items: [{
            xtype: 'filefield',
            id: 'form-file',
            emptyText: 'Выберите файл',
            fieldLabel: 'DBF',
            name: 'dbf-path',
            width: 350,
            buttonText: '',
            buttonConfig: {
                iconCls: 'upload-icon'
            }
        }],
        buttons: [{
            text: 'Загрузить',
            handler: function() {
                var form = this.up('form').getForm();
                if (form.isValid()) {
                    form.submit({
                        url: 'file-upload.php',
                        //waitMsg : 'Загружаем Ваш файл...',
                        success: function(fp, o) {
                            // msg('Ок', 'Файл "' + o.result.file + '" загружен на сервер');
                            filename_ = o.result.file;
                            process(filename_);
                            openFile.ownerCt.close();
                        },
                        failure: function(fp, o) {
                            openFile.ownerCt.close();
                        }
                    });
                }
            }
        }, {
            text: 'Reset',
            handler: function() {
                this.up('form').getForm().reset();
            }
        }]
    });

 

Форма с двумя кнопками «Загрузить» и  «Отмена». При нажатии кнопки Загрузить проверяется форма на заполненность и пересылаем файл на сервер. При корректной загрузке success передаем управление функции process():

function process() {
    if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0) {
        xmlHttp.open("GET", "dbfshow.php?func=getModel&filename=" + filename_);
        xmlHttp.onreadystatechange = handleServerResponse;
        xmlHttp.send(null);
    } else setTimeout('process()', 1000);

В этой функции обращаемся к dbfshow.php на сервере и передаем ей как параметр имя функции func = getModel и имя открываемого файла filename_

Если dbfshow.php получает func = getModel, то он считывает формат загруженной DBF-ки (заголовок, описание колонок) и передает ответ клиенту с указанием func = DEFINITION, дабы клиент знал что пришло описание колонок, необходимое для динамического заполнения Model и Store :

<?php

 include 'dbf.php';

 $db = new dbf();
 $filename = $_GET["filename"];
 if ($_GET['func']=='getModel')
 {
     $db->open("Upload/".$filename);     
     $db->readHeader();
     $db->readColumns();
     $text ="[";
     $columns ="[";
     for ($i=0; $i<=$db->getCountColumns()-1;$i++)
     {
         $text.="{name:'";
         $text.=iconv("windows-1251", "UTF-8",$db->getColumnName($i));
         $text.="', type:'";
         $text.="string'";
         $text.="},";

         $columns.="{ text:'";
         $columns.=iconv("windows-1251", "UTF-8",$db->getColumnName($i));
         $columns.="', dataIndex: '";
         $columns.=iconv("windows-1251", "UTF-8",$db->getColumnName($i));
         $columns.="'},";
     }    
     $text = substr($text, 0, strlen($text)-1);
     $text.="]";
     $columns = substr($columns, 0, strlen($columns)-1);
     $columns.="]";         

     $a = array();
     array_push($a, array('MODEL'=>$text));
     array_push($a, array('COLUMNS' =>$columns));
        $db->close();
        echo json_encode(array(
    'FUNC'=> 'DEFINITION',$a));
 }
 ?>

Вот как выглядит ответ сервера:

При получении ответа клиентом, запускается функция:

function handleServerResponse() {
    if (xmlHttp.readyState == 4) {
        if (xmlHttp.status == 200) {
            response = xmlHttp.responseText;
            //response.setContentType('text/html')
            var data = JSON.parse(response);

            if (data.FUNC == 'DEFINITION') {
                columns = eval('(' + data[0][1].COLUMNS + ')');
                var myModel = Ext.ModelManager.getModel('Model');
                fields = myModel.prototype.fields.getRange();
                Ext.each(columns, function(permission) {
                    fields.push({
                        name: permission.text,
                        type: 'string'
                    });
                });
                 myModel.setFields(fields);
                store.removeAll();
                grid.reconfigure(store, columns);
                store.load({
                    params: {
                        filename: filename_
                    }
                });
            }

        } else {
            alert("При обращении к серверу возникли проблемы: " + xmlHttp.statusText);
        }
    }

 

Если в пришедших данных data Func = DEFINITION, то пришло описание полей.

Создаём новую переменную копию нашей Model

var myModel = Ext.ModelManager.getModel('Model');

Заполняем массив описания колонок fileds:

fields = UserType.prototype.fields.getRange();
      Ext.each(columns, function(permission) {
      fields.push({
           name: permission.text,
           type: 'string'
       });
});

Конфигурируем наш store и grid:

myModel.setFields(fields);
store.removeAll();
grid.reconfigure(store, columns);

И заставляем наш store загрузить данные, через указанный нами ранее proxy (в настройках store):

store.load({
        params: {
                  filename: filename_
        }
})

Напомню что proxy в store настроен на получение данных с вызовом get_data.php:

        proxy: {
            type: 'ajax',
            url: 'get_data.php',
            extraParams: {
                filename: filename_
            },

Содержимое файла get_data.php, который отдает данные из dbf нашему гриду:

<?php

include 'dbf.php';

$a = array();
$rows = array();
$row = array();
$limit = $_GET["limit"];
$start = $_GET["start"];
$filename = $_GET["filename"];

$db = new dbf();
$db -> open("Upload/" . $filename);
$db -> readHeader();
$db -> readColumns();

$countRows = $db -> GetCountRows();
$totalRows = $start + $limit;

if ($totalRows > $countRows)
    $totalRows = $countRows;
for ($z = $start; $z <= $totalRows; $z++) {
    for ($i = 0; $i <= $db -> getCountColumns() - 1; $i++) {
        $row[iconv("windows-1251", "UTF-8", $db -> getColumnName($i))] = iconv("windows-1251", "UTF-8", $db -> getValue($z, $i));
    }
    array_push($rows, $row);
    $row = array();
}
$db -> close();
echo json_encode(array('sucess' => true, 'total' => $countRows, 'records' => $rows));
?>

Так выглядят данные отправляемые сервером для грида:

Ну вот вроде и всё ).

Надо опять вернуться и расширить функционал:  отображение прогресса загрузки, использование правильной кодировки файла.

Исходник: [download id=»6″]

 

Просмотр DBF файлов онлайн на ExtJS. Часть 3. Клиент.
Метки:        

Одно мнение о “Просмотр DBF файлов онлайн на ExtJS. Часть 3. Клиент.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая на кнопку "Отправить комментарий", я даю согласие на обработку персональных данных и соглашаюсь c политикой конфиденциальности *