No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Reuse of validation rules

    Framework
    5
    11
    8214
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      tdumitr last edited by

      I really like the fact that validations are now handled directly by the Quasar framework and not by an external package. They are also straightforward to define, including the error messages when the validation fails. But (as far as I can tell) using the same validation rules in more than one form requires repeating the code. Here is an example of what I expected I can do:

      1. Have a validations.js file with the list of rules to be used throughout my project
      const emailPattern = /^(?=[a-zA-Z0-9@._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}@(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/;
      
      export const email = val => emailPattern.test(val) || 'Please enter a valid email address';
      export const required = val => !!val || 'Field is required';
      
      1. Use the rules in validations.js wherever validation is required. For example a login form would look something like:
      <template>
        <div style="width: 500px; max-width: 90vw;">
          <q-input
            v-model="form.userName"
            label="User"
            :rules="[required, email]" />
          <q-input
            v-model="form.password"
            type="password" label="Password"
            @keyup.enter="loginClick"
            :rules="[required]" />
          <div class="row" style="display: flex;align-items: center;">
            <div class="col-4">
              <small>
                Not registered?
                <span @click="openUserRegistration()">Register now</span>
              </small>
            </div>
            <div class="col-6"></div>
            <div class="col-2">
              <q-btn rounded color="primary" label="Login" @click="loginClick" />
            </div>
          </div>
        </div>
      </template>
      
      <script>
      import { required, email } from '../validations';
      
      export default {
      ......................
      }
      </script>
      

      When I try running this code, eslint gives me a no-unused-vars on the import line as if the required and email are not used anywhere, but they are clearly used in the :rules attributes on the q-input tags. If I disable the eslint error for that line, the code runs, but no validation occurs. For example I can have an invalid e-mail address in the User field, and no error will be shown. Or I can have empty user and password and no error will be shown.

      The only way I could make the validations work is to either define the functions directly in the :rules attribute, which is really ugly and impractical, or I can define methods in the component like:

        methods: {
          // validations
          required(val) {
            return required(val);
          },
          email(val) {
            return email(val);
          },
          // end validations
      .......................
        },
      

      and change the :rules attribute in the template to be:

            :rules="[this.required, this.email]"
      

      While I like this second approach better than defining the functions directly in the attribute, it still defies the principle of re-usability.

      My questions are: why is my first approach not working and how can I have reusable validation rules?

      1 Reply Last reply Reply Quote 1
      • s.molinari
        s.molinari last edited by

        If you don’t have your methods, props, computeds, etc. inside the component’s options object (the code inside export default{}), then the component’s template has no knowledge of or rather can’t access those things. Just importing the methods does nothing and eslint is right for saying they aren’t used.

        Also, this isn’t needed inside of the template. You only need [required, email].

        Lastly, if you just do this,

        methods: {
          email, 
          required
        }
        

        you have successfully added your imported methods into the component.

        https://codesandbox.io/s/codesandbox-app-fs1hy

        Scott

        1 Reply Last reply Reply Quote 1
        • T
          tdumitr last edited by tdumitr

          Scott, thank you for the example. It is indeed a lot more compact than what I had. It’s almost as good as what I wanted and I already modified my code to match it. My concern is that as concise as this is, it still requires me to mention the validation rules twice, once in the import and once in the methods. I can easily see compilation errors in my future, when I forget to add a rule in one of the two places where I have to have it or delete it from one of the two places it is.

          I guess my question then is to the Quasar team: could a babel plugin be written to automatically generate the

          methods: {
             email,
             required,
          }
          

          when the code is compiled, and include the plugin with the Quasar framework?

          1 Reply Last reply Reply Quote 0
          • metalsadman
            metalsadman last edited by metalsadman

            you can make a boot file and register your methods as a vue prototype, if youre concern about importing and whatnot, then in your component call it this.$myValHelper.required(someval) in script part of your sfc and without this in the template.
            I dunno why you are so concern with compile errors, in your trivial case a good ide would already warn you about error and won’t let you compile.

            1 Reply Last reply Reply Quote 0
            • s.molinari
              s.molinari last edited by

              I don’t get the concern either. The import and declaration in methods is one way. Globally binding the methods to Vue through a boot file is another.

              Put it this way. If you imported the functions in any other code anywhere else, you’d have to also “use” them (i.e. write them out) somewhere in your JS code too.

              Something else you can try is to construct/ design your own custom input component with whatever validation you need and “reuse” your custom component, where you need it. For instance a <my-email-input> component.

              Scott

              donsherman 1 Reply Last reply Reply Quote 0
              • donsherman
                donsherman @s.molinari last edited by

                I had the same issue and solved it like Scott did it. Thanks!
                But how could this be made in validations.js?

                export const email = val => emailPattern.test(val) || $t('validAddress');
                export const required = val => !!val || $t('required');
                
                

                In other words: How put i i18n in there?
                Because if I do like this above, $t and this.$t is unknown .

                1 Reply Last reply Reply Quote 0
                • s.molinari
                  s.molinari last edited by

                  Create regular methods and use them.

                  Scott

                  1 Reply Last reply Reply Quote 0
                  • donsherman
                    donsherman last edited by

                    Ok, i did like this:

                    export const email = (val,msg) => emailPattern.test(val) || msg 
                    ...
                    

                    and in the q-input of the component:

                     :rules="[ val => !!val || $t('required'),  val => email(val,$t('validAddress')) ]"
                    

                    I think that is what you meant with reg. methods, or?

                    dobbel 1 Reply Last reply Reply Quote 0
                    • dobbel
                      dobbel @donsherman last edited by

                      @donsherman

                      Just as a side note: testing for the validity of an email address is almost impossible to do correct.

                      This video explains why( surprised me too btw ):

                      https://www.youtube.com/watch?v=xxX81WmXjPg

                      1 Reply Last reply Reply Quote 0
                      • donsherman
                        donsherman last edited by

                        Sure. I am also surprised. So in fact, there’ll be no regex for that check?
                        Better to let user enter whatever he types?

                        dobbel 1 Reply Last reply Reply Quote 0
                        • dobbel
                          dobbel @donsherman last edited by

                          @donsherman

                          All regex pattern’s for testing an email addresses validity are probably not 100% correct.
                          As long as there is at least one ‘@’ present, it’s best to just to send it.

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post