首頁  >  文章  >  後端開發  >  在 Joomla 中使用模態選擇範例建立自訂表單欄位類型

在 Joomla 中使用模態選擇範例建立自訂表單欄位類型

Susan Sarandon
Susan Sarandon原創
2024-11-17 10:18:03572瀏覽

使用 Joomla 5 中的 ModalSelect 表單欄位類型,可以在開發擴充功能時使用類別、製造商和搜尋在模式視窗中進行過濾,從而簡化從數千個產品中找到正確產品的流程。

簡介

在與客戶合作的過程中,會遇到各種程度的任務:有人需要一個 5-6 頁的簡單網站。有人需要大量的商品目錄或使用 REST API 與第三方系統整合的線上商店。其他人需要非標準功能,但沒有可用的流行解決方案。

Joomla 非常適合開發,並允許您創建易於維護的程式碼。如果需求遵循 CMS 核心,那麼它對所有這些情況都有答案。

要完成一個大項目,我們需要將其拆分為更小的任務,我想在本文中討論解決其中一個任務。

初始數據

客戶已經在 Joomla (JoomShopping) 線上商店的熱門組件之一上建立了產品目錄。他們可以選擇產品的參數,將其放入購物車並進行購買。一切如常。但是,現在您需要新增為產品建立圖形佈局的功能。例如,您的產品是杯子或 T 卹。在購買之前,您可以去找產品設計師,上傳您的徽標或照片,編寫文本,然後將此佈局附加到線上商店的訂單中。付款後,佈局直接進入生產,圖像和文字將被應用到您的杯子上並發送到地址。

由於此功能的實作非常耗時,因此將其建立為單獨的產品設計器元件。並且資料提供者外掛程式已經創建,允許您使用一個或另一個電子商務元件。

其中一個小的應用任務是在線上商店組件的商品和產品設計器組件中的商品之間建立連接。對於將來處理內容的內容管理者來說,這應該是方便且直覺的。因此,僅建立一個文字欄位來指示所需產品的 ID 號碼是不夠的。一個網路商店可能只有幾十種產品,那麼選擇一款產品來溝通並不是一件很困難的事。如果有數千種產品,則按參數搜尋和過濾產品的功能就很重要。如果您可以按類別、製造商過濾產品列表,或按名稱在數百個其他產品中尋找產品,您的工作將變得更快、更輕鬆。

Creating a custom Form field type in Joomla sing the Modal Select example
看影片

此欄位與編輯器按鈕插件(editors-xtd 群組)的工作非常相似,其中用於選擇的資料顯示在模式視窗中:文章的連結、模組的簡短程式碼等。

一點理論

在Joomla管理員面板中,有不同的欄位需要填入其他元件的資料:指定文章、選單項目、聯絡人、產品等。通常這些欄位被設計為選擇選項下拉列表,它們可以設計為帶有資料列表的輸入類型=“文字”,但也有方便的欄位顯示所需實體的列表,具有過濾、搜尋和分頁功能。不僅網站內的來源(各種元件、外掛程式)可以充當資料來源,還可以透過 REST API 提供第三方服務:CRM、交付服務、外部資料庫、其他 Joomla 網站等等。

當在選單項目中選擇文章(例如「文章- 單篇文章」、「聯絡人- 單一聯絡人」)或建立選單項目的別名- 「系統連結- 選單」時,我們都看過這些字段的作用項目別名」。不過,讓我們提醒自己它們是什麼樣子的。

模態文章選擇視窗。

Creating a custom Form field type in Joomla sing the Modal Select example
模式單一聯絡人選擇視窗。

Creating a custom Form field type in Joomla sing the Modal Select example

Joomla中模態選擇字段的機會

讓我們仔細看看這些欄位 - 它們到底允許您做什麼。在內心深處,我們知道該欄位的主要工作是取得所選實體的ID並將該ID放入文字段落。但在螢幕上我們看到了其他東西 - 我們看到的不是 ID 號,而是文章或聯絡人的標題。很好很方便。您不需要記住 ID 為 1452704 的文章的名稱。此外,影片清楚顯示,如果該欄位已經有值,則會出現「清除」按鈕。它會重置欄位的值並允許您再次點擊“選擇”按鈕。

Creating a custom Form field type in Joomla sing the Modal Select example

在某些情況下,我們有機會在建立選單項目的過程中建立選定類型的實體 - 文章、聯絡人等

