I want add link field (label + url internal/external) in custom form
This not work:
$form['test_ink'] = array(
'#type' => 'link',
'#title' => $this->t('Link title'),
'#url' => '',
);
Drupal Answers is a question and answer site for Drupal developers and administrators. It only takes a minute to sign up.
Sign up to join this communityThe link
(Link) render element type is used to render an anchor element on a page, and not used to provide an input element in a form that is constrained for URLs.
As an example you may look at LinkWidget::formElement, which shows how that field widget creates form elements for a Link field. And the way it does this is to use the url
(Url) form element, which will provide an input element that validates URLs. Make sure that the #url
property is a valid (Url) object.
use Drupal\Core\Url;
$form['test_link'] = [
'#type' => 'url',
'#title' => $this->t('Link title'),
// Example of a Url object from a route. See the documentation
// for more methods that may help generate a Url object.
'#url' => Url::fromRoute('entity.node.canonical', ['node' => 1]),
];
Edit:
url
type is not used, rather the entity_autocomplete
.
use Drupal\Core\Url; $element['test_link'] = [ '#type' => 'link', '#title' => t('Link title'), '#url' => Url::fromRoute('entity.node_type.collection'), ];
I liked @mpp's answer on how to create a linkit field if you have Linkit module enabled. His example was not code formatted, so this is just a repost using formatted code for better readability and to make it easier to copy paste this to use in your own projects. Create a linkit field with Drupal's form api:
$form['block_link'] = [
'#type' => 'linkit',
'#title' => $this->t('Select link target'),
'#description' => $this->t('Start typing to see a list of results. Click to select.'),
'#autocomplete_route_name' => 'linkit.autocomplete',
'#autocomplete_route_parameters' => [
'linkit_profile_id' => 'default',
],
'#default_value' => isset($config['block_link']) ? $config['block_link'] : '',
];
Note that you can change 'default' to any linkit profile you might have in your project. Also note: my default value in this case comes from a block config form because I added this linkit field to a block's settings page. Remove #default_value if it is not applicable to your case or change it depending on where you get your value from.
For anyone stumbling across this post looking at adding Linkit to a config form (thanks @mpp and @Flyke), there's been a slight change in the API: 'linkit_profile_id' => 'default',
should now be 'linkit_profile' => 'default',
$form['block_link'] = [
'#type' => 'linkit',
'#title' => $this->t('Select link target'),
'#description' => $this->t('Start typing to see a list of results. Click to select.'),
'#autocomplete_route_name' => 'linkit.autocomplete',
'#autocomplete_route_parameters' => [
'linkit_profile' => 'default',
],
'#default_value' => isset($config['block_link']) ? $config['block_link'] : '',
];
Small point but worth knowing.
I was facing this problem when I needed to add a link (url+label) to the theme settings form. I didn't use the url field cause it has a bug if the user wants to add an internal link.
This is how it looked on the CMS:
This is the code:
/**
* Implements hook_form_system_theme_settings_alter().
**/
function francisco_form_system_theme_settings_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id = NULL) {
// Work-around for a core bug affecting admin themes. See issue #943212.
if (isset($form_id)) {
return;
}
$form['francisco_theme_option_sidebar'] = array(
'#type' => 'details',
'#title' => t('Sidebar'),
'#description' => t('Lorem ipsum.'),
'#open' => TRUE,
);
$form['francisco_theme_option_sidebar']['francisco_theme_option_sidebar_footer_cta_title'] = array(
'#type' => 'textfield',
'#title' => t('Link Title'),
'#default_value' => theme_get_setting('francisco_theme_option_sidebar_footer_cta_title'),
'#description' => t("Lorem ipsum."),
'#maxlength' => 255
);
$form['francisco_theme_option_sidebar']['francisco_theme_option_sidebar_footer_cta_url'] = array(
'#type' => 'textfield',
'#title' => t('URL'),
'#default_value' => theme_get_setting('francisco_theme_option_sidebar_footer_cta_url'),
'#description' => t("Lorem ipsum."),
'#maxlength' => 2048,
);
}
To add link field (label + url internal/external) & core link widget's url field validation in custom form:
$form['resource_fieldset']['design_tool_link'] = [
'#type' => 'entity_autocomplete',
'#target_type' => 'node',
'#title' => $this->t('Design Tool Link'),
'#description' => $this->t('Select Design Tool Link'),
'#required' => TRUE,
'#element_validate' => [
[
'Drupal\link\Plugin\Field\FieldWidget\LinkWidget',
'validateUriElement',
],
],
'#attributes' => [
'data-autocomplete-first-character-blacklist' => '/#?',
],
'#process_default_value' => FALSE,
'#default_value' => $design_tool_link ?? : '',
];
$form['resource_fieldset']['title'] = [
'#type' => 'textfield',
'#title' => $this->t('Title'),
];
Note: by adding #element_validate attribute :