Câu trả lời nhanh là Có , mọi thứ đều có thể với Thành phần UI vì nó thực sự linh hoạt như lời giới thiệu của nó.
Mặt khác, tôi không nghĩ việc phụ thuộc / ghi đè lên thành phần UI mặc định (như bạn đã đề cập trong bài đăng - ui-select
) là một ý tưởng hay. Vì vậy, trong hướng dẫn này, tôi sẽ tạo một thành phần UI mới cho các thẻ. Nó có thể được sử dụng không chỉ ở dạng sản phẩm mà cả dạng trang cms hoặc bất cứ điều gì phụ thuộc vào biểu mẫu UI.
Bây giờ hãy để niềm vui bắt đầu!
Đầu tiên, hình thức ui_component của bạn sẽ trông như thế này
StackOverflow / Catalog / view / adminhtml / ui_component / product_form.xml
<field name="parent">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Tags</item>
<item name="componentType" xsi:type="string">field</item>
<item name="formElement" xsi:type="string">input</item>
<item name="component" xsi:type="string">StackOverflow_Catalog/js/form/element/tags</item>
<item name="elementTmpl" xsi:type="string">StackOverflow_Catalog/form/element/tags</item>
<item name="dataScope" xsi:type="string">data.parent</item>
<item name="filterOptions" xsi:type="boolean">true</item>
<item name="showCheckbox" xsi:type="boolean">false</item>
<item name="disableLabel" xsi:type="boolean">true</item>
<item name="levelsVisibility" xsi:type="number">1</item>
<item name="sortOrder" xsi:type="number">20</item>
<item name="required" xsi:type="boolean">true</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
<item name="listens" xsi:type="array">
<item name="${ $.namespace }.${ $.namespace }:responseData" xsi:type="string">setParsed</item>
</item>
</item>
</argument>
</field>
Ghi chú để formEuity , thành phần và ElementTmpl . Nó phải là một trường đầu vào bình thường.
Bây giờ, chúng ta cần tạo trình kết xuất khung nhìn cho thành phần UI đó
StackOverflow / Catalog / view / cơ sở / web / js / form / Element / tags.js
/**
* StackOverflow Catalog.
*
* @category Mage
*
* @author Toan Nguyen <me@nntoan.com>
* @copyright 2018 Toan Nguyen (https://nntoan.com)
*/
define([
'underscore',
'mageUtils',
'Magento_Ui/js/form/element/abstract',
'ko',
'Magento_Ui/js/lib/validation/validator'
], function (_, utils, Element, ko, validator) {
'use strict';
return Element.extend({
defaults: {
list: ([]),
valueUpdate: 'afterkeydown',
listens: {
'valueArea': 'onUpdateArea'
}
},
initialize: function () {
this._super();
this.on('value', this.onUpdateArea.bind(this));
var self = this;
var list = this.value().split(',');
_.each(list, function (value, index) {
if (value.length > 0) {
self.list.push(value.trim());
}
});
return this;
},
initObservable: function () {
this._super();
this.observe(['valueArea']);
this.observe('list', this.list);
return this;
},
onUpdateArea: function (value) {
if (value.length > 1) {
if (value.indexOf(',') !== -1 || value.indexOf(' ') !== -1) {
var newValue = value.slice(0, -1);
this.correctValue(newValue);
}
}
},
correctValue: function (tag) {
if (this.hasTag(tag)) {
this.valueArea('');
return false;
}
if (this.isValidTag(tag).passed) {
this.list.push(tag);
this.joinList(this.list());
this.valueArea('');
return true;
}
return false;
},
isValidTag: function (tag) {
return validator('validate-alphanum', tag);
},
OnBlurEvent: function (object) {
if (this.valueArea() && this.valueArea().length > 0) {
if (!this.correctValue(this.valueArea())) {
this.valueArea('');
}
}
},
deleteTag: function (self, value, event) {
event ? event.stopPropagation() : false;
var key = -1;
_.each(this.list(), function (element, index) {
if (value === element) {
key = index;
}
});
if (key > -1) {
this.list.splice(key, 1);
this.joinList(this.list());
this.valueArea('');
}
},
joinList: function (array) {
this.value(array.join(','));
},
hasTag: function (value) {
return this.list().indexOf(value) !== -1;
}
});
});
mẫu loại trực tiếp đang trên đường ...
StackOverflow / Catalog / view / cơ sở / web / mẫu / biểu mẫu / phần tử / tags.html
<div class="tags">
<div class="admin__control-text">
<div class="apps-share-chips-editor">
<input class="admin__control-text" type="hidden"
data-bind="
value: value,
valueUpdate: valueUpdate,
attr: {
name: inputName,
placeholder: placeholder,
'aria-describedby': noticeId,
id: uid,
disabled: disabled
}"/>
<span data-bind="foreach: { data: list, as: 'item' }">
<span class="field-tag-chip">
<div class="field-tag-content" data-bind="text: item"></div>
<div class="field-tag-close-before">
<span class="field-tag-close" data-bind="event: {click: $parent.deleteTag.bind($parent, $index)}"></span>
</div>
</span>
</span>
<textarea
class="field-tag-input" placeholder="Add more tags..." data-bind="
event: {change: userChanges, blur: OnBlurEvent},
hasFocus: focused,
valueUpdate: valueUpdate,
value: valueArea
"></textarea>
</div>
</div>
</div>
một số kiểu dáng có thể? ...
StackOverflow / Catalog / view / cơ sở / web / css / tags.css
.field-tag-content {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
white-space: nowrap;
}
.field-tag-chip {
background: #e0e0e0;
border: 1px solid #e0e0e0;
display: inline-block;
-webkit-border-radius: 3px;
color: #444;
margin: 4px 1px 0 2px;
outline: none;
vertical-align: middle;
cursor: default;
padding: 0;
-webkit-border-radius: 2px;
border-radius: 2px;
overflow: hidden;
padding:5px;
padding-right:25px;
}
.field-tag-input {
display: inline-block;
margin: 10px 4px 0 4px;
vertical-align: middle;
background: none;
border: 0;
height: 25px;
outline: 0;
overflow-x: hidden;
overflow-y: auto;
padding: 0 0 0 5px;
position: relative;
resize: none;
width:50%;
}
.field-tag-close-before {
position:relative;
}
.field-tag-close{
position: absolute;
top: -10px;
right: -5px;
cursor: pointer;
}
.field-tag-close:before,
.field-tag-close:after {
content: "";
position: absolute;
top: 0px;
left: 0px;
width: 15px;
height: 4px;
background: #303030;
}
.field-tag-close:before {
webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.field-tag-close:after {
webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
Tại sao phải đặt mọi thứ trong view/base
? Tôi không có câu trả lời rõ ràng cho nó, nhưng nó có vẻ phù hợp với tôi vì nhóm Magento cũng đang đặt tất cả các yếu tố UI của họ view/base
? :)
Và cuối cùng, bạn sẽ cần thêm bạn tags.css
vàoview/adminhtml/layout/catalog_product_edit.xml
và view/adminhtml/layout/catalog_product_new.xml
.
Vì vậy, đó là nó! Bây giờ đầu vào của bạn sẽ trông như thế này:
Chúc mừng.