サンプル
想定イメージは、下記の前回記事でタスクを登録してユーザーに紐づくタスクを一覧化する機能について紹介します。
ディレクトリ構造
MY-FIRST-BEEGO-PROJECT
├─ conf
│ └─ app.conf
├─ controllers
│ └─ default.go
├─ crypt
│ └─ crypt.go
├─ models
│ └─ todo.go
├─ routers
│ └─ router.go
└─ static
├─ css
├─ img
├─ js
│ ├─ form.js
│ ├─ login.js
│ ├─ reload.min.js
│ ├─ todoCreate.js
│ ├─ todoCard.js
│ └─ todoList.js
├─ lib
│ └─ bootstrap
│ ├─ css
│ │ ├─ bootstrap-grid.min.css
│ │ └─ bootstrap.min.css
│ ├─ js
│ │ ├─ bootstrap-bundle.min.js
│ │ └─ bootstrap.min.js
│ ├─ jquery
│ │ └─ jquery.js
│ └─ upload
├─ views
│ ├─ mytodo
│ │ ├─ addTodo.tpl
│ │ └─ myList.tpl
│ ├─ index.tpl
│ ├─ subIndex.tpl
│ └─ thirdIndex.tpl
└─ main.go
フロント側のコード
views/subIndex.tpl
<!DOCTYPE>
<html>
<head>
<title>Todoリスト</title>
<!--共通-->
<link rel="stylesheet" type="text/css" href="/static/lib/bootstrap/css/bootstrap.min.css"/>
<script type="text/javascript" src="/static/lib/jquery/jquery.js"></script>
<!--個別-->
<script type="text/javascript" src="/static/js/todoList.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<button id="backToTopPage" class="btn btn-primary">
トップページへ
</button>
<div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<button id="myTaskCreate" class="btn btn-primary">
タスク登録
</button>
</li>
<li class="nav-item">
<button id="logout" class="btn btn-secondary">
ログアウト
</button>
</li>
</ul>
</div>
</div>
</nav>
<div>
<input type="hidden" id="userId" name="userId" value=""/>
</div>
<div id="cardTodo" class="grid gap-3" style="display:flex"></div>
</body>
</html>
今回は、Cardコンポーネントにしてみます。
static/js/todoList.js
$(document).ready(function(){
//Session StorageからユーザIDを取得する
const userId = sessionStorage.getItem("userId");
let inputValueInUserId = document.getElementById("userId");
inputValueInUserId.value = userId;
//トップページに戻るボタンをクリックしたときの処理
$('#backToTopPage').on('click',function(){
});
//タスク登録ボタンをクリックし時の処理
$('#myTaskCreate').on('click',function(){
location.replace('/mytodo/addTodo'); //location.replace('myTodo/addTodo');
});
//ログアウトボタンをクリックしたときの処理
$('#logout').on('click',function(){
sessionStorage.removeItem('user');
location.replace('/');
});
$.ajax({
url:`/controllers/sub/getTasks?userid=${userId}`,// /controllers/sub
method:'GET',
success:function(response){
console.log(response);
const cardComponent = document.getElementById("cardTodo");
//タスクデータがある場合、ループして表示する
if(response.length > 0){
for(let i=0;i<response.length;i++){
const task = response[i];
cardComponent.innerHTML += `
<div class="card" style="width: 10rem">
<img src="${task.TaskImage}" class="card-img-top" alt=" style="height:50px"${task.TaskName}"/>
<div class="card-body">
<h5 class="card-title">${task.TaskName}</h5>
<p class="card-text">${task.TaskDescription}</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
`;
}
}else{
cardComponent.innerHTML = `
<p>登録済みのデータはありません。</p>
<div>
<button id="backToTopPage" class="btn btn-secondary">
トップに戻る<br/>
<small>Back To TopPage</small>
</button>
</div>
`;
}
},
error:function(response){
alert('データを取得できませんでした。');
const cardComponent = document.getElementById("cardTodo");
cardComponent.innerHTML = `
<div>
<button id="backToTopPage" class="btn btn-secondary">
トップに戻る
<br/>
<small>
Back To TopPage
</small>
</button>
</div>`;
}
});
});
サーバ側のコード
routers/router.go
package routers
import (
"my-first-beego-project/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
//追加
beego.Router("/sub", &controllers.SubController{}) //beego.Router("/sub", &controllers.SubController{})
beego.Router("/:id", &controllers.ThirdController{})
beego.Router("/controllers/user", &controllers.UserController{})
beego.Router("/login", &controllers.LoginController{})
beego.Router("/controllers/login", &controllers.LoginController{})
beego.Router("/mytodo/addTodo", &controllers.TodoCreateController{})
beego.Router("/controllers/todoAdd", &controllers.TodoAddController{})
// GetTasksアクションのためのルーティング追加
beego.Router("/controllers/sub/getTasks", &controllers.SubController{}, "get:GetTasks")
}
レンダリングするためのコントローラ
まずは、subIndex.tpl
をレンダリング表示するコントローラの修正です。
controllers/default.go
// 20250205追加
type SubController struct {
beego.Controller
}
// 20250205
func (c *SubController) Get() {
//クエリパラメータでユーザIDを取得する
userId, err := c.GetInt("userid")
//仮のコード
//userId = 1
fmt.Println("取得したリクエストパラメータuseridは、", userId)
if err != nil {
beego.Error("リクエストパラメータ 'userid' がありません。リクエストURL:", c.Ctx.Request.URL.String())
c.Ctx.ResponseWriter.WriteHeader(400)
c.Ctx.WriteString("ユーザIDが指定されていません。")
return
}
//ORMを使ってユーザIDに紐づくタスクを取得する
o := orm.NewOrm()
var tasks []models.Task
_, err = o.QueryTable("task").Filter("register", userId).All(&tasks)
if err != nil {
c.Ctx.ResponseWriter.WriteHeader(500)
c.Ctx.WriteString("タスクデータの取得に失敗しました。")
return
}
fmt.Println("データベースから取得したtasksは", tasks)
//タスクをJSONで返す
//c.Data["json"] = tasks
c.Data["Page"] = "SubPage"
c.TplName = "subIndex.tpl"
//c.ServeJSON()
}
JSONデータを返却するコントローラの作成
つぎに、JSONデータを返却するコントローラを作成します。
JavaScript でタスクデータを取得して動的にTodoリストを表示する方法
テンプレート内でタスク情報を表示する場合、tasks
データをレンダリングして表示できます。
しかし、もしAJAX
を使って動的にタスク情報を取得したい場合は、コントローラを分けて、GET メソッドではページをレンダリングし、AJAXリクエストでJSONを返すようにします。
なので、GetTasks
メソッドを追加して、AJAX
リクエストを使ってタスクデータを取得できるようにします。
controllers/default.go
func (c *SubController) GetTasks() {
// ユーザIDを取得
userId, err := c.GetInt("userid")
fmt.Println("GetTasksのユーザIDは、", userId)
if err != nil {
beego.Error("リクエストパラメータ 'userid' がありません。")
c.Ctx.ResponseWriter.WriteHeader(400)
c.Ctx.WriteString("ユーザIDが指定されていません。")
return
}
// ORMを使ってタスクを取得
o := orm.NewOrm()
var tasks []models.Task
_, err = o.QueryTable("task").Filter("register", userId).All(&tasks)
if err != nil {
c.Ctx.ResponseWriter.WriteHeader(500)
c.Ctx.WriteString("タスクデータの取得に失敗しました。")
return
}
// タスクデータをJSON形式で返す
c.Data["json"] = tasks
c.ServeJSON()
}
以上です。