JSFiddle - React, Tailwind, and code Playground

by tanakaworld

HTML

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

<h1>SearchBoxLikeGithub</h1>

<div ng-controller="SearchBoxController as vm">

    <div>
        <span class="search-group">
            <span class="scope-badge" ng-if="vm.filter != '$'">
                {{vm.filterLabel[vm.filter]}}
                <i class="fa fa-times fs5 pointer" ng-click="vm.switchFilter('$')"></i>
            </span>

            <input type="text" ng-init="vm.filter = '$'" ng-model="vm.keyword[vm.filter]" placeholder="Keyword"/>
        </span>
    </div>

    <div>
        <span>Filter List: </span>
        <span ng-repeat="(k, v) in vm.filterLabel" ng-click="vm.switchFilter(k)" class="pointer">[{{v}}]</span>
    </div>

    <p>
        検索ヒット数 : <span class="vm.searchResultCount hit">{{(vm.users | filter:vm.keyword).length}}</span>
        件 / <span class="vm.searchResultCount">{{vm.users.length}}</span> 件中
    </p>

    <table class="data-table">
        <thead>
        <tr>
            <th>ID</th>
            <th>氏名</th>
            <th>フリガナ</th>
            <th>備考</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="user in vm.users | filter:vm.keyword">
            <td>{{user.id}}</td>
            <td>{{user.name}}</td>
            <td>{{user.kana}}</td>
            <td>{{user.note}}</td>
        </tr>
        </tbody>
    </table>
    <p>
        <small>※ サンプルデータは、
            <a href="http://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%A7%E3%82%B8%E3%83%A7%E3%81%AE%E5%A5%87%E5%A6%99%E3%81%AA%E5%86%92%E9%99%BA">
                ジョジョの奇妙な冒険
            </a> から拝借しました
        </small>
    </p>
</div>

CSS

body {
    background-color: whitesmoke;
}

table, td, th {
    text-align: left;
    border: 1px solid;
}

th {
    background-color: darkgray;
}

td {
    background-color: lightgray;
}

.pointer {
    cursor: pointer;
}

.search-group {
    position: relative;
}

.search-group > .scope-badge {
    position: absolute;
    padding: 5px 5px;
    margin: 2px 3px;
    font-size: 8px;
    color: #777;
    background-color: #eee;
    display: inline-block;
    border-radius: 2px;
    vertical-align: middle;
}

.search-group > input {
    width: 300px;
    height: 27px;
    box-sizing: border-box;
}

JavaScript

function SearchBoxService() {
}

SearchBoxService.prototype.getData = function () {
    return [
        {
            id: 1,
            name: "空条承太郎",
            kana: "クウジョウジョウタロウ",
            note: "オラオラ"
        },
        {
            id: 2,
            name: "東方仗助",
            kana: "ヒガシカタジョウスケ",
            note: "変な髪型"
        },
        {
            id: 3,
            name: "荒木飛呂彦",
            kana: "アラキヒロヒコ",
            note: "歳を取らない"
        },
        {
            id: 4,
            name: "虹村億泰",
            kana: "ニジムラオクヤス",
            note: "東方仗助が岸辺露伴を困らせた時わたしは焼身自殺します"
        },
        {
            id: 5,
            name: "岸辺露伴",
            kana: "キシベロハン",
            note: "岸部露伴は動かない"
        },
        {
            id: 6,
            name: "広瀬康一",
            kana: "ヒロセコウイチ",
            note: "エコーズ"
        }
    ];
};

function SearchBoxController($timeout, searchBoxService) {
    var self = this;

    self.$timeout = $timeout;
    self.users = searchBoxService.getData();

    self.keyword = {
        id: '',
        name: '',
        kana: '',
        note: '',
        $: ''
    };

    self.filterLabel = {
        id: 'ID',
        name: '氏名',
        kana: 'フリガナ',
        note: '備考',
        $: 'ALL'
    };
}

SearchBoxController.prototype.switchFilter = function (target) {
    this.filter = target;
    for (var k in self.keyword) {
        this.keyword[k] = '';
    }

    this.$timeout(function () {
        var badge = $(".search-group .scope-badge");
        var badgeWidth = 0;

        if (badge.width() != null) {
            badgeWidth = badge.width() + 15;
        }
        $(".search-group > input").css('padding-left', badgeWidth + "px");
    }, 15);
};


angular.module("SearchBoxLikeGithubApp", [])
    .service("searchBoxService", SearchBoxService)
    .controller("SearchBoxController", SearchBoxController);