【PHP】phpでstrftimeを使って和暦や午前、午後のフォーマットで表示する方法

phpでstrftimeを使って和暦や午前、午後のフォーマットで表示する方法

Linux環境で試したらできた。
(Cライブラリに依存するらしいです。)

setlocale(LC_TIME, "ja_JP.utf8", "Japanese_Japan.932");
print strftime('%EC%Ey年%B%#d日(%A) %OP %I時%M分', strtotime('2015-02-26 11:30:00'));
平成27年2月26日(木曜日) 午前 11時30分

■参考URL

strftimeで和暦表示
http://qiita.com/iwykzm@github/items/e6ff9f735a8ac7998a72

strftime – convert date and time to a string
http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html

【FuelPHP】dompdfで作成するPDFのサイズを小さくしてみる

dompdfで作成するPDFのサイズを小さくしてみる

前回dompdfを使ってHTMLからPDFを生成できるようになったのですが、
どうもPDFにフォントが全て含まれているようでファイルサイズがでかかった。
そこで設定を変更して利用しているフォントだけを含むようにしてみる。

■dompdf_config.custom.inc.php

//define("DOMPDF_ENABLE_FONTSUBSETTING", true);
// ↓
define("DOMPDF_ENABLE_FONTSUBSETTING", true);

上記の設定変更で問題無いはずだけど以下のエラーが発生。

Fatal Error - Class 'Font' not found in /****/fuel/packages/pdf/lib/dompdf/lib/class.pdf.php on line 2352
// Load font
$font_obj = Font::load($fbfile);

上記のFontクラスが読めていない模様。
そもそも前回パスを勝手に変更して設置しているのでその影響かもしれない。
とりあえず該当クラスでFontが読めるように数行追記

■packages/pdf/lib/dompdf/lib/class.pdf.php

require_once "php-font-lib/classes/Autoloader.php";
use FontLib\Font;

実行するとさらに以下のエラーが発生。

Fatal Error - Class 'Font_Binary_Stream' not found in /****/fuel/packages/pdf/lib/dompdf/lib/class.pdf.php on line 2367

php-font-lib/classesの下を見ても「Font_Binary_Stream」は無いので、
名前が似ている「Binary_Stream」を利用するように変更してみる。

■packages/pdf/lib/dompdf/lib/class.pdf.php

require_once "php-font-lib/classes/Autoloader.php";
use FontLib\Font;
use FontLib\Binary_Stream;

■packages/pdf/lib/dompdf/lib/class.pdf.php @2367くらい

//$font_obj->open($tmp_name, Font_Binary_Stream::modeWrite);
//↓
$font_obj->open($tmp_name, Binary_Stream::modeWrite);

実行すると動いた。
元々4.3MBあったPDFが39KBに激減した。

これでいいのかな・・・・?

■参考サイト
DOMPDFでPDFファイルサイズを小さくする
http://madroom-project.blogspot.jp/2012/12/dompdfpdf.html

【FuelPHP】FuelPHPでfuel-pdfを使うまでの道のり

FuelPHPでfuel-pdfを使うまでの道のり

HTMLをPDFとして出力したいのでfuel-pdfをインストールしdompdfを使ってみる。
設定するまでにかなりてこずったのでメモ。

fuel-pdfをoilコマンドでいれるよりも、dompdfをそのまま
インストールしたほうがフォントのインストールとかも考えたら
やりやすいかもしれない。
【FuelPHP】FuelPHPでdompdfを使うまでの道のり

 

■fuel-pdfをインストール

$ php oil package install pdf

■フォルダ名を変更する
「fuel/packages/fuel-pdf」から
「fuel/packages/pdf」に変更

■利用できるようにconfigを変更

編集ファイル:「fuel/app/config/config.php」

	 'always_load'  => array(

		 'packages'  => array(
             'pdf'
		),

		・・・
		),

■とりあえず動かすために適当なコントローラを用意して以下を記述

    public function action_hoge()
    {

        \Package::load('pdf');
        $pdf = \Pdf::factory('dompdf')->init();

        $html ='<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>xxx</title>
<style>
body { font-family: "ipagothic;" }
</style>
</head>
<body>
マルチバイト
</body>
</html>';

        $pdf->load_html($html);
        $pdf->render();
        $pdf->stream("test.pdf");
    }

この状態でPDFがダウンロードできるが????とか文字化けしている状態のはず。

■日本語が表示できるフォントが無いのでIPAフォントをインストールする

まずIPAのサイトにしたがってフォントをサーバにインストールする。

Linuxに対するフォントインストール例
http://ipafont.ipa.go.jp/fontinstall.html

■dompdfを最新のものに変更

まず最初に。。
http://madroom-project.blogspot.jp/2012/11/fuel-pdfhtmlpdf.html
このサイトに沿って

pdf/lib/dompdfと
pdf/lib/dompdf/lib/php-font-lib
を差し替える

■次にdompdf側でIPAフォントをロードする

以下のコマンドでロードを行う模様

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf

しかし失敗

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf
PHP Warning:  require_once(/home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes/Font.php): failed to open stream: No such file or directory in /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/dompdf_config.inc.php on line 332
PHP Fatal error:  require_once(): Failed opening required '/home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes/Font.php' (include_path='.:/usr/share/pear:/usr/share/php') in /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/dompdf_config.inc.php on line 332

「fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes/Font.php」
↑これが無いっていっている

dompdf fails to load
http://stackoverflow.com/questions/15028250/dompdf-fails-to-load

↑このページを参考にして
「php-font-lib/src/FontLib」を「php-font-lib/classes/」として配置する。

$ cd fuel/packages/pdf/lib/dompdf/lib/php-font-lib/src
$ cp -r FontLib ../classes
$ pwd
/home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes
$ ll
合計 68
drwxrwxr-x 8 user user 4096  2月 24 16:49 2015 ./
drwxrwxr-x 7 user user 4096  2月 24 16:49 2015 ../
-rw-rw-r-- 1 user user 5867  2月 24 16:49 2015 Adobe_Font_Metrics.php
-rw-rw-r-- 1 user user  986  2月 24 16:49 2015 Autoloader.php
-rw-rw-r-- 1 user user 8715  2月 24 16:49 2015 Binary_Stream.php
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 EOT/
-rw-rw-r-- 1 user user  836  2月 24 16:49 2015 Encoding_Map.php
-rw-rw-r-- 1 user user 1606  2月 24 16:49 2015 Font.php
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 Glyph/
-rw-rw-r-- 1 user user  725  2月 24 16:49 2015 Header.php
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 OpenType/
drwxrwxr-x 3 user user 4096  2月 24 16:49 2015 Table/
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 TrueType/
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 WOFF/

このようにしてFont.phpがある状態にする

しかしまだ失敗。。

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf
Unable to find bold face file.
Unable to find italic face file.
Unable to find bold_italic face file.
Copying /home/user/.fonts/IPAfont00303/ipagp.ttf to /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp.ttf...
Generating Adobe Font Metrics for /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp...
PHP Fatal error:  Class 'Font' not found in /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/load_font.php on line 139

DOMPDF – Class ‘Font’ not found
http://stackoverflow.com/questions/22226218/dompdf-class-font-not-found

↑このページを参考にload_font.phpを変更

require_once "dompdf_config.inc.php";

↓以下に変更する

require_once "dompdf_config.inc.php";
require_once "lib/php-font-lib/classes/Autoloader.php";
use FontLib\Font;

やっと成功。

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf
Unable to find bold face file.
Unable to find italic face file.
Unable to find bold_italic face file.
Copying /home/user/.fonts/IPAfont00303/ipagp.ttf to /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp.ttf...
Generating Adobe Font Metrics for /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp...

load_font.phpは無事に動いた。

この状態でプログラムを動かすとPDFに日本語が表示された。

■参考サイト

TJS-Technology/fuel-pdf
https://github.com/TJS-Technology/fuel-pdf

FuelPHP の fuel-pdf パッケージを利用し日本語の PDF を生成する
http://qiita.com/hmukaida/items/a960408e736b079390ef

dompdf
https://code.google.com/p/dompdf/wiki/Installation

