InfyOm Laravel Generator でカスタムフィールドを追加する

InfyOm Laravel Generator を使っているときに、
設定できるフィールドを増やしてみた。

事前に、以下のコマンドを実行しておくこと。
これを実行しておくと、各フィールドのテンプレートがresources 配下にコピーされる。

```  
php artisan infyom.publish:templates
```

css, js を読み込むように設定しておく

./resources/views/layouts/app.blade.php

cssが記載されている箇所の下に追記

```
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<link href="//cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.4/build/jquery.datetimepicker.min.css" rel="stylesheet">
<link rel="stylesheet" href="/css/colorbox.css">

```

jsが記載されている箇所の下に追記

```
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<script src="/js/jquery.datetimepicker.full.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery.colorbox/1.6.4/jquery.colorbox-min.js"></script>
<script type="text/javascript" src="/packages/barryvdh/elfinder/js/standalonepopup.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/4.6.2/tinymce.min.js"></script>
<script src="/js/common.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $(":input").inputmask();

    datepickerSetup();
    datetimepickerSetup();

    // 住所検索ボタン　クリック時
    $("#prefSearch").click(function()
    {
        prefSearch();
    });

    tinymce.init({
        selector : "textarea.wysiwyg",
        //language : 'ja',
        language_url : '/js/tinymce_langs/ja.js',
        plugins  : ["autolink searchreplace textcolor textpattern colorpicker table paste image imagetools legacyoutput contextmenu lists charmap code codesample link media anchor hr preview tabfocus template visualblocks"],
        toolbar  : "undo redo | styleselect | bold italic forecolor backcolor | table | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | code",
        table_grid: true,
        table_appearance_options: true,
        table_toolbar: "tableprops tabledelete | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol",
        paste_data_images: true,
        paste_as_text: false,
        paste_remove_styles_if_webkit: false,
        forced_root_block: '',
        relative_urls: false,
        templates: [],
        file_browser_callback : elFinderBrowser
    });
});
</script>
```

./public/js/common.js はこんな感じで記載

```
function elFinderBrowser (field_name, url, type, win) {
  tinymce.activeEditor.windowManager.open({
    file: '/elfinder/tinymce4',
    title: 'elFinder 2.0',
    width: 900,
    height: 450,
    resizable: 'yes'
  }, {
    setUrl: function (url) {
      win.document.getElementById(field_name).value = url;
    }
  });
  return false;
}

$(function($){
  $.datepicker.regional['ja'] = {
    closeText: '閉じる',
    prevText: '&#x3C;前',
    nextText: '次&#x3E;',
    currentText: '今日',
    monthNames: ['1月','2月','3月','4月','5月','6月',
    '7月','8月','9月','10月','11月','12月'],
    monthNamesShort: ['1月','2月','3月','4月','5月','6月',
    '7月','8月','9月','10月','11月','12月'],
    dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
    dayNamesShort: ['日','月','火','水','木','金','土'],
    dayNamesMin: ['日','月','火','水','木','金','土'],
    weekHeader: '週',
    dateFormat: 'yy/mm/dd',
    firstDay: 0,
    isRTL: false,
    showMonthAfterYear: true,
    yearSuffix: '年'};
  $.datepicker.setDefaults($.datepicker.regional['ja']);
});

function datepickerSetup(){

	$('.datepick')
	.datepicker({
		dateFormat: 'yy/mm/dd',
		showOn: 'focus',
		minDate:'-80',
		maxDate:'30',
		changeMonth: true,
		changeYear: true,
		constrainInput: true,
		numberOfMonths: 3,
		onSelect: function(){
			$(this).removeClass('placeholder');
			if( $(this).val().length < 1){
				$(this).val($(this).attr('placeholder'));
				$(this).attr('used', 'false')
				$(this).addClass('placeholder');
			}else{
				$(this).attr('used', 'true')
			}
		}
	});
}

function datetimepickerSetup(){

	$('.datetimepick')
	.datetimepicker({
		timepicker:true,
		format:'Y/m/d H:i',
		minDate:'-1970/01/01',
		maxDate:'+1970/01/08',
		defaultTime:'10:00',
		validateOnBlur: false,
		allowTimes:[
		    '08:00', '09:00', '10:00', '11:00', '12:00',
		    '13:00', '14:00', '15:00', '16:00', '17:00',
		    '18:00', '19:00', '20:00', '21:00', '22:00',
		],
		onSelect: function(){
			$(this).removeClass('placeholder');
			if( $(this).val().length < 1){
				$(this).val($(this).attr('placeholder'));
				$(this).attr('used', 'false')
				$(this).addClass('placeholder');
			}else{
				$(this).attr('used', 'true')
			}
		}
	});
}

function prefSearch(){

    var req = '';
    req += $('#zipcode').val();

    $.ajax({
        url: "/pref",
        data: {req:req},
        cache: false,
        success: function(html){
            $this.spinner('remove');
            if (null != html.addr1 && null != html.addr2){
                $("#pref").val(html.pref).trigger("change");
                $("#addr01").val(html.addr1 + html.addr2).removeClass("placeholder").attr("used","true");
                $("#addr01").css("color","#000");
            }
        }
    });
}
```

