[Решено] Поле Entity Reference в зависимости от значения другого поля.

Аватар пользователя Koreychenko Koreychenko 27 сентября 2012 в 11:20

Приветствую общественность!

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

Есть сайт медицинской тематики.
На сайте есть термины таксономии "Поликлиника".
К этому термину таксономии привязаны материалы типа "Врач".
К этому термину таксономии могут быть привязаны материалы типа "Услуга".
Материалы "Услуга" и "Врач" связываются между собой с помощью Entity Reference.

Вопрос: как можно сделать так, чтобы при создании материала "Услуга" отображались лишь те врачи, которые принадлежат той же поликлинике, в которой создается услуга?

Т.е. список поля Entity Reference должен фильтроваться после того, как выбрано значение в поле Taxonomy Term.

Есть модуль reference_option_limit, но я что-то не совсем вкурил как оно работает и как оно поможет лично мне )

Комментарии

Аватар пользователя Koreychenko Koreychenko 27 сентября 2012 в 12:23

Пока мне видится, что это будет свой собственный модуль с hook_form_alter, который прицепит ajax callback к полю выбора термина таксономии и перестроит поле Reference.

Про ajax формы читать здесь. http://drupal.org/node/752056

Аватар пользователя iNFerNo iNFerNo 27 сентября 2012 в 12:38

"Koreychenko" wrote:
reference_option_limit,

Решает маленькую задачу...

связь между текстовым полем и Entity Reference все. причем для одно пары полей.

в филд колекшен - не пашет
в мультигрупах не пашет.

а так выполняет задачу.

Аватар пользователя Orion76 Orion76 27 сентября 2012 в 13:02

Наверное можно и без аякса обойтись.. имеется в виду что поле Node Reference - автозаполняемое?
Наверное логичнее использовать просто список или группу чекбоксов(если выбор "множественный")..

А далее строите ссылку на форму добавления Услуги c параметром, содержащим tid термина Поликлиника.
например node/add/usluga?tid=[tid Термина Поликлиника]
В form_alter фильтруете список Врачей по этому термину..
Все..

Аватар пользователя Koreychenko Koreychenko 27 сентября 2012 в 15:05

Задача решена следующим образом. С аяксом и красиво Wink

Делаем собственный модуль и в нем пишем.

<?php
function dependrefs_form_alter(&$form$form_state$form_id){
if ((
strpos($form_id,'_node_form') !== false)) {
    
$form['field_usluga_doctor']['#prefix'] = '<div id="doctorwrapper">';
    
$form['field_usluga_doctor']['#suffix'] = '</div>';   
    
$form['field_clinic']['und']['#ajax'] = array(
      
'callback' => 'dependrefs_term_callback',
      
'wrapper' => 'doctorwrapper',
      
'method' => 'replace',
      
'effect' => 'fade',
    );
}
}

function 

dependrefs_term_callback($form$form_state) {
    
$opt=array();
   
$query db_select('field_data_field_clinic''f'); 
    
$query->join('node''n''f.entity_id = n.nid');
    
$query->fields('f', array('entity_id')) 
  ->
condition('field_clinic_tid'$form_state['values']['field_clinic']['und'][0]['tid'], '='
  ->
condition('bundle''doctor''='); 
  
$query->fields('n', array('title'));
  
$result $query->execute();
      
  while (
$record $result->fetchAssoc()) { 
  
$opt[$record['entity_id']]=$record['title']; 
}
    
    
 
$form['field_usluga_doctor']['und']['#options']=$opt;
  return 
$form['field_usluga_doctor'];
}
?>

Что здесь происходит:
1. Оборачиваем поле с выбором врачей в div. В этот div будет впоследствии грузиться новая версия поля.

2. Сажаем на поле выбора поликлиник ajax обработчик. При выборе какого-либо элемента этого поля, выбранное значение передается в функцию, которая делает выборку из базы данных по соответствующему условию и формирует новый список элементов поля врачей.

3. Загружаем новую версию поля врачей вместо старой версии.

Аватар пользователя iNFerNo iNFerNo 27 сентября 2012 в 17:27

"Koreychenko" wrote:
Материалы "Услуга" и "Врач" связываются между собой с помощью Entity Reference.

а тут услуга связана с врачем или врач с услугой?

Аватар пользователя Koreychenko Koreychenko 27 сентября 2012 в 17:30

"iNFerNo" wrote:
а тут услуга связана с врачем или врач с услугой?

Услуга связывается с врачем. Т.е. при редактировании у материала "услуга" есть поле "врач".

Аватар пользователя iNFerNo iNFerNo 28 сентября 2012 в 9:20

а если эти 2 поля в мультигруппу, и добавление еще одной гурппы полей. аякс работает?

а если поликлиника и врач не термины? решение ваше наверное не подойдет да?

Аватар пользователя Koreychenko Koreychenko 28 сентября 2012 в 10:56

"iNFerNo" wrote:
а если эти 2 поля в мультигруппу, и добавление еще одной гурппы полей. аякс работает?

Ну а куда он денется ) Только конкретно этот вариант не предусматривает добавление новых элементов на форму, а так сделать аналогичным образом не проблема. Я выше давал ссылку на очень хорошую статью по ajax в drupal 7.

"iNFerNo" wrote:
а если поликлиника и врач не термины? решение ваше наверное не подойдет да?

Поликлиника - это термин. Врач - это нода. Поле Врач на странице Услуга - это Entity Reference. Wink

Тут надо понимать несколько простых вещей.

1. После сабмита вашей формы Entity Reference должен получать id сущности, с которой он свяжет создаваемый материал. В моем случае - это nid материала типа Врач.
2. Вы абсолютно свободно можете изменять список материалов, доступных для выбора. Вы делаете выборку из базы данных по каким-то своим условиям и полностью переопределяете массив опций поля select, главное чтобы массив был в виде array(nid1 => 'label1',nid2 => 'label2'). Тогда после сабмита формы у вас не будет ошибки и все отлично свяжется.

Аватар пользователя iNFerNo iNFerNo 28 сентября 2012 в 11:42

я просто это к тому что тот же reference_option_limit - лишен такой возможности.

Аватар пользователя iNFerNo iNFerNo 28 сентября 2012 в 12:04

"Koreychenko" wrote:
На сайте есть термины таксономии "Поликлиника".
К этому термину таксономии привязаны материалы типа "Врач".
К этому термину таксономии могут быть привязаны материалы типа "Услуга".

могут быть привязаны - это тоже Entity Reference ???

Аватар пользователя Koreychenko Koreychenko 28 сентября 2012 в 12:06

"iNFerNo" wrote:
могут быть привязаны - это тоже Entity Reference ???

Это просто ссылка на термин таксономии.