Drupal Admin form AJAX callback not working - drupal

I am trying to implement an AJAX callback to change a drop down list options based on the values of another drop down.I have looked into the examples online and the examples in the examples module. I am trying to implement the example on one of the admin pages forms.
To simplify, I tried to achieve the following: Just to change the title of the second dropdown with a random number once the first dropdown has changed. Please note that I am using a field collection field.
function myaction_form_alter(&$form, &$form_state, $form_id) {
$form['field_programme_permission']['und']['0']['field_programme']['und']['#ajax']=array(
'event' => 'change',
'callback' => 'programmes_ajax_callback',
'method' => 'replace',
'wrapper' => 'countries_wrapper'
);
$form['field_programme_permission']['und']['0']['field_countries']['und']['#title']=rand(1,100);
return $form;
}
function programmes_ajax_callback($form, $form_state) {
return $form['field_programme_permission']['und']['0']['field_countries'];
}
It is as if programmes_ajax_callback is not triggered at all. I see this Drupal AJAX please wait message but nothing actually happens. The weird thing, If I submit the form and it doesn't pass validation, I don't even see this Drupal AJAX "please wait" message. I have simplified the code as much as possible to try to pin point the problem, but it didn't work...
Any ideas?

The problem was caused by the fact that countries_wrapper didn't actually exist as I was actually calling it countries-wrapper somewhere else.
Find below the code that I have actually used. This code covers a muti-value (up to 10) field collection at which one field (countries) in the field collection is dependent on the other (programme). Hopefully, it will prove to be useful for someone.
function mymodule_form_alter(&$form, &$form_state, $form_id) {
for($i=0;$i<10;$i++) {
if(($form_id=='user_register_form') || ($form_id=='user_profile_form')) {
if(isset($form_state['values']['field_programme_permission'][LANGUAGE_NONE][$i]['field_programme'][LANGUAGE_NONE][0]['tid'])) {
$programme_selected= $form_state['values']['field_programme_permission'][LANGUAGE_NONE][$i]['field_programme'][LANGUAGE_NONE][0]['tid'];
} else {
$programme_selected=0;
}
if(isset($form_state['field']['field_programme_permission']['und']['entity'][$i]->field_programme['und'][0]['tid'])){
$programme_selected=$form_state['field']['field_programme_permission']['und']['entity'][$i]->field_programme['und'][0]['tid'];
}
$form['field_programme_permission'][LANGUAGE_NONE][$i]['field_programme'][LANGUAGE_NONE]['#ajax']=array(
'event' => 'change',
'callback' => '_programmes_ajax_callback',
'method' => 'replace',
'wrapper' => 'countries_wrapper'.$i
);
$form['field_programme_permission'][LANGUAGE_NONE][$i]['field_countries'][LANGUAGE_NONE]['#title']='Countries';
$form['field_programme_permission'][LANGUAGE_NONE][$i]['field_countries'][LANGUAGE_NONE]['#prefix']='<div id="countries_wrapper'.$i.'">';
$form['field_programme_permission'][LANGUAGE_NONE][$i]['field_countries'][LANGUAGE_NONE]['#suffix']='</div>';
$form['field_programme_permission'][LANGUAGE_NONE][$i]['field_countries'][LANGUAGE_NONE]['#options']=_countries_ajax_callback($programme_selected);
}
}
return $form;
}
function _programmes_ajax_callback($form, $form_state) {
//we first need to know the triggering element, to know the index of the countries field that we need to affect.
$index= $form_state['triggering_element']['#field_parents'][2];
return $form['field_programme_permission'][LANGUAGE_NONE][$index]['field_countries'];
}
function _countries_ajax_callback($selected) {
$programme_value = $selected;
$options=array();
if(taxonomy_term_load($programme_value)){
$programme_taxonomy=taxonomy_term_load($programme_value);
if(isset($programme_taxonomy->field_countries[LANGUAGE_NONE])) {
$countries=$programme_taxonomy->field_countries[LANGUAGE_NONE];
foreach($countries as $country) {
$country_tid = $country['tid'];
$country_term = taxonomy_term_load($country_tid);
$country_name = $country_term->name;
$options[$country_tid]=$country_name;
}
}
}
return $options;
}

Related

WordPress publish_{$post_type} hook works only for posts and not for custom post types or pages

I'm trying to send push notification when any of posts, custom post types or pages is published. I'm getting enabled post types from the plugin settings and adding action via foreach loop in my class __construct method. The problem is that it only works for posts and not for any of custom post types or pages. Here is my function and action:
foreach ((array)get_option('PushPostTypes') as $postType) {
add_action("publish_{$postType}", array($this, 'doNewPostPush'), 10, 2);
}
public function doNewPostPush($id, $post) {
$pushData = array(
'title' => $post->post_title,
'body' => strip_tags($post->post_content),
'data' => array(
'url' => trailingslashit(get_permalink($id)),
),
);
if (has_post_thumbnail($id)) {
$pushData['image'] = get_the_post_thumbnail_url($id);
}
$this->sendNotification($pushData);
}
get_option('PushPostTypes') is an array of post types that user choose, for example: array('post', 'page', 'custom_post');
Any idea why it only works for post and not for pages or custom post types?
Your code worked for me, assuming your get_option('PushPostTypes') is working as intended (Obviously I had to mock that).
Try a different approach that does not rely on get_option('PushPostTypes') to see if you get the same result;
add_action('transition_post_status', function ($new_status, $old_status, $post) {
if ($new_status !== 'publish') {
return;
}
// do something
}, 10, 3);
Try the 'transition_post_status' hook that works for all posts without specifically defining them. Put that somewhere just to see if it runs. Do whatever debugging statement that suits you. Then if that works, then move it into Class code and see if that works. I'm debugging by trying to isolate where the first thing goes wrong. Keeping it very simple to get it to work, then gradually adding complexity until it breaks.

