简体   繁体   English

如何验证来自 html5 Datalist 的输入?

[英]How can i validate the input from a html5 Datalist?

I would like to know how I can validate the input value that comes from a Datalist .我想知道如何验证来自Datalist的输入值。 I mean, if I have a Datalist where the user can start to write a value and then choosing it from the Datalist , but the user decides to don't choose any value from the list and he submits the form with the incomplete value, the sent value will be wrong.我的意思是,如果我有一个Datalist ,用户可以在其中开始写入一个值,然后从Datalist选择它,但用户决定不从列表中选择任何值,并且他提交了具有不完整值的表单,则发送的值将是错误的。

I thought about iterate over all the elements of the Datalist but I think that it can't be a good idea if the Datalist has more than 1.000 values and I don't know any other way to validate it.我考虑过遍历Datalist所有元素,但我认为如果Datalist有超过 1.000 个值并且我不知道任何其他方法来验证它,这不是一个好主意。

Here is an example of the Datalist that I'm going to use:这是我将要使用的Datalist的示例:

<input type="text" list="colours">

<datalist id="colours">
    <option value="Red" data-id="1">
    <option value="Blue" data-id="2">
    <option value="Green" data-id="3">
    <option value="Black" data-id="4">
    <option value="White" data-id="5">
</datalist>

Try this:尝试这个:

<input type="text" list="colours" id='txt'>

And on form submit you can check:在表单提交时,您可以检查:

var val = $("#txt").val();

var obj = $("#colours").find("option[value='" + val + "']");

if(obj != null && obj.length > 0)
    alert("valid");  // allow form submission
else
    alert("invalid"); // don't allow form submission

I'd like to share a non-jquery alternative, only in Js:我想分享一个非 jquery 替代方案,仅在 Js 中:

 function is_valid_datalist_value(idDataList, inputValue) { var option = document.querySelector("#" + idDataList + " option[value='" + inputValue + "']"); if (option != null) { return option.value.length > 0; } return false; } function doValidate() { if (is_valid_datalist_value('colours', document.getElementById('color').value)) { alert("Valid"); } else { alert("Invalid"); } }
 <form onsubmit="return false"> <input type="text" id="color" list="colours"> <datalist id="colours"> <option value="Red" data-id="1" /> <option value="Blue" data-id="2" /> <option value="Green" data-id="3" /> <option value="Black" data-id="4" /> <option value="White" data-id="5" /> </datalist> <button onclick="doValidate();">Send</button> </form>

You can do this with HTML5 validation using pattern .您可以通过使用pattern HTML5 验证来做到这一点。 It's easier if you're populating your datalist with some sort of template, but it would look something like this (Note that you would need additional code to handle the validation - I just added very simple CSS to display the validation state)如果您使用某种模板填充数据列表会更容易,但它看起来像这样(请注意,您需要额外的代码来处理验证 - 我只是添加了非常简单的 CSS 来显示验证状态)

It's worth noting that this automatically blocks form submission and provides proper semantics for accessibility and other standards-compliant interoperability.值得注意的是,这会自动阻止表单提交并为可访问性和其他符合标准的互操作性提供适当的语义。

 input:valid { border: 1px solid green; } input:invalid { border: 1px solid red; }
 <input type="text" list="colours" pattern="^(Red|Blue|Green|Black|White)$" > <datalist id="colours"> <option value="Red" data-id="1"> <option value="Blue" data-id="2"> <option value="Green" data-id="3"> <option value="Black" data-id="4"> <option value="White" data-id="5"> </datalist>

If you use jQuery find method, it will traverse the DOM tree trying to find the correct element taking into account the value of one of its attributes, and looking at your comment, I think that you are concerned about performance.如果你使用jQuery find方法,它会遍历DOM树,试图找到正确的元素,同时考虑到它的一个属性的值,看看你的评论,我认为你关心的是性能。

Your first idea about iterate over all the options and check the value property is better (speaking about performance) than traversing the DOM tree looking for an element with a particular value in one of their attributes ( look at this comparison ).您关于迭代所有选项并检查 value 属性的第一个想法(谈到性能)比遍历DOM树以查找在其属性中具有特定值的元素( 查看此比较)更好。 You need to be aware that shorter code is not the same as faster code .您需要注意较短的代码较快的代码不同

A faster solution is to generate an array of strings at the beginning and search the correct value inside it in the validation process:一个更快的解决方案是在开头生成一个字符串array ,并在验证过程中搜索其中的正确值:

//---At the beginning of your application
let list = Array.prototype.map.call(document.getElementById("colours").options, (option) => option.value);

//---Later in your validation process
if (list.indexOf(value) < 0) {
    //Invalid
}

Another faster solution is to generate an object at the beginning and use it as a hash map , checking for the correct value inside it in the validation process:另一个更快的解决方案是在开始时生成一个object并将其用作哈希映射,在验证过程中检查其中的正确值:

//---At the beginning of your application
let hashmap = Array.prototype.reduce.call(document.getElementById("colours").options, (obj, option) => {
    if (!obj[option.value]) { obj[option.value] = true; }
    return obj;
}, {});

//---Later in your validation process
if (!hashmap[value]) {
    //Invalid
}

Here you have the four methods compared in measurethat :在这里,您在measurethat 中比较了四种方法:

1 - Your first idea (iterate over all the Datalist options) 1 - 您的第一个想法(遍历所有Datalist选项)

2 - Use the jQuery find method (@nsthethunderbolt solution) 2 - 使用jQuery find 方法(@nsthethunderbolt 解决方案)

3 - Create an array of strings at the beginning and search the value in the Array in the validation process 3 - 在开头创建一个strings array ,并在验证过程中搜索该Array中的值

4 - Create a hash map at the beginning and check if the value is true in the validation process 4 - 在开始时创建一个哈希映射并在验证过程中检查该值是否为true

https://www.measurethat.net/Benchmarks/Show/4430/0/search-an-option-inside-a-datalist https://www.measurethat.net/Benchmarks/Show/4430/0/search-an-option-inside-a-datalist

Just to clarify, I show you a working example, which initialize an array of options:为了澄清起见,我向您展示了一个工作示例,该示例初始化了一组选项:

 const colours = [...document.querySelectorAll('#colours option')].map( option => option.value) document.getElementById("colour").addEventListener("keyup", e => { if(colours.includes(e.target.value)) { document.querySelector('#colour').classList.remove('invalid') document.querySelector('#colour').classList.add('valid') } else { document.querySelector('#colour').classList.remove('valid') document.querySelector('#colour').classList.add('invalid') } })
 .valid { border: 3px solid green; } .invalid { border: 3px solid red; }
 <input id="colour" type="text" list="colours"> <datalist id="colours"> <option value="Red" data-id="1"> <option value="Blue" data-id="2"> <option value="Green" data-id="3"> <option value="Black" data-id="4"> <option value="White" data-id="5"> </datalist>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM