I have been finding out many users who are having trouble with running #ajax with tableselect, and it seems the problem is specifically when one uses checkboxes.

When a tableselect is created with multiple = false, which means radios buttons on the left column, the #ajax attribute works fine. However with multiple = true, the #ajax attribute doesn't do anything.

CommentFileSizeAuthor
#50 1458824-50.patch2.98 KBtherealssj
#46 1458824-46.patch476 bytestherealssj
#46 1458824-46-tests-only.patch2.51 KBtherealssj
#39 drupal-tableselect-ajax-checkboxes-1458824-39.patch476 bytesmayaz17
#36 1458824-36.patch3.61 KBcwoky
#1 drupal-tableselect-ajax-checkboxes-123456-1.patch915 bytesHenrik Opel
#6 drupal-tableselect-ajax-checkboxes-1458824-6.patch487 bytesJvE
#9 drupal-tableselect-ajax-fixntest-1458824-9.patch2.31 KBJvE
#9 drupal-tableselect-ajax-testonly-1458824-9.patch1.82 KBJvE
#12 drupal-tableselect-ajax-fixntest-1458824-12.patch2.45 KBJvE
#12 drupal-tableselect-ajax-testonly-1458824-12.patch1.96 KBJvE
#14 drupal-tableselect-ajax-checkboxes-1458824-14.patch469 bytesmayaz17
#16 Table Display1.png35.78 KBlearnbydrop
#16 Table Display2.png36.06 KBlearnbydrop
#16 Table row status change.png8.57 KBlearnbydrop
#16 status changed2.png7.99 KBlearnbydrop
#16 search1.png13.21 KBlearnbydrop
#16 noresults.png7.45 KBlearnbydrop
#16 after code modifcations search results working.png8.45 KBlearnbydrop
#16 Update feature.png8.13 KBlearnbydrop
#16 not working.png35.84 KBlearnbydrop
#24 1458824-24.fail_.patch2 KBidebr
#24 1458824-24.patch2.64 KBidebr
#28 interdiff-28-24.txt1.21 KBidebr
#28 1458824-28.fail_.patch2.01 KBidebr
#28 1458824-28.patch2.65 KBidebr
#31 1458824-31.patch3.6 KBidebr
#31 1458824-31.fail_.patch2.96 KBidebr
#31 interdiff-31-28.txt3.6 KBidebr
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Henrik Opel’s picture

Status: Active » Needs review
FileSize
915 bytes

I can confirm the problem. Looking at form_process_tableselect() in form.inc shows that the line which passes the '#ajax' property on to the created child elements is only present in the 'radios' related else part of the if clause, but absent for the default checkbox creation part. Adding the line there fixes the problem on first sight - not sure if this has some negative effects and was left out on purpose, but I doubt that.

The attached patch does just that - add the '#ajax' property passing line from the 'radios' related part to the 'checkboxes' related one as well.

jbeuckm’s picture

This patch works without a pager. However, I have a pager for this tableselect and after paging, the ajax handler is only called on the first checkbox clicked. Subsequent clicks do not fire the checkbox ajax.

UPDATE: This was due to my ajax form causing "An illegal choice has been detected. Please contact the site administrator." -- which I haven't solved yet.

UPDATE2: Hours later, I'm using my own custom ajax pager, which causes the same "illegal choice" error with my dynamically generated options. ['#validated']= TRUE; successfully suppresses the drupal form security feature that was balking at my changed form option values.

jbeuckm’s picture

I have SimpleTests that are failing without this patch. What is the best practice for continuing to SimpleTest my modules until this patch is merged into core?

ashishdalvi’s picture

kevinquillen’s picture

Version: 7.12 » 7.14

Just a follow up on the patch, it works fine if there is no pager.

If you do not have a paged display, it correctly attaches the AJAX callback and properties.

JvE’s picture

Version: 7.14 » 8.x-dev
Issue tags: +Needs backport to D7
FileSize
487 bytes

Rolled a patch for D8 to get it fixed there and marking for backport to D7.

I think the whole tableselect code could do with a review, but let's get the real problems like this fixed first.

This patch will make #ajax work for for checkboxes, but not for the "select all" checkbox that comes with them. This is probably a good thing, but something to be aware of.

nod_’s picture

Issue tags: -Needs tests

@jbeuckm could you post your tests here?

Patch is using tabs.

Other than that it looks good but it needs tests.

