:::

6. 檢查必填欄位與常用小工具

一、檢查必填欄位

  1. 加到新增、修改函數:
    • add()
      function add()
      {
          global $db, $smarty;
      
          $message = '';
          if (empty($_POST['title'])) {
              $message .= '標題必填 | ';
          }
          if (empty($_POST['directions'])) {
              $message .= '描述必填 | ';
          }
      
          if (!isset($_POST['assign'])) {
              $message .= '至少指派一名';
          }
      
          if (!empty($message)) {
              echo "<script>alert('" . $message . "');history.back();</script>;";
              exit;
          }
          /************省略*****************/
      
      }
    • update()
      //更新清單
      function update()
      {
          global $db, $smarty;
      
          $message = '';
          if (empty($_POST['title'])) {
              $message .= '標題必填 | ';
          }
          if (empty($_POST['directions'])) {
              $message .= '描述必填 | ';
          }
      
          if (!isset($_POST['assign'])) {
              $message .= '至少指派一名';
          }
      
          if (!empty($message)) {
              // 返回上一頁並重新整理
              echo "<script>alert('" . $message . "');self.location=document.referrer;</script>;";
              exit;
          }
      
      
          /****************省略***************/
      }

       

二、加入所見即所得編輯器

  1. 官網:https://ckeditor.com/ckeditor-5/
  2. 參考文件:https://ckeditor.com/ckeditor-5/demo/
  3. 下載:https://ckeditor.com/ckeditor-5/online-builder/ 勾選
    • Alignment
    • Font background color、Font color、Font size、Font family
    • Highlight
    • Horizontal line
    • Indent block
    • List style
    • Table cell properties、Table properties
    • Underline
  4. 在【 htdocs】內建目錄【 class 】並將檔案 ckeditor5.zip 解壓到目錄【 class /ckeditor5】。
    D:\xampp\htdocs> mkdir class
  5. 可刪除目錄【sample】。
  6. post_form.tpl 最後引入
    <script src="/class/ckeditor5/build/ckeditor.js"></script>
    <script>ClassicEditor
        .create( document.querySelector( '#editor' ), {
          toolbar: {
            items: [
              'heading',
              '|',
              'alignment',
              'bold',
              'italic',
              'link',
              'bulletedList',
              'numberedList',
              '|',
              'outdent',
              'indent',
              '|',
              'imageUpload',
              'blockQuote',
              'insertTable',
              'mediaEmbed',
              'undo',
              'redo',
              'fontBackgroundColor',
              'fontColor',
              'fontSize',
              'fontFamily',
              'highlight',
              'underline',
              'horizontalLine'
            ]
          },
          language: 'zh',
          image: {
            toolbar: [
              'imageTextAlternative',
              'imageStyle:full',
              'imageStyle:side'
            ]
          },
          table: {
            contentToolbar: [
              'tableColumn',
              'tableRow',
              'mergeTableCells',
              'tableCellProperties',
              'tableProperties'
            ]
          },
          licenseKey: '',
    
    
        } )
        .then( editor => {
          window.editor = editor;
        } )
        .catch( error => {
          console.error( 'Oops, something went wrong!' );
          console.error( 'Please, report the following error on https://github.com/ckeditor/ckeditor5/issues with the build id and the error stack trace:' );
          console.warn( 'Build id: 1rgkipb73di4-u4vchuqjbqta' );
          console.error( error );
        } )
    
    .editorConfig(config=>{
        config.allowedContent = {
            script: true,
            $1: {
                // This will set the default set of elements
                elements: CKEDITOR.dtd,
                attributes: true,
                styles: true,
                classes: true
            }
        }})
    ;
    </script>
  7. 設置高度
  8. <style>
      .ck-editor__editable {
          min-height: 8rem;
      }
    </style>
  9. post_form.tpl 修改大量文字框
    <textarea id="editor" class="form-control" name="directions" >{$content.directions}</textarea>
  10. 顯示在網頁不需轉換HTML特殊符號,修改index.php函數 find_one()
    function find_one($sn = "")
    {
        global $db;
    
        /****省略***/
        /**********註記以下********/
        //$data['directions'] = htmlspecialchars($data['directions'], ENT_QUOTES);
    
    }
  11.  show_one.tpl
    <div class="row">
            <label class="col-sm-3 text-right">
                描述
            </label>
            <div class="col-sm-9">
                {$content.directions}
            </div>
        </div>

