Si vous avez déjà travaillé avec des listes universelles dans Bitrix24, vous savez probablement que la page de détail d'un élément est complètement identique à la page d'édition. La seule différence est que si l'utilisateur dispose de droits en lecture seule, la page n'aura pas de boutons Enregistrer et Appliquer. D'accord, pas l'interface la plus agréable.
Et donc, quand au travail il est devenu nécessaire d'utiliser des listes universelles, j'ai décidé de changer la page de vue détaillée, car nous utilisons une boîte, et les possibilités de personnalisation sont tout simplement illimitées.
24 , , , .
local , . .
— DOM- Javascript.
En fait, il suffit de changer le lien vers la page détaillée dans le tableau de liste:
Cependant, en réalité, ce n'est pas si facile à mettre en œuvre, car vous devez aller dans le composant responsable de l'affichage des listes universelles et y éditer le lien.
Par conséquent, nous prendrons un chemin différent - via Javascript, nous ouvrirons la page dans le curseur en utilisant la bibliothèque bitrix SidePanel.
Il y a deux façons de faire cela - dans init.php et dans votre propre module. Vous devez également enregistrer votre bibliothèque JS.
Et bien que la deuxième méthode soit plus pratique, je vais vous montrer la première, et à la fin de l'article je donnerai un lien vers mon module.
Alors allons-y. Toutes les actions doivent être effectuées dans le dossier local.
Vous devez d'abord créer un dossier séparé dans lequel notre bibliothèque sera stockée. Appelons-le, par exemple, visualiseur, et il aura la structure suivante:
/viewer
-/js
--viewer.js // js-
-include.php // , init.php
Arrêtons-nous un peu ici. Pour le code php, j'ai créé un fichier séparé, que je vais ensuite inclure dans init.php afin de ne pas gâcher ce dernier.
Enregistrons maintenant notre bibliothèque en utilisant l'ancienne méthode CJSCore :: RegisterExt :
// include.php
// .. js- viewer,
CJSCore::RegisterExt('elementviewer', [
'js' => '/local/viewer/js/viewer.js', //
'rel' => ['SidePanel'] //
]);
Il ne reste plus qu'à connecter cette bibliothèque sur la page des listes universelles avec la méthode CJSCore :: Init , et, semble-t-il, c'est dans le sac - vous pouvez commencer à écrire la bibliothèque elle-même.
Cependant, tout n'est pas si simple, car avant de vous connecter, vous devez vérifier que nous sommes sur la bonne page. Il est préférable de le faire en utilisant des expressions régulières, car l'identifiant de la liste dans l'adresse peut changer
// include.php
$pattern = '/\/lists\/(\d+)\/view\//'; // , (\d+) = id
$server = Bitrix\Main\Context::getCurrent()->getServer(); // Server,
if(preg_match($pattern, $server->getRequestUri())) {
CJSCore::Init(['elementviewer']); //
}
Donc, la bibliothèque est connectée, il reste à l'écrire. Pour ce faire, créez un fichier viewer.js (si vous ne l'avez pas créé auparavant) et tout d'abord nous déclarons un espace de noms à l'aide de la fonction BX.namespace :
const ElementViewer = BX.namespace('Viewer');
Désormais, toutes les variables et fonctions peuvent être déclarées de la manière suivante:
ElementViewer.init = function() {
}
Afin de ne pas écrire tout le code dans une seule fonction, décomposons-le en plus petits pour plus de commodité.
La première chose à faire est de trouver le nœud sur la page qui contient le lien vers la page de détails. Pour ce faire, nous utiliserons la fonction BX.findChildren , qui devrait nous renvoyer une liste de tous les objets contenant des liens vers la page de détail:
ElementViewer.findCell = function () {
return BX.findChildren(document, {
class: 'main-grid-cell-content' // css-
}, true);
}
En même temps, nous écrirons une fonction qui extraira l'id de la liste et de l'élément du lien pour un travail ultérieur:
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])
};
}
}
Revenons à BX.findChildren. La particularité de cette fonction est qu'elle renvoie une liste de tous les objets avec la classe css spécifiée, et ce n'est pas un fait que ce sera un lien. Par conséquent, nous devons vérifier, et seulement après cela, annuler l'événement d'ouverture de lien et ouvrir le curseur:
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); //
})
}
}
});
}
Il nous reste à écrire la dernière fonction qui ouvrira le curseur. Pour ce faire, nous utilisons la bibliothèque 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
});
}
Bon, la librairie est écrite, il reste à appeler la fonction init après la connexion. Pour ce faire, revenons à include.php, où l'adresse de la page est vérifiée:
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);
}
La touche finale reste - pour inclure notre code dans init.php:
// init.php
$file = $_SERVER['DOCUMENT_ROOT'] . '/local/path/to/viewer/include.php';
if(file_exists($file)) {
require $file;
}
Si tout est fait correctement, alors lorsque vous cliquez sur un élément de la liste universelle, un curseur s'ouvre:
Enfin, comme promis, un lien vers un module qui implémente la même chose.
Merci de votre attention.