Hi there,

I think I am about to lose my mind .. how in earths name do I get the value of a field in a widget during creation? I created a custom field widget, and during creation of new content I want to be able to do the following:

I want to create a custom field that I can attach to any content type. This custom field has two elements, a textfield to search for products in MySQL. And a selectbox. The selextbox should get filled with options that match the letters that the user types in the textfield.

I checked field_get_items and a lot more, but I just cannot get it. The code below has elements from a form that I made, so please just overlook those parts. I used DPM($something); everywhere trying to see if I can see the value of $element['searchfield'] anywhere ..

$items = field_get_items('node', $node, 'searchfield'); .. doesnt work, but from what I understand this is only to be used after the node is created .. ie to retrieve the added values, I NEED the values during runtime ...

/**
 * Implements hook_field_widget_form().
 */
function field_zoekproduct_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  switch ($instance['widget']['type']) {
    case 'field_zoekproduct_field' :
	
      $element['searchfield'] = array(
        '#title' => t('Zoek naar een product'),
        '#type' => 'textfield',
        '#maxlength' => 115,
        '#size' => 55,
        '#weight' => 0,
		'#default_value' => 'zoek...',
		'#attributes' => array('onfocus' => "this.value = '';"),  //when textbox gets focus the default value will be removed
		'#ajax' => array(
			  'event' => 'change',
			  'callback' => 'zoekproduct_zoek_getypte_text',
			  'keypress' => true,
			  //'effect' => 'fade',
			  'wrapper' => 'dropdown-second-replace',
			),
    );

// with the piece of code below in a form module I can get the value of the textfield in $selected and
therefor am able to fill my select with options from the database that match $selected .. now How do I do the same with a custom field????

	$options_first = zoekproduct_maak_een_eerste_selectie();
	$selected = isset($form_state['values']['searchfield']) ? $form_state['values']['searchfield'] : key($options_first);

	$element['overzicht_producten'] = array(
		'#type' => 'select',
		'#title' => t('Overzicht producten'),
		'#prefix' => '<div id="dropdown-second-replace">',
		'#suffix' => '</div>',
		'#size'=>1,
		'#validated' => TRUE,
		'#options' => zoekproduct_zoek_naar_getypte_text($selected),
		'#default_value' => isset($item['overzicht_producten']) ? $item['overzicht_producten'] : '',
		'#ajax' => array(
			  'event' => 'change',
			  'callback' => 'zoekproductfield_selecteer_product',
			  'wrapper' => 'find_product',
			),
		); 

      break;
  }
  return $element;
}

Comments

jaypan’s picture

The Drupal Form API already has this functionality - #autocomplete_path. Is there any reason why you aren't using this?

Contact me to contract me for D7 -> D10/11 migrations.

blogook’s picture

yeah, I do .. the database is big (8K+ rows) plus the result set can be like 20+ rows

jaypan’s picture

Why would that preclude using the #autocomplete_path?

Contact me to contract me for D7 -> D10/11 migrations.

blogook’s picture

the result set in some cases can be 100+ .. or more even.. that precludes me

jaypan’s picture

I don't really think it does, but let's ignore that.

You are using Drupal's #ajax in the form. So the value in the field will be part of $form_state['values']. I'd usually say that it would be $form_state['values']['searchfield'], but since you are doing this in a field, it's likely not there. It's probably at $form_state['values']['something']['something_else']['searchfield']. It's been a while since I wrote a custom field, but the values of 'something', 'something_else' and any other depths will be available in $field, $instance, $langcode, $items, $delta, and/or $element. You'll have to first figure out where the value is stored in $form_state['values'], then you'll have to compare the data in the elements I just listed to see how you can retrieve this.

It can be done, it's just a bit of a pain in the butt.

Contact me to contract me for D7 -> D10/11 migrations.

blogook’s picture

found it:

$form['values']['field_zoekproduct']['und']['0']['searchfield'];

The reason why I want to have a selectbox with options is because the database is a nutrition database. I want to create a field that allows users to search for a nutrition, and provide a SQL LIKE resultset based on their search query. The next step would be to scroll up or down in the selectbox to find the nutrition they are after.

but heh, another 'problem' .. the options are not updated .. how do I return the form of a widget? .... bleeeh this is annoying.

function zoekproduct_zoek_getypte_text($element,$form, $form_state,$entity_type, $entity, $field, $instance, $langcode, &$items) {

  return $form['overzicht_producten'];
	} 
jaypan’s picture

Have you looked at the #ajax example in the examples package? That's the first step to understanding the AJAX system. You return the section you want in the ajax callback.

Contact me to contract me for D7 -> D10/11 migrations.

blogook’s picture

yeah I looked at the example. The thing is that $form is different in a field widget.. I am frantically trying to find what I should return :) ... very annoying ....

jaypan’s picture

Set up your callback, and then examine both $form, and $form_state and see what they contain. That's what it always essentially comes down to - finding the information you want/need in the variables you're provided with.

Contact me to contract me for D7 -> D10/11 migrations.

blogook’s picture

If you or someone else could be as kind to point out what I should return you will make me very happy :)

Below a dump from $form in the callback function .. $form_state = empty.

$form	Array [21]	
	build_info	Array [4]	
	programmed	false	
	cache	true	
	node	stdClass	
	field	Array [5]	
	process_input	true	
	has_file_element	true	
	rebuild	true	
	rebuild_info	Array [1]	
	redirect	<Uninitialized>	
	temporary	Array [0]	
	submitted	false	
	executed	false	
	method	post	
	groups	Array [9]	
	buttons	Array [10]	
	no_redirect	true	
	input	Array [25]	
	values	Array [29]	
	complete form	Array [49]	
	triggering_element	Array [25]	
jaypan’s picture

If $form_state is empty, then you have an error somewhere, as it should never been empty in your AJAX callback, since the callback cannot be made without the form being submitted (through AJAX), and if the form is submitted, $form_state is empty.

As for which element to return, it may be somewhere in the 'field' section, but It may also just be that you have a bug somewhere, for as I say, $form_state should not be empty.

Contact me to contract me for D7 -> D10/11 migrations.

blogook’s picture

Believe it or not it is in 'complete form' ..

return $form_state['complete form']['field_zoekproduct'];

this rebuilds my selectbox with options :-)

now next step ..$form_state = empty .. why?

edit:

function was wrong , it expected too many arguments .. the code below works

function zoekproduct_zoek_getypte_text($form, $form_state) {

//dpm($form);

 return $form['field_zoekproduct']['und']['0']['overzicht_producten'];
 
	}