Score:0

Dynamic Registration Form submission using vanilla Javascript ajax

us flag

I want to use the ajax capability of not refreshing the page or rerouting the user to the registration page. Login / Register dialogue modals have been created. I have the login javascript ajax working perfectly using an ajax call to the login api without any configurations or added modules. I want to integrate the registration form in the same way. I would like the registration to:

  1. show in a modal - this works.
  2. Submit javascript code works with preventDefault
  3. response is failing.

Ajax Post is returning '<' obviously this is returning some html. How do I know how to pass the data in the ajax call and what to expect as a response? My example below:

<style>
.scroll {
  //background-color: #fed9ff;
  //width: 600px;
  height: 500px;
  overflow-x: hidden;
  overflow-y: auto;
  //text-align: center;
  //padding: 20px;
}


.close { 
  margin: 10px 25px 0px;
}
#log-title { 
  margin-left:25px;
}
</style>

<a data-target="#register-modal" data-toggle="modal" class="" id="" href="#register-modal">Register / Create an Account </a>
 
<div id="overlay_container"></div>

 
<!--  Register to download button so stays on same page.  -->
<div id="register-modal" class="modal" tabindex="-1" role="dialog" aria-hidden="true">
  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
    <span aria-hidden="true">&times;</span>
  </button> 
  <h3 id="log-title">Please register:</h3>   
  <div class="modal-dialog">
    <div class="modal-content scroll">
      <?php
        $register_form = \Drupal::service('entity.form_builder')->getForm(\Drupal\user\Entity\User::create([]), 'register', []);    
        // Load the service renderer
        $render = Drupal::service('renderer');
        $rform = $render->renderPlain($register_form);
        echo $rform;
      ?>
    </div> <!-- Register modal content end-->
  </div><!-- Register modal-dialog end -->
</div><!-- Register modal end -->

<script>
  var registerForm = document.getElementById('user-register-form');
  if (registerForm ) {
    // capture registration submit, prevent from submission and use ajax to get response
    registerForm.onsubmit = async (e) => {
      e.preventDefault();
        // callRegCaptcha();
      elms =document.getElementById("user-register-form").elements; 
      var url = "https://website/user/register"; //website is a true url

      fetch(url, {
        method: 'POST',
        body: elms
      })
      .then(response=>response.json())
      .then(json => {
        console.log(json);
      });
    }
  }
</script>

Everything is working except the response. I cant find anywhere what to expect as a response. Or if Im binding the data of elms correctly. Can anyone help me in this area?

The login required a csrfToken to be passed along with

 headers: {
                'Content-Type': 'application/json',
                'X-CSRF-Token': csrfToken
              },

and "?_format=json" appended to the url but for the registration values I am running blindly. Does anyone have any information on what to pass? The response I get is the html page.

Lastly, the Registration has a captcha v2 which outputs the error: "The answer you entered for the CAPTCHA was not correct"

I also looked at this page: https://www.drupal.org/node/2405657

Showing the #Register

POST: https://example.com/user/register?_format=json
Content-type: application/json

{
  "name": { "value": "fooBar" },
  "mail": { "value": "[email protected]" },
  "pass": { "value": "secretSauce" }
}
200 OK

I dont get a json response, it returns the syntax error: unexpected token < in JSON at position 1.

fetch(url, {
            method: 'POST',
            data:  JSON.stringify({
  "name": { "value": "fooBar" },
  "mail": { "value": "[email protected]" },
  "pass": { "value": "secretSauce" }
}),


            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function(data) {
                console.log(data);
                successmessage = 'Data was succesfully captured';
                $("#overlay_container").text(successmessage);
            },
            error: function(data) {
                console.log(data);
                successmessage = 'Error';
                $("#overlay_container").text(successmessage);
            }
        })
        .then(response=>response.json())
        .then(json=> {
            console.log(json);
        }).catch(function(err) {
                        console.log(err);      // shows the above exception
                 });

None of the success: or error is responding, just the catch

Further more, when the _format=json to the url, the following error is reported:

{message: 'Not acceptable format: json'}
message: "Not acceptable format: json"
[[Prototype]]: Object

Next, I have tried to follow this posts response by @Fons Vandamme of installing Rest UI and configuring the user registration

user registration with rest

message: "No user account data for registration received."
[[Prototype]]: Object

Next: under admin extend, changed the authentication from cookies to basic authentication by installing the HTTP basic authentication, navigating to the rest UI configuration for the User registration /user/register: POST and the new error is a 400 Bad Request.

Score:1
us flag

To get this to work, These were the steps taken to get it functional. As per many comments, Follow this links instructions: https://areatype.com/blog/register-user-drupal-8-rest-api

  1. Enable RESTful Web Services, HAL, REST UI, Serialization
  2. Configure Rest UI click 'configure' under extend Rest UI. Enable the 'User registration' resource with the following settings:

       a. path -> /user/register: POST  
       b. methods: POST
       c. formats: hal_json, json
       d. authentication: cookie  "**NOTE**: this maybe avoids credentials for new users..."
  1. Account settings: Under Configuration -> Account settings "Who can register accounts?" -> visitor disable "Require email verification when a visitor creates an account"

  2. RESTful Web Services -> Extend ->RESTful Web Services -> permissions "Access POST on User registration resource" Grant Anonymous user checkbox.

  3. Get Postman for chrome and set it up as such: POST -> url endpoint -> http://{website-name-pointer}/user/register?_format=hal_json Authorization: none Headers: Content-Type:application/json x-csrf-token:OGVi9xj9vemD3BItXOWf4-3ml2maqy-2kk0gkjIRuHk **Get x-csrf-token token through new builder get call ** ** http://{website}/session/token ** it outputs a csrf token in return body.

should look like this:

header: X-CSRF-Token and Content-Type
post url: http://{website-name-pointer}/user/register?_format=hal_json
body:
{
"name":[{"value":"test3"}],
"mail":[{"value":"[email protected]"}],
"pass":[{"value":"test"}]
}

This should return a 200 ok status along WITH the newly registered users uid uuid etc content. as a response just as it would if the registration page were submitted.

NOTE if it is returning the html page "create/register user" in the response body, or other values, it is the settings in the rest ui configuration or the vistor configuration most likely.

If you are receiving other less identifyable status, it is all incorrect. If you are receiving the 500 error it is likely the authentication problem and switch from either cookie to basic authorization or double check the UI settings for authenticators. Number 2 and 3 seemed to be the area of trial and error.

It seems troubleshooting is more difficult than it should be, and it took 3 days of searching the internet for answers and reading a lot of the code change log.

I put this out there to help anyone with similar difficulties getting the process to work effectively.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.