2019年11月4日 星期一

Python 學習筆記 : Django 2 測試 (四) : 本機前端框架環境配置

由於在前一篇前端網頁框架模板測試中發現 EasyUI 最新版的 CDN 檔案似乎有 Bug, 資料表格 datagrid 的表頭與表身寬度不齊會錯開, 反而以前下載的舊版不會, 可見得 CDN 雖然方便, 但可能會因為版本差異而使網頁外觀不符需求, 因此準備一份本機端的框架環境有其必要性.

本系列之前的測試筆記參考 :

Python 學習筆記 : Django 2 測試 (一) : 請求與回應處理
Python 學習筆記 : Django 2 測試 (二) : 模板基礎與靜態檔案
Python 學習筆記 : Django 2 測試 (三) : 模板的匯入與繼承

本篇主要是延續上面的第三篇測試, 差別主要是將框架函式庫來源從 CDN 改為本機環境而已.

首先說明目錄結構, 我在 static 下分別建立 bootstrap, jqueryui, easyui, 以及 extjs 這四個框架子目錄以放置本地框架函式庫, 結構如下 :

mysite (上層專案目錄)
     |____ manage.py
     |____ mysite  (下層專案目錄)
     |              |____ __init__.py
     |              |____ settings.py
     |              |____ urls.py
     |              |____ views.py  (自行添加)
     |              |____ wsgi.py
     |____ templates (網頁模板目錄)
     |              |____ bootstrap.htm
     |              |____ jqueryui.htm
     |              |____ easyui.htm
     |              |____ extjs.htm
     |____ static (靜態檔案目錄)
                    |____ bootstrap
                    |____ jqueryui
                    |____ easyui
                    |____ extjs




靜態目錄 static 底下的結構如下 :







除了 ExtJS 外, 其他框架均以 jQuery 為基礎, 所以它們每一個框架都有相同的一份 jquery.min.js, 這樣方便開發單一框架專案時可順利分割. 各框架的版本如下 :
  1. jQuery v3.4.1
  2. jQuery UI v1.12.1
  3. jQuery DataTables v1.10.20
  4. Bootstrap v3.3.7
  5. EasyUI 1.4.1
  6. ExtJS v4.2.2
本篇測試比上一篇多加了 ExtJS 框架的兩個測試, 其實要改的部份主要是 template 底下各框架的模板網頁, 即 bootstrap.htm, jqueryui.htm, easyui.htm, 以及新加的 extjs.htm. 另外就是主題佈景測試需更改 Link 元素的 href 屬性, 套用本地檔案時也需要修改. 其餘的測試網頁均不變, 此處不再列出, 參考上一篇 "模板的匯入與繼承".


一. 修改 /template 下的四個框架模板網頁 : 

HTML 基礎模板網頁 base.htm 不變, 內容如下 :

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>{% block title %}{% endblock %}</title>
  {% block link %}{% endblock %}
  {% block script %}{% endblock %}
  <style>
  {% block style %}{% endblock %}
  </style>
</head>
<body>
  {% block body %}{% endblock %}
</body>
</html>


四個框架模板都繼承自 base.htm, 由於是本地供檔, 以此需使用 load static 指令匯入靜態目錄位置. 注意, 由於 extends 指令必須放在首位, 所以 load static 放在第二位 :


1. jQueryui 模板網頁 :

<--! jqueryui.htm -->
{% extends "base.htm" %}
{% load static %}
{% block link %}
  <link id="theme" rel="stylesheet"  href='{% static "jqueryui/themes/hot-sneaks/jquery-ui.css" %}'>
  <link rel="stylesheet" href='{% static "jqueryui/jquery.dataTables.min.css" %}'>
{% endblock %}
{% block script %}
  <script src='{% static "jqueryui/jquery.min.js" %}'></script>
  <script src='{% static "jqueryui/jquery-ui.min.js" %}'></script>
  <script src='{% static "jqueryui/jquery.dataTables.min.js" %}'></script>
{% endblock %}


2. EasyUI 模板網頁 : 

<--! easyui.htm -->
{% extends "base.htm" %}
{% load static %}
{% block link %}
  <link id="theme" rel="stylesheet" href='{% static "easyui/themes/default/easyui.css" %}'>
  <link rel="stylesheet" href='{% static "easyui/themes/icon.css" %}'>
{% endblock %}
{% block script %}
  <script src='{% static "easyui/jquery.min.js" %}'></script>
  <script src='{% static "easyui/jquery.easyui.min.js" %}'></script>
  <script src='{% static "easyui/locale/easyui-lang-zh_TW.js" %}'></script>
{% endblock %}


3. Bootstrap 模板網頁 : 

<--! bootstrap.htm -->
{% extends "base.htm" %}
{% load static %}
{% block link %}
  <link rel="stylesheet" href='{% static "bootstrap/bootstrap.min.css" %}'>
  <link rel="stylesheet" href='{% static "bootstrap/bootstrap-theme.min.css" %}'>
  <link rel="stylesheet" href='{% static "bootstrap/bootstrap-table.min.css" %}'>
{% endblock %}
{% block script %}
  <script src='{% static "bootstrap/jquery.min.js" %}'></script>
  <script src='{% static "bootstrap/bootstrap.min.js" %}'></script>
  <script src='{% static "bootstrap/bootstrap-table.min.js" %}'></script>
{% endblock %}


4. ExtJS 模板網頁 :

使用 ExtJS 需載入 ext-all.css 與 ext-all.js 以及語言檔 ext-lang-zh_TW.js, 我使用的是五年前的舊版本 v4.2.2 GPL 版 (之前買的書也是 v4.1 版), 參考 :

ExtJs 環境部署

<--! extjs.htm -->
{% extends "base.htm" %}
{% load static %}
{% block link %}
<link id="theme" rel="stylesheet" href='{% static "extjs/resources/css/ext-all.css" %}'>
{% endblock%}
{% block script %}
<script type="text/javascript" src='{% static "extjs/ext-all.js" %}'></script>
<script type="text/javascript" src='{% static "extjs/locale/ext-lang-zh_TW.js" %}'></script>
{% endblock%}

注意, 遷就之前的主題佈景測試範例使用 Javascript 切換, 因此這裡 id="theme" 在下面的佈景切換測試中還用不到.


二. 修改測試首頁 home.htm 

為了新增 ExtJS 的兩項測試, 需修改首頁 /templates/home.htm :

<--! home.htm -->
<!DOCTYPE html>
<html>
<head>
  <title>前端框架模板模板測試</title>
  <meta charset="utf-8">
</head>
<body>
  <h3>前端框架模板測試</h3>
  <ul>
    <li><a href="/jqui_test_tabs">jQueryUI 頁嵌面板 Tabs</a></li>
    <li><a href="/jqui_test_themes">jQueryUI 主題布景切換 Themes</a></li>
    <li><a href="/jqui_test_datatables_array">jQueryUI 資料表格 DataTables (陣列)</a></li>
    <li><a href="/jqui_test_datatables_ajax">jQueryUI 資料表格 DataTables (Ajax)</a></li>
    <li><a href="/ezui_test_tabs">EasyUI 頁嵌面板 Tabs</a></li>
    <li><a href="/ezui_test_themes">EasyUI 主題布景切換 themes</a></li>
    <li><a href="/ezui_test_datagrid_ajax">EasyUI 資料表格 Datagrid (Ajax)</a></li>
    <li><a href="/bootstrap_test_table_html">Bootstrap 表格 (HTML)</a></li>
    <li><a href="/bootstrap_test_table_ajax">Bootstrap 表格 (Ajax)</a></li>
    <li><a href="/bootstrap_test_jumbotron">Bootstrap 主題 (jumbotro)</a></li>
    <li><a href="/extjs_test_themes">ExtJS 主題布景切換 themes</a></li>
    <li><a href="/extjs_test_grid_panel">ExtJS 資料表格 GridPanel</a></li>
  </ul>
