Напишем поле, которое позволит админу редактировать некоторые поля прямо со страницы записи

+10
445
Напишем поле, которое позволит админу редактировать некоторые поля прямо со страницы записи

Давно я ничего не ломал, решил на ночь глядя наверстать упущенное. Сегодня ночью  всё сломаем напишем поле, которое позволит админу редактировать текстовые (text, html) и строковые (string, number) поля прямо на странице записи без перехода на страницу редактирования.

Традиционно начнем с создания файлов. Два обязательных — файл поля и файл шаблона. Создадим их. Это файлы system/fields/fieldseditor.php и templates/default/assets/fields/fieldseditor.tpl.php. Второй создали и закрыли — он нам больше не нужен. Еще сразу создадим файлы js и css. Это файлы templates/default/js/fields/fieldseditor.js и templates/default/css/fields/fieldseditor.css.

Сейчас начнем писать код, но сперва я сразу хочу предупредить, что у нас не будет разных проверок для защиты от хакеров. Поле будет выполнять свои задачи только для админа. А если админ захочет стереть свой сайт, то это его выбор. Хотя пару проверок мы все-таки делаем.

Начнем с файла поля — system/fields/fieldseditor.php.

Начинается он с объявления класса:

  1. <?php class fieldFieldseditor extends cmsFormField {
  2.  
  3. }

Внутри добавим заголовок, тип поля в БД, отключим его от показа в фильтре:

  1. <?php class fieldFieldseditor extends cmsFormField {
  2.  
  3. public $title = 'Редактор полей';
  4. public $sql = 'int(1) NULL DEFAULT 1';
  5. public $filter_type = false;
  6. public $allow_index = false;
  7.  
  8. }

Добавим опции, вернее одну — список полей, которые можно редактировать:

  1. <?php class fieldFieldseditor extends cmsFormField {
  2.  
  3. public $title = 'Редактор полей';
  4. public $sql = 'int(1) NULL DEFAULT 1';
  5. public $filter_type = false;
  6. public $allow_index = false;
  7.  
  8. public function getOptions() {
  9.  
  10. return [
  11.  
  12. new fieldList('fields', array(
  13. 'title' => 'Поля, доступные для редактирования',
  14. 'is_chosen_multiple' => true,
  15. 'generator' => function() {
  16.  
  17. $model = cmsCore::getModel('content'); // Модель контента
  18.  
  19. $table_prefix = 'con_'; // Префикс таблиц. Для типов контента это con_
  20.  
  21. if ($this->subject_name == 'cms_users' || $this->subject_name == 'groups') { // Если поле в профилях пользователей или в группах
  22.  
  23. $table_prefix = ''; // то префикса нет
  24.  
  25. }
  26.  
  27. $fields = $model->get($table_prefix.$this->subject_name.'_fields'); // Получаем поля
  28.  
  29. $f_types = ['string', 'number', 'text', 'html']; // Создаем массим с типами полей, которые можно редактировать
  30.  
  31. $list = []; // Наш список полей для редактирования, пока он пустой
  32.  
  33. foreach ($fields as $field) { // Перебираем поля типа контента
  34.  
  35. if (!in_array($field['type'], $f_types)) { // Если типа поля нет в массиве разрешенных типов
  36.  
  37. continue; // то пропускаем
  38.  
  39. }
  40.  
  41. $list[$field['name']] = $field['title']; // Формируем массив полей, ключом будет системное имя, а в списке его заголовок
  42.  
  43. }
  44.  
  45. return $list; // Возвращаем список полей
  46.  
  47. }
  48. )),
  49.  
  50. ];
  51.  
  52. }
  53.  
  54. }

Открывает тип контента, профили или группы и создаем новое поле. Форма опций выглядит так:

Изображение

Отключаем показ заголовков и сохраняем.

Теперь добавим метод store(), где запретим полю в БД становиться пустым при редактировании записи:

  1. public function store($value, $is_submitted, $old_value=null) {
  2.  
  3. return 1;
  4.  
  5. }

