【问题标题】:Odoo - prevent button from closing wizardOdoo - 防止按钮关闭向导
【发布时间】:2015-11-04 22:39:59
【问题描述】:

我有一个用作对话的瞬态模型。在我的表单视图中,我有一个这样的按钮:

<footer states="partnerId">
   <button name="check_tax_id" string="Tovább" type="object"/>
</footer>

按钮调用这个函数(我可以确认它确实调用了):

@api.one
    def check_tax_id(self, context=None):
        self.state = "partnerDetails"

        return None;

我的问题是单击此按钮后对话框窗口立即关闭! 我做错了什么?

【问题讨论】:

    标签: python xml python-2.7 odoo-8 odoo


    【解决方案1】:

    解决方案 0

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

    此解决方案由 Tadeusz Karpinski here 提供。

    解决方案 1

    您可以返回具有相同记录 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',
        }
    

    解决方案 2

    您可以在 jQuery 中创建一个小部件。这将打开向导,您可以手动将所需的行为分配给按钮。你也可以使用call函数来调用python函数:

    [...]
    
    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(); }},                       
          ],
    });
    
    [...]
    

    解决方案 3

    当然你也可以重写create方法以避免在某些情况下创建记录

    解决方案 4

    最后一个选项。创建具有状态字段的工作流。创建工作流按钮以发送信号以更改状态。您可以使用 attrs 属性和 state 字段显示或隐藏其余字段。但我不知道这是否会适应您的需求。

    【讨论】:

    • 目前您的解决方案似乎是唯一有效的解决方案。
    • 在向导启动时已经创建了记录,如果你传递当前向导的 id,它不会再次创建,但如果你在 res_id 中传递 False,它将被创建。
    • 看来此解决方案要求您接受事实窗口正在隐藏并再次显示。看起来这应该是公认的答案:stackoverflow.com/a/42421758/548696
    • @Tadeck 是的,你是对的,这应该是正确的答案。我不知道。我应该删除我的答案吗?我现在要把它添加到我的解决方案中
    • "type": "set_scrollTop",(@user3778322 回答)优于"type": "ir.actions.do_nothing",因为这不会引发异常
    【解决方案2】:

    在 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',
                }
    

    【讨论】:

      【解决方案3】:

      您可以做的是让按钮打开另一个向导,传递上下文,其中包含输入到第一个向导中的所有值。这允许您执行某些功能,即。你的按钮。并保持你的向导的状态。因此,向导中字段的默认值必须首先检查上下文并回退到其他内容。

      这是一个例子:

      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'}',
              }
      

      【讨论】:

      • 谢谢,但我认为在实现相同目标的同时,接受的答案更简单、更有效。
      【解决方案4】:

      在我的例子中,这段代码有效。

      @api.multi
      def test(self):
          l = logging.getLogger()
          l.warn("xD")
          return {
              "type": "ir.actions.do_nothing",
          }
      

      【讨论】:

        【解决方案5】:

        最简单的做法是:

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

        由于该类型用于调用ActionManager类上的任何方法(javascript)

        比 "type": "ir.actions.do_nothing" 生成异常要好(这个属性不存在)

        【讨论】:

          【解决方案6】:

          昨天我碰到了同样的问题。我需要显示一个按钮来做某事而不提交整个向导。我根本不使用按钮来解决它。这非常简单有效。你需要什么:

          1. 向导模型中的布尔标志
          2. 附加到标志的 onchange(替换您的 sumbmit 函数)
          3. 将视图中的按钮替换为带有 invisible="1" 的标志和要设置为按钮样式的标签

          代码如下:

          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" />
          

          这个技巧很有效,因为当标签具有for 属性时,它会像复选框本身一样,所以如果你点击标签,你实际上是在切换复选框。

          【讨论】:

            猜你喜欢
            • 2022-11-03
            • 2017-08-05
            • 1970-01-01
            • 2012-11-24
            • 2016-11-17
            • 1970-01-01
            • 2016-03-28
            • 2012-08-22
            • 1970-01-01
            相关资源
            最近更新 更多