Search code examples
odoo-13

How do I do a use an action like opening an email composer in odoo13 with only javascript outside of the odoo library environment?


I have a simple question.

I am using odoo13 and I utilize my own javascript libraries. In other words I don't rely only on the odoo libraries.

I want to add an action on a button and do simple stuff. For example: I want to click a button and open the mail composer just as it is done in "Sales Order / Send by email" button.

So I use jQuery for example and do something like this:

$('.something').on('click', function(){
    var el = $(this);
    var myConfig = {
        'name': 'Compose Email',
        'type': 'ir.actions.act_window',
        'res_model': 'mail.compose.message',
        'views': [(false, 'form')],
        'view_id': false,
        'target': 'new',
        'context': {}
    };
    var action = new WhatMustIDoHere('?????');
    action.run(myConfig);
    // the config above is supposed to be passed to the action and cause mail composer to pop-up
});

It is completely outside of what it is typically associated with:

odoo.define('my_module.my_extended_action', function (require) {
'use strict';
    ...blah blah blah
});

... which requires a whole bunch of templating and what not.

The same code works as follows: You can add something like this inside a view:

<button type="object" name"action_myActionNameWhichIsInPython">Click me</button>

... and then inside python:

@api.model
def action_myActionNameWhichIsInPython(self):
    return {
        name': 'Compose Email',
        'type': 'ir.actions.act_window',
        'res_model': 'mail.compose.message',
        'views': [(False, 'form')],
        'view_id': False,
        'target': 'new',
        'context': {}
    }

... and the whole lot works! But that is NOT what I want to do. I want to do the jQuery way because I have dynamically generated content with a whole bunch of libraries and what not which do not rely on the odoo environment.

If you look at my code and if someone can point me to the right direction to replace "WhatMustIDoHere('?????')" I would truly appreciate it.


Solution

  • So I managed to do something that seems to work. I am not sure if it is the right or nicest way to do it, but I would like to share it for other aspiring programmers.

    I added an extension and I created a global function:

    // set the action element functionality
    odoo.define('my_module.whatever', function (require) {
      "use strict";
      var holder = require('web.SystrayMenu');
      var obj = require('web.Widget');
      var ext = obj.extend({
          template:'my_module._odoo_action_element', // This template is added in the templates file and it will be used globally
          events: {
              "click": "on_click",
          },
    
          on_click: function (e) {
            var el = $(e.currentTarget);
            var action = el.data('_action'); // This is added by the function marked as "_odoo_action" 
            if (action){
              this.do_action(action);
            }
          },
      });
      // add the element to the systray menu so that it can be available globally
      holder.Items.push(_utils.var.erp_systray);
    
      // create an external function to be used later
      window._odoo_action = function(action){
        $('._odoo_action_element').data('_action', action).click();
      }
    });
    

    Then I added the template which will be injected inside the systrayMenu. It is hidden so it won't be visible.

    <templates xml:space="preserve">
      <t t-name="my_module._odoo_action_element">
        <div class="_odoo_action_element" style="display: none !important;">
          
        </div>
      </t>
    </templates>
    

    Lastly, whenever I want to use it I can do something like this:

    $('.some_element').on('click',  function(){
        window._odoo_action({
            'name': 'My  title',
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'mail.compose.message',
            'views': [(false, 'form')],
            'view_id': false,
            'target': 'new',
            'context': context,
        });
    });