Skip to content

Commit cb141c5

Browse files
committed
Merge remote-tracking branch 'origin/2.3-develop' into 2.3-develop-pr22
2 parents f5df570 + 33393e2 commit cb141c5

File tree

20 files changed

+309
-45
lines changed

20 files changed

+309
-45
lines changed

app/code/Magento/Catalog/i18n/en_US.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,9 @@ Groups,Groups
516516
"Maximum image width","Maximum image width"
517517
"Maximum image height","Maximum image height"
518518
"Maximum number of characters:","Maximum number of characters:"
519+
"Maximum %1 characters", "Maximum %1 characters"
520+
"too many", "too many"
521+
"remaining", "remaining"
519522
"start typing to search template","start typing to search template"
520523
"Product online","Product online"
521524
"Product offline","Product offline"

app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/text.phtml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,23 @@ $class = ($_option->getIsRequire()) ? ' required' : '';
6161
cols="25"><?= $block->escapeHtml($block->getDefaultValue()) ?></textarea>
6262
<?php endif; ?>
6363
<?php if ($_option->getMaxCharacters()): ?>
64-
<p class="note"><?= /* @escapeNotVerified */ __('Maximum number of characters:') ?>
65-
<strong><?= /* @escapeNotVerified */ $_option->getMaxCharacters() ?></strong></p>
64+
<p class="note note_<?= /* @escapeNotVerified */ $_option->getId() ?>">
65+
<?= /* @escapeNotVerified */ __('Maximum %1 characters', $_option->getMaxCharacters()) ?>
66+
<span class="character-counter no-display"></span>
67+
</p>
6668
<?php endif; ?>
6769
</div>
70+
<?php if ($_option->getMaxCharacters()): ?>
71+
<script type="text/x-magento-init">
72+
{
73+
"[data-selector='options[<?= /* @escapeNotVerified */ $_option->getId() ?>]']": {
74+
"Magento_Catalog/js/product/remaining-characters": {
75+
"maxLength": "<?= /* @escapeNotVerified */ $_option->getMaxCharacters() ?>",
76+
"noteSelector": ".note_<?= /* @escapeNotVerified */ $_option->getId() ?>",
77+
"counterSelector": ".note_<?= /* @escapeNotVerified */ $_option->getId() ?> .character-counter"
78+
}
79+
}
80+
}
81+
</script>
82+
<?php endif; ?>
6883
</div>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'jquery',
8+
'mage/translate',
9+
'jquery/ui'
10+
], function ($, $t) {
11+
'use strict';
12+
13+
$.widget('mage.remainingCharacters', {
14+
options: {
15+
remainingText: $t('remaining'),
16+
tooManyText: $t('too many'),
17+
errorClass: 'mage-error',
18+
noDisplayClass: 'no-display'
19+
},
20+
21+
/**
22+
* Initializes custom option component
23+
*
24+
* @private
25+
*/
26+
_create: function () {
27+
this.note = $(this.options.noteSelector);
28+
this.counter = $(this.options.counterSelector);
29+
30+
this.updateCharacterCount();
31+
this.element.on('change keyup paste', this.updateCharacterCount.bind(this));
32+
},
33+
34+
/**
35+
* Updates counter message
36+
*/
37+
updateCharacterCount: function () {
38+
var length = this.element.val().length,
39+
diff = this.options.maxLength - length;
40+
41+
this.counter.text(this._formatMessage(diff));
42+
this.counter.toggleClass(this.options.noDisplayClass, length === 0);
43+
this.note.toggleClass(this.options.errorClass, diff < 0);
44+
},
45+
46+
/**
47+
* Format remaining characters message
48+
*
49+
* @param {int} diff
50+
* @returns {String}
51+
* @private
52+
*/
53+
_formatMessage: function (diff) {
54+
var count = Math.abs(diff),
55+
qualifier = diff < 0 ? this.options.tooManyText : this.options.remainingText;
56+
57+
return '(' + count + ' ' + qualifier + ')';
58+
}
59+
});
60+
61+
return $.mage.remainingCharacters;
62+
});