Теперь всегда будет единица.

Давайте сделаем так, чтобы поле не работало в списках типов контента. За это у нас отвечает метод parseTeaser(). Тут всё просто:

  1. public function parseTeaser($value) {
  2.  
  3. return '';
  4.  
  5. }

Переходим к выводу в записи. Это метод parse(). Вот такой будет у нас код:

  1. public function parse($value) {
  2.  
  3. // Если пользователь не админ
  4. // или не выбраны поля для для редактирования в опциях
  5. // или в записи нет $this->item['ctype_name'] или $this->item['id']
  6. if (!cmsUser::getInstance()->is_admin || !$this->options['fields'] || empty($this->item['ctype_name']) || empty($this->item['id'])) {
  7.  
  8. return ''; // то ничего не будет
  9.  
  10. }
  11.  
  12. // Таможню прошли, значит подключаем файлы стилей и скриптов
  13. cmsTemplate::getInstance()->addCSS('templates/default/css/fields/fieldseditor.css');
  14. cmsTemplate::getInstance()->addJS('templates/default/js/fields/fieldseditor.js');
  15.  
  16. $script = ''; // Это будет скрипт, который мы добавим в тело страницы
  17.  
  18. $script .= '<script>$(document).ready(function(){'; // Начало скрипта
  19.  
  20.  
  21. // Здесь мы соберем массив из кусочков скрипта, где
  22. // каждый элемент соответствует полю из опций
  23. foreach ($this->options['fields'] as $field) { // Перебираем поля из опций
  24.  
  25. // Повесим на каждое поле событие, выполняющее
  26. // функцию fieldseditorEdit,
  27. // в которую мы передадим имя типа контента, id записи и имя поля
  28. $action = '"fieldseditorEdit(\''.$this->item['ctype_name'].'\', '.$this->item['id'].', \''.$field.'\')"';
  29.  
  30. // Добавим полям немного стилей и вызовем событие двойным кликом по полю (ondblclick)
  31. // и соберем всё это в массив $ff
  32. $ff[] = '$(\'.f_'.$field.'\').css({"cursor":"pointer", "userSelect":"none"}).attr("ondblclick", '.$action.');';
  33.  
  34. }
  35.  
  36. $script .= implode('', $ff); // Середина скрипта - делаем из массива строку
  37.  
  38. $script .= '});</script>'; // Конец скрипта
  39.  
  40. cmsTemplate::getInstance()->addBottom($script); // Закидываем наш скрипт вниз страницы
  41.  
  42. return ''; // Больше ничего не показываем
  43.  
  44. }