dompdfで日本語を扱う
http://www.yazin.info/blog/archives/2012/0719_203107.html

FuelPHPのfuel-pdfパッケージをセットアップしてHTMLをPDFにコンバートして出力
http://madroom-project.blogspot.jp/2012/11/fuel-pdfhtmlpdf.html

Unable to locate the ttf2afm / ttf2pt1 executable
http://stackoverflow.com/questions/21675533/unable-to-locate-the-ttf2afm-ttf2pt1-executable

dompdf fails to load
http://stackoverflow.com/questions/15028250/dompdf-fails-to-load

DOMPDF – Class ‘Font’ not found
http://stackoverflow.com/questions/22226218/dompdf-class-font-not-found

dompdf samples
http://pxd.me/dompdf/www/examples.php#encoding_utf-8.html,pdf

CodeIgniterで「Disallowed Key Characters. __utmt_~1」

「Disallowed Key Characters. __utmt_~1」

CodeIgniterで作成したシステムで上記のエラーが
出るようになった。

原因は1ページ内にGoogle Analyticsのタグを複数
記述してしまったことが原因らしい。

タグを1つにして「~」のついているCookieを削除して解決。

ただCookieに入った「__utmt_~1」の「~」の影響で
「Disallowed Key Characters.」が出るのが気持ち悪い。。

Input.phpの「_clean_input_keys」に「~」を追加するやり方を
してる人もいた。

Disallowed Key Characters – Codeigniter urgent
http://stackoverflow.com/questions/26145721/disallowed-key-characters-codeigniter-urgent

Hunting Down the CodeIgniter “Disallowed Key Characters” Error
http://wejn.com/blog/2014/10/hunting-down-the-codeigniter-disallowed-key-characters-error/

AngularJSでng-repeartを使って動的に入力フォームを作成した時のバリデーション

AngularJSでng-repeartを使って動的に入力フォームを作成した時に
requiredなどのバリデーションが上手く動かなかったのでそのときの対処方法。

あと、plunker使ってみました。

■通常のエラーチェックの例
http://plnkr.co/edit/AXxoyf2ZU5ti7WQDXW70?p=preview

問題が起きたケースはinputタグなどをng-repeartを使って
複数作成した場合にでした。
たとえば以下のような記述です。
※実際にはモーダル画面の中でinputタグの動的追加みたいなことをしてました。

<form name="mainForm">
	<div ng-repeat="title in titles">
		<input type="text "name="title{{ $index }}" ng-model="titles[$index]" required />
		<span ng-show="mainForm.title{{ $index }}.$error.required">Title required!</span>
	</div>
</form>

ただ自分の場合はこれだと値を空にしてもエラーメッセージが表示されませんでした。
ググってみると

Dynamic validation and name in a form with AngularJS
http://stackoverflow.com/questions/14378401/dynamic-validation-and-name-in-a-form-with-angularjs

上記のようなページが見つかり、上記ページ中の↓のように「ng-form」を
利用することで正常にエラーが表示されるようになりました。
formタグの入れ子の利用ということかな?
これでわざわざnameを変えなくてもバリデーションがかけられます。

<form name="outerForm">
<div ng-repeat="item in items">
   <ng-form name="innerForm">
      <input type="text" name="foo" ng-model="item.foo" />
      <span ng-show="innerForm.foo.$error.required">required</span>
   </ng-form>
</div>
<input type="submit" ng-disabled="outerForm.$invalid" />
</form>

ng-form

formディレクティブの入れ子のエイリアスです。 HTMLはフォーム要素の入れ子を許可していません。 例えば、コントロールのサブグループのみの検証が必要なケースで、入れ子のフォームは便利です。

■ng-repeatを使ったフォームのエラーチェック例
http://plnkr.co/edit/1cccXO6UmCi4K6it78Zj?p=preview

 

AngularJS読書メモ

AngularJS読書メモ

娘に歯が生え始めました!

ディレクティブとかサービスとかどこに何を書けばいいのかよくわかってないので、
本で学習。

