Help ! How to create a Custom Registration Form, to avoid duplicate email registration

Since with the custom wix form, it would failed to show the error message for duplicate email registration, it would keep staying at the page for registration.

I got the reply from Wix Technical Support,
if I require to do the custom validation on the password and login email, the custom Wix form would failed to function well.

Here is the newly create Velo Form, however, the registration failed, and no error message would be pop up, I don’t know what is going wrong.

The registration is required to be approved by System Admin, and the email is required to register.

Here are the coding at the backend.

/*******************************
 * Backend code - register.jsw *
 *******************************/

import { authentication } from 'wix-members-backend';
import { triggeredEmails } from 'wix-crm-backend';

     

// To be called from the registration page code
export async function doRegistration(email, password, options) {
  // Register the member
  
  const registrationOptions = {
        contactInfo: {
          "firstName": options.firstName,
          "lastName" : options.lastName,
          "mainPhone": options.mainPhone,
          "code": options.code,
          "mobile": options.mobile,
          "countryRegion":options.countryRegion,
          "companyName": options.companyName, 
          "companyNameLocal":options.companyNameLocal,
          "crn":options.crn,
          "industry":options.industry,
          "otherIndustry":options.otherIndustry,
          "productLine":options.productLine,
          "productName":options.productName,
          "partner":options.partner,
          "otherPartner":options.otherPartner,
          "webSite":options.webSite,
          "postalCode":options.postalCode,
          "address":options.address
       }
    };
  
  
  const registration = await authentication.register(email, password, registrationOptions);
  console.log('Member is now registered with the site and pending approval');

  // Send a registration confirmation email
  const emailOptions = {
    variables: {
      name: registrationOptions.firstName,
      verifyLink: `http://yourdomain.com/post-register?token=${registration.approvalToken}`
    }
  };
  triggeredEmails.emailMember('verifyRegistration', registration.member._id, emailOptions);
  console.log('Confirmation email sent');
}

// To be called from the post-registration page code
export async function doApproval(token) {
  try {
    // Approve the member
    const sessionToken = await authentication.approveByToken(token);
    console.log('Member approved');
    return {
      approved: true,
      sessionToken: sessionToken
    };
  } catch (error) {
    // If an error is encountered and the member can't be approved
    console.log('Member not approved');
    return {
      approved: false,
      reason: error
    };
  }
}

Here is coding at my frontend

// Velo API Reference: https://www.wix.com/velo/reference/api-overview/introduction

import wixLocation from 'wix-location';
import { doRegistration, chkValidEmail } from 'backend/reg';
import wixWindow from 'wix-window';
import {session } from 'wix-storage';

$w.onReady(function () {

        $w('#txtPassword').inputType = "password";
        $w('#txtConfirmedPassword').inputType = "password";
        wixWindow.lightbox.close();

    

    // Write your Javascript code here using the Velo framework API

    // Print hello world:
    // console.log("Hello world!");

    // Call functions on page elements, e.g.:
    // $w("#button1").label = "Click me!";

    // Click "Run", or Preview your site, to execute your code

});

