0

I have a form that has two text areas and three buttons, "Copy", "Reverse" and "Clear". I would like the buttons to, respectively, copy the text from one text area to the other, take the text from the first area and place the reverse of it in the other, and clear both text areas using AJAX.

I know how to do these functions in PHP but I can't seem to get the AJAX to work at all. Here is my existing code, any help would be appreciated:

<?php

    function produce_form() {
    $form['input'] = array(
        '#type' => 'textarea',
        '#title' => t('Input text'),
        '#prefix' => '<div id="in-text">',
        '#value' => '',
        '#attributes' => array(
            'placeholder' => t('Enter some text here... '),
        ),
        '#suffix' => '</div>',
    );

    $form['buttons'] = array(
        '#type' => 'fieldset',
        '#title_display' => 'invisible',
        '#attributes' => array(
            'style' => 'border: 0px; text-align: right',
            'class' => array('container-inline'),
        ),
    );

    $form['buttons']['copy'] = array(
        '#type' => 'button',
        '#value' => 'Copy text',
        '#ajax' => array(
            'callback' => 'copy_text',
            'wrapper' => 'out-text',
//          'method' => 'replace',
//          'effect' => 'fade',
        ),
    );

    $form['buttons']['reverse'] = array(
        '#type' => 'button',
        '#value' => t('Reverse text'),
    );

    $form['buttons']['clear'] = array(
        '#type' => 'button',
        '#value' => t('Clear text'),
    );

    $form['output'] = array(
        '#type' => 'textarea',
        '#title' => t('Output text:'),
        '#prefix' => '<div id="out-text">',
        '#value' => '',
        '#attributes' => array(
            'placeholder' => t('Your text will appear here...'),
        ),
        '#suffix' => '</div>',
    );

    return $form;
    }
    print render(produce_form());

    function copy_text($form, &$form_state){
        $form['output']['#value'] = $form_state['values']['input'];
        return $return['output'];
    }
?>

1 Answer 1

0

Just two problem with your form:

  1. Remove #value element from 'input' element
  2. replace return $return['output']; with return $form['output'];

The problem with #value is that the element gets re-initialised on form render.

Here is the working version(copy button) of your code:

<?php


function playground_menu() {
  $items['playground/form'] = array(
    'title' => 'Form',
    'description' => '',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('playground_demo_form'),
    'access arguments' => array('access content'),
  );
  return $items;
}

function playground_demo_form($form, $form_state) {

  $form['input'] = array(
    '#type' => 'textarea',
    '#title' => t('Input text'),
    '#prefix' => '<div id="in-text">',
    '#attributes' => array(
      'placeholder' => t('Enter some text here... '),
    ),
    '#suffix' => '</div>',
  );

  $form['buttons'] = array(
    '#type' => 'fieldset',
    '#title_display' => 'invisible',
    '#attributes' => array(
      'style' => 'border: 0px; text-align: right',
      'class' => array('container-inline'),
    ),
  );

  $form['buttons']['copy'] = array(
    '#type' => 'button',
    '#value' => 'Copy text',
    '#ajax' => array(
      'callback' => 'copy_text',
      'wrapper' => 'out-text',
//          'method' => 'replace',
//          'effect' => 'fade',
    ),
  );

  $form['buttons']['reverse'] = array(
    '#type' => 'button',
    '#value' => t('Reverse text'),
  );

  $form['buttons']['clear'] = array(
    '#type' => 'button',
    '#value' => t('Clear text'),
  );

  $form['output'] = array(
    '#type' => 'textarea',
    '#title' => t('Output text:'),
    '#prefix' => '<div id="out-text">',
    '#value' => '',
    '#attributes' => array(
      'placeholder' => t('Your text will appear here...'),
    ),
    '#suffix' => '</div>',
  );

  return $form;
}

function copy_text($form, $form_state){
  $form['output']['#value'] = $form_state['values']['input'];
  return $form['output'];
}
11
  • Ok, so at first when I saw your point #2 I felt kind of stupid, it was always meant to be return $form['output'] but at last, it made no difference. Furthermore the only thing removing the #value element did was generate an undefined index notice. Any other ideas? Thanks for your help so far
    – Andy
    Aug 3, 2014 at 9:17
  • I just updated the code that's working in my D7 installation.
    – vijaycs85
    Aug 3, 2014 at 10:46
  • Hmmm, that's strange. I can see that the AJAX is now working as the 'Please wait' text is now appearing and it wasn't before, but the text is not being copied. The only thing I've changed is rather than using playground_menu, I've used print render(drupal_get_form('playground_demo_form')); as this is more suitable for my needs
    – Andy
    Aug 3, 2014 at 11:07
  • In that case, try to use render(druapl_get_form("producer_form")); instead of render directly.
    – vijaycs85
    Aug 3, 2014 at 11:14
  • Sorry, I don't quite understand. There is no producer_form?
    – Andy
    Aug 3, 2014 at 11:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.