### カレンダーアイコン付きの日付フィールド

datetimepick のクラス属性をdatepick に変えたら時刻指定は非表示になる

```
vi ./resources/infyom/infyom-generator-templates/scaffold/fields/date.stub

<!-- $FIELD_NAME_TITLE$ Field -->
<div class="form-group col-sm-6 @if($errors->has('$FIELD_NAME$')) has-error @endif">
    {!! Form::label('$FIELD_NAME$', __('$FIELD_NAME_TITLE$').':') !!}
    <div class="input-group date">
        <div class="input-group-addon">
            <i class="fa fa-calendar"></i>
        </div>
        {!! Form::text('$FIELD_NAME$', null, ['class' => 'form-control  pull-right datetimepick']) !!}
    </div>
    {!! $errors->first('$FIELD_NAME$', '<span class="help-block">:message</span>') !!}
</div>

```


### 隠しフィールド

```
vi ./resources/infyom/infyom-generator-templates/scaffold/fields/hidden.stub


<!-- $FIELD_NAME_TITLE$ Field -->
{!! Form::hidden('$FIELD_NAME$', $input['$FIELD_NAME$']) !!}
```

### elFinder を使ったファイル選択フィールド

```
vi ./resources/infyom/infyom-generator-templates/scaffold/fields/file.stub

<!-- $FIELD_NAME_TITLE$ Field -->
<div class="form-group col-sm-6 @if($errors->has('image')) has-error @endif">
    {!! Form::label('$FIELD_NAME$', '$FIELD_NAME_TITLE$:') !!}
    <div class="input-group">
        {!! Form::text('$FIELD_NAME$', null, ['class' => 'form-control', 'for' => '$FIELD_NAME$']) !!}
        <span class="input-group-btn">
            <button type="button" class="btn btn-info btn-flat popup_selector" data-inputid="$FIELD_NAME$">{!! __('Browse') !!}</button>
        </span>
    </div>
    {!! $errors->first('$FIELD_NAME$', '<span class="help-block">:message</span>') !!}
</div>
```

### 郵便番号フィールド（住所検索ボタン付き）

data-inputmask を変更すれば、携帯電話などの対応もできる

```
vi ./resources/infyom/infyom-generator-templates/scaffold/fields/zipcode.stub

<!-- $FIELD_NAME_TITLE$ Field -->
<div class="form-group col-sm-6 @if($errors->has('$FIELD_NAME$')) has-error @endif">
    {!! Form::label('$FIELD_NAME$', __('$FIELD_NAME_TITLE$').':') !!}

	<div clss="input-group">
        <div class="col-xs-8" style="padding-left:0;">
            {!! Form::text('$FIELD_NAME$', null, ['class' => 'form-control', 'data-inputmask' => "'mask': '999-9999'"]) !!}
        </div>
        <div class="col-xs-4">
            <span class="input-group-btn" style="padding-left:0px;">
                 <button type="button" class="btn btn-info btn-flat" id="prefSearch">{!! __('prefSearch') !!}</button>
            </span>
        </div>
    </div>
</div>
```

### チェックボックスフィールド

チェックボックスは、１つしか作成できない仕様。
マルチにしたい場合は、複数作成して、テンプレートでまとめる感じ。
当然、DBカラムはチェックボックス分出来上がる。

元ファイルからの変更点は、label部分にfield_nameとvalueを繋げて表示するようにしたこと。
翻訳ファイルをかますことで、自由にラベルを設定できるので、便利かと。

```
vi ./resources/infyom/infyom-generator-templates/scaffold/fields/checkbox.stub

<!-- $FIELD_NAME_TITLE$ Field -->
<div class="form-group col-sm-6 @if($errors->has('$FIELD_NAME$')) has-error @endif">
    {!! Form::label('$FIELD_NAME$', __('$FIELD_NAME_TITLE$').':') !!}
    <label class="checkbox-inline">
        {!! Form::hidden('$FIELD_NAME$', false) !!}
        {!! Form::checkbox('$FIELD_NAME$', '$CHECKBOX_VALUE$', null) !!} {!! __('$FIELD_NAME$$CHECKBOX_VALUE$') !!}
    </label>
    {!! $errors->first('$FIELD_NAME$', '<span class="help-block">:message</span>') !!}
</div>
```

zipcode.stubなどは、新規ファイルなので、
最後にHTMLFieldGenerator の１３行目あたりに、タイプを追加する。

```
vi ./vendor/infyomlabs//laravel-generator/src/Utils/HTMLFieldGenerator.php

        switch ($field->htmlType) {
            case 'text':
            case 'textarea':
            case 'date':
            case 'file':
            case 'email':
            case 'password':
            case 'zipcode':
                $fieldTemplate = get_template('scaffold.fields.'.$field->htmlType, $templateType);
                break;
```