The Workflow Transition Form that is displayed on the node is very difficult to theme because the "id" attribute is too specific and there is no "class" attribute to select with.

This is easily fixed:

function workflow_transition_form($form, &$form_state, $field, $instance, $entity_type, $entity) {
  $form['#attributes'] = array('class' => array('workflow-transition-form'));
.
.
.
CommentFileSizeAuthor
#3 2510958-3.patch643 bytesNancyDru
#2 2510958.patch592 bytesNancyDru
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

NancyDru’s picture

For anyone seeing this before it is fixed, this also works:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_workflow_transition_form_alter(&$form, &$form_state, $form_id) {
  $form['#attributes'] = array('class' => array('workflow-transition-form'));
}
NancyDru’s picture

Status: Active » Needs review
FileSize
592 bytes

Patch attached.

NancyDru’s picture

FileSize
643 bytes

Actually, this one seems more consistent.

doxigo’s picture

Nancy I applied the #3 patch but didnt change anything, can you check the patch out please ?

NancyDru’s picture

Status: Needs review » Needs work

I must have had trouble too, because I am now doing this:

function captconnect_custom_form_workflow_transition_form_alter(&$form, &$form_state, $form_id) {
  $current_sid = $form['#default_value'];

  // Put a class wrapper on the form.
  $current_state = workflow_state_load_single($current_sid);
  $class = drupal_html_class('state-' . ($current_state ? workflow_get_sid_label($current_sid) : 'unknown state'));
  $form['#attributes']['class'] = array('workflow-transition-form', $class);
}
doxigo’s picture

Thanks Nancy, How about adding class to each state buttons?

NancyDru’s picture

Yes, that would be nice. I'm still having trouble figuring out how the buttons get there because I try to get rid of the "same state" button (see #2363521: Remove unnecessary action button in Node View page.), but it comes back any way.

doxigo’s picture

Well I end up writing a custom module for adding the classes to my button which is more like a hack and is not the best way to do this since I statically added my buttons ID to it but here's the code in case you need it, also I hide the current state with the following:

function _mymodule_manage_workflow($form, &$form_state) {
    // workflow states
    $arr=array(
         5 => 'wf-b-sold',
         2 => 'wf-b-invisible',
         4 => 'wf-b-publish',
         7 => 'wf-b-expired',
         3 => 'wf-b-unpublish',

    );
    foreach($form['actions'] as $i=>$item){
        if(preg_match ( '/workflow_([0-9]+)/', $i, $matches ) ){
            //add class to workflow buttons
            $form['actions'][$i]['#attributes']['class'][]=$arr[$matches[1]];
            if($form['#default_value']==$matches[1]){
            //hide default workflow button
            hide($form['actions'][$i]);
            }
        }
        }

    return $form;
}
function mymodule_form_alter(&$form, &$form_state, $form_id) {

    if (preg_match ( '/workflow_transition_form_node_([0-9]+)_([0-9]+)/', $form_id, $matches )) {
      $form['#attributes'] = array('class' => array('workflow-transition-form'));
        $form['#after_build'][] = '_mymodule_manage_workflow';
    }
}
johnv’s picture

doxigo’s picture

It can be related but I don't really think it is, this issue is mainly about lack of css class related to each state, I suggest adding state machine name as a class to the button/radio for easier theming of workflow.

johnv’s picture

Can either of you provide a proposal for a definite fix? I see too many different options to decide myself.
I see:
- add class for form;
- add class for button; (there are other issues regarding this.)

Thanks.

doxigo’s picture

Currently if in a page you have a list of nodes and each with a workflow field attached to it, you will end up with a structure like this:

First Node:
form#workflow-transition-form-node-[nodeID]
button#edit-workflow-1
button#edit-workflow-2
button#edit-workflow-3

Second Node:
form#workflow-transition-form-node-[nodeID]
button#edit-workflow-1--2
button#edit-workflow-2--2
button#edit-workflow-3--2

and so on.

I suggest having a simple class for form tag, such as "workflow-field-[nodeID]" and per buttons classes like "workflow-btn-[stateName]" so it's easier to theme, also the same approach for radio buttons.

johnv’s picture

(Using d.o. as my notepad)

This is a radio button in html with values N/A, LABEL_1, LABEL_2:

<div id="edit-field-list-und" class="form-radios">
  <div class="form-item form-type-radio form-item-field-list-und">
    <input id="edit-field-list-und-none" name="field_list[und]" value="_none" class="form-radio" type="radio">
      <label class="option" for="edit-field-list-und-none">N/A </label></div>

  <div class="form-item form-type-radio form-item-field-list-und">
     <input id="edit-field-list-und-KEY_1" name="field_list[und]" value="KEY_1" checked="checked" class="form-radio" type="radio">
       <label class="option" for="edit-field-list-und-a">LABEL_1 </label></div>

  <div class="form-item form-type-radio form-item-field-list-und">
     <input id="edit-field-list-und-KEY_2" name="field_list[und]" value="KEY_2" class="form-radio" type="radio">
       <label class="option" for="edit-field-list-und-KEY_2">LABEL_2</label></div>
</div>

And this is a select list.

<label for="edit-field-workflow-und-0-workflow-workflow-sid">MY_WORKFLOW_LABEL</label>
 <select id="edit-field-workflow-und-0-workflow-workflow-sid" name="field_workflow[und][0][workflow][workflow_sid]" class="form-select">
    <option value="14">LABEL_14</option>
    <option value="11" selected="selected">LABEL_11</option>
    <option value="13">LABEL_13</option>
</select>

And these are the action buttons:


<div class="form-actions form-wrapper" id="edit-actions">
<input class="form-save-default-button form-submit"
            id="edit-workflow-11" name="op" value="eerste &amp; 1" type="submit">
<input id="edit-workflow-14" name="op" value="eerste naar <b>nulde</b>" class="form-submit" type="submit">
<input id="edit-workflow-13" name="op" value="Rules" class="form-submit" type="submit">
<input id="edit-preview" name="op" value="Preview" class="form-submit" type="submit">
<input id="edit-delete" name="op" value="Delete" class="form-submit" type="submit">
</div>

  • johnv committed fc389fe on 7.x-2.x
    Issue #2510958: Added css-classes to Workflow Transition Form
    

  • johnv committed 0b97ec6 on 8.x-1.x
    Issue #2510958: Added css-classes to Workflow Transition Form
    

  • johnv committed 710fd40 on 7.x-2.x
    Issue #2510958: Added css-classes to Workflow Transition Form
    
johnv’s picture

Above commits add classes to the form (on workflow tab and on formatter-as-widget ) and on the workflow-container within the form:

  public function buildForm(array $form, array &$form_state) {
// ...
    // Add class following node-form pattern (both on form and container).
    $workflow_type_id = $workflow->getName();
    $element['workflow']['#attributes']['class'][] = 'workflow-transition-container';
    $element['workflow']['#attributes']['class'][] = 'workflow-transition-' . $workflow_type_id . '-container';
    // Add class for D7-backwards compatibility (only on container).
    $element['workflow']['#attributes']['class'][] = 'workflow-form-container';

// ...

    $form += $element;

    // Add class following node-form pattern (both on form and container).
    $workflow_type_id = $workflow->getName();
    $form['#attributes']['class'][] = 'workflow-transition-form';
    $form['#attributes']['class'][] = 'workflow-transition-' . $workflow_type_id . '-form';

    return $form;
  }

D7 and D8 version are slightly different, as they try to emulate the nodeForm pattern.

johnv’s picture

@doxigo, as I am no themer:
why would you need the class on the button, if even the 'preview' and 'delete' buttons (on node edit page) have a class?
Each button does have an ID:

<input id="edit-workflow-14" ...  value="LABEL_14" class="form-submit" type="submit">
<input id="edit-workflow-13" ...  value="LABEL_13" class="form-submit" type="submit">
<input id="edit-preview" ... value="Preview" class="form-submit" type="submit">
<input id="edit-delete" ... value="Delete" class="form-submit" type="submit">

Can you please create a new issue for the buttons, and add your solution for the removed button to : #2363521: Remove unnecessary action button in Node View page.
(since I'm getting confused)

johnv’s picture

Please use #2545660: Make action buttons more unique for the identifiable/themable action buttons.

johnv’s picture

doxigo’s picture

@johnv, simply having just ID per action buttons is not enough as I mentioned in previous comment, imagine having a list of nodes and each node has a workflow action button, you cannot globally select each states just by using ID.

Here's an example:

States: Unpublish - Publish - Promote - Delete - Upgrade

Now imagine if you want to make "Delete" action buttons red and add an icon next to it.

Unless there's a class for that state, you have to manually select each ID for that button to do so, and if you have more than one workflow field in a page (views page maybe) the ID of the "Delete" buttons will look like this:

First Node's Workflow field: #edit-workflow-1
Second Node's Workflow field: #edit-workflow-1--2
Third Node's Workflow field: #edit-workflow-1--3

and so on.

Based on this pattern, you simply can't select "Delete" buttons using CSS selectors, that's why I suggest adding classes for each action button and radio buttons.

I will create a separate issue for this.

johnv’s picture

@doxigo,
please see #2545660: Make action buttons more unique where I added a class, not an id:
$workflow_submit_button['#attributes']['class'][] = drupal_html_class('workflow_button_' . $option_name)

See also #2366867: Allow CSS/HTML in state / transition labels

kopeboy’s picture

You should let the classes be separate.

Like
class="workflow-button target-state-machine-name"
in case of a form, and
class="workflow-state current-state-machine-name"
in case of a field (shown on Node Display and in a View);

so we can target all of them and any specific one of them with the CSS.

johnv’s picture

I am a nooby in classes, css, etc. A patch is highly appreciated.