コントローラはスコープをセットアップする関数。
コントローラで$scopeのメソッドを定義する際に複雑な
ロジックを記述してしまうのではなく、プレゼンテーション
ロジックはフィルターやディレクティブに、ビジネスロジック
はサービスに分離して記述し、コントローラはあくまでも
スコープのセットアップ処理だけに徹するのがいい。

プレゼンテーションロジックを実装する:ディレクティブ、フィルター
ビジネスロジックや共通処理を実装する:サービス
これらを繋ぎ合わせる:コントローラ、スコープ
その他:DI、モジュール管理機能

読んだからといって出来てるわけではないです。。

AngularJSでDragAndDropとSortableとModalを組み合わせてみた

AngularJSでDragAndDropとSortableとModalを組み合わせてみた

あけましておめでとうございます。2015年もぼちぼちブログにメモしていきます。

前回に引き続き、AngularJS。

リストの並べ替えとドラッグ&ドロップでの
リスト要素追加、リスト要素の削除とリスト要素の内容変更を
モーダルウィンドウで行うを組み合わせてみました。
あと一応タッチデバイスでも動くように「jQuery UI Touch Punch」
も読み込んでます。

まだAngularJSがよくわかってないので書き方がおかしい
かもしれませんが晒してみます。

わかった範囲でコメントも記載しています。

おかしなところがあったら指摘をお願いします。。

demo

■index.html

<!DOCTYPE html>
<html ng-app="myapp">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>AngularJs drag and drop and sortable sample</title>
	<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.0/css/bootstrap.min.css"/>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
	<script src="jquery.ui.touch-punch.min.js"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js"></script>
	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.min.js"></script>
	<script src="app.js"></script>

</head>
<body ng-controller="myCtrl">
	<div class="container" style="margin-top:20px;">
		<h1>AngularJs drag and drop and sortable sample.</h1>

		<div class="row">

			<div class="col-md-4">
				<div class="panel panel-default">
					<div class="panel-heading">
						drag要素
					</div>
					<div class="list-group" ng-model="items">
						<div my-draggable="#sortable" class="list-group-item" ng-repeat="item in items">{{item.title}}</div>
					</div>
				</div>
			</div>

			<div class="col-md-8">
				<div class="panel panel-default">
					<div class="panel-heading">
						sortable要素
					</div>
					<div class="list-group" ng-model="blocks" my-sortable id="sortable">

						<div class="list-group-item" ng-repeat="block in blocks">
							<div>■{{block.title}}</div>
							<button class="btn btn-primary sortable-handle" >並び替え</button>
							<button class="btn btn-success" my-modal-edit>編集</button>
							<button class="btn btn-danger" my-modal-delete>削除</button>
						</div>

					</div>
				</div>
			</div>

		</div>

		<!-- デバッグ用エリア -->
		<div class="row">
			<div class="col-md-4">
				<pre>
					{{items | json }}
				</pre>
			</div>
			<div class="col-md-8">
				<pre>
					{{blocks | json }}
				</pre>
			</div>
		</div>

	</div>

   <!-- Modal for edit -->
    <script type="text/ng-template" id="T_editForm">
        <div class="modal-header">
            <button type="button" class="close" ng-click="$dismiss()">&times;</button>
            <h3>要素編集モーダル</h3>
        </div>
        <div class="modal-body">
            <form role="form">
                <div class="form-group">
                    <label>title</label>
                    <input ng-model="editData.title" type="text" class="form-control" placeholder="タイトル" />
                </div>
            </form>
        	<div ng-show="error">
        		{{error}}
        	</div>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-success" my-update>編集</button>
        </div>
    </script><!-- Modal for edit-->

   <!-- Modal for delete -->
    <script type="text/ng-template" id="T_deleteForm">
        <div class="modal-header">
            <button type="button" class="close" ng-click="$dismiss()">&times;</button>
            <h3>要素削除モーダル</h3>
        </div>
        <div class="modal-body">
        	<div>
        		タイトル:{{block.title}}を削除します。
        	</div>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-success" ng-click="$close()">削除する</button>
        </div>
    </script><!-- Modal for delete-->

</body>
</html>

■app.js