app/code/Magento/CatalogGraphQl/etc/schema.graphqls

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,6 @@ input ProductSortInput @doc(description: "ProductSortInput specifies the attrib
492492
news_from_date: SortEnum @doc(description: "The beginning date for new product listings, and determines if the product is featured as a new product")
493493
news_to_date: SortEnum @doc(description: "The end date for new product listings")
494494
custom_layout_update: SortEnum @doc(description: "XML code that is applied as a layout update to the product page")
495-
category_ids: SortEnum @doc(description: "An array of category IDs the product belongs to")
496495
options_container: SortEnum @doc(description: "If the product has multiple options, determines where they appear on the product page")
497496
required_options: SortEnum @doc(description: "Indicates whether the product has required options")
498497
has_options: SortEnum @doc(description: "Indicates whether additional attributes have been created for the product")
Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
# Copyright © Magento, Inc. All rights reserved.
22
# See COPYING.txt for license details.
33

4-
input ProductFilterInput {
5-
tax_class_id: FilterTypeInput
6-
}
7-
8-
interface ProductInterface {
9-
tax_class_id: Int
10-
}
11-
12-
input ProductSortInput {
13-
tax_class_id: SortEnum
14-
}
15-
164
enum PriceAdjustmentCodesEnum {
175
TAX
186
}

app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@
336336
.lib-css(margin-top, @indent__xs);
337337
}
338338
}
339+
.field {
340+
.note.mage-error {
341+
color: @error__color;
342+
}
343+
}
339344
}
340345

341346
.product-options-bottom .price-box,
@@ -789,7 +794,7 @@
789794
clear: both;
790795
max-width: 100%;
791796
overflow-x: auto;
792-
position: relative; // Needed for Safari(iOS) to properly render "overflow-x" rule.
797+
position: relative; // Needed for Safari(iOS) to properly render 'overflow-x' rule.
793798

