drupal field widget not saving submitted data - drupal

I'm trying to create a custom widget but when I submit, Drupal doesn't seem to save any data. When using hook_field_attach_submit() to display what data I've pasted, it is listed as null.
Strangely, if i change the #type to be a single textfield instead of a fieldset it will save only the first character of the string that has been entered.
This seems like a validation issue, but I'm not sure how to hook into it or to debug the problem. Where can I go from here?
<?php
function guide_field_widget_info(){
dpm("guide_field_widget_info");
return array(
'guide_text_textfield' => array(
'label' => t('test Text field'),
'field types' => array('text'),
'settings' => array('size' => 60),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
'default value' => FIELD_BEHAVIOR_DEFAULT,
),
)
);
}
function guide_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$field_name = $instance['field_name'];
$required = $element['#required'];
$item =& $items[$delta];
$element += array(
'#type' => 'fieldset',
'#title' => t('helloooooooo'),
);
$required = $element['#required'];
$item =& $items[$delta];
$element['nametest'] = array(
'#title' => t('Name'),
'#type' => 'textfield',
'#required' => $required,
// use #default_value to prepopulate the element
// with the current saved value
'#default_value' => isset($item['nametest']) ? $item['nametest'] : '',
);
$element['checkme'] = array(
'#title' => t('Check this box or dont'),
'#type' => 'checkbox',
'#default_value' => isset($item['checkme']) ? $item['checkme'] : '',
);
//When changing the above code to have a single field, $value is no longer null but will display the first character of the string. I've pasted the code I used to test beloe
/*
$element+= array(
'#title' => t('Name'),
'#type' => 'textfield',
'#default_value' => isset($item['nametest']) ? $item['nametest'] : '',
);
*/
return $element;
}
//hooking this here is required given that after submit, the value is a multidimensional array, whereas the expected value of text is, well, text :-)
function guide_field_attach_submit($entity_type, $entity, $form, &$form_state){
dpm($form,"guide_field_attach_submit data"); //shows $form[field_test_field][und][0] [value] as being null
}

hook_field_is_empty is mandatory and has to be implement like following:
/**
* Implements hook_field_is_empty().
*/
function MODULENAME_field_is_empty($item, $field) {
if ($field['type'] == 'FIELDTYPE') {
if (empty($item[$field['type']]['YourField']) ) {
return (TRUE);
}
}
return (FALSE);
}

Related

Drupal 7 Custom Field Widget not saving user input