var app = angular.module('myapp', ['ui.bootstrap']);

app.controller('myCtrl', function($scope, $modal) {
    // drag元データ
    $scope.items = [
    {'title' : 'テキストA'},
    {'title' : 'テキストB'},
    {'title' : 'テキストC'},
    {'title' : 'テキストD'},
    {'title' : 'テキストE'},
    {'title' : 'テキストF'},
    {'title' : 'テキストG'},
    {'title' : 'テキストH'},
    {'title' : 'テキストI'},
    ];

    // sortable対象データ -> 初回は本来はサーバから取得する
    $scope.blocks = [
    {'title' : 'デフォルトA'},
    {'title' : 'デフォルトB'},
    {'title' : 'デフォルトC'},
    {'title' : 'デフォルトD'},
    {'title' : 'デフォルトE'},
    {'title' : 'デフォルトF'},
    {'title' : 'デフォルトG'},
    {'title' : 'デフォルトH'},
    {'title' : 'デフォルトI'},
    {'title' : 'デフォルトJ'},
    ];

    // 編修のモーダルインスタンスを保持する用
    $scope.editModalInstance = null;

    // sort処理
    // $on -> $emitや$broadcastで送信したイベントを受け取るメソッド
    $scope.$on('my-sorted',function(event,val){
      $scope.blocks.splice(val.to, 0, $scope.blocks.splice(val.from, 1)[0]);
    })

    // drag処理
    $scope.$on('my-created',function(event,val){
      $scope.blocks.splice(val.to, 0,{title:'#'+($scope.blocks.length+1)+': '+val.title});
    })

    // delete処理
    $scope.$on('my-delete',function(event,val){
      $scope.blocks.splice(val, 1);
    })

    // blockの更新
    $scope.$on('my-update',function(event,val){
      $scope.blocks.splice(val.index, 1, val.data); // 差し替え
    })

  });

// sortableのディレクティブ
app.directive('mySortable',function(){
  return {
    // scope -> scope,
    // el -> ディレクティブが適用された箇所の要素,
    // attrs -> ディレクティブが適用された要素の属性
    link:function(scope,el,attrs){
      // jQuery UI sortableのオプション
      // http://www.jqref.net/ui/interactions/sortable.php
      el.sortable({
        revert: true,
        axis: 'y',
        cancel: "", // 指定しない -> 参考: http://kamegu.hateblo.jp/entry/jquery-ui/sortable-handle
        handle: ".sortable-handle"
      });
      el.disableSelection();

      // deactivate は、アイテムがドラッグ終了した時に呼び出されます。
      // event - イベントオブジェクト
      // ui - ui オブジェクト
      //    item - ドラッグ開始したアイテムの jQuery オブジェクト
      el.on( "sortdeactivate", function( event, ui ) {
        // scope -> 要素に結び付いている$scopeを取得する dragされてきた場合は$indexはundefined
        var from = angular.element(ui.item).scope().$index;
        //console.log('from -> ' + from);

        // jQueryオブジェクト内で、引数で指定されたエレメントのインデックス番号を返す。インデックスは、ゼロから始まる連番。
        // もし渡されたエレメントがjQueryオブジェクト内に存在しない場合、戻り値には-1が返る。
        var to = el.children().index(ui.item);
        //console.log('to -> ' + to);

        if(to>=0){
          // $apply -> AngularJS管理外のイベントハンドラの中で$applyメソッドを実行すると、強制的に実行できる。
          scope.$apply(function(){
            if(from>=0){
              // fromがあるからソート処理  $emit -> 派生元のスコープに対してイベントを送信するメソッド
              scope.$emit('my-sorted', {from:from,to:to}); // イベント呼び出し
            }else{
              // fromが無いから追加処理
              scope.$emit('my-created', {to:to, title:ui.item.text()}); // イベント呼び出し
              ui.item.remove();
            }
          })
        }
      } );
    }
  }
})