。此按鈕的工作原理考慮了 ACL - Joomla 中的存取權限分離。

假設您正在建立一個網站並建立一個「聯絡人」頁面。如果您沒有一堆結構複雜的公司分支機構,那麼這只是「未分類」類別中常見的 Joomla 文章。它已經擁有文本或變數形式的所有聯絡人。在古代,您必須先建立文章,然後轉到選單項目並為其建立選單項目。你現在不必這樣做。

Creating a custom Form field type in Joomla sing the Modal Select example

如果欄位已經有值,那麼在某些情況下,可以在建立選單項目的過程中編輯所選實體(文章、選單項目等)。

因此,使用模式視窗中的選擇字段,我們可以:

  • 選擇
  • 建立
  • 編輯
  • 清晰

這就是我眼前的情況。但在 Joomla 的深處還有一個奇怪的 urlCheckin 參數,它允許您將選定的值傳送到欄位中指定的 url。值得注意的是,Joomla 中的這項功能已經逐漸發展了相當長的時間。然而,可以滿足您的需求的單獨通用欄位類型僅出現在 Joomla 5 中。甚至在 Joomla 4 中也沒有。

Joomla管理面板介面的Form建構函式的欄位是如何排列的?

以前,這個建構子稱為 JForm。我假設並非所有讀者都擁有像 IDE 這樣的開發工具 - 開發環境 - PHP Storm 或 VS Code,因此我將嘗試提供額外的指導來導航程式碼庫。

在 Joomla 中,邏輯與視圖(實際的 HTML 輸出)是分離的,因此我們將同時在多個地方對其進行探索。

邏輯是表單類

邏輯是表單類別。在 Joomla 5 中,Form 類別檔案位於 libraries/src/Form 中。我們檢查這些文件是為了了解邏輯本身、資料會發生什麼以及如何使用它。

Creating a custom Form field type in Joomla sing the Modal Select example

簡而言之,Form 建構子接收帶有欄位描述的 XML。讀取資料(欄位類型、來自 addfieldprefix 屬性的自訂欄位類別(如果有)等),使用 FormHelper 載入所需的欄位類別。如果字段有一些過濾輸出資料的規則 - 使用 FormRule 類別 - 記住 filelist 類型的 Joomla 字段,您可以在其中指定過濾參數並選擇,例如僅 php 或僅 css 檔案。

Joomla 表單欄位類別檔案 位於libraries/src/Form/Field。溫和地說,有很多。這是管理面板的建造材料,有時也是前端的建造材料。

Creating a custom Form field type in Joomla sing the Modal Select example

類別檔案描述了類別屬性,例如 $type、$layout 以及其他操作所需的屬性。大多數字段都有方法 getInput() - 實際上返回字段的 HTML 輸出,getLayoutData() - 在將字段發送到渲染之前預處理字段數據,getLabel() - 使用字段標籤等。

我們記得欄位類別繼承父 FormField 類別。在類別檔案 libraries/src/Form/FormField.php 中,描述了欄位的可能屬性,這些屬性可以在 XML 描述中使用。他們簡要地描述了它是什麼以及為什麼。

Creating a custom Form field type in Joomla sing the Modal Select example
子類別(繼承者)能夠使用父類別的方法,並在必要時覆寫它。

Creating a custom Form field type in Joomla sing the Modal Select example

Joomla 5 中字段的視圖(HTML 輸出、佈局)

每個欄位類別都有一個 HTML 輸出。在經典的 MVC 中,視圖會立即處理資料輸出,但在 Joomla 中還有一個附加層 - 佈局,它允許您覆蓋佈局 - 該 CMS 最重要的功能之一。 核心佈局是預計位於站點根目錄的 layouts 資料夾 中。它們傳遞一個 $displayData 數組,其中包含從 getLayoutData() 方法接收到的所有資料。我們在 $layout 類別屬性中指定要使用的輸出佈局。

<?php
/**
 * Name of the layout being used to render the field
 *
 * @var    string
 * @since  3.7
 */
protected $layout = 'joomla.form.field.email';

這種類型的錄音很常見。在 Joomla 中,layout 是網站根目錄下的佈局資料夾中佈局檔案的以點分隔的路徑。 也就是說,條目 $layout = 'joomla.form.field.email' 表示渲染欄位時將使用版面配置 layouts/joomla/form/field/email.php.