В этом файле всё. Вот его полный код:

  1. <?php class fieldFieldseditor extends cmsFormField {
  2.  
  3. public $title = 'Редактор полей';
  4. public $sql = 'int(1) NULL DEFAULT 1';
  5. public $filter_type = false;
  6. public $allow_index = false;
  7.  
  8. public function getOptions() {
  9.  
  10. return [
  11.  
  12. new fieldList('fields', array(
  13. 'title' => 'Поля, доступные для редактирования',
  14. 'is_chosen_multiple' => true,
  15. 'generator' => function() {
  16.  
  17. $model = cmsCore::getModel('content');
  18.  
  19. $table_prefix = 'con_';
  20.  
  21. if ($this->subject_name == 'cms_users' || $this->subject_name == 'groups') {
  22.  
  23. $table_prefix = '';
  24.  
  25. }
  26.  
  27. $fields = $model->get($table_prefix.$this->subject_name.'_fields');
  28.  
  29. $f_types = ['string', 'number', 'text', 'html'];
  30.  
  31. $list = [];
  32.  
  33. foreach ($fields as $field) {
  34.  
  35. if (!in_array($field['type'], $f_types)) {
  36.  
  37. continue;
  38.  
  39. }
  40.  
  41. $list[$field['name']] = $field['title'];
  42.  
  43. }
  44.  
  45. return $list;
  46.  
  47. }
  48. )),
  49.  
  50. ];
  51.  
  52. }
  53.  
  54. public function parse($value) {
  55.  
  56. $user = cmsUser::getInstance();
  57.  
  58. if (!$user->is_admin || !$this->options['fields'] || empty($this->item['ctype_name']) || empty($this->item['id'])) {
  59.  
  60. return '';
  61.  
  62. }
  63.  
  64. cmsTemplate::getInstance()->addCSS('templates/default/css/fields/fieldseditor.css');
  65. cmsTemplate::getInstance()->addJS('templates/default/js/fields/fieldseditor.js');
  66.  
  67. $script = '';
  68.  
  69. $script .= '<script>$(document).ready(function(){';
  70.  
  71. foreach ($this->options['fields'] as $field) {
  72.  
  73. $action = '"fieldseditorEdit(\''.$this->item['ctype_name'].'\', '.$this->item['id'].', \''.$field.'\')"';
  74.  
  75. $ff[] = '$(\'.f_'.$field.'\').css({"cursor":"pointer", "userSelect":"none"}).attr("ondblclick", '.$action.');';
  76.  
  77. }
  78.  
  79. $script .= implode('', $ff);
  80.  
  81. $script .= '});</script>';
  82.  
  83. cmsTemplate::getInstance()->addBottom($script);
  84.  
  85. return '';
  86.  
  87. }
  88.  
  89. public function parseTeaser($value) {
  90.  
  91. return '';
  92.  
  93. }
  94.  
  95. public function store($value, $is_submitted, $old_value=null) {
  96.  
  97. return 1;
  98.  
  99. }
  100.  
  101. }

Теперь при двойном клике на поле в записи должно что-то произойти. Мы на каждое поле повесили событие ondblclick, при двойном клике должна выполнятсья функция fieldseditorEdit(). Напишем ее. Открываем js-файл и добавляем в него такой код:

  1. function fieldseditorEdit(ctype_name, item_id, field_name) {
  2.  
  3. }

Давайте отправим имя типа контента, id записи и имя поля в экшен, в котором получим форму нашего поля:

  1. function fieldseditorEdit(ctype_name, item_id, field_name) {
  2.  
  3. $.post('/content/fieldseditor/' + ctype_name + '/' + item_id + '/' + field_name).done(function(response) {
  4.  
  5. result = $.parseJSON(response);
  6.  
  7. if (result.action === 'error') {
  8.  
  9. fieldseditorUpdate(ctype_name, item_id, field_name);
  10.  
  11. }
  12.  
  13. });
  14.  
  15. }

Здесь мы отправили аяксом наши данные в экшен fieldseditor компонента content. Мне говорили, что лучше создать отдельный контроллер. Я с этим полностью согласен, но пока сделаем это в контроллере content, а отдельный создадим в другой раз.

Перед созданием нового экшена, давайте посмотрим, что еще у нас в этом js-коде. Значит, отправили мы данные в экшен, оттуда вернется какой-то результат. Мы сразу написали, что если вернется ошибка, то мы обновим поле на странице. Давайте добавим такую функцию ниже:

  1. async function fieldseditorUpdate(ctype_name, item_id, field_name) {
  2.  
  3. var elem = '.f_' + field_name;
  4.  
  5. try{
  6. var html = await(await fetch(location.href)).text();
  7. var newdoc = new DOMParser().parseFromString(html, 'text/html');
  8. document.querySelector(elem).outerHTML = newdoc.querySelector(elem).outerHTML;
  9. $(elem).css({"cursor":"pointer", "userSelect":"none"}).attr("ondblclick", "fieldseditorEdit('" + ctype_name + "', " + item_id + ", '" + field_name + "')");
  10. } catch (err) {
  11. $(elem).remove();
  12. }
  13.  
  14. return true;
  15.  
  16. }

Объяснять, как это работает, не буду, сам не понимаю)) Скажу только, что здесь мы после обновления поля вернули ему всё, как было при загрузке страницы.

