How it works...

So that you can understand our example, let's go over the life cycle of the widget by looking at its components:

  • init(): This is the widget constructor. It is used for initialization purposes. When the widget is initialized, this method is called first.
  • willStart(): This method is called when the widget is initialized and in the process of being appended in the DOM. It is used to initialize asynchronous data into the widget. It is also supposed to return a deferred object, which can be obtained simply from a super() call. We will use this method in the subsequent recipe.
  • start(): This method is called after the widget has completed the rendering but is not yet added in the DOM. It is very useful for a post rendering job and is supposed to return a deferred object. You can access a rendered element in this.$el.
  • destroy(): This method is called when the widget is destroyed. It is mostly used for basic cleanup operations, like event unbinding.
The fundamental base class for widgets is Widget (defined by web.Widget). If you want to dig further into this, you can study it at /addons/web/static/src/js/core/widget.js.

In step 1, we imported AbstractField and fieldRegistry.

In step 2, we created colorField by extending AbstractField. Through this, our colorField will get all the properties and methods from the AbstractField.

In step 3, we added three properties—className is used to define the class for the root element of the widget, tagName is used for the root element type, and supportedFieldTypes is used for deciding which type of fields are supported by this widget. In our case, we want to create a widget for the integer type field.

In step 4, we mapped the events of our widget. Usually, the key is a combination of the event name and the optional CSS selector. The event and CSS selector are separated by a space, and the value will be the name of the widget method. So, when the event is performed, the assigned method is called automatically. In this recipe, when a user clicks on the color pill, we want to set the integer value in the field. To manage click events, we have added a CSS selector and the method name in the events key.

In step 5, we have overridden the init method and set the value of the this.totalColors attribute. We will use this variable to decide on the number of color pills. We want to display ten color pills, so we assigned the value of 10.

In step 6, we added two methods—_renderEdit and _renderReadonly. As their names suggest, _renderEdit was called when the widget was in edit mode, and _renderReadonly was called when the widget was in read-only mode. In the edit method, we added a few <span> tags, with each representing a separate color in the widget. Upon clicking the <span> tag, we will set the value in the field. We added them into this.$el. Here, $el is the root element of the widget, and it will be added in the form view. In read-only mode, we just want to display the active color, so we added a single pill via the _renderReadonly() method. For now, we have added pills in a hardcoded way, but in the next recipe, we will use a JavaScript Qweb template to render the pills. Note that in the edit method, we used the totalColors property, which was set from the init() method.

In step 7, we added the clickPill handler method to manage pill clicks. To set the field value, we used the _setValue method. This method is added from the AbstractField class. When you set the field value, the Odoo framework will rerender the widget and call the _renderEdit method again, so that you can render the widget with the updated values.

In step 8, after we've defined our new widget, it's crucial to register it with the form widget registry, which lives in web.field_registry. Note that all view types look at this registry, so if you want to create another way of displaying a field in a list view, you can also add your widget here and set the widget attribute on the field in the view definition.

Finally, we exported our widget class so that other add-ons can extend it or inherit from it. Then, we added a new integer field called color in the library.book model. We also added the same field in the form view with the widget="int_color" attribute. This will display our widget in the form, instead of the default integer widget.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset