Change field value and submit node with a custom button - drupal

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
}

Related

SilverStripe DropdownField populated by js - [value] is not a valid option

I've got a SilverStripe form which includes a dropdown field displayed on the front-end of my website.
$fields = new FieldList(
...
DropdownField::create(
'Employer',
'Employer'
)
...
);
....
$actions = new FieldList(
FormAction::create('doReportIssue')->setTitle('Report')
);
$required = new RequiredFields('FirstName', 'LastName');
$form = new Form($this, 'ReportIssueForm', $fields, $actions, $required);
return $form;
I've got some javascript which sets the options in the dropdown.
let employerEl = $("#Form_ReportIssueForm_Employer");
let employers = [{ "name":"employerA" }, { "name":"employerB" }];
employers.forEach((employer) => {
employerEl.append($("<option></option>").val(employer.name).text(employer.name));
});
});
The field is generated correctly in the form, and the javascript correctly populates the options.
However, when I submit the form I get the message
Please select a value within the list provided.
employerA is not a valid option
I don't need this field to be validated server-side.
How do I stop this behaviour from happening?
I worked out a solution, but I'm sure there's a more elegant SilverStripe way of doing it.
I extended the DropdownField class, and made validate always return true.
class NoValidationDropdownField extends DropdownField {
public function validate($validator)
{
return true;
}
}

Drupal 7 - Hide 'remove' button on file field

I have a content type with an image field. Users can create the content and upload an image. I'd like to not allow users to change/remove the image once it was uploaded, but still show the image on the node edit form. So I only need to disable/remove the 'remove' button from the image field.
I tried the following (via hook_form_alter), but it didn't work:
$form['field_image']['#disabled'] = TRUE;
The below works, but it hides the image element completely, which is not what I'm after:
$form['field_image']['#access'] = FALSE;
Please help to find a workaround.
You have to use the hook_field_widget_form_alter function and inside there look for the variable details using dpm() and then alter the button using an attribute from the Forms API.
But I would suggest to make the widget field read only on the edit form and not remove the delete button.
// Hide remove button from an image field
function MYMODULE_field_widget_form_alter(&$element, &$form_state, $context) {
// If this is an image field type
if ($context['field']['field_name'] == 'MY_FIELD_NAME') {
// Loop through the element children (there will always be at least one).
foreach (element_children($element) as $key => $child) {
// Add the new process function to the element
$element[$key]['#process'][] = 'MYMODULE_image_field_widget_process';
}
}
}
function MYMODULE_image_field_widget_process($element, &$form_state, $form) {
//dpm($element);
// Hide the remove button
$element['remove_button']['#type'] = 'hidden';
// Return the altered element
return $element;
}
Useful issues:
Drupal 7: How to alter image field widget "alt" or title" label
How to disable a field or make it readonly in Drupal 7
https://drupal.stackexchange.com/q/32861/12163
You can also do it using hook_form_alter and after_build function
// hook_form_alter implementation
function yourmodule_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'your_form_id':
$form['your_file_field'][LANGUAGE_NONE]['#after_build'][] = 'yourmodule_hide_remove_button';
break;
}
}
// after_build function
function yourmodule_hide_remove_button($element, &$form_state) {
// if multiple files are allowed in the field, then there may be more than one remove button.
// and we have to hide all remove buttons, not just the one of the first file of the field
//
// Array
// (
// [0] => 0
// [1] => 1
// [2] => #after_build
// [3] => #field_name
// [4] => #language
// [5] => ...
// )
//
// the exemple above means we have 2 remove buttons to hide (2 files have been uploaded)
foreach ($element as $key => $value){
if (is_numeric($key)){
unset($element[$key]['remove_button']);
} else break;
}
return $element;
}

Drupal Admin form AJAX callback not working

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;
}

Change field using theme_preprocess_field()

gunwinner is my theme name and i want to change a field on particular content type.
I have tried this code,
function gunwinner_preprocess_field(&$variables) {
$element = $variables['element'];
if($element['#field_name'] == 'field_deal_url') {
$values = $element['#items'][0]['value'];
$deal_link = l(t("Go to Store"), "$values", array('attributes' => array('class' => 'store-link')));
$element['#items'][0]['value'] = "Store";
return;
}
}
which returns me the array with the link title "Go to Store" but it doesn't reflect on the page for the particular field.
Can anyone help me out for this?
You're making a copy of $variables['element'] and manipulating that, so the changes aren't being persisted into the original variable.
Just change the first line of your function to
$element = &$variables['element'];

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