Posts Tagged Drupal

Assign attributes to options using FormAPI in Drupal

Drupal FAPI does not support this feature but we can add attributes to options by slightly modifying form.inc file.

You only need to change following line in form.inc file.

<?php
        $options .= '<option value="'. check_plain($key) .'"'. $selected .'>'. 
				check_plain($choice) .'</option>';
	//line no. 1437 of form_select_options() in drupal 6.10
?>

with this

<?php
	$options .= '<option value="'. check_plain($key) .'"'. $selected . 
			drupal_attributes($element['#options_attribute'][$key]) . '>'. 
			check_plain($choice) .'</option>';
?>

You can use like it.

<?php
    $shipping_methods = array('1' => 'Standard Two-Day ($17.00 Total Shipping Price)',
        '2' => 'Priority Overnight ($26.00 Total Shipping Price)',
        '3' => 'FedEx Next Day Delivery $23.95',
        '4' => 'FedEx Next Day Delivery $23.95');
 
    $shipping_method_options = array(
        '1' => array('price' => '17.00', 'class' => 'one'),
        '2' => array('price' => '26.00', 'class' => 'two'),
        '3' => array('price' => '23.95', 'class' => 'three'),
        '4' => array('price' => '23.95', 'class' => 'four'));
 
    $form['default_shipping_method'] = array(
        '#title' => t('Shipping Method'),
        '#type' => 'select',
        '#options' => $shipping_methods,
        '#options_attribute' => $shipping_method_options,
        '#default_value' => variable_get('default_shipping_method', 0),
        '#description' => t('You can change your shipping method from here.'),
    );
?>

, ,

3 Comments


Create Drupal form using theme_table() like module list form

I am showing here an example for Drupal form like you saw in Module list pages.

Drupal Form using theme_table() function

Drupal Form using theme_table() function

I am considering here an example of Featured Product Management form so we can easily understand it.

Step 1:- Create a menu hook for registering your page path. This registered path will display the featured product management page.

<?php
function product_menu() {
	$items = array();
	$items['featured_product_mgmt'] = array(
		‘title’ => ‘Manage featured product’,
		‘page callback’ => ‘drupal_get_form’,
		‘page arguments’ => array(’featured_product_form’),
		‘access arguments’ => array(’access product’),
		‘type’ => MENU_CALLBACK,
	);
    return $items;
}
?>

Step 2:- Create form object for your form. Here the important part is “featured” form element of type “checkboxes”. Checkboxes type is a group of checkbox and format a set of checkboxes. #options is an associative array, where the key is the #return_value of the checkbox and the value is displayed. We will store other information like name, category, discount etc. of product in form array so we can display it later.