// draggableのディレクティブ
app.directive('myDraggable',function(){
  return {
    link:function(scope,el,attrs){
      // jQuery UI draggableのオプション
      // http://www.jqref.net/ui/interactions/draggable.php
      el.draggable({
        connectToSortable: attrs.myDraggable, // connectToSortable を指定すると、sortable にコネクト(項目を追加)することができます。
        helper: "clone",
        revert: "invalid"
    });
    el.disableSelection(); // jQuery UI マッチした要素集合のテキスト選択を無効にします。
    }
  }
})

// 削除のモーダルを開くディレクティブ
app.directive('myModalDelete', function($modal){
  return {
    scope: false, // falseを指定すると、そのディレクティブを利用している箇所のスコープがディレクティブのスコープとして扱える
    link:function(scope,el,attr){
      el.on("click", function( event ){
        scope.$apply(function(){
          var modalInstance = $modal.open({
            templateUrl: "T_deleteForm",
            scope: scope // 呼び出されたときのスコープをそのまま渡しているのでテンプレート側でblockが使える
          });

          // modalInstanceからのコールバックを受ける
          modalInstance.result.then(function() {
            //console.log("モーダル側でcloseが呼ばれた!");
            scope.$emit('my-delete', scope.$index);
          }, function() {
            //console.log("モーダル側でdismissが呼ばれた!");
          });
        })
      });
    }
  }
})

// 編集のモーダルを開くディレクティブ
app.directive('myModalEdit', function($modal){
  return {
    scope: false, // falseを指定すると、そのディレクティブを利用している箇所のスコープがディレクティブのスコープとして扱える
    link:function(scope,el,attr){
      el.on("click", function( event ){
        scope.$apply(function(){
          scope.editData = angular.copy(scope.block); // リアルタイムに編集してしまわないようにコピーする

          // 外部の操作で閉じられるようにモーダルのインスタンスを親スコープに保存しておく
          scope.$parent.editModalInstance = $modal.open({
            templateUrl: "T_editForm",
            scope: scope // 呼び出されたときのスコープをそのまま渡しているのでテンプレート側でblockが使える
          });

          // modalInstanceからのコールバックを受ける
          scope.editModalInstance.result.then(function() {
            //console.log("モーダル側でcloseが呼ばれた!");
          }, function() {
            //console.log("モーダル側でdismissが呼ばれた!");
          });
        })
      });
    }
  }
})

// 編集でデータの更新
app.directive('myUpdate', function(){
  return {
    scope: false, // falseを指定すると、そのディレクティブを利用している箇所のスコープがディレクティブのスコープとして扱える
    link:function(scope,el,attr){
      el.on("click", function( event ){
        scope.$apply(function(){

          // エラーチェック -> サービスに切り出すほうがいいのかも。
          if(!scope.editData.title){
            scope.error = 'タイトルは必須です。';
            return;
          }

          // データの更新
          scope.$emit('my-update', {index:scope.$index, data:scope.editData});
          scope.editData = null; // 念の為消しておく

          // モーダル閉じる
          scope.editModalInstance.close();
        })
      });
    }
  }
})

参考サイト

■Drag object into sortable list – AngularJS
http://stackoverflow.com/questions/18835619/drag-object-into-sortable-list-angularjs
⇒回答者のデモ
http://plnkr.co/edit/aSOlqR0UwBOXgpQSFKOH?p=preview

■Angular.js入門 (5)ディレクティブ その2
http://qiita.com/_rdtr/items/590ccb7be16dc8ed9be3

■AngularJS 製アプリで jQuery を使いたい
http://dev.classmethod.jp/client-side/javascript/angularjsandjquery/

■積極的に利用したい AngularJS グローバル API
http://dev.classmethod.jp/client-side/javascript/angularjsglobalapis/

■AngularJSではじめるHTML5開発 – Part8 モーダルダイアログによる新規レコード作成フォーム
http://www.nkjmkzk.net/?p=5401

■AngularJSでBootstrapのModalを出す方法メモ
http://otiai10.hatenablog.com/entry/2014/10/30/000537

■AngularJSで HTML5的なアラートウィンドウを表示する
http://www.walbrix.com/jp/blog/2014-01-angularjs-simplemodal.html

■jQuery UI Touch Punch
https://github.com/furf/jquery-ui-touch-punch