<?php 
use Joomla\CMS\Layout\LayoutHelper;

$displayData = [
                'src' => $this->item->image,
                'alt' => $this->item->name,
               ];

echo LayoutHelper::render(
                        'joomla.html.image',
                         $displayData
                    );

同樣,此範例將使用佈局layouts/joomla/html/image.php。可以在網站範本和管理面板的 html 資料夾中覆蓋某些版面配置。

因此,如果我們想確切地看到最終有哪些資料進入佈局以及如何顯示,請轉到佈局檔案中查看。

在 Joomla 5 的模態選擇視窗中建立資料選擇字段

現在讓我們回到本文的主要任務。

範例對於我們學習很重要(撰寫本文時為 Joomla 5.0.1):

  • 此欄位的主類別是libraries/src/Form/Field/ModalSelectField.php
  • Joomla 文章模態選擇欄位 - administrator/components/com_content/src/Field/Modal/ArticleField.php
  • 選單類型模態選擇欄位 - administrator/components/com_menus/src/Field/MenutypeField.php
  • 選單項目模態選擇欄位 - administrator/components/com_menus/src/Field/MenutypeField.php
  • 輸出佈局 - layouts/joomla/form/field/modal-select.php

在撰寫本文時,com_contacts 中的單一聯絡人模式選擇欄位尚未轉換為通用欄位類型一,僅位於(在撰寫本文時的Joomla 5.0.2 中)administrator /components/com_contact/src/ Field/Modal/ContactField.php。它直接繼承FormField,而不是ModalSelectField。

加入自己的欄位的操作演算法如下:

  • 使用 xml 檔案中的欄位或以程式設計方式使用 SimpleXMLElement 建立 XML 表單。
  • 如果我們即時工作,則使用 onContentPrepareForm 事件的插件,將 XML 表單新增至所需的表單(在此之前檢查 $form->getName())
  • 建立欄位類別。
  • 如有必要,我們可以建立自己的欄位 HTML 輸出(佈局)。我們將把它排除在本文的討論範圍之外。 它有效。 ## 欄位 XML 這段程式碼中最重要的是 addfieldprefix 屬性,它的意思是字段類別的命名空間。類別名稱由 addfieldprefix "" type "Field" 組成。在這種情況下,欄位類別將為 JoomlaPluginWtproductbuilderProviderjoomshoppingFieldProductlistField。
<?php
/**
 * Name of the layout being used to render the field
 *
 * @var    string
 * @since  3.7
 */
protected $layout = 'joomla.form.field.email';

字段的 HTML 輸出(佈局)

為了清楚 PHP 中發生的一切,您需要先查看欄位輸出的佈局。它位於檔案 layouts/joomla/form/field/modal-select.php 中。事實上,有 2 個輸入欄位是輸出 - 一個可見,另一個不可見。所選文章、聯絡人或產品的標題以佔位符的形式輸入到可見欄位 - $valueTitle 參數。第二個是他的 id - $value。如果我們還沒有選擇任何內容,則該欄位中應該有一個短語,例如「選擇文章」或「選擇產品」。這是一個語言常數,我們將其放入 XML 欄位的提示屬性中或欄位類別的 setup() 方法中。

可用於輸出佈局的所有參數(這表示可以透過程式設計方式或在 XML 檔案中使用的參數):

<?php
/**
 * Name of the layout being used to render the field
 *
 * @var    string
 * @since  3.7
 */
protected $layout = 'joomla.form.field.email';

PHP 字段類

正如您可能已經猜到的那樣,字段類別位於我的插件中。方法plugins/wtproductbuilder/providerjoomshopping/src/Field/ProductlistField.php。我以單模態文章選擇欄位為基礎,重新設計它以滿足我的需求——從 JoomShopping 線上商店選擇產品。我們用我們自己的類別來擴展父 ModalSelectField 類別。

我的任務只包括產品選擇,編輯和創作不是,所以在文章正文中我們只討論產品選擇。 PHP類別很小,我會完整給出並評論。

<?php 
use Joomla\CMS\Layout\LayoutHelper;

$displayData = [
                'src' => $this->item->image,
                'alt' => $this->item->name,
               ];

echo LayoutHelper::render(
                        'joomla.html.image',
                         $displayData
                    );

