神社 地域 にデジタルを

❝地図とグラフで見る豊中市データ❞のコーディング

2023年06月03日 | 最終更新日:2023年09月06日 | コーディング |
Django4 python3.10 javascript wsl bootstrap folium geopandas shell_plus pandas plotly

大阪府のデータを用いたMap・Graphのコーディングと内容は相似しています。

ただし、豊中市内の町丁レベルで区分けし、その単位で7年間のデータを取り込むため、大阪府のデータよりもはるかに多量を要します。

前段階がかなり多く、豊中市が公表しているデータ、大阪府の公表データ・大阪府警の公表データから、豊中市部位の町丁データを取り出すなどが必要。

豊中市の場合は、蛍池の蛍が螢であったりと表記ゆれの対応が必要で、住所が漢数字だったりアラビア数字だったりしたため、統一させる加工が必要でした。

町丁レベルで合わせても、データが欠落している場合もあります。

町丁レベルの画面の切り替え表示には、Getパラメータを用いJavascriptで実装しました。

セレクトボックスへの町丁データの投入は、views.py側から受け取る形を取っています。

動きは遅いですが、ほぼ想定通りに動きます。概要を記します。

<更新:2023-9-6>

以下の記述でも動きますが、動作が遅いため実際には修正しています。

まず地図の読み込みが遅いため、foliumで処理完了状態のhtmlを出力し、このhtmlをダイレクトに描画する形に変更しました。出力後のhtmlに微修正を施しています。
map.save(xxx.html)でhtmlファイルが出力されます。

グラフの描画遅いため、plotlyのjsの読み方を工夫しました。

views.pyで、fig.to_html(include_plotlyjs=False)としてjsの読み込みをFalseにし
template側でcdnでplotlyのjsを読み込みます。

体感ですが、早くなりました。


事前準備(手順の概略)

<Poetryで仮想環境を準備(例)>事前にPoetryをインストールしておく

仮想環境をフォルダ直下にする

poetry config virtualenvs.in-project true
~$ mkdir o_poetry_dj
~$ cd o_poetry_dj/
~/o_poetry_dj$ poetry init

以下の設問にEnter、yes、noを入力

This command will guide you through creating your pyproject.toml config.
Package name [o_poetry_dj]:※Enterキー
Version [0.1.0]:※Enterキー
Description []:※Enterキー
Author [user , n to skip]:※Enterキー
License []:※Enterキー
Compatible Python versions [^3.10]:※Enterキー
Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file
[tool.poetry]
name = "o_poetry_dj"
version = "0.1.0"
description = ""
authors = ["user "]
[tool.poetry.dependencies]
python = "^3.10"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
Do you confirm generation? (yes/no) [yes] yes
poetry shell

<venvの場合(例)>※venvがインストールされていることを確認

python3 -m venv app_toyonaka_data
source app_o_ytdl/bin/activate

以後、仮想環境で作業

必要なパッケージをインストール

<poetryの場合>

(仮想名) poetry add folium geopandas pandas plotly...

<pipの場合>

(仮想名) pip install folium geopandas pandas plotly...

加えて

shell_plusがつかえるようにする ※Djangoのshellでモデルの操作をするときなど、sehllが格段に使いやすくなります。

(仮想名) poetry add django-extensions ...or...
(仮想名) pip install django-extensions

使い方

(仮想名) python manage.py shell_plus

以上


Djangoプロジェクトにアプリを作成

python manage.py startapp toyonaka_data

スーパーユーザーを作成

python manage.py createsuperuser

settings.py(config/settings.py)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    "toyonaka_data",    
    ...省略...

    # 3th party
   'django_extensions',

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / "templates"],
        ...省略...

STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / "static"]

MEDIA_URL = 'media/'
MEDIA_ROOT = BASE_DIR / 'media'

プロジェクトフォルダのsettings.pyに記述


urls.py(config/urls.py)

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [ path('admin/', admin.site.urls), path("toyonaka_data/", include("toyonaka_data.urls")), ...省略... if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

プロジェクトフォルダのurls.pyに記述


フォルダ構成

toyonaka_data/
    ├── admin.py
    ├── apps.py
    ├── __init__.py
    ├── management/
    ├── migrations/
    ├── models.py
    ├── __pycache__/
    ├── tests.py
    ├── urls.py
    └── views.py

managementフォルダにcommandsフォルダを作り、load_toyonaka_data.pyとload_toyonaka_generation.pyを配置します。

├── management/
│   └── commands/
│       ├── load_toyonaka_data.py
│       ├── load_toyonaka_generation.py

models.py

from django.db import models


class ToyonakaBase(models.Model):
    area = models.CharField(max_length=100)
    population = models.IntegerField()
    setai = models.IntegerField()
    setai_per = models.FloatField()
    crime = models.FloatField(null=True, blank=True)
    elevation = models.FloatField()
    
    def __str__(self):
        return "{} - {}".format(self.aria, self.population)


class ToyonakaGeneration(models.Model):
    area = models.CharField(max_length=100)
    age = models.CharField(max_length=30)
    male = models.IntegerField()
    female = models.IntegerField()
    total = models.IntegerField()
    year = models.CharField(max_length=30)
    age_range = models.CharField(max_length=30)
    market_range = models.CharField(max_length=30)
    
    def __str__(self):
        return str(self.pk)

models.pyには、前処理したデータのカラム(列名)に合わせたモデルを設計します。


toyonaka_data/management/commands/load_toyonaka_data.py

modelにデータを投入するための独自コマンドを2つ作る

import csv
from django.conf import settings
from django.core.management.base import BaseCommand
from toyonaka_data.models import ToyonakaBase


class Command(BaseCommand):
    # データを更新する場合は削除して挿入し直す
    # if ToyonakaBase.objects.count() > 0:
    #     ToyonakaBase.objects.all().delete()
    
    help = "豊中市の基礎データをモデルに投入"
    
    def handle(self, *args, **kwargs):
        data_file = settings.BASE_DIR / "data" / "last_data2.csv"
        keys = (
            "area", "population", "setai", "setai/per", "crime", "elevation"
        )
        
        records = []
        with open(data_file, "r") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                records.append({k: row[k] for k in keys})
                
        for record in records:
            
            ToyonakaBase.objects.get_or_create(
                area=record["area"],
                population=record["population"],
                setai=record["setai"],
                setai_per=record["setai/per"],
                crime=record["crime"],
                elevation=record["elevation"]
            )

toyonaka_data/management/commands/load_toyonaka_generation.py


import csv
from django.conf import settings
from django.core.management.base import BaseCommand
from toyonaka_data.models import ToyonakaGeneration


class Command(BaseCommand):
    #データを更新刷る場合は削除して挿入し直す
    if ToyonakaGeneration.objects.count() > 0:
        ToyonakaGeneration.objects.all().delete()
    
    help = "豊中市の年齢別人口の推移データをモデルに投入"
    
    def handle(self, *args, **kwargs):
        data_file = settings.BASE_DIR / "data" / "h27tor3_toyonaka_bese.csv"
        keys = (
            "area", "age", "male", "female", "total", "year",
            "age_range", "market_range"
        )
        
        records = []
        with open(data_file, "r") as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                records.append({k: row[k] for k in keys})
                
        for record in records:
            
            ToyonakaGeneration.objects.get_or_create(
                area=record["area"],
                age=record["age"],
                male=record["male"],
                female=record["female"],
                total=record["total"],
                year=record["year"],
                age_range=record["age_range"],
                market_range=record["market_range"]
            )
(仮想名) python manage.py load_toyonaka_generation または load_toyonaka_data
  • コマンドを使ってDBモデルに投入します。
  • shell_plusで投入できたか確認

urls.py

from django.urls import path
from .views import(
    toyonaka_map_index, toyonaka_map_setai,
    toyonaka_map_hinan, toyonaka_map_crime,
    toyona_age_range, toyona_market_range,
)


app_name = "toyonaka_data"


urlpatterns = [
    path("", toyonaka_map_index, name="main"),
    path("setai/", toyonaka_map_setai, name="setai"),
    path("ele_hinan/", toyonaka_map_hinan, name="ele_hinan"),
    path("crime/", toyonaka_map_crime, name="crime"),
    
    path("g_main/", toyona_age_range, name="g_main"),
    path("g_market/", toyona_market_range, name="g_market"),
]

地図とグラフを表示させるためのurlを設定します。


views.py


from django.shortcuts import render
import folium
import geopandas as gpd
import pandas as pd

import plotly.express as px
import plotly.graph_objects as go

from .models import ToyonakaBase, ToyonakaGeneration
from django.conf import settings

from folium.features import CustomIcon


icon_path = settings.BASE_DIR / "data" / 'jija_marker.png'

icon = CustomIcon(
    icon_image = str(icon_path)
    ,icon_size = (25, 25)
    ,icon_anchor = (30, 30)
    ,popup_anchor = (3, 3)
)


def toyonaka_map_index(request):
    data = ToyonakaBase.objects.all().values()
    df = pd.DataFrame(data)
    
    geo_data = settings.BASE_DIR / "data" / "toyonaka_geo2.json"
    geo_df = gpd.read_file(geo_data)
    geo_df = geo_df[["S_NAME", "geometry", "Y_CODE", "X_CODE"]]
    
    last_df = pd.merge(geo_df, df, how="left", left_on="S_NAME", right_on="area")
    last_df["pref"] = [x for x in range(1, 338)]
    
    # print(last_df)
    # print(last_df.columns)    

    last_df = last_df[["pref", "area", "geometry", "population", "setai", "setai_per", "crime",
                   "elevation", "Y_CODE", "X_CODE"]]
    
    last_df_plot = last_df.copy()
    last_df_plot["pref"] = last_df["pref"].astype(str) 
    
    ### Map 処理 ###
    last_df_plot.crs = "epsg:4326"
    
    toyonaka_pop = folium.Map(
    location=["34.7812", "135.4697"],
    tiles="cartodbpositron",
    zoom_start=13,
    )

    folium.Choropleth(
        geo_data=last_df_plot,
        data=last_df_plot,
        columns=["pref", "population"],
        key_on="feature.properties.pref",
        name="令和3年 豊中市の人口分布",
        fill_color="RdPu",
        fill_opacity=0.5,
        line_opacity=0.2,
        legend_name="令和3年 豊中市の人口分布",
        # bins=bins,
        reset=True,
    ).add_to(toyonaka_pop)

    style_function = lambda x: {
        "fillColor": "#ffffff",
        "color": "#000000",
        "fillOpacity": 0.1,
        "weight": 0.1
    }

    highlight_function = lambda x: {
        "fillColor": "#000000",
        "color": "#000000",
        "fillOpacity": 0.50,
        "weight": 0.1
    }

    NIL = folium.features.GeoJson(
        last_df_plot,
        style_function=style_function,
        control=False,
        highlight_function=highlight_function,
        tooltip=folium.features.GeoJsonTooltip(
            fields=["area", "population"],
            aliases=["町名 : ", "人口(人) : "],
            style=("background-color: white; color: #333333; font-family: arial; font-size: 12px; padding: 10px")
        )
    )

    toyonaka_pop.add_child(NIL)

    folium.Marker(location=[34.76967354061533, 135.48738845413897], 
                tooltip="当 若宮 住吉神社", icon=icon).add_to(toyonaka_pop)
    # folium.Marker(location=[34.76967354061533, 135.48738845413897], 
    #             tooltip="若宮 住吉神社").add_to(toyonaka_pop)
    

    context = {
        "map": toyonaka_pop._repr_html_(),
        
    }
    
    return render(request, "toyonaka_data/main.html", context)


def toyonaka_map_setai(request):
    data = ToyonakaBase.objects.all().values()
    df = ...
        上のコードとほぼ同じ "setai_per"をキーにする
    ...
    
    return render(request, "toyonaka_data/setai.html", context)


def toyonaka_map_hinan(request):
    ### 避難場所のデータ ###
    hinan_path = settings.BASE_DIR / "data" / "2021_toyonaka_hinan.csv"
    df_hinan = pd.read_csv(hinan_path)
    df_hinan = df_hinan[["名称", "住所", "緯度", "経度", "災害種別_洪水", "災害種別_津波", "想定収容人数"]]
    
    df_hinan_flood = df_hinan[df_hinan["災害種別_洪水"]==1]
    df_hinan_tsunami = df_hinan[df_hinan["災害種別_津波"]==1]
    ### end ###
    
    data = ToyonakaBase.objects.all().values()
    df = ...
        上のコードとほぼ同じ "elevation"をキーに
    ...

    folium.Marker(location=[34.76967354061533, 135.48738845413897], 
                tooltip="若宮 住吉神社", icon=icon).add_to(toyonaka_ele)

    ... 省略 ...
    
    return render(request, "toyonaka_data/ele_hinan.html", context)


def toyonaka_map_crime(request):
    
    data = ToyonakaBase.objects.all().values()
    df = ...
        上のコードとほぼ同じ "crime"をキーに
    ...
    
    return render(request, "toyonaka_data/crime.html", context)

### Graph setting ###
color_list = ["#073472", "#DAB021", "#B9D4E8", "#25232F", "#BF7356"]
colname_list = ["幼年人口-0~14歳", "高年齢人口-65歳以上", "生産年齢人口-15~64歳"]

colname_male = ["M1層-男性20~34歳", "M2層-男性35~49歳", "M3層-男性50~64歳"]
colname_female = ["F1層-女性20~34歳", "F2層-女性35~49歳", "F3層-女性50~64歳"]
### end ###


def toyona_age_range(request):
    
    data = ToyonakaGeneration.objects.all().values()
    s_area = ToyonakaGeneration.objects.all().values_list("area", flat=True).order_by("area").distinct()
    
    chose_area = request.GET.get("area")
    if chose_area:
        chose_area=chose_area
    else:
        chose_area="若竹町1丁目"
    print(chose_area)
    
    df = pd.DataFrame(data)
    
    df_s = df[df["area"]==chose_area].groupby(["area", "year", "age_range"])["total"].sum().unstack()
    df_s = df_s.reset_index()    
    
    fig = go.Figure()

    t_text = df_s["area"][0]

    for i, col in enumerate(df_s.columns[2:]):
        fig.add_trace(go.Bar(
            y=df_s["year"], x=df_s[col],
            marker_color=color_list[i],
            name=colname_list[i]
        ))
        

    fig.update_traces(width=0.5,
                    hovertemplate="%{x}人",
                    texttemplate="%{x}人",
                    textposition="inside",
                    textfont={"color": "white",
                                "size": 12},
                    orientation="h")

    fig.update_layout(title=f"<b>{t_text}人口構成の推移",
                    legend=dict(orientation="h",
                                xanchor="right",
                                x=1,
                                yanchor="bottom",
                                y=1.05,
                                traceorder="normal"),
                    yaxis=dict(title='平成27年~令和3年',
                             tickformat='年',
                             ),
                    xaxis=dict(title='単位:人',
                              tickformat='人',
                             ),
                    barmode="stack",
                    plot_bgcolor="white",
                    height=700)
    
    html = fig.to_html()
    
    context = {"chart": html, "area": s_area}
    
    return render(request, "toyonaka_data/g_main.html", context)


def toyona_market_range(request):
    
    data = ToyonakaGeneration.objects.all().values()
    s_area = ToyonakaGeneration.objects.all().values_list("area", flat=True).order_by("area").distinct()
    
    chose_area = request.GET.get("area")
    if chose_area:
        chose_area=chose_area
    else:
        chose_area="若竹町1丁目"
    print(chose_area)
    
    df = pd.DataFrame(data)
    
    df_cm = df[df["area"]==chose_area].groupby(["area", "year", "market_range"])["male"].sum().unstack()
    df_cm = df_cm.reset_index()
    
    df_cf = df[df["area"]==chose_area].groupby(["area", "year", "market_range"])["female"].sum().unstack()
    df_cf = df_cf.reset_index()
    
    fig = go.Figure()

    t_text = df_cf["area"][0]

    for i, col in enumerate(df_cm.columns[2:5]):
        fig.add_trace(go.Scatter(
            x=df_cm["year"], y=df_cm[col],
            mode='markers+lines',
            marker=dict(
                size=13,
                symbol='star',
            ),
            name=colname_male[i],
            line=dict(color=color_list[i]),
            opacity=0.8
        ))
        
    for i, col in enumerate(df_cf.columns[2:5]):
        fig.add_trace(go.Scatter(
            x=df_cf["year"], y=df_cf[col],
            mode='markers+lines',
            marker=dict(
                size=13,
                symbol='square',
            ),
            name=colname_female[i],
            line=dict(color=color_list[i]),
            opacity=0.8
        ))

    fig.update_layout(
        title=f"<b>{t_text}の世代人口の推移",
        # legend=dict(
        #     x=0.01,
        #     y=0.99,
        #     xanchor='left',
        #     yanchor='top',
        #     orientation='h'
        # ),
        xaxis=dict(title='平成27年~令和3年',
                             tickformat='年',
                             ),
        yaxis=dict(title='単位:人',
                    tickformat='人',
                    ),
        height=700
    )
    
    html = fig.to_html()
    
    context = {"chart": html, "area": s_area}
    
    return render(request, "toyonaka_data/g_market.html", context)

views.pyは地図、グラフともにコードを記述するため、長いコードになりました。

  • valuesでpandasのdataframeとして読み込みます。27行目
  • geopandasで境界データを読み込みます。30行目
  • 豊中市の中心をlocationに指定してマップを作成。50行目以降
  • 161行目以降はグラフ表示の記述。Getパラメータで受け取り、項目に応じた表示に切り分けます。

templates/base.html

※雛形のイメージhtmlです 用途に合わせて手直してください


{% load static %}
<!doctype html>
<html lanh=ja>
    <head>
        <!-- Require meta tags -->
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0", shrink-to-fit=none>
        
        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        
        <!-- custom css & js -->
        <link rel="stylesheet" href="{% static 'style.css' %}">
        <script src="{% static 'main.js' %}" defer></script>
        
        
        <title>Spiner | {% block title %}{% endblock title %}</title>
    </head>
    <body>
        <div class="container mt-3">
            {% block content %}
            {% endblock content %}
        </div>
        <!-- Optional Javascript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS-->
        <script
        src="https://code.jquery.com/jquery-3.6.3.min.js"
        integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU="
        crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
    </body>
</html>

templates/toyonaka_data/main.html

base.htmlを継承した表示用のhtmlを作成します。

{% extends 'base.html' %}

{% block title %}地図で見る豊中市のデータ - 人口 -{% endblock title %}

{% block contents %}
    <div class="row">
        <div class="col">
            <h3 class="mb-3">地図で見る豊中市のデータ - 人口 -</h3>

            <div class="dropdown dropdown-on-hover d-inline-block">
                <button class="btn btn-dark dropdown-toggle" id="dropdownMenuHoverButton" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">豊中市の地図データを選択</button>
                <div class="dropdown-menu dropdown-menu-right py-0" aria-labelledby="dropdownMenuHoverButton">
                  <a class="dropdown-item" href="{% url 'toyonaka_data:main' %}">令和3年 豊中市の人口の分布:人</a>
                  <a class="dropdown-item" href="{% url 'toyonaka_data:setai' %}">令和2年 豊中市の一世帯の人数:人</a>
                  <a class="dropdown-item" href="{% url 'toyonaka_data:ele_hinan' %}">豊中市の町丁の標準地の標高と避難所(令和4年更新場所)</a>
                  <a class="dropdown-item" href="{% url 'toyonaka_data:crime' %}">令和3年 豊中市の盗難犯罪の発生の分布</a>
                </div>
              </div>

              <h4 class="text-center">令和3年 豊中市の人口の分布:人</h4>

            {{ map|safe }}

            <p><small>豊中市の境界のデータ<br>
              「e-Stat」<br>
              https://www.e-stat.go.jp/gis/statmap-search?page=2&type=2&aggregateUnitForBoundary=A&toukeiCode=00200521&toukeiYear=2015&serveyId=A002005212015&prefCode=27&coordsys=1&format=shape</small></p>
            <p><small>年齢別人口【町丁目別】<br>
            「豊中市」<br>
            https://www.city.toyonaka.osaka.jp/joho/toukei_joho/jinkou_toukei/nenreibetsujinko/index.html</small></p>
        </div>
    </div>
{% endblock contents %}

ほぼ同じ内容で、以下のテンプレートを用意します。

  • templates/toyonaka_data/crime.html
  • templates/toyonaka_data/ele_hinan.html
  • templates/toyonaka_data/setai.html

templates/area_data/bar_65over.html

棒グラフ表示用のhtmlを作成します。

{% extends 'base.html' %}
{% load static %}

{% block title %}グラフで見る豊中市のデータ - 年代構成 -{% endblock title %}


{% block contents %}
    <div class="row">
        <div class="col">
            
            <h3 class="mb-3">グラフで見る豊中市のデータ - 年代構成 -</h3>

            <form nethod="GET" action="{% url 'toyonaka_data:g_main' %}" name="area-form">

                <div class="select-box">
                    <div class="select-option">
                        <input type="text" placeholder="市内の町丁を選択" id="soValue" name="area">
                    </div>
                    <div class="content">
                        <div class="search">
                            <input type="text" id="optionSearch" placeholder="Search" name="">
                        </div>
                        <ul class="options">
                            
                            {% for item in area %}
                                <li>{{ item }}</li>
                            {% endfor %}
                        </ul>                   
                    </div>
                </div>

                <button type="submit" class="btn btn-primary mt-2 mb-3">グラフ表示</button> 
            </form>           

            {{ chart|safe }}
            <p><small>年齢別人口【町丁目別】<br>
                「豊中市」<br>
                https://www.city.toyonaka.osaka.jp/joho/toukei_joho/jinkou_toukei/nenreibetsujinko/index.html</small></p>
    
        </div>
    </div>
{% endblock contents %}

{% block end_scripts %}

    <script src={% static 'js/selected.js' %}></script>
    
{% endblock end_scripts %}

ほぼ同じ内容で、以下のテンプレートを用意します。

  • templates/toyonaka_data/g_market.html

static/js/selected.js

セレクトボックスと検索のためのjavascriptを記述します

const selectBox = document.querySelector(".select-box");
const selectOption = document.querySelector(".select-option");
const soValue = document.querySelector("#soValue");
const optionSearch = document.querySelector("#optionSearch");
const options = document.querySelector(".options")
const optionsList = document.querySelectorAll(".options li");

selectOption.addEventListener("click", function(){
    selectBox.classList.toggle("active");
})

optionsList.forEach(function(optionListSingle){
    optionListSingle.addEventListener("click", function(){
        text = this.textContent;
        soValue.value = text;
        selectBox.classList.remove("active");
    })
});

optionSearch.addEventListener("keyup", function(){
    var filter, li, i, textValue;
    filter = optionSearch.value;
    li = options.getElementsByTagName("li");
    for(i=0; i<li.length; i++){
        liCount = li[i];
        textValue = liCount.textContent || liCount.innerText;
        if(textValue.indexOf(filter) > -1){
            li[i].style.display = "";
        }else{
            li[i].style.display = "none";
        }
    }
})
私の願い

私は神社の宮司です。神社や地域を担う次世代の人々に対し、何かを残してお役に立ててもらいたいとの願いが、強く芽生えました。個業としての神社や、小規模な地域社会に、恩恵が届くのが遅くなりそうな「デジタル」の分野。門外漢として奮闘した実体験から得た経験則を、わずかずつでも残し未来につなぎたいと願うばかりです。

More

若宮 住吉神社

サイトへ

最近の投稿

Copyright ©All rights reserved | by omo fun

Made withby Toshio Omote