I'm building a custom field module to work with our streaming video provider. As part of this, I need to grab a video based on a selected category from the provider's API. The field will need to store a number of pieces - the selected category, the selected video, and some additional details (such as a caption) yet to be added.
I can get this form to appear on the node edit page (after attaching the field to a content type), but it doesn't appear to be saving the user's input. Here's the form in place on the edit node screen: Field on node editing screen. Workflow for the user is they select a category, which populates the list of videos to select. When they select a video, they're shown a preview in $element['teacherstv']['teacherstv_video_details']. This is working right up to the point where the user saves the form. At that point, the selected values are lost.
I've looked through the Field API and Forms API docs for D7, but can't see any clear instructions for how to set up this kind of field widget and have it save user input.
Here's the code for hook_field_widget_form()
function teacherstv_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
// $value = $isset($items[$delta['teacherstv']) ? $items[$delta]['teacherstv'] : '';
$widget['#delta'] = $delta;
//lets get an array of our categories from core
$coreapi = new coreapi();
$APIsettings = variable_get('teacherstv_API_settings');
$coreapi->apiuser = $APIsettings['username'];
$coreapi->apipwd = $APIsettings['password'];
$coreapi->apiurl = $APIsettings['api_url'];
$coreapi->sortcriteria = "alpha";
//$categoriesavailable = $coreapi->get_categories();
$categories = coreapi_get_categories();
$defaults = $field['settings'];
$settings = $instance['settings'];
$category = !is_null($form_state['values'][$field['field_name']]['und'][$delta]['teacherstv']['teacherstv_category']) ? $form_state['values'][$field['field_name']]['und'][$delta]['teacherstv']['teacherstv_category'] : $defaults['teacherstv']['defaultcategory'];
switch ($instance['widget']['type']) {
case 'teacherstv':
$element['teacherstv'] = array(
'#tree' => TRUE,
'#type' => 'fieldset',
'#title' => t('TeachersTV Video'),
'#description' => '<p>' . t('Select a video from the TeachersTV service to embed.') . '</p>',
'#delta' => $delta,
);
$element['teacherstv']['teacherstv_category'] = array(
'#type' => 'select',
'#field_parents' => 'teacherstv',
'#title' => t('Video Categories'),
'#options' => $categories,
'#description' => t('Select a video category for a list of videos'),
'#default_value' => !is_null($settings['teacherstv_category']) ? array($settings['teacherstv_category']) : array($category),
'#ajax' => array(
'callback' => 'teacherstv_ajax_videolist',
'wrapper' => 'teacherstv-videolist-' . $delta . '-div',
'method' => 'replace',
),
'#delta' => $delta,
);
$videos = coreapi_list_videos($category);
$videos[0] = "--Please select a video--";
asort($videos);
$element['teacherstv']['teacherstv_video'] = array(
'#type' => 'select',
'#title' => t('Select a video'),
'#field_parents' => 'teacherstv',
'#prefix' => '<div id="teacherstv-videolist-' . $delta . '-div">',
'#suffix' => '</div>',
'#options' => array(0 => 'Video 1'),
'#default_value' =>
isset($form_state['values'][$field['field_name']]['und'][$delta]['teacherstv']['teacherstv_video']) ? $form_state['values'][$field['field_name']]['und'][$delta]['teacherstv']['teacherstv_video'] : NULL,
'#description' => t('Select a video.'),
'#options' => $videos,
'#ajax' => array(
'callback' => 'teacherstv_ajax_videoselect',
'wrapper' => 'teacherstv-videodetails-' . $delta . '-div',
),
'#delta' => $delta,
);
$video_keys = array_keys($videos);
$selected_video = isset($form_state['values'][$field['field_name']]['und'][$delta]['teacherstv_category']) ? $form_state['values'][$field['field_name']]['und'][$delta]['teacherstv_category'] : NULL;
$element['teacherstv']['teacherstv_video_details'] = array(
'#type' => 'markup',
'#field_parents' => 'teacherstv',
'#title' => t('Video details'),
'#prefix' => '<div id="teacherstv-videodetails-' . $delta . '-div">',
'#suffix' => '</div>',
'#description' => t('Details about the video.'),
'#markup' => teacherstv_ajax_render_video($selected_video),
'#delta' => $delta,
);
break;
}
return $element;
}
Its probably the AJAX callback , in your AJAX callback, use
$form_state['rebuild'] = TRUE;
or assign the ajax value to a new element to have it in the $form_state array..
use devel and dpm($form_state). I bet your value is ""

Drupal 7 adding custom menus to pages

I have been developing with Drupal 7 for the past 4 months now, and I can't seem to find a straight answer as to how to add more menus on my pages. I understand the whole system_main_menu and system_secondary_menu, but how in the world can I add more menus to my page if I make a custom menu, let's say I have a footer_social_menu? I just love dynamic menus.
Here's what I am working with right now
function cornmaze_links($variables){
$html = '<ul>';
foreach($variables['links'] as $link){
$html .= '<li>'. l($link['title'], $link['href'], $link).'</li>';
}
$html .= '</ul>';
return $html;
}
I tried using the THEME_links($vars) function, but that affects ALL of the menus, what if I wanted to add a certain ID to a custom menu? or change the custom menu to use all divs? That's what I don't get. I can't necessarily loop through the menus using the THEME_links() function?
I don't want to put them in a block either, if I don't have to, just to avoid any extra markup that I don't need. I just want to be able to control menus, whether they be system or custom.
Any help, or light shed would be awesome! Thank you in advance!
Try menu block module. It creates your menus as blocks and highly configurable.
Here's the documentation link.
Please Check , this may be help ful for you,
function formuserentry_menu() {
$items = array();
$items['formuserentry'] = array( //this creates a URL that will call this form at "examples/form-example"
'title' => 'Entry Page',
'page callback' => array('formuserentry_view'),
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM
);
$items['formuserentry/application'] = array( //this creates a URL that will call this form at "examples/form-example"
'title' => 'Entry Application Forms', //page title
'description' => 'A form to mess around with.',
'page callback' => 'drupal_get_form', //this is the function that will be called when the page is accessed. for a form, use drupal_get_form
'page arguments' => array('formuserentry_application' , 2), //put the name of the form here
'access arguments' => array('administer your module'),
);
return $items;
}
/********** front page view ***********/
function formuserentry_view() {
$result = 'My Sub Menu URL was hit';
$header = array('Entry Id','Name', 'DOB', 'Year', 'Image' );
$rows = array();
$no_yes = array('No', 'Yes');
$results = db_query("SELECT * FROM userentryform ORDER BY userentryId DESC");
foreach ($results as $node) {
$rows[] = array(
l($node->firstname, 'formuserentry/application/'. $node->userentryId ),
array('data' => $node->firstname, 'class' => 'title'),
array('data' => $node->lastname, 'class' => 'type'),
array('data' => $node->birthyear, 'class' => 'type'),
array('data' => '<img src="sample.jpg">dff', 'class' => 'image'),
);
}
return theme('table', array('header' => $header, 'rows' => $rows));
}
/********************** add form ***************************/
function formuserentry_application($form, &$form_state, $candidateId) {
$firstname = '';
$lastname = '';
$birthyear = '';
/****** query fetch ******/
if(isset($candidateId)){
$fetchquery = db_select('userentryform', 'n')
->fields('n', array('firstname','lastname', 'birthyear'))
->fields('n')
->condition('userentryId',$candidateId)
->execute()
->fetchAll();
$firstname = $fetchquery[0]->firstname;
$lastname = $fetchquery[0]->lastname;
$birthyear = $fetchquery[0]->birthyear;
}
/**************************/
//print($fetchquery);
//drupal_set_message('<pre>'. print_r($fetchquery[0]->firstname, TRUE) .'</pre>');
$form['name'] = array(
'#type' => 'fieldset',
'#title' => t('Name'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['name']['first'] = array(
'#type' => 'textfield',
'#title' => t('First Name'),
'#required' => TRUE,
'#default_value' => $firstname,
'#description' => "Please enter your first name.",
'#size' => 20,
'#maxlength' => 20,
);
$form['name']['canid'] = array(
'#type' => 'hidden',
'#required' => FALSE,
'#default_value' => $candidateId,
'#description' => "Please enter your first name.",
'#size' => 20,
'#maxlength' => 20,
);
$form['name']['last'] = array(
'#type' => 'textfield',
'#title' => t('Last name'),
'#value' => $lastname,
'#required' => TRUE,
);
$form['name']['year_of_birth'] = array(
'#type' => 'textfield',
'#title' => "Year of birth",
'#description' => 'Format is "YYYY"',
'#value' => $birthyear,
'#required' => TRUE,
);
// Image upload field.
$form['name']['image'] = array(
'#type' => 'managed_file',
'#title' => 'File',
'#upload_location' => 'public://my-files/',
'#process' => array('formuserentry_my_file_element_process'),
"#upload_validators" => array('file_validate_is_image' => array())
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
/********* for validation ************/
> function formuserentry_my_file_element_process($element, &$form_state,
> $form) { $element = file_managed_file_process($element, $form_state,
> $form); $element['upload_button']['#access'] = FALSE; return
> $element; }
>
> function formuserentry_application_validate($form, &$form_state) {
> $year_of_birth = $form_state['values']['year_of_birth'];
> if ($year_of_birth && ($year_of_birth < 1900 || $year_of_birth > 2000)) {
> form_set_error('year_of_birth', 'Enter a year between 1900 and 2000.');
> } }
/********** form submission ***************/
function formuserentry_application_submit($form, &$form_state) {
$first_name = $form_state['values']['first'];
$last_name = $form_state['values']['last'];
$year_of_birth = $form_state['values']['year_of_birth'];
$profileimage = $form_state['values']['image'];
$canid = $form_state['values']['canid'];
if($canid == '') {
$nid = db_insert('userentryform')
->fields(array(
'firstname' => $form_state['values']['first'],
'lastname' => $form_state['values']['last'],
'birthyear' => $form_state['values']['year_of_birth'],
'profileimage' => $form_state['values']['profileimage'],
))
->execute();
drupal_set_message(t('The form has been Added your last insert ID is => '.$nid));
} else {
$nid = db_update('userentryform')
->fields(array(
'firstname' => $form_state['values']['first'],
'lastname' => $form_state['values']['last'],
'birthyear' => $form_state['values']['year_of_birth']
))
->condition('userentryId',$canid)
->execute();
drupal_set_message(t('The form has been Updated your last insert ID is => '.$nid));
}
drupal_goto("/formuserentry/");
}

My Form Submit Function Is Not Working

I'm developing a custom module for Drupal 6, that creates a simple form. My problem is that the submit function is not being called/processed!!! Here's my code:
function listgroups_menu(){
$items['user/%/groups-settings'] = array(
'title' => 'Groups Settings',
'page callback' => 'listgroups_groups_list',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_LOCAL_TASK,
);
return $items;
}
function listgroups_groups_list ($uid){
/*
* Couple lines here to access the DB & get the user's $groups.
*/
variable_set('listgroups_database_result', $groups );
$output = drupal_get_form('listgroups_settiongs_form');
return $output;
}
/**
* Form Builder
*/
function listgroups_settiongs_form(){
$groups = variable_get('database_result', array());
//Building the form
$form['display_option'] = array(
'#type' => 'checkbox',
'#title' => t('Show my group.'),
);
$form['groups_selection'] = array(
'#type' => 'radios',
'#title' => 'Please select your group',
'#options' => $groups,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return system_settings_form($form);
}
/**
* Submition
*/
function listgroups_settiongs_form_submit($form, &$form_state){
echo "<pre>I'm heeeeeeeeeeeeeeeeeeeeeerr!!!</pre>";
drupal_set_message('Your settings have been saved! YES!!!');
}
Now, the form rendering & the data retrival of the Db is just perfect. It's when I click the submit button, I get nothing at all!! Only the page refreshes & the messages doesn't appear!!
Any idea why?!!!!
use
return $form;
instead of
return system_settings_form($form);
and also
function xyz_form_submit($form, &$form_state){
//echo "<pre>I'm heeeeeeeeeeeeeeeeeeeeeerr!!!</pre>";
drupal_set_message('<pre>I\'m heeeeeeeeeeeeeeeeeeeeeerr!!!</pre>Your settings have been saved! YES!!!');
}
the problem was if you use system_setting_form then it start behaving as a system setting page that is generally used to store some information in database. So making it normal form you need to return only $form.
Include a submit handler and then assign it a function
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#submit' => array('my_module_function_submit'),
);
my_module_function_submit($form, $form_state){
.
.
.
.
.
}
Refer this link https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#submit_property

Drupal Form foreach loop

I wonder if anyone can help me out with this..
I have a foreach loop in a form in drupal which iterates through options for some JQuery sliders.
This works fine.
However I wanted to add a markup field within the loop, so that I could have a header div above wach slider. Instead of looping through each one, it displayed all 4 headers in one go, then all 4 sliders? Is this the correct behaviour? Please see below.
foreach ($categories as $key => $title) {
$form['sliderHead'][$key] = array(
'#type' => 'markup',
'#value' => "<div id='sliderHeaders'>Header Text</div>"
);
$form['vote'][$key] = array(
'#type' => 'slider',
'#title' => $title,
'#name' => $key, // TODO: define it with the $key variable.
'#options' => $options,
);
}
Thanks a lot,
Ross
Because Drupal renders in order of array depth unless you specify a #weight for everything, then it will order by weight.
So if you don't want to use weights you could have done it like this although the suggestion above using #prefix is better for your case:
foreach ($categories as $key => $title) {
$form['slider']['head'][$key] = array(
'#type' => 'markup',
'#value' => "<div id='sliderHeaders'>Header Text</div>"
);
$form['slider']['vote'][$key] = array(
'#type' => 'slider',
'#title' => $title,
'#name' => $key, // TODO: define it with the $key variable.
'#options' => $options,
);
}
Slider is not a valid type. Are you using another module to provide that type?
If so:
foreach ($categories as $key => $title) {
$form['vote'][$key] = array(
'#type' => 'slider',
'#title' => $title,
'#prefix' => t("<div id='sliderHeaders'>Header Text</div>"),
'#name' => $key, // TODO: define it with the $key variable.
'#options' => $options,
);
}
Use the #prefix form attribute.

Drupal - add form element on successful submission

In a Drupal custom module, I want to make $form['link_wrapper'] conditional on a successful submission of the form but this is not a very successful way of doing this. Can anyone suggest better approach.
function my_function_my_form($form_state){
//echo "-" . $form_state['post']['op'] ."-";
//die();
global $base_root;
$form = array();
$form ['query_type'] =array (
'#type' => 'radios',
'#title' => t('Select from available Queries'),
'#options' => array(
"e_commerce_orders" => t("Query1"),
"new_orders" => t("Query2"),
"cancelled_orders" => t("Query3")),
'#required' => TRUE,
);
// only show link when submitted
if($form_state['post']['op'] == 'Submit')
{
$form['link_wrapper'] = array(
'#prefix' => '<div>',
'#value' => l("Click to View file"),
'#suffix' => '</div><br><br>',
);
}
// add submit button
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'));
return $form;
}
Have you tried setting your condition in the validate hook?
Something like:
function my_function_my_form_validate($form_state){
//some condition is true
$form_state['something'] = TRUE;
}
http://api.drupal.org/api/function/hook_validate/6
This is rough. I can't remember the args for hook_validate

Resources