いいね!数

0

閲覧数
386

あるXPageの中に組み込んであるクライアントサイドJavaScript(CSJS)を、可読性をよくしようとライブラリ化すると挙動が変わってしまいました。

私の認識だと、ページ内に直接書いても、ライブラリ化しても、同じようなものだと思ってました。

ライブラリ化しかのはDojo関係なんですが、もしかして、Dojo特有の制限事項みたいなものがあるのでしょうか。

 

以下のページの最後の方にある「Download Demo Database」と書いてあるリンクからサンプルをダウンロードします。

http://www.pipalia.co.uk/xpages-2/implementing-dojo-drag-and-drop-in-xpages/

このサンプル中にxDragDropというXPageがあり、ソースを見ると、以下のように<xp:scriptBlock>でCSJSが組み込まれてます。

このサンプルで、表のアイテムをゴミ箱アイコンにドラッグ&ドロップすると、targetDrop()が実行されました(あるべき動作)。

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" dojoTheme="true">
    <xp:this.data>
        <xp:dominoView var="view1" viewName="ByName"></xp:dominoView>
    </xp:this.data>
    <xp:this.resources>
        <xp:dojoModule name="dojo.dnd.Source"></xp:dojoModule>
        <xp:styleSheet href="/.ibmxspres/dojoroot/dojo/resources/dnd.css"></xp:styleSheet>
        <xp:styleSheet href="/dragndrop.css"></xp:styleSheet>
    </xp:this.resources>
    <xp:scriptBlock>
        <xp:this.value><![CDATA[
XSP.addOnLoad(init);
var divTrash;

function init() {
    console.log("init");
    divTrash = new dojo.dnd.Target("#{id:divTrash}");
    dojo.connect(divTrash, "onDndDrop", targetDrop); // Connect the onDndDrop event to target
}

function targetDrop(source, nodes, copy, target) {
    console.log("targetDrop");
    // To verify that this is the right handler for drop event
    if (dojo.dnd.manager().target !== this) {

   ..... 省略....

    this._partialRefresh("post", form, refreshId, options);
}
]]></xp:this.value>
    </xp:scriptBlock>

    <xp:eventHandler event="deleteDocs" id="ehDeleteDocs" refreshMode="partial" refreshId="dataTable" submit="false">
        <xp:this.action><![CDATA[#{javascript:
          var doc:NotesDocument;

... 省略...

 

 

 

ソースコードの見通しをよくしようと思い、<xp:scriptBlock>内のCSJSをdragDrop.jsという名前を付けたライブラリに外だししてみました。

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" dojoTheme="true">
    <xp:this.data>
        <xp:dominoView var="view1" viewName="ByName"></xp:dominoView>
    </xp:this.data>
    <xp:this.resources>
        <xp:dojoModule name="dojo.dnd.Source"></xp:dojoModule>
        <xp:styleSheet
            href="/.ibmxspres/dojoroot/dojo/resources/dnd.css">
        </xp:styleSheet>
        <xp:styleSheet href="/dragndrop.css"></xp:styleSheet>
        <xp:script src="/dragDrop.js" clientSide="true"></xp:script>
    </xp:this.resources>

    <xp:eventHandler event="deleteDocs" id="ehDeleteDocs" refreshMode="partial" refreshId="dataTable" submit="false">
        <xp:this.action><![CDATA[#{javascript:
          var doc:NotesDocument;

... 省略...

dragDrop.jsはこんな感じです。単純に <xp:scriptBlock>に組み込まれてたCSJSを抜き出しただけです。

XSP.addOnLoad(init);
var divTrash;

function init() {
    console.log("init");
    divTrash = new dojo.dnd.Target("#{id:divTrash}");
    dojo.connect(divTrash, "onDndDrop", targetDrop); // Connect the onDndDrop event to target
}

function targetDrop(source, nodes, copy, target) {
    console.log("targetDrop");
    // To verify that this is the right handler for drop event
    if (dojo.dnd.manager().target !== this) {

   ..... 省略....

    this._partialRefresh("post", form, refreshId, options);
}

 

これだけなら挙動か変わらないと思ったのですが、今度は表のアイテムをゴミ箱アイコンにドラッグ&ドロップしても、targetDrop()に処理が流れてきません(ブラウザのデバッグコンソールに'targetDrop'が表示されない)。

ただ、ブラウザのデバッグコンソールを見る限りは、init()は実行されているようです。

 

 

サーバー情報: | クライアント情報: | 
カテゴリ:アプリ開発 - XPages | タグ:
  | 質問日時:Feb 8, 2015, 5:13:01 PM

回答・コメント

いいね!数

0

はずしていたら申し訳ありません。

コード自体に問題無いと仮定して。。。

アプリケーションプロパティの「実行時最適化 JavaScript とCSS リソース」にチェックが入っていると JavaScript が圧縮されてるのですが、たまに他のフレームワークを使用するとき、たまにJSライブラリを変な(?)風に圧縮するので期待通りの動きをしないことがあります。このオプションがチェックされている(デフォルトはオン)のであれば、オフにしたらどうなるでしょうか?

回答日時:Feb 8, 2015, 6:16:37 PM

いいね!数

3

xp:scriptBlock 内にある #{id:divTrash} というシンタックスはXPagesファイル内でなければ正常に動作しません。

サンプルのコードを見るとざっと以下のシンタックスがCSJSに埋め込まれていました。

#{id:divTrash}
#{id:trashIcon}
#{id:ehDeleteDocs}
#{id:dataTable}

CSJSをライブラリ化する場合、これらのシンタックスをXPages側でグローバル変数として一度格納してやるなどすれば、希望どおりの実装が可能です。

以下、例になります。

----------------------------------------------------------------------------------------------------------------

    <xp:scriptBlock>
        <xp:this.value><![CDATA[var divTrashId = "#{id:divTrash}";
var trashIconId = "#{id:trashIcon}";
var ehDeleteDocsId = "#{id:ehDeleteDocs}";
var dataTableId = "#{id:dataTable}";
        ]]></xp:this.value>
    </xp:scriptBlock>

----------------------------------------------------------------------------------------------------------------

CSJS側、

----------------------------------------------------------------------------------------------------------------

XSP.addOnLoad(init);

var divTrash;

function init() {
    console.log("init");
    divTrash = new dojo.dnd.Target(divTrashId);
    dojo.connect(divTrash, "onDndDrop", targetDrop); // Connect the onDndDrop event to target
}

function targetDrop(source, nodes, copy, target) {
    console.log("targetDrop");
   ..... 省略....
    var propsEnlarge = {
        width: {start: "80", end: "94", unit: "px"},
        height: {start: "80", end: "94", unit: "px"}
    };
    dojo.anim(trashIconId, propsShrink, 250);
    dojo.anim(trashIconId, propsEnlarge, 250);

    // Get all the note IDs and put them in an array
    var notesIDs = new Array();
    dojo.forEach(nodes, function (node, i) {
        notesIDs.push(dojo.attr(node, "noteid"));
    });

    XSP.executeOnServer(ehDeleteDocsId, // Event handler to be executed
            dataTableId,  // Data table to be partially refreshed
        {}, // onStart, onError and onComplete events
        notesIDs.join(",") // Value to be submitted so that SSJS code can process it
    );
}

XSP.executeOnServer = function () {
   ..... 省略....
}

回答日時:Feb 8, 2015, 7:41:56 PM

いいね!数

0

katomanさん、kazutさん、回答ありがとうございます。

> たまにJSライブラリを変な(?)風に圧縮するので期待通りの動きをしないことがあります

今回はこれではありませんでしたが、こういうトラブル元があるというのは覚えておきます。

 

> xp:scriptBlock 内にある #{id:divTrash} というシンタックスはXPagesファイル内でなければ正常に動作しません。

なるほど! 教えてもらった方法でうまく動作しました。

<xp:scriptBlock>の中に組み込まれているうちは、#{id:xxxx}が使えるが、CSJSライブラリに外だしするときは、変換されずにブラウザに引き渡されるので、うまくいかなかったということですね。

これまでSSJSばかり扱ってきたので、このあたりの注意点をうまく理解できてませんでした。

回答日時:Feb 9, 2015, 7:09:41 AM