Суббота, 20 мая 2017 20:29

Создаем виджет amoCRM

Оцените материал
(6 голосов)

Статья является естественным продолжением материала Шумейко записывают, или мучения работодателя, но описывает на сей раз не подробности получения черной зарплаты в компании NeuroCRM, а, собственно, сам процесс создания виджетов amoCRM - вполне вероятно, данная информация окажется весьма полезной начинающим кодерам, которые хотели бы познакомиться с самыми что ни на есть началами процесса разработки виджетов amoCRM. Хотя начать знакомство с amoCRM автор рекомендует, несомненно, с внимательного чтения технической документации.

Это была прелюдия, а теперь к делу. Итак, мы с вами загрузили базовый виджет из соответствующего раздела документации amoCRM и с интересом разглядываем содержимое архива widget.zip; ок, ну а что же дальше? Как создать свой собственный виджет, предположим, некую формочку, которая по нажатию submit станет обрабатывать введенные пользователем данные?

Спрашиваете - отвечаю: все несложно. Собственно, для того, чтобы инсталлировать полученный виджет в своей учетке amoCRM (две недели, к слову сказать, бесплатного полнофункционального тестового периода - пробуем) нам с вами придется всего лишь изменить две строчки в файле manifest.json: "code" и "secret_key", заменив дефолтные значения на свои собственные, характерные только для нашей учетной записи - создаем новый виджет, открыв вкладку API, обзываем как душе угодно (это и будет "code", но название должно быть уникальным, учтите), и получаем для него тут же сгенерированный "secret_key". С этим все просто, но необходимо ведь добавить какой-то HTML, а также обработчик?

 

 

Начну с утверждения: handler.php виджета amoCRM вы, вероятнее всего, вынуждены будете использовать на каком-то удаленном сервере, т.к. использовать php непосредственно в виджете допустимо только в случае создания публичного, прошедшего модерацию, виджета; т.е. виджета, доступного всем без исключения зарегистрированным пользователям amoCRM. В большинстве случаев, поскольку речь идет о коммерческой разработке, этот вариант неприемлем... ок, таким образом, начнем мы с вами с создания HTML-формы, способной выглядеть вот таким, например, образом:

 

<html>
<head>
<meta charset="utf-8">
  <script type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js"></script>
</head>
<body>
<form id="form">
<table width="30%" cellspacing="0" cellpadding="4">
 <tr><td>Item category</td><td width="80%"><input type="text" name="product_type" value="Наружная реклама" style="width:100%"></td></tr>
 <tr><td>Item</td><td><input type="text" name="product" value="Световой короб" style="width:100%" ></td></tr>
  <tr><td>Item type</td><td>
  <select id="test" name="item_type" style="width:100%" > 
   <option value="">-------</option> 
    <option value="square_lightbox">Прямой световой короб</option> 
    <option value="composite_lightbox">Композитный световой короб</option> 
    <option value="shaped_lightbox">Фигурный клееный световой короб</option>
    <option value="shaped_twosided_lightbox">Двусторонний фигурный световой короб</option> 
    <option value="click_data_lightbox">Лайтбокс со сменной информацией Click</option> 
</select>
  </td></tr>
  <tr><td>Height</td><td><input type="text" placeholder="Введите значение" name="height" style="width:100%"></td></tr>
  <tr><td>Width</td><td><input type="text" placeholder="Введите значение" name="width" style="width:100%"></td></tr>
</table>
<input type="button" onclick="dosubmit()" value="Submit">
</form>
<div id="result" style="padding:5px;">
</div>
<script>
function dosubmit( ) {
  new Ajax.Updater( 'result', 'handler.php', { method: 'get',
    parameters: $('form').serialize() } );
  $('form').reset();
}
</script>
</body>
</html>

 

В скобках отметим, что использование prototype.js в своем коде в теории вполне здесь допустимо, но на практике вызывает конфликт с априори подключенным jquery.js, поэтому не рекомендуется. Ок, а теперь попробуем интегрировать свой HTML в файл script.js виджета, получаем следующее:

 