</body>
</html>

藍色部分即所新增的兩個 ExtJS 測試.


三. 修改主題佈景測試網頁 : 

因 jQuery UI 與 EasyUI 提供主題佈景, 在上一篇測試中直接取用 CDN 供檔, 但若改為本地供檔時, 網頁中的 Javascript 程式需進行修改, 原先 jqui_test_themes.htm 在 CDN 版本是這樣寫的 :

    $(document).ready(function(){
      $("#datepicker").datepicker();
      $("#themes").selectmenu();
      $("#themes").val("hot-sneaks");
      $("#themes").selectmenu("refresh");
      $('#themes').on('selectmenuchange', function() {
        var theme=$(this).val();
        var href="https://code.jquery.com/ui/1.12.0/themes/" + theme +
                 "/jquery-ui.min.css";
        $("#theme").attr("href", href);
        });

此處由本地供檔要改為如下 :

    $(document).ready(function(){
      $("#datepicker").datepicker();
      $("#themes").selectmenu({width:180});
      $("#themes").val("hot-sneaks");
      $("#themes").selectmenu("refresh");
      $('#themes').on('selectmenuchange', function() {
        var theme=$(this).val();
        var href='{% static "jqueryui/themes/" %}' + theme + "/jquery-ui.min.css";
        $("#theme").attr("href", href);
        });
      });

此處用到 static 指令, 因此在網頁最前面需先用 load static 指令取得靜態目錄位置, 修改後的測試網頁如下 :

{% extends "jqueryui.htm" %}
{% load static %}
{% block style %}
    body {
      font-family: Arial, Helvetica, sans-serif;
      font-size:10px;
      }
{% endblock%}
{% block body %}
  <select id="themes">
    <option value="base">base</option>
    <option value="black-tie">black-tie</option>
    <option value="blitzer">blitzer</option>
    <option value="cupertino">cupertino</option>
    <option value="dark-hive">dark-hive</option>
    <option value="dot-luv">dot-luv</option>
    <option value="eggplant">eggplant</option>
    <option value="excite-bike">excite-bike</option>
    <option value="flick">flick</option>
    <option value="hot-sneaks" selected>hot-sneaks</option>
    <option value="humanity">humanity</option>
    <option value="le-frog">le-frog</option>
    <option value="mint-choc">mint-choc</option>
    <option value="overcast">overcast</option>
    <option value="pepper-grinder">pepper-grinder</option>
    <option value="redmond">redmond</option>
    <option value="smoothness">smoothness</option>
    <option value="south-street">south-street</option>
    <option value="start">start</option>
    <option value="sunny">sunny</option>
    <option value="swanky-purse">swanky-purse</option>
    <option value="trontastic">trontastic</option>
    <option value="ui-darkness">ui-darkness</option>
    <option value="ui-lightness">ui-lightness</option>
    <option value="vader">vader</option>
  </select><br><br>
  <script>
    $(document).ready(function(){
      $("#datepicker").datepicker();
      $("#themes").selectmenu({width:180});
      $("#themes").val("hot-sneaks");
      $("#themes").selectmenu("refresh");
      $('#themes').on('selectmenuchange', function() {
        var theme=$(this).val();
        var href='{% static "jqueryui/themes/" %}' + theme + "/jquery-ui.min.css";
        $("#theme").attr("href", href);
        });
      });
  </script>
{% endblock%}

我覺得這 selectmenu 似乎怪怪的, 選項像清單一樣全部打開不會收闔, 之前測試不會, 難道是與 datepicker 犯沖嗎? 參考 :

jQuery UI 學習筆記 (十) : 下拉式選單 (Selectmenu)
jQuery UI 學習筆記 (一) : 主題布景 (Themes)

其實 jQuery UI 的主題佈景中我最喜歡的只有 hot-sneaks, 用在公司的專案都是使用此佈景.

原先 ezui_test_themes.htm 在 CDN 版本是這樣寫的 :

    $(document).ready(function() {
      $("#theme_sel").combobox({
        onSelect:function(rec){
          var css="http://www.jeasyui.com/easyui/themes/" +
                  rec.value + "/easyui.css";
          $("#theme").attr("href", css);
          }
        });
      });

此處由本地供檔要改為如下 :

    $(document).ready(function() {
      $("#theme_sel").combobox({
        onSelect:function(rec){
          var css='{% static "easyui/themes/" %}' + rec.value + "/easyui.css";
          $("#theme").attr("href", css);
          }
        });
      });

這裡同樣在網頁最前面需先用 load static 指令取得靜態目錄位置, 修改後的測試網頁如下 :

<!--ezui_test_themes.htm-->
{% extends "easyui.htm" %}
{% load static %}
{% block style %}
    body {
      font-family: Arial, Helvetica, sans-serif;
      font-size:10px;
      }
{% endblock%}
{% block body %}
  <select id="theme_sel" class="easyui-combobox" style="width:120px" panelHeight="320">
    <option value="default" selected>default</option>
    <option value="gray">gray</option>
    <option value="black">black</option>
    <option value="bootstrap">bootstrap</option>
    <option value="metro">metro</option>
    <option value="metro-blue">metro-blue</option>
    <option value="metro-gray">metro-gray</option>
    <option value="metro-green">metro-green</option>
    <option value="metro-orange">metro-orange</option>
    <option value="metro-red">metro-red</option>
    <option value="ui-cupertino">ui-cupertino</option>
    <option value="ui-dark-hive">ui-dark-hive</option>
    <option value="ui-pepper-grinder">ui-pepper-grinder</option>
    <option value="ui-sunny">ui-sunny</option>
  </select><br><br>
  <input id="datebox1" type="text" class="easyui-datebox">
  <script>
    $(document).ready(function() {
      $("#theme_sel").combobox({
        onSelect:function(rec){
          var css='{% static "easyui/themes/" %}' + rec.value + "/easyui.css";
          $("#theme").attr("href", css);
          }
        });
      });
  </script>
{% endblock%}

藍色部分為修改或增加的部分, 其餘不變.


四. 新增兩個 ExtJS 測試網頁 :

在 templates 目錄下新增 extjs_test_themes.htm (主題佈景測試) 與 extjs_test_grid_panel. htm (資料表格) 兩個測試網頁, 其中主題佈景測試 取自之前的 ExtJS 測試, 參考 :

# ExtJS 4 測試 (二) : 主題佈景切換 (Look and Feel)

<--! extjs_test_themes.htm -->
{% extends "extjs.htm" %}
{% load static %}
{% block style %}
   body {padding:20px;}
{% endblock%}
{% block body %}
  <script type="text/javascript">
    Ext.onReady(function() {
      var btn_alert=new Ext.Button({
          text : "訊息框",
          width : 100,
          renderTo : Ext.getBody(),
          handler : function(btn) {
            Ext.MessageBox.alert("通知訊息", "您好! Hello World!");
            }
          });
      var neptune=new Ext.Button({
          text : "Neptune",
          width : 100,
          renderTo : Ext.getBody(),
          handler : function() {
            var url='{% static "extjs/resources/css/ext-all-neptune.css" %}';
            Ext.util.CSS.swapStyleSheet("theme",url);
            }
          });
      var gray=new Ext.Button({
          text : "Gray",
          width : 100,
          renderTo : Ext.getBody(),
          handler : function() {
            var url='{% static "extjs/resources/css/ext-all-gray.css" %}';
            Ext.util.CSS.swapStyleSheet("theme",url);
            }
          });
      var access=new Ext.Button({
          text : "Access",
          width : 100,
          renderTo : Ext.getBody(),
          handler : function() {
            var url='{% static "extjs/resources/css/ext-all-access.css" %}';
            Ext.util.CSS.swapStyleSheet("theme",url);
            }
          });
      var Default=new Ext.Button({
          text : "Default",
          width : 100,
          renderTo : Ext.getBody(),
          handler : function() {
            var url='{% static "extjs/resources/css/ext-all.css" %}';
            Ext.util.CSS.swapStyleSheet("theme",url);
            }
          });
      }); //end of onReady
  </script>
{% endblock%}


而資料表格測試 extjs_test_grid_panel. htm 則參考下列的範例 1 :

# ExtJS 4 測試 : GridPanel (一)

<--! extjs_test_grid_panel. htm -->
{% extends "extjs.htm" %}
{% block style %}
   body {padding:20px;}
{% endblock%}
{% block body %}
  <div id="grid"></div>
  <script type="text/javascript">
    Ext.onReady(function() {
      //定義表頭欄位
      var columns=[{header:"股票名稱",dataIndex:"name"},
                   {header:"股票代號",dataIndex:"id"},
                   {header:"收盤價 (元)",dataIndex:"close"},
                   {header:"成交量 (張)",dataIndex:"volumn"}
                   ];
      //定義原始資料
      var data=[["台積電","2330",123.0,25119],
                ["中華電","2412",96.4,5249],
                ["中碳","1723",192.5,918],
                ["創見","2451",108.0,733],
                ["華擎","3515",118.5,175],
                ["訊連","5203",97.0,235]
                ];
      //轉成 Store 物件
      var store=Ext.create("Ext.data.ArrayStore", {
          data:data,
          fields:[
            {name:"name"},
            {name:"id"},
            {name:"close"},
            {name:"volumn"}]
          });
      store.load();
      //建立 GridPanel
      var grid=Ext.create("Ext.grid.Panel",{
        title:"台股",
        columns:columns,
        store:store,
        renderTo:"grid",
        autoHeight:true,
        width:450
        });
      }); //end of onReady
  </script>
{% endblock%}


五. 修改 urls.py 與 views.py :

路由程式 urls.py 新增兩個 URL (藍色部分) : 

#urls.py
from django.contrib import admin
from django.urls import path
import mysite.views as views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('jqui_test_tabs/', views.jqui_test_tabs),
    path('jqui_test_tab2/', views.jqui_test_tab2),
    path('jqui_test_tab3/', views.jqui_test_tab3),
    path('jqui_test_themes/', views.jqui_test_themes),
    path('jqui_test_datatables_array/', views.jqui_test_datatables_array),
    path('jqui_test_datatables_ajax/', views.jqui_test_datatables_ajax),
    path('get_stocks_list/', views.get_stocks_list),
    path('ezui_test_tabs/', views.ezui_test_tabs),
    path('ezui_test_tab2/', views.ezui_test_tab2),
    path('ezui_test_tab3/', views.ezui_test_tab3),
    path('ezui_test_themes/', views.ezui_test_themes),
    path('ezui_test_datagrid_ajax/', views.ezui_test_datagrid_ajax),
    path('get_stocks_list_ezui/', views.get_stocks_list_ezui),
    path('bootstrap_test_table_html/', views.bootstrap_test_table_html),
    path('bootstrap_test_table_ajax/', views.bootstrap_test_table_ajax),
    path('bootstrap_test_jumbotron/', views.bootstrap_test_jumbotron),
    path('extjs_test_themes/', views.extjs_test_themes),
    path('extjs_test_grid_panel/', views.extjs_test_grid_panel),
    path('', views.home),
]

視圖處理程式 views.py 新增兩個函數 (藍色部分) :

#views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.http import JsonResponse
from datetime import datetime

def jqui_test_tabs(request):
    return render(request, 'jqui_test_tabs.htm', {})

def jqui_test_tab2(request):
    tab=2
    return render(request, 'jqui_test_tab2.htm', locals())

def jqui_test_tab3(request):
    return HttpResponse("<h3>這是頁籤 3 (直接回應)</h3>")

def jqui_test_themes(request):
    return render(request, 'jqui_test_themes.htm', {})

def jqui_test_datatables_array(request):
    return render(request, 'jqui_test_datatables_array.htm', {})

def jqui_test_datatables_ajax(request):
    return render(request, 'jqui_test_datatables_ajax.htm', {})

def get_stocks_list(request):
    data={"aaData":[{"stock_name":"台積電",
                    "stock_id":"2330",
                    "close":111.5,
                    "volumn":19268},
                   {"stock_name":"中華電",
                    "stock_id":"2412",
                    "close":95.1,
                    "volumn":7096},
                   {"stock_name":"中碳",
                    "stock_id":"1723",
                    "close":145.0,
                    "volumn":317},
                   {"stock_name":"創見",
                    "stock_id":"2451",
                    "close":104.0,
                    "volumn":459},
                   {"stock_name":"華擎",
                    "stock_id":"3515",
                    "close":104.0,
                    "volumn":95},
                   {"stock_name":"訊連",
                    "stock_id":"5203",
                    "close":98.5,
                    "volumn":326}]}
    return JsonResponse(data)

def ezui_test_tabs(request):
    return render(request, 'ezui_test_tabs.htm', {})

def ezui_test_tab2(request):
    tab=2
    return render(request, 'ezui_test_tab2.htm', locals())

def ezui_test_tab3(request):
    return HttpResponse("<h3>這是頁籤 3 (直接回應)</h3>")

def ezui_test_themes(request):
    return render(request, 'ezui_test_themes.htm', {})

def ezui_test_datagrid_ajax(request):
    return render(request, 'ezui_test_datagrid_ajax.htm', {})

def get_stocks_list_ezui(request):
    data={"totals":"6",
          "rows":[{"stock_name":"台積電",
                    "stock_id":"2330",
                    "close":111.5,
                    "volumn":19268},
                   {"stock_name":"中華電",
                    "stock_id":"2412",
                    "close":95.1,
                    "volumn":7096},
                   {"stock_name":"中碳",
                    "stock_id":"1723",
                    "close":145.0,
                    "volumn":317},
                   {"stock_name":"創見",
                    "stock_id":"2451",
                    "close":104.0,
                    "volumn":459},
                   {"stock_name":"華擎",
                    "stock_id":"3515",
                    "close":104.0,
                    "volumn":95},
                   {"stock_name":"訊連",
                    "stock_id":"5203",
                    "close":98.5,
                    "volumn":326}]}
    return JsonResponse(data)

def bootstrap_test_table_html(request):
    return render(request, 'bootstrap_test_table_html.htm', {})

def bootstrap_test_table_ajax(request):
    return render(request, 'bootstrap_test_table_ajax.htm', {})

def bootstrap_test_jumbotron(request):
    return render(request, 'bootstrap_test_jumbotron.htm', {})

def extjs_test_themes(request):
    return render(request, 'extjs_test_themes.htm', {})

def extjs_test_grid_panel(request):
    return render(request, 'extjs_test_grid_panel.htm', {})

def home(request):
    return render(request, 'home.htm', {})


以上就是此次測試的全紀錄, 終於順利將四個前端 UI 框架納入 Django 架構中, 四個框架檔案大小合計 18.6MB, 但實際應用時不需要全上, 只要挑選要用的框架放在 static 目錄下即可. 下面僅紀錄 ExtJS 的兩個測試結果, 其它三個框架的測試參考上一篇 "模板的匯入與繼承" :






Bingo! 繼續往下一站前進!

參考 :

https://www.jeasyui.com/extension/themes_older.php

2019-11-04 補充 :

上面的 ExtJS 主題佈景測試可以跟 jQueryUI 與 EasyUI 一樣改用 ComboBox 來做主題設定, extjs_test_themes.htm 網頁更改如下 : 

<--! extjs_test_themes.htm -->
{% extends "extjs.htm" %}
{% load static %}
{% block style %}
   body {padding:20px;}
{% endblock%}
{% block body %}
  <script type="text/javascript">
    Ext.onReady(function() {
      var themes=Ext.create('Ext.data.Store', {
          fields : ['theme', 'value'],     //theme=顯示用, value=值
          data : [
            {"theme":"Default", "value":"default"},
            {"theme":"Neptune", "value":"neptune"},
            {"theme":"Gray", "value":"gray"},
            {"theme":"Access", "value":"access"}
            ]
        });
      Ext.create('Ext.form.ComboBox', {
          fieldLabel: '選擇主題',
          store: themes,
          queryMode: 'local',
          displayField: 'theme',
          valueField: 'value',
          renderTo: Ext.getBody(),
          listeners:{
            change: function(combo, nv, ov){  //nv=新選項, ov=舊選項
              if (nv=="default") {
                var href='{% static "extjs/resources/css/ext-all.css" %}';
                }
              else {         
                var href='{% static "extjs/resources/css/ext-all-" %}' + nv + ".css";
                }
              var theme_link=Ext.get("theme");  //取得 Link 元件物件
              theme_link.set({'href' : href});  //設定新佈景
              }
            }
          });
      var btn_alert=new Ext.Button({
          text : "訊息框",
          width : 100,
          renderTo : Ext.getBody(),
          handler : function(btn) {
            Ext.MessageBox.alert("通知訊息", "您好! Hello World!");
            }
          });
      }); //end of onReady
  </script>
{% endblock%}

此程式首先為下拉式選單建立資料來源 (data store), 然後在 listeners 屬性中設定監聽 change 事件, 只要偵測到選項改變就呼叫 Link 元件的 set() 方法更改要套用的主題佈景之 css 檔. 預設佈景是 ext-all.css, 而其它佈景為 ext-all-xxx.css, 因此需用 if else 來判斷. 結果如下 :




參考 : 

https://docs.sencha.com/extjs/6.2.0/classic/Ext.form.field.ComboBox.html
DOM的查詢&遍歷
ExtJS4.2 下拉列表Combobox级联选择
https://www.extjs-tutorial.com/extjs/working-with-dom
Ext.form.field.ComboBoxView source

2019-11-05 補充 :

關於上面 jQuery UI 主題佈景切換測試中, 發現下拉式選單 SelectMenu 元件整個清單會展開亂跳的現象, 今天將 jquery.htm 改換回 CDN 供檔方式就正常, 其次更改底下切換主題 CSS 的來源為本地主題又不行 :

var href="https://code.jquery.com/ui/1.12.0/themes/" + theme +
               "/jquery-ui.min.css";     //OK
var href="/static/jqueryui/themes/" + theme + "/jquery-ui.min.css";  //NG

本地使用最新的 jQuery UI 1.12.1 版, 我以為是版本問題, 就去下載 jQuery UI 1.12.0 版, 結果還是一樣會亂跳, 但只要底下切換主題的 href 改回 CDN 來源就正常, 很奇怪, 明明都是從 jQuery UI 官網下載的 1.12.0 版, 為何會有這種差別?

https://jqueryui.com/download/all/

我又改為使用 CDN 供檔的 1.12.1 版也 OK 啊! 可見不是版本問題, 難道是開發伺服器問題? 目前無解, 總之, 若使用 jQuery UI 開發, 我想還是使用 CDN 供檔方式較妥當, 不然就固定用漂亮的 hot-sneaks 主題就好, 別切換了.

基於以上測試心得, 結論是 EasyUI 與 ExtJS 最好使用本機供檔方式以固定版本保證網站外觀; 而 jQuery UI 與 Bootstrap 就直接使用 CDN 供檔即可, 因為 Bootstrp 與 jQuery UI 都已很成熟.

沒有留言 :