Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Replace jquery/ui usages with individual jQuery UI components #5923

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion guides/v2.3/javascript-dev-guide/javascript/custom_js.md

This file was deleted.

169 changes: 169 additions & 0 deletions guides/v2.3/javascript-dev-guide/javascript/custom_js.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
---
group: javascript-developer-guide
title: Use custom JavaScript
---

This topic discusses how to use custom [JavaScript](https://glossary.magento.com/javascript) components with the components provided by Magento or custom replacement implementations.

We strongly recommend that you do not change the source code of default Magento components and widgets. All customizations must be implemented in custom modules or themes.

## Add a custom JS component {#custom_js_overview}

To add a custom JS component (module), take the following steps:

1. Place the custom component source file in one of the following locations:
- Your theme JS files: `<theme_dir>/web/js` or `<theme_dir>/<VendorName>_<ModuleName>/web/js`. In this case the component is available in your theme and its [child themes]({{ page.baseurl }}/frontend-dev-guide/themes/theme-inherit.html).
- Your module view JS files: `<module_dir>/view/frontend/web/js`. In this case, the component is available in all modules and themes (if your module is enabled).

1. Optionally, in the corresponding [module](https://glossary.magento.com/module) or theme, create a `requirejs-config.js` configuration file, if it does not yet exist there and set path for your resource. The RequireJS configuration file can be placed in one of the following locations:

- Your theme: `<theme_dir>`
- Module within your theme: `<theme_dir>/<module_dir>`
- Your module (depending on the needed area - **base**, **frontend**, **adminhtml**): `<module_dir>/view/<area>`

## Replace a default JS component {#js_replace}

To use a custom implementation of an existing Magento JS component:

Place the custom component source file in one of the following locations:

- Your theme JS files: `/web/js`
- Your module view JS files: `<module_dir>/view/frontend/web/js`

Create a RequireJS configuration file `requirejs-config.js`, having specified the following:

```javascript
var config = {
"map": {
"*": {
"<default_component>": "<custom_component>"
}
}
};
```

- `<default_component>`: the name of the default component you replace
- `<custom_component>`: the name of the custom component

For example, if you want to use a custom `navigation-menu.js` script instead of the default menu widgets, your `requirejs-config.js` should contain the following:

```javascript
var config = {
"map": {
"*": {
"menu": "js/navigation-menu",
"mage/backend/menu": "js/navigation-menu"
}
}
};
```

Place your `requirejs-config.js` file in one of the following directories (according to the location of your custom script, see step 1 of this procedure):

- Your [theme](https://glossary.magento.com/theme) files: `<theme_dir>`
- Your module view files: `<module_dir>/view/frontend`

This way, your custom JS component is used instead of the [Magento component](https://glossary.magento.com/magento-component) in all entries all over the [frontend](https://glossary.magento.com/frontend) area.

## Extend a default JS component {#extend_js}

You can add a custom JS component/widget, which will extend a default Magento component/widget.

### Extend Magento widget {#extend_js_widget}

To extend a default Magento [jQuery](https://glossary.magento.com/jquery) widget, create `<your_widget_name>.js` with contents similar to the following:

```javascript
define([
'jquery',
'jquery-ui-modules/widget', // use individual jQuery UI component if your widget is for frontend or base areas
// 'jquery/ui', // use all 'jquery/ui' library if your widget is for adminhtml area
'mage/<widget.name>' // usually widget can be found in /lib/web/mage dir
], function($){

$.widget('<your_namespace>.<your_widget_name>', $.mage.<widget.name>, { ... });

return $.<your_namespace>.<your_widget_name>;
});
```

Where the following notation is used:

- `<your_namespace>.<your_widget_name>` - the name of your custom [widget](https://glossary.magento.com/widget). According to the jQuery widgets naming convention, this value must contain a [namespace](https://glossary.magento.com/namespace) and name.
- `mage.<widget.name>` - the name of the Magento widget that you extend.

{:.bs-callout .bs-callout-tip}
All jQuery UI components for frontend and base areas are located in `lib/web/jquery/ui-modules` dir. They can be used in JS widgets by `jquery-ui-modules` path mapping like `jquery-ui-modules/widget` and `jquery-ui-modules/slider`.
Using individual jQuery UI components instead of the monolithic jQuery UI library improves storefront performance.

For information about initializing your custom widget in a `.phtml` template, see the [JavaScript initialization]({{ page.baseurl }}/javascript-dev-guide/javascript/js_init.html) topic.

### Extend a default Ui component {#extend_js_component}

To extend a default JS Ui component, your custom script must contain the following:

```javascript
define([
'<component_path>'
], function(<component_alias>){

return <component_alias>.extend({

defaults: { ... }, // properties with default values
... // methods of your component
});
});
```

Where the following notation is used:

- `<component_path>`: path to the default component that you extend
- `<component_alias>`: variable containing the default component that you extend

For example, `Filters.js` script extends the default `filters.js`:

```javascript
define([
'Magento_Ui/js/grid/filters/filters'
], function(Filters){

return Filters.extend({

defaults: { ... }, // properties with default values
... // methods of your component
});
});
```

For information about initializing your custom JS component in a `.phtml` template, see the [JavaScript initialization] topic.

## Disable default Magento JS {#disable_default_js}

To disable the auto-loading of default Magento JS components and widget initialization:

1. Create a `requirejs-config.js` file with the following content:

```javascript
var config = { deps: [ ] };
```

1. Put the `requirejs-config.js` file in one of the following
locations:

- Your custom theme files: `<theme_dir>`
- Your custom module files: `<module_dir>/view/frontend`

If you need to enable the loading of default Magento JS components and widget initialization on a certain stage, add the following code in your JS script:

```javascript
$(mage.apply);
```

{:.ref-header}
Related topic

- [JavaScript resources in Magento]({{ page.baseurl }}/javascript-dev-guide/javascript/js-resources.html)
- [About AMD modules and RequireJS]({{ page.baseurl }}/javascript-dev-guide/javascript/js-resources.html)

[JavaScript initialization]: {{page.baseurl}}/javascript-dev-guide/javascript/js_init.html
v2.3/performance-best-practices/advanced-js-bundling.html
1 change: 0 additions & 1 deletion guides/v2.3/javascript-dev-guide/javascript/js_practice.md

This file was deleted.

140 changes: 140 additions & 0 deletions guides/v2.3/javascript-dev-guide/javascript/js_practice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
group: javascript-developer-guide
title: Customizing JavaScript illustration
---

This topic features a step-by-step illustration of how to customize a [jQuery](https://glossary.magento.com/jquery) [widget](https://glossary.magento.com/widget) and how to use a custom widget instead the default Magento one.

## Customize a default Magento jQuery widget

In their Orange theme, OrangeCo wants to remove the "Click on image to view it full sized" message displayed on the product page.

The high-level steps for this task are the following:

1. Define how the message is output.
1. Add the custom script extending the default one.
1. Update RequireJS configuration to use the custom script instead of the default one.

Let's look at each step in more detail.

### Step 1: Define how the message is output {#define_script1}

OrangeCo needs to define how the message is output. To do this, they take the following steps:

1. Open a product page.
1. Select to view the page source.
1. Search for the "Click on image to view it full sized" string. The illustration of the search result follows: ![Page source search result]
1. View that it is output by [`gallery.js`].

We see that the script which OrangeCo needs to alter is `gallery.js`.

To be able to extend `gallery.js`, OrangeCo needs to know the path to it. To get this info, they refer to `requirejs-config.js`, which [can be reached from the page source view or from the file system]. According to the configuration, the path for `gallery` is `mage/gallery`. The illustration follows:

![RequireJS config file]

### Step 2: Add the custom widget extending the gallery widget {#add_code1}

In the `app/design/frontend/OrangeCo/orange/web/js` OrangeCo adds `orange-gallery.js` with the following content:

```javascript
define([
'jquery',
'jquery-ui-modules/widget',
'mage/gallery'
], function($){

$.widget('orange.gallery', $.mage.gallery, {
_create: function() { // special method of jQuery UI Widgets
this._setOption('controls', {'notice': {}});
}
});

return $.orange.gallery;
});
```

### Step 3: Update the RequireJS configuration {#config1}

OrangeCo adds the custom `app/design/OrangeCo/orange/requirejs-config.js` with the following content:

```javascript
var config = {
"map": {
"*": {
"gallery": "js/orange-gallery"
}
}
};
```

The new behavior is applied once the store pages are reloaded.

## Add and use a custom widget (jCarousel) {#use_custom_widget}

OrangeCo wants to use the [jCarousel widget] to display product images on product pages. The high level steps for this task are the following:

1. Define how product images are displayed by default.
1. Add the custom script to the file system.
1. Update RequireJS configuration to use the custom script instead of the default one.

Let's look at each step in more detail.

### Step 1: Define what is the default implementation

Using the approach described in the previous section, OrangeCo defines that the product images are displayed by [`gallery.js`], and the configuration path for it is `mage/gallery`.

### Step 2: Add the custom script to the file system

For the jCarousel widget to be able to use the configuration passed to the gallery widget,
OrangeCo needs to add a "wrapper" script.

To do this, OrangeCo adds the following files in the `app/design/frontend/OrangeCo/orange/web/js` directory:

- The jCarousel widget source file: `jquery.jcarousel.js`
- A \"wrapper\" `orange-carousel.js` with the following content:

```javascript
define([
'jquery',
'js/jquery.jcarousel'
], function($){

return function (config, element) {
var jCarouselConfig = {
list: '.items.thumbs',
items: '.item.thumb'
};
$(element).jcarousel(jCarouselConfig);
}
});
```

### Step 3: Update RequireJS configuration

In the `app/design/OrangeCo/orange` directory OrangeCo adds `requirejs-config.js` with the following content:

```javascript
var config = {
"map": {
"*": {
"gallery": "js/orange-gallery"
}
},
"shim": {
"js/jquery.jcarousel": ["jquery"] // as jquery.jcarousel isn't an AMD module
}
};
```

{:.ref-header}
Recommended reading

[Use custom JavaScript]

[Page source search result]: {{site.baseurl}}/common/images/fdg_js_pr1.png
[`gallery.js`]: {{ site.mage2bloburl }}/{{ page.guide_version }}/lib/web/mage/gallery/gallery.js
[can be reached from the page source view or from the file system]: {{page.baseurl}}/javascript-dev-guide/javascript/custom_js.html#extend_js
[RequireJS config file]: {{site.baseurl}}/common/images/fdg_pr_2.png
[jCarousel widget]: http://sorgalla.com/jcarousel/
[`gallery.js`]: {{ site.mage2bloburl }}/{{ page.guide_version }}/lib/web/mage/gallery/gallery.js
[Use custom JavaScript]: {{page.baseurl}}/javascript-dev-guide/javascript/custom_js.html