Przejdź do głównej treści

Dodanie przycisku typu menu na pasku zadań (toolbar) w module/dialogu

Ready_™ Developer TeamMniej niż 1 minuta

Wprowadzenie

Na platformie Ready_™ istnieje możliwość definiowania własnych przycisków typu menu na pasku zadań (toolbarze) zwanych dalej jako CustomWidget.

Zdarza się czasami, że liczba opcji dla danego modułu jest na tyle duża (7+), że nie mieści się na pasku zadań. Dobrą opcją jest grupowanie bezpośrednio w pliku CustomModule.xml, jednak co w przypadku jak menu chcemy wydrukować w standardowym module. Z pomocą przychodzi opcja, która obejmuje oba te przypadki. Aby z niej skorzystać, należy zdefiniować następujący custom widget.

Aby utworzyć swój własny CustomWidget należy:

  1. Wejść w Panel Sterowania
  2. Następnie przejść do Mechanizm CustomWidget,
Panel Sterowania z zaznaczoną opcją CW
Panel Sterowania z zaznaczoną opcją CW
  1. Następnie klikamy w lewym górnym rogu przycisk Nowy.
Dodawanie nowego custom wideta
Dodawanie nowego custom wideta
  1. W otwartym formularzu „Element CustomWidget” uzupełnij pola:
  • Nazwa – Wprowadź tekst, który będzie wyświetlany na przycisku (caption),
  • Typ – Dla obecnego przykładu, wybierz taką samą opcję jak na obrazku powyżej
  • Parametry - Wprowadź tekst w formie json-a, przykład
  • Miejsce - Należy wprowadzić wartość z miejsc użycia więcej informacji znajdziesz poniżej
  • Kliknij na przycisk ZAPISZ.

Miejsca użycia

Tabelka z danymi do wprowadzenia do pola w formularzu miejsca użycia
Miejsce użyciaOpisPrzykład
adocuments/toolbarW module Dokumentyprzykład
aisodocs/toolbarW module ISOprzykład
aregisters/toolbarW module Dziennikiprzykład
contacts/toolbarW module Klienciprzykład
cregisterview/toolbarWszystkie rejestryprzykład
cregisterview/toolbar::[{cregids}]Wszystkie rejestry, których identyfikatory zostały wymienione po przecinku zamiastprzykład
custom/{id_widgetu}Własne użycie np. w definicji przycisku xmlprzykład
document_{dctpid}/toolbarNa liście zadań w formatce dokumentuprzykład
document_products_form_{dctpid}/toolbarNa zakładce pozycje w dokumencie o wskazany typie (dctpid)przykład
custom_document_products_form_{dctpid}/toolbarNa zakładce pozycje w customowym dokumencie o wskazany typie (dctpid)przykład
document_del_summary_{dctpid}/toolbarLista rachunków na dokumencie delegacji
document_travelcosts_{dctpid}/toolbar Koszty delegacji
depository/toolbarW module Produktyprzykład
emails/toolbarW module Pocztaprzykład
employees/toolbarW module Pracownicyprzykład
processes/toolbarW module Sprawyprzykład
process_documents/toolbarNa zakładce dokumenty na kartotece Sprawyprzykład
process_products_form/toolbarNa zakładce pozycje na kartotece Sprawyprzykład
process_tasks_form/toolbarNa zakładce terminarz w kartotece Sprawyprzykład
product/toolbarNa kartotece produktuprzykład
servicemod/toolbarW module Serwisprzykład
task_TODO/toolbarDla formatki zdarzenia typu zadanieprzykład
task_MEETING/toolbarDla formatki zdarzenia typu spotkanieprzykład
task_PHONECALL/toolbarDla formatki zdarzenia typu rozmowa telefonicznaprzykład
task_EVENT/toolbarDla formatki zdarzenia typu terminprzykład
vatnote_costs_list_form/toolbarNa zakładce koszty w dokumencie fakturyprzykład

Przykład tablicy JSON do pola Parametry

{
  "script": "CustomJSMenu.inc",
  "image": "24x24/menu-24.png"
}

Objaśnienia kluczy:

  • script - nazwa pliku z katalogu public_html/apps/edokumenty/scripts ,
    pliki mogą być zgrupowane w foldery, lecz wtedy w scripts należy podać dodatkowo ścieżkę. więcej informacji
  • image - nazwa ikony z katalogu public_html/framework/img/toolbarIcons/24x24/ lub public_html/apps/edokumenty/var/img/icons/24x24/.
    Nazwa ikony musi być poprzedzona 24x24/nazwa.rozszerzenie
    Ikona musi mieć rozmiar 24px x 24px

Tworzenie skryptu

Podczas tworzenia skryptu należy trzymać się następujących zasad:

  • plik musi być o rozszerzeniu inc
  • plik musi zawierać klasę o takiej samej nazwie jak nazwa pliku, bez rozszerzenia
  • plik na końcu musi zawierać sekcję inicjacji klasy, gdy istnieje zmienna $args
  • zapisany kod musi być w języku PHP obsługiwany zarówno dla wersji 7.4 i 8.0
  • plik należy umieścić w następującej lokalizacji: public_html/apps/edokumenty/scripts. Plik może znajdować się w katalogu, który również jest w tej lokalizacji.

Przykład

Poniżej w zakładce "Plik do pobrania" mamy już gotowy skrypt (należy go poprzednio wypakować z archiwum ZIP), który umieszczamy w następującej lokalizacji: public_html/apps/edokumenty/scripts

