0%

[技能檢定]題組一 步驟15 製作編輯次選單功能

次選單功能是本題組中較為複雜,但說明卻相對模糊的功能,這裏我們採用較直覺的做法來解題,依照題目給出的參考圖來看,題目希望次選單的新增/修改/刪除都在彈出視窗中完成。

由於一個畫面的表單中要同時具有增改刪查的功能,因此我們無法延用先前製作的API或彈出視窗表單來處理次選單的功能,所以次選單的API單獨一支程式來處理,因此我們在 ./view/backend/menu.php 的彈出視窗的按鈕參數上採用指定路徑檔名的方式來處理,而不是和先前幾個功能一樣採用帶入資料表變數的方式。

/Controller/Menu.php

1
2
3
4
5
6
7
8
9
10
//function backend();
----------------------------------
$view=['header'=>'選單管理',
'table'=>$this->table,
'rows'=>$rows,
'addbtn'=>'新增主選單',
'modal'=>"./view/modal/menu.php",
'updateModal'=>"./view/modal/submenu.php", //指定次選單表單的檔案
'updateBtn'=>"編輯次選單"
];

建立彈出視窗表單
/view/modal/submenu.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!--因為是獨立的功能,而且會使用到資料表,所以要先include base.php進來使用-->
include_once "../../base.php";

//ajax的請求中會在網址中帶入id參數,利用此id參數,我們可以取得主選單下的所有次選單
$subs=$Menu->all(['main_id'=>$_GET['id']]);

?>
<h3 class="cent">編輯次選單</h3>
<hr>
<!--編輯次選單的api為獨立的一支,不和edit.php共用-->
<form action="./api/submenu.php" method='post' enctype="multipart/form-data">
<table style="width:70%;margin:auto" id="submenu">
<tr>
<td>主選單名稱:</td>
<td>選單連結網址:</td>
<td>刪除</td>
</tr>
<?php
/**
* $subs 有可能是沒有資料的 ,但沒資料就不會印出任何東西,
* 所以這邊就不再特別去判斷$subs是否有值
*/
foreach($subs as $sub){
?>
<tr>
<td><input type="text" name="text[<?=$sub['id'];?>]" value="<?=$sub['text'];?>"></td>
<td><input type="text" name="href[<?=$sub['id'];?>]" value="<?=$sub['href'];?>"></td>
<td><input type="checkbox" name="del[<?=$sub['id'];?>]" value="<?=$sub['id'];?>"></td>
</tr>
<?php }  ?>
</table>
<div class="cent">
<input type="hidden" name="table" value="menu">
<!--將主選單的id加入到隱藏欄位中,
讓後台的api知道這個表單的次選單資料是屬於那個主選單的-->
<input type="hidden" name="main_id" value="<?=$_GET['id'];?>">
<input type="submit" value="修改確認">
<input type="reset" value="重置">
<input type="button" value="更多次選單" onclick="more()">
</div>
</form>
<script>
/**
* 新增次選單的js函式
*/
function more(){
//宣告一個次選單的html字串
let row=`<tr>
<td><input type="text" name="text2[]"></td>
<td><input type="text" name="href2[]"></td>
<td></td>
</tr>`
//使用append()函式將html字串,添加到列表的最後面
$("#submenu").append(row);
}
</script>

在API的部份,我們透過表單中的name屬性命名(text vs text2 ; href vs href2),區分出那些資料是屬於新增的,而那些資料是屬於改和刪的。

建立次選單編輯api
/api/submenu.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
include_once "base.php";

/**
* 判斷$_POST中沒有text這個項目,有的話表示有資料要編輯,
* 沒有的話表示資料表中還沒有資料。
*/
if(isset($_POST['text'])){

/**
* 因為次選單可能有多筆資料,所以使用回圈來一筆一筆處理
* 同時因為我們在設計表單欄位時也把id放到陣列的key中
* 因此使用foreach 可以拆出id和text兩項資訊
* */
foreach($_POST['text'] as $id => $text){

//首先判斷$_POST中沒有del這個項目,有的話表示有資料要刪除
//接著判斷目前迴圈輪到的id有沒有在$_POST['del']中
//有的話表示目這一筆id的次選單是需要刪除的
if(isset($_POST['del']) && in_array($id,$_POST['del'])){
$Menu->del($id);
}else{

//需要編輯的資料先把資料撈出來
$row=$Menu->find($id);

//依序更新name及href資料
$row['name']=$text;
$row['href']=$_POST['href'][$idx];

//存回資料表
$Menu->save($row);
}
}
}

//判斷$_POST中是否有text2這個項目,有的話表示有資料要新增
if(isset($_POST['text2'])){

//新增的資料可能多筆,因此使用迴圈來一筆一筆處理
foreach($_POST['text2'] as $idx => $text){

//判斷$text的內容是否為空值,如果是空值則不新增
if($text!=''){

//將text和對應的href2欄位內容寫入資料表
//預設sh欄位都是1,
//主選單main_id欄位為表單傳送過來的$_POST['main_id']
$Menu->save([
'text'=>$text,
'href'=>$_POST['href2'][$idx],
'sh'=>1,
'main_id'=>$_POST['main_id']
]);
}
}
}

//導回後台的選單管理頁面
to("../backend.php?do=".$_POST['table']);