Default values of field widgets Drupal 8 - drupal

I have a custom field that extends the ImageField to add a checkbox to the image, similarly to how the image field contains a text field for title and alt information. I can get the checkbox to appear and save values as they show on the formatter page ok, but I cannot figure out how to get the default value for the checkbox. My code initializes the checkbox in formElement function:
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
$field_settings=$this->getFieldSettings();
// Setup how the show_image field is shown on the node edit form.
$element['#show_image'] = $field_settings["show_image"];
return $element;
}
And then creates the checkbox field when the file is uploaded and the process callback function is called:
/**
* {#inheritdoc}
*
* This is a callback from formElement. For example, this could be triggered from an ajax call.
*/
public static function process($element, FormStateInterface $form_state, $form) {
$item = $element['#value'];
$item['fids'] = $element['fids']['#value'];
$element["show_image"] = array(
'#default_value' => $element['#show_image'],
'#type' => 'checkbox',
'#title' => t('Show image on website'),
'#description' => t('This may be from an external source. Show on the website?'),
'#weight' => 10,
'#access' => (bool) $item['fids']
);
return parent::process($element, $form_state, $form);
}
After changing the #default_value key, I can't seem to have the form both display the default setting of "checked" on new uploads, and show the correct value that is saved in previously saved nodes. For example, if I set the
#default_value=>$element['#show_image']
I always get the default value, no matter what the user saves. If I set it like this:
isset($item['show_image']) ? $item['show_image'] : $element['#show_image']
It always shows the saved value, and never the default, even on new uploads. So my question is, how do I show both the default value for new uploads and the saved value for updates?

Related

How do you modify entity references on a form in a custom ajax action in Drupal 8?

I have added a custom button to a form:
$form['actions']['autotag_content'] = [
'#type' => 'button',
'#value' => 'Autotag Content',
'#ajax' => [
'callback' => ['\Drupal\taxonomy_migrate\taggerService', 'tagContent'],
'wrapper' => ['block-adminimal-theme-content'],
'progress' => [
'type' => 'throbber',
'message' => 'Tagging content',
],
],
];
Then in the callback I want to add or remove entities from an entity reference field on the form. This would then get sent back to the browser and rerendered. I don't want the changes to be save, I just want them populated in the form and then the user can accept the changes.
For the sake of this example, I have simplified this to just demonstrate the point. I would like to add two entity references to field_tax_subjects and have the frontend form rerender. Currently, the frontend form rerenders, but doesn't reflect the changes
public static function tagContent(array &$form, FormStateInterface &$form_state) {
$node = $form_state->getFormObject()->getEntity();
$node->field_tax_subjects[] = 12345;
$node->field_tax_subjects[] = 23456;
$form = \Drupal::service('entity.form_builder')->getForm($node);
$form_state->setRebuild();
return $form;
}
my answer is just for in case your ajax is working
because in your question you have'nt full code of form
also its not clear its node form or something else
any way
If your ajax is working you only have to correct how to set value for entity reference field and term reference filed
for entity reference and term reference
public static function tagContent(array &$form, FormStateInterface &$form_state) {
$node = $form_state->getFormObject()->getEntity();
// for entity refrence
$node->field_tax_subjects[]['target_id'] = 12345;
$node->field_tax_subjects[]['target_id'] = 23456;
// for term reference
//$node->field_tax_subjects[]['tid'] = 12345;
//$node->field_tax_subjects[]['tid'] = 23456;
$form = \Drupal::service('entity.form_builder')->getForm($node);
$form_state->setRebuild();
return $form;
}
HOPE THIS HELP YOU
THANKS

Display user's data from database on their profile pages

In Drupal 7, is it possible to show a result of a DB query on each users' respective profile page, in some table? I need to do this programmatically within my existing module. So the input to the query would be the ID of a user whose profile is currently being viewed.
Only to show the queried data - no administration, no edits, nothing else.
something along the lines of.. (image)
Also the block or field or whatever would make this possible needs to be configurable through the _permission() hook as to who can or cannot view it.
I thought since this is basically just a query with no extra custom stuff there would be an easy way via the Drupal API.
you can create custom block for that and view it in current user profile
/**
* Implements hook_block_info().
*/
function custom_block_block_info() {
$blocks = array();
$blocks['my_block'] = array(
'info' => t('My Custom Block'),
'status' => TRUE,
'region' => 'Content',
'visibility' => BLOCK_VISIBILITY_LISTED,
'pages' => 'user/*',
);
return $blocks;
}
/**
* Implements hook_block_view().
*/
function custom_block_view($delta = '')
{
// The $delta parameter tells us which block is being requested.
switch ($delta)
{
case 'my_block':
// Create your block content here
$block['subject'] = t('This is just a test block created programatically');
$block['content'] = _user_detail_list();
break;
}
return $block;
}
/**
* Implements costome code we want to print().
*/
function _user_detail_list(){
//enter your query and output in some variable
$value = "<p>User Detail</p>"
return $value;
}
Note :- Here profile is extended with new block
There will be some coding to get what you want, but if you just want style/show the data that's already available with the "user" object then #1 below will do it.
Easy way(#1):
1. Create a view and choose the "user" info that you need shown and give it a path. Then in your sub-theme use the correct template -see the code snippets.
https://www.drupal.org/forum/support/post-installation/2011-04-04/modify-the-default-profile-pagelayout
other ways:
use the user-profile.tpl.php see
https://api.drupal.org/api/drupal/modules%21user%21user-profile.tpl.php/7.x
in your module, you need to call and reach out to the hook_user_view.
https://api.drupal.org/api/drupal/modules%21user%21user.api.php/function/hook_user_view/7.x
Here you fetch user profile data from database then follow it
function modulename_menu() {
$items['user-data'] = array(
'title' => 'User data',
'page callback' => 'user_data',
'access callback' => ('user_is_logged_in'),
'#type' => MENU_NORMAL_ITEM,
);
return $items;
}
function user_data(){
global $user;
$user_fields = user_load($user->uid);
$output = "" //return those $user_fields values into table using theme('table',header,rows)
return $output;
}
https://www.drupal.org/node/156863 (for create table view)
i.e
global $user;
$user_fields = user_load($user->uid);
$firstname = $user_fields->field_firstname['und']['0']['value'];
$lastname = $user_fields->field_lastname['und']['0']['value'];

Drupal 7 : Is there a way to create a formatter for drupal email field

Is there a way to create a formatter for drupal email field to decrypt when viewed in a view table.
I have tried to create a formatter for the same using the below code
function MYMODULE_field_formatter_info() {
return array(
'views_decrypt_field' => array(
'label' => t('Decrypt this field'),
'field types' => array('textfield'),
),
);
}
function MYMODULE_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$settings = $display['settings'];
$element = array();
if ($display['type'] == 'views_decrypt_field') {
dsm($items);
}
return $element;
}
when I run this code, other fields with "textfield" type shows this formatter.
I am trying to create a generic formatter for all "text" type fields so that if they are encrypted then I can use this formatter in the view to decrypt the same.
N.B: The email field is not showing any formatter dropdown in the field settings in the VIEW.
You need to use all function listing in this page : https://api.drupal.org/api/drupal/modules!field!field.api.php/group/field_formatter/7.x
hook_field_formatter_info => Expose Field API formatter types.
hook_field_formatter_info_alter => Perform alterations on Field API formatter types.
hook_field_formatter_prepare_view => Allow formatters to load information for field values being displayed.
hook_field_formatter_view => Build a renderable array for a field value.

Drupal: adding autocomplete to textfield for custom content type