nod_’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
JvE’s picture

Status: Needs work » Needs review
Issue tags: +Needs tests
FileSize
2.31 KB
1.82 KB

Okay, my first attempt at tests.
One without fix which should fail and one with fix which should pass.

cosmicdreams’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests, +Needs backport to D7

The last submitted patch, drupal-tableselect-ajax-fixntest-1458824-9.patch, failed testing.

JvE’s picture

Re-rolled for file location changes.

orbistertius’s picture

This fixes the ajax callback if you select one of the options but if you select the "all" checkbox in the table header nothing happens like mentioned in #6. I know that this is an old bug report but it would be nice to get this fixed, please.

mayaz17’s picture

Updated the patch for the current 7.x core version

Status: Needs review » Needs work

The last submitted patch, 14: drupal-tableselect-ajax-checkboxes-1458824-14.patch, failed testing.

learnbydrop’s picture

Title: Ajax doesn't work with Tableselect with checkboxes, but it does with radios » Ajax doesn't work with Tableselect with checkboxes
Version: 8.x-dev » 7.26
Priority: Normal » Major
Status: Needs work » Active
FileSize
35.78 KB
36.06 KB
8.57 KB
7.99 KB
13.21 KB
7.45 KB
8.45 KB
8.13 KB
35.84 KB

Hi,

I written a module with table select form element, but when I search a value with ajax, the tableselect is not showing results.

To resolve this issue, I utilize "form_process_tableselect", so the result is showing perfectly.

But the issue is, when I get search results, I don't perform any action on the results.

Procedure:

1. Form showing new post button ( to add the records )
2. table showing the records with tableselect element
3. Update button working to update the status

4. search a value with search field and button

No results are showing.

Modifications are added in the module like:
$form_html = drupal_render($form['list_form_items']);
changed this line with
$form_html = form_process_tableselect($form['list_form_items']);

4. results are showing, but when I select the check box for status update its not working.

Please check the code and let me know solutions

Example 1: ( no results are showing)

<?php

function advance_form_menu() {
    
    $items['advance-form'] = array(
        'title' => 'Advance form',
        'page callback' => 'user_advance_form_callback',
        //'page arguments' => array('advance_form_mod'),
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK,
    );
    $items['new-items/%'] = array(
        'title' => 'New form',
        'page callback' => 'advance_new_page',
        'page arguments' => array(1),
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );
    $items['change-service-status/%/%'] = array(
        'title' => 'Change service status',
        'page callback' => 'change_service_status',
        'page arguments' => array(1,2),
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );
    
    return $items;
}

function user_advance_form_callback(){


   $build = array();

    // Render your two forms here.
	  $build[] = drupal_get_form('advance_form_mod');
    $build[] = drupal_get_form('advance_user_search');
  

  return $build;
}
/**
 * Implements hook_form().
 */
function advance_form_mod($form, &$form_state) {
    drupal_add_js(drupal_get_path('module','advance_form').'/js/advance_form.js');
    ctools_include('modal');
    ctools_modal_add_js();
    $form = array();
    $slogan_url='new-items/1';
    
    
    $form['url'] = array(
        '#type' => 'hidden',
        '#attributes' => array('class' => array('hs-ajax-button-url')),
        '#value' => url($slogan_url),
    );
    
    $form['ajax_button'] = array(
        '#type' => 'button',
        '#value' => t('New Post'),
        '#attributes' => array('class' => array('ctools-use-modal','ctools-modal-slogan-style')),
        '#id' => 'hs-ajax-button',
    );
    $form['change_status'] = array(
        '#type' => 'fieldset',
        '#title' => t('Change status'),
        '#attributes' => array('class' => array('container-inline')),
    );
    $form['change_status']['operations'] = array(
        '#type' => 'select',
        '#title' => t('Operation'),
//        '#title_display' => 'Change status options',
        '#options' => array('select_status'=>t('Select status'),t('Stop'),t('Start')),
        '#default_value' => 'select_status',
    );
    $form['change_status']['submit'] = array(
        '#type' => 'button',
        '#value' => t('Update'),
        '#ajax' => array(
            'callback' => 'changing_selected_item_status',
            'wrapper' => 'itemlist-div',
            'method' => 'replace',
            'effect' => 'fade',
        ),
    );
    
    $header = array(
        'name' => array('data' => t('Name')),
        'last_name' => array('data' => t('Last name')),
        'status' => array('data' => t('Status')),
        'enable_disable' => array('data' => t('Enable/Disable')),
    );
    
    $query = db_select('advance_form', 'af');
    
    $count_query = clone $query;
    $count_query->addExpression('COUNT(af.advance_form_id)');
    
    $query = $query->extend('PagerDefault')->extend('TableSort');
    $query
        ->fields('af', array('name', 'last_name','advance_form_id','fruite','status'))
        ->limit(5)
        ->orderByHeader($header)
        ->setCountQuery($count_query);
    $result = $query->execute();
    
    foreach ($result as $account) {
        $linkLabel = $account->status?'Stop':'Start';
        $changeStatusTo = $account->status?0:1;
        $options[$account->advance_form_id] = array(
            'name' => $account->name,
            'last_name' =>  $account->last_name,
            'status' =>  '<div id="current_status_'.$account->advance_form_id.'">'.($account->status?'active':'disabled'),
            'enable_disable' => array(
                  'data' => array(
                      '#markup' => "<div id='change_status_".$account->advance_form_id."'>".l($linkLabel,'change-service-status/nojs/'.$changeStatusTo.'-'.$account->advance_form_id,array('attributes' => array('class' => 'use-ajax')))."</div>",
                  ),
            ),
        );
    }
//    echo "<pre>";print_r($options);exit;
    
    
    $form['list_form_items'] = array(
        '#type' => 'tableselect',
        '#header' => $header,
        '#options' => (!empty($options))?$options:array(),
        '#prefix' => '<div id="itemlist-div">',
        '#suffix' => '</div>',
//        '#multiple' => FALSE,
//        '#js_select' => FALSE,
        '#empty' => t('No forms available.'),
      );
    
    $form['pager'] = array('#markup' => theme('pager'));
   
   
    //$form['#executes_submit_callback'] = FALSE;
    return $form;
}
function advance_user_search($form, &$form_state){
    $form['search_area'] = array(
        '#type' => 'fieldset',
        '#title' => t('Search'),
        '#attributes' => array('class' => array('search-container-inline')),
    );
    $form['search_area']['operations'] = array(
        '#type' => 'textfield',
        '#title' => t('Search'),
        '#size' => 40,
        '#default_value' => '',
    );
    $form['search_area']['submit'] = array(
        '#type' => 'button',
        '#value' => t('Search'),
        '#ajax' => array(
            'callback' => 'search_items',
            'wrapper' => 'itemlist-div',
            'method' => 'replace',
            'effect' => 'fade',
        ),
    );
    return $form;
}

function advance_new_form($form, &$form_state) {
    $form['name'] = array(
        '#type' => 'textfield',
        '#title' => t('your name'),
    );
    $form['last-name'] = array(
        '#type' => 'textfield',
        '#title' => t('last name'),
    );
    $form['selected-fruite'] = array(
        '#type' => 'hidden',
        '#value' => $form_state['input']['select-fruite'],
    );
    $form['some_text'] = array(
        '#type' => 'submit',
        '#value' => 'Submit'
    );

    return $form;
}

function advance_new_form_submit(&$form, &$form_state) {
    db_insert('advance_form')->fields(array(
        'name' => $form_state['values']['name'],
        'last_name' => $form_state['values']['last-name'],
        'fruite' => $form_state['input']['selected-fruite'],
        'status' => 1,
    ))->execute();
    // Tell the browser to close the modal.
    
//    echo "<pre>";print_r($form_html);
//    drupal_render($form_html);
//    $form['#redirect'] = '/advance-form';
//    drupal_render($form['list_form_items']);
      $form_state['ajax_commands'][] = ctools_modal_command_dismiss();
      $form_state['ajax_commands'][] = ctools_ajax_command_redirect('advance-form');
}

function advance_new_page($ajax) {
    if ($ajax) {
        ctools_include('ajax');
        ctools_include('modal');


        $form_state = array(
            'ajax' => TRUE,
            'title' => t('New Form'),
        );

        // Use ctools to generate ajax instructions for the browser to create
        // a form in a modal popup.
        $output = ctools_modal_form_wrapper('advance_new_form', $form_state);

        // If the form has been submitted, there may be additional instructions
        // such as dismissing the modal popup.
        if (!empty($form_state['ajax_commands'])) {
            $output = $form_state['ajax_commands'];
        }

        // Return the ajax instructions to the browser via ajax_render().
        print ajax_render($output);
        drupal_exit();
    } else {
        return drupal_get_form('advance_new_form');
    }
}

function changing_selected_item_status($form,&$form_state){
   // echo "<pre>";print_r($form_state['input']['list_form_items']);exit;
//    $form_state['input']['operations'];
    
    foreach($form_state['input']['list_form_items'] as $key => $value){
        if($value){
            if($form_state['input']['operations']==1){
                $num_updated = db_update('advance_form')
                    ->fields(array(
                      'status' => 1,
                    ))
                    ->condition('advance_form_id',$value , '=')
                    ->execute();
            }else{
                $num_updated = db_update('advance_form')
                    ->fields(array(
                      'status' => 0,
                    ))
                    ->condition('advance_form_id',$value , '=')
                    ->execute();
            }
            
        }
    }
    $form = drupal_build_form('advance_form_mod', $form_state);
    
    $form_html = drupal_render($form['list_form_items']);
    return $form_html;
}
//for search
function search_items($form,&$form_state){
    
    $header = array(
        'name' => array('data' => t('Name')),
        'last_name' => array('data' => t('Last name')),
        'status' => array('data' => t('Status')),
        'enable_disable' => array('data' => t('Enable/Disable')),
    );
    $query = db_select('advance_form', 'af');
    $count_query = clone $query;
    $count_query->addExpression('COUNT(af.advance_form_id)');
    $searchValue=$form_state['input']['operations'];
    //echo $searchValue;exit;
    $query = $query->extend('PagerDefault')->extend('TableSort');
    $query
        ->condition('af.name','%'.$searchValue.'%','like')
        ->fields('af', array('name', 'last_name','advance_form_id','fruite','status'))
        ->limit(5)
        ->orderByHeader($header)
        ->setCountQuery($count_query);
    $result = $query->execute();
    //echo "<pre>";print_r($result);exit;
    foreach ($result as $account) {
        $linkLabel = $account->status?'Stop':'Start';
        $changeStatusTo = $account->status?0:1;
        $options[$account->advance_form_id] = array(
            'name' => $account->name,
            'last_name' =>  $account->last_name,
            'status' =>  '<div id="current_status_'.$account->advance_form_id.'">'.($account->status?'active':'disabled'),
            'enable_disable' => array(
                  'data' => array(
                      '#markup' => "<div id='change_status_".$account->advance_form_id."'>".l($linkLabel,'change-service-status/nojs/'.$changeStatusTo.'-'.$account->advance_form_id,array('attributes' => array('class' => 'use-ajax')))."</div>",
                  ),
            ),
        );
    }
    $form['list_form_items'] = array(
        '#type' => 'tableselect',
        '#header' => $header,
        '#options' => (!empty($options))?$options:array(),
        '#prefix' => '<div id="itemlist-div">',
        '#suffix' => '</div>',
        '#empty' => t('No forms available.'),
        '#multiple' => TRUE,
      );
    /*echo "<pre>";
    print_r($form['list_form_items']);exit;*/
    $form_html = drupal_render($form['list_form_items']);

    return $form_html;

}

function change_service_status($type,$status){
    if($type=='ajax'){
        drupal_add_library('system', 'drupal.ajax'); drupal_add_library('system', 'jquery.form');
        list($newStatus,$serviceID)=  explode('-', $status);
        $num_updated = db_update('advance_form')
                        ->fields(array(
                          'status' => $newStatus,
                        ))
                        ->condition('advance_form_id',$serviceID , '=')
                        ->execute();
        $showNewStatus = ($newStatus?'active':'disabled');
        $showLabel = ($newStatus?'Stop':'Start');
        $changeStatus=($newStatus?0:1);
        $commands[] = ajax_command_replace("#current_status_$serviceID", $showNewStatus); 
        $commands[] = ajax_command_replace("#change_status_$serviceID", "<div id='change_status_".$serviceID."'>".l($showLabel,'change-service-status/nojs/'.$changeStatus.'-'.$serviceID,array('attributes' => array('class' => 'use-ajax'))).'</div>'); 
        $page = array('#type' => 'ajax', '#commands' => $commands); 
        ajax_deliver($page);
    }
}

After modifications results are showing:

<?php