三、html簡易表單驗證

  1. 簡單的表單驗證,可以考慮使用 HTML5 表單驗證。
  2. 相關屬性
    • 必填欄位:required
      <input type="text" required>
    • 限定長度: maxlength、 minlength
      <input type="text" id="text" name="text" minlength="2" maxlength="20">
    • 使用正規表達式進行驗證 : pattern
      <input type="text" class="form-control" id="title" name='title' placeholder="字數 2 ~ 20" value='{$content.title}' required pattern="{literal}[a-zA-Z0-9_]{2,20}{/literal}">
    • https://cloudlab.tw/wp/sampleFiles/RegExp/
    • 限定範圍: min 與 max
      <input type="date" class="form-control" id="end" name="end" value='{$content.end}' required min="{$now}" max="2022-12-31">
  3. post_form.tpl
    <div class="row m-3">
      <label for="title" class="col-sm-2 col-form-label text-end">待辦事項</label>
      <div class="col-sm-10">
        <input type="text" class="form-control" id="title" name='title' placeholder="字數 2 ~ 20" value='{$content.title}' required pattern="{literal}[a-zA-Z0-9_]{2,20}{/literal}">
      </div>
    </div>
      <!-- 省略 -->
     
    <div class="row m-3">
      <label for="end" class="col-sm-2 col-form-label text-end">到期日</label>
      <div class="col-sm-10">
        <input type="date" class="form-control" id="end" name="end" value='{$content.end}'  required min="{$now}" max="2022-12-31">
      </div>
    </div>

四、分頁功能

  1. 下載 PageBar fot bootstrap5 分頁物件
  2. 解壓到 class/PageBar.php
  3. 修改 index.php 中的 list_all() 函數:
    • 必須放在原有的 $sql 和 $result 之間才行!
    • // 列出所有
      function list_all()
      {
          global $db, $smarty, $content;
      
          include_once "class/PageBar.php";
      
          $sql = "select * from `list` order by priority,end";
      
          $PageBar = getPageBar($db, $sql, 10, 10);
          $bar     = $PageBar['bar'];
          $sql     = $PageBar['sql'];
          $total   = $PageBar['total'];
          $result  = $db->query($sql);
      
          if (!$result) {
              throw new Exception($db->error);
          }
      
          /**省略**/
          $smarty->assign('total', $total);
          $smarty->assign('bar', $bar);
      }
      
  4. getPageBar的參數說明:
    • getPageBar($mysqli, $sql, $show_num = 20, $page_list = 10, $to_page = "", $url_other = "")
    • $mysqli:使用的資料庫物件名稱(必要)
    • $sql:欲執行的語法(必要)
    • $show_num = 20:每頁顯示資料數

    • $page_list = 10:分頁工具列呈現的頁數

    • $to_page = "":要連結到那一個頁面

    • $url_other = "":其他額外的連結參數

  5. 修改 templates/index.tpl 樣板,在表格上方加入資料數:
    <h3>待辦清單<small>(共 {$total} 個事項)</small></h3>
  6. 在表格下面加入分頁工具列:
    {$bar}

五、sweet alert

  1. sweet alert官網:http://t4t5.github.io/sweetalert/
  2. 用 npm 安裝 ,按 Ctrl+ ` 開啟終端機,並貼上:
    npm i jquery
    npm install --save sweetalert
    
  3. 修改刪除按鈕為
    <a href="javascript:del({$row.sn})" class="btn btn-danger" title="刪除"><i class="fas fa-times-circle"></i> 刪除</a>
  4. 參考:https://github.com/t4t5/sweetalert (A warning message, with a function attached to the confirm message:Using promises)
    • 將以下語法貼到有上述連結的樣板檔案中,或者存成 templates\sweetalert_delete.tpl:
      <script src='/node_modules/jquery/dist/jquery.min.js'></script>
      <script type='text/javascript' src='/node_modules/sweetalert/dist/sweetalert.min.js'></script>
      <script type="text/javascript">
        function del(sn){
          swal({
            title: "確定要刪除嗎?",
            text: "刪除後資料就救不回來囉!",
            type: "warning",
            buttons: {
              cancel: "不...別刪",
              roll: {
                text: "是!含淚刪除!",
                value: "roll",
              },
            },
          }).then(willDelete => {
            if (willDelete) {
              swal("OK!刪掉惹!", "該資料已經隨風而逝了...", "success");
              location.href='index.php?op=delete&sn=' + sn;
            }
          });
        }
      </script>
  5. 然後在 index.tpl 引入該樣板檔即可:
    {include file='sweetalert_delete.tpl'}
  6. 移除 index.php 流程 case 'delete': 中的 echo
    switch ($op) {
        case 'delete':
            del($sn);
            // 轉向
            header("location:index.php");
            exit;
    /*********** 省略 *******************/

六、課後練習

  1. 顯示單筆待辦事項詳細資料。
    <a class="btn btn-link" href=""></a>

     

  2. 首頁只顯示未完成事項。
    $sql = "SELECT * FROM `list` where done!=1 order by end desc"

     

  3. 做一頁已完成待辦清單。
    • 1.header.php 加入導覽列
      $navbar = ['home' => "回首頁", 'post' => "發布待辦事項", 'done' => "已完成清單"];
      2.navbar.tpl
      <li class="nav-item">
          <a class="nav-link {if isset($op) && $op=='done'}active{/if}" href="{$action}?op=done">{$navbar.done}</a>
      </li>
      3. 根據op 在 index.php加流程,在 index.tpl加一組樣板
         case 'done':
               done();
               break;
      
      {elseif $op=="done"}
              {include file='done.tpl'}
      4.撰寫 function done()
      5.製作顯示頁done.tpl