另外,引入了 getValueTitle() 方法,該方法在已選擇並保存實體的情況下顯示所選實體的名稱(產品名稱、文章標題等)。也就是說,我們去編輯選單項,我們不觸及該字段,但我們希望看到人們可以理解的文章標題/產品名稱,而不僅僅是一個id。此方法顯示所需的標題。

<field
      type="productlist"
      name="product_id"
      addfieldprefix="Joomla\Plugin\Wtproductbuilder\Providerjoomshopping\Field"
      label="Field label"
      hint="Field placeholder"
      />

在一些需要更複雜功能的欄位中 - 多語言關聯等 - 欄位類別中還有其他方法覆寫 FormField 類別的基本方法:

  • setLayoutData() 是在實際渲染欄位之前預處理資料的方法
  • getRenderer() - 用於渲染的附加參數 等等

在我們的例子中,沒有這樣的需求,所以我們不使用它們。

模態視窗內容的 HTML 輸出

按一下「選擇」按鈕時,將開啟一個模式 Bootstrap 窗口,其中在

Creating a custom Form field type in Joomla sing the Modal Select example
在我的外掛程式中,onAjaxProviderjoomshopping() 方法傳回產品清單的 HTML 輸出。我們用它們循環遍歷數組,拍攝照片、名稱和輸出。程式碼通常很長,所以我將發布最重要的片段。

簡化循環程式碼範例:

<?php
extract($displayData);

/**
 * Layout variables
 * -----------------
 * @var   string   $autocomplete    Autocomplete attribute for the field.
 * @var   boolean  $autofocus       Is autofocus enabled?
 * @var   string   $class           Classes for the input.
 * @var   string   $description     Description of the field.
 * @var   boolean  $disabled        Is this field disabled?
 * @var   string   $group           Group the field belongs to. <fields> section in form XML.
 * @var   boolean  $hidden          Is this field hidden in the form?
 * @var   string   $hint            Placeholder for the field.
 * @var   string   $id              DOM id of the field.
 * @var   string   $label           Label of the field.
 * @var   string   $labelclass      Classes to apply to the label.
 * @var   boolean  $multiple        Does this field support multiple values?
 * @var   string   $name            Name of the input field.
 * @var   string   $onchange        Onchange attribute for the field.
 * @var   string   $onclick         Onclick attribute for the field.
 * @var   string   $pattern         Pattern (Reg Ex) of value of the form field.
 * @var   boolean  $readonly        Is this field read only?
 * @var   boolean  $repeat          Allows extensions to duplicate elements.
 * @var   boolean  $required        Is this field required?
 * @var   integer  $size            Size attribute of the input.
 * @var   boolean  $spellcheck      Spellcheck state for the form field.
 * @var   string   $validate        Validation rules to apply.
 * @var   string   $value           Value attribute of the field.
 * @var   string   $dataAttribute   Miscellaneous data attributes preprocessed for HTML output
 * @var   array    $dataAttributes  Miscellaneous data attribute for eg, data-*
 * @var   string   $valueTitle
 * @var   array    $canDo
 * @var   string[] $urls
 * @var   string[] $modalTitles
 * @var   string[] $buttonIcons
 */

第二個。連結標籤代碼必須包含我們需要的資料的資料屬性。我們在貨物輸出循環的範例程式碼中看到了這個片段。

<?php
/**
 * Name of the layout being used to render the field
 *
 * @var    string
 * @since  3.7
 */
protected $layout = 'joomla.form.field.email';

JavaScript 處理。將資料從 發送到父視窗中的字段

現在讓我們開始使用 JavaScript。在撰寫本文的過程中,出現了一些細微差別,使我們能夠討論新舊工作方式。

我們記得在工作的過程中,我們連接了以下js腳本

  • media/system/js/fields/modal-fields.min.js - 此檔案已連接到文章選擇欄位的類別。然而,我們現在可以說這是一種古老且過時的工作方法。不再需要該文件。我們在 PHP 類別中註解掉了它。
  • media/plg_wtproductbuilder_providerjoomshopping/js/providerjoomshopping.modal.js - 我們自己的 js 檔案。

讓我們從自己的 javascript 開始。在這裡,使用 select-link 類,我們獲取所有選擇器並將單擊事件的偵聽器掛在它們上。

<?php 
use Joomla\CMS\Layout\LayoutHelper;

$displayData = [
                'src' => $this->item->image,
                'alt' => $this->item->name,
               ];

