Вложение Odoo AJAX или создание изображений на стороне клиента (внешний интерфейс) - PullRequest
2 голосов
/ 05 июня 2019

Что я знаю

В модальном объекте создания я знаю, как добавить вложение или изображение, потому что все <input> находятся внутри формы, и когда пользователь нажимает кнопку отправки, действие формы запускает контроллер, который управляет входными данными.

Например:

<form id="formId" t-attf-action="/my/object/#{slug(object)}/create" method="post" enctype="multipart/form-data">
    <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
    <input type="hidden" name="object" t-att-value="object"/>
    <input type="text" name="text" class="o_website_form_input form-control"/>
    <input type="file" name="image" class="o_website_form_input form-control" accept="image/*"/>
    <input type="submit" class="btn btn-success" value="Create/"/>
</form>

Запустит следующий контроллер:

@route(['/my/object/<model("object.model"):object>/create'],
       type='http', auth="user", methods=['POST'], website=True)
def object_create(self, object, **post):
    if not object:
        return request.render("website.404")

    attachment = post.get('image')
    text = post.get('text')
    values = {
        'text': text,
    }
    # If present get image data from input file
    if attachment:
        data_image = base64.b64encode(attachment.read())
        values['image'] = data_image

    request.env['object.model'].create(values)
    # Redirect to the details page with new value
    string_url = '/my/object/view/' + slug(object)
    return werkzeug.utils.redirect(string_url)

Итак, теперь у нас есть синхронизация POST, которая создает объект с текстом и изображением с перенаправлением на объект создания.

Теперь вопрос:

Как управлять записями с обновлениями изображений или вложений?

Для простого обновления записи я использую следующие методы:

1) кнопка изменения, которая показывает скрытые <input> или <textarea>, которые будут принять новые значения

2) on. ('Change', '.class-to-monitorate'), который заполняет объект как пункт 3)

3) dataToSend = {} Это стало что-то вроде: dataToSend = {object_id: {values from input}} -> Это хорошо для write () внутри контроллера

4) An ajax.jsonRpc("/my/path/for/update/value", "call", dataToSend)

Проблема в том, что с контроллером типа JSON и <input type="file"> я не знаю, как передавать файлы.

Можно ли использовать контроллер type="http" и отправлять данные как <form>? Поэтому я могу получать все измененные <input type="file"/> и сохранять их, не обновляя каждый раз всю страницу.

EDIT

Здесь JS, который заполняет объект dataToSend

   // onChange bind that manage confirmity line values save
    $(document).on("change", ".conformity-line-value", function () {
        let value = $(this).val();
        let name = $(this).attr('name');
        let type = $(this).attr('type');
        let non_conformity_line_id = Number($(this)
            .closest('div.non-conformities-line')
            .find("input[name='non_conformity_line_id']").val());

        //If the dict for this line does not exist create it
        if (!dataToSaveConformities[non_conformity_line_id]) {
            dataToSaveConformities[non_conformity_line_id] = {}
        }
        //Add changed elements into dic to corresponding line
        switch (name) {
            case 'name':
                dataToSaveConformities[non_conformity_line_id]['name'] = value;
                if (value === '') {
                    $(this).addClass('error_input');
                } else {
                    $(this).removeClass('error_input');
                }
                break;
            case 'non_conformity_note':
                dataToSaveConformities[non_conformity_line_id]['non_conformity_note'] = value;
                break;
            default:
                break;
        }
    });

Для класса .conformity-line-value установлены все входные данные, textarea, select, флажок, который мне нужно отслеживать, если пользователь их изменяет.

Здесь функция JS, которая вызывает контроллер, который сохраняет данные:

   function save_changed_values() {
        if (!isEmpty(dataToSaveConformities)) {
            ajax.jsonRpc("/my/sale_worksheet_line/non_conformity/update/value", "call", dataToSaveConformities)
                .then(function (data) {
                    //Clear data to send
                    for (var member in dataToSaveConformities) delete dataToSaveConformities[member];
                    if (data.error) {
                        //FIXME: check that case or manage it
                        $('.non-conformities-div').load(window.location + " .non-conformities-div>*", function () {
                            $('select.js-conformities-read-multiple').select2();
                        });
                    } else {
                        $('.non-conformities-div').load(window.location + " .non-conformities-div>*", function () {
                            $('select.js-conformities-read-multiple').select2();
                        });
                    }
                });
        }
    }

Я пытаюсь взять base64 изображения из <input type="file"> и поместить его в отправленный объект (проанализированный как JSON) Но в контроллере я получаю пустое значение внутри ** post

...