jQuery」カテゴリーアーカイブ

CakePHP MediaPlugin + Plupload 複数ファイルの同時アップロード

追記 2011-08-01
CakePHPのプラグイン化してみました
https://junichi11.com/?p=1406

複数のファイルを同時にアップロード

多くのファイルをアップロードしたい場合は、ファイルを何度も選択するのが大変。

何かいいものはないかと探していたところ、

PluploadというjQueryのプラグインを見つけた。
Pluploadでは下図のように複数のファイルを一度に選択することができる。

ダウンロード:http://www.plupload.com/

Pluploadの仕組み

Pluploadは以下のような仕組みになっている。

  1. 非同期で選択したファイルを複数に分割(chunkというもの)して送信する。
  2. 全ての送信が完了。
  3. 送信したファイル情報をPOSTで送信する。
    送信したファイルの情報はPluploadのサイトを参照。
    サーバー側には上図のような情報がファイル数分送られてくる。

 CakePHPでの処理

  1. 送信されてきたファイルを処理するメソッドを作成する。
    メソッドの中身はDLしたpluploadのファイルの中に、ファイルを処理するプログラムファイルがあるのでそれをそのまま使う。
  2. POSTされてきた情報をもとに、ファイルのUPロード処理を行う。
    (MediaPluginを使用する。)

MediaPluginのインストールは下記を参照
http://d.hatena.ne.jp/slywalker/20090730/1248916519
http://www.zontheworld.com/blog/archives/111
PHPで作る携帯サイト デベロッパーズガイド」秀和システム 滝下真玄著

ここではPHPで作る携帯サイト デベロッパーズガイドを参考にMediaPluginをインストールしています。

通常Pictureの部分はAttachementとして作成されているかもしれません。

app/controllers/photos_controller.php

class PhotosController extends AppController {
    public $name = 'Photos';
public $uses = array('Photo', 'Picture');

public $components = array('RequestHandler');
    //  …

function plupload(){
// plupload/examples/upload.phpの中身をコピペ
}

    function add(){

/*....................................................
* POST
* uploader_0_tmpname
* uploader_0_name
* uploader_0_status
* ...
....................................................*/
if(!empty($this->data)){
        $plupload = null;
$cnt = 0;
$tmpdir = ini_get('upload_tmp_dir');
foreach($_POST as $key => $value){
if($key == 'uploader_count'){
$cnt = $value;
}
$split = explode('_', $key);

if(in_array('tmpname', $split) || in_array('name', $split)){
$plupload[$split[1]][$split[2]] = $value;
}

}
foreach($plupload as $file){
@rename($tmpdir.DS.$file['tmpname'], $tmpdir.DS.$file['name']);
}

for($i = 0; $i<count($plupload); $i++){
$this->data['Picture'][$i]['title'] = '';
$this->data['Picture'][$i]['description'] = '';
$this->data['Picture'][$i]['model'] = 'Photos';
$this->data['Picture'][$i]['file'] = $tmpdir.DS.$plupload[$i]['name'];
        }

        if($this->Photos->saveAll($this->data, array('validate' => 'first'))){
$this->flash('データを追加しました', 'index',3);
foreach($plupload as $file){
@unlink($tmpdir.DS.$file['name']);
}
return;
}else{
$this->flash('失敗', 'add');
foreach($plupload as $file){
@unlink($tmpdir.DS.$file['name']);
}
        }
        }
}

    function beforeFilter(){
        if ($this->RequestHandler->isFlash()) {
            $this->Auth->allow('add');
        }
    }

}


/app/models/photos.php

class Photo extends AppModel {
var $name = 'Photo';

//アソシエーション設定
var $hasMany = array(
'Picture' => array(
'className' => 'Picture',
'foreignKey' => 'foreign_key',
'conditions' => array('Picture.model' => 'Photo'),
'dependent' => true,
),
);
}

最初に上手くいかなかったのが、下記の部分。
送られてくる情報が通常のファイルを送信する場合と違うから、
[‘file’]の部分をどうしていいのかわからなかった。

    $this->data['Picture'][$i]['file'] = $tmpdir.DS.$plupload[$i]['name'];

mediapluginのgitのwikiをみると解決。

MediaPluginの転送方法は3つある

[‘file’]の部分は以下の指定が可能。
pluploadでアップした場合2番目の使い方をする。

HTML formタグによるHTTP POST配列を使う

array(
'name' => 'hoge.jpg',
'type' => 'image/jgeg',
'tmp_name' => '/tmp/3242ljl',
'error' => 0,
'size' => 3524
)

ファイルへの絶対パスを使う

