タグ ‘Tips’ 一覧
ExtJS入門22 グリッドのイベント処理(ダブルクリック、右クリック)
前回はツールバーでグリッドの情報を取得し、ポップアップで表示しました。今回はグリッドのダブルクリックと右クリックのイベントで詳細を表示する処理を実行します。
グリッドのダブルクリックと右クリック(コンテクストメニュー)で処理を実装することで、より直感的なグリッドの操作が可能になります。
サンプルは前回のExJS入門21 グリッド・セレクション・モデルをベースにイベントの処理を追加しています。
グリッドパネル関連の過去の記事はこちらからです。
- ExtJSで楽しくRIA業務アプリ開発 ExJS入門17 グリッド・パネル 基本編
- ExtJSで楽しくRIA業務アプリ開発 ExtJS入門18 グリッド レンダラーを使ってデザインを変える
- ExtJS入門19 グリッドにページング機能を追加する
- ExtJS入門20 グリッドにフィルタリング機能を追加する
- ExtJS入門21 グリッド・セレクション・モデル
リファレンスはこちらから
今回はExt.menu.Menuクラスを右クリックに仕込んでいます。
ExtJS -3.0 日本語APIドキュメント – Ext.grid.GridPanelクラス
http://extdocs.xenophy.com/?class=Ext.grid.GridPanel
ExtJS -3.0 日本語APIドキュメント – Ext.menu.Menuクラス
http://extdocs.xenophy.com/?class=Ext.menu.Menu
ExJS入門21 グリッド・セレクション・モデル
グリッド関連4回目は、セレクションモデルを設定して、行の選択状態を取得する簡単なサンプルです。
ExtJSのグリッドの様々なセレクションモデルを設定して、行の選択の仕方を指定します。今回は一番基本となる、単一の行を選択するセレクションモデルを設定して、その行の情報を取り出すようにします。以前に紹介したグリッドのサンプルではセレクションモデルが明示的に設定されていないためグリッドのデフォルトのセレクションモデルが自動的に設定されていました。実際に試してもらうと分かりやすいのですが、Ctrlもしくはcommandキーを押しながらクリックすると複数選択ができます。
今回のサンプルではセレクションモデルを独自に設定して、一行だけを選択するようにします。
ExtJS入門 Ext.XTemplateの補足
Ext.XTemplateの補足というか真髄の機能にテンプレート内でforやifによる制御ができる点です。
Ext.XTempalteでは、テンプレートにセットするデータの値によって処理を分岐したり、配列の値をループで取り出すことができます。
サンプルではダミーのデータ(data)をオブジェクトで用意して、その内容に対してテンプレート側で制御をしながらHTMLを構築しています。
ExtJS入門 DomHelperの使い方3 位置指定の追加と削除
DomHelperで要素を追加するの追加項目です。
DomHelperで要素の追加を行うときappendでは対象の要素の子の要素として要素を追加しましたが、insertBefore,insertAfterでは対象の要素の前後に要素を追加します。
今回はあえてパネルを使わずにやってみます。
DomHelperについてはこちらにサンプルがあります。
ExtJS Tips FirefoxでExtJSとブラウザのコンテストメニューが重なるときの対応方法
今回は備忘録も兼ねてFireFoxのコンテクストメニュー(右クリックメニュー)とExtJSで設定したコンテクストメニューが重なる場合の対処方法の紹介です。
グリッドなどで独自のコンテクストメニューを作成したときに、ブラウザのメニューを出さないようにキャンセルさせるには、以下のようにコンテクストメニューのイベントでe.stopEvent();を実行します。
/**
* コンテクストメニューを生成
*/
onContextClick: function(grid, index, e)
{
・・・
e.stopEvent();
grid.contextMenu.showAt(e.getXY());
・・・
}
通常はこれでブラウザのコンテクストメニューはキャンセルされて表示されません。
しかしFirefoxでは、まれに以下のようにブラウザのメニューが表示されてしまい、Extのメニューを覆ってしまいます。
この動作はJavaScriptのコードバグではなく、ブラウザのJavaScriptの実行設定が原因のようです。
ブラウザのJavaScriptの実行設定を変更します。
Firefox > ツール > オプション > コンテンツ > JavaScriptを有効にする > 詳細設定 > コンテキストメニューを無効化または変更する にチェックを入れる
これでExtのコンテキストメニューだけが表示されるようになります。
JavaScriptのセキュリティを強化しているFirefoxでよく見かけるので、特定のFirefoxだけおかしい場合に疑ってみてください。
ExtJS入門17 グリッド・パネル 基本編
いよいよグリッド・パネルをサンプルをやっていこうと思います。
まず基本として、ごくシンプルなグリッドパネルを作成します。
グリッド関連APIリファレンスはこちらから
ExtJS -3.0 日本語APIドキュメント – Ext.grid.GridPanel
http://extdocs.xenophy.com/?class=Ext.grid.GridPanel
ExtJS -3.0 日本語APIドキュメント – Ext.data.JsonStore
http://extdocs.xenophy.com/?class=Ext.data.JsonStore
ExtJS -3.0 日本語APIドキュメント – Ext.grid.ColumnModel
http://extdocs.xenophy.com/?class=Ext.grid.ColumnModel
グリッドパネルについて
グリッドパネルはスプレッドシートのような表を作るウィジェットで様々なデータを一覧表示させるのに便利です。ExtJSではExt.grid.GridPanelやExt.grid.EditorGridなどが用意されており、高機能なグリッドを作成することができます。
グリッドパネルの作るために必要な要素はデータソースと表示列(カラム)の設定です。
データソースはExtJSではストア(store)と呼ばれます。ストアはJSONやXML等のデータをExtJS内で保持するためのかたちです。
ストアに渡すデータはローカル変数でもリモートのAPIでも構いません。JsonStoreやXmlStoreを使えば簡単にJSON形式、XML形式のデータをストア格納できます。
表示列の設定は、ストアに格納しているデータをどのようなカラムでグリッドに表示するかを設定します。Ext.grid.ColumnModelクラスを使います。
簡単なグリッドであれば以上の2つをグリッドクラスのコンフィグに設定するだけで、あとはGridクラスがすべてやってくれます。
早速サンプルを紹介します。
ExtJS入門15 DataViewの使い方
テンプレートの関連のクラスとしてもう一つ、Ext.DataViewクラスがあります。
DataViewはStoreに保持しているデータをページに表示できる形式でアウトプットしてくれるクラスです。
Ext.DataViewでは、BoxComponentが帰ってきます。
Ext.ListView
ExtJS -3.0 日本語APIドキュメント – Ext.DataView
http://extdocs.xenophy.com/?class=Ext.DataView
DataViewではストアに登録されているデータをシンプルに表示させるのに使います。
以下がサンプルコードです。
・HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ExtJS名古屋勉強会 DataViewの使い方</title>
<!--Ext JS CSS-->
<link rel="stylesheet" href="../js/ext/resources/css/ext-all.css" type="text/css" />
<!--Ext JS-->
<script type="text/javascript" src="../js/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../js/ext/ext-all.js"></script>
<script type="text/javascript" src="dataview-paul.js"></script>
</head>
<body>
<div class="body">
</div>
</body>
</html>
今回はJS側でテンプレートを生成するんので、ほとんど何もありません。
・JS
Ext.onReady(function(){
var calcData = function() {
var data = [];
var item = {}
for (var i =0; i < 50; i++) {
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
item = {
id:i,
rgb:String.format('rgb({0},{1},{2})', r, g, b)
};
data[i] = item;
}
return data;
};
var initData = calcData();
var store = new Ext.data.JsonStore({
autoLoad:true,
data:initData,
fields:['id','rgb']
});
//XTemplate.fromだとstyleに値を設定できない(Firefox)
var dataViewTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="paul">',
'<div>',
'<div style="background:{rgb};width:100%;height:15px;color:#EEE; font-size:small;">',
'<div>',
'</div>',
'</div>',
'</tpl>'
);
new Ext.Panel({
renderTo:Ext.getBody(),
id:'myPanel',
title:'DataViewでカラーバーを表示',
bodyStyle:{
'text-align':'center'
},
items:{
xtype:'dataview',
tpl:dataViewTpl,
store: store,
autoHeight:true,
itemSelector:'div.paul'
},
buttonAlign:'center',
buttons:[{
scale:'large',
text:'New Color!',
handler:function(){
var newData = calcData();
store.loadData(newData);
}
}]
});
});
まずストアを用意して、データを設定します。今回はJava Scriptでデータを生成していますが、urlでJSONを取得することもできます。
今回はランダムな色を生成してJsonStoreに保持します。アップデートボタンをつけてJsonStoreの値を変更するため関数を作っておきます。
dataViewはそのままではBoxComponentですので、パネルのアイテムとして設定します。これで階層が少し深くなりますが、パネルの機能が使えるようになります。
・実行結果
ランダムに生成された色の値をdivに設定して表示します。ボタンをクリックして内容を更新することができます。なんちゃって横ポールスミスみたいな画面です。
XTemplateなどでは、毎回overwriteメソッドのように上書きを自分で指定していましたが、DataViewの場合はStoreの内容が更新されると自動的に再描画されます。
ストアの内容をさっと表示したい場所では便利です。また外部にAPIを持っていて、頻繁に更新するような場合もDataViewの方が簡単に表示を更新できます。
さらにストアの内容を簡易のグリッドとして表示するExt.ListViewクラスもあります。
ExtJS入門16 ListViewの使い方
http://extjs.blog.sus4.co.jp/2010/01/27/extjs-tutorial16/
ExtJS入門13 Ext.DomHelperの使い方
ExtJSでDOMを操作するときはExt.DomHelperを使うと便利です。
Ext.DomHelper – Ext 3.0 – API Documentation 日本語版
http://extdocs.xenophy.com/?class=Ext.DomHelper
詳しい解説はAPIドキュメントを見ていただくとして、ここでは使い方に重点をまとめてみます。
注意点としてはExt.DomHelperクラスはシングルトンであることです。
そのため直接インスタンスを生成してはいけません。newせずに直接メソッドを呼んであげます。
では実際の使い方です。
使い方
DomHelperクラスを起動して、メソッドを指定します。
構築するDOMのオブジェクトを渡す。
サンプルコード1
・html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ExtJS名古屋勉強会 DomHelperのサンプル1</title>
<!--Ext JS CSS-->
<link rel="stylesheet" href="../js/ext/resources/css/ext-all.css" type="text/css" />
<!--Ext JS-->
<script type="text/javascript" src="../js/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../js/ext/ext-all.js"></script>
<script type="text/javascript" src="domhelper-sample1.js"></script>
</head>
<body>
<div class="body">
</div>
</body>
</html>
・javascript
Ext.onReady(function(){
var appendDom = function() {
console.debug('dom');
Ext.DomHelper.append('my-div',{
id:'url-list',
tag:'ul',
cn:[
{
tag:'li',
cn:[{
tag:'a',
html:'google',
href:'http://www.google.com'
}]
},{
//targetが追加されているa要素
tag:'li',
cn:[{
tag:'a',
html:'yahoo',
href:'http://www.yahoo.com',
target:'_blank'
}]
}
]
});
}
new Ext.Panel({
renderTo:Ext.getBody(),
id:'myPanel',
title:'DOMHelperで要素を追加する',
//パネルの内容
bodyStyle:{
padding:'15px',
'text-align':'center'
},
html: '<div id="my-div">',//このdivをターゲットにする。
//ボタン設定
buttonAlign:'center',
buttons:[
{
text:'要素を追加',
handler:function(){
appendDom();
}
}
]
});
});
・実行結果
パネルのhtmlに設定されているdivが構築されると、listenersに設定されているappendDom関数でDOMHelperによるDOMの追加が行われています。Ext.DomHelperはシングルトンなのでnewせずに、そのままメソッドを呼びます。
appendメソッドはターゲットとなる要素にDOMを追加します。ターゲットとなる要素は要素のidで指定します。ここでは’my-div’という名前のdivが指定しています。
追加する要素はオブジェクトで設定します。
DomHelperに渡すオブジェクトの形式は以下用になっています
DomHelperエレメントオブジェクトの仕様
DomHelperエレメントオブジェクトは、エレメントを作成するときに使用します。 このオブジェクトは、次の4つの属性から成り立ちます。
tag :
タグ名
children : または cn
配列形式で、好きなだけ作成するエレメントを指定できます。 また、入れ子にすることで多階層のエレメントを構築することもできます。
cls :
class属性を指定します。
html :
エレメントに追加するinnerHTML形式の文字列を指定します。
APIドキュメントより
基本的には属性:設定値という指定方法です。html属性がinnerHTMLにあたります。
childrenまたはcnとして、その要素の子要素を設定します。
aタグのhref属性など、タグ別の属性値は href:url のように設定します。ここでは’yahoo’の方にだけtarget属性を設定しています。
tagの設定を省略するとdivとして生成されます。
サンプルのオブジェクトは以下のようになっています。
{
id:'url-list',
tag:'ul',
cn:[
{
tag:'li',
cn:[{
tag:'a',
html:'google',
href:'http://www.google.com'
}]
},{
//targetが追加されているa要素
tag:'li',
cn:[{
tag:'a',
html:'yahoo',
href:'http://www.yahoo.com',
target:'_blank'
}]
}
]
}
XTemplateはパネルの内容を一気に変更するのに向いており、DomHelperはパネル内の一部の要素を書き換えるのに向いています。
この二つのクラスをうまく使い分けることで、効率良くエレメントの操作が行えます。
ExtJS tips Htmleditorフィールドを必須項目にする
ExtJSのフォームフィールドにHtmleditorが有ります。このHtmleditorフィールドは文字通りTEXTの編集ができるリッチエディタのフィールド作ります。
このフィールドはExt.form.HtmlEditorクラスで定義されています。このクラスはExt.form.Fieldクラスを継承しています、同じサブクラスのExt.form.TextFieldにはallowBlankのコンフィグオプションがありますが、HtmlEditorクラスにはallowblankがないため必須項目にできません。
なんとなく頑張れば出来そうな気もしますが、他の人もきっとつまづいていそうなポイントだと思いフォーラムで解決方法を探してみると、簡単にみつかりました。
やり方はいくつかあるようですが、一番簡単そうなExt.form.HtmlEditorクラスをオーバーライドするを使ってみました。
Ext.form.HtmlEditorクラスをオーバーライドして必須にする
allowBlank:false, on html editor not working ? – Ext JS Forums
http://www.extjs.com/forum/showthread.php?t=37285より
コードはフォーラムのものそのままでは、エラーメッセージが英語なので、
日本語に変更しておきます。以下のコードでオーバーライドします。
Ext.override(Ext.form.HtmlEditor, {
markInvalid: function(msg){
if(!this.rendered || this.preventMark){
return;
}
msg = msg || this.invalidText;
switch(this.msgTarget){
case 'qtip':
this.iframe.qtip = msg;
this.iframe.qclass = 'x-form-invalid-tip';
Ext.get(this.iframe).addClass(this.invalidClass);
break;
}
return Ext.form.TextArea.superclass.markInvalid.call(this, [msg]);
},
clearInvalid: function(){
if(!this.rendered || this.preventMark){
return;
}
switch(this.msgTarget){
case 'qtip':
this.iframe.qtip = '';
Ext.get(this.iframe).removeClass(this.invalidClass);
break;
}
return Ext.form.TextArea.superclass.clearInvalid.call(this);
},
validateValue:function(){
if(this.allowBlank==false){
var value =this.getRawValue();
value = value.replace(/&amp;amp;nbsp;/gi,"");
value = value.replace(/<br>/gi,"");
value = value.trim();
if(value != ''){
this.clearInvalid();
return true;
}
else{
this.markInvalid("この項目は必須項目です。")
return false;
}
}else{
this.clearInvalid();
return true;
}
}
});
このコードをHtmlFieldを使うところに設定しておいてあげれば、allowBlank有効になります。
オーバーライドしたことによりHtmlEditorフィールドの妥当性チェックが有効になったので、送信ボタンをvalidationの状態と連動されることもできるようになります。
今回のフォームのようなよくありそうなつまづきポイントは、フォーラムに既に議論された解決方法が載っている場合がよくあります。本家のフォーラムは英語ではかなりの議論が行われているので、頑張って探してみると意外と良いものが転がっていたりします。
Ext本家のフォーラム(英語)
http://www.extjs.com/forum/
ExtJS入門11 Ext.XtemplateでJS内のテンプレートを使う
前回はExt.XTemplateクラスのfromメソッドでHTML内のファイルをテンプレートに使いましたが、今回はJavascriptのファイル内にテンプレートを書く方法を紹介します。
前回の記事
ExtJS入門10 Ext.XTemplateを使う
Ext.XTemplateクラス – Ext 3.0 – API Documentation 日本語版
http://extdocs.xenophy.com/?class=Ext.XTemplate
・HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ExtJS名古屋勉強会 xtemplateの使い方(Javascript内のテンプレート)</title>
<!--Ext JS CSS-->
<link rel="stylesheet" href="../js/ext/resources/css/ext-all.css" type="text/css" />
<!--Ext JS-->
<script type="text/javascript" src="../js/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../js/ext/ext-all.js"></script>
<!--my App JS-->
<script type="text/javascript" src="xtemplate-new.js"></script>
</head>
<body>
<h1 style="background-color:#BDD3EF;">JS内のテンプレートを使ったXTempalte</h1>
<div id="tpl-target">
</div>
</body>
</html>
・Javascript
Ext.onReady(function(){
var data = {
name:'株式会社sus4',
url:'http://www.sus4.co.jp',
};
/**
* テンプレート
* 中括弧でdataオブジェクトのプロパティ名を指定する。
* js内の文字列でテンプレートを指定する場合は,
* new Ext.XTemplate(テンプレート文字列)とする。newしないとエラーになります。
* カンマで区切ることで複数行に渡ってテンプレート文字列を書くことができます。
* 最後にカンマがつくとエラーになります。
*/
var tpl = new Ext.XTemplate(
'<h2>リンクを作る</h2>',
'<a href="{url}">{name}</a>',
'<h2>テーブルを作る</h2>',
'<table>',
'<tr>',
'<th style="padding:3px;">{name}:</th><td>{url}</td>',
'</tr>',
'</table>'
);
//htmlファイルに作った要素のIDを指定
var tplHtml = tpl.apply(data);
var panel = new Ext.Panel({
renderTo:'tpl-target',
title:'テンプレートを使ったパネル',
bodyStyle:'padding:20px',
html:tplHtml
});
});
・実行結果
Ext.XTemplateのテンプレートはJavascript内に記述しています。
var tpl = new Ext.XTemplate(
'<h2>リンクを作る</h2>',
'<a href="{url}">{name}</a>',
'<h2>テーブルを作る</h2>',
'<table>',
'<tr>',
'<th style="padding:3px;">{name}:</th><td>{url}</td>',
'</tr>',
'</table>'
);
文字列でテンプレートとなるHTMLを記述しています。テンプレート文字列が長くなって改行する場合は一旦文字列を区切って「,」(カンマ)で新しい文字列を連結して書いていきます。
例:
new Ext.XTemplate( '文字列', ’文字列’ );
文字列を区切らずそのまま改行するとエラーになります。連結した最後の文字列のあとにカンマがついてもダメです。
データの設定する箇所は「{}」(中括弧)でデータオブジェクトのプロパティ名を指定します。
HTMLファイルにテンプレートを記述する、Ext.XTemplate.from()ではnewしていませんでしたが、JSファイル内に文字列としてテンプレートを記述して使う場合はnewしなければいけません。Ext.XTemaplate.from()メソッドを使うとHTMLに描いた文字列からテンプレートオブジェクトを生成して返しているためnewしなくても良かったのですが、今回は自分できちんとnewして文字列からテンプレートオブジェクトを生成します。
あとはExt.XTemplate.fromと同じようにapplyでデータの設定して、パネルの要素に設定しています。









