by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    andrefcferreira
    @andrefcferreira
    They are responsible to bind and unbind the active view module, i believe!
    if-permission.js
    import { inject, customAttribute, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
    import userService from 'services/api/userService';
    
    @customAttribute('if-permission')
    @inject(BoundViewFactory, ViewSlot)
    @templateController
    export class IfPermission {
    
      constructor(viewFactory, viewSlot) {
    
        this.viewFactory = viewFactory;
        this.viewSlot = viewSlot;
        this.showing = false;
        this.view = null;
        this.bindingContext = null;
        this.overrideContext = null;
      }
    
      /**
      * Binds the if to the binding context and override context
      * @param bindingContext The binding context
      * @param overrideContext An override context for binding.
      */
      bind(bindingContext, overrideContext) {
        // Store parent bindingContext, so we can pass it down
        this.bindingContext = bindingContext;
        this.overrideContext = overrideContext;
        this.valueChanged(this.value);
      }
    
      valueChanged(newValue) {
        if (this.__queuedChanges) {
          this.__queuedChanges.push(newValue);
          return;
        }
    
        let maybePromise = this._runValueChanged(newValue);
        if (maybePromise instanceof Promise) {
          let queuedChanges = this.__queuedChanges = [];
    
          let runQueuedChanges = () => {
            if (!queuedChanges.length) {
              this.__queuedChanges = undefined;
              return;
            }
    
            let nextPromise = this._runValueChanged(queuedChanges.shift()) || Promise.resolve();
            nextPromise.then(runQueuedChanges);
          };
    
          maybePromise.then(runQueuedChanges);
        }
      }
    
      _runValueChanged(newValue) {
        newValue = userService.hasPermission(newValue);
        if (!newValue) {
          let viewOrPromise;
          if (this.view !== null && this.showing) {
            viewOrPromise = this.viewSlot.remove(this.view);
            if (viewOrPromise instanceof Promise) {
              viewOrPromise.then(() => this.view.unbind());
            } else {
              this.view.unbind();
            }
          }
          this.showing = false;
          return viewOrPromise;
        }
    
        if (this.view === null) {
          this.view = this.viewFactory.create();
        }
    
        if (!this.view.isBound) {
          this.view.bind(this.bindingContext, this.overrideContext);
        }
    
        if (!this.showing) {
          this.showing = true;
          return this.viewSlot.add(this.view);
        }
      }
    
      /**
      * Unbinds the if
      */
      unbind() {
        if (this.view === null) {
          return;
        }
    
        this.view.unbind();
    
        if (!this.viewFactory.isCaching) {
          return;
        }
    
        if (this.showing) {
          this.showing = false;
          this.viewSlot.remove(this.view, true, true);
        }
        this.view.returnToCache();
        this.view = null;
      }
    }
    if-user-role.js
    import { inject, customAttribute, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
    import userService from 'services/api/userService';
    
    @customAttribute('if-user-role')
    @inject(BoundViewFactory, ViewSlot)
    @templateController
    export class IfUserRole {
    
      constructor(viewFactory, viewSlot) {
        this.viewFactory = viewFactory;
        this.viewSlot = viewSlot;
        this.showing = false;
        this.view = null;
        this.bindingContext = null;
        this.overrideContext = null;
      }
    
      /**
      * Binds the if to the binding context and override context
      * @param bindingContext The binding context
      * @param overrideContext An override context for binding.
      */
      bind(bindingContext, overrideContext) {
        // Store parent bindingContext, so we can pass it down
        this.bindingContext = bindingContext;
        this.overrideContext = overrideContext;
        this.valueChanged(this.value);
      }
    
      valueChanged(newValue) {
        if (this.__queuedChanges) {
          this.__queuedChanges.push(newValue);
          return;
        }
    
        let maybePromise = this._runValueChanged(newValue);
        if (maybePromise instanceof Promise) {
          let queuedChanges = this.__queuedChanges = [];
    
          let runQueuedChanges = () => {
            if (!queuedChanges.length) {
              this.__queuedChanges = undefined;
              return;
            }
    
            let nextPromise = this._runValueChanged(queuedChanges.shift()) || Promise.resolve();
            nextPromise.then(runQueuedChanges);
          };
    
          maybePromise.then(runQueuedChanges);
        }
      }
    
      _runValueChanged(newValue) {
        newValue = userService.hasRole(newValue);
    
        if (!newValue) {
          let viewOrPromise;
          if (this.view !== null && this.showing) {
            viewOrPromise = this.viewSlot.remove(this.view);
            if (viewOrPromise instanceof Promise) {
              viewOrPromise.then(() => this.view.unbind());
            } else {
              this.view.unbind();
            }
          }
    
          this.showing = false;
          return viewOrPromise;
        }
    
        if (this.view === null) {
          this.view = this.viewFactory.create();
        }
    
        if (!this.view.isBound) {
          this.view.bind(this.bindingContext, this.overrideContext);
        }
    
        if (!this.showing) {
          this.showing = true;
          return this.viewSlot.add(this.view);
        }
      }
    
      /**
      * Unbinds the if
      */
      unbind() {
        if (this.view === null) {
          return;
        }
    
        this.view.unbind();
        if (!this.viewFactory.isCaching) {
          return;
        }
    
        if (this.showing) {
          this.showing = false;
          this.viewSlot.remove(this.view, true, true);
        }
        this.view.returnToCache();
        this.view = null;
      }
    }
    I have been debugging but reached no conclusion... all logs that i try to check this.view they are not null...
    Oh! This is a result of an old aurelia framework version and i am at the end of the aurelia upgrade. Which this is the only error that i have been getting
    andrefcferreira
    @andrefcferreira
    Good Hello Everyone
    andrefcferreira
    @andrefcferreira
    Here is a stackoverflow for my problem
    Arne Deruwe
    @arnederuwe
    @andrefcferreira the main discussion room for Aurelia is here: https://gitter.im/aurelia/Discuss
    you should post all non-validation related things there
    andrefcferreira
    @andrefcferreira
    What do you understand as Validation then?
    Okay! My question is: what is the porpuse of the group then?
    Arne Deruwe
    @arnederuwe
    this is the room discussing issues with the Aurelia validation plugin: https://github.com/aurelia/validation
    VagyokC4
    @VagyokC4
    image.png
    I'm experiencing an issue where my validation controller is missing the html element required to show the validation error
    I just recently upgraded to the latest bits and this issue showed up
    Any ideas on how to get the element to re-register?
    Ischca
    @Ischca
    Is there a way to signal an error to validation-errors when you call controller.validate ({object: this.obj})?
    Ischca
    @Ischca
    this is solved
    jsprpalm
    @jsprpalm

    Hi. I tried to simplify the html needed to create a form with fields+validation+error display by creating a custom component.

    validated-input.html

    <template>
        <div class="form-input ${class}">
            <slot name="icon"></slot>
            <label if.bind="!floatingLabel">${label}</label>
            <div>
                <div class="ui input primary-input">
                    <input type="text" ref="field" class="${errors.length > 0 ? 'has-errors': ''}"
                        keydown.delegate="keyDownHandler($event)" value.bind="value" blur.trigger="blur()" input.trigger="input()" autocomplete="off">
                    <div if.bind="floatingLabel" class="floating-label"><span class="floating-label-focus">${label}</span></div>
                </div>
                <div if.bind="errors.length > 0" class="validation-error">
                    <i class="exclamation triangle icon"></i>
                    <span repeat.for="e of errors">${e.message}</span>
                </div>
            </div>
        </div>
    </template>

    validated-input.ts

    import { ValidationController, ValidateResult, validateTrigger } from "aurelia-validation";
    import { customElement, bindable, containerless, autoinject, bindingMode, DOM } from "aurelia-framework";
    
    @autoinject
    @containerless
    @customElement("validated-input")
    export class ValidatedInput {
        @bindable field: HTMLInputElement;
        @bindable label: string;
        @bindable class: string = "";
        @bindable({ defaultBindingMode: bindingMode.twoWay }) value: string;
        @bindable name: string;
        @bindable floatingLabel: boolean = false;
        @bindable validationTrigger: string = "change";
        @bindable maxlength: string | null = null;
        @bindable pattern: string | null = null;
        errors: ValidateResult[];
        private controller: ValidationController;
    
        constructor(private element: Element) {
        }
    
        bind(bindingContext: any) {
            this.field.setAttribute("value", this.value || "");
            this.controller = bindingContext.controller;
            if (this.maxlength) {
                this.field.setAttribute("maxlength", this.maxlength);
            }
            if (this.pattern) {
                this.field.setAttribute("pattern", this.pattern);
            }
            this.controller.subscribe((e) => this.errors = e.results.filter((x) => x.propertyName === this.name && !x.valid));
        }
    
        blur() {
            if (this.validationTrigger === "blur") {
                this.validate();
            }
        }
    
        input() {
            if (this.validationTrigger === "change") {
                this.validate();
            }
        }
    
        private validate() {
            this.field.setAttribute("value", this.value || "");
            this.controller.validate().then((validate) => {
                this.errors = validate.results.filter((x) => x.propertyName === this.name && !x.valid);
            });
        }
    
        private keyDownHandler(e: KeyboardEvent) {
            if (e.key === "Enter") {
                this.element.dispatchEvent(DOM.createCustomEvent("enter"));
            }
            return true;
        }
    }

    The problem I have is that I need (I think) to have each field subscribe to the validation callback to perform their logic to filter the errors collection. This is because a validation can be triggered by the page that contains the submit button. But by having each field subscribe to the validation callback this also means that as soon as I validate one of the fields in the blur or change handlers all of the fields are validated. I only want this full form validation when you try to submit the form.

    The ValidationController and the ValidationRules are created and defined in the containing page.

    I feel that I have over complicated this solution and that there must be something simpler?

    Antonio
    @eagle06_gitlab
    Max
    @MaximBalaganskiy
    @eagle06_gitlab check that you haven't got a duplicate aurelia-validation folder sitting in local package dependencies
    what might happen is that you patch FluentRules from a duplicate package
    Antonio
    @eagle06_gitlab
    image.png
    @MaximBalaganskiy I have multiple aurelia-validation files, but I try to use the d.ts file, since I'm working with typescript:
    Max
    @MaximBalaganskiy
    Check the folders, not files
    Antonio
    @eagle06_gitlab
    @MaximBalaganskiy this could be it, I have two different versions in npm_modules and jspm-packages/npm
    Max
    @MaximBalaganskiy
    Are you using jspm?
    Antonio
    @eagle06_gitlab
    yes
    I have only one folder of aurelia-validation in npm and one in jspm-packages/npm
    now I get this error: node_modules/aurelia-validation/dist/commonjs/property-info.d.ts(3,11): error TS2451: Cannot redeclare block-scoped variable 'getContextFor'.
    Max
    @MaximBalaganskiy
    You still might get a duplicate module loaded. Check in the code if fluentrules object is the same in augmenting module and view model
    Antonio
    @eagle06_gitlab
    uuh, how can I check this?
    Max
    @MaximBalaganskiy
    Console.log
    Antonio
    @eagle06_gitlab
    Ok, the problem above has nothing to do with adding the rule, it's something else with deprecating the aurelia-validation version in the node_modules to the same as in jspm-packages. I first need to fix this
    Antonio
    @eagle06_gitlab
    Ok, the code FluentRules is the one from node_modules, and the FluentRules Object in the view model is from JSPM. Since these are two different versions, this could cause the problem. Thanks for the hint
    Max
    @MaximBalaganskiy
    I wonder how did you manage to load both of them...
    Antonio
    @eagle06_gitlab
    Not sure, it's an old project. Interessting fact, as soon as I adapt one of the two to the version of the other, the whole project breaks. I need to fix this and use the same version in node_modules and jspm-packages
    Max
    @MaximBalaganskiy
    Module resolution picks the wrong module during patching, try specifying the path to the one in jspm
    norgie
    @norgie

    Does aurelia-validation require that every "property" referred to in .ensure(...)is not null? I have the following piece of code

      editinfoChanged(newEditInfo: any, oldValue: any) : void {
        if (this.domainobject && newEditInfo) {
          this.editinfo.forEach((field: { requisiteness: string; name: string | number; label: string }) => {
            if (this.isMandatory(field.requisiteness)) {
              ValidationRules.ensure(this.domainobject[field.name]).displayName(field.label).required().on(this.domainobject);
            };
          });
        }
      }

    which fails and produces the following error message:

    Uncaught TypeError: Cannot read property 'toString' of null
        at PropertyAccessorParser.parse (aurelia-validation.js?f0d7:91)
        at FluentEnsure.ensure (aurelia-validation.js?f0d7:1700)
        at Function.ValidationRules.ensure (aurelia-validation.js?f0d7:1767)
        at eval (new-item-view.ts?c01b:112)
        at Array.forEach (<anonymous>)
        at NewItemView.editinfoChanged (new-item-view.ts?c01b:110)

    When I look at the value of this.domainobject[field.name](in the first iteration) it is null and this makes me wonder if that's the cause of the error?

    Trobax
    @Trobax

    hello guys can someone help me with "form-field-validation" i'm trying to validate a checkbox table the validation works but the red border css not working

    in the noop.bind i passe the validated list

    <div class="box stackpanel vertical fit form-field-validation" noop.bind="posteUFDTOList & validate:validationController">
         <div class="box-header bg-primary stackpanel horizontal fit">
                <input id="chx_all" class="form-control colSelection" type="checkbox" change.delegate="cocherDecocherTout()" />
                 <label for="chx_all" class="box-title" i18n="sante:ui.fwm.gestionutilisateur.postes.postedetail.cocherdecocher"></label>
         </div>
    </div>
    
    if (this.posteUFDTOList) {
              this.validationController.validate({ object: this.posteUFDTOList });
         }
    image.png
    Radenko Zec
    @radenkozec
    I am getting this error on simple example email&validate' is not compatible with the validate binding-behavior.
    Jason
    @jasonhjohnson
    Is it possible to validate a form that's as a slot within a custom element? Example:
    <app-form-group>
                <app-label label="Name" for="name" slot="label"></app-label>
                <app-input
                  id="name"
                  value.two-way="model.name & validateOnBlur"
                  slot="input"
                ></app-input>
     </app-form-group>
    Max
    @MaximBalaganskiy
    don't see why not... validate binding behaviour should find the current controller anyway... is it not working for you?
    Khalil Mohammad Mirza
    @KhalilMohammad

    Hi,

    I am a newbie in aurelia.

    Aurelia Validation Demo - Nested object properties
    https://gist.github.com/jsobell/d81428170f1572ae916e3fbf67779014
    BootstrapFormRenderer example
    https://gist.github.com/y2k4life/8adacec7627d792a304f62a899f21049

    I am getting correct validation when using controller.validate() method

    Problem is that in BootstrapFormRenderer

    In render method, elements are always empty.

      render(instruction: RenderInstruction) {
        debugger;
        for (let { result, elements } of instruction.unrender) {
          for (let element of elements) {
            this.remove(element, result);
          }
        }
    
        for (let { result, elements } of instruction.render) {
          for (let element of elements) {
            this.add(element, result);
          }
        }
      }
    Khalil Mohammad Mirza
    @KhalilMohammad
    I have got above working but now.
    Reset is not working.
    After clearing state and resetting validation.
    If I check validation again with an empty object.
    It succeeds.