function advance_form_menu() {
    
    $items['advance-form'] = array(
        'title' => 'Advance form',
        'page callback' => 'user_advance_form_callback',
        //'page arguments' => array('advance_form_mod'),
        'access arguments' => array('access content'),
        'type' => MENU_CALLBACK,
    );
    $items['new-items/%'] = array(
        'title' => 'New form',
        'page callback' => 'advance_new_page',
        'page arguments' => array(1),
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );
    $items['change-service-status/%/%'] = array(
        'title' => 'Change service status',
        'page callback' => 'change_service_status',
        'page arguments' => array(1,2),
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );
    
    return $items;
}

function user_advance_form_callback(){


   $build = array();

    // Render your two forms here.
	  $build[] = drupal_get_form('advance_form_mod');
    $build[] = drupal_get_form('advance_user_search');
  

  return $build;
}
/**
 * Implements hook_form().
 */
function advance_form_mod($form, &$form_state) {
    drupal_add_js(drupal_get_path('module','advance_form').'/js/advance_form.js');
    ctools_include('modal');
    ctools_modal_add_js();
    $form = array();
    $slogan_url='new-items/1';
    
    
    $form['url'] = array(
        '#type' => 'hidden',
        '#attributes' => array('class' => array('hs-ajax-button-url')),
        '#value' => url($slogan_url),
    );
    
    $form['ajax_button'] = array(
        '#type' => 'button',
        '#value' => t('New Post'),
        '#attributes' => array('class' => array('ctools-use-modal','ctools-modal-slogan-style')),
        '#id' => 'hs-ajax-button',
    );
    $form['change_status'] = array(
        '#type' => 'fieldset',
        '#title' => t('Change status'),
        '#attributes' => array('class' => array('container-inline')),
    );
    $form['change_status']['operations'] = array(
        '#type' => 'select',
        '#title' => t('Operation'),
//        '#title_display' => 'Change status options',
        '#options' => array('select_status'=>t('Select status'),t('Stop'),t('Start')),
        '#default_value' => 'select_status',
    );
    $form['change_status']['submit'] = array(
        '#type' => 'button',
        '#value' => t('Update'),
        '#ajax' => array(
            'callback' => 'changing_selected_item_status',
            'wrapper' => 'itemlist-div',
            'method' => 'replace',
            'effect' => 'fade',
        ),
    );
    
    $header = array(
        'name' => array('data' => t('Name')),
        'last_name' => array('data' => t('Last name')),
        'status' => array('data' => t('Status')),
        'enable_disable' => array('data' => t('Enable/Disable')),
    );
    
    $query = db_select('advance_form', 'af');
    
    $count_query = clone $query;
    $count_query->addExpression('COUNT(af.advance_form_id)');
    
    $query = $query->extend('PagerDefault')->extend('TableSort');
    $query
        ->fields('af', array('name', 'last_name','advance_form_id','fruite','status'))
        ->limit(5)
        ->orderByHeader($header)
        ->setCountQuery($count_query);
    $result = $query->execute();
    
    foreach ($result as $account) {
        $linkLabel = $account->status?'Stop':'Start';
        $changeStatusTo = $account->status?0:1;
        $options[$account->advance_form_id] = array(
            'name' => $account->name,
            'last_name' =>  $account->last_name,
            'status' =>  '<div id="current_status_'.$account->advance_form_id.'">'.($account->status?'active':'disabled'),
            'enable_disable' => array(
                  'data' => array(
                      '#markup' => "<div id='change_status_".$account->advance_form_id."'>".l($linkLabel,'change-service-status/nojs/'.$changeStatusTo.'-'.$account->advance_form_id,array('attributes' => array('class' => 'use-ajax')))."</div>",
                  ),
            ),
        );
    }
//    echo "<pre>";print_r($options);exit;
    
    
    $form['list_form_items'] = array(
        '#type' => 'tableselect',
        '#header' => $header,
        '#options' => (!empty($options))?$options:array(),
        '#prefix' => '<div id="itemlist-div">',
        '#suffix' => '</div>',
//        '#multiple' => FALSE,
//        '#js_select' => FALSE,
        '#empty' => t('No forms available.'),
      );
    
    $form['pager'] = array('#markup' => theme('pager'));
   
   
    //$form['#executes_submit_callback'] = FALSE;
    return $form;
}
function advance_user_search($form, &$form_state){
    $form['search_area'] = array(
        '#type' => 'fieldset',
        '#title' => t('Search'),
        '#attributes' => array('class' => array('search-container-inline')),
    );
    $form['search_area']['operations'] = array(
        '#type' => 'textfield',
        '#title' => t('Search'),
        '#size' => 40,
        '#default_value' => '',
    );
    $form['search_area']['submit'] = array(
        '#type' => 'button',
        '#value' => t('Search'),
        '#ajax' => array(
            'callback' => 'search_items',
            'wrapper' => 'itemlist-div',
            'method' => 'replace',
            'effect' => 'fade',
        ),
    );
    return $form;
}

