1

As clearly titled I want to send a form values to js file in Drupal 8. I've made some researches and all I successfully coded was sending a PHP variable from a Controller to the JS file I'am using.

Here is the code:

library_name.libraries.yml

library_name:
  version: 1.x
  js:
    js/<js_file_name>.js: {}
  dependencies:
    - core/jquery
    - core/drupalSettings

controller_name.php (class)

namespace Drupal\module_name\Controller;

use Drupal\Core\Controller\ControllerBase;


class <class_name> extends ControllerBase {

  public function <method>(){

      return array(
        '#attached' => array(
            'library' => array(
            '<module_name>/<library_name>'
            ),
            'drupalSettings' => array(
                '<module_name>' => array(
                  '<library_name' => array(
                      'foo' => 'bar'
                  )
                )
            )
        )
      );

  }

js_file_name.js (under /js folder)

console.log(drupalSettings.<module_name>.<library_name>.foo);

Everything works great!

But how about using a form? I've declared a form extending from FormBase and in the submitForm() overridden method I typed the same array:

return array(
        '#attached' => array(
            'library' => array(
            '<module_name>/<library_name>'
            ),
            'drupalSettings' => array(
                '<module_name>' => array(
                  '<library_name' => array(
                      'foo' => 'bar'
                  )
                )
            )
        )
      );

I know this won't work! But any ideas? I thought about using another library, point to a js file there, and use that js file to get the form values using the #attached tag like above, and then send those values to the other js file using JSON

If any one can provide me with a better Drupal Standard? that would be great! cause this my first time using Drupal.


EDIT:

I fixed this, using: the module_name.settings.yml file under module_name/config/install folder and also by using the module_name.module file where I've implemented the hook_form_alter() method.

So,

From my module_name.module file, here goes my code:

/**
 * Implements hook_form_alter().
 */

function modulename_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){


     if($form_id === your_form_id){

        $form['#attached']['library'][] = 'module_name/route_name';
    // that's the route name you've defined in your module_name.libraries.yml file
    // where you've located the js file you're going to use

        $form['#attached']['drupalSettings']
        [module_name][route_name][send_this_variable_to_js] = \Drupal::config(module_name.settings)->get(key);

        return $form;
    }


}

Now in your JS file, you can console.log like this:

console.log(drupalSettings.module_name.route_name.server.send_this_variable_to_js)

Hope this help!

1

You'll either need to add a js behavior that attaches itself to the normal submit event of the form, or create an AJAX Command that invokes a function in your script.

See: https://www.drupal.org/node/2290235

  • Thanks Kevin for the answer! I am still in the same prob since yesterday, trying to find how can I pass through this using the Drupal API... which needs a LOT of time to get used to, for such a beginner like me. – jelhouss Mar 8 '16 at 14:41
  • I've made some changes, switching from FormBase to ConfigFormBase, and also saving all form data in a <module_name>.settings.yml file. However, I have a Javascript file that needs to handle the form data as well, and I am still trying to know what's the best way to do this. Thinking of parsing the YAML file using javascript... it's possible btw... however, I am still searching for a Drupal way to do this. – jelhouss Mar 8 '16 at 14:46
  • In that case, your form ajax submit needs to return an AjaxResponse, you can attach an InvokeCommand to call your jQuery method and pass data as arguments. See this answer which is similar (for D7 though): drupal.stackexchange.com/a/193144/57 – Kevin Mar 8 '16 at 14:55
  • Also see: kalose.net/oss/drupal-8-ajax-forms – Kevin Mar 8 '16 at 14:57
  • Still nothing new Kevin. Here's my code: pastebin.com/khdVNJ3e, see the title. – jelhouss Mar 9 '16 at 10:06
1

#attached only works on a page that is rendered. A form submission isn't, it's redirect and goes to some other page. It also doesn't have a return value.

You need to store this information somewhere, for example in the user session and then display it on the next page.

Alternatively, you could use $form_state->setRebuild(TRUE), store it with $form_state->set(), then buildForm() will be called again and you can add it there to $form. That's however usually only done when you actually explicitly want to keep the user "in" he form, somethink like an upload image or "add another" button.

  • Thanks for answering Berdir! As I have wrote to Kevin, I've made some changes to my code, switching the form from FormBase to ConfigFormBase, and also saving all form data in a <module_name>.settings.yml file. However, I have a Javascript file that needs to handle the form data as well, and I am still trying to know what's the best way to do this. Thinking of parsing the YAML file using javascript... it's possible btw... however, I am still searching for a Drupal way to do this. – jelhouss Mar 8 '16 at 14:47
  • So you store the settings in yaml and then later on need to use it somewhere and send it to JS? That's not a problem, just access the config (in PHP, there is no way you can access that from JS), add it to drupalSettings and you're done? – Berdir Mar 8 '16 at 16:58
  • Hi Bedir, Yes, and I want to send the Values from the submitForm() overriden method (myclass extends from ConfigFormBase), to make sure that the values are in the submit stage so they're safe to send. I tried to attach a js file for let's say debugging to make sure that I can add variables later, this line didn't work: $form['#attached']['library'][] = '<module_name>/<route_name>'; return parent::submitForm($form, $form_state); However in the buildForm() it worked – jelhouss Mar 8 '16 at 18:22
  • Thanks Berdid, I did likely the same solution you've pointed to. – jelhouss Mar 9 '16 at 12:05

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.