问题
I have a transient model that serves as a dialog. In my form view I have a button like this:
<footer states="partnerId">
<button name="check_tax_id" string="Tovább" type="object"/>
</footer>
The button invokes this function (I can confirm it actually invokes):
@api.one
def check_tax_id(self, context=None):
self.state = "partnerDetails"
return None;
My problem is that the dialog window is closed immediately once I click this button! What am I doing wrong?
回答1:
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.
回答2:
In my case this code works.
@api.multi
def test(self):
l = logging.getLogger()
l.warn("xD")
return {
"type": "ir.actions.do_nothing",
}
回答3:
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)
回答4:
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:
- a boolean flag in your wizard model
- an onchange attached to the flag (that replaces you sumbmit function)
- 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.
回答5:
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',
}
回答6:
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'}',
}
来源:https://stackoverflow.com/questions/31963214/odoo-prevent-button-from-closing-wizard