/**
*   Adds an event handler that runs when the element is clicked.
    [Read more](https://www.wix.com/corvid/reference/$w.ClickableMixin.html#onClick)
*    @param {$w.MouseEvent} event
*/
export function btnSubmit_click(event) {
    // This function was added from the Properties & Events panel. To learn more, visit http://wix.to/UcBnC-4
    // Add your code for this event here: 
       let validationMessage ="";
       let firstName= $w('#txtFirstName').value ;
       let lastName = $w('#txtLastName').value;
       let mainPhone =$w('#txtTel').value;
       let code =$w('#dropdown1').value;
       let mobile =$w('#input6').value;
       let countryRegion =$w('#ddlCountryRegion').value;
       let companyName =$w('#txtCompanyNameEng').value;
       let companyNameLocal =$w('#txtCompanyLocal').value; //default
       let crn =$w('#txtCRN').value;

       let industry =$w('#chkgIndustry').value;
       let otherIndustry =$w('#txtOthersIndustry').value;
       let productLine =$w('#chkgProductLine').value;
       let productName =$w('#txtProductName').value;
       let partner = $w('#chkgPartner').value;
       let otherPartner =$w('#txtOtherPartner').value;
       let webSite =$w('#companyWebSite').value;
       let postalCode =$w('#txtPostalCode').value;
       let address =$w('#addressInputCompany').value;

       let email = $w('#txtEmail').value;
       let password =$w('#txtPassword').value;
       let confirmedPassword =$w('#txtConfirmedPassword').value;
       let validationPass = false;
       
       $w('#errMessage').text ="";
       let options = {
        contactInfo: {
          "firstName": firstName,
          "lastName" : lastName,
          "mainPhone": mainPhone,
          "code": code,
          "mobile": mobile,
          "countryRegion":countryRegion,
          "companyName": companyName, 
          "companyNameLocal":companyNameLocal,
          "crn":crn,
          "industry":industry,
          "otherIndustry":otherIndustry,
          "productLine":productLine,
          "productName":productName,
          "partner":partner,
          "otherPartner":otherPartner,
          "webSite":webSite,
          "postalCode":postalCode,
          "address":address
       }
    }

    $w("#txtEmail").onCustomValidation((value, reject) => {
        let emaildomain = $w("#txtEmail").value;
        //let emaildomain = value;
        let firstCut = emaildomain.substring(emaildomain.lastIndexOf('@') + 1, emaildomain.lastIndexOf('.'));

        //console.log("firstCut " + firstCut);

        if (firstCut.toLowerCase() === "gmailxxx" || firstCut.toLowerCase() === "hotmail" || firstCut.toLowerCase() === "outlook" || firstCut.toLowerCase() === "yahoo") {
            validationMessage +=("Email address must be a company email address./n")
            reject("Email address must be a company email address.");
        }

        chkValidEmail(value)
        .then((result) => {
                if (result.succeeded === true) {
                    console.log ("success") ;
                } else {
                    if (result.succeeded === false) {
                         if (result.returnMessage === "This email is already in use") {
                             $w('#errMessage').text ="This email is already in use"
                           reject ("This email is already in use");
                        } else {
                            reject ("Fail to get the database record");
                        }
                    } else {
                         reject ("Fail to get the database record");
                    }
                }
            })
            .catch((err) => {
                  reject ("Fail to get the database record");
            });

    });

      $w("#txtConfirmedPassword").onCustomValidation((value, reject) => {
        let password1 = $w("#txtPassword").value;
        let password2 = value;

         if (password1 === password2) {
            console.log("They match!");
            
          //  $w('#btnSubmit').enable

        } else {
             validationMessage +="Password and Confirmed Password should be match/n";

            //$w('#btnSubmit').disable
            console.log("Password and Confirmed Password are not match");
            validationPass =false ;
            reject("Password and Confirmed Password are not match");
        }
      

           let regExp = new RegExp(/^(?=^.{8,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$/);

            if (regExp.test(password1))

            {

                console.log ("password match the pattern" )
                    validationPass= true;
            } else {    
                validationMessage += "password must be at least 8 characters and containing nubmer and alaphbet, upper case and lower case/n"
                console.log('password must be at leat 8 characters and containing nubmer and alaphbet with both upper case and lower case');
                $w('#errMessage').text ="password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case";
                $w('#errMessage').show;
                reject('password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case');
 
            }

                doRegistration( email, password, options)
            .then((result) => {
                if (result.succeeded === true) {
                    console.log ("success") ;
                    session.setItem("email", email);
                      wixLocation.to ('/registerSuccess');
                } else {
                    if (result.succeeded === false) {
                         if (result.returnMessage === "This email is already in use") {
                             $w('#errMessage').text ="This email is already in use"
                           reject ("This email is already in use");
                        } else {
                            reject ("Fail to get the database record");
                        }
                    } else {
                         reject ("Fail to get the database record");
                    }
                }
            })
            .catch((err) => {
                  reject ("Fail to get the database record");
            });

       
                  //  $w("#lblMessage").text =validationMessage;
                   // $w("#lblMessage").show;
    })

    

     $w('#errMessage').text =validationMessage;
      $w('#errMessage').show;
}

/**
*   Adds an event handler that runs when an input element's value
 is changed.
    [Read more](https://www.wix.com/corvid/reference/$w.ValueMixin.html#onChange)
*    @param {$w.Event} event
*/

/**
*   Adds an event handler that runs when an input element's value
 is changed.
    [Read more](https://www.wix.com/corvid/reference/$w.ValueMixin.html#onChange)
*    @param {$w.Event} event
*/
export function chkViewPassword_change(event) {
    // This function was added from the Properties & Events panel. To learn more, visit http://wix.to/UcBnC-4
    // Add your code for this event here: 
            console.log ("checked ? " + $w('#chkViewPassword').checked);
           if ($w('#chkViewPassword').checked){
            $w('#txtPassword').inputType = "text";
            $w('#txtConfirmedPassword').inputType = "text";

            
    } else {
          $w('#txtPassword').inputType = "password";
          $w('#txtConfirmedPassword').inputType = "password";
    }
}

Here is the frontend layout.


Finally, I give up to use the default “custom registration form”, which is the default option would be displayed if you choose custom registration form.

  1. If I using the pure velo form without lightbox, I could only register users with email only. I don’t know why the rest of the fields could not add to the members records.

  2. If I using the new velo form with lightbox, since no member registration form for me to choose, I chose the closest alternative, the contact form; the contact form is successfully added to the contact database, however, newly added contact only, it would not registered the user as a site members.

  3. Since the duplicate email could not show after registration, the duplicate email checking is added to the form, when clicking on the submit button.
    Here is my coding:

import wixLocation from ‘wix-location’ ;
import wixData from ‘wix-data’ ;
import { chkValidEmail } from ‘backend/reg’ ;
import { authentication , currentMember } from ‘wix-members’ ;
import { doRegisgration } from ‘backend/reg’
import wixWindow from ‘wix-window’ ;
import { session } from ‘wix-storage’ ;
let validationMessage ;

let validatedEmail = false ;
let validatedPassword = false ;

$w . onReady ( function () {
console.log ( “form ready” );
$w ( ‘#txtConfirmedPassword’ ). inputType = “password”
validationMessage = “” ;

});

export function btnClose_click ( event ) {
wixLocation . to ( /for-vip-only );
// This function was added from the Properties & Events panel. To learn more, visit Velo: Working with the Properties & Events Panel | Help Center | Wix.com
// Add your code for this event here:
}

export function chkViewPassword_change ( event ) {
// This function was added from the Properties & Events panel. To learn more, visit Velo: Working with the Properties & Events Panel | Help Center | Wix.com
// Add your code for this event here:
if ( $w ( ‘#chkViewPassword’ ). checked ){
$w ( ‘#txtPassword’ ). inputType = “text” ;
$w ( ‘#txtConfirmedPassword’ ). inputType = “text” ;

}  **else**  { 
      $w ( '#txtPassword' ). inputType  =  "password" ; 
      $w ( '#txtConfirmedPassword' ). inputType  =  "password" ; 
} 

}

export function btnSubmit_click ( event ) {
//session.clear;
// verify password
let password1 = $w ( “#txtPassword” ). value ;
let password2 = $w ( “#txtConfirmedPassword” ). value ;
let emaildomain = $w ( “#txtEmail” ). value ;
console . log ( "validatedEmail " + validatedEmail );
console . log ( "norton-this is custom form " );

$w ( "#txtPassword" ). onCustomValidation (( value ,  reject ) => { 
  
   
    console.log  ( " validate at btn Sumbit password1 "  +  password1  +  "  password2 "  +  password2  +   " value"  +  value ); 
    let  regExp  =  **new**  RegExp (/^(?=^.{8,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$/); 

    if  ( regExp . test ( password1 . toString ())){     
        console.log  ( "password match the pattern"  ) 

        if ( password2  ===  **null**   ||  password2  ===  "" ) { 
            console.log  (  "bypass" ) ; 
            
        }  **else**  { 
                if ( value  ===  password2  ||  password1  ===  password2  ){ 
                console.log  ( "password1 and password2 are match" ) 
            }  **else**  { 
                    console . log ( "Password and Confirmed Password are not match1v" ); 
                    reject ( "Password and Confirmed Password are not match" ); 
            } 
        } 
    } **else**  {     
   
        validationMessage  +=  "password must be at least 8 characters and containing nubmer and alaphbet, upper case and lower case/n"    
        console . log ( 'password must be at leat 8 characters and containing nubmer and alaphbet with both upper case and lower case' ); 
        $w ( '#text185' ). text  = "password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case" ; 
        $w ( '#text185' ). expand ; 

        reject ( 'password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case' ); 


    } 

            
}); 


//verify confirmed password 
$w ( "#txtConfirmedPassword" ). onCustomValidation (( value ,  reject ) => { 
  
   
   console.log  ( " validate at btn Sumbit Confirmed password1 "  +  password1  +  "  password2 "  +  password2  +  " value"  +  value  ); 
    if  ( value  ===  password1  ||  password1  ===  password2 ) { 
        console . log ( "They are match 2!" ); 

        let  regExp  =  **new**  RegExp (/^(?=^.{8,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$/); 

        if  ( regExp . test ( password2 )){ 

            console.log  ( "password match the pattern"  ) 

        }  **else**  {     

            validationMessage  +=  "password must be at least 8 characters and containing nubmer and alaphbet, upper case and lower case/n" 
     
            console . log ( 'password must be at leat 8 characters and containing nubmer and alaphbet with both upper case and lower case 2' ); 
           
            reject ( 'password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case' ); 
        } 

    }  **else**  { 

         validationMessage  += "Password and Confirmed Password should be match/n" ; 
       
        console . log ( "Password and Confirmed Password are not match 2" ); 
        reject ( "Password and Confirmed Password are not match" ); 
    } 
              
}); 

    // verify email 
$w ( "#txtEmail" ). onCustomValidation (( value ,  reject ) => { 
    console.log  ( "input txtEmail_input value "  +  value ); 
    let  emaildomain  =   $w ( "#txtEmail" ). value ; 
    
    let  firstCut  =  emaildomain . substring ( emaildomain . lastIndexOf ( '@' ) +  1 ,  emaildomain . lastIndexOf ( '.' )); 
   // let secondCut =firstCut.substring(0, firstCut.IndexOf('.')); 

 //   console.log("emaildomain " + emaildomain + " firstCut " + firstCut + " secondCut " + secondCut ); 

   if  ( firstCut . toLowerCase () ===  "gmailxxx"  ||  firstCut . toLowerCase () ===  "hotmail"  ||  firstCut . toLowerCase () ===  "outlook"  ||  firstCut . toLowerCase () ===  "yahoo"   ||  firstCut . toLowerCase () ===  "yahoo.com" ) { 
        validationMessage  +=( "Email address must be a company email address./n" ) 
        console.log  ( " should be a company address" ) 
         $w ( "#lblMessage" ). html  =  "<p style=' color: #FF0000;'>"  +  value  +  "</p>" 
         $w ( '#lblMessage' ). text = "Please use company email." ; 
         validatedEmail  =  **false** ; 
        reject ( "Email address must be a company email address." ); 
    } 

    console . log ( "I am here~~~~" ); 
        
    chkValidEmail ( value ). then (( result ) => { 

        const  {  succeeded ,  returnMessage  } =  result ; 
        

        if  ( succeeded ) { 

            console . log ( "The email can be used" ); 
            validatedEmail  =  **true** ; 
            
        }  **else**  { 

            console . log ( "chkValidEmail "  +  returnMessage ); 

            validatedEmail  =  **false** ; 
            reject ( "Email already exists" ); 

        } 

    }); 
}); 

      if  ( validatedEmail ) { 
      wixLocation . to ( "/registerSuccess" ) 
  }  **else**  { 
      console . log  ( " error " ); 
  } 

}

/**

  • Adds an event handler that runs when an input element’s value
    is changed.
    Read more

  • @param {$w.Event} event
    /
    export function txtPassword_change ( event ) {
    // This function was added from the Properties & Events panel. To learn more, visit Velo: Working with the Properties & Events Panel | Help Center | Wix.com
    // Add your code for this event here:
    $w ( “#txtPassword” ). onCustomValidation (( value , reject ) => {
    let password1 = value ;
    let password2 = $w ( “#txtConfirmedPassword” ). value
    console.log ( " password1 " + password1 + " password2 " + password2 );
    let regExp = new RegExp (/^(?=^.{8,}$)((?=.
    [A-Za-z0-9])(?=.[A-Z])(?=.[a-z]))^.*$/);

    if ( regExp . test ( password1 . toString ())){
    console.log ( “password match the pattern” )

       if ( password2  ===  **null**   ||  password2  ===  "" ) { 
           console.log  (  "bypass" ) ; 
           
       }  **else**  { 
               if ( value  ===  password2  ){ 
               console.log  ( "password1 and password2 are match" ) 
           }  **else**  { 
                   console . log ( "Password and Confirmed Password are not match1v" ); 
                   reject ( "Password and Confirmed Password are not match" ); 
           } 
       } 
    

    } else {

       validationMessage  +=  "password must be at least 8 characters and containing nubmer and alaphbet, upper case and lower case/n"    
       console . log ( 'password must be at leat 8 characters and containing nubmer and alaphbet with both upper case and lower case' ); 
       $w ( '#text185' ). text  = "password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case" ; 
       $w ( '#text185' ). expand ; 
    
       reject ( 'password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case' ); 
    

    }

}); 

}

/**

  • Adds an event handler that runs when an input element’s value
    is changed.
    Read more

  • @param {$w.Event} event
    */
    export function txtConfirmedPassword_change ( event ) {
    //verify confirmed password
    $w ( “#txtConfirmedPassword” ). onCustomValidation (( value , reject ) => {
    let password1 = $w ( “#txtPassword” ). value ;
    let password2 = $w ( “#txtConfirmedPassword” ). value ;

    if ( value === password1 ) {
    console . log ( “They are match 2!” );

       let  regExp  =  **new**  RegExp (/^(?=^.{8,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$/); 
    
       if  ( regExp . test ( password2 )){ 
    
           console.log  ( "password match the pattern"  ) 
    
       }  **else**  {     
    
           validationMessage  +=  "password must be at least 8 characters and containing nubmer and alaphbet, upper case and lower case/n" 
    
           console . log ( 'password must be at leat 8 characters and containing nubmer and alaphbet with both upper case and lower case 2' ); 
          
           reject ( 'password must be at least 8 characters and containing nubmer and alaphbet with both upper case and lower case' ); 
       } 
    

    } else {

        validationMessage  += "Password and Confirmed Password should be match/n" ; 
      
       console . log ( "Password and Confirmed Password are not match 2" ); 
       reject ( "Password and Confirmed Password are not match" ); 
    

    }

}); 

}

/**

/**

  • Adds an event handler that runs when an input element’s value
    is changed.
    Read more
  • @param {$w.Event} event
    */

/**

  • Adds an event handler that runs when an input element’s value
    is changed.
    Read more

  • @param {$w.Event} event
    */
    export function txtEmail_change ( event ) {
    // This function was added from the Properties & Events panel. To learn more, visit Velo: Working with the Properties & Events Panel | Help Center | Wix.com
    // Add your code for this event here:
    // verify email
    $w ( “#txtEmail” ). onCustomValidation (( value , reject ) => {
    console.log ( “input txtEmail_input” );
    let emaildomain = $w ( “#txtEmail” ). value ;
    //let emaildomain = value;
    let firstCut = emaildomain . substring ( emaildomain . lastIndexOf ( ‘@’ ) + 1 , emaildomain . lastIndexOf ( ‘.’ ));

    console . log ( "firstCut " + firstCut );

    if ( firstCut . toLowerCase () === “gmailxxx” || firstCut . toLowerCase () === “hotmail” || firstCut . toLowerCase () === “outlook” || firstCut . toLowerCase () === “yahoo” || firstCut . toLowerCase () === “yahoo.com” ) {
    validationMessage +=( “Email address must be a company email address./n” )

         validatedEmail  =  **false** ; 
         console.log  ( " should be a company address" ) 
         reject ( "Email address must be a company email address." ); 
    

    }

           chkValidEmail ( value ,  reject ). then (( result ) => { 
    
               const  {  succeeded ,  returnMessage  } =  result ; 
    
               if  ( succeeded ) { 
                   $w ( "#lblMessage" ). html  =  "<p style=' color: #FFFFFF;'>"  +  value  +  "</p>" 
                   $w ( '#lblMessage' ). text = "Please use company email." ; 
                   console . log ( "The email can be used" ); 
                   validatedEmail  =  **true** ; 
    
               }  **else**  { 
    
                   console . log ( "我估到你啦" , returnMessage ); 
                   validatedEmail  =  **false** ; 
                    $w ( "#lblMessage" ). html  =  "<a href='https://www.glodacert.co/contactus' style=' color: #FF0000;'>"  +  value  +  "</a>" 
                   $w ( '#lblMessage' ). text = "Email Already Exists, please contact us for details." ; 
                   
                   reject ( "The email has been used." ); 
    
                   
                   //reject("Email already exists") 
               } 
           }); 
    
}); 

}

Backend :

export const chkValidEmail = async (email, reject) => {

  try {

    const emailDupeCheckResult = await searchForSignupDuplicateEmails(email);



    if (emailDupeCheckResult > 0)

      return {

        succeeded: false,

        returnMessage: "This email is already in use",

      };



    return { succeeded: true, returnMessage: "This email is valid" };

  } catch (err) {

    return { succeeded: false, returnMessage: err.message };

  }

};

Hello! It sounds like you’re using a custom form, but your users aren’t registered to Wix Members, is that correct?

I would check out this video tutorial on how to set up Custom Registration using the Wix Members API .

Do not give up.
It is not the easiest task to generate a good working Registration-Form or even a FULLY - LOGIN-SYSTEM.

If you need some ideas …
look here, you will find maybe some useful links and ideas.

There is even more stuff about my little login-system-project.

Try to find some more posts about this topic.

I just saw and remembered, that i have had similar issues, what was the reason to generate own LOGIN-SYSTEM.

If you need more simple examples, you also can check this old ones, but simple ones…

https://russian-dima.wixsite.com/meinewebsite/blank-9

To know if a similar e-mail already exists inside your Databse, you will have first to try to register.

The registration-try, will give you back a result, which will give you back an ERROR-CODE.

Find-out what the code tells you, it will be something like…

if(CODE = -77845) {console.log(‘email already existing’)}
if(CODE = -74445) {console.log(‘blocked user’)}

I don’t know the exact codes, but everytime when you try to register an Email, you will get Error-Codes registration wents wrong.

It will give you back an ERROR