794799
.table-comparison > tbody > tr {
795800
> th,

dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/AdminProductActionGroup.xml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,40 @@
139139
<seeInField userInput="{{simpleProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="assertFieldUrlKey"/>
140140
</actionGroup>
141141

142+
<!--Fill fields for simple product in a category in Admin, including text option with char limit-->
143+
<actionGroup name="AdminCreateSimpleProductWithTextOptionCharLimit">
144+
<arguments>
145+
<argument name="category"/>
146+
<argument name="simpleProduct"/>
147+
<argument name="charLimit"/>
148+
</arguments>
149+
<amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/>
150+
<click selector="{{AdminProductGridActionSection.addProductToggle}}" stepKey="clickAddProductDropdown"/>
151+
<click selector="{{AdminProductGridActionSection.addSimpleProduct}}" stepKey="clickAddSimpleProduct"/>
152+
<fillField userInput="{{simpleProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="fillName"/>
153+
<fillField userInput="{{simpleProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="fillSKU"/>
154+
<fillField userInput="{{simpleProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/>
155+
<fillField userInput="{{simpleProduct.quantity}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillQuantity"/>
156+
<searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[{{category.name}}]" stepKey="searchAndSelectCategory"/>
157+
<click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSection"/>
158+
<fillField userInput="{{simpleProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="fillUrlKey"/>
159+
160+
<click selector="{{AdminProductCustomizableOptionsSection.customezableOptions}}" stepKey="openCustomOptionsSection"/>
161+
<click selector="{{AdminProductCustomizableOptionsSection.addOptionBtn}}" stepKey="clickAddOption"/>
162+
<fillField userInput="option1" selector="{{AdminProductCustomizableOptionsSection.optionTitleInput}}" stepKey="fillOptionTitle"/>
163+
<click selector="{{AdminProductCustomizableOptionsSection.optionTypeOpenDropDown}}" stepKey="openTypeDropDown"/>
164+
<click selector="{{AdminProductCustomizableOptionsSection.optionTypeTextField}}" stepKey="selectTypeTextField"/>
165+
<fillField userInput="20" selector="{{AdminProductCustomizableOptionsSection.maxCharactersInput}}" stepKey="fillMaxChars"/>
166+
167+
<click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/>
168+
<seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/>
169+
<seeInField userInput="{{simpleProduct.name}}" selector="{{AdminProductFormSection.productName}}" stepKey="assertFieldName"/>
170+
<seeInField userInput="{{simpleProduct.sku}}" selector="{{AdminProductFormSection.productSku}}" stepKey="assertFieldSku"/>
171+
<seeInField userInput="{{simpleProduct.price}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="assertFieldPrice"/>
172+
<click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSeoSectionAssert"/>
173+
<seeInField userInput="{{simpleProduct.urlKey}}" selector="{{AdminProductSEOSection.urlKeyInput}}" stepKey="assertFieldUrlKey"/>
174+
</actionGroup>
175+
142176
<!--Assert text in Related, Up-Sell or Cross-Sell section in Admin Product page-->
143177
<actionGroup name="AssertTextInAdminProductRelatedUpSellCrossSellSection">
144178
<arguments>

dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/ActionGroup/StorefrontProductPageActionGroup.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,21 @@
2121
<waitForPageLoad stepKey="waitForPageLoad"/>
2222
<see selector="{{StorefrontMessagesSection.success}}" userInput="You added {{productName}} to your shopping cart." stepKey="seeAddToCartSuccessMessage"/>
2323
</actionGroup>
24+
25+
<!--Verify text length validation hint with multiple inputs-->
26+
<actionGroup name="testDynamicValidationHint">
27+
<arguments>
28+
<argument name="charLimit"/>
29+
</arguments>
30+
<fillField userInput="abcde" selector="{{StorefrontProductPageSection.customTextOptionInput}}" stepKey="textInput1"/>
31+
<see selector="{{StorefrontProductPageSection.charCounter}}" userInput="(15 remaining)" stepKey="assertHint1"/>
32+
<fillField userInput="abcdefghjklansdmnbv" selector="{{StorefrontProductPageSection.customTextOptionInput}}" stepKey="textInput2"/>
33+
<see selector="{{StorefrontProductPageSection.charCounter}}" userInput="(1 remaining)" stepKey="assertHint2"/>
34+
<fillField userInput="abcdefghjklansdmnbvd" selector="{{StorefrontProductPageSection.customTextOptionInput}}" stepKey="textInput3"/>
35+
<see selector="{{StorefrontProductPageSection.charCounter}}" userInput="(0 remaining)" stepKey="assertHint3"/>
36+
<fillField userInput="abcdefghjklansdmnbvds" selector="{{StorefrontProductPageSection.customTextOptionInput}}" stepKey="textInput4"/>
37+
<see selector="{{StorefrontProductPageSection.charCounter}}" userInput="(1 too many)" stepKey="assertHint4"/>
38+
<fillField userInput="abcdefghjklansdmnbvdsasdfghjmn" selector="{{StorefrontProductPageSection.customTextOptionInput}}" stepKey="textInput5"/>
39+
<see selector="{{StorefrontProductPageSection.charCounter}}" userInput="(10 too many)" stepKey="assertHint5"/>
40+
</actionGroup>
2441
</actionGroups>

dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/AdminProductCustomizableOptionsSection.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
<element name="useDefaultOptionTitleByIndex" type="text" selector="[data-index='options'] [data-index='values'] tr[data-repeat-index='{{var1}}'] [name^='options_use_default']" parameterized="true"/>
1616
<element name="addOptionBtn" type="button" selector="button[data-index='button_add']"/>
1717
<element name="fillOptionTitle" type="input" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//span[text()='Option Title']/parent::label/parent::div//input[@class='admin__control-text']" parameterized="true"/>
18+
<element name="optionTitleInput" type="input" selector="input[name='product[options][0][title]']"/>
19+
<element name="optionTypeOpenDropDown" type="button" selector=".admin__dynamic-rows[data-index='options'] .action-select"/>
20+
<element name="optionTypeTextField" type="button" selector=".admin__dynamic-rows[data-index='options'] .action-menu._active li li"/>
21+
<element name="maxCharactersInput" type="input" selector="input[name='product[options][0][max_characters]']"/>
22+
23+
1824
<element name="checkSelect" type="select" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//span[text()='Option Type']/parent::label/parent::div//div[@data-role='selected-option']" parameterized="true"/>
1925
<element name="checkDropDown" type="select" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//parent::label/parent::div//li[@class='admin__action-multiselect-menu-inner-item']//label[text()='Drop-down']" parameterized="true"/>
2026
<element name="clickAddValue" type="button" selector="//span[text()='{{var1}}']/parent::div/parent::div/parent::div//tfoot//button" parameterized="true"/>

dev/tests/acceptance/tests/functional/Magento/FunctionalTest/Catalog/Section/StorefrontProductPageSection.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@
1313
<element name="addToCartBtn" type="button" selector="button.action.tocart.primary"/>
1414
<element name="successMsg" type="button" selector="div.message-success"/>
1515
<element name="addToWishlist" type="button" selector="//a[@class='action towishlist']" timeout="30"/>
16+
<element name="customTextOptionInput" type="input" selector=".input-text.product-custom-option"/>
17+
<element name="charCounter" type="text" selector=".character-counter"/>
1618
</section>
1719
</sections>

0 commit comments

Comments
 (0)