Рейтинг:5

Как сделать флажок доступным только для чтения/отключенным из списка ссылок на объекты пользователя

флаг cn

В моем типе контента я добавляю поле Ссылка: Пользователь с неограниченными значениями, эталонным методом с точки зрения менеджеров пользователей и флажками виджетов.

По сути, когда менеджер пользователей редактирует узел, он может установить флажок только со своим именем. Остальные флажки отключены. Узел будет опубликован, если все менеджеры поставят галочку.

Я попытался создать функцию form_alter, как показано ниже.

функция mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    если ($ form_id === 'node_request_order_edit_form') {

        $field_approved_by = $form['field_approved_by']['виджет']['#options'];
        
        foreach($field_approved_by as $key=>$val) {
            если($key != \Drupal::currentUser()->id()) {
                $form['field_approved_by']['widget']['#options'][$key]['#disabled'] = true;
            }
        }
    }
}

Но я получил ошибку

Ошибка: невозможно использовать объект типа Drupal\Core\Field\FieldFilteredMarkup в качестве массива...

Если я сниму флажки с помощью unset,

    ...
    если($key != \Drupal::currentUser()->id()) {
        unset($form['field_approved_by']['widget']['#options'][$key]);
    }
    ...

Значение перезаписывается, когда другой менеджер устанавливает флажок и сохраняет узел.

Спасибо за любую помощь.

ОБНОВЛЕНИЕ 1:

Итак, я как бы решаю это, используя JavaScript для отключения этих флажков. Вот справочные руководства:

Но я не знаю, лучше или хуже производительность/стабильность, чем предоставленное решение из ответов.

В основном я создаю файл библиотеки JS: spo_core.libraries.yml

request_order_edit:
  js:
    js/request_order_edit.js: {}
  зависимости:
    - ядро/jquery
    - ядро/jquery.once
    - ядро/друпал
    - настройки ядра/друпала

Затем в папке JS создайте файл: request_order_edit.js

(функция ($) {
  'использовать строгий';
  Drupal.behaviors.addLayer = {
    прикрепить: функция (контекст, настройки) {
        console.log(drupalSettings.spo_core.current_uid);
        $('#edit-field-approved by input:checkbox').each(function(){
            если (это.значение!= drupalSettings.spo_core.current_uid){
                this.disabled = истина;
            }
        });

        /*включите флажок перед отправкой, чтобы отключенный флажок мог публиковать значение*/
        $("form#node-request-order-edit-form").submit(function() {
        $('#edit-field-approved-by.form-checkboxes input:checkbox').removeAttr("disabled");
    });
    }
  }
})(jQuery);

Затем прикрепите его в форме изменить, как это

...
$form['#attached']['library'][] = 'spo_core/request_order_edit';
$form['#attached']['drupalSettings']['spo_core']['current_uid'] = \Drupal::currentUser()->id();
...
sonfd avatar
флаг in
Это может быть хорошей возможностью для создания виджета пользовательского поля, который расширяет виджет флажков ядра, а не использует хук изменения формы.
флаг cn
@sonfd Спасибо за ответ. Я обновил свой вопрос, добавив свой обходной путь с помощью JavaScript. Но я Но я не знаю, сравнимы ли производительность/стабильность/стандартизация с вашим решением/ответом. что ты думаешь?
sonfd avatar
флаг in
Когда у меня был аналогичный сценарий (отключение некоторых флажков в элементе поля), я создал виджет поля, который расширил ядро, и использовал модуль атрибутов параметров формы, чтобы отключить флажки. На мой взгляд, это лучшее решение. С вашим подходом к javascript возможно, хотя и маловероятно, кто-то может установить флажок, прежде чем он будет отключен.
Рейтинг:4
флаг in

Насколько я знаю, ядро ​​Drupal не предоставляет такой функциональности из коробки — нет возможности добавить атрибуты к отдельным опциям элемента.

Тем не менее, я сделал это с помощью Атрибуты параметров формы модуль.

Модуль [Атрибуты параметров формы] добавляет возможность указывать атрибуты для отдельных параметров в элементах Drupal Form API типов: выбор, флажки и радио.

Это довольно легко использовать. Со страницы проекта:

Чтобы добавить атрибуты к параметрам элемента формы, добавьте ключ #options_attributes в определение элемента формы. Значение #options_attributes должно быть массивом с ключами, которые соответствуют ключам в массиве значений #options. Значения в массиве #options_attributes должны быть отформатированы так же, как основной массив #attributes.

Например:

$ форма ['мое_поле'] = [
  '#варианты' => [
    '1' => 'Пользователь 1',
    '123' => 'Пользователь 123',
    '456' => 'Пользователь 456',
  ]
  '#options_attributes' => [
    // Отключить эту опцию.
    '1' => [
      'отключено' => 'отключено',
    ],
    // Разрешить эту опцию.
    '123' => [],
    // Отключить эту опцию.
    '456' => [
      'отключено' => 'отключено',
    ],
  ],
];

Или посмотреть модуль ПРОЧТИ МЕНЯ для более полных примеров.

Рейтинг:2
флаг cn

Сделай это:

функция mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    если ($ form_id === 'node_request_order_edit_form') {

        $field_approved_by = $form['field_approved_by']['виджет']['#options'];
        
        foreach($field_approved_by as $key=>$val) {
            если($key != \Drupal::currentUser()->id()) {
                $form['field_approved_by']['widget'][$key]['#disabled'] = true;
            }
        }
    }
}

Суть в том, что когда вы указываете атрибуты параметров, вы работаете с дочерним элементом «виджета», а не «#options».

флаг us
Спасибо. Это помогло отключить или скрыть групповые роли для членов группы. $form['group_roles']['widget']['имя-роли']['#disabled'] = true; или же $form['group_roles']['widget']['имя-роли']['#access'] = false;

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

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