|
| 1 | +/** @odoo-module **/ |
| 2 | +import publicWidget from "@web/legacy/js/public/public_widget"; |
| 3 | +/* Copyright 2016 LasLabs Inc. |
| 4 | + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
| 5 | + */ |
| 6 | + |
| 7 | +publicWidget.registry.field_autocomplete = publicWidget.Widget.extend({ |
| 8 | + selector: ".js_website_autocomplete", |
| 9 | + |
| 10 | + /* Query remote server for autocomplete suggestions |
| 11 | + * @param request object Request from jQueryUI Autocomplete |
| 12 | + * @param response function Callback for response, accepts array of str |
| 13 | + */ |
| 14 | + autocomplete: function (request, response) { |
| 15 | + let domain = [[this.queryField, "ilike", request.term]]; |
| 16 | + if (this.add_domain) { |
| 17 | + domain = domain.concat(this.add_domain); |
| 18 | + } |
| 19 | + return $.ajax({ |
| 20 | + dataType: "json", |
| 21 | + url: "/website/field_autocomplete/" + this.model, |
| 22 | + contentType: "application/json; charset=utf-8", |
| 23 | + type: "POST", |
| 24 | + data: JSON.stringify({ |
| 25 | + jsonrpc: "2.0", |
| 26 | + method: "call", |
| 27 | + params: {domain: domain, fields: this.fields, limit: this.limit}, |
| 28 | + }), |
| 29 | + }).then((records) => { |
| 30 | + const data = records.result.reduce((a, b) => { |
| 31 | + a.push({label: b[this.displayField], value: b[this.valueField]}); |
| 32 | + return a; |
| 33 | + }, []); |
| 34 | + response(data); |
| 35 | + return records; |
| 36 | + }); |
| 37 | + }, |
| 38 | + |
| 39 | + /* Return arguments that are used to initialize autocomplete */ |
| 40 | + autocompleteArgs: function () { |
| 41 | + const self = this; |
| 42 | + return { |
| 43 | + source: (request, response) => { |
| 44 | + this.autocomplete(request, response); |
| 45 | + }, |
| 46 | + focus: function (event, ui) { |
| 47 | + self.$target.val(ui.item.label); |
| 48 | + self.many2oneCompatibility(ui.item); |
| 49 | + return false; |
| 50 | + }, |
| 51 | + select: function (event, ui) { |
| 52 | + self.$target.val(ui.item.label); |
| 53 | + self.many2oneCompatibility(ui.item); |
| 54 | + return false; |
| 55 | + }, |
| 56 | + }; |
| 57 | + }, |
| 58 | + |
| 59 | + start: function () { |
| 60 | + this.model = this.$target.data("model"); |
| 61 | + this.queryField = this.$target.data("query-field") || "name"; |
| 62 | + this.displayField = this.$target.data("display-field") || this.queryField; |
| 63 | + this.field = this.$target.data("field") || this.field; |
| 64 | + this.valueField = this.$target.data("value-field") || this.displayField; |
| 65 | + this.limit = this.$target.data("limit") || 10; |
| 66 | + this.add_domain = this.$target.data("domain"); |
| 67 | + this.fields = [this.displayField]; |
| 68 | + if (this.valueField !== this.displayField) { |
| 69 | + this.fields.push(this.valueField); |
| 70 | + } |
| 71 | + this.$target.autocomplete(this.autocompleteArgs()); |
| 72 | + return this._super(...arguments); |
| 73 | + }, |
| 74 | + |
| 75 | + many2oneCompatibility: function (item) { |
| 76 | + if (!this.field) return; |
| 77 | + let formField = $(this.el.closest("form")).find(`input[name='${this.field}']`); |
| 78 | + if (!formField.length) { |
| 79 | + formField = $(this.el.closest("form")).append( |
| 80 | + `<input class="d-none" name='${this.field}' />` |
| 81 | + ); |
| 82 | + } |
| 83 | + formField.val(item.value); |
| 84 | + }, |
| 85 | +}); |
0 commit comments