2017-01-19 4 views
2

aurelia-validationプラグインを使用してフォームの検証を実行しようとしています。私は入力ボックスの色を変更するだけでなく、ボックスの隣にアイコンを配置するカスタム検証レンダラーを作成しています。アイコンがクリックまたはホバーされると、実際のエラーメッセージを表示するポップアップメッセージが表示されます。現在Aurelia検証レンダラー内のビューにVMを作成するには

enter image description here

、私はレンダラに手動でコードでこれのすべてをレンダリングするんだけど、関連付けられているとともに、htmlファイルで定義され、このすべてのHTMLを持っていいだろうように思えますjsファイルをクリックして、アイコンをホバーします。 IOW、View/ViewModelにすべてのエラー内容(ポップアップを持つアイコン)をカプセル化し、次に検証用レンダラーのrender()に、何らかの形で問題の要素の直後に新しいインスタンスを作成します。

これは可能ですか?私は<compose></compose>要素の使い方を見てきましたが、実際にフォームのすべての入力ボックスに追加する必要はありません。

これは、私は現在、私のレンダラに持っているものです:あなたが提供することができます任意の助け

import {ValidationError, RenderInstruction} from 'aurelia-validation' 

export class IconValidationRenderer { 
    render(instruction){ 
     //Unrender old errors 
     for(let {result, elements} of instruction.unrender){ 
      for(let element of elements){ 
       this.remove(element, result); 
      } 
     } 

     //Render new errors 
     for(let {result, elements} of instruction.render){ 
      for(let element of elements){ 
       this.add(element, result) 
      } 
     } 
    } 

    add(element, result){ 
     if(result.valid) 
      return 

     //See if error element already exists 
     if(element.className.indexOf("has-error") < 0){ 
      let errorIcon = document.createElement("i") 
      errorIcon.className = "fa fa-exclamation-circle" 
      errorIcon.style.color = "darkred" 
      errorIcon.style.paddingLeft = "5px" 
      errorIcon.id = `error-icon-${result.id}` 
      errorIcon.click = "" 
      element.parentNode.appendChild(errorIcon) 

      element.classList.add("has-error") 
      element.parentNode.style.alignItems = "center" 

      let errorpop = document.createElement("div") 
      let errorarrow = document.createElement("div") 
      let errorbody = document.createElement("div") 
      errorpop.id = `error-pop-${result.id}` 
      errorpop.className = "flex-row errorpop" 
      errorarrow.className = "poparrow" 
      errorbody.className = "flex-col popmessages" 
      errorbody.innerText = result.message 
      console.log("Computing position") 

      let elemRec = errorIcon.getBoundingClientRect() 
      let elemH = errorIcon.clientHeight 
      errorpop.style.top = elemRec.top - 10 + "px" 
      errorpop.style.left = elemRec.right + "px" 

      errorpop.appendChild(errorarrow) 
      errorpop.appendChild(errorbody) 
      element.parentNode.appendChild(errorpop) 
     } 
    } 

    remove(element, result){ 
     if(result.valid) 
      return 

     element.classList.remove("has-error") 
     let errorIcon = element.parentNode 
      .querySelector(`#error-icon-${result.id}`) 
     if(errorIcon) 
      element.parentNode.removeChild(errorIcon) 

     //Need to remove validation popup element 
    } 
} 

感謝。

P.S.この時点で、私は言及したようにクリックやホバーを実装していません - それは私がしたいことですが、私はこの時点でどのようにしているのか分かりません。私がVMを組み立てることができれば、より真っ直ぐになるだろう。

EDIT

私はアウレリアギッターチャネル上の誰かによってthis記事を指摘しました。私はTemplatingEngineを実装しようとしましたが、明らかに私はそれを正しい方法でやっていません。ここに私が持っているものがあります。検証してフォームを持っている

アドオン人dialog.js // VM

import {TemplatingEngine,NewInstance} from 'aurelia-framework' 
import {ValidationController} from 'aurelia-validation' 
import {IconValidationRenderer} from './resources/validation/icon-validation-renderer' 

export class AddPersonDialog { 
    static inject = [NewInstance.of(ValidationController),TemplatingEngine] 

    constructor(vc, te){ 
     this.vc = vc 
     this.vc.addRenderer(new IconValidationRenderer(te)) 
    } 

アイコン検証-renderer.js

//Plus all the other bits that I posted in the code above 
constructor(te){ 
    this.te = te 
} 

add(element, result){ 
    if(result.valid) return 

    if(element.className.indexOf("has-error") < 0 { 
     //replaced there error icon code above with this (as well as a few different variations 
     let test = document.createElement("field-error-info") 
     element.parentNode.appendChild(test) 
     this.te.enhance({element: test}) 
    } 
} 

フィールド・エラー情報.html

<template> 
    <require from="./field-error-info.css" ></require> 

    <i class="fa fa-exclamation-circle" click.delegate="displayMessage = !displayMessage" mouseenter.delegate="displayMessage = true" mouseleave.delegate="displayMessage = false"></i> 
    <div show.bind="displayMessage" class="flex-row errorpop" style="left:300px"> 
     <div class="poparrow"></div> 
     <div class="flexcol popmessages">Message 1</div> 
    </div> 
</template> 

最終的に<field-error-info></field-error-info>がDOMに追加されますが、実際にレンダリングされることはありません。 (ちなみに、私もadd-person-dialog.htmlに<require from='./elements/field-error-info'></require>を追加しようとしました。

答えて

2

エラーアイコンとツールチップロジックをカプセル化するフォームコントロールカスタム要素を作成できます。要素は、ラベルに渡す有効にするために2つのコンテンツの投影スロットを露出させ、入力/選択/などができます:ここで

<template> 
    <div validation-errors.bind="errors" 
     class="form-group ${errors.length ? 'has-error' : ''}"> 

    <!-- label slot --> 
    <slot name="label"></slot> 

    <!-- input slot --> 
    <slot name="input"></slot> 

    <!-- icon/tooltip stuff --> 
    <span class="control-label glyphicon glyphicon-exclamation-sign tooltips" 
      show.bind="errors.length"> 
     <span> 
     <span repeat.for="errorInfo of errors">${errorInfo.error.message}</span> 
     </span> 
    </span> 
    </div> 
</template> 

は、それが使用される方法は次のとおりです。

<template> 
    <require from="./form-control.html"></require> 

    <form novalidate autofill="off"> 

    <form-control> 
     <label slot="label" for="firstName" class="control-label">First Name:</label> 
     <input slot="input" type="text" class="form-control" 
      value.bind="firstName & validateOnChange"> 
    </form-control> 

    <form-control> 
     <label slot="label" for="lastName" class="control-label">Last Name:</label> 
     <input slot="input" type="text" class="form-control" 
      value.bind="lastName & validateOnChange"> 
    </form-control> 

    </form> 
</template> 

ライブ例:https://gist.run/?id=874b100da054559929d5761bdeeb651c

ごまかしツールチップをお許しください。

+0

恐ろしいジェレミー!ありがとうトン! – RHarris

関連する問題