Sign in

Зарегистрируйтесь, чтобы стать полноправным участником сообщества Masterpro.ws.

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

Статья является естественным продолжением материала Шумейко записывают, или мучения работодателя, но описывает на сей раз не подробности получения черной зарплаты в компании 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
});

 

 

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

 

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

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