function advance_new_form($form, &$form_state) {
    $form['name'] = array(
        '#type' => 'textfield',
        '#title' => t('your name'),
    );
    $form['last-name'] = array(
        '#type' => 'textfield',
        '#title' => t('last name'),
    );
    $form['selected-fruite'] = array(
        '#type' => 'hidden',
        '#value' => $form_state['input']['select-fruite'],
    );
    $form['some_text'] = array(
        '#type' => 'submit',
        '#value' => 'Submit'
    );

    return $form;
}

function advance_new_form_submit(&$form, &$form_state) {
    db_insert('advance_form')->fields(array(
        'name' => $form_state['values']['name'],
        'last_name' => $form_state['values']['last-name'],
        'fruite' => $form_state['input']['selected-fruite'],
        'status' => 1,
    ))->execute();
    // Tell the browser to close the modal.
    
//    echo "<pre>";print_r($form_html);
//    drupal_render($form_html);
//    $form['#redirect'] = '/advance-form';
//    drupal_render($form['list_form_items']);
      $form_state['ajax_commands'][] = ctools_modal_command_dismiss();
      $form_state['ajax_commands'][] = ctools_ajax_command_redirect('advance-form');
}

function advance_new_page($ajax) {
    if ($ajax) {
        ctools_include('ajax');
        ctools_include('modal');


        $form_state = array(
            'ajax' => TRUE,
            'title' => t('New Form'),
        );

        // Use ctools to generate ajax instructions for the browser to create
        // a form in a modal popup.
        $output = ctools_modal_form_wrapper('advance_new_form', $form_state);

        // If the form has been submitted, there may be additional instructions
        // such as dismissing the modal popup.
        if (!empty($form_state['ajax_commands'])) {
            $output = $form_state['ajax_commands'];
        }

        // Return the ajax instructions to the browser via ajax_render().
        print ajax_render($output);
        drupal_exit();
    } else {
        return drupal_get_form('advance_new_form');
    }
}

function changing_selected_item_status($form,&$form_state){
   // echo "<pre>";print_r($form_state['input']['list_form_items']);exit;
//    $form_state['input']['operations'];
    
    foreach($form_state['input']['list_form_items'] as $key => $value){
        if($value){
            if($form_state['input']['operations']==1){
                $num_updated = db_update('advance_form')
                    ->fields(array(
                      'status' => 1,
                    ))
                    ->condition('advance_form_id',$value , '=')
                    ->execute();
            }else{
                $num_updated = db_update('advance_form')
                    ->fields(array(
                      'status' => 0,
                    ))
                    ->condition('advance_form_id',$value , '=')
                    ->execute();
            }
            
        }
    }
    $form = drupal_build_form('advance_form_mod', $form_state);
    
    $form_html = drupal_render($form['list_form_items']);
    return $form_html;
}
//for search
function search_items($form,&$form_state){
    
    $header = array(
        'name' => array('data' => t('Name')),
        'last_name' => array('data' => t('Last name')),
        'status' => array('data' => t('Status')),
        'enable_disable' => array('data' => t('Enable/Disable')),
    );
    $query = db_select('advance_form', 'af');
    $count_query = clone $query;
    $count_query->addExpression('COUNT(af.advance_form_id)');
    $searchValue=$form_state['input']['operations'];
    //echo $searchValue;exit;
    $query = $query->extend('PagerDefault')->extend('TableSort');
    $query
        ->condition('af.name','%'.$searchValue.'%','like')
        ->fields('af', array('name', 'last_name','advance_form_id','fruite','status'))
        ->limit(5)
        ->orderByHeader($header)
        ->setCountQuery($count_query);
    $result = $query->execute();
    //echo "<pre>";print_r($result);exit;
    foreach ($result as $account) {
        $linkLabel = $account->status?'Stop':'Start';
        $changeStatusTo = $account->status?0:1;
        $options[$account->advance_form_id] = array(
            'name' => $account->name,
            'last_name' =>  $account->last_name,
            'status' =>  '<div id="current_status_'.$account->advance_form_id.'">'.($account->status?'active':'disabled'),
            'enable_disable' => array(
                  'data' => array(
                      '#markup' => "<div id='change_status_".$account->advance_form_id."'>".l($linkLabel,'change-service-status/nojs/'.$changeStatusTo.'-'.$account->advance_form_id,array('attributes' => array('class' => 'use-ajax')))."</div>",
                  ),
            ),
        );
    }
    $form['list_form_items'] = array(
        '#type' => 'tableselect',
        '#header' => $header,
        '#options' => (!empty($options))?$options:array(),
        '#prefix' => '<div id="itemlist-div">',
        '#suffix' => '</div>',
        '#empty' => t('No forms available.'),
        '#multiple' => TRUE,
      );
    /*echo "<pre>";
    print_r($form['list_form_items']);exit;*/
    $form_html = form_process_tableselect($form['list_form_items']);

    return $form_html;

}