Ex : ‘/var/www/tmp/hoge.jpg’

URLを指定する

Ex : ‘http://www.cakephp.org/imgs/hoge.png’

/app/views/photos/add.ctp


<!-- Thirdparty intialization scripts, needed for the Google Gears and BrowserPlus runtimes -->
<?php echo $javascript->link('plupload/gears_init.js');?>
<script type="text/javascript" src="<a href="http://bp.yahooapis.com/2.4.21/browserplus-min.js%22%3E%3C/script">http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script</a>>

<!-- Load plupload and all it's runtimes and finally the jQuery queue widget -->
<?php echo $javascript->link('plupload/plupload.full.min.js');?>
<?php echo $javascript->link('plupload/jquery.plupload.queue.min.js');?>
<script type="text/javascript">
// Convert divs to queue widgets when the DOM is ready
$(function() {
$("#uploader").pluploadQueue({
// General settings
runtimes : 'gears,flash,silverlight,browserplus,html5',
url : '<?php echo $html->webroot('/photos/plupload')?>',
max_file_size : '3mb',
chunk_size : '1mb',
unique_names : true,

// Resize images on clientside if we can
//resize : {width : 640, height : 480, quality : 100},

// Specify what files to browse for
filters : [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
],

// Flash settings
flash_swf_url : '<?php echo $html->webroot('/js/plupload/');?>plupload.flash.swf',

// Silverlight settings
silverlight_xap_url : '<?php echo $html->webroot('/js/plupload/');?>plupload.silverlight.xap'
});

// Client side form validation
$('form').submit(function(e) {
var uploader = $('#uploader').pluploadQueue();

// Validate number of uploaded files
if (uploader.total.uploaded == 0) {
// Files in queue upload them first
if (uploader.files.length > 0) {
// When all files are uploaded submit form
uploader.bind('UploadProgress', function() {
if (uploader.total.uploaded == uploader.files.length)
$('form').submit();
});

uploader.start();
} else
alert('You must at least upload one file.');

e.preventDefault();
}
});
});
</script>
<h2>写真の追加</h2>
Add files をクリックしてファイルを追加してください。<br />
ファイルを選択するときに複数のファイルを選択することができます。<br />
Google Gears をインストールしていれば、ファイルをドラッグ&ドロップで追加できます。
<?php echo $form->create('Photo', array('type' => 'file', 'action' => 'add', 'class' => 'plupload')); ?>
<span id="plupload">
<div id="uploader">
<p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
</div>
<br style="clear: both" />
</span>
<?php echo $form->end('追加'); ?>

実際に作ったものと名前等を変えているので、調整しないと動かないかもしれません。

もっといい作り方があるかもしれませんが、

参考までに。。

CakePHP + jQueryUI 絵文字入力ダイアログ

jQueryとCSS Spriteを利用して、絵文字入力ダイアログを作成しました。

完成イメージ

概要

  1. jQuery, jQueryUI関係のものをダウンロード(省略)
  2. 絵文字の画像(1枚の画像にまとめる)の準備
  3. CSSの作成
  4. コードをelement化

絵文字の画像は1枚1枚読み込んでいると、何度もサーバー側に何度も画像を要求しないといけないので、CSS Spriteで読み込む速度を高速化する。

実際、そのまま画像を読み込もうとすると200回以上やりとりしないといけないので、最初にダイアログが表示されるまで少々かかる。

通常の場合

CSS Spriteの場合

絵文字画像

CSSを書くのが面倒だけれど、CSS Sprite Generatorを使うと、複数の画像を固めてくれて、CSSも吐き出してくれる。

CSS Sprite Generator : http://ja.spritegen.website-performance.org/

バラバラになっている絵文字を持っている場合は、zip形式で固めて、上記のサイトから画像とCSSを作成することができる。

ただ、自分の場合画像がちゃんとできなかったので、手動で作成した。

画像作成

使用した絵文字は、こちら。

http://start.typepad.jp/typecast/

inkscapeとかの画像処理ソフトで、ダウンロードした絵文字を整列させて1枚にまとめる。

1つが16×16の画像を2px間隔あけて並べる。

それで作成したものがこちら。

上記の絵文字はクリエイティブ・コモンズライセンスです。

CSSコーディング

1枚の画像から必要な部分をCSSで切り出していきます。

emoji.css


/***************************************
emoji
***************************************/
#emoji {
padding: .4em 1em .4em 0px;
text-decoration: none;
position: relative;
}
#emoji span:hover {
color: #666;
text-decoration: underline;
}
#emoji span{
cursor: pointer;
}

.sprite{
float: left;
height: 16px;
width: 16px;
background-image: url(../img/emoji.png);
background-repeat:no-repeat;
}

