Odoo - 防止按钮关闭向导
Odoo - prevent button from closing wizard
我有一个用作对话的瞬态模型。在我的表单视图中,我有一个这样的按钮:
<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;
我的问题是单击此按钮后对话框 window 立即关闭!
我做错了什么?
解决方案 0
@api.multi
def check_tax_id(self):
self.ensure_one()
self.name = "New name"
return {
"type": "ir.actions.do_nothing",
}
此解决方案由 Tadeusz Karpinski 提供。
解决方案 1
您可以return一个具有相同记录 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 字段显示或隐藏其余字段。不过不知道适不适合你的需求
在 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',
}
你可以做的是让按钮打开另一个向导传递上下文,所有值都输入到第一个向导中。这允许你执行一些功能,即。你的按钮。并保持您的向导状态。因此,向导中字段的默认值必须首先检查上下文,然后回退到其他内容。
这是一个例子:
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'}',
}
在我的例子中,这段代码有效。
@api.multi
def test(self):
l = logging.getLogger()
l.warn("xD")
return {
"type": "ir.actions.do_nothing",
}
最简单的做法是:
@api.multi
def null_action(self):
return {
"type": "set_scrollTop",
}
因为该类型用于调用 class ActionManager (javascript)
上的任何方法
优于 "type": "ir.actions.do_nothing" 生成异常(此属性不存在)
昨天我遇到了同样的问题。我需要在不提交整个向导的情况下显示一个按钮来做某事。我通过根本不使用按钮来解决它。它非常简单有效。你需要什么:
- 向导模型中的布尔标志
- 附加到标志的 onchange(取代您的 sumbmit 函数)
- 将视图中的按钮替换为带标志的
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
属性时,其行为将像复选框本身一样,因此如果您单击标签,实际上是在切换复选框。
我有一个用作对话的瞬态模型。在我的表单视图中,我有一个这样的按钮:
<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;
我的问题是单击此按钮后对话框 window 立即关闭! 我做错了什么?
解决方案 0
@api.multi
def check_tax_id(self):
self.ensure_one()
self.name = "New name"
return {
"type": "ir.actions.do_nothing",
}
此解决方案由 Tadeusz Karpinski
解决方案 1
您可以return一个具有相同记录 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 字段显示或隐藏其余字段。不过不知道适不适合你的需求
在 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',
}
你可以做的是让按钮打开另一个向导传递上下文,所有值都输入到第一个向导中。这允许你执行一些功能,即。你的按钮。并保持您的向导状态。因此,向导中字段的默认值必须首先检查上下文,然后回退到其他内容。
这是一个例子:
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'}',
}
在我的例子中,这段代码有效。
@api.multi
def test(self):
l = logging.getLogger()
l.warn("xD")
return {
"type": "ir.actions.do_nothing",
}
最简单的做法是:
@api.multi
def null_action(self):
return {
"type": "set_scrollTop",
}
因为该类型用于调用 class ActionManager (javascript)
上的任何方法优于 "type": "ir.actions.do_nothing" 生成异常(此属性不存在)
昨天我遇到了同样的问题。我需要在不提交整个向导的情况下显示一个按钮来做某事。我通过根本不使用按钮来解决它。它非常简单有效。你需要什么:
- 向导模型中的布尔标志
- 附加到标志的 onchange(取代您的 sumbmit 函数)
- 将视图中的按钮替换为带标志的
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
属性时,其行为将像复选框本身一样,因此如果您单击标签,实际上是在切换复选框。