echo LayoutHelper::render(
                        'joomla.html.image',
                         $displayData
                    );

如果 id 和 title 一切都很直觀,那麼資料物件和 postMessage 對於那些習慣使用 Joomla 的人來說可能並不明顯。

就像在 Joomla 3 和 Joomla 4 中一樣

之前,在Joomla 2.5、3.x 甚至4.x 中,使用了以下方法:在字段輸出的佈局中,我們使用內聯腳本將處理函數掛在視窗上,並從< ;iframe>我們稱為window.parent[functionName]。看看這段程式碼

<field
      type="productlist"
      name="product_id"
      addfieldprefix="Joomla\Plugin\Wtproductbuilder\Providerjoomshopping\Field"
      label="Field label"
      hint="Field placeholder"
      />

在此形式中,函數名稱在文章/聯絡人/選單項目清單中每個連結的 data-function 屬性中指定。函數本身被內聯放置,有時將其名稱與附加 id 統一。例如,"jSelectArticle_".$this->id.

jSelectArticle() 函數或類似函數(我們將使用 jSelectProduct())是檔案 modal-fields.min.js 中標準 processModalSelect() 函數的包裝器。它依序呼叫 processModalParent() 函數並在執行後關閉模態視窗。

Creating a custom Form field type in Joomla sing the Modal Select example
這個函數需要指定一堆參數才能運作:實體的類型(文章、聯絡人等)、欄位的前綴(實際上是 HTML 欄位選擇器的 id)、實際的 id和 title - 我們需要的參數等

Creating a custom Form field type in Joomla sing the Modal Select example
在一項功能中,所有場合的一切都被收集起來。這就是我們欄位中資料的放置位置。

Joomla 5 中的情況如何

但是,現在,在 Joomla 5 中,不再需要此文件。如果我們使用欄位輸出的標準佈局,那麼 modal-content-select-field 資源就會連接到它,以一種新的方式運作。

Creating a custom Form field type in Joomla sing the Modal Select example
現在,Joomla 5 前端正在切換為使用 JavaScript postMessages。由於並非所有舊擴充都已準備好切換到新 Rails,因此已實作 JoomlaExpectingPostMessage 標誌,它允許您區分過時的事件呼叫方法。它與所描述的工作方法有間接關係,但可能對某人有用。在完全過渡到 postMessages 後,此標誌將被刪除。

Creating a custom Form field type in Joomla sing the Modal Select example

所以,現在我們不需要帶有被呼叫函數名稱的額外連結屬性。相反,我們使用 postMessage 機制。為此,在資料物件中,我們需要指定等於 joomla:content-select 的 messageType 參數。為什麼?從 JavaScript 的角度來看,在 Joomla 中工作如下:

  • 點擊連結並取得連結屬性
  • 向父視窗發送訊息 window.parent.postMessage(data)
  • media/system/js/fields/modal-content-select-field.js 檔案連接到具有訊息事件監聽器的父視窗。
  • 它檢查訊息類型,如果是 joomla:content-select,則將值放置在必填欄位中並關閉模式視窗

Creating a custom Form field type in Joomla sing the Modal Select example

在研究Joomla核心程式碼和尋找解決方案的過程中,很自然地遇到了jSelectArticle()之類的函數。然後我遇到了 postMessage 並決定透過給它一個長的唯一名稱來創建我的 MessageType。為了使其工作,我編寫了自己的處理過程,調用(事實證明,已經過時的)processModalSelect() 函數。我面臨的事實是,儘管資料已正確插入到欄位中,但模式視窗不想以任何方式關閉。進一步的搜尋首先找到了正確的事件類型,然後刪除了不必要的腳本並簡化了整個程式碼。

概括

Joomla 為開發人員提供了一套豐富的工具,用於處理第三方來源的資料並從第三方來源獲取資料並在程式碼中使用它。對於開發人員建立自己的擴充功能時,使用 JForm 欄位非常重要,特別是當需要解決超出典型範圍的任務時。當然,這樣的模式視窗和其中的資料選擇是一種相當特殊的情況,但透過這種方式,您既可以覆蓋任何其他 JForm 字段,也可以使用自己的 UX 邏輯創建自己的類型。

Joomla 社群資源

  • https://joomla.org/
  • Joomla 社區雜誌中的這篇文章

以上是在 Joomla 中使用模態選擇範例建立自訂表單欄位類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn