我正在尝试使用aurelia-validation插件对表单执行验证。我正在创建一个自定义验证渲染器,它将更改输入框的颜色以及在框旁边放置一个图标。单击或悬停图标时,会出现一条弹出消息,显示实际的错误消息。
目前,我在渲染器中手动渲染所有这些代码,但似乎在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。在这一点上,我没有像我提到的那样实现点击或悬停 - 这是我想做的事情,但我现在还不确定如何。如果我能组成一个虚拟机,会更直接。
修改
我被Aurelia Gitter频道的某人指出this文章。我已经尝试过实现TemplatingEngine,但很明显我没有采用正确的方法。这就是我所拥有的。
add-person-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})
}
}
字段-误差在info.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>
。
答案 0 :(得分:3)
您可以创建一个表单控件自定义元素,用于封装错误图标和工具提示逻辑。该元素可以暴露两个内容投影槽,以便传入标签和输入/选择/ etc:
<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
请原谅蹩脚的工具提示css