function change_service_status($type,$status){
    if($type=='ajax'){
        drupal_add_library('system', 'drupal.ajax'); drupal_add_library('system', 'jquery.form');
        list($newStatus,$serviceID)=  explode('-', $status);
        $num_updated = db_update('advance_form')
                        ->fields(array(
                          'status' => $newStatus,
                        ))
                        ->condition('advance_form_id',$serviceID , '=')
                        ->execute();
        $showNewStatus = ($newStatus?'active':'disabled');
        $showLabel = ($newStatus?'Stop':'Start');
        $changeStatus=($newStatus?0:1);
        $commands[] = ajax_command_replace("#current_status_$serviceID", $showNewStatus); 
        $commands[] = ajax_command_replace("#change_status_$serviceID", "<div id='change_status_".$serviceID."'>".l($showLabel,'change-service-status/nojs/'.$changeStatus.'-'.$serviceID,array('attributes' => array('class' => 'use-ajax'))).'</div>'); 
        $page = array('#type' => 'ajax', '#commands' => $commands); 
        ajax_deliver($page);
    }
}

Update Status feature is not working

find the screen shots ::

presleyd’s picture

Version: 7.26 » 7.31
Status: Active » Needs review

Patch in 14 has been working for me for over a year now.

kevinquillen’s picture

I concur, that patch is also working perfectly for me and has been used on half a dozen forms with tableselect AJAX inputs.

dcam’s picture

Version: 7.31 » 8.0.x-dev

Re-setting the version back to Drupal 8. Issues must be fixed for the current development version first, then backported.

It looks like there is an 8.x patch in #12. I'm guessing it won't apply anymore, but I'll re-test it next.

The last submitted patch, 12: drupal-tableselect-ajax-fixntest-1458824-12.patch, failed testing.

dcam’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

#12 needs to be rerolled.

idebr’s picture

The last submitted patch, 24: 1458824-24.fail_.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 24: 1458824-24.patch, failed testing.

idebr’s picture

Status: Needs work » Needs review
FileSize
1.21 KB
2.01 KB
2.65 KB

I replaced the call to drupalPostAJAX() with the new drupalPostAjaxForm()

The last submitted patch, 28: 1458824-28.fail_.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 28: 1458824-28.patch, failed testing.

idebr’s picture

Status: Needs work » Needs review
FileSize
3.6 KB
2.96 KB
3.6 KB

Did the empty ajax callback ever pass the testbot? Anyway, I added a valid one.

The last submitted patch, 31: 1458824-31.fail_.patch, failed testing.

omarlopesino’s picture

