[英]How to use a json response from an ajax request in a JavaScript function as a Javascript array
I have created a autocomplete form using javascript which takes data in the form of an array like 我已经使用javascript创建了自动填充表单,该表单以数组形式获取数据,例如
var city_list = ["Allahabad","Baramulla","Bellary"]
But my controller returns the requested data in json format like 但是我的控制器以json格式返回请求的数据,例如
[{"city_id": 9,"city_name": "Allahabad"},{"city_id": 47,"city_name": "Baramulla"},{"city_id": 60,"city_name": "Bellary"}]
I have searched a lot of StackOverflow and internet posts but nothing worked for me and since I am not good at javascript so I am unable to find a solution on my own. 我搜索了很多StackOverflow和Internet帖子,但对我没有任何帮助,并且由于我不擅长javascript,因此无法自行找到解决方案。
Ajax Request Ajax请求
$('#heroCitySearch').keyup(function () {
var q = 'q='+$(this).val();
if(q != '') {
$.ajax({
type:'GET',
url:"/fetch/city",
data:q,
success:function (data) {
if(data){
$.each(data,function(value){
autocomplete(document.getElementById("heroCitySearch"), data[value].city_name);
// "data[value].city_name" <- This parameter must be an array
}
}
})
}
});
Javascript Function (autocomplete) Javascript函数(自动完成)
function autocomplete(inp, arr) {
/*the autocomplete function takes two arguments,
the text field element and an array of possible autocompleted values:*/
var currentFocus;
/*execute a function when someone writes in the text field:*/
inp.addEventListener("input", function(e) {
var a, b, i, val = this.value;
/*close any already open lists of autocompleted values*/
closeAllLists();
if (!val) { return false;}
currentFocus = -1;
/*create a DIV element that will contain the items (values):*/
a = document.createElement("DIV");
a.setAttribute("id", this.id + "autocomplete-list");
a.setAttribute("class", "autocomplete-items");
/*append the DIV element as a child of the autocomplete container:*/
this.parentNode.appendChild(a);
/*==== Below is the code block which uses array elements====*/
/*for each item in the array...*/
for (i = 0; i < arr.length; i++) {
/*check if the item starts with the same letters as the text field value:*/
if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
/*create a DIV element for each matching element:*/
b = document.createElement("DIV");
/*make the matching letters bold:*/
b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
b.innerHTML += arr[i].substr(val.length);
/*insert a input field that will hold the current array item's value:*/
b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
/*execute a function when someone clicks on the item value (DIV element):*/
b.addEventListener("click", function(e) {
/*insert the value for the autocomplete text field:*/
inp.value = this.getElementsByTagName("input")[0].value;
/*close the list of autocompleted values,
(or any other open lists of autocompleted values:*/
closeAllLists();
});
a.appendChild(b);
}
}
});
/*execute a function presses a key on the keyboard:*/
inp.addEventListener("keydown", function(e) {
var x = document.getElementById(this.id + "autocomplete-list");
if (x) x = x.getElementsByTagName("div");
if (e.keyCode == 40) {
/*If the arrow DOWN key is pressed,
increase the currentFocus variable:*/
currentFocus++;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 38) { //up
/*If the arrow UP key is pressed,
decrease the currentFocus variable:*/
currentFocus--;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 13) {
/*If the ENTER key is pressed, prevent the form from being submitted,*/
e.preventDefault();
if (currentFocus > -1) {
/*and simulate a click on the "active" item:*/
if (x) x[currentFocus].click();
}
}
});
function addActive(x) {
/*a function to classify an item as "active":*/
if (!x) return false;
/*start by removing the "active" class on all items:*/
removeActive(x);
if (currentFocus >= x.length) currentFocus = 0;
if (currentFocus < 0) currentFocus = (x.length - 1);
/*add class "autocomplete-active":*/
x[currentFocus].classList.add("autocomplete-active");
}
function removeActive(x) {
/*a function to remove the "active" class from all autocomplete items:*/
for (var i = 0; i < x.length; i++) {
x[i].classList.remove("autocomplete-active");
}
}
function closeAllLists(elmnt) {
/*close all autocomplete lists in the document,
except the one passed as an argument:*/
var x = document.getElementsByClassName("autocomplete-items");
for (var i = 0; i < x.length; i++) {
if (elmnt != x[i] && elmnt != inp) {
x[i].parentNode.removeChild(x[i]);
}
}
}
/*execute a function when someone clicks in the document:*/
document.addEventListener("click", function (e) {
closeAllLists(e.target);
});
}
I have copied the above script from w3school . 我从w3school复制了上面的脚本。
And in above code b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
在上面的代码中
b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
instead of city name if I want to use city Id, what changes should I make. 如果要使用城市ID,请使用城市名称而不是城市名称,我应该进行哪些更改。
Thanks for your help. 谢谢你的帮助。
Below example snippet would help you get only the city name: 下面的示例代码片段将帮助您仅获取城市名称:
<!-- begin snippet: js hide: false console: true babel: false -->
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> * { box-sizing: border-box; } body { font: 16px Arial; } .autocomplete { /*the container must be positioned relative:*/ position: relative; display: inline-block; } input { border: 1px solid transparent; background-color: #f1f1f1; padding: 10px; font-size: 16px; } input[type=text] { background-color: #f1f1f1; width: 100%; } input[type=submit] { background-color: DodgerBlue; color: #fff; cursor: pointer; } .autocomplete-items { position: absolute; border: 1px solid #d4d4d4; border-bottom: none; border-top: none; z-index: 99; /*position the autocomplete items to be the same width as the container:*/ top: 100%; left: 0; right: 0; } .autocomplete-items div { padding: 10px; cursor: pointer; background-color: #fff; border-bottom: 1px solid #d4d4d4; } .autocomplete-items div:hover { /*when hovering an item:*/ background-color: #e9e9e9; } .autocomplete-active { /*when navigating through the items using the arrow keys:*/ background-color: DodgerBlue !important; color: #ffffff; } </style> </head> <body> <h2>Autocomplete</h2> <p>Start typing:</p> <!--Make sure the form has the autocomplete function switched off:--> <form autocomplete="off" action="/action_page.php"> <div class="autocomplete" style="width:300px;"> <input id="myInput" type="text" name="myCountry" placeholder="Country"> </div> <input type="submit"> </form> <script> function autocomplete(inp, arr) { /*the autocomplete function takes two arguments, the text field element and an array of possible autocompleted values:*/ var currentFocus; /*execute a function when someone writes in the text field:*/ inp.addEventListener("input", function(e) { var a, b, i, val = this.value; /*close any already open lists of autocompleted values*/ closeAllLists(); if (!val) { return false;} currentFocus = -1; /*create a DIV element that will contain the items (values):*/ a = document.createElement("DIV"); a.setAttribute("id", this.id + "autocomplete-list"); a.setAttribute("class", "autocomplete-items"); /*append the DIV element as a child of the autocomplete container:*/ this.parentNode.appendChild(a); /*for each item in the array...*/ for (i = 0; i < arr.length; i++) { /*check if the item starts with the same letters as the text field value:*/ if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) { /*create a DIV element for each matching element:*/ b = document.createElement("DIV"); /*make the matching letters bold:*/ b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>"; b.innerHTML += arr[i].substr(val.length); /*insert a input field that will hold the current array item's value:*/ b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>"; /*execute a function when someone clicks on the item value (DIV element):*/ b.addEventListener("click", function(e) { /*insert the value for the autocomplete text field:*/ inp.value = this.getElementsByTagName("input")[0].value; /*close the list of autocompleted values, (or any other open lists of autocompleted values:*/ closeAllLists(); }); a.appendChild(b); } } }); /*execute a function presses a key on the keyboard:*/ inp.addEventListener("keydown", function(e) { var x = document.getElementById(this.id + "autocomplete-list"); if (x) x = x.getElementsByTagName("div"); if (e.keyCode == 40) { /*If the arrow DOWN key is pressed, increase the currentFocus variable:*/ currentFocus++; /*and and make the current item more visible:*/ addActive(x); } else if (e.keyCode == 38) { //up /*If the arrow UP key is pressed, decrease the currentFocus variable:*/ currentFocus--; /*and and make the current item more visible:*/ addActive(x); } else if (e.keyCode == 13) { /*If the ENTER key is pressed, prevent the form from being submitted,*/ e.preventDefault(); if (currentFocus > -1) { /*and simulate a click on the "active" item:*/ if (x) x[currentFocus].click(); } } }); function addActive(x) { /*a function to classify an item as "active":*/ if (!x) return false; /*start by removing the "active" class on all items:*/ removeActive(x); if (currentFocus >= x.length) currentFocus = 0; if (currentFocus < 0) currentFocus = (x.length - 1); /*add class "autocomplete-active":*/ x[currentFocus].classList.add("autocomplete-active"); } function removeActive(x) { /*a function to remove the "active" class from all autocomplete items:*/ for (var i = 0; i < x.length; i++) { x[i].classList.remove("autocomplete-active"); } } function closeAllLists(elmnt) { /*close all autocomplete lists in the document, except the one passed as an argument:*/ var x = document.getElementsByClassName("autocomplete-items"); for (var i = 0; i < x.length; i++) { if (elmnt != x[i] && elmnt != inp) { x[i].parentNode.removeChild(x[i]); } } } /*execute a function when someone clicks in the document:*/ document.addEventListener("click", function (e) { closeAllLists(e.target); }); } /*An array containing all the country names in the world:*/ var countries = [{"city_id": 9,"city_name": "Allahabad"},{"city_id": 47,"city_name": "Baramulla"},{"city_id": 60,"city_name": "Bellary"}].map(city => city.city_name); /*initiate the autocomplete function on the "myInput" element, and pass along the countries array as possible autocomplete values:*/ autocomplete(document.getElementById("myInput"), countries); </script> </body> </html>
const cityArry = [{"city_id": 9,"city_name": "Allahabad"},{"city_id": 47,"city_name": "Baramulla"},{"city_id": 60,"city_name": "Bellary"}]
console.log(cityArry.map(city => city.city_name))
You can pluck out what you want from that JSON response. 您可以从JSON响应中提取想要的内容。 Something like this:
像这样:
// You example var cities = [{ "city_id": 9, "city_name": "Allahabad" }, { "city_id": 47, "city_name": "Baramulla" }, { "city_id": 60, "city_name": "Bellary" }]; const myFormat = cities.map((city) => { return city.city_name; }) console.log(myFormat); // Output // [ // "Allahabad", // "Baramulla", // "Bellary" // ]
instead of this: 代替这个:
if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
}
use this: 用这个:
if (arr[i].city_id == +val ||
arr[i].city_name.substr(0, val.length).toUpperCase() == val.toUpperCase()) {
}
+val
will convert value to the number. +val
将值转换为数字。
and you can also improve the search by adding regex matching, so it will found text anywhere in the name 并且您还可以通过添加正则表达式匹配项来改善搜索效果,这样它将在名称中的任意位置找到文本
var re = new RegExp(val, 'i');
if (arr[i].city_id == +val || re.test(arr[i].city_name)) {
}
if you want to be able to use special characters like *
or +
in input, you will need to escape the regex special characters . 如果要在输入中使用
*
或+
等特殊字符,则需要转义regex特殊字符 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.