機能拡張v.1
前章までは、見た目だけで機能はない。 本章では、簡単な検索機能を実装する。
サンプルコードは、こちら。
フラグメント - team-search-box -
team_search/serve.js
const express = require('express')
const app = express()
app.set("view engine", "ejs")
const port = process.env.PORT || 6000;
app.get('/search-box', (req, res) => {
const defualtQuery = {k: ''}
const query = Object.assign(defualtQuery, req.query);
res.render('./search-box.ejs', query);
})
app.listen(port, () => {
console.log(`Team Search app listening at http://localhost:${port}`)
})
team_search/views/search-box.ejs
<style>
.team-search-box-button {
border: none;
background-color: inherit;
}
.team-search-box-input {
width: 50%;
}
</style>
<form method="GET" action="./">
<input name="k" value="<%= k %>" placeholder="Please enter keywords ..." class="team-search-box-input"></input><button class="team-search-box-button" type="submit">🔍</button>
</form>
form
を使い、button
にtype="submit"
と書くことで、サーバーへ検索キーワードを送信するようにする。
組成
team_composite/serve.js
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.set("view engine", "ejs");
const port = process.env.PORT || 2000;
const inspireHost = process.env.INSPIRE_HOST || 'localhost:4000';
const productHost = process.env.PRODUCT_HOST || 'localhost:5000';
const searchHost = process.env.SEARCH_HOST || 'localhost:6000';
const items = ['apple', 'banana', 'grapes', 'mango', 'orange'];
const filterItems = (arr, query) => {
return arr.filter(el => el.toLowerCase().indexOf(query.toLowerCase()) !== -1)
};
app.get('/', async (req, res) => {
queryParams = req.query;
keyword = queryParams['k'];
let localItems = items;
if (keyword !== undefined) {
localItems = filterItems(items, keyword);
}
urlQueryParams = Object.keys(queryParams).map(key => key + '=' + queryParams[key]).join('&');
const inspireList = await (await fetch(`http://${inspireHost}/inspire-list?i=${localItems.join(',')}`)).text();
const inspireLabel = await (await fetch(`http://${inspireHost}/inspire-label`)).text();
const productList = await (await fetch(`http://${productHost}/product-list?i=${localItems.join(',')}`)).text();
const searchBox = await (await fetch(`http://${searchHost}/search-box?${urlQueryParams}`)).text();
res.render("./index.ejs", {
inspireList: inspireList,
inspireLabel: inspireLabel,
productList: productList,
searchBox: searchBox
});
});
app.listen(port, () => {
console.log(`Team Composite app listening at http://localhost:${port}`)
});
検索キーワードをクエリパラメータk
に格納される。
k
から商品(items
)をフィルタリングし、その結果をproductList
とinspireList
へURLのクエリパラメータ(i
)として渡す。
フラグメント - team-product-list -
team_product/serve.js
const express = require('express')
const app = express()
app.set("view engine", "ejs")
const port = process.env.PORT || 5000;
app.get('/product-list', (req, res) => {
const defualtQuery = {items: []}
let query = defualtQuery;
query['items'] = req.query['i'].split(',').filter((e) => e !== '');
res.render('./product-list.ejs', query)
})
app.listen(port, () => {
console.log(`Team Product app listening at http://localhost:${port}`)
})
URLのクエリパラメータi
より、商品のリストを表示する。
team_product/views/product-list.ejs
<style>
.team-product-item {
border: medium solid;
display: inline-block;
text-align: center;
padding: 20px 0;
width: 100%;
margin: 10px 0;
}
</style>
<% for (let item of items) { %>
<%- include("./product-item.ejs", {item: item}) %>
<% } %>
フラグメント - team-inspire-list -
team_inspire/serve.js
const express = require('express')
const app = express()
app.set("view engine", "ejs")
const port = process.env.PORT || 4000;
const recommendItems = {
apple: ['apple pie'],
banana: ['banana juice'],
grapes: ['grape mousse'],
mango: ['mango ice'],
orange: ['orange cake']
}
app.get('/inspire-list', (req, res) => {
const defualtQuery = {items: []}
let query = defualtQuery;
const productItems = req.query['i'].split(',').filter((e) => e !== '');
const localRecommendItems = productItems.map((item) => recommendItems[item]).flat();
query['items'] = localRecommendItems;
res.render('./inspire-list.ejs', query);
})
app.get('/inspire-label', (req, res) => {
res.render('./inspire-label.ejs');
})
app.listen(port, () => {
console.log(`Team Inspire app listening at http://localhost:${port}`)
})
URLのクエリパラメータi
より、お勧めする商品を探索し、それを表示する。
team_inspire/views/inspire-list.ejs
<style>
.team-inspire-item {
border: medium solid;
display: block;
text-align: center;
padding: 20px 0;
border-radius: 50%;
margin: 10px 0;
}
</style>
<% for (let item of items) { %>
<%- include("./inspire-item.ejs", {item: item}) %>
<% } %>
結果
その結果、次のような画面が表示される。