Następnie w systemie dodajemy nowy CustomWidget, gdzie następująco wypełniamy pola:

  • Nazwa: Hello CustomWidgetMenu
  • Typ: przycisk otwierający menu
  • Parametry:
{
    "script": "CustomJSMenu.inc",
    "image": "24x24/menu-24.png"
}
  • Miejsce użycia: adocuments/toolbar

Listing przykładowej klasy

Kod
<?php

/**
 * CustomJSMenu jako custom widget
 */
final class CustomJSMenu {
    /**
     * @var string[]
     */
    // opisane w ptk. 1.
    private static $cMethods = [
        'execute'
    ];

    /**
     * @return string[]
     */
    public function getCallableMethods() {
        return self::$cMethods;
    }

    /**
     * @param $params
     * @return string|true
     */
    // opisane w ptk. 2.
    public function execute($params) {
        $pData = JSON::toArray($params);

        return print_r($pData, TRUE);
    }

    /**
     * @param $args
     * @return bool
     */
    // opisane w ptk. 3.
    public static function init($args) {
        if (!isset($args['menu']) || !$args['menu'] instanceof JSMenu) {
            return FALSE;
        }
        // opisane w ptk. 3.1.
        $HWND = App::registerClass('./scripts/CustomJSMenu.inc', __CLASS__);

        // menu drugiego poziomu
        $newSubMenu = new JSMenu($args['menu']->name.'newSubMenu');
        $newSubMenu->width = 260;
        $newSubMenu->addItem('document', Translator::translate('Nowy dokument'), NULL, 'on', TRUE);
        $newSubMenu->addItem('report', Translator::translate('Nowy raport'), NULL, 'on', TRUE);
        $newSubMenu->onChange = '(value) => {alert(value);}';

        $args['menu']->addItem('new', Translator::translate('Nowy'), NULL, 'on', TRUE, $newSubMenu);
        $args['menu']->addItem('edit', Translator::translate('Edycja)'), NULL, 'on', TRUE);
        $args['menu']->onChange = '(value) => {
                let params = '.(isset($args['params']) ? $args['params'] : '\'{}\'').'.parseJSON();
                let keyval = (typeof params[\'keyval\'] !== \'undefined\') ? params[\'keyval\'] : [];
                let js_after = (typeof params[\'js_after\'] !== \'undefined\') ? params[\'js_after\'] : () => {};                

                if (value === \'new\') {
                    // opisane w ptk. 3.2.
                    $A1(\''.$HWND.'\', null, '.(int)array_search('execute', self::$cMethods).', ({contid:keyval, js_after:js_after}).toJSONString(), \'alert(text);\');
                }
                
                if (value === \'edit\') {
                    // moze byc wiele zaznaczonych -> edytuj tylko pierwszego klienta
                    if (keyval.length) {
                        App.openDialogByCls(\'CONTACT_EDIT\', keyval.shift());
                    } else {
                        WidgetException(null, \'Wybierz klienta z listy\');
                    }
                }                
            }';
    }
}

// Wymagane, aby uruchomić skrypt
// W zmiennej $args, są to parametry w formie JSON lub ARRAY, przesłane z pola Parametry i obiektu, na którym dodany jest przycisk
CustomJSMenu::init($args);

Objaśnienie przykładu

  1. Parametr $cMethods
private static $cMethods = [
    'execute'
];

Parametr przechowuje listę dostępnych medot, które możemy wyołać poprzez JavaScript przez funkcje $A11. Ów listę możęmy w łatwy sposób przeszukać poprzez użycie array_search, np.

array_search('execute', self::$cMethods)
  1. Metoda execute W ów metodzie, możemy zawżeć całą logikę biznesową. Np. sprawdzić prawa i wyrenderować do html-a cały formularz

By móc użyć zwracanych danych (różnego typu) w wywołaniu poprzez $A1 z ów metody Metoda zwraca stringa, który później będzie użyty w $A1

public function execute($params) {
    $pData = JSON::toArray($params);

    return print_r($pData, TRUE);
}
  1. Metoda statyczna init,

Ta metoda musi być statyczna, gdyż po za ciałem klasy musimy ją wywołać poprzez:

CustomJSMenu::init($args);

a to wszystko po to by, framework załadował ów klase i odrazu wywołał interesującą nas metodę.

3.1. $HWND - złapanie uchwytu, na daną klasę, potrzebny dla js-owej metody $A1

$HWND = App::registerClass('./scripts/CustomJSMenu.inc', __CLASS__);

3.2. $A1 - Jest to ajaxowe wywołanie

$A1(\''.$HWND.'\', null, '.(int)array_search('execute', self::$cMethods).', ({contid:keyval, js_after:js_after}).toJSONString(), \'alert(text);\');

Parametr nr 1. - parametr HWND czyli nasz uchwyt na daną klasę,

Parametr nr 2. - w przykładzie podaliśmy wartość null, ale możemy w prost podać nazwę elementu, np. pola typu input, bądz panelu

Parametr nr 3. - id metody execute w tablicy self::$cMethods,

Parametr 4. - są to parametry do metody execute w formie JSON-a, np.

{
  contid: keyval,
  js_after: js_after
}

Parametr 5. - są to dane zwrócone z metody execute i wrzucone dla przykładu w js-owy alert,

alert(text);

Możemy tutaj zastosować funkcje, która sprawdzi czy otrzymaliśmy callbacka i dane włoży w znaleziony element, np.

function(text){$(\''.$this->name.'rp\').innerHTML = text;}

Efekt końcowy

W ten oto sposób możemy się cieszyć własnym przyciskiem typu menu na pasku zadań w module Dokumenty.

@todo dodać zdjęcie menu