# 七、\[前端] Todo List 前端開發

※之後自己用純前端仿造了一個 todo list

* <https://github.com/ayugioh2003/frondEnd_todolist_project>

我畫的草稿好醜啊 orz 而且感覺我之後不會想用這介面 XD

![TODO範例圖](https://i.imgur.com/g49oQad.png)

## 建立 HTML 架構

php

MAMP，沒有事先講怎麼安裝

* 結合 php，Apache伺服器、MySQL伺服器
* [MAMP & MAMP PRO - Downloads](https://www.mamp.info/en/downloads/)
* [\[PHP\]\[Windows\] 00. 覺得開發環境設定很麻煩嗎，用 MAMP 安裝就對了！](https://progressbar.tw/posts/28)
* [\[PHP\]\[Mac\] 00. 覺得開發環境設定很麻煩嗎，用 MAMP 安裝就對了！](https://progressbar.tw/posts/27)
* [\[MAC\] MAMP 輕鬆在 MAC 上佈置 Apache + MySQL + PHP 環境！ - Orz 快樂學電腦](https://www.orztw.com/2014/05/macos-mamp-apache-mysql-php-phpmyadmin.html)

```
<?php include('header.php') ?>

<div id="panel">
    <h1>Todo List</h1>
    <div id="todo-list">
        <ul>
            <li>
                <div class="checkbox"></div>
                <div class="content">Lorem, ipsum dolor.</div>
                <div class="actions">
                    <div class="delete">x</div>
                </div>
            </li>
            <li>
                <div class="checkbox"></div>
                <div class="content">Lorem, ipsum dolor.</div>
                <div class="actions">
                    <div class="delete">x</div>
                </div>
            </li>
            <li>
                <div class="checkbox"></div>
                <div class="content">Lorem, ipsum dolor.</div>
                <div class="actions">
                    <div class="delete">x</div>
                </div>
            </li>
            <li class="new">
                <div class="checkbox"></div>
                <div class="content" contenteditable="true"></div>
            </li>          
        </ul>
    </div>
</div>   


<?php include('footer.php') ?>
```

## 準備 CSS 檔案

bootstrap

越基礎的 css，link 要放月前面

權重

clear cache

先從大的，再修小的

## \[CSS] 版面置中

```css
/* main.css */

#panel {
    width: 600px;
    padding: 30px;
    background-color: #eee;
    margin: 0 auto;    
}
```

## \[CSS] todo list 項目

ul

* 把點拿掉

.checkbox

* border-radius: 50%; 圓角

排版

* 用 bootstrap 的 clearfix:after 清除浮動
* 舊的排版，用 float:left，用 width 佔寬度

```css
#panel {
    width: 600px;
    padding: 30px;
    background-color: #eee;
    margin: 0 auto;    
}

#todo-list ul {
    margin: 0;
    padding: 0;
    list-style-type: none;
}

#todo-list .checkbox {
    float: left;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    background-color: #ccc;
}

#todo-list .content {
    float: left;
    width: calc(100% - 60px);
}

#todo-list .actions {
    float: left;
    width: 30px;
}
```

新的排版 flex

* [Flexbox basic / 網頁基礎 15 天 - Blog](https://www.everyonecanwebsite.com/blog/post/flexbox-basic)

flex container 下了 display: flex 後，flex items 就會有預設值 flex: 0 1 auto

1. ​ flex: 1 0;
2. 1. ​    flex-grow: 1; // 空餘空間成長
   2. ​    flex-shrink: 0; // 寬度超出容器時，要不要縮小
   3. ​    flex-basis: 0%; // 依照自己的寬度

.list

* hover list 時，有顏色區別
* 偽元素

.checkbox, .actions

* 點點可以點，hover 時會變成手指頭

.actions

* .delete 按鈕太小，幫他 padding 加寬

```css
#panel {
    width: 600px;
    padding: 30px;
    background-color: #eee;
    margin: 0 auto;    
}

#todo-list ul {
    margin: 0;
    padding: 0;
    list-style-type: none;
}

#todo-list li {
    display: flex;
    padding: 10px;
}

#todo-list li:hover {
    background-color: #f8f8f8;
}

#todo-list .checkbox {
    margin-right: 10px;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    background-color: #ccc;
    cursor: pointer;
}

#todo-list .content {
    flex: 1; 
}


#todo-list .actions > *  {
    padding: 0 10px;
    cursor: pointer;
}
```

基礎的東西打好了

## \[CSS] todo list 完成狀態

狀態沒有改變。雖然後端可能收到資料了，但前端畫面沒有改變，使用者會困惑

`todo-list li.complete .checkbox`

* 當使用者點選按鈕後，checkbox 會變顏色

`todo-list li.complete .content`

* 當使用者點選按鈕後，內容會有刪除線

## 準備 jQuery 檔案

jQuery download

記得引入 js 檔

## \[jQuery] 製作功能：create todo list

`$(document).ready();` 很重要

要什麼功能？

* CRUD
* 排序
* complete&#x20;

新增

* 架構要變成和其他 list 一樣
* 新增完，li.new>.content 的資料要清空
* 可以先建立空白範本，隱藏起來

## 使用 Handlerbars.js 建立 todo list 的模板

專門做 js template 的工具

* <https://handlebarsjs.com/>
* 自己做 template hide 的作法，對 SEO 可能不利

建立 handlebar 形式的 template

```markup
<script id="todo-list-item-template" type="text/x-handlebars-template">
    <li class="{{#if is_complete}}complete{{/if}}">
        <div class="checkbox"></div>
        <div class="content">{{content}}</div>
        <div class="actions">
            <div class="delete">x</div>
        </div>
    </li>

</script>
```

解析它，存在 var template 裡面

```javascript
        var source = $('#todo-list-item-template').html();
        var template = Handlebars.compile(source);
```

準備好內容，塞到 template，變成 li

```javascript
        todo = {
            is_complete: false,
            content: todo,
        };
        var li = template(todo);
```

判斷使用者沒有輸入空白

## \[jQuery] 製作功能：update todo list 的內容

dblclick

點兩下，進入編輯模式

blue，取消編輯模式

## \[jQuery] 區分 create 和 update 的機制

on. 可以連寫

用 if (isNew) 判斷 li 是不是 li.new

```javascript
var isNew = $('this').closest('li').is('.new');
```

## \[jQuery] 製作功能：delete todo list

click

## \[jQuery] 製作功能：製作功能：完成待辦事項

taker 標題打成代辦了

complete

toggleClass() 開關 class

* [jQuery 學習筆記—— .addClass()/.removeClass()/.toggleClass()\_ 教程\_w3cplus](https://www.w3cplus.com/blog/117.html)

## \[jQuery] 製作功能：todo list 排序

jQuery sortable

* [Sortable | jQuery UI](https://jqueryui.com/sortable/)

引入 ui 的 js 和 css 後，加上這句

```javascript
$('#todo-list').find('ul').sortable();
```

但會有一個問題，新增 TODO 的列也被跟著移動了。但官網裡有排除某些 list 被拖曳的範例

這一節是我上這個課程時，第一次跟不太上的 XD
