Model
class ItemStocks(models.Model):
_name = 'item.stocks'
item_url = fields.Char('View Item')
ItemStocks()
View
<record id="view_item_stocks_form" model="ir.ui.view">
<field name="name">item.stocks.form</field>
<field name="model">item.stocks</field>
<field name="arch" type="xml">
<form string="Item Stocks">
...
<page string="Live Site">
<form string="Embedded Webpage" version="7.0" edit="false">
<iframe marginheight="0" marginwidth="0" frameborder="0"
src="{Variable for this.item_url}" width="100%" height="1000"/>
</form>
</page>
...
</form>
</field>
</record>
How can I replace {Variable for this.item_url} with a valid expression for the field in model? Is there a better way to do like this? What would you prefer to solve the requirement of showing dynamically an embedded webpage?
Context: Odoo 8, New Api, ir.ui.view
**`Image Url wise Set Dynamic Iframe In Odoo`**
# v11 odoo community
you need to create fields like this :
image_url = fields.Char('Image Url')
img_attach = fields.Html('Image Html')
# set image_url in iframe
#api.onchange('image_url')
def onchange_image_url(self):
if self.image_url:
self.img_attach = '<img id="img" src="%s"/>' % self.image_url
# set image_url in form view
<field name="image_url" />
# after added script
<script>
if(document.getElementById("img")){
var value= document.getElementById("img").src;
document.getElementById("custom_src").src=value;
}
</script>
# also set iframe in form view
<iframe id="custom_src" src="" width="200" height="200" />
#output
show the image : https://i.stack.imgur.com/0x7et.png
Related
Good day!
Is there a way to add a button above the Tree View in Odoo?
I would like to run a function whenever the User Clicks the button.
If this is not possible can you help me with an alternative?
here is my code on view:
'''<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_payment_import_view_tree" model="ir.ui.view">
<field name="name">account.payment.import.view.tree</field>
<field name="model">account.payment.import</field>
<field name="arch" type="xml">
<tree string="Payment Imports" decoration-info="payment_id != False" decoration-danger="error_msg != False">
<field name="transaction_date"/>
<field name="facts_id"/>
<field name="paid_in_lei"/>
<field name="paid_in_euro"/>
<field name="amount"/>
<field name="account"/>
<field name="account_no"/>
<field name="document_no"/>
<field name="details_bk_statement"/>
<field name="error_msg"/>
<field name="invoice_number" invisible="1"/>
<field name="payment_id" widget="many2onebutton" invisible="1"/>
<field name="invoice_id" widget="many2onebutton" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="currency_id" invisible="1"/>
</tree>
</field>
</record>
<record id="account_payment_import_action" model="ir.actions.act_window">
<field name="name">Payment Imports</field>
<field name="res_model">account.payment.import</field>
<field name="view_mode">tree</field>
<field name="domain">[]</field>
<field name="context">{'edit': 0}</field>
</record>
<menuitem
id="account_payment_import_menu"
name="Payment Imports"
action="account_payment_import_action"
parent="account.menu_finance_receivables"
sequence="160"/>
</odoo>'''
Well, here's my attempt to get the button in the tree view. I'll try to explain you well step by step.
First we have to add the button to the tree view via qweb, inheriting the tree view from the web module.
This will make our new button appear in all tree views, which we don't want. So to avoid that we add a condition t-if='widget.modelName == "account.payment.import"' which will cause the button to be generated only for the views whose model is the one that interests us. We also add a CSS class oe_new_custom_button to be able to identify the button from the javascript.
Let's call the file that contains this qweb tree_view_button.xml and place it in your_module_name/static/src/xml.
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-extend="ListView.buttons">
<t t-jquery="div.o_list_buttons" t-operation="append">
<button type="button" t-if='widget.modelName == "account.payment.import"'
class="oe_new_custom_button btn btn-primary">Custom Button
</button>
</t>
</t>
</templates>
Second we must give functionality to the button, we achieve this through javascript.
Here we inherit the tree view controller, called ListController, whose its role is to render and bind all extra buttons/pager in the control panel, among other things.
Let's call the file that contains this javascript tree_view_button.js and place it in your_module_name/static/src/js.
odoo.define('your_module_name.tree_view_button', function (require){
"use strict";
var ajax = require('web.ajax');
var ListController = require('web.ListController');
ListController.include({
renderButtons: function($node) {
this._super.apply(this, arguments);
var self = this;
if (this.$buttons) {
$(this.$buttons).find('.oe_new_custom_button').on('click', function() {
//custom code
});
}
},
});
});
Finally, we add our javascript to the odoo assets and configure the manifest to take all our changes.
Let's call the file that contains the assets assets.xml and place it in your_module_name/views.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets_backend" name="your_module_name_assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/your_module_name/static/src/js/tree_view_button.js"></script>
</xpath>
</template>
</data>
</odoo>
And that's what it should look like manifest.py.
{
'data': [
[ ... ]
'views/assets.xml', # <- important
],
"qweb": ['static/src/xml/*.xml'], # <- important
}
We already have everything, but now, what can be done from javascript?
A little bit of everything, but the most important thing would be the following.
Call a model method
odoo.define('your_module_name.tree_view_button', function (require){
"use strict";
var ajax = require('web.ajax');
var ListController = require('web.ListController');
var rpc = require('web.rpc')
ListController.include({
renderButtons: function($node) {
this._super.apply(this, arguments);
var self = this;
if (this.$buttons) {
$(this.$buttons).find('.oe_new_custom_button').on('click', function() {
rpc.query({
model: 'account.payment.import',
method: 'some_method',
args: [],
}).then(function(res){
// console.log(res)
// self.reload();
})
});
}
},
});
});
The first argument of args is a list of the ids you want to appear in the self variable of the some_method.
Call an action
odoo.define('your_module_name.tree_view_button', function (require){
"use strict";
var ajax = require('web.ajax');
var ListController = require('web.ListController');
ListController.include({
renderButtons: function($node) {
this._super.apply(this, arguments);
var self = this;
if (this.$buttons) {
$(this.$buttons).find('.oe_new_custom_button').on('click', function() {
self.do_action('model_name.action_id', {
additional_context: {},
});
});
}
},
});
});
additional_context should be, for example,
{
'active_id': 1,
}
The end
That's all, I hope it works for you. I attach an image of what the button would look like.
I'm using Odoo V12 CE and my issue is I try to edit a PageA view.
Have some PageA, PageB and more, inherit ParentPage.
I want to inherit ParentPage into PageA to add some content and, PageB must be: PageB = ParentPage(without modifications from PageA) + PageB.
Helps please and thanks for all!!
<template id="tpml_id" inherit_id="parent.tpml_parent_id" name="Posts">
<xpath expr="//ul[#id='post-list']" position="after">
<span>This is my posts list for all page (MyPage and all page inherits ParentPage). It's so bad. </span>
</xpath>
</template>
<!-- I want this -->
<template id="tpml_id" copy_inherit_id="parent.tpml_parent_id" name="Posts">
<xpath expr="//ul[#id='post-list']" position="after">
<span>This is my post list for this page only. </span>
</xpath>
</template>
If you want to inherit view but do not want to add anything in parent.tpml_parent_id then you can write as following :
<template id="tpml_id" inherit_id="parent.tpml_parent_id" name="Posts" primary="True">
<xpath expr="//ul[#id='post-list']" position="after">
<span>This is my post list for this page only. </span>
</xpath>
</template>
I have one field was the M2o and that opposite O2m. I try to display the O2m field in the M2o class just like that and display all the O2m field in the tree view. But I need to hide the one column is based on the ir.config_parameter
from odoo import models, fields, api
class AbcXyz(models.Model):
_name='abc.xyz'
b_ids=fields.One2many('xyz.abc','a_id',string="Xyz")
#api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
res = super(AbcXyz, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
if view_type=='form' and self.b_ids:
for line in self.b_ids:
is_applying_view = eval(self.env['ir.config_parameter'].sudo().get_param('test_module.is_applying_k_qty'))
doc = etree.XML(res['arch'])
if is_applying_view:
for node in doc.xpath("//field[#name='line.k_qty']"):
node.set('invisible', '0')
else:
for node in doc.xpath("//field[#name='line.cartoon_qty']"):
node.set('invisible', '1')
return res
class XyzAbc(models.Model)
_name='xyz.abc'
#api.multi
def get_default_k_qty_visible(self):
return eval(self.env['ir.config_parameter'].sudo().get_param('test_module.is_applying_k_qty'))
a_id=fields.Many2one('abc.xyz',string="ABC")
<!---other fields--->
k_qty=fields.Integer(string="Cartoon Qty", default=0)
is_k_qty_visible = fields.Boolean(string="Is K Qty Visible", compute=get_default_cartoon_qty_visible, store=True)
based is_k_qty_visible I try to hide the k_qty column.
<record id="abc_form_view" model="ir.ui.view">
<field name="name">abc.form.view</field>
<field name="model">abc.xyz</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="ABC Process">
<notebook>
<page string="K Qty">
<field name="b_ids" nolabel='1' mode="tree">
<tree>
<field name="k_qty" attrs="{'invisible':[('is_k_qty_visible','!=',True)]}" />
</tree>
</field>
</page>
</notebook>
</form>
</field>
<record>
But it not working for me.
This is not the answer of this question. I have share some information.
This code is used to hide fields in one2many(tree) in odoo11
<
field name="my_field" attrs="{'column_invisible': [('parent.field_name','=',False)]}" />
this type of code only works gives 'parent' in condition
I think this will type of code will work in odoo12 too.
class InvoiceWizard(models.TransientModel):
_name = "pos.order.invoice.wizard"
date_order = fields.Datetime(string='Date Order', readonly=True)
partner_id = fields.Many2one('res.partner', string='Partner')
#api.multi
def to_invoice(self):
pos_order = self.env['pos.order'].search([('id','=',self._context.get('active_id'))])
pos_order.create_invoice()
<record id="pos_order_invoice_done" model="ir.ui.view">
<field name="name">pos.order.wizard.invoice</field>
<field name="model">pos.order.invoice.wizard</field>
<field name="arch" type="xml">
<form string="To Invoice">
<group>
<field name="partner_id"/>
<field name="date_order"/>
</group>
<footer>
<button name="to_invoice"
string="Finished" type="object"
class="btn-primary"/>
<button string="Cancel"
class="btn-default"
special="cancel" />
</footer>
</form>
</field>
</record>
My goal is to create invoice from pos order with this 2 fields that manuale i will select in wizard. what do i'm missing here? i need to transfer data from those fields to create_invoice() method.
partner_id is required in invoice object, so you must fill the fields in create method like:
#api.multi
def to_invoice(self):
invoice_obj =self.env['account.invoice']
values = {'partner_id' : self.partner_id,
'date_invoice' : self.date_order
}
invoice_obj.create(values)
note : make sure all fields required is filled.
I am using redux-form immutable, I am trying to do simple todo list, I am using FieldArray for todo items,
When form is submitted, I do not get the value of index since it is read only for user and I am rendering using div. how to get the value of index during submission of the form. How should MyCustom component look like.
<TableRow selectable={false} key={index}>
<TableRowColumn style={styles.item}>
<Field name={`${todo}.index`} component={MyCustom} val={index + 1} />
</TableRowColumn>
<TableRowColumn style={styles.done}>
<Field name={`${todo}.done`} component={CheckBox} label=""/>
</TableRowColumn>
<TableRowColumn style={styles.description}>
<Field name={`${todo}.description`} component={Text}/>
</TableRowColumn>
<TableRowColumn style={styles.duration}>
<Field name={`${todo}.duration`} component={Duration} type="number" normalize={integer}/>
</TableRowColumn>
<TableRowColumn style={styles.delete}>
{/* <button type="button" title="X" onClick={() => fields.remove(index)}>X</button> */}
<IconButton onClick={() => fields.remove(index)}>
<DeleteIcon/>
</IconButton>
</TableRowColumn>
</TableRow>
MyCustom
<div>
<span>{val}</span>
</div>
index is not a field here, it's just a value. So pass it as a prop.
<MyCustom val={index + 1} />