I would like to use JQuery.UI.Autocomplete component in my module for Magento 2.
Also, I am using KO.js for the user interface of my application.
So, I have added a custom binding for KO:
define([
'ko',
'jquery',
'jquery/ui'
], function (ko, $) {
'use strict';
ko.bindingHandlers.autoComplete = {
init: function (element, valueAccessor) {
var settings = valueAccessor();
var selectedOption = settings.selected;
var options = settings.options();
var updateElementValueWithLabel = function (event, ui) {
event.preventDefault();
$(element).val(ui.item.label);
if(typeof ui.item !== "undefined") {
selectedOption(ui.item);
}
};
$(element).autocomplete({
source: options,
select: function (event, ui) {
updateElementValueWithLabel(event, ui);
},
focus: function (event, ui) {
updateElementValueWithLabel(event, ui);
},
change: function (event, ui) {
updateElementValueWithLabel(event, ui);
}
});
}
};
});
I've added the following code in my html template:
<div class="suggestions">
<input id="suggestion_box" type="text" data-bind="autoComplete: { selected: $data.productSuggestions.selectedSuggestion, options: $data.productSuggestions.suggestions }" />
</div>
It looks good, but it doesn't work. I've got a error message in the browser console. I debugged it and as it turned out, the reason of the issue is in the following lines(they start from the 6819 line) of jquery-ui.js library:
this.menu = $( "<ul>" )
.addClass( "ui-autocomplete ui-front" )
.appendTo( this._appendTo() )
.menu({
// disable ARIA support, the live region takes care of that
role: null
})
.hide()
.data( "ui-menu" );
The this.menu field is undefined, because of invoking data( "ui-menu" ) method. Methods that invoke before data() one are returns their results.
It seems like I've inited JQuery.UI.Autocomplete in a wrong way, but all examples of configuring are quite simple and I'm not sure what have I done wrong.
Any ideas?
2 Answers 2
jQuery ui menu extended in magento core library lib/web/mage/menu.js as mage.menu.
jQuery generate widgetName for any component
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
Widget name used as attribute name for storage widget instance in widget DOM elements.
$.data( element, this.widgetName, this );
After extending by magento core widget name changed from ui-menu to mage-menu and element.data("ui-menu") become undefined.
Keep in mind that magento use different jquery-ui versions for frontend and backend and in one from this versions this issue reproduced (in frontend if I remember correctly)
You can use mixin as workaround for this issue
require-config.js
var config = {
config: {
mixins: {
'mage/menu': {
'Vendor_Module/js/lib/mage/menu-mixin': true
}
}
}
};
Vendor_Module/view/frontend/web/js/lib/mage/menu-mixin.js
define([
'jquery',
'jquery/ui'
], function ($) {
'use strict';
return function (data) {
$.widget('mage.menu', data.menu, {
_create: function () {
$(this.element).data('ui-menu', this);
this._super();
}
});
data.menu = $.mage.menu;
return data;
};
});
-
I have tried it. but still not working. Any idea?vinothavn– vinothavn2017年06月14日 09:13:49 +00:00Commented Jun 14, 2017 at 9:13
-
its not workingSiva Kumar Koduru– Siva Kumar Koduru2018年01月29日 14:40:27 +00:00Commented Jan 29, 2018 at 14:40
-
12 things need to be change for it to work from the above answer (At least for Magento 2.3.1). 1. File name require-config.js must be requirejs-config.js. 2.
$.widget('mage.menu', data.menu,must be$.widget('mage.menu', $.ui.menu, {Thanu– Thanu2019年07月25日 01:11:20 +00:00Commented Jul 25, 2019 at 1:11 -
1You just saved my day! Thanks :)davidvelilla– davidvelilla2020年05月13日 12:11:42 +00:00Commented May 13, 2020 at 12:11
The small issue needs to be corrected in the above accepted answer
Please change
require-config.js to requirejs-config.js
-
@max You answer worked for me but you need to change require-config.js to requirejs-config.jsSyed Saleem– Syed Saleem2019年01月02日 02:46:27 +00:00Commented Jan 2, 2019 at 2:46
Explore related questions
See similar questions with these tags.