This question has been flagged
1 Reply
3998 Views

Hi!

I know how to use @api.onchange('my_field') in the Model for the backend, but now I am implementing the Controller and the Templates for the portal access and I want a similar behavior, I have searched the documentation but I have not found how to do it.


Model:

from odoo import fields, models, api
class MyModel(models.Model):
    _name = 'mymodule.mymodel'
    _inherit = ['mail.thread', 'mail.activity.mixin', 'portal.mixin']
    _description = 'My Model'
    _order = 'create_date desc'
    _rec_name = 'name'

    name = fields.Char()
    description = fields.Char()

    @api.onchange('name')
    def onchange_name(self):
        if self.name == False
            self.description = False


View:

<?xml version="1.0"?>
<odoo>
  <record id="view_mymodule_mymodel_form" model="ir.ui.view">
    <field name="name">MyModel Form</field>
    <field name="model">mymodule.mymodel</field>
    <field name="arch" type="xml">
      <form string="MyModel">
        <sheet>

          <field name="id" invisible="1"/>
          <group name="group_data" col="1">
            <group col="4">
              <field name="name"/>
              <field name="description"/>
            </group>
          </group>
          <div class="oe_chatter">
            <field name="message_follower_ids" widget="mail_followers"/>
            <field name="message_ids" widget="mail_thread"/>
          </div>

        </sheet>
      </form>
    </field>
  </record>
</odoo>


Controller:

from odoo import http, _
from odoo.addons.portal.controllers.portal import CustomerPortal

class MyModelCustomerPortal(CustomerPortal):
    @http.route(['/mymodule/mymodel/edit/<model("mymodule.mymodel"):mymodel>'], type='http', auth='user', website=True)
    def mymodel_portal_edit(self, mymodel, **post):
        if post:
            mymodel.sudo().write(post)
            return http.request.redirect('/mymodule/mymodel/view/%s' % slug(mymodel))
        response = http.request.render("mymodule.mymodel_portal_edit", {'mymodel': mymodel})
        return response


Template:

<odoo>
    <template id="mymodel_portal_edit" name="MyModel Form" >
        <t t-call="portal.portal_layout">
            <t t-set="breadcrumbs_searchbar" t-value="True"/>
            <t t-call="portal.portal_searchbar"> <t t-set="title">MyModel</t> </t>
            <t t-if="not mymodel"><p>There are currently no data for your account.</p></t>
            <h3>My Model</h3>
            <form t-attf-action="/mymodule/mymodel/edit/{{slug(mymodel)}}" method="post">
                <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
                <div class="row o_portal_details">
                    <div class="col-lg-12">
                        <div class="row">
                            <div class="col-lg-12">
                              <div t-if="error_message" class="alert alert-danger" role="alert">
                                  <t t-foreach="error_message" t-as="err"><t t-esc="err"/><br /></t>
                              </div>
                            </div>
                            <div t-attf-class="form-group col-xl-6">
                                <label class="col-form-label" for="name">Name</label>
                                <input type="text" name="name" t-att-value="mymodel.name" t-attf-class="form-control"/>
                            </div>
                            <div t-attf-class="form-group col-xl-6">
                                <label class="col-form-label" for="description">Description</label>
                                <input type="text" name="description" t-att-value="mymodel.description" t-attf-class="form-control"/>
                            </div>
                        </div>
                        <div class="clearfix">
                            <button type="submit" class="btn btn-primary float-left mb32 ">
                                Save<span class="fa fa-long-arrow-right" />
                            </button>
                            <a t-attf-href="/mymodule/mymodel/view/{{slug(mymodel)}}" class="btn btn-danger float-right mb32 ">
                                Cancel <span class="fa fa-long-arrow-right" />
                            </a>
                        </div>
                    </div>
                </div>
            </form>
            <div class="oe_structure"/>
        </t>
    </template>
</odoo>


Thank you.

Avatar
Discard
Best Answer

You can always call the onchange method using the recordset.

Try the following code:

class MyModelCustomerPortal(CustomerPortal):
    @http.route(['/mymodule/mymodel/edit/<model("mymodule.mymodel"):mymodel>'], type='http', auth='user', website=True)
    def mymodel_portal_edit(self, mymodel, **post):
        if post:
            mymodel.sudo().write(post)
mymodel.onchange_name() # This will reflect the changes done by onchange and you will see the update in the record


Avatar
Discard
Author

Hi Sudhir

Thank you for your answer.

I tried this way, and you are right, the record is updated, but the values in the control form does not change, for thant i had to implemente onchange in the JS. I dont know if there is a better way

Thanks again