I've added a custom content type, "Property" (as in, a building). I've added a text field to this content type. At /admin/structure/types/manage/property/fields, this field is displayed as:
Label: Property Region
Machine Name: field_property_region
Field Type: Text
Widget: Text field
When an admin user goes to add a new Property, I'd like this field to display autocomplete suggestions using existing values from other Property nodes. However, no autocomplete circle is displayed in the text input when I load the form page, and no suggestions are displayed when input is entered.
Here's what I've done (in modules/custom/hr_misc.module):
function hr_misc_form_alter(&$form, &$form_state, $form_id)
{
if($form_id == "property_node_form"){
$form['field_property_region']['#autocomplete_path'] = 'hr_misc/autocomplete/property_regions';
dpm($form['field_property_region']);
}
}
When I load the form (at /node/add/property), the dpm() debug output is displayed and includes the #autocomplete_path value as expected.
function hr_misc_menu() {
$items['hr_misc/autocomplete/property_regions/%'] = array(
'page callback' => '_hr_misc_autocomplete_property_regions',
'access callback' => TRUE,
'page arguments' => array(3),
'weight' => 1,
'type' => MENU_CALLBACK,
);
return $items;
}
Most of the examples I've seen don't include the wildcard or passing page_arguments. One did, and it makes sense to me that it should, so I've included it. I've tried both approaches. If I visit
http://mysite/hr_misc/autocomplete/property_regions/Lond
I see the JSON output:
{"London":"London"}
The JSON is produced by the following function:
function _hr_misc_autocomplete_property_regions($string)
{
$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
->propertyCondition('type', 'property')
->fieldCondition('field_property_region', 'value', '%'. $string.'%', 'LIKE');
$result = $query->execute();
$nodes = $result['node'];
// Get all fields attached to a given node type
$fields = field_info_instances('node', 'property');
// Get id of body field
$field_id = $fields['field_property_region']['field_id'];
// Attach a field of selected id only to get value for it
field_attach_load('node', $nodes, FIELD_LOAD_CURRENT, array('field_id' => $field_id));
$items = array();
foreach ($nodes AS $nid => $node) {
$region = $node->field_property_region[LANGUAGE_NONE][0]['value'];
$items[$region] = $region;
}
print drupal_json_output($items);
exit();
}
I'm at a loss. There are loads of articles on adding autocomplete fields, and they all seem to say that this is all you need. Do I need to add something else? The "author" field of my node autocompletes just fine, and I'm not seeing any errors (JS or PHP).

Using Drupal's node form in a new page

In a custom module I want to have a page defined in hook_menu, that shows the add form for a specific content type, with some modifications to the form.
So far it's working, and even saving the new node, but only with the default values I'm setting in the code, i.e. it's not picking up anything the user types into the form. I checked and $form_state['input'] contains the inputted values, but $form_state['values'] doesn't, so the new node gets saved wrong.
Here's the relevant code:
function mymodule_menu() {
return array(
'admin/content/myadd/%' => array(
'title' => 'my custom add page',
'page callback' => 'mymodule_node_add',
'page arguments' => array(3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
),
);
}
function mymodule_node_add() {
module_load_include('inc', 'node', 'node.pages');
//I'm doing a print here instead of returning because I'm calling this page
//in an AJAX popup, so I don't want the whole page to output, only the form.
print render(drupal_get_form('mymodule_node_add_form'));
}
function mymodule_node_add_form($form, &$form_state) {
if (!isset($form_state['node']) {
global $user;
$node = (object) array(
'uid' => $user->uid,
'type' => 'mycontenttype',
'language' => LANGUAGE_NONE,
);
//this is setting a default value
$node->myfield = array(LANGUAGE_NONE => array(array('value' => arg(3))));
$form_state['build_info']['args'] = array($node);
$form = drupal_build_form('mycontenttype_node_form', $form_state);
$form['actions']['submit']['#submit'][0] = 'mymodule_node_add_form_submit';
//there's a lot more customization of the form here, like adding fields, etc.
}
return $form;
}
function mymodule_node_add_form_submit($form, &$form_state) {
//here's where $form_state['input'] is correct but $form_state['values'] isn't.
$node = node_form_submit_build_node($form, $form_state);
node_save($node);
$form_state['values']['nid'] = $node->nid;
$form_state['nid'] = $node->nid;
$form_state['redirect'] = 'some/other/page';
}
So, am I doing something wrong here? Should I be concerned about form ids being wrong? (my form's id is mymodule_node_add_form, but the actual form might output mycontenttype_node_form), would this affect me?
You want hook_form_alter() (see api.drupal.org). I would try to use the existing content type's form and simply alter it with hook_form_alter(). I would also try to first get it working as a standard, non-AJAX page, so you can get all the advantages of dpm() and other debugging techniques. When you have it down solid, then modify it to take advantage of the AJAX techniques.
mymodule_form_alter(&$form, &$form_state, $form_id) {
// use this with your devel module turned on to verify
// your $form_id and contents of all forms that load on a given page
dpm($form);
// once you verify your $form_id, you can begin accessing your form and altering it
switch( $form_id ) {
case 'my_target_form_id' :
// this part is just pseudocode, I haven't memorized the $form structure,
// you can get it from your dpm().
if( $form['node']->type == 'my_target_content_type' ) {
$form['actions']['submit']['#submit'][0] = 'mymodule_node_add_form_submit';
}
break;
}
}

Resources