<?php
function featured_product_form() {
	$query = “SELECT p.*, UNIX_TIMESTAMP(p.create_date) AS create_date, c.name FROM {product} p LEFT JOIN {category} c ON p.cid = c.cid
	WHERE p.status = 1 ORDER BY p.product_name”;
	$rs = db_query($query);
 
	$featured_products = featured_product();
	$status = array();
 
	if ($rs) {
		while ($data = db_fetch_object($rs)) {
            $options[$data->productid] =;
 
            $form[$data->productid]['name'] = array(#value’ => stripslashes($data->product_name));
            $form[$data->productid]['category'] = array(#value’ => stripslashes($data->name));
            $form[$data->productid]['discount'] = array(#value’ => $data->discount . ‘%’);
            $form[$data->productid]['createdon'] = array(#value’ => date(’m-d-Y’, $data->create_date));
    
            if (in_array($data->productid, $featured_products)) {
                $status[] = $data->productid;
            }
		}
	}
 
	$form['featured'] = array(#type’ => ‘checkboxes’,
#options’ => $options,
#default_value’ => $status,
	);
 
	$form['submit'] = array(#type’ => ’submit’,
#value’ => t(’Submit’),
	);
 
	$form['cancel'] = array(#type’ => ‘markup’,
#value’ => l(t(’Cancel’), ‘dashboard’),
	);
 
	$form['#redirect'] = ‘featured_product_mgmt’;
 
	return $form;
}
?>

Step 3:- Create a form submit function. Any form submitted using the “submit” button will pass to their corresponding function if it is available. We will extract the user input from the form array and update our database accordingly.

<?php
function featured_product_form_submit($form_id, $form) {
	$form_values = $form['values'];
	$featured = $form_values['featured'];
 
	$selected_products = array();
 
	foreach($featured as $key => $value) {
		if ($value) {
			$selected_products[] =($value);
		}
	}
 
	$value_string = @implode(,', $selected_products);
 
	// Delete all previous featured products
	$query = “DELETE FROM {product_featured}”;
	db_query($query);
 
	// Insert new featured products
	if (count($selected_products)) {
		$query = “INSERT INTO {product_featured}(productid) VALUES $value_string”;
		db_query($query);
	}
 
	drupal_set_message(t(’Featured product list has been updated successfully.’));
}
?>

Step 4:- Register your modules theme implementation using “hook_theme()” function.

<?php
function product_theme() {
	return array(
		‘featured_product_form’ => array(‘arguments’ => array(’form’ => NULL),),
	);
}
?>

Step 5:- Then finally define your theme function which actually format your form layout in list using the $form array. Using “foreach” loop we navigate through each item of $form array and create $rows array which we pass to “theme_table()” function later. Create the header of your table and call “table_theme()” function with $header and $rows parameters. Call the “drupal_render()” function for render the submit and cancel buttons.

<?php
function theme_featured_product_form($form) {
	$rows = array();
	foreach (element_children($form) as $key) {
		$row = array();
		if (isset($form[$key]['name'])) {
 
			$status = drupal_render($form['featured'][$key]);
			$row[] = array(’data’ => $status,class=> ‘checkbox’);
 
			$row[] = ‘‘. drupal_render($form[$key]['name']) .’‘;
			$row[] = array(’data’ => drupal_render($form[$key]['category']));
			$row[] = array(’data’ => drupal_render($form[$key]['discount']));
			$row[] = array(’data’ => drupal_render($form[$key]['createdon']));
 
			$rows[] = $row;
		}
	}
 
	// Individual table headers.
	$header = array();
	$header[] = array(’data’ => t(’Featured’),class=> ‘checkbox’);
	$header[] = t(’Name’);
	$header[] = t(’Category’);
	$header[] = t(’Discount’);
	$header[] = t(’Created on’);
 
	$output = theme(’table’, $header, $rows);
	$output .= drupal_render($form);
	return $output;
}
?>

, ,

32 Comments


Add cancel button in your Drupal form

You can add the Cancel button or Cancel link in your Drupal form so you can cancel the form and go back previous page.

Code:-

<?php
$form['submit'] = array(#type’ => ’submit’,
#value’ => t(’Submit’),
);
$form['cancel'] = array(#type’ => ‘markup’,
#value’ => l(t(’Cancel’), ‘category’),
);
?>

This code add a “Cancel” link after “Submit” button.

,

3 Comments


Display menu or tab according to nodetype in Drupal

Sometime your wan’t to display menus and tabs in drupal as per the nodetype. For example, you want “Images” tab in case of nodetype “Hotel” but not want this when story or page nodetype is viewed. In drupal 6.x, the menu system is changed a lot.

Drupal 6.x Code:

<?php
$items['node/%hotel_node/images'] = array(
	‘title’ => ‘Images’,
	‘type’ => MENU_LOCAL_TASK,
	‘weight’ => -10,
	‘page callback’ => ’show_tab_page’,
        ‘page arguments’ => array(1,’images’),
        ‘access callback’ => TRUE,
        ‘access arguments’ => array(1),
);
 
function hotel_node_load($nid) {
	if (is_numeric($nid)) {
		$node = node_load($nid);
        if ($node->type == ‘hotel’) {
            return $node;
        }
    }
	return FALSE;
}
?>

Here, when the menu system is build its call “hotel_node_load()” function with “$nid” as function parameter. We will check the type of node and if the current node type is “hotel” we will return currently loaded node. Otherwise we will return FALSE. This way only node having type “hotel” will display “Images” tab.

Drupal 5.x code:

In drupal 5.x we can do same thing like this.

<?php
	if (arg(0) == ‘node’ && is_numeric(arg(1))) {
		$node = node_load(arg(1));
		if ($node->type == ‘hotel’) {
			$items[] = array(
            	’path’ => ‘node/. arg(1),
                ‘title’ => t(’Images’),
                ‘callback’ => ’show_tab_page’,
                ‘callback arguments’ => array($node),
                ‘access’ => node_access(’view’, $node),
                ‘type’ => MENU_CALLBACK);
		}
	}
?>

For more information click here

,

12 Comments


Styling or modifying drupal primary and secondary tabs like drupal.org

If you want your drupal website’s primary and secondary tabs in same style like drupal.org have in “bluebeach” theme. (See the below graphic.)

Durpal styled tab

Drupal styled tab

Then you have to create a wrapper for tabs so you can put the rounded corner images on both side of tabs. like this

<span class=”a”><span class=”b”>Tab Title</span></span>

But the default “garland” theme does not provide this wrapper. So, you have to put this wrapper by customizing theme. Here I am just illustrating the code that you need to create wrapper around the tabs. After that you need to put the necessary style in your CSS files.

You need to change the “theme_menu_item_link()” to put these wrappers in tab. I am using the code of Drupal 6.9 in this example but I think this approach will work in all versions of Drupal by little tweak.

Existing code:

<?php
	function theme_menu_item_link($link) {
		if (empty($link['localized_options'])) {
			$link['localized_options'] = array();
		}
 
                return l($link['title'], $link['href'], $link['localized_options']);
	}
?>

New code (With changes required)

<?php
	function theme_menu_item_link($link) {
		if (empty($link['localized_options'])) {
			$link['localized_options'] = array();
		}
               if ($link['tab']) {
			$link['title'] =<span class=”a”><span class=”b”>. $link['title'] .</span></span>;
			$link['localized_options'] = $link['localized_options'] + array(’html’ => TRUE);
	       }
 
               return l($link['title'], $link['href'], $link['localized_options']);
        }
?>

, ,

7 Comments