Ändern der Seite zum Anzeigen des Elements universeller Listen in Bitrix24

Hallo.



Wenn Sie jemals mit universellen Listen in Bitrix24 gearbeitet haben, wissen Sie wahrscheinlich, dass die Detailseite eines Elements vollständig mit der Bearbeitungsseite identisch ist. Der einzige Unterschied besteht darin, dass die Seite nicht über die Schaltflächen Speichern und Übernehmen verfügt, wenn der Benutzer über schreibgeschützte Berechtigungen verfügt. Stimmen Sie zu, nicht die angenehmste Oberfläche.







Als es bei der Arbeit notwendig wurde, universelle Listen zu verwenden, habe ich beschlossen, die Detailansichtseite zu ändern, da wir eine Box verwenden und die Anpassungsmöglichkeiten einfach unbegrenzt sind.







24 , , , .



local , . .



— DOM- Javascript.



Tatsächlich müssen wir nur den Link zur detaillierten Seite in der Listentabelle ändern:







In der Realität ist dies jedoch nicht so einfach zu implementieren, da Sie müssen in die Komponente gehen, die für die Anzeige universeller Listen verantwortlich ist, und dort den Link bearbeiten.



Daher werden wir einen anderen Weg einschlagen - durch Javascript öffnen wir die Seite im Schieberegler mithilfe der SidePanel-Bitrix-Bibliothek.



Es gibt zwei Möglichkeiten, dies zu tun - in init.php und in Ihrem eigenen Modul. Sie müssen auch Ihre JS-Bibliothek registrieren.



Und obwohl die zweite Methode bequemer ist, zeige ich Ihnen die erste und gebe am Ende des Artikels einen Link zu meinem Modul.



So lass uns gehen. Alle Aktionen müssen im lokalen Ordner ausgeführt werden.



Zuerst müssen Sie einen separaten Ordner erstellen, in dem unsere Bibliothek gespeichert wird. Nennen wir es zum Beispiel Viewer, und es hat die folgende Struktur:



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


Lassen Sie uns hier ein wenig aufhören. Für den PHP-Code habe ich eine separate Datei erstellt, die ich dann in init.php aufnehmen werde, um letztere nicht zu verunreinigen.



Registrieren wir jetzt unsere Bibliothek mit der alten CJSCore :: RegisterExt-Kernmethode :



// include.php

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


Es bleibt nur, diese Bibliothek auf der Seite der universellen Listen mit der CJSCore :: Init- Methode zu verbinden , und es scheint, dass sie in der Tasche ist - Sie können mit dem Schreiben der Bibliothek selbst beginnen.



Allerdings ist da nicht alles so einfach Bevor Sie eine Verbindung herstellen, müssen Sie überprüfen, ob wir auf der richtigen Seite sind. Es ist besser, dies mit regulären Ausdrücken zu tun, da Die ID der Liste in der Adresse kann sich ändern



// include.php

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

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


Also, die Bibliothek ist verbunden, es bleibt zu schreiben. Erstellen Sie dazu eine viewer.js-Datei (falls Sie diese noch nicht erstellt haben) und deklarieren Sie zunächst einen Namespace mit der Funktion BX.namespace :



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


Jetzt können alle Variablen und Funktionen folgendermaßen deklariert werden:



ElementViewer.init = function() {

}


Um nicht den gesamten Code in einer Funktion zu schreiben, teilen wir ihn der Einfachheit halber in kleinere auf.



Als erstes müssen wir den Knoten auf der Seite finden, der den Link zur Detailseite enthält. Dazu verwenden wir die Funktion BX.findChildren , die uns eine Liste aller Objekte zurückgeben soll, die Links zur Detailseite enthalten:



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


Gleichzeitig schreiben wir eine Funktion, die die ID der Liste und des Elements für weitere Arbeiten aus dem Link extrahiert:



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])
        };
    }
}


Kehren wir zu BX.findChildren zurück. Die Besonderheit dieser Funktion besteht darin, dass sie eine Liste aller Objekte mit der angegebenen CSS-Klasse zurückgibt und es sich nicht um eine Verknüpfung handelt. Daher müssen wir überprüfen und erst danach das Ereignis zum Öffnen des Links abbrechen und den Schieberegler öffnen:



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); //  
                })
            }
        }
    });

}


Es bleibt uns überlassen, die letzte Funktion zu schreiben, die den Schieberegler öffnet. Dazu verwenden wir die SidePanel- Bibliothek :



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
    });
}


Nun, die Bibliothek ist geschrieben, es bleibt die init-Funktion nach dem Verbinden aufzurufen. Kehren wir dazu zu include.php zurück, wo die Seitenadresse überprüft wird:



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);
}


Der letzte Schliff bleibt - um unseren Code in init.php aufzunehmen:



// init.php

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

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


Wenn alles richtig gemacht wurde, wird beim Klicken auf das Element der universellen Liste ein Schieberegler geöffnet:











Schließlich, wie versprochen, ein Link zu einem Modul , das dasselbe implementiert.



Vielen Dank für Ihre Aufmerksamkeit.



All Articles