define(['jquery'], function ($) {
    var CustomWidget = function () {
        var self = this, system = self.system;
        this.callbacks = {
            settings: function () {

            }, init: function () {
                /*$.getScript("http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js", function (data, textStatus, jqxhr) {
                 });*/
                return true;
            },
            bind_actions: function () {

                $('.print-calc-form-button').on('click', function () {
                    $('.mgc-template-modal').remove();

                    $calc_container = '<form id="form"> <table width="30%" cellspacing="0" cellpadding="4"> <tr><td>Item category</td><td width="80%"><input type="text" name="product_type" value="Outer ads" style="width:100%"></td></tr> <tr><td>Item</td><td><input type="text" name="product" value="Lightbox" style="width:100%" ></td></tr> <tr><td>Item type</td><td> <select id="test" name="item_type" style="width:100%" > <option value="">-------</option> <option value="square_lightbox">Прямой световой короб</option> <option value="composite_lightbox">Композитный световой короб</option> <option value="shaped_lightbox">Фигурный клееный световой короб</option> <option value="shaped_twosided_lightbox">Двусторонний фигурный световой короб</option> <option value="click_data_lightbox">Лайтбокс со сменной информацией Click</option> </select> </td></tr> <tr><td>Height</td><td><input type="text" name="height" style="width:100%"></td></tr> <tr><td>Width</td><td><input type="text" name="width" style="width:100%"></td></tr> </table> <input type="button" value="Submit" class="submit-button"> </form> <div id="result" style="padding:5px;"> </div>';

                    $('body').append('<div class="modal modal-list modal_print-calc modal_calc-action mgc-calc-modal"> <div class="modal-scroller custom-scroll"> <div class="modal-body modal-body-relative"> <div class="modal-body__inner"> <div class="calc-action__header"><h2 class="calc-action__caption head_2">Расчет стоимости полиграфии</h2> <div class="calc-action__top-controls"> <button type="button" class="button-input button-cancel " tabindex="" id="" style=""><span>Закрыть</span></button> </div> </div>' + $calc_container + ' </div> </div> <div class="default-overlay modal-overlay default-overlay-visible"><span class="modal-overlay__spinner spinner-icon spinner-icon-abs-center"style="display: none;"></span></div> </div> </div>');

                    $('.mgc-calc-modal .button-cancel').on('click', function () {
                        $('.mgc-calc-modal').remove();
                    });
                    $('.mgc-calc-modal .submit-button').on('click', function (e) {
                        e.preventDefault();
                        var formEl = $('.mgc-calc-modal form'),
                            formData = formEl.serialize();
                        $.get("https://your_remote_server/ajax-handler-calc-app/handler.php", formData)
                            .done(function (data) {
                                //console.log("Data Loaded: " + data);
                                $('.mgc-calc-modal #result').empty().append(data);
                                formEl[0].reset();
                            });
                    });


                });


                return true;
            },
            render: function () {
                var lang = self.i18n('userLang');
                w_code = self.get_settings().widget_code;
                if (typeof(AMOCRM.data.current_card) != 'undefined') {
                    if (AMOCRM.data.current_card.id == 0) {
                        return false;
                    }
                }
                self.render_template({
                    caption: {
                        class_name: 'js-ac-caption',
                        html: ''
                    },
                    body: '',
                    render: '<div class="ac-form"><div class="print-calc-form-button ac_sub">Калькулятор полиграфии</div></div><link type="text/css" rel="stylesheet" href="/upl/' + w_code + '/widget/style.css" >'
                });
                return true;
            },
            contacts: {
                selected: function () {
                    var c_data = self.list_selected().selected;
                    console.log(c_data);

                    var names = [],
                        length = c_data.length;
                    for (var i = 0; i < length; i++) {
                        names[i] = {
                            ecalcs: c_data[i].ecalcs,
                            phones: c_data[i].phones
                        };
                    }
                    console.log(names);
                    for (var i = 0; i < length; i++) {

                    }
                    $(self.contacts).remove();
                    self.contacts = names;
                }
            },
            leads: {
                selected: function () {

                }
            },
            onSave: function () {

                return true;
            }
        };
        return this;
    };
    return CustomWidget;
});

 