.sprite span{
display:none;
}

#sun{ background-position: 0px 0px;}
#cloud{ background-position: -18px 0px;}
#rain{ background-position: -36px 0px;}
#snow{ background-position: -54px 0px;}
#thunder{ background-position: -72px 0px;}
#typhoon{background-position: -90px 0px;}
#mist{background-position: -108px 0px;}
#sprinkle{background-position: -126px 0px;}
#aries{background-position: -144px 0px;}
#taurus{background-position: -162px 0px;}
#gemini{background-position: -180px 0px;}
#cancer{background-position: -198px 0px;}
#leo{background-position: -216px 0px;}
#virgo{background-position: -234px 0px;}
#libra{background-position: 0px -18px;}
#scorpius{background-position: -18px -18px;}
#sagittarius{background-position: -36px -18px;}
#capricornus{background-position: -54px -18px;}
#aquarius{background-position: -72px -18px;}
#pisces{background-position: -90px -18px;}
#sports{background-position: -108px -18px;}
#baseball{background-position: -126px -18px;}
#golf{background-position: -144px -18px;}
#tennis{background-position: -162px -18px;}
#soccer{background-position: -180px -18px;}
#ski{background-position: -198px -18px;}
#basketball{background-position: -216px -18px;}
#motorsports{background-position: -234px -18px;}
#pocketbell{background-position: 0px -36px;}
#train{background-position: -18px -36px;}
#subway{background-position: -36px -36px;}
#bullettrain{background-position: -54px -36px;}
#car{background-position: -72px -36px;}
#car{background-position: -90px -36px;}
#bus{background-position: -108px -36px;}
#ship{background-position: -126px -36px;}
#airplane{background-position: -144px -36px;}
#house{background-position: -162px -36px;}
#building{background-position: -180px -36px;}
#postoffice{background-position: -198px -36px;}
#hospital{background-position: -216px -36px;}
#bank{background-position: -234px -36px;}
#atm{background-position: 0px -54px;}
#hotel{background-position: -18px -54px;}
#cvs{background-position: -36px -54px;}
#gasstation{background-position: -54px -54px;}
#parking{background-position: -72px -54px;}
#signaler{background-position: -90px -54px;}
#toilet{background-position: -108px -54px;}
#restaurant{background-position: -126px -54px;}
#cafe{background-position: -144px -54px;}
#bar{background-position: -162px -54px;}
#beer{background-position: -180px -54px;}
#fastfood{background-position: -198px -54px;}
#boutique{background-position: -216px -54px;}
#hairsalon{background-position: -234px -54px;}
#karaoke{background-position: 0px -72px;}
#movie{background-position: -18px -72px;}
#upwardright{background-position: -36px -72px;}
#carouselpony{background-position: -54px -72px;}
#music{background-position: -72px -72px;}
#art{background-position: -90px -72px;}
#drama{background-position: -108px -72px;}
#event{background-position: -126px -72px;}
#ticket{background-position: -144px -72px;}
#smoking{background-position: -162px -72px;}
#nosmoking{background-position: -180px -72px;}
#camera{background-position: -198px -72px;}
#bag{background-position: -216px -72px;}
#book{background-position: -234px -72px;}
#ribbon{background-position: 0px -90px;}
#present{background-position: -18px -90px;}
#birthday{background-position: -36px -90px;}
#telephone{background-position: -54px -90px;}
#mobilephone{background-position: -72px -90px;}
#memo{background-position: -90px -90px;}
#tv{background-position: -108px -90px;}
#game{background-position: -126px -90px;}
#cd{background-position: -144px -90px;}
#heart{background-position: -162px -90px;}
#spade{background-position: -180px -90px;}
#diamond{background-position: -198px -90px;}
#club{background-position: -216px -90px;}
#eye{background-position: -234px -90px;}
#ear{background-position: 0px -108px;}
#rock{background-position: -18px -108px;}
#scissors{background-position: -36px -108px;}
#paper{background-position: -54px -108px;}
#downwardright{background-position: -72px -108px;}
#upwardleft{background-position: -90px -108px;}
#foot{background-position: -108px -108px;}
#shoe{background-position: -126px -108px;}
#eyeglass{background-position: -144px -108px;}
#wheelchair{background-position: -162px -108px;}
#newmoon{background-position: -180px -108px;}
#moon1{background-position: -198px -108px;}
#moon2{background-position: -216px -108px;}
#moon3{background-position: -234px -108px;}
#fullmoon{background-position: 0px -126px;}
#dog{background-position: -18px -126px;}
#cat{background-position: -36px -126px;}
#yacht{background-position: -54px -126px;}
#xmas{background-position: -72px -126px;}
#downwardleft{background-position: -90px -126px;}
#phoneto{background-position: -108px -126px;}
#mailto{background-position: -126px -126px;}
#faxto{background-position: -144px -126px;}
#info01{background-position: -162px -126px;}
#info02{background-position: -180px -126px;}
#mail{background-position: -198px -126px;}
#by-d{background-position: -216px -126px;}
#d-point{background-position: -234px -126px;}
#yen{background-position: 0px -144px;}
#free{background-position: -18px -144px;}
#id{background-position: -36px -144px;}
#key{background-position: -54px -144px;}
#enter{background-position: -72px -144px;}
#clear{background-position: -90px -144px;}
#search{background-position: -108px -144px;}
#new{background-position: -126px -144px;}
#flag{background-position: -144px -144px;}
#freedial{background-position: -162px -144px;}
#sharp{background-position: -180px -144px;}
#mobaq{background-position: -198px -144px;}
#one{background-position: -216px -144px;}
#two{background-position: -234px -144px;}
#three{background-position: 0px -162px;}
#four{background-position: -18px -162px;}
#five{background-position: -36px -162px;}
#six{background-position: -54px -162px;}
#seven{background-position: -72px -162px;}
#eight{background-position: -90px -162px;}
#nine{background-position: -108px -162px;}
#zero{background-position: -126px -162px;}
#ok{background-position: -144px -162px;}
#heart01{background-position: -162px -162px;}
#heart02{background-position: -180px -162px;}
#heart03{background-position: -198px -162px;}
#heart04{background-position: -216px -162px;}
#happy01{background-position: -234px -162px;}
#angry{background-position: 0px -180px;}
#despair{background-position: -18px -180px;}
#sad{background-position: -36px -180px;}
#wobbly{background-position: -54px -180px;}
#up{background-position: -72px -180px;}
#note{background-position: -90px -180px;}
#spa{background-position: -108px -180px;}
#cute{background-position: -126px -180px;}
#kissmark{background-position: -144px -180px;}
#shine{background-position: -162px -180px;}
#flair{background-position: -180px -180px;}
#annoy{background-position: -198px -180px;}
#punch{background-position: -216px -180px;}
#bomb{background-position: -234px -180px;}
#notes{background-position: 0px -198px;}
#down{background-position: -18px -198px;}
#sleepy{background-position: -36px -198px;}
#sign01{background-position: -54px -198px;}
#sign02{background-position: -72px -198px;}
#sign03{background-position: -90px -198px;}
#impact{background-position: -108px -198px;}
#sweat01{background-position: -126px -198px;}
#sweat02{background-position: -144px -198px;}
#dash{background-position: -162px -198px;}
#sign04{background-position: -180px -198px;}
#sign05{background-position: -198px -198px;}
#slate{background-position: -216px -198px;}
#pouch{background-position: -234px -198px;}
#pen{background-position: 0px -216px;}
#shadow{background-position: -18px -216px;}
#chair{background-position: -36px -216px;}
#night{background-position: -54px -216px;}
#soon{background-position: -72px -216px;}
#on{background-position: -90px -216px;}
#end{background-position: -108px -216px;}
#clock{background-position: -126px -216px;}
#appli01{background-position: -144px -216px;}
#appli02{background-position: -162px -216px;}
#t-shirt{background-position: -180px -216px;}
#moneybag{background-position: -198px -216px;}
#rouge{background-position: -216px -216px;}
#denim{background-position: -234px -216px;}
#snowboard{background-position: 0px -234px;}
#bell{background-position: -18px -234px;}
#door{background-position: -36px -234px;}
#dollar{background-position: -54px -234px;}
#pc{background-position: -72px -234px;}
#loveletter{background-position: -90px -234px;}
#wrench{background-position: -108px -234px;}
#pencil{background-position: -126px -234px;}
#crown{background-position: -144px -234px;}
#ring{background-position: -162px -234px;}
#sandclock{background-position: -180px -234px;}
#bicycle{background-position: -198px -234px;}
#japanesetea{background-position: -216px -234px;}
#watch{background-position: -234px -234px;}
#think{background-position: 0px -252px;}
#confident{background-position: -18px -252px;}
#coldsweats01{background-position: -36px -252px;}
#coldsweats02{background-position: -54px -252px;}
#pout{background-position: -72px -252px;}
#gawk{background-position: -90px -252px;}
#lovely{background-position: -108px -252px;}
#good{background-position: -126px -252px;}
#bleah{background-position: -144px -252px;}
#wink{background-position: -162px -252px;}
#happy02{background-position: -180px -252px;}
#bearing{background-position: -198px -252px;}
#catface{background-position: -216px -252px;}
#crying{background-position: -234px -252px;}
#weep{background-position: 0px -270px;}
#ng{background-position: -18px -270px;}
#clip{background-position: -36px -270px;}
#copyright{background-position: -54px -270px;}
#tm{background-position: -72px -270px;}
#run{background-position: -90px -270px;}
#secret{background-position: -108px -270px;}
#recycle{background-position: -126px -270px;}
#r-mark{background-position: -144px -270px;}
#danger{background-position: -162px -270px;}
#ban{background-position: -180px -270px;}
#empty{background-position: -198px -270px;}
#pass{background-position: -216px -270px;}
#full{background-position: -234px -270px;}
#leftright{background-position: 0px -288px;}
#updown{background-position: -18px -288px;}
#school{background-position: -36px -288px;}
#wave{background-position: -54px -288px;}
#fuji{background-position: -72px -288px;}
#clover{background-position: -90px -288px;}
#cherry{background-position: -108px -288px;}
#tulip{background-position: -126px -288px;}
#banana{background-position: -144px -288px;}
#apple{background-position: -162px -288px;}
#bud{background-position: -180px -288px;}
#maple{background-position: -198px -288px;}
#cherryblossom{background-position: -216px -288px;}
#riceball{background-position: -234px -288px;}
#cake{background-position: 0px -306px;}
#bottle{background-position: -18px -306px;}
#noodle{background-position: -36px -306px;}
#bread{background-position: -54px -306px;}
#snail{background-position: -72px -306px;}
#chick{background-position: -90px -306px;}
#penguin{background-position: -108px -306px;}
#fish{background-position: -126px -306px;}
#delicious{background-position: -144px -306px;}
#smile{background-position: -162px -306px;}
#horse{background-position: -180px -306px;}
#pig{background-position: -198px -306px;}
#wine{background-position: -216px -306px;}
#shock{background-position: -234px -306px;}

