Editablemultiselect.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Form editable select element
  8. *
  9. * Element allows inline modification of textual data within select
  10. *
  11. * @author Magento Core Team <core@magentocommerce.com>
  12. */
  13. namespace Magento\Framework\Data\Form\Element;
  14. use Magento\Framework\Escaper;
  15. class Editablemultiselect extends \Magento\Framework\Data\Form\Element\Multiselect
  16. {
  17. /**
  18. * @var \Magento\Framework\Serialize\Serializer\Json
  19. */
  20. private $serializer;
  21. /**
  22. * Editablemultiselect constructor.
  23. * @param Factory $factoryElement
  24. * @param CollectionFactory $factoryCollection
  25. * @param Escaper $escaper
  26. * @param array $data
  27. * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
  28. * @throws \RuntimeException
  29. */
  30. public function __construct(
  31. Factory $factoryElement,
  32. CollectionFactory $factoryCollection,
  33. Escaper $escaper,
  34. array $data = [],
  35. \Magento\Framework\Serialize\Serializer\Json $serializer = null
  36. ) {
  37. parent::__construct($factoryElement, $factoryCollection, $escaper, $data);
  38. $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
  39. ->get(\Magento\Framework\Serialize\Serializer\Json::class);
  40. }
  41. /**
  42. * Name of the default JavaScript class that is used to make multiselect editable
  43. *
  44. * This class must define init() method and receive configuration in the constructor
  45. */
  46. const DEFAULT_ELEMENT_JS_CLASS = 'EditableMultiselect';
  47. /**
  48. * Retrieve HTML markup of the element
  49. *
  50. * @return string
  51. * @throws \InvalidArgumentException
  52. */
  53. public function getElementHtml()
  54. {
  55. $html = parent::getElementHtml();
  56. $selectConfig = $this->getData('select_config');
  57. if ($this->getData('disabled')) {
  58. $selectConfig['is_entity_editable'] = false;
  59. }
  60. $elementJsClass = self::DEFAULT_ELEMENT_JS_CLASS;
  61. if ($this->getData('element_js_class')) {
  62. $elementJsClass = $this->getData('element_js_class');
  63. }
  64. $selectConfigJson = $this->serializer->serialize($selectConfig);
  65. $jsObjectName = $this->getJsObjectName();
  66. // TODO: TaxRateEditableMultiselect should be moved to a static .js module.
  67. $html .= "
  68. <script type='text/javascript'>
  69. require([
  70. 'jquery',
  71. 'jquery/ui'
  72. ], function( $ ){
  73. function isResolved(){
  74. return typeof window['{$elementJsClass}'] !== 'undefined';
  75. }
  76. function init(){
  77. var {$jsObjectName} = new {$elementJsClass}({$selectConfigJson});
  78. {$jsObjectName}.init();
  79. }
  80. function check( tries, delay ){
  81. if( isResolved() ){
  82. init();
  83. }
  84. else if( tries-- ){
  85. setTimeout( check.bind(this, tries, delay), delay);
  86. }
  87. else{
  88. console.warn( 'Unable to resolve dependency: {$elementJsClass}' );
  89. }
  90. }
  91. check(8, 500);
  92. });
  93. </script>";
  94. return $html;
  95. }
  96. /**
  97. * Retrieve HTML markup of given select option
  98. *
  99. * @param array $option
  100. * @param string[] $selected
  101. * @return string
  102. */
  103. protected function _optionToHtml($option, $selected)
  104. {
  105. $html = '<option value="' . $this->_escape($option['value']) . '"';
  106. $html .= isset($option['title']) ? 'title="' . $this->_escape($option['title']) . '"' : '';
  107. $html .= isset($option['style']) ? 'style="' . $option['style'] . '"' : '';
  108. if (in_array((string)$option['value'], $selected)) {
  109. $html .= ' selected="selected"';
  110. }
  111. if ($this->getData('disabled')) {
  112. // if element is disabled then no data modification is allowed
  113. $html .= ' disabled="disabled" data-is-removable="no" data-is-editable="no"';
  114. }
  115. $html .= '>' . $this->_escape($option['label']) . '</option>' . "\n";
  116. return $html;
  117. }
  118. }