LoginSignup
6
16

More than 5 years have passed since last update.

見積もり作成フォームのテンプレート

Last updated at Posted at 2017-03-07

業務系アプリケーションを作るときに、いつも面倒なので bootstrap でテンプレートを作っておいた。
丸ごとプラグインにしようというのは無理だったです…。

localhost_2017-03-08_00-03-39.png

index.php
<!DOCTYPE HTML>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>見積もり入力フォームサンプル</title>
        <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
        <style type="text/css">
            body {
                background: #F9F9F9;
            }
            .wrapper {
                width: 100%;
            }
            .content-wrapper {
                width: 100%;
                margin: 0 auto;
            }
            .content {
                width: 75%;
                margin: 0 auto;
            }
            .form-horizontal {
                margin: 2em 3em;
            }
            .form-header {
                margin: 1em 0;
            }
            .form-horizontal table caption {
                color: #FFF;
                background-color: #CCC;
                margin: 2em 0;
                padding: 0.5em 2em;
            }
        </style>
    </head>
    <body>
        <div class="wrapper">
            <div class="content-wrapper">
                <section class="content">
                    <form action="" method="post" class="form-horizontal" class="estimate">

                        <h2 class="form-header">見積作成フォーム</h2>

                        <div class="row">
                            <div class="col-md-8">
                                <div class="form-group">
                                    <label for="client-name" class="col-sm-2 control-label">宛先</label>
                                    <div class="col-sm-10">
                                        <input type="text" name="client_name" class="form-control" id="client-name" placeholder="宛先">
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label for="client-name" class="col-sm-2 control-label">消費税率</label>
                                    <div class="col-sm-5">
                                        <div class="input-group">
                                            <input type="text" name="tax_rate" class="form-control" data-format="number" readonly="readonly" value="8">
                                            <span class="input-group-addon">
                                                <span class="fa fa-percent"></span>
                                            </span>
                                        </div>
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label for="client-name" class="col-sm-2 control-label">計算方法</label>
                                    <div class="col-sm-10">
                                        <div class="radio">
                                            <label>
                                                <input type="radio" name="tax_calc_type" value="1" checked="checked">
                                                明細ごとに税金を算出する
                                            </label>
                                        </div>
                                        <div class="radio">
                                            <label>
                                                <input type="radio" name="tax_calc_type" value="2">
                                                総合計に税金を算出する
                                            </label>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <table class="table">

                            <caption>明細</caption>

                            <col width="40" />
                            <col width="240" />
                            <col width="180" />
                            <col width="" />
                            <col width="" />

                            <thead>
                                <tr>
                                    <th>#</th>
                                    <th>名称</th>
                                    <th>数量</th>
                                    <th>単価</th>
                                    <th></th>
                                </tr>
                            </thead>
                            <tfoot>
                                <tr>
                                    <th>&nbsp;</th>
                                    <th>
                                        <button type="button" class="btn btn-default" id="add_field">フィールドの追加</button>
                                    </th>
                                    <th>&nbsp;</th>
                                    <th>
                                        <div class="input-group">
                                            <span class="input-group-addon" id="basic-addon1">税抜</span>
                                            <input type="text" class="form-control" id="total-ex-tax" readonly="readonly" data-format="number">
                                        </div>
                                    </th>
                                    <th>
                                        <div class="input-group">
                                            <span class="input-group-addon" id="basic-addon1">税込</span>
                                            <input type="text" class="form-control" id="total" readonly="readonly" data-format="number">
                                        </div>
                                    </th>
                                </tr>
                                <tr>
                                    <th colspan="5">
                                        <button class="btn btn-primary">登録</button>
                                    </th>
                                </tr>
                            </tfoot>
                            <tbody>
                            </tbody>
                        </table>
                    </form>
                </section>
            </div>
        </div>
        <script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="jquery.number-format.js"></script>
        <script>
            $(function () {

                /*
                 * 明細を追加する
                 */
                var add_row = function () {

                    // 番号
                    var num = $('tbody > tr').length;
                    if (num >= count_max_forms) {
                        return;
                    }

                    // 単位
                    var unit_arr = ['個', '式'];
                    // 明細各行のHTML構造
                    var html_detail = $('<tr>');
                    html_detail.appendTo('tbody');
                    // 列設定
                    var tds = [];
                    tds[0] = $('<td>').text('#' + (num + 1).toString());
                    // 名称
                    tds[1] = $('<td>');
                    var input_text_itemname = $('<input>')
                            .prop({
                                'type': 'text'
                                , 'name': 'item[]'
                            })
                            .addClass('form-control item')
                            .attr({
                                'placeholder': '名称'
                            })
                            .appendTo(tds[1]);
                    // 数量
                    tds[2] = $('<td>');
                    var input_group_quantity = $('<div>')
                            .addClass('input-group')
                            .appendTo(tds[2]);
                    var input_text_quantity = $('<input>')
                            .prop({
                                'type': 'text'
                                , 'name': 'quantity[]'
                            })
                            .addClass('form-control quantity')
                            .attr({
                                'data-format': 'number'
                            })
                            .appendTo(input_group_quantity);
                    var input_hidden_unit = $('<input>')
                            .prop({
                                'type': 'hidden'
                                , 'name': 'unit[]'
                            })
                            .addClass('unit')
                            .appendTo(input_group_quantity);
                    var div_input_group_btn = $('<div>')
                            .addClass('input-group-btn')
                            .appendTo(input_group_quantity);
                    var button_toggle = $('<button>')
                            .addClass("btn btn-default dropdown-toggle")
                            .attr({
                                'data-toggle': 'dropdown'
                                , 'aria-haspopup': 'true'
                                , 'aria-expanded': 'false'
                            })
                            .append($('<span>').text('個'))
                            .append('&nbsp;')
                            .appendTo(div_input_group_btn);
                    var span_caret = $('<span>')
                            .addClass('caret')
                            .appendTo(button_toggle);
                    var ul_dropdown_menu = $('<ul>')
                            .addClass('dropdown-menu')
                            .appendTo(div_input_group_btn);
                    var li_unit = [];
                    var li_unit_a = [];
                    $.each(unit_arr, function (i, obj) {
                        li_unit[i] = $('<li>')
                                .appendTo(ul_dropdown_menu);
                        li_unit_a[i] = $('<a>')
                                .text(obj)
                                .appendTo(li_unit[i])
                                .on('click', function () {
                                    input_hidden_unit.val(obj);
                                    button_toggle.find('span:first').text(obj);
                                });
                        ;
                        if (i < unit_arr.length - 1) {
                            $('<li>').attr('role', 'separator')
                                    .addClass('divider')
                                    .appendTo(li_unit[i]);
                        }
                    });


                    // 単価
                    tds[3] = $('<td>');
                    var input_group_price = $('<div>')
                            .addClass('input-group')
                            .appendTo(tds[3]);
                    var span_input_group_addon = $('<span>')
                            .addClass('input-group-addon')
                            .append($('<span>').addClass('fa fa-yen'))
                            .appendTo(input_group_price);
                    var input_text_price = $('<input>')
                            .prop({
                                'type': 'text'
                                , 'name': 'price[]'
                            })
                            .attr({
                                'data-format': 'number'
                            })
                            .addClass('form-control price')
                            .appendTo(input_group_price);
                    // 小計
                    tds[4] = $('<td>');
                    var input_group_sum_detail = $('<div>')
                            .addClass('input-group')
                            .append(span_input_group_addon.clone())
                            .appendTo(tds[4]);
                    var input_text_sum_detail = $('<input>')
                            .prop({
                                'type': 'text'
                                , 'name': 'sum_detail[]'
                            })
                            .attr({
                                'data-format': 'number'
                                , 'readonly': true
                            })
                            .addClass('form-control sum_detail')
                            .appendTo(input_group_sum_detail);

                    // td > tr 追加
                    html_detail.append(tds);
                };
                /*
                 * 複数の明細を追加する
                 */
                var add_rows = function (count) {
                    var num = 0;
                    while (num < count && num < count_max_forms) {
                        add_row();
                        num = $('tbody tr').length;
                    }
                    calc_rows();
                };
                // 明細1行の計算
                var calc_row = function (i) {
                    if ($('tbody tr').length === 0) {
                        return 0;
                    }

                    var quantity = $('tbody tr').eq(i).find('.quantity');
                    var q = (quantity.attr('data-value')) ? quantity.attr('data-value') : 0;

                    var price = $('tbody tr').eq(i).find('.price');
                    var p = (price.attr('data-value')) ? price.attr('data-value') : 0;

                    var sum = q * p;
                    return sum;
                };

                var calc_tax = function (num) {
                    return Math.floor(tax_rate * num);
                };

                var calc_rows = function () {
                    var i = 0;
                    var sum = 0;
                    var sum_t = 0;
                    while (i < $('tbody tr').length) {
                        var d = 0;
                        var dt = 0;
                        d = calc_row(i);
                        dt = calc_tax(calc_row(i));
                        if (tax_calc_type.toString() === '1') {
                            d = calc_row(i);
                            dt = calc_tax(calc_row(i));
                        } else if (tax_calc_type.toString() === '2') {
                            d = calc_row(i);
                            dt = calc_tax(calc_row(i));
                        }
                        sum_t += dt;
                        sum += d;
                        $('tbody tr').eq(i).find('.sum_detail')
                                .val(number_format((tax_calc_type.toString() === '1') ? dt : d));
                        i++;
                    }
                    $('#total-ex-tax').val(number_format(sum));
                    $('#total').val(number_format((tax_calc_type === '1') ? calc_tax(sum) : sum_t));
                };

                var number_format = function (num) {
                    var val = num.toString().replace(',', '');
                    var formattedVal = val.replace(/(\d)(?=(?:\d{3}){2,}(?:\.|$))|(\d)(\d{3}(?:\.\d*)?$)/g
                            , '$1$2,$3');
                    return formattedVal;
                };

                // 税率
                var tax_rate = $('[name=tax_rate]').val() / 100 + 1;
                // ロード時に表示する明細フォームの行数
                var count_forms = 4;
                // 明細フォールの最大数
                var count_max_forms = 20;
                // 税金計算方法
                var tax_calc_type = 1;
                // 初期表示
                add_rows(count_forms);
                // フィールド追加
                $('#add_field').on('click', function () {
                    add_row();
                });

                // カンマ区切
                $('[data-format=number]')
                        .numberformat()
                        .on('change', function () {
                            calc_rows();
                        });

                $('[name=tax_calc_type]').on('click', function () {
                    // 税金計算方法
                    tax_calc_type = $(this).val();
                    calc_rows();
                });
        </script>
    </body>
</html>
jquery.number-format.js
/*!
 jquery.number-format.js

 This software is released under the MIT License
 http://opensource.org/licenses/mit-license.php
 */
(function ($) {

    $.fn.numberformat = function (options) {

        // option
        var setting = $.extend({
            align: 'right',
            separator: ','
        }, options);

        // make the string formatted on changed
        this.change(function () {
            var val = $(this).val().toString()
                    .replace(setting.separator, '');
            var formattedVal = val.replace(/(\d)(?=(?:\d{3}){2,}(?:\.|$))|(\d)(\d{3}(?:\.\d*)?$)/g
                    , '$1$2' + setting.separator + '$3');
            $(this).val(formattedVal)
                    .css({
                        textAlign: setting.align
                    })
                    .attr('data-value', val);
        }).change();

        // Move caret to end of string on focused
        this.focus(function () {
            var val = $(this).val();
            $(this).val('').val(val);
        });

        // Remove comma on submit
        this.parents('form').submit(function () {
            var input = $(this).find('input');
            input.each(function () {
                var val = $(this).val().replace(setting.separator, '');
                $(this).val(val);
            });
        });

        return this;
    };
})(jQuery);
6
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
16