function theme_submit($element) {
  return theme('button', $element);
}

function theme_button($element) {
  return '<input type="submit" ...  />\n";
}

I'm unable to create a simple button with form-api! All buttons are automatically of type="submit".
Form.inc contains to functions for theming a button (look above):
1. theme_submit() what creates a type="submit" button. Perfect.
2. theme_button() what also create a submit button. Why?
I think theme_button() should create a type="button" button instead, right?
And let theme_submit() handle the creation of a submit button.

Comments

profix898’s picture

Sorry. I forgot:
'#button_type' => 'button'
There is an attribute for buttons #button-type. But in form.inc it is completly ignored.
All generated buttons are submit buttons.

I think the code should be:

function theme_submit($element) {
  return '<input type="submit" class="form-'. $element['#button_type'] .'" name="'. $element['#name'] .'" value="'. check_plain($element['#value']) .'" '. drupal_attributes($element['#attributes']) ." />\n";
}

function theme_button($element) {
  return '<input type="'. $element['#button_type'] .'" class="form-'. $element['#button_type'] .'" name="'. $element['#name'] .'" value="'. check_plain($element['#value']) .'" '. drupal_attributes($element['#attributes']) ." />\n";
}

That creates a submit button in theme_submit() and a button of type #button_type
in theme_button().

asiby’s picture

In my version of theme_button(), I have made sure that not every value will be accept for the tag parameter "type". This way, if the type provided by the form element is either "submit", "reset", or "button", then it will be left unchanged since those type exist in the real html world. But if something else is thrown at it, then the html INPUT TAG type will default to "submit".

function theme_button($element) {
	//Begin. By Abdoulaye Siby
	$type = $element['#button_type'];
	switch(strtolower($element['#button_type'])){
		case 'submit':
		case 'reset':
		case 'button':
			break;
		default:
			$type = 'submit';
			break;
	}
	//End. By Abdoulaye Siby
  // Make sure not to overwrite classes.
	if (isset($element['#attributes']['class'])) {
    $element['#attributes']['class'] = 'form-'. $element['#button_type'] .' '. $element['#attributes']['class'];
  }
  else {
    $element['#attributes']['class'] = 'form-'. $element['#button_type'];
  }
	 
  return '<input type="'.$type.'" '. (empty($element['#name']) ? '' : 'name="'. $element['#name'] .'" ')  .'id="'. $element['#id'].'" value="'. check_plain($element['#value']) .'" '. drupal_attributes($element['#attributes']) ." />\n";
}

Live long ... and prosper!

budda’s picture

Excellent stuff. Worked great. Can't believe Drupal 5.xs is still ignoring the '#button_type' out of the box.

--
Ixis (UK) providing Drupal consultancy and Drupal theme design.

johnhanley’s picture

Yeah, I just ran into this problem while trying to add a button with an onclick attribute. #button_type is completely useless and the problem still persists in version 5.7. I don't know how this slipped past testing.

Rather than hacking the core in form.inc, asiby's override function can be added to template.php as phptemplate_button().

sushyl’s picture

Can you please explain where and how to write the phptemplate_button() function. I am new to this.

 function  phptemplate_button($element) {
//Begin.
$type = $element['#button_type'];
switch(strtolower($element['#button_type'])){
case 'submit':
case 'reset':
case 'button':
break;
default:
$type = 'submit';
break;
}
//End.

Does it need any parameters?
Thanks!!

-
Cheers!
Sushil H

johnhanley’s picture

The code is inserted into the theme's template.php file, located in the root of the theme directory. The code may need to be massaged, depending on what you're trying to accomplish.

sushyl’s picture

function  phptemplate_button($element) {

	$type = $element['#button_type'];
	switch(strtolower($element['#button_type'])){
	case 'submit':
	case 'reset':
	case 'button':
	$type = 'button';
	break;
	default:
	$type = 'submit';
	break;
	}
}

But still taking the buttons have type "submit".
Is there anything wrong on above code or i need to make changes in some other files too?
Sorry if its annoying but i am new to drupal coding. :(

-
Cheers!
Sushil H

vaudric’s picture

I believe too button support should be fixed in the core form.inc.
The workaround that worked for me in D7:

Add the following function in your template's template.php file.

<?php
function templatename_button($variables) {
  $element = $variables['element'];
  $type = strtolower($element['#button_type']);
  switch($type){
    case 'submit':
    case 'reset':
    case 'button':
      break;
    default:
      $type = 'submit';
      break;
  }
  $element['#attributes']['type'] = $type;

  element_set_attributes($element, array('id', 'name', 'value'));

  $element['#attributes']['class'][] = 'form-' . $element['#button_type'];
  if (!empty($element['#attributes']['disabled'])) {
    $element['#attributes']['class'][] = 'form-button-disabled';
  }

  return '<input' . drupal_attributes($element['#attributes']) . ' />';
}
?>

and in your form

<?php
  $form['mybutton'] = array(
    '#type'  => 'button',
    '#value' =>  t('mytext'),
    '#button_type' => 'button',
  );  
?>
sushyl’s picture

$form['social']['go'] = array(
'#type' => 'button',
'#value' => t('Go'),
'#button_type' => 'button',
'#prefix' => '

',
'#suffix' => '

',
);

-
Cheers!
Sushil H

btully’s picture

not sure if this is known, but for some reason adding these to my template.php causes a javascript error when adding or editing a node:

drupal.js line 31

"button has no properties"

related to the Drupal.redirectFormButton() function

anyone have a workaround?

usonian’s picture

This works quite well, but if you're relying on the button's 'op' value to drive conditional logic in the form's _submit function (for instance if you have multiple image buttons with different values), you will probably run up against an IE annoyance: IE doesn't pass values from image inputs! I spent several hours tearing my hair out yesterday wondering why my multistep form with its pretty image buttons wasn't working in IE6/7.

I wound up tearing out the custom theming code and implementing the graphic buttons as CSS background images as described in the comments at http://drupal.org/node/51526.

mtsanford’s picture

Drupal seems to want all buttons to be "submit" type. Arg!

motto’s picture

I wasted a lot of time as well assuming Drupal is able to generate a normal button and wondering why it keeps following the action defined in the
-header.

EDDYL’s picture

a real shame for core developpers ! FAPI is supposed to be one of the main elements of drupal and it's still containing bugs from 4.7 !!!

Once again, i lost several hours to fix a core bug with a theme function ...

doobs’s picture

Yep.
Just got me with drupal 6.10.

Jax’s picture

Indeed, both #type button and submit will render a <input type="submit"> But there is also another difference! The description of #type buttons says:
Format an action button. When the button is pressed, the form will be submitted to Drupal, where it is validated and rebuilt. The submit handler is not invoked.

draenen’s picture

'#type' => 'button' will not invoke the submit handler but it will still invoke validation handlers. Why?

--
Caleb Thorne
Developer | Monarch Digital
https://www.calebthorne.com

ibragim’s picture

Yep, vary bad things, i use suffix
$form['gemini_file_role']['gemini_role'] = array(
'#type' => 'checkboxes',
'#title' => t('Roles'),
'#options' => gemini_get_roles(),
'#suffix' => ""

josegaert’s picture

I think that a good way of preventing your button to submit is to use the following. I don't know the inner workings of the DOM or the javascript (jquery) that I use so this is open for discussion.

$('find your button').click( function(e) {
  e.preventDefault();
});

I am in debt to this site:
http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/