I applied the patch of mayaz17 (#14) and it worked for me.

nod_ queued 31: 1458824-31.patch for re-testing.

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Patch no longer applies.

cwoky’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
3.61 KB

I rerolled the patch 1458824-31.patch (#31)

gcardinal’s picture

Status: Needs review » Needs work

Tested 1458824-36.patch and it doesn't seem to work. Also it is not possible to add radios / checkboxes within FormStateInterface on #ajax callback.

lokapujya’s picture

Status: Needs work » Needs review

According to the provided test, the AJAX works now with the patch. We use table select with checkboxes in multiple places in Core, but not combined with AJAX. I can't find anything wrong. Possibly the test could do something more than just verifying that the AJAX was executed. The array() can be updated to []. But, I don't see a specific reason mentioned in #37 why this should be "Needs work".

mayaz17’s picture

I updated the patch to work with the current version 7.43

lokapujya’s picture

Status: Needs review » Needs work

For a better assert.

lokapujya’s picture

Status: Needs work » Reviewed & tested by the community

On second thought, the test is ok, this isn't about testing AJAX, just that AJAX is working. So RTBC #36.

alexpott’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed #36 / f6bfa62 and pushed to 8.0.x, 8.1.x and 8.2.x. Thanks!

  • alexpott committed e657998 on 8.2.x
    Issue #1458824 by idebr, JvE, mayaz17, cwoky, Henrik Opel: Ajax doesn't...

  • alexpott committed f6bfa62 on 8.0.x
    Issue #1458824 by idebr, JvE, mayaz17, cwoky, Henrik Opel: Ajax doesn't...
kevinquillen’s picture

WOOO!

therealssj’s picture

therealssj’s picture

Status: Patch (to be ported) » Needs review

The last submitted patch, 46: 1458824-46-tests-only.patch, failed testing.

lokapujya’s picture

Status: Needs review » Needs work

The patch should have the tests.

therealssj’s picture

Patch with tests.

therealssj’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 50: 1458824-50.patch, failed testing.

therealssj’s picture

I am not sure why the test fails.
It works on simplytest and even in local environment.

lokapujya’s picture

Status: Needs work » Needs review
lokapujya’s picture

This has got to be good for D7; It's the same fix. Can any of the original commenters confirm that this fixes their issue?

kwoxer’s picture

Today I was facing the same issue. I have a custom button which does some database stuff and finally adding a new element via Ajax to a tableselect list. Works great so far. Just the the checkboxes are now correctly enabled, though they are enabled. When reloading it is correctly. So abviously a refreshing bug.

I tested so many stuff. And finally I found this one here. So it's a real issue anyway. At least it was not my fault in defining the form. I just tested unset($form_state['input']['my_tableselect']); and it instantly worked.

So yeah give it a try. It will just be fixed in Drupal 8. Is this correct? Or will there also be a fix in Drupal 7?

Hope I could help someone here with Drupal 7.

dddave’s picture

Sorry @kwoxer but overzealous Mollom unpublished your posts.

kwoxer’s picture

Really sad. Because there was always the message, post successfully. Finally it's published. It's ok.

Maybe it was because I had a link to Stackoverflow at the very first. But now it's just the code. I think that's ok, too. :)

lokapujya’s picture

It will just be fixed in Drupal 8. Is this correct? Or will there also be a fix in Drupal 7?

It is committed to Drupal 8. Someone needs to test the Drupal 7 patch in comment #50 and move the issue to RTBC. Then, it may be committed to Drupal 7.

@kwoxer: Thank you for adding that solution. But, what you describe in #60 doesn't seem to be the exact same problem that this issue is about. Actually, it doesn't even seem like a bug; Seems like you just needed to add that code to unset the $form_state for your specific problem. This issue is specifically about the #ajax not even triggering.

kwoxer’s picture

Actually my issue was this one here: http://drupal.stackexchange.com/questions/25131/need-to-force-default-va...

But I reread the description here, that says: "When a tableselect is created with multiple = false, which means radios buttons on the left column, the #ajax attribute works fine. However with multiple = true, the #ajax attribute doesn't do anything.".

This sounds like exactly my issue. :)

As I said, the form_state did not set the checkbox states for me.

Sorry when it's the wrong issue here. But I landed here and maybe someone else with my issue.

botris’s picture

Status: Needs review » Reviewed & tested by the community

Tested this patch and it works.
I have:

$table = array(
  '#type' => 'tableselect',
  '#header' => $header,
  '#options' => $options,
  '#ajax' => array(
    'callback' => 'my_ajax_callback',
    'wrapper' => 'my-wrapper',
  )
);

Without patch nothing happens, with patch ajax callback get's triggered.

presleyd’s picture

We also use this patch on 7 and it works for us. My vote for rtbc status.

Fabianx’s picture

Issue tags: +Pending Drupal 7 commit

RTBC + 1, looks good to me, straightforward bug fix and if this really conflicted somewhere it can still be work-around'ed.

Marked for commit.

stefan.r’s picture

Fabianx’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Pending Drupal 7 commit

Committed and pushed to 7.x! Thanks!

  • Fabianx committed f68bbb9 on 7.x
    Issue #1458824 by idebr, JvE, therealssj, mayaz17, cwoky, Henrik Opel,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.