手動で作ると計算しながらなので面倒。。。

絵文字入力用のコードをelement化

前回書いたキャレット位置に文字を挿入することを応用。

実行することは以下のとおり。

  • ダイアログの表示
  • キャレット位置に絵文字を挿入
  • 動的にjQueryのコードを生成
  • element化(引数に、絵文字の入力を有効にしたいid名の配列をとるようにする)

/app/view/elements/emoji.ctp

<script>
var tmpFocus;
//絵文字の追加
$(function(){
$.fn.extend({
insertAtCaret: function(v) {
var o = this.get(0);
o.focus();
if (jQuery.browser.msie) {
var r = document.selection.createRange();
r.text = v;
r.select();
} else {
var s = o.value;
var p = o.selectionStart;
var np = p + v.length;
o.value = s.substr(0, p) + v + s.substr(p);
o.setSelectionRange(np, np);
}
}
});

$("#emoji_table .sprite").click(
function() {
<?php foreach($targets as $target){?>
if(tmpFocus == "<?php echo $target?>"){
$("#<?php echo $target?>").insertAtCaret($(this).attr("title"));
}
<?php }// foreach?>
})
});
$(function(){
<?php foreach($targets as $target){?>
$("#<?php echo $target?>").focus(
function(){
tmpFocus = "<?php echo $target?>";
});
<?php }// foreach?>
});

