Edit-in-place на компонентах Bootstrap

    Привет, Хабр!
    В этой статье я коротко расскажу о библиотеке Editable for Bootstrap, позволяющей вводить данные на страницу методом edit-in-place и основанной на компонентах Bootstrap. Я использую ее в админ-части проектов, либо когда нужно оперативно сделать интерфейс с возможностью пользовательского ввода.
    Подробности под катом.


    Механизм ввода данных реализован на базе плагинов Bootstrap Form и Popover. При клике на элементе всплывает popover, в котором находится контрол в зависимости от указанного типа. Сейчас поддерживается 4 типа контролов:
    • Text
    • Select
    • Date
    • Textarea

    Для Date используется jQuery UI Datepicker, стилизованный под bootstrap.
    Тип контрола и все остальные параметры можно указывать как через data-* атрибуты, так и в виде опций при вызове.
    Например, чтобы сделать обычный текст редактируемым и отправляющим данные на post.php, нужно:
    <a href="#" id="firstname" data-type="text" data-pk="1" data-name="firstname" data-url="post.php">John</a>
    

    Javascript:
    $('#firstname').editable();
    

    Либо:
    <a href="#" id="firstname">John</a>
    

    $('#firstname').editable({
        url: 'post.php',
        type: 'text',
        pk: 1,
        name: 'firstname',
        title: 'Enter your firstname'
    });
    

    При отправке на сервер в запрос попадут имя поля, идентификатор объекта (primary key) и новое значение:
    {name: 'firstname', pk: 1, value: 'John2'}

    Этого достаточно, чтобы сохранить в базе новое значение.

    Полный список параметров и примеры работы с остальными типами подробно описаны в документации. Также там есть пример создания новой записи.

    Любые идеи/замечания буду рад услышать в комментариях или на github.
    Спасибо за внимание!
    Поделиться публикацией

    Похожие публикации

    Комментарии 26

      +4
      Для даты www.eyecon.ro/bootstrap-datepicker/
      И как минимум остальные окошки должны пропадать если я кликаю редактировать другую строчку.
        0
        Изначально делал как раз этот datepicker. Но не удалось подружить его в popover'ом, т.к. оба всплывающие.
        На счет скрывания окошек согласен, сделаем. Спасибо!
          +4
          Вчера только работал с этим компонентом. Автор забросил его развивать. Например, до сих пор нет возможности локализации на разные языки. Однако народ не дремлет и форкнул его на гитхабе. Форкнутый проект уже поддерживает разные языки и некоторые другие опции. Вот ссылка на активный форк: github.com/eternicode/bootstrap-datepicker
            +1
            спасибо, посмотрю!
            Конечно с этим компонентом было бы более нативно.
          0
          Спасибо то что нужно, а то я велосипед писал, как раз интерфейс на Bootstrap
            +2
            Не смотрел еще сорцы, но было бы хорошо, если бы была возможность переопределить шаблон того, что показывается внутри поп-овера ( у самого поповера, кстати, такая есть) и функцию получения значения. Может быть мое имя, которое выводится, надо как-то преобразовать.
              0
              да, это можно. Через функции render, setInputValue и getInputValue, которые передать через конфиг.
                +3
                Хорошая вещь, удобная. Но есть одна идея…
                У меня некоторые поля показываются в виде ссылки. По нажатию на такое поле, как и ожидается, открывается новое окно со страницей по указанному адресу. Для таких полей я могу или оставить открытие страницы по ссылке, или сделать редактирование in-place. А хочется, как обычно, и того, и другого. :) Посему предлагаю разнести элементы «значения» и «клика». Элемент-«клик» может представлять собой, скажем, иконку редактирования, по нажатию на которую открывается popover. Но в качестве редактируемого значения берется текст элемента-«значения», в него же возвращается и результат редактирования. Если в качестве «клика» и «значения» выступает один и тот же элемент — имеем функционал в точности такой же, как нынешний.
                  0
                  Согласен, так будет еще более гибко. Добавлю, спасибо!
                  +1
                  Нельзя tab-ать от ввода к вводу, т.е. без мыши совсем никак…
                    0
                    Да, это было бы полезно. Сейчас проверил в FF / IE9: если поставить фокус на ссылку, то по enter он ее открывает и по табу переходит на следующую.
                    Значит нужно после закрытия поповера просто ставить фокус обратно на ссылку, чтобы по табу переключиться дальше. Посмотрю вечерком, спасибо.
                      0
                      А почему не сделать по нажатию таба из открытого поп-овера, чтобы открывался следующий по tabOrder и на его поле ввода ставился фокус? Можно оформить как два разных поведения, и задавать через data-tab-behaviour атрибут, например…
                    +1
                    Спасибо, очень вовремя и пригодилось!
                    Нужно событие что-нибудь типа onchange. Потому что выполнять пост аяксом на сервер мне не нужно (у меня приложение на node.js работющее через вебсокеты), но узнавать, что значение изменилось — надо. Пока что я переопределил setText для этих нужд, но вообще же нужен безкостыльный метод :-)
                      0
                      Для этого можно использовать validate.
                      Он отрабатывает всегда перед сохранением нового значения.
                      Хотя с onchange было бы красивее, вот только бы не вышло перебора с кол-вом параметров :) подумаю, спасибо!
                      0
                      А мне вот это больше по душе www.editablegrid.net
                        0
                        а будет работать с версией jQuery 1.9.0?
                          0
                          Проверил, все работает, кроме wysihtml5. Там $.browser надо поменять.
                          да, проект перерос в x-editable
                          0
                          спасибо, подскажите ещё, если у меня выводится список заголовков, допустим на каждую страницу по 20 шт. То нужно под каждый заголовок назначать $('#title_N').editable();, или есть другой способ?
                            0
                            можно назначить им класс, допустим .header и применить сразу ко всем:
                            $('.header').editable({
                            ...
                            });
                            

                            При этом различающиеся параметры удобно указать в data-* аттрибутах
                            <a class="header" data-name="title_N">
                            

                              0
                              У меня почему-то при таком раскладе сохраняется только первый отредактированный текст.
                              На странице 20 блоков для редактирования.

                              <div class="redactorEdit" data-type="textarea" data-name="content_id">[[+content]]</div>
                              

                                      <script type="text/javascript">
                                      $(document).ready(function(){
                                              $.fn.editable.defaults.mode = 'inline'; 
                                          $('.redactorEdit').editable({
                                              pk: 1,
                                              url: '/ajax.php',    
                                              params: {page_id: [[+id]]}
                                          });
                                      });
                                      </script> 
                              </div>
                              

                              В файле ajax.php проверяю если $name == content_$page_id то обновляю контент.

                              Проблема: обновляется и сохраняется в базе лишь первый отредактированный блок из 20 которые на странице. Остальные только обновляются новым значением, но в базу не сохраняются и при обновлении страницы возвращаются старые значения. В чём проблема?
                                0
                                Разобрался. Я для каждого блока вызывал отдельно функцию editable. Я просто сменил классы на уникальные, типа .redactorEdit_12
                            0
                            огромное вам спасибо, помогло. Ещё такой вопрос, смотрел документацию, но не нашёл как можно поменять размер кнопок или поля input по меньше. В Bootstrap имеется клас для кнопок btn-small но как его применить тут можно?
                              0
                              для input — через параметр inputclass, например поставить inputclass: 'input-mini'.
                              для кнопок стиль меняется глобально, т.к. предолагается, что интерфейс должен быть единым. вот примерчик jsfiddle.net/xBB5x/194/
                                0
                                А как можно передать ещё данные в php-обработчик и получить их?
                                Допустим нужно передать уникальный id страницы.
                                  0
                                  Для этого нужно использовать параметр params:
                                  $('#firstname').editable({
                                      ...
                                      params: {page_id: 123}
                                  });
                                  
                                    0
                                    Ура, заработало!
                                    Спасибо что ответили так быстро!

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое