投稿日:

アウトオブ眼中

ボタンをクリックしたら隠しdivの中のフォームをコピーして、
通し番号を発行して表に追加する、みたいな処理をよく書きます。
通し番号の入る場所は仮にダミー文字列(今回はQQQQ)を置いておいて、ボタンが押されたときの処理でまとめて書き換える感じです

何度か書いているうちにdata-属性に行番号を持たせることで、:lastから現在の最大行番号を把握し、
次の行番号を探る、なんてことをやるようになりました。
隠しフィールドよりずいぶんすっきり見えます。attrで持たせると文字列で保存されるので、取得時に0を引いて数値に解釈しなおすことをお忘れなく。 …【1】
追加するときだけじゃなくて削除にも役立ちます。$(“tr[data-no=’行番号’]”,”#fueruTable”).remove() で行ごと削れます。

ところで、これはこれで面倒なことが一つあって、これを実際submitしたとき。

QQQQはダミーフィールドなので使わないはずだし、何よりdataに関してforeachとか回すなんてことになると邪魔。
サーバー側にunset($_POST[‘data’][‘QQQQ’])を噛ませて長いことやってました。

ある時、formの閉じタグ位置を間違えて、隠しフィールドをformの外に追いやってしまったんです。
それでsubmitしたらどうなったかというと

QQQQがいない。
これはこれで何か問題がある気もするけれど、ただテンプレートとして置いておきたいだけで、そもそもsubmitする気のないフィールドは
そもそもform内に置かなければよかった!

考えてみれば当たり前のことなのに、長いこと気づかなかったのでついブログに書き出してしまいました。
submitしないフォームはformタグの外、アウトオブ眼中!他の事例でも使えたら使うつもりでいます。

投稿日:

就職していた期間の合計を取得する方法

2000/01/08から2005/05/31まで就労
2006/01/08から2010/05/31まで就労
2011/01/08から現在も就労
の全就労日数を求める方法を紹介します。

データ構造サンプル
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(40) NOT NULL ,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=1 ;
CREATE TABLE works (
id INT NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL ,
start_date DATE NOT NULL ,
retire_date DATE NULL DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=1 ;

データの情報としては、
users.id:1,users.name:奥進太郎
works.id:1,works.user_id:1,works.start_date:2000/01/08,works.retire_date:2005/05/31
works.id:1,works.user_id:1,works.start_date:2006/01/08,works.retire_date:2010/05/31
works.id:1,works.user_id:1,works.start_date:2011/01/08,works.retire_date:null

1回毎の就労日数を求めるVIEWを作成します。
CREATE VIEW work_diffs AS
select works.user_id AS user_id,
(case when isnull(works.retire_date) then (to_days(curdate()) – to_days(works.start_date))
else (to_days(works.retire_date) – to_days(works.start_date)) end end) AS work_diff
from `works`;

上記VIEWをgroup byで合計すると、全就労日数が取得できます。
CREATE VIEW work_sum_diffs as
select work_diffs.user_id as user_id,sum(work_diffs.work_diff) as sum_work_diff
from work_diffs group by work_diffs.user_id;

usersとwork_diffsをJOINすれば、users毎の全就労日数を取得することができます。

投稿日:

jQueryカラーピッカーspectrum.jsの使用方法

案件にて、色を扱いたいといった事があって、サクッと色を選べるプラグインが無いかなと探してみた所、spectrum.jsというイイ感じのプラグインが見つかりましたので、ご紹介したいと思います。

spectrum.js

DEMO

使用方法

このプラグインはjQueryに依存しますので、jQueryを先に読み込ませます。
そして、使用したいhtmlにspectrum.jsとspectrum.cssを読み込みます。
jquery.spectrum-ja.jsは日本語対応です。必要である場合は使用します。





inputにクラス名を付けておきます。


bodyタグの最後にscriptにてspectrumを呼び出します。
パレットに予め色を用意しておきたい場合は、paletteプロパティに配列で色を#RRGGBB形式で入力しておきます。

	jQuery(function($){
		$(".picker").spectrum({
			color: "#f00", //初期色
			showPalette: true, // パレット表示あり
			palette: [ // パレットで使う色を指定
				["#f00", "#0f0", "#00f", "#ff0", "#f0f", "#0ff"]
			]
		});
	});

IE11でsubmitしても値が反映されなかった時の対応

IE11を使用してシステムにsubmitした際、データが飛ばないので探ってみると、カラーピッカーを使用した後にinputのvalueに#RRGGBBの形で値が設定されていませんでした。

spectrumに用意されている`change`イベントでinputを#RRGGBB値に書き換えるようにしてやれば解決しました。

    jQuery(function($){
        $(".picker").spectrum({
			color: "#CF85A1", //初期色
			showPalette: true, // パレット表示あり
			palette: [ // パレットで使う色を指定
				["#CF85A1", "#CCD58D", "#94DAC0", "#A49CDF", "#ACA4E4"]
			],
            change: function(color) {
                $(this).val(color.toHexString());
            }
        });
    });

簡単な設定で細かい色指定ができるので、これは重宝しそうです。

投稿日:

引越します

注:ブログ移転記事ではありません

4月後半となると、新生活に伴う引越もひと段落して、生活が軌道に乗った頃かと思います。
奥進システムでも、引越を進めています。
SVNからGitの引越で、事務所が物理的に動いているわけではないですけどね。

SVNからGitに乗り換えるにあたって、やることを調べていて、
最初こそおっかなびっくりやってたんですが、今となれば手順がはっきりしてきたので、
簡易版ではあるけれど、引越の為にやったことを今回のブログに書こうかと。

一応準備:
・Git Bashでプロジェクト展開先に入っておく
・他のGit操作がなんか面倒ならSourceTreeなど見繕っておく

1:Git Bash上、git-svnでSVNリポジトリをGitリポジトリに転換して抽出

git svn clone -s svn+ssh://[プロジェクトのアドレス]

SVNで使ってたtrunkが取り出される感じです。
もし最終リビジョンだけでいいなら -r HEAD をアドレスの前に付ければよし。

2:SVNに関する設定を抹消する

ここは色々と試していました。なんとかSVNと縁を切る方法はないかと。
SourceTreeから毎回「SVNブランチ作る?」と作れもしないのに聞かれるのにウンザリしていたものですから。

結局、2ステップにまとまりました。
プロジェクト直下.gitフォルダの中を操作するので、隠しフォルダの表示をお忘れなく

2-1:configファイルのsvn-remote “svn”以下項目を削除

このファイルに[svn-remote]で始まる項目があると思います。そこをテキストエディタで開いて消すだけです。

2-2:svnフォルダも丸ごと削除

もしかしたらもうちょっとうまいことやる方法あるのかもしれないですけれどね。
今のところ問題はないのでこちらもバッサリ削除。

3:ついでに.gitignoreとemptyファイルを用意しておく
.gitignoreは無視リスト、
毎回管理するかどうか聞くなとするファイルをリストしておけます。(詳しい書き方はご自分で。)
emptyファイル今こそファイルは入っていないけれど将来的にないと困るフォルダを抑えておくカカシみたいなもの。
gitはファイルのないフォルダを覚えていてくれませんからね…。

.gitignoreみたいにドット始まりのファイルをWindowsで作りたいなら、
ファイル名を”.gitignore.”とするといいみたいです。

もちろん、この変更は「Gitに」コミットしておきましょう。

5:あとは適当にリモートとつなげてプッシュ

まだローカルにGitリポジトリがある状態です。
チームで共有するために、リモートリポジトリを作ります。

とりあえずはこんなところです。
細かい設定をできる限り追うことなくSVNと縁を切る方法、
少なくとも、configファイル編集とsvnファイルの丸ごと削除だけは大事です。

投稿日:

phpexcelのEXCEL列表記のテーブル作成

phpExcelにて列を指定して値を表示する際に、
EXCEL列の配列になったものをインデックスで指定して表示できれば、
横に長い表を作成する際に役に立つと思いこのテーブルを作成しました。


// EXCELの横座標を設定する。
$col1 = array("","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
$col2 = array("","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
$col3 = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
$col4 = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
$colArr = array();
$idx = 0;
foreach ($col1 as $val1) {
    if ($val1 == "") {
        foreach ($col2 as $val2) {
            foreach ($col3 as $val3) {
                $colArr[$idx] = $val1 . $val2 . $val3;
                $idx++;
            }
        }
    } else {
        foreach ($col4 as $val2) {
            foreach ($col3 as $val3) {
                $colArr[$idx] = $val1 . $val2 . $val3;
                $idx++;
            }
        }
    }
}
$col = 0;
$row = 1;
$sheet->setCellValue("{$colArr[$col]}{$row}", "日付");  // A1に「日付」表示
$col = 26;
$sheet->setCellValue("{$colArr[$col]}{$row}", "日付");  // AA1に「日付」表示
$col = 702;
$sheet->setCellValue("{$colArr[$col]}{$row}", "日付");  // AAA1に「日付」表示
$col = 1378;
$sheet->setCellValue("{$colArr[$col]}{$row}", "日付");  // BAA1に「日付」表示
$col = 16383;
$sheet->setCellValue("{$colArr[$col]}{$row}", "日付");  // XFD1に「日付」表示 ここがEXCEL横の最大値です。

PHPEXCELにて、列表記をインデックスで扱いたい時の配列です。

投稿日:

全画面ページを簡単に作成!fullpage.jsの使い方とTIPS集

案件で全画面ページを簡単に作るプラグイン「fullpage.js」を使用する事がありました。

今回、レスポンシブ対応にあたって、文章等が1ページの範囲を超える場合があり、その際はスクロールバーを表示してスクロールできるようにしたいため、scrolloverflow.jsも使用しました。

そちらの簡単な使い方とハマった所をtipsとして取り上げます。

初期設定

まずは、必要な読み込みファイルから。

fullpage.js 公式サイト

まず、表示させたいページに必要なCSSとjsを読み込みます。








全画面ページにしたい所は起点の要素(今回はIDがfullpageの要素)と、その子クラスにsectionの名前を付けます。

横スライドも欲しい場合は、section要素にその子のクラスにslideという名前を付けます。

Some section
Some section
Some section
Slide 1
Slide 2
Slide 3
Slide 4
Some section

jQueryを使って呼び出します。

$('#fullpage').fullpage({
   anchors: ['page1', 'page2', 'page3', 'page4'], // ページのアンカー名を指定
   menu: '#global-menu', // グローバルメニューのID名
   scrollOverflow: true, //全画面よりコンテンツが多い場合スクロールバーを出すかどうか
   loopHorizontal:false, //横スライダーをループさせない
   touchSensitivity: 16, //タッチデバイスでのセクション切替の強さの閾値
   afterLoad: function (anchorLink, index) {
    //セクションが読み込み終わりのイベント
    if (index === 1) {
     //TOPロード時
	
    }else if(index === $('#fullpage .section').length){
     //最下ページ時
    }else{
     //その他のページの時
    }
   },
   afterSlideLoad: function (anchorLink, index, slideAnchor, slideIndex) {
     // スライドが読み込み終わった後のイベント
   },
   onLeave: function (index, nextIndex, direction) {
     // セクションを離れた時のイベント
   },
   onSlideLeave: function (anchorLink, index, slideIndex, direction, nextSlideIndex) {
     // スライドを離れた時のイベント
   },
   afterResize: function () {
    // リサイズ後のイベント
  }
});

グローバルメニューが要る場合には、上記menu:"#global-menu"のように指定して、li要素のdata-menuanchorに上記anchors配列で指定した名前と対応させます。

そうすると、グルーバルメニューのクラスに現在居るページはactiveが付きます。ページが遷移される度に現在居るクラスにactiveが付き、移動元ページのactiveクラスは外れますので、メニューのON/OFFのCSSの装飾などが簡単に作れます。


これで、縦4ページ、3ページ目に横に4スライドある全画面ページが出来上がったと思います。

TIPS

作成に当たって色々とありましたので、そこで得たTipsをドドーンと紹介しちゃいます。

可変サイズ対応

全画面のページのサイズが確定した後にAJAXやdisplay:noneしていた要素を表示させて、表示させている要素が増えた場合、スクロールする領域が足りない事が起きたりします。その際は、rebuild()関数を呼び出して、再度サイズ計算し新たなページのサイズを確定させます。

// フェードイン・フェードアウトの後fullpage.js再計算
$("#recruit-space").fadeToggle(500,function(){
    $.fn.fullpage.reBuild();
})

fullpage.jsの読み込み後に何かをさせたい場合

jQueryのロード時とfullpage.jsのロード時はタイミングとして別になるので、 fullpage.jsが読み込まれた後に処理を走らせたい場合は、afterRender以下に処理を書きます。

afterRender: function () {
    //(例)クリッカブルマップレスポンシブ
     $('img[usemap]').rwdImageMaps();
}

ページを遷移させる度にGoogle Analyticsのコードを送る

fullpage.jsは1ページを複数ページとして見せているだけなので、普通にGoogle Analyticsコードを貼っても該当ページの読み込み時に1回しか送られません。

貼るコードを分けて、縦ページの遷移、横ページをスライドさせた時に、Analyticsのコードを送るように書けば思うようなデータが取れます。

通常のアナリティクスコード読み込みの時に、下の方にあるga('send', 'pageview');を外します。


そして、fullpage.jsの横スライドが読み込まれた際に起きるイベントafterSlideLoad内にga('send'...のコードを書きます。

afterSlideLoad: function(anchorLink, index, slideAnchor, slideIndex) {
   ga('send', 'pageview', { 'page': anchorLink, 'title': slideAnchor });
},

縦ページ遷移に対応するにはadterLoadイベント内に記述します。

  afterLoad: function (anchorLink, index) {
     ga('send', 'pageview', { 'page': anchorLink, 'title':anchorLink });               
  }

まとめ

SPA風にページが手軽に作れたり、アイデア次第で面白いページが作れると思います。その分独自のライフサイクルやイベントがあるのでハマり所があったり、SEO的にはどうなるんだろうと思う所がありましたが、ここまで対応できれば普通に使えそうですね。

また何かあったら追記しようと思います。

fullpage.js 公式サイト

投稿日:

ドラッグアンドドロップでファイルをアップロードする

今回ファイルを選択してあげている所をドラッグアンドドロップでファイルを指定して上げたいという要望を受けて対応しました。
jqueryさえあれば簡単に出来ちゃうので一番シンプルなサンプルを作ってみました。
続きを読む ドラッグアンドドロップでファイルをアップロードする

投稿日:

Say yes or die!

凄く過激なタイトルを付けてしまいました。
これはあるSQL文を見て、それを短く書き換えたときの感情です。


SELECT SUM(CASE WHEN condition > 100 THEN 0 ELSE 1 END) as positive FROM some_table

1行で書いてしまいましたが、もともとはCASE文が数層入れ子になっていて、複雑な条件式を最後にSUMで括っていた、というのが複数項目にも及んでいた感じのSQLでした。そして、CASE式で評価される結果は必ず0か1。つまるところ、CASE文をたくさん組み合わせて条件を作り、条件に合うものを数えるということをやっていたわけです。

最初に思ったのは「WHERE句で条件絞ってcountすればいいじゃん」ってことです

SELECT COUNT(condition) as positive FROM some_table WHERE condition > 100

そうできればよかったんですが…条件に合う件数を数える項目がほかにもたくさんあり、それぞれで
毎回SQLを発行するのもこれまた頭が悪い。

SQLの返答をphp側でforeach回してオレオレカウントする…というのも考えたのですが、
カウント部分で何をやっているかを把握しようとするとCASE文のピラミッドとどっこいどっこいだなとも。

「テーブル全体を検索しつつ、複数条件それぞれにおいて条件に合うものをcountするには…」と調べていて、
このタイトルの「Say yes or die!」にたどり着いたわけです。

MySQLの論理式にはTrue、FalseのほかにNullを叩き込むことができると言う話があって…

  • True AND Null = Null
  • False AND Null = False
  • True OR Null = True
  • False OR Null = Null

つまるところ、Nullの有無にかかわらずTrue/False断言できる式は断言してもらえるという結果になるわけです。
そして、count()はNullでないものを数える。

というわけで生まれるイディオムが count([何か条件式] OR Null) というわけです。
条件式がTrueならレコードはTrueと評価され、カウントの対象になる、
条件式がFalseまたはNullなら、レコードはFalseと評価され、カウントされない。

このイディオムを使って最初のSQLを書き直すと…

SELECT count((condition > 100) OR NULL)as positive FROM some_table

‘OR NULL’という書き方の意味さえ知っていれば、これが何かを「合計」しているわけではなく「数えている」ことが一目でわかりますし、何より、WHERE句を変えながら何度もSQL発行しなくて済みます。別のカウントをしたいときは条件を変えた検索フィールドを追加するだけですから。

「Say yes or die!」もとい「Be true or null!」使えると思います!

投稿日:

JSONで画像データを送信する方法

JSONで単純にファイル名を渡しても、当然ファイルのデータは送ることができません。
そのような場合は、base64_encodeを使って送りましょう。
このサンプルでは、JAVAScriptの時点でPHPのbase64_encodeを使用してデータ化した文字列を送り
受けて側で、base64_decodeしてファイルへ保存で渡すことが可能です。
続きを読む JSONで画像データを送信する方法

投稿日:

WebサイトをPDFに変換する

HTMLでシステムの画面のモックを作成していた時に
お客様が全ページ画面キャプチャするのが大変・・・
印刷して朱書きで要望等簡単に書けないか?ということがありました。

社内でも調整してほしい箇所をキャプチャするのは大変だし、何かいい方法ないか調べてみました!

続きを読む WebサイトをPDFに変換する