// 絵文字入力ダイアログの表示
$(function(){
// Dialog
$('#emoji_table').dialog({
autoOpen: false,
width: 300,
buttons: {
"Ok": function() {
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
}
});

// Dialog Link
$('#emoji span').click(function(){
$('#emoji_table').dialog('open');
return false;
});
});
</script>

<div id="emoji_table" style="display:none;" title="絵文字">
<div id="sun" title=""><span></span></div>
<div id="cloud" title="" ><span></span></div>
<div id="rain" title="" ><span></span></div>
<div id="snow" title="" ><span></span></div>
<div id="thunder" title="" ><span></span></div>
<div id="typhoon" title="" ><span></span></div>
<div id="mist" title="" ><span></span></div>
<div id="sprinkle" title="" ><span></span></div>
<div id="aries" title="" ><span></span></div>
<div id="taurus" title="" ><span></span></div>
<div id="gemini" title="" ><span></span></div>
<div id="cancer" title="" ><span></span></div>
<div id="leo" title="" ><span></span></div>
<div id="virgo" title="" ><span></span></div>
<div id="libra" title="" ><span></span></div>
<div id="scorpius" title="" ><span></span></div>
<div id="sagittarius" title="" ><span></span></div>
<div id="capricornus" title="" ><span></span></div>
<div id="aquarius" title="" ><span></span></div>
<div id="pisces" title="" ><span></span></div>
<div id="sports" title="" ><span></span></div>
<div id="baseball" title="" ><span></span></div>
<div id="golf" title="" ><span></span></div>
<div id="tennis" title="" ><span></span></div>
<div id="soccer" title="" ><span></span></div>
<div id="ski" title="" ><span></span></div>
<div id="basketball" title="" ><span></span></div>
<div id="motorsports" title="" ><span></span></div>
<div id="pocketbell" title="" ><span></span></div>
<div id="train" title="" ><span></span></div>
<div id="subway" title="" ><span></span></div>
<div id="bullettrain" title="" ><span></span></div>
<div id="car" title="" ><span></span></div>
<div id="car" title="" ><span></span></div>
<div id="bus" title="" ><span></span></div>
<div id="ship" title="" ><span></span></div>
<div id="airplane" title="" ><span></span></div>
<div id="house" title="" ><span></span></div>
<div id="building" title="" ><span></span></div>
<div id="postoffice" title="" ><span></span></div>
<div id="hospital" title="" ><span></span></div>
<div id="bank" title="" ><span></span></div>
<div id="atm" title="" ><span></span></div>
<div id="hotel" title="" ><span></span></div>
<div id="cvs" title="" ><span></span></div>
<div id="gasstation" title="" ><span></span></div>
<div id="parking" title="" ><span></span></div>
<div id="signaler" title="" ><span></span></div>
<div id="toilet" title="" ><span></span></div>
<div id="restaurant" title="" ><span></span></div>
<div id="cafe" title="" ><span></span></div>
<div id="bar" title="" ><span></span></div>
<div id="beer" title="" ><span></span></div>
<div id="fastfood" title="" ><span></span></div>
<div id="boutique" title="" ><span></span></div>
<div id="hairsalon" title="" ><span></span></div>
<div id="karaoke" title="" ><span></span></div>
<div id="movie" title="" ><span></span></div>
<div id="upwardright" title="" ><span></span></div>
<div id="carouselpony" title="" ><span></span></div>
<div id="music" title="" ><span></span></div>
<div id="art" title="" ><span></span></div>
<div id="drama" title="" ><span></span></div>
<div id="event" title="" ><span></span></div>
<div id="ticket" title="" ><span></span></div>
<div id="smoking" title="" ><span></span></div>
<div id="nosmoking" title="" ><span></span></div>
<div id="camera" title="" ><span></span></div>
<div id="bag" title="" ><span></span></div>
<div id="book" title="" ><span></span></div>
<div id="ribbon" title="" ><span></span></div>
<div id="present" title="" ><span></span></div>
<div id="birthday" title="" ><span></span></div>
<div id="telephone" title="" ><span></span></div>
<div id="mobilephone" title="" ><span></span></div>
<div id="memo" title="" ><span></span></div>
<div id="tv" title="" ><span></span></div>
<div id="game" title="" ><span></span></div>
<div id="cd" title="" ><span></span></div>
<div id="heart" title="" ><span></span></div>
<div id="spade" title="" ><span></span></div>
<div id="diamond" title="" ><span></span></div>
<div id="club" title="" ><span></span></div>
<div id="eye" title="" ><span></span></div>
<div id="ear" title="" ><span></span></div>
<div id="rock" title="" ><span></span></div>
<div id="scissors" title="" ><span></span></div>
<div id="paper" title="" ><span></span></div>
<div id="downwardright" title="" ><span></span></div>
<div id="upwardleft" title="" ><span></span></div>
<div id="foot" title="" ><span></span></div>
<div id="shoe" title="" ><span></span></div>
<div id="eyeglass" title="" ><span></span></div>
<div id="wheelchair" title="" ><span></span></div>
<div id="newmoon" title="" ><span></span></div>
<div id="moon1" title="" ><span></span></div>
<div id="moon2" title="" ><span></span></div>
<div id="moon3" title="" ><span></span></div>
<div id="fullmoon" title="" ><span></span></div>
<div id="dog" title="" ><span></span></div>
<div id="cat" title="" ><span></span></div>
<div id="yacht" title="" ><span></span></div>
<div id="xmas" title="" ><span></span></div>
<div id="downwardleft" title="" ><span></span></div>
<div id="phoneto" title="" ><span></span></div>
<div id="mailto" title="" ><span></span></div>
<div id="faxto" title="" ><span></span></div>
<div id="info01" title="" ><span></span></div>
<div id="info02" title="" ><span></span></div>
<div id="mail" title="" ><span></span></div>
<div id="by-d" title="" ><span></span></div>
<div id="d-point" title="" ><span></span></div>
<div id="yen" title="" ><span></span></div>
<div id="free" title="" ><span></span></div>
<div id="id" title="" ><span></span></div>
<div id="key" title="" ><span></span></div>
<div id="enter" title="" ><span></span></div>
<div id="clear" title="" ><span></span></div>
<div id="search" title="" ><span></span></div>
<div id="new" title="" ><span></span></div>
<div id="flag" title="" ><span></span></div>
<div id="freedial" title="" ><span></span></div>
<div id="sharp" title="" ><span></span></div>
<div id="mobaq" title="" ><span></span></div>
<div id="one" title="" ><span></span></div>
<div id="two" title="" ><span></span></div>
<div id="three" title="" ><span></span></div>
<div id="four" title="" ><span></span></div>
<div id="five" title="" ><span></span></div>
<div id="six" title="" ><span></span></div>
<div id="seven" title="" ><span></span></div>
<div id="eight" title="" ><span></span></div>
<div id="nine" title="" ><span></span></div>
<div id="zero" title="" ><span></span></div>
<div id="ok" title="" ><span></span></div>
<div id="heart01" title="" ><span></span></div>
<div id="heart02" title="" ><span></span></div>
<div id="heart03" title="" ><span></span></div>
<div id="heart04" title="" ><span></span></div>
<div id="happy01" title="" ><span></span></div>
<div id="angry" title="" ><span></span></div>
<div id="despair" title="" ><span></span></div>
<div id="sad" title="" ><span></span></div>
<div id="wobbly" title="" ><span></span></div>
<div id="up" title="" ><span></span></div>
<div id="note" title="" ><span></span></div>
<div id="spa" title="" ><span></span></div>
<div id="cute" title="" ><span></span></div>
<div id="kissmark" title="" ><span></span></div>
<div id="shine" title="" ><span></span></div>
<div id="flair" title="" ><span></span></div>
<div id="annoy" title="" ><span></span></div>
<div id="punch" title="" ><span></span></div>
<div id="bomb" title="" ><span></span></div>
<div id="notes" title="" ><span></span></div>
<div id="down" title="" ><span></span></div>
<div id="sleepy" title="" ><span></span></div>
<div id="sign01" title="" ><span></span></div>
<div id="sign02" title="" ><span></span></div>
<div id="sign03" title="" ><span></span></div>
<div id="impact" title="" ><span></span></div>
<div id="sweat01" title="" ><span></span></div>
<div id="sweat02" title="" ><span></span></div>
<div id="dash" title="" ><span></span></div>
<div id="sign04" title="" ><span></span></div>
<div id="sign05" title="" ><span></span></div>
<div id="slate" title="" ><span></span></div>
<div id="pouch" title="" ><span></span></div>
<div id="pen" title="" ><span></span></div>
<div id="shadow" title="" ><span></span></div>
<div id="chair" title="" ><span></span></div>
<div id="night" title="" ><span></span></div>
<div id="soon" title="" ><span></span></div>
<div id="on" title="" ><span></span></div>
<div id="end" title="" ><span></span></div>
<div id="clock" title="" ><span></span></div>
<div id="appli01" title="" ><span></span></div>
<div id="appli02" title="" ><span></span></div>
<div id="t-shirt" title="" ><span></span></div>
<div id="moneybag" title="" ><span></span></div>
<div id="rouge" title="" ><span></span></div>
<div id="denim" title="" ><span></span></div>
<div id="snowboard" title="" ><span></span></div>
<div id="bell" title="" ><span></span></div>
<div id="door" title="" ><span></span></div>
<div id="dollar" title="" ><span></span></div>
<div id="pc" title="" ><span></span></div>
<div id="loveletter" title="" ><span></span></div>
<div id="wrench" title="" ><span></span></div>
<div id="pencil" title="" ><span></span></div>
<div id="crown" title="" ><span></span></div>
<div id="ring" title="" ><span></span></div>
<div id="sandclock" title="" ><span></span></div>
<div id="bicycle" title="" ><span></span></div>
<div id="japanesetea" title="" ><span></span></div>
<div id="watch" title="" ><span></span></div>
<div id="think" title="" ><span></span></div>
<div id="confident" title="" ><span></span></div>
<div id="coldsweats01" title="" ><span></span></div>
<div id="coldsweats02" title="" ><span></span></div>
<div id="pout" title="" ><span></span></div>
<div id="gawk" title="" ><span></span></div>
<div id="lovely" title="" ><span></span></div>
<div id="good" title="" ><span></span></div>
<div id="bleah" title="" ><span></span></div>
<div id="wink" title="" ><span></span></div>
<div id="happy02" title="" ><span></span></div>
<div id="bearing" title="" ><span></span></div>
<div id="catface" title="" ><span></span></div>
<div id="crying" title="" ><span></span></div>
<div id="weep" title="" ><span></span></div>
<div id="ng" title="" ><span></span></div>
<div id="clip" title="" ><span></span></div>
<div id="copyright" title="" ><span></span></div>
<div id="tm" title="" ><span></span></div>
<div id="run" title="" ><span></span></div>
<div id="secret" title="" ><span></span></div>
<div id="recycle" title="" ><span></span></div>
<div id="r-mark" title="" ><span></span></div>
<div id="danger" title="" ><span></span></div>
<div id="ban" title="" ><span></span></div>
<div id="empty" title="" ><span></span></div>
<div id="pass" title="" ><span></span></div>
<div id="full" title="" ><span></span></div>
<div id="leftright" title="" ><span></span></div>
<div id="updown" title="" ><span></span></div>
<div id="school" title="" ><span></span></div>
<div id="wave" title="" ><span></span></div>
<div id="fuji" title="" ><span></span></div>
<div id="clover" title="" ><span></span></div>
<div id="cherry" title="" ><span></span></div>
<div id="tulip" title="" ><span></span></div>
<div id="banana" title="" ><span></span></div>
<div id="apple" title="" ><span></span></div>
<div id="bud" title="" ><span></span></div>
<div id="maple" title="" ><span></span></div>
<div id="cherryblossom" title="" ><span></span></div>
<div id="riceball" title="" ><span></span></div>
<div id="cake" title="" ><span></span></div>
<div id="bottle" title="" ><span></span></div>
<div id="noodle" title="" ><span></span></div>
<div id="bread" title="" ><span></span></div>
<div id="snail" title="" ><span></span></div>
<div id="chick" title="" ><span></span></div>
<div id="penguin" title="" ><span></span></div>
<div id="fish" title="" ><span></span></div>
<div id="delicious" title="" ><span></span></div>
<div id="smile" title="" ><span></span></div>
<div id="horse" title="" ><span></span></div>
<div id="pig" title="" ><span></span></div>
<div id="wine" title="" ><span></span></div>
<div id="shock" title="" ><span></span></div>
</div>
<div id="emoji"><!--「 絵文字」と画面に表示される部分 -->
<p><span>
<?php echo $html->image('application_view_icons.png'');// ここは、適当な画像を。?>絵文字
</span></p>
</div>

前半はjQueryの部分で、キャレット位置に絵文字を入れる処理です。

動的に絵文字を挿入するテキストエリアに関する部分を作成しています。

titleとspanには絵文字のバイナリを入れています。

spanタグの部分は表示されずに、絵文字に画像と置き換わります。

絵文字の順番は結構バラバラになっているので、表示したいように並び替えてください。

使い方

  • jQuery関係のものを読み込む。
  • emoji.cssを読み込む。
  • 作成した画像のUP。
  • 設置したい場所にelementを読み込む。

/app/views/hoge/add.ctp


<?php echo $this->element('emoji', array('targets' => array('BoardTitle', 'BoardName', 'BoardContent')));?>

引数にはテキストエリアのid名の配列をいれる。

※テキストボックスではちゃんと動かない。使いたい場合は入力をテキストエリアにすること。

docomoの絵文字ツールをインストールしていると絵文字が表示されるが、
そうではない場合、□にしか表示されないかもしれません。

あとはjQueryUIの表示を好きなように変更する。

elementを作成しておけば、1行でいつでも設置できるので便利です。

入力した絵文字をPCのブラウザで表示するには

KtaiLibraryの機能を使うと便利です。

KtaiLibraryについてはこちら。
http://blog.ecworks.jp/

Ktaiヘルパーを読み込み以下の設定をします。

<?php $ktai->options['output_auto_convert_emoji'] = true;?>
<?php $ktai->options['use_img_emoji'] = true;?>

これでPCの画面上に画像の絵文字が出力されるはずです。

jQuery テキストエリアのキャレット(カーソル)位置に文字を挿入

随分前にぐぐってみつけていた記事。

ブックマーク等は元記事へお願いします

http://d.hatena.ne.jp/okinaka/20090727/1248671860

追記:

コードはリンク先を参照して下さい。メモとして書いていましたが申し訳ないのでコメントアウトしました。

カーソル位置に文字を挿入したい場合に有効。

注意:
テキストエリアのみ有効!!テキストボックス内では挿入されない。