ボックス化されたBitrix24のユニバーサルリストアイテムの表示ページを変更する

こんにちは。



Bitrix24でユニバーサルリストを使用したことがある場合は、要素の詳細ページが編集ページと完全に同一であることをおそらくご存知でしょう。唯一の違いは、ユーザーが読み取り専用の権限を持っている場合、ページには[保存]ボタンと[適用]ボタンがないことです。同意します、最も快適なインターフェースではありません。







そのため、仕事でユニバーサルリストを使用する必要が生じたとき、ボックスを使用しており、カスタマイズの可能性は無限であるため、詳細ビューページを変更することにしました。







24 , , , .



local , . .



— DOM- Javascript.



実際、リストテーブルの詳細ページへのリンクを変更する必要があります。







ただし、実際には、これは実装がそれほど簡単ではありません。ユニバーサルリストの表示を担当するコンポーネントに移動し、そこでリンクを編集する必要があります。



したがって、別のパスを使用します。Javascriptを使用して、SidePanelbitrixライブラリを使用してスライダーでページを開きます。



これを行うには、init.phpと独自のモジュールの2つの方法があります。また、JSライブラリを登録する必要があります。



2番目の方法の方が便利ですが、最初の方法を紹介し、記事の最後にモジュールへのリンクを示します。



じゃ、行こう。すべてのアクションは、ローカルフォルダーで実行する必要があります。



まず、ライブラリを保存する別のフォルダを作成する必要があります。たとえば、ビューアと呼びましょう。次の構造になります。



/viewer 
-/js
--viewer.js //  js-
-include.php // ,      init.php


ここで少し立ち止まりましょう。phpコード用に、別のファイルを作成しました。このファイルをinit.phpに含めて、後者を散らかさないようにします。



古いコアCJSCore :: RegisterExtメソッドを使用してライブラリを登録しましょう



// include.php

// ..    js- viewer,     
CJSCore::RegisterExt('elementviewer', [ 
    'js' => '/local/viewer/js/viewer.js', //   
    'rel' => ['SidePanel'] // 
]);


CJSCore :: Init メソッドを使用してユニバーサルリストのページでこのライブラリを接続することだけが残っており、それは袋に入っているように見えます-ライブラリ自体を書き始めることができます。



ただし、すべてがそれほど単純なわけではありません。接続する前に、正しいページにいることを確認する必要があります。なぜなら、通常の式を使用してこれを行う方が良いからです。アドレス内のリストのIDは変更される可能性があります



// include.php

$pattern = '/\/lists\/(\d+)\/view\//'; //     ,  (\d+) = id 
$server = Bitrix\Main\Context::getCurrent()->getServer(); //  Server,     

if(preg_match($pattern, $server->getRequestUri())) {
       CJSCore::Init(['elementviewer']); //  
}


それで、ライブラリは接続されています、それを書くことは残っています。これを行うには、viewer.jsファイルを作成し(以前に作成したことがない場合)、まず、BX.namespace関数を使用して名前を宣言します



const ElementViewer = BX.namespace('Viewer');


これで、すべての変数と関数を次の方法で宣言できます。



ElementViewer.init = function() {

}


1つの関数にすべてのコードを記述しないように、便宜上、コードを小さなコードに分割してみましょう。



まず、詳細ページへのリンクを含むページ上のノードを見つける必要があります。これを行うには、BX.findChildren関数を使用します。これにより、詳細ページへのリンクを含むすべてのオブジェクトのリストが返されます。



ElementViewer.findCell = function () {
    return BX.findChildren(document, {
        class: 'main-grid-cell-content' // css-    
    }, true);
}


同時に、次の作業のために、リンクからリストと要素のIDを抽出する関数を記述します。



ElementViewer.pattern = '/lists/(\\d+)/element/0/(\\d+)'; //        ,    = id ,   = id .

ElementViewer.extractListData = function (url) {
    let match = url.match(this.pattern); //   
    if(match) {
        return {
            list_id: Number(match[1]),
            element_id: Number(match[2])
        };
    }
}


BX.findChildrenに戻りましょう。この関数の特徴は、指定されたcssクラスを持つすべてのオブジェクトのリストを返すことであり、これがリンクになることは事実ではありません。したがって、確認する必要があります。その後、リンクオープンイベントをキャンセルしてスライダーを開きます。



ElementViewer.init = function (sliderUrl) {

    const cell = this.findCell();

    cell.forEach(item => {

        let itemChild = item.children;
        let child = itemChild[0];

        if(child && child.tagName === 'A') {
            const listData = this.extractListData(child.toString()); //  id     

            if(listData !== undefined) {
                child.addEventListener('click', (e) => {
                    e.preventDefault(); //    
                    this.openSlider(sliderUrl, listData.list_id, listData.element_id); //  
                })
            }
        }
    });

}


スライダーを開く最後の関数を作成する必要があります。これを行うには、SidePanelライブラリを使用します



ElementViewer.openSlider = function (sliderUri, listId, elementId) {

//       POST,       id   
    let sliderParams = {
        list_id: listId,
        element_id: elementId
    }

    return BX.SidePanel.Instance.open(sliderUri, {
        allowChangeHistory: false,
        cacheable: false,
        requestMethod: 'POST',
        requestParams: sliderParams
    });
}


さて、ライブラリは書かれています、それは接続した後にinit関数を呼び出すために残っています。これを行うには、ページアドレスがチェックされるinclude.phpに戻りましょう。



if(preg_match($pattern, $server->getRequestUri())) {
       CJSCore::Init(['elementviewer']); //  
       $asset = Bitrix\Main\Page\Asset::getInstance();
       $script = '<script>BX.ready(function() {
  ElementViewer.init();
})</script>';
      $asset->addString($script);
}


最後の仕上げは残ります-init.phpにコードを含めるには:



// init.php

$file = $_SERVER['DOCUMENT_ROOT'] . '/local/path/to/viewer/include.php';

if(file_exists($file)) {
   require $file;
}


すべてが正しく行われると、ユニバーサルリストの要素をクリックすると、スライダーが開きます。











最後に、約束どおり、同じことを実装するモジュールへのリンクが表示されます



清聴ありがとうございました。



All Articles