■AngularJSで、動的に入力項目数を設定する
http://diaryruru.blog.fc2.com/blog-entry-64.html

AngularJSでsortableのサンプル

AngularJSでsortableのサンプル

最近ちょっとAngularJsを触りだしました。

まだ本家のチュートリアルドットインストール
やったくらいのレベル。

今後業務でsortableなリストとか作る
必要がありそうなので調査。

どうも「AngularUI」を使ってみるとイイっぽい。

■AngularUI
http://angular-ui.github.io/

以下のサイトでも紹介されています。

■AngularUIってどんなもの?
http://knightso.hateblo.jp/entry/2014/04/02/182924

「AngularUI」内の「UI-Modules」にある「ui-sortable」を利用して
作成してみます。

「ui-sortable」の使い方は以下。
angular-ui/ui-sortable
https://github.com/angular-ui/ui-sortable

で、実際にsortableなものを作ってみたのがこちら。

DEMO

一応ソース

<html ng-app="myApp">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>AngularJs sortable sample</title>
	<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.0/css/bootstrap.min.css"></link>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.1.3/angular.min.js"></script>
	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"></script>
	<script>
		var app = angular.module('myApp', ['ui']);

		app.controller('myCtrl', function($scope) {

		// サンプルデータ
		$scope.items = [
		{'title' : 'aaaaa'},
		{'title' : 'bbbbb'},
		{'title' : 'ccccc'},
		{'title' : 'ddddd'},
		{'title' : 'eeeee'},
		{'title' : 'fffff'},
		{'title' : 'ggggg'},
		{'title' : 'hhhhh'},
		{'title' : 'iiiii'},
		];

		// jQueryUIのsortableのオプションが使える。
		$scope.sortableOptions = {
			axis: 'y'
		};

	});
	</script>
</head>
<body ng-controller="myCtrl">
	<div class="container" style="margin-top:20px;">
		<h1>AngularJs sortable sample.</h1>
		<div class="row">
			<div class="col-md-4">

				<div class="panel panel-default">
					<div class="panel-heading">
						↓並び替え
					</div>
					<div class="list-group" ui-sortable="sortableOptions" ng-model="items">
						<a class="list-group-item" href="#" ng-repeat="item in items">{{item.title}}</a>
					</div>
				</div>

			</div>
			<div class="col-md-8">
				<h3>↓データの状態</h3>
				<pre>{{items|json}}</pre>
			</div>
		</div>
	</div>
</body>
</html>

すっきりしてていい感じ。


ベビーバスチェア購入

IMG_4834_2

最近完全二重になった娘ちゃんです。

最近自分の帰りが遅いのでお嫁さんが頑張ってひとりで
お風呂に入れてくれているのですが、待ってる間に娘ちゃん
が号泣するということで、一緒に入れるバスチェアを購入しました。

お風呂広いわけではないので折りたためるのがいいですね。

実際に使ってみたところ大人しく待っててくれるみたいです。
そろそろ寒くなってきたので頻繁にお湯をかけてあげる必要はありますが、
外で号泣されるよりも断然安心みたいです。

本人も気にいってるようです。

IMG_0957_2

DDDリポジトリメモ

DDDリポジトリメモ

いつになってもDDDがしっくりはまらない。。
調べなおしたところをメモ。
リポジトリについて。

集約内部にあるどのオブジェクトもルートから
辿る以外の方法でアクセスすることは禁止されている。

トランザクションの管理はリポジトリが手を出さないほうが単純になる。
■リポジトリとファクトリの関係

ファクトリはオブジェクトのライフサイクルに
おける始まりを処理し、リポジトリは中期から
終わりを管理するのを助ける。

格納されたオブジェクトを再構成することは
新しい概念オブジェクトを生成することとは違う。

ファクトリ

新しいもの

リポジトリ

永続化したもの

リポジトリは既存のオブジェクトを再構築
するにあたってファクトリを使用する。

探してなければ生成する機能は実装してはいけない。
少し便利になるだけ。両者を透過的に組み合わせると
状況を混乱させてしまう。
新しいのか永続化されているのかははっきりわかったほうが都合が良い。