0

I have a custom form with text and number fields, saved with a Submit button. In this form, I also have another button which outputs the form data to a PDF (without submitting it).

The code for the pdf button is as follows:

$form['wrapper']['pdf'] = [
    '#type' => 'submit',
    '#name' => 'makepdf',
    '#value' => t('View pdf'),
    '#submit' => array(array($this, 'generatepdf')),
];

My generatepdf() ajax function processes the form data and outputs it to a PDF.

I am using the FPDF, FPDI, and TCPDF libraries to create this PDF. There are only four output options for the completed PDF, and one of them simply loads the PDF in the current tab. There is no native option to output to a new tab.

I understand that there are a variety of workarounds to accomplish this: the FPDF documentation states to "add a target="_blank" to your link or form." This would be fine, but the button creating the PDF is not a link, and adding it to the form would also make the save/submit button open a new tab which I do not want.

I have also tried to change the button calling the PDF generator to an HTML tag of type "a":

$form['wrapper']['pdf'] = [
    '#type' => 'html_tag',
    '#tag' => 'a',
    '#value' => $this->t('View pdf'),
    '#attributes' => ['target' => '_blank'],
    '#ajax' => array(
        'event' => 'click',
        'callback' => array($this, 'generatepdf')
    )
];

but the #ajax attribute does not seem to do anything for this type of form element, nothing happens when I click it.

I have also tried changing it to a Link form element:

$form['wrapper']['pdf'] = [
    '#type' => 'link',
    '#url' => null,
    '#title' => $this->t('View pdf'),
    '#attributes' => ['target' => '_blank'],
    '#ajax' => array(
        'event' => 'click',
        'callback' => array($this, 'generatepdf'),
    )
];

but the link never renders, it is nowhere to be found in the form or in the page inspector.

Is this possible to accomplish using Ajax in drupal forms?

EDIT: I got the Link element to at least show up and show an ajax spinner when clicked:

$form['wrapper']['pdf'] = [
    '#type' => 'link',
    '#url' => Url::fromUserInput('#'),
    '#title' => $this->t('View pdf'),
    '#attributes' => ['target' => '_blank'],
    '#ajax' => array(
        'event' => 'click',
        'callback' => 'generatepdf'
    )
];

When I click on it, the spinner shows, but disappears after a second. Nothing else happens. The generatepdf function is never fired. I even added ddl(true); to the start of the generatepdf() function to see if it is firing, and nothing shows up in the ddl logs.

  • 1
    The render element needs to be a link rather than html_tag, then it'll work. See RenderElement::preRenderAjaxForm – Clive Jun 1 '17 at 15:01
  • I saw that function exists but I don't understand how to use it in the context of a form builder, and I'm having trouble getting a link to render without a target URL. – saramm1 Jun 1 '17 at 15:02
  • You don't use it, the element uses it, e.g. api.drupal.org/api/drupal/…. Reading a bit further you might actually be able to do this with an html_tag, but there's no default event. Add 'event' => 'click' to the ajax property in the render array and you might get a quick win – Clive Jun 1 '17 at 15:07
  • Thanks for clearing that up. I tried adding the event to the html tag code, but clicking it still does nothing. I also tried making a link, but I have no idea where #url should point to (I don't want it to go anywhere, just launch a new tab) and the link element does not render at all, it's nowhere to be found on the page or in the inspector. – saramm1 Jun 1 '17 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.