Odoo - prevent button from closing wizard

后端 未结 6 1957
死守一世寂寞
死守一世寂寞 2020-12-29 11:54

I have a transient model that serves as a dialog. In my form view I have a button like this:

相关标签:
6条回答
  • 2020-12-29 11:59

    What you can do is have the button open another wizard passing context with all the values entered into the first wizard. This allows you to execute some function ie. your button. And maintain the state of your wizard. So the default value for fields in your wizard must check context first and fallback to something else.

    Here is an example:

    class MyWizard(models.TransientModel):
        _name = 'myaddon.mywizard'
    
        def _get_default_char(self):
            return self._context.get('mychar',"")
    
        mychar = fields.Char(string="My Char", default=_get_default_char)
    
        @api.multi
        def my_button(self):
            # Execute Function Here
            # reload wizard with context
    
            return {
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'myaddon.mywizard',
                'type': 'ir.actions.act_window',
                'target': 'new',
                'context': '{"mychar":'HELLO WORLD'}',
            }
    
    0 讨论(0)
  • 2020-12-29 12:12

    on odoo 7

    def traszero(self ,cr ,uid ,ids ,context=None):
            data_obj = self.pool.get('stock.return.picking.line')
            ret_wizard = self.browse(cr, uid, ids, context=context)
            if ret_wizard.product_return_moves:
                line_ids = ret_wizard.product_return_moves.mapped('id')
                data_obj.write(cr, uid, line_ids, {'quantity': 0}, context=context)
            return {'name':"Return Shipment",
                'res_model':"stock.return.picking",
                'src_model':"stock.picking",
                'view_mode':"form",
                'target':"new",
                'key2':"client_action_multi",
                'multi':"True",
                'res_id':ids[0],
                'type': 'ir.actions.act_window',
                }
    
    0 讨论(0)
  • 2020-12-29 12:20

    The simplest this to do is :

    @api.multi
    def null_action(self):
        return {
            "type": "set_scrollTop",
        }
    

    As the type is used to call any method on the class ActionManager (javascript)

    It's better than "type": "ir.actions.do_nothing" which generate an exception (this attribute doesn't exist)

    0 讨论(0)
  • 2020-12-29 12:20

    yesterday I bumped on this same issue. I needed to show a button to do something without submitting the whole wizaard. I worked around it by not using a button at all. It's pretty simple and effective. What you need:

    1. a boolean flag in your wizard model
    2. an onchange attached to the flag (that replaces you sumbmit function)
    3. replace the button in the view w/ the flag w/ invisible="1" and a label to be styled as a button

    Here's the code:

    source_it = fields.Boolean(string='Source')
    [...]
    def action_source(self):
        # do stuff
    
    @api.onchange('source_it')
    def onchange_source_it(self):
        if self.env.context.get('sourcing_now') or not self.source_it:
            return
        self.action_source()
    [...]
    <label for="source_it" class="pull-left btn btn-success" />
    <field name="source_it" invisible="1" />
    

    The trick works because when a label has for attribute is going to act like the checkbox itself, so if you click on the label you are actually switching the checkbox.

    0 讨论(0)
  • 2020-12-29 12:22

    Solution 0

    @api.multi
    def check_tax_id(self):
        self.ensure_one()
        self.name = "New name"
        return {
            "type": "ir.actions.do_nothing",
        }
    

    This solution was provided here by Tadeusz Karpinski.

    Solution 1

    You can return a new form with the same record id.

    @api.multi
    def check_tax_id(self):
        self.ensure_one()
        self.name = "New name"
        return {
            'context': self.env.context,
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'model_name',
            'res_id': self.id,
            'view_id': False,
            'type': 'ir.actions.act_window',
            'target': 'new',
        }
    

    Solution 2

    You can create a widget in jQuery. This will open the wizard and you can assign the behaviour you want to the buttons manually. You can use the call function to call python functions as well:

    [...]
    
    new instance.web.Dialog(this, { 
        title: _t("Title"), 
        width: '95%', 
        buttons: [
              { text: _t("First button"), click: function() { self.first_button(); }}, 
              { text: _t("Second button"), click: function() { self.second_button(); }},
              { text: _t("Close"), click: function() {  dialog.close(); }},                       
          ],
    });
    
    [...]
    

    Solution 3

    Of course you can override the create method as well to avoid the creation of the record in some cases

    Solution 4

    One last option. Create a workflow with a state field. Create workflow buttons in order to send signals to change the state. You can show or hide the rest of the fields using the attrs attribute and the state field. But I do not know if that would adapt to your needs.

    0 讨论(0)
  • 2020-12-29 12:22

    In my case this code works.

    @api.multi
    def test(self):
        l = logging.getLogger()
        l.warn("xD")
        return {
            "type": "ir.actions.do_nothing",
        }
    
    0 讨论(0)
提交回复
热议问题