Blog Post

...

Using Javascript in Odoo snippet options

Hi there, this post is dedicated to the theme of Odoo snippet options extension using Javascript. Basically it extends the previous post about snippet options (link), adding a set of Odoo programming techniques that help to solve different tasks related to snippet options using JS.

So first of all let’s start with an example of a slider (carousel) snippet defined in Odoo 14. We won’t dig into all round comprehensive code of the slider, but concentrate on main points only. The code of the slider:

<template id="s_dq_card_carousel" name="Card Carousel">
  <section class="s_dq_card_carousel">
    <div class="dq-card-carousel">
      <div class="carousel-cell">
        <h4>Quality and finish</h4>
        <p>
          Our market-leading products are designed and manufactured to the highest standards
        </p>
      </div>
    </div>
  </section>
</template>       

Now let’s say we need to add a ‘new slide’ option and ‘remove all slides’ option. How can we do that? Let’s start with the Odoo designed way. Here’s the snippet option should be defined:

<template id="s_dq_card_carousel_opt" inherit_id="website.snippet_options">
  <xpath expr="." position="inside">
    <div data-js="s_dq_card_carousel_options" data-selector=".s_dq_card_carousel">
      <we-row string="Cards">
        <we-button data-add="true" data-no-preview="true">Add</we-button>
        <we-button data-remove-all="true" data-no-preview="true">Remove all</we-button>
      </we-row>
    </div>
  </xpath>
</template>

We should notice from this excerpt 2 snippet option attributes data-add and data-remove-all. They both refer to our custom javascript methods where names mapped snake_case –> camel_case:

options.registry.s_dq_card_carousel_options = options.Class.extend({
    removeAll: function (previewMode) {
        if (confirm('Remove all cards from carousel?')) {
            this.$target.find('.dq-card-carousel').html('');
        }
    },
    add: function (previewMode) {
        var $container = this.$target.find('.dq-card-carousel');
        $('<div class="carousel-cell"><h4>Lorem ipsum</h4><p>Dolor sit amet.</p></div>').appendTo($container);
    },
});

In the first method the JS removes all slides from the carousel. In the latter one a new slide is created and appended to the carousel. On snippet start (on first render) a slider-plugin does initialization using just modified html.

<template id="s_proj_carousel_opt" inherit_id="website.snippet_options">
  <xpath expr="//div[@data-js='CoverProperties']" position="after">
    <div data-js="s_project_slide_options" data-selector=".s_proj_carousel">
      <div class="slide-status"></div>
      <div class="btn-group">
        <button type="button" class="btn btn-secondary btn-sm btn-remove-slide" data-no-preview="true">
          <i class="fa fa-trash-o"></i>Remove Slide
        </button>
        <button type="button" class="btn btn-secondary btn-sm btn-add-slide" data-no-preview="true">
          <i class="fa fa-plus-circle"></i>Add Slide
        </button>
      </div>
    </div>
  </xpath>
</template>  

And then attach javascript methods on snippet start using JQuery:

options.registry.s_project_slide_options = options.Class.extend({
    start: function () {
        var self = this;
        this.$el.find('.btn-add-slide').on('click', function () {
            var $slide = $('<div class="s_project_slide slide" data-name="Project Slide"><img src="/theme/static/src/img/pictures/projects-03.jpg" alt="" /><div class="text"><h1>Lorem ipsum dolor</h1></div><p>Lorem ispum dolor sit emet.</p></div>');
            var $active = self.$target.find('.active');
            if ($active.length) {
                $slide.insertAfter($active);
                self.$target.find('.slideshow').trigger('next');
            } else {
                self.$target.find('.slideshow .slideshow-inner').append($slide);
                self.$target.find('.slideshow').trigger('update');
            }
        });
        this.$el.find('.btn-remove-slide').on('click', function () {
            self.$target.find('.active').remove();
            self.$target.find('.slideshow').trigger('prev');
        });
    }
});  

When you save the modifications on a page, the updated html will be stored and rendered using Slider-plugin.

That’s it, in this article we’ve learned how to use Javascript to extend the core Odoo functionality in the area of snippet options. I hope you liked it, enjoy Odoo coding!


Comments (1)

Tags: odoo


Comments:

...

Leonardo Cabrera De La Cruz Jun 05, 2021 at 00:59 #

BUENAS TARDES TENGOS UNOS DETALLES CON ESTE MODULO LO ESTOY PROBANDO CUANDO AGREGO UN SNIPPETS EN EL CONTENIDO SI LO AGREGAR PERO CUANDO LO QUIERO AGREGAR EN UN APARTADO MAS PEQUEÑO NO LO GUARDA. https://apps.odoo.com/apps/modules/13.0/website_snippet_html/ SALUDOS ESPERO PUEDAN APOYARME.

Leave a Comment