Вернемся в функции fieldseditorEdit. Если получили ошибку, то сделали всё, как надо. Что же будет, если ошибки нет? А вот что:

  1. function fieldseditorEdit(ctype_name, item_id, field_name) {
  2.  
  3. $.post('/content/fieldseditor/' + ctype_name + '/' + item_id + '/' + field_name).done(function(response) {
  4.  
  5. result = $.parseJSON(response);
  6.  
  7. if (result.action === 'error') {
  8.  
  9. fieldseditorUpdate(ctype_name, item_id, field_name);
  10.  
  11. }
  12.  
  13. $('.f_' + field_name).html(result.content).removeAttr('ondblclick').css({"cursor":"default","userSelect":"text"}).append('<div class="fieldseditor_btn" onmouseup="fieldseditorSave(\'' + ctype_name + '\', ' + item_id + ', \'' + field_name + '\', \'' + result.field_type + '\')">Сохранить</div><div class="fieldseditor_btn fieldseditor_cancel" onmouseup="fieldseditorCancel(\'' + ctype_name + '\', ' + item_id + ', \'' + field_name + '\')">Отменить</div>');
  14.  
  15. });
  16.  
  17. }

Теперь напишем экшен, который вернет нам форму поля. В папке system/controllers/content/actions создаем файл fieldseditor.php, в нем объявляем класс и добавляем метод run(), в который приходят наши данные. В этом методе делаем пару простых проверок и если всё нормально, возвращаем поле:

  1. <?php class actionContentFieldseditor extends cmsAction { // Объявляем класс
  2.  
  3. public function run($ctype_name, $item_id, $field_name) { // Ночало метода run()
  4.  
  5. $result = []; // Массив с резульататами, пока пустой
  6.  
  7. $result['action'] = 'error'; // По-умолчанию у нас ошибка
  8.  
  9. if (!cmsUser::getInstance()->is_admin) { // Если пользователь не админ,
  10.  
  11. return $this->cms_template->renderJSON($result); // то возвращаем ошибку
  12.  
  13. }
  14.  
  15. $table_prefix = 'con_'; // Префикс таблицы
  16.  
  17. if ($ctype_name == 'users' || $ctype_name == 'groups') { // Если это профили или группы,
  18.  
  19. $table_prefix = ''; // то префикс не нужен
  20.  
  21. }
  22.  
  23. $item = $this->model->getItemById($table_prefix.$ctype_name, $item_id); // Получаем запись
  24.  
  25. if (!$item) { // Если нет записи,
  26.  
  27. return $this->cms_template->renderJSON($result); // то возвращаем ошибку
  28.  
  29. }
  30.  
  31. // Получаем поля.
  32. // Для типов контента и профилей есть отличия.
  33. if ($ctype_name == 'users' || $ctype_name == 'groups') { // Если это профили или группы
  34.  
  35. if ($ctype_name == 'users') { // Если это профили
  36.  
  37. $ctype_name = '{'.$ctype_name.'}'; // оборачиваем системное имя в фигурные скобки
  38.  
  39. }
  40.  
  41. $fields = $this->model->setTablePrefix('')->getContentFields($ctype_name, $item['id']); // Получаем поля
  42.  
  43. } else {
  44.  
  45. $fields = $this->model->getContentFields($ctype_name); // Получаем поля
  46.  
  47. }
  48.  
  49. $result['action'] = 'ok'; // Меняем ошибку на успех
  50.  
  51. $result['field_type'] = $fields[$field_name]['type']; // Получаем тип нашего поля
  52.  
  53. $result['content'] = $fields[$field_name]['handler']->getInput($item[$field_name]); // Вот так мы получим форму
  54.  
  55. return $this->cms_template->renderJSON($result); // Возвращаем всё скрипту
  56.  
  57. }
  58.  
  59. }

Если бы это поле было доступно не только админу, а всем подряд, то надо было бы проверить, какие данные пришли, проверить, существует ли тип контента, поле и т.д. Но так как это для админа, то обойдемся без этих лишних проверок.

Так, это сделали, форму получили. Выглядит и работает это так:

Изображение

Но кроме формы у нас там еще две кнопки было — «Сохранить» и «Отменить». Сначала напишем для них стили в css-файле:

  1. .fieldseditor_btn{
  2. display:inline-block;
  3. vertical-align:top;
  4. padding:0 15px;
  5. line-height:32px;
  6. border-radius:3px;
  7. color:#fff;
  8. background:#d00000;
  9. cursor:pointer;
  10. transition:all ease .15s;
  11. margin:10px 5px 10px 0;
  12. }
  13. .fieldseditor_btn:hover{
  14. background:#f00000;
  15. }
  16. .fieldseditor_cancel{
  17. background:#999;
  18. }
  19. .fieldseditor_cancel:hover{
  20. background:#666;
  21. }

И на каждой из кнопок свое событие. Напишем сначала для кнопки отмены. Добавляем в js-файле новую функцию:

  1. function fieldseditorCancel(ctype_name, item_id, field_name) {
  2.  
  3. fieldseditorUpdate(ctype_name, item_id, field_name);
  4.  
  5. }

При нажатии на кнопку просто обновится поле и вместо формы будет показано текущее значение.

Изображение

Теперь напишем функцию для сохранения данных. Нужен еще один экшен. И данных мы будем передавать в этот раз больше. И данные могут быть сложнее. Добавляем новую функцию:

  1. function fieldseditorSave(ctype_name, item_id, field_name, field_type) {
  2.  
  3. /* Объявляем массив с нашими данными */
  4. var $data = {};
  5.  
  6. $data['ctype_name'] = ctype_name;
  7. $data['item_id'] = item_id;
  8. $data['field_name'] = field_name;
  9.  
  10. /* Если поле text или html, то новое значение поля будем брать из textarea */
  11. if (field_type === 'text' || field_type === 'html') {
  12.  
  13. var f_type = 'textarea';
  14.  
  15. }
  16.  
  17. /* Если поле число или строка, то новое значение поля будем брать из input */
  18. if (field_type === 'number' || field_type === 'string') {
  19.  
  20. var f_type = 'input';
  21.  
  22. }
  23.  
  24. /* Новое значение поля */
  25. $data['value'] = $('.f_' + field_name + ' ' + f_type + '#' + field_name).val();
  26.  
  27. /* Отправляем данные в экшен и после этого обновляем поле */
  28. $.post('/content/fieldseditor_save', $data, function(response) {
  29.  
  30. fieldseditorUpdate(ctype_name, item_id, field_name);
  31.  
  32. });
  33.  
  34. }

Обратите внимание, как я добавлял комментарии в коде. В js нужно это делать только так. Если добавлять комментарии двумя слэшами, то при объединении js-файлов всё сломается.

Пишем экшен. В папке system/controllers/content/actions добавляем файл fieldseditor_save.php с таким содержимым:

  1. <?php class actionContentFieldseditorSave extends cmsAction {
  2.  
  3. public function run() {
  4.  
  5. $result = [];
  6.  
  7. $result['action'] = 'error';
  8.  
  9. if (!cmsUser::getInstance()->is_admin) {
  10.  
  11. return $this->cms_template->renderJSON($result);
  12.  
  13. }
  14.  
  15. $data = $_POST; // Это наши данные
  16.  
  17. $ctype_name = $data['ctype_name'];
  18.  
  19. $table_prefix = 'con_';
  20.  
  21. if ($ctype_name == 'users' || $ctype_name == 'groups') {
  22.  
  23. $table_prefix = '';
  24.  
  25. }
  26.  
  27. $field_name = $data['field_name'];
  28.  
  29. $item = $this->model->getItemById($table_prefix.$ctype_name, $data['item_id']);
  30.  
  31. if (!$item) {
  32.  
  33. return $this->cms_template->renderJSON($result);
  34.  
  35. }
  36.  
  37. $result['action'] = 'ok';
  38.  
  39. // Если всё хорошо, перезаписываем наше поле новыми данными
  40. $this->model->update($table_prefix.$ctype_name, $item['id'], [$field_name => $data['value']]);
  41.  
  42. return $this->cms_template->renderJSON($result);
  43.  
  44. }
  45.  
  46. }

Теперь это работает так:

Изображение

Вот и всё. Осталось всё это дело собрать в кучу и сделать установщик. Как это делать, я рассказывал здесь. Всё то же самое.

Кому лень вникать, установщик сделаю в ближайшее время.

+1
Happy Happy 6 дней назад #

Почему только для админов ?)

+2
Loadырь Loadырь 6 дней назад #

Если бы это поле было доступно не только админу, а всем подряд, то надо было бы проверить, какие данные пришли, проверить, существует ли тип контента, поле и т.д. Но так как это для админа, то обойдемся без этих лишних проверок.

Просто автору это не надо, себе вы можете сделать сами эти проверки и открыть доступ всем желающим.

+1
Нифигаccе о-го-гошеньки Нифигаccе о-го-гошеньки 6 дней назад #

Потому что другим юзерам в таком виде предоставлять такую возможность опасно. Не известно, что они напишут в этих полях. Это не стандартная форма, которая вычистит текст от лишнего. Редактируемые поля не отправятся на модерацию. Всё, что вводится в этих полях, отправляется прямиком в БД. Вы готовы доверять пользователям до такой степени? Я нет. Но это удобно для админа, когда приходится часто что-то исправлять.

0
CEH9I CEH9I 6 дней назад #

Очень удобная фича однако))

0
Happy Happy 6 дней назад #

Так они напишут ровно столько же сколько через add. Если дать права править только свои записи 

0
Нифигаccе о-го-гошеньки Нифигаccе о-го-гошеньки 5 дней назад #

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

0
Happy Happy 5 дней назад #

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

0
Нифигаccе о-го-гошеньки Нифигаccе о-го-гошеньки 5 дней назад #

Добавлю бесплатно. Смысл добавлять платно, если весь код выше?)) Надо посоветоваться с кем-нибудь, кто разбирается в безопасности. Я пока не вникал, у меня сегодня бетонные работы.

Еще будут добавлены другие типы полей, будут небольшие изменения в коде. Этот (и другие подобные, опубликованные ранее) пост не презентация дополнения. 

0
Make Make 5 дней назад #

Интересное решение,  поэкспериментировал с кодом — вывел правку полей в модальном окне с кнопкой сохранения. Я бы еще добавил функцию по ограничению редактирования поля по временному диапазону. Но это так, мысли. А так — люто плюсую, офигенно крутое решение! 

0
RSN RSN 5 дней назад #

Хорошая штука. Хотелось бы увидеть в этом поле свои специфические хотелки (по желанию и возможности автора).

Хотелось бы изменять к какой категории принадлежит запись и количество просмотров записи...

Последнее (количество просмотров) для меня особо актуально, приходится каждый раз в БД лазить...

0
Нифигаccе о-го-гошеньки Нифигаccе о-го-гошеньки 5 дней назад #

Проще написать хук, который при добавлении записи установит нужное количество просмотров, чтобы вообще не думать об этом. Вы это имеете ввиду?

0
RSN RSN 5 дней назад #

Нет, такой хук (подобный) для автоматической очистки seo полей по крону я даже сам смог сделать))… и можно бы было, наверное, сделать запрос по какому то рандомному изменению просмотров… но не подходит.

Проблема возможно сугубо индивидуальная, хотя возможно кому то понадобиться например для имитации просмотров (накрутки) какого то контента...

Если коротко… поднимаю некоторые объявления на сайте (как на авито), но после поднятия такого объявления дата добавления становится «Сегодня», а просмотров уже много, приходится лезть в БД и там менять...

Поэтому давно уже подумывал, как бы этот процесс сделать более удобным… НО если это не входит в концепцию данного поля, ничего страшного… пойму)

0
Нифигаccе о-го-гошеньки Нифигаccе о-го-гошеньки 5 дней назад #

Да в общем-то написать поле, в котором можно менять количество просмотров не проблема. Если не забуду, завтра или на днях расскажу как. Но вот понять не могу, зачем менять дату публикации для поднятия в списке? Можно ведь завести другое поле с датой и сортировать по нему, а дату публикации не трогать. В одном моем компоненте (UpJump) именно так работает. И не надо заниматься уменьшением просмотров, если они настоящие. Мне кажется, вы пытаетесь бороться со следствием, а не с причиной.

+2
Loadырь Loadырь 5 дней назад #

Зачем писать поле, если в движке это всё уже заложено. Например для объявлений создаем новое поле типа Число. Системное имя hits_counts. В опциях выставить «Только положительные числа», «Только целые числа» и «Сохранять нулевые значения»,  доступ кому надо и видимость желательно отключить в списке и в записи. Всё остальное по желанию. Далее лезем в базу в таблицу cms_con_board_fields и меняем название (name) c hits_counts на hits_count. Всё, больше в базу лезть не надо. В таблице cms_con_board у вас будет столбец с названием hits_counts, его можно удалить или пусть болтается баластом.

0
RSN RSN 5 дней назад #

Но вот понять не могу, зачем менять дату публикации для поднятия в списке?

Как мысленно не пытаюсь ответить получается очень много букаф)

НО вот вроде Loadырь дал решение вопроса без лишних телодвижений))

Зачем писать поле, если в движке это всё уже заложено

Loadырь, спасибо большое, попробую что получится))

0
Денис Васильевич Денис Васильевич 5 дней назад #

Браво! Полезная штука. И я как-то публиковал такое но делал редактирование любых полей, в модальном окне, выводив системную форму полей. Просто исключал из неё не нужные. 

0
Денис Васильевич Денис Васильевич 5 дней назад #

Думаю подобное было полезно а может и ещё полезнее для полей список, чекбокс

0
Def Def 3 дня назад #

Да, по юзабильному было бы здорово применять такое ко всем полям: изображение, html поле, текстовое поле, флаг, список...

А так огромное спасибо автору за такой подробный разбор и само дополнение. Если доработать до полноценного функционала, то также можно продавать, я бы купил:)

0
Нифигаccе о-го-гошеньки Нифигаccе о-го-гошеньки 3 дня назад #

Так вы ж публиковали такое, в чем проблема опубликовать снова?

У меня была задача добавить быстрое редактирование полей text и html (превью и текст статьи), заодно добавил строку и число, можно изменять и другие поля, значения которых хранятся в БД в неизменном виде — список, дата и т.д. Но, например, таким образом не получится изменять поле html с редактором TinyMCE, потому что здесь текст пишется не в textarea. Можно добавить поле url, но тогда будут проблемы с двойным кликом. Да и другие поля с автоссылками могут работать не так, как ожидаем.

Сам по себе пост не рекламное предложение и не презентация дополнения, а что-то типа «урока», хотя учитель из меня так себе — сам ничего не умею. Дорабатывать до чего-то большего пока нет необходимости и времени. Я даже то, что сейчас есть, не спешу упаковывать в установщик и публиковать, так как сомневаюсь, что такому «дополнению» место в каталоге.

Если у вас есть — опубликуйте, как минимум два человека, судя по комментариям, приобретут у вас это дополнение (но это не точно).

0
Loadырь Loadырь 2 дня назад #

Можно добавить поле url, но тогда будут проблемы с двойным кликом. Да и другие поля с автоссылками могут работать не так, как ожидаем.

Можно сделать как в виджетах при наведении мышки на поле показывать иконку редактирования.

Еще от автора

Поддержка "UserPay" в компоненте "UpJump - продвижение записей в списке"
По многочисленным просьбам добавлена поддержка UserPay.
WDStat статистика контента. Обновление и публикация в каталоге дополнений.
Добавлены новые опции на основе хотелок. Виджет теперь можно сказать в каталоге дополнений бесплатно.
Как сделать липкий сайдбар
Иногда возникает необходимость зафиксировать сайдбар при прокрутке страницы. Сделать это очень просто.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.