Ну вот примерно так, for example. Разумеется, делайте для себя лучше и круче, делайте красивее; но сейчас нам с вами важен сугубо принцип. HTML остался практически неизменен, как видите (только строчки кода объединены), плюс подключен style.css; ну, тут уж все совсем как обычно, надеюсь, правилам работы с каскадными таблицами стилей вас обучать не надо, останавливаться на этом моменте не будем. В конце статьи выложен для ознакомления готовый виджет, который не составляет труда (изменив, как уже было сказано выше, "code" и "secret_key" в файле manifest.json) сразу же инсталлировать в свою учетку amoCRM и вдоволь наиграться с дивами и стилями; только не забудьте поместить обработчики (также приложены) на удаленный сервер и правильно прописать путь к нему:

 

 $.get("https://your_remote_server/ajax-handler-calc-app/handler.php", formData)
                            .done(function (data) {
                                //console.log("Data Loaded: " + data);
                                $('.mgc-calc-modal #result').empty().append(data);
                                formEl[0].reset();
                            });

 

Пожалуй, для начала это все, или почти все; как видите, ничего сложного. Области отображения вашего нового виджета в веб-интерфейсе amoCRM регулируются в том же самом manifest.json. Подробнее в документации, а для начала вы попросту можете ограничиться следующей несложной редакцией:

 

"locations":[
            "ccard-1",
            "clist-0",
            "lcard-1",
            "llist-0",
            "settings"
            ],

 

Допустимо ли в одном-единственном виджете отображать их несколько? - вполне, и это очень несложно: повторяем различный HTML:

  

 bind_actions: function () {

                $('.print-calc-form-button').on('click', function () {
                    $('.mgc-template-modal').remove();
                    $calc_container = 
                    --------------------------------------
                    
                 $('.print-calc2-form-button').on('click', function () {
                    $('.mgc-template-modal').remove();
		            $calc_container =
		            --------------------------------------
		            
                $('.print-calc3-form-button').on('click', function () {
                    $('.mgc-template-modal').remove();
		            $calc_container =
		            --------------------------------------
		            
                 return true;
            },


и, соответственно:

 

render: '<div class="ac-form"><div class="print-calc-form-button ac_sub">Наружная реклама</div></div><link type="text/css" rel="stylesheet" href="/upl/' + w_code + '/widget/style.css" > <div class="ac-form"><div class="print-calc2-form-button ac_sub">Широкоформатная печать</div></div><link type="text/css" rel="stylesheet" href="/upl/' + w_code + '/widget/style.css" > <div class="ac-form"><div class="print-calc3-form-button ac_sub">Печать баннеров</div></div><link type="text/css" rel="stylesheet" href="/upl/' + w_code + '/widget/style.css" >'

 

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

 

Еще примеры, также продолжение статьи на форуме.

 

Напоследок следует заметить, что в качестве альтернативы описанному способу разработчики amoCRM предлагают и другой: вовсе не обязательно использовать свои шаблоны, можно попробовать воспользоваться уже готовыми здесь темплейтами шаблонизатора twig.js. Правда, далеко не во всех случаях этот путь является оптимальным; позволю себе сослаться на мнение Алексея Рябова, разработчика amoCRM, весьма любезно согласившегося ответить на все мои вопросы:

 

Учитывая, что у вас три разных модальных окна с разными типами информации — чекбоксами и выпадающими списками, вам будет удобней написать свои шаблоны, чем пытаться совместить наши встроенные (отдельно кнопка, отдельно чекбокс, отдельно список), так как для каждого потребуется вызывать свою функцию.
Создайте в архиве с виджетом папку templates. В неё добавьте свой шаблон. Добавить шаблон в скрипт можно, например, таким кодом.

Здесь в переменную загружается шаблон:

 

var templ = self.render({
href:'templates/template.twig', //путь до шаблона
base_path: self.params.path;
load: callback //вызов функции обратного вызова произойдет только если шаблон существует и загружен
}, params); //параметры для шаблона

 

 

Здесь шаблон загружается в панель шаблонов:

 

self.render_template({
caption: {
class_name: 'class',
html: ''
},
body: '',
render: templ
});

 

 

Более подробная информация есть в документации.

 

1 Комментарий

  • Комментировать mastersoftna Воскресенье, 27 января 2019 09:40 написал mastersoftna

    Добрый день!

    Вот у Вас в коде, списки заполнятся непосредственно в html, а если мне надо в amocrm вывести свою форму, списки в которой должны заполнятся значениями с моего сервера, как это сделать?

Оставить комментарий

Добавьте ваш комментарий

Donate

Сумма (руб)

Заказать сайт

Веб-разработка. Заказать сайт

Вы можете заказать сайт-визитку, блог, корпоративный сайт, интернет-магазин или коммерческий web-портал.