Change field value and submit node with a custom button

I am attempting to write a module that adds a button to a node type that, when pressed, will change a value of a field in that node and submit the changes. Everything seems to be working, as the button appears correctly and the node submits when it's pressed, but the value of the field remains unchanged. I feel like I'm missing something obvious.
<?php
function iu_buttons_node_view($node, $view_mode, $langcode) {
if ($node->type == 'billing_entry') {
if ($node->field_status['und'][0]['value'] == 'open') {
$form = drupal_get_form('submit_button_form');
$node->content['submit_button'] = $form;
}
}
}
function submit_button_form($form, &$form_submit) {
$form['submit'] = array(
'#type' => 'button',
'#value' => ('Submit'),
'#submit' => array('submit_button_form_submit'),
);
return $form;
}
function submit_button_form_submit($form, &$form_state) {
$node->field_status['und'][0]['value']['#value'] = 'submitted';
}
It's probably worth noting that the field I'm trying to change is a select list. Should I be using a different function than hook_form_submit?
I am assuming you are writing this code in a custom module named iu_buttons and you want to display this button in the node page, not in the node edit form.
In this case, the problem is that you never saved the node in your submit function. Here is a version of your submit function that will save the node.
function submit_button_form_submit($form, &$form_state) {
$node = menu_get_object(); //get the current node
$node->field_status['und'][0]['value']['#value'] = 'submitted';
node_save($node); // save the changed node
}
I think you may be interested in saving only the field, without the need to save the whole node. In this case, you might use the following:
function submit_button_form_submit($form, &$form_state){
$node = new stdClass(); // Create empty object
$node->nid = intval(args(1)); // Include the nid so that Drupal saves the new value to the correct node
$node->field_status['und'][0]['value']['#value'] = 'submitted';
field_attach_update('node', $node); // Save the field
}

Drupal Hook_Block_View perform action on button click

I am learning drupal and am trying to add some extra features to a module I've made following a tutorial
I have one block 'History' which shows the last x pages you've viewed.
Now I've made a second block with a button 'clear history', but I can't figure out how to make the set_value('trails_block_history','0') happen when my button is clicked (which would clear my history in the database)
anybody who can help me out here?
My blocks:
function trails_block_info() {
$blocks['history'] = array(
'info' => t('History'),
'cache' => DRUPAL_NO_CACHE,
);
$blocks['clearHist'] = array(
'info' => t('Clear history'),
'cache' => DRUPAL_NO_CACHE
);
return $blocks;
}
hook block save:
function trails_block_save($delta = '', $edit = array()) {
variable_set('trails_block_num', $edit['trails_block_num']);
variable_set('trails_block_granularity',$edit['trails_block_granularity']);
}
and the problem:
function trails_block_view($delta = '') {
...
case 'clearHist' :
{
$block['subject'] = 'Clear History';
$block['content'] = '<button>clear history</button>';
} break;
...
Still a student and reaaally new to this (started the module-coding this morning) so sorry if this seems like a stupid question (which it most probably is) but I just can't find it..
Have made another extra feature on the module allready, so I want this one to work as well!
You should use Forms API to create a form with submit button. Then clear your history when form is submitted. More info here and some example code here

how to add a button to drupal forms?

I want to add a custom button to drupal create form so if the user clicked on it instead of submit button, the workflow state of the created object change to another state(not the default first state)
any suggestion?
To modify the default forms generated by drupal you have to add a form_alter hook to your module. You can do it by defining a function like modulename_form_alter assuming the name of your module is modulename. The drupal system passed the form array and the form_state array which you can use to override the default behavior. In your case, the complete function would look something like this.
function modulename_form_alter(&$form, $form_state, $form_id) {
if($form_id == 'what you want') {
$form['buttons']['another_button'] = array(
'#type' => 'submit',
'#value' => 'Add to another state',
'#submit' => array('modulename_custom_form_submit')
);
}
}
function modulename_custom_form_submit($form, &$form_state) {
if($form_state['values']['another_button'] == 'Add to another state') {
//Do your thing
}
}
After you made the necessary modifications, you can simply submit to the default submit action of the creation form.

Drupal 6 Form Api adding an item to an existing form

I want to add a new item into an existing form. I have the ID of the form and I know I need to use hook form_alter but not sure how to add it.
function modulename_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'form id goes here':
// Need to do something here....
break;
}
}
Because the &$form variable is a reference, whatever you do to it changes the original value. so just add it to $form;
//After, need to do something here:
$form['my_new_field'] = array(
'#type' => 'select',
//etc..
);
//You can also add a new validation here:
$form['#validate'][] = 'my_valiation_callback';
See the drupal api ref for better details:

Resources