This is my JavaScript code:
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
$("input#suggestZams").autocomplete({
source: "content/prevadzky/zam/zam_json2.php?letter=all",
minLength: 1,
delay: 0,
select: function(event, ui) {
alert(1);
}
});
});
//]]>
</script>
This is my HTML:
<input id="suggestZams" class="input" size="10" />
The URL zam_json2.php?letter=all returns this json:
[
{ "id": "31440", "value": "Andrej\u010d\u00e1k, Ing." },
{ "id": "31690", "value": "Alexovi\u010d , Ing." },
{ "id": "31796", "value": "Antoni\u010d , Ing." },
{ "id": "31989", "value": "Antolik , Ing." },
{ "id": "32010", "value": "Ambrozov\u00e1 RNDr., PhD." },
{ "id": "32014", "value": "Aksam\u00edt" },
{ "id": "32024", "value": "Angelovi\u010d" },
{ "id": "32102", "value": "Andrej\u010d\u00e1k" },
{ "id": "32168", "value": "Avukov\u00e1 , Ing." },
{ "id": "32177", "value": "Andr\u00e1\u0161" },
{ "id": "32181", "value": "Andrej\u010d\u00e1kov\u00e1 , Mgr." },
{ "id": "32403", "value": "Arend\u00e1\u0161 , Bc." },
{ "id": "47379", "value": "An\u010fal" },
{ "id": "47399", "value": "Adam\u00edk , Ing." },
{ "id": "50022", "value": "Abo\u0161i" },
{ "id": "50085", "value": "Armer\u00eda Olmedo , Ing." },
{ "id": "53468", "value": "Anto\u0161" },
{ "id": "54837", "value": "Adamec , Ing." },
{ "id": "56659", "value": "Apostolou" },
{ "id": "57820", "value": "Alez\u00e1r" },
{ "id": "58576", "value": "Andrej\u010d\u00e1k , Bc." },
{ "id": "58587", "value": "Aronov\u00e1 , Ing." },
{ "id": "58595", "value": "Abaffy , Bc." },
{ "id": "58607", "value": "Adamec , Bc." },
{ "id": "58643", "value": "Antu\u0161 , Ing." },
{ "id": "62277", "value": "Adam\u010d\u00e1k , Mgr." },
{ "id": "62379", "value": "Andruch" },
{ "id": "63415", "value": "Adamkovi\u010d , Ing." }
]
Quote:
Autocomplete can be customized to work
with various data sources, by just
specifying the source option. A data
source can be:
an Array with local data
a String, specifying a URL
a Callback
When a String is used, the
Autocomplete plugin expects that
string to point to a URL resource that
will return JSON data. It can be on
the same host or on a different one
(must provide JSONP). The request
parameter "term" gets added to that
URL. The data itself can be in the
same format as the local data
described above.
What you are doing looks odd to me. I think that you will actually need to edit the server side script so that it expects the query string variable term instead of letter and returns an array of strings or an array of {label, value} objects instead of {value, id}.
If the URL content/prevadzky/zam/zam_json2.php?letter=all is provides the "complete" list of words at once, you can do something along these lines:
$.getJSON("content/prevadzky/zam/zam_json2.php?letter=all", function(data) {
var datacopy = $.map(data, function(item) {
return {
label: item.value,
value: item.id
};
});
$("input#suggestZams").autocomplete({
source: datacopy,
minLength: 1,
delay: 0,
select: function(event, ui) {
alert(typeof ui);
}
});
});
If you want to get the data from a url you have to define a function for source:
source: function( request, response ) {
$.ajax({url: "content/prevadzky/zam/zam_json2.php?letter=all",
dataType: "json",
...
});
},
...
EDIT:
In the docs it says: source can be a URL. In this case, try to change the JSON response to have 'label' instead of 'id' in the returned objects.
Here an Script that work for me in jQuery 1.5.1.
source: function( request, response ) {
$.ajax({
url: "...",
dataType: "json",
...
success: function( data ) {
# data = json response
}
});
}
Related
I have an ajax result as follow:
{
"data": [
{
"id": "AABB",
"text": "AABB"
},
{
"id": "BBCC",
"text": "BBCC"
},
{
"id": "CCDD",
"text": "CCDD"
},
{
"id": "DDEE",
"text": "DDEE"
}
]
}
by that I load it to select2 using ajax below:
$("#timezone").select2({
ajax: {
url: "/User/Timezone",
dataType: 'json',
delay: 250,
type: 'GET',
data: function (params) {
return {
q: params.term, // search term
};
},
processResults: function (data) {
var arr = []
$.each(data, function (index, value) {
arr.push({
id: value.id,
text: value.text
})
})
return {
results: arr
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 3,
minimumResultsForSearch: 20
})
I try to search the word CCD, of course I expect the pointer brings me to the CCDD line, but it keeps staying on the first data, did I miss something?
It seems I can't reproduce it, it should not show results that do not match your input.
$("#timezone").select2({
data: [{
"id": "AABB",
"text": "AABB"
},
{
"id": "BBCC",
"text": "BBCC"
},
{
"id": "CCDD",
"text": "CCDD"
},
{
"id": "DDEE",
"text": "DDEE"
},
{
"id": "AABB1",
"text": "AABB1"
},
{
"id": "BBCC1",
"text": "BBCC1"
},
{
"id": "CCDD1",
"text": "CCDD1"
},
{
"id": "DDEE1",
"text": "DDEE1"
},
{
"id": "AABB2",
"text": "AABB2"
},
{
"id": "BBCC2",
"text": "BBCC2"
},
{
"id": "CCDD2",
"text": "CCDD2"
},
{
"id": "DDEE2",
"text": "DDEE2"
},
{
"id": "AABB3",
"text": "AABB3"
},
{
"id": "BBCC3",
"text": "BBCC3"
},
{
"id": "CCDD3",
"text": "CCDD3"
},
{
"id": "DDEE3",
"text": "DDEE3"
}
],
escapeMarkup: function(markup) {
return markup;
},
minimumInputLength: 3,
minimumResultsForSearch: 20
})
select {
width: 200px;
}
<select id="timezone"></select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
I have an object that looks like the following {key: id numbers}
var obj = {
"c4ecb": {id: [3]},
"a4269": {id: [34,36]},
"d76fa": {id: [54,55,60,61]},
"58cb5": {id: [67]}
}
How do I loop each above id in the following array, and return the label?
var response =
{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}
Finally, what I want to do is look up the key and return a string of id values.
For example, input c4ecb and output strawberry. Input a4269 and output lettuce, radish. Input d76fa and output "spaghetti, rigatoni, lasagna, fettuccine"
I think to join the multiple labels output into one string I could use something like
array.data.vegetables.map(vegetables => vegetables.value).join(', ')].toString();
So in the end I want to have something like
var fruits = [some code that outputs "strawberry"];
var vegetables = [some code that outputs "lettuce, radish"];
var pasta = [some code that outputs "spaghetti, rigatoni, lasagna, fettuccine"];
What I've tried so far:
The following loop will return the id only if there is one id to be called for: e.g. only in case one where {id: 3} but returns null in cases like {id: 34,36} (because it's looking for '34,36' in id, which doesn't exist - I need to look for each one individually.
response.data.forEach(({key, options}) => {
if (obj[key]) {
options.forEach(({id, label}) => {
if (id == obj[key].id) obj[key].label = label;
});
}
});
console.log(obj)
Filter the response object to focus on the category that matches the id.
Map over the options array and select the items which appear in obj[id].
Finally convert the filtered results to a string.
See filteredLabelsAsString() function below for implementation.
var obj = {
"c4ecb": {"id": [3]},
"a4269": {"id": [34,36]},
"d76fa": {"id": [54,55,60,61]},
"58cb5": {"id": [67]}
}
var response =
[{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}];
function filteredLabelsAsString(obj_key, obj, content=response) {
// sanity check: obj must contain obj_key
if (Object.keys(obj).includes(obj_key)) {
return content.filter((item) => {
// filter content using value of obj_key
return item.data[0].key == obj_key;
}).map((item) => {
// item : { success: true, data: [] }
// map over options array
return item.data[0].options.map((opt) => {
// option : {id, label}
// return the label if the id is in the obj object's list
if (obj[item.data[0].key].id.includes(opt.id))
return opt.label;
}).filter((label) => {
// filter out empty items
return label !== undefined;
});
}).join(",");
}
// if obj does not contain obj_key return empty string
return "";
}
console.log("fruits: " + filteredLabelsAsString("c4ecb", obj));
console.log("vegetables: " + filteredLabelsAsString("a4269", obj));
console.log("pasta: " + filteredLabelsAsString("d76fa", obj));
I have the following code. But I am not sure why the names observable array is empty. It does not populate anything on the html.
function SolViewModel() {
names = ko.observableArray([{
"type": "optiongroup",
"label": "The Griffins",
"children": [
{ "type": "option", "value": "Peter", "label": "Peter Griffin" },
{ "type": "option", "value": "Lois", "label": "Lois Griffin" },
{ "type": "option", "value": "Chris", "label": "Chris Griffin" },
{ "type": "option", "value": "Meg", "label": "Meg Griffin" },
{ "type": "option", "value": "Stewie", "label": "Stewie Griffin" }
]
}
]);
$(function () {
$('#my-select').searchableOptionList({
data: function () {
var dataInSolFormat = names ; // this is empty
return dataInSolFormat;
}
});
});
}
ko.applyBindings(new SolViewModel());
you need to access observable with () like names().
I'm trying to use the jQuery UI Autocomplete widget with a custom JSON feed I'm getting back from an API, which is formatted as follows:
{
"SearchTerm": "ches",
"HasDirectCountyHit": false,
"DirectCountyHitId": null,
"HasDirectLocationHit": false,
"DirectLocationHitId": null,
"Developments": [
{
"Id": "45339ae3e55a",
"Label": "Chestnut Walk, Bilston",
"Url": "/developments/chestnut-walk-bilston"
},
{
"Id": "4835f52e053a",
"Label": "Crown Park, Chester",
"Url": "/developments/crown-park-chester"
},
{
"Id": "757964964cc6",
"Label": "The Birches, West Timperley",
"Url": "/developments/the-birches-west-timperley"
}
],
"Counties": [
{
"Id": "7",
"Label": "Cheshire",
"Url": "/search?cid=7"
},
{
"Id": "24",
"Label": "Greater Manchester",
"Url": "/search?cid=24"
}
],
"Locations": [
{
"Id": "12061",
"Label": "Cheselbourne, Dorset (DT2 7)",
"Url": "/search?lid=12061"
},
{
"Id": "12062",
"Label": "Chesham, Buckinghamshire (HP5 1)",
"Url": "/search?lid=12062"
},
{
"Id": "12063",
"Label": "Chesham, Greater Manchester (BL9 6)",
"Url": "/search?lid=12063"
},
{
"Id": "12064",
"Label": "Chesham Bois, Buckinghamshire (HP6 5)",
"Url": "/search?lid=12064"
},
{
"Id": "12065",
"Label": "Cheshunt, Hertfordshire (EN8 9)",
"Url": "/search?lid=12065"
},
{
"Id": "12066",
"Label": "Chesley, Kent (ME9 7)",
"Url": "/search?lid=12066"
},
{
"Id": "12067",
"Label": "Cheslyn Hay, Staffordshire (WS6 7)",
"Url": "/search?lid=12067"
},
{
"Id": "12068",
"Label": "Chessetts Wood, Warwickshire (B94 6)",
"Url": "/search?lid=12068"
},
{
"Id": "12069",
"Label": "Chessington, Kingston upon Thames - Greater London (KT9 2)",
"Url": "/search?lid=12069"
},
{
"Id": "12070",
"Label": "Chessmount, Buckinghamshire (HP5 1)",
"Url": "/search?lid=12070"
}
]
}
The API I'm calling returns results based on my search term, so I know that all of the results in the nested objects are matches - my problem is how to access these objects ('Developments', 'Counties' and 'Locations') so that the autocomplete widget can pick up the 'Label' values?
Thanks,
Robin
Ok - here's what you can do:
//put all the keys you want to pull out of your json in an array
var props = [
"Locations", "Counties", "Developments"
];
//empty array for your autocomplete
var labels = [];
//loop thru all the properties you care about
$.each(props, function () {
$.each(source[this], function () {
//and pull out all the labels and add them to the labels array
labels.push(this.Label)
});
});
$("#autocomplete").autocomplete({
source: labels
});
and to see it all in action I created a quick fiddle
http://jsfiddle.net/fr5yb3n0/
I have a form where i collect the form data and when i serializeArray() this form i have this:
[
{
"name": "authenticity_token",
"value": "HRjaGFRSqX6EqTYnyohQbc9g6P6RTsDgV3qizYuoh+E="
},
{
"name": "test[form_meta][index]",
"value": "0"
},
{
"name": "test[form_meta][location]",
"value": "http://localhost/static/test/password.html"
},
{
"name": "test[form_meta][title]",
"value": "Passwords Form"
},
{
"name": "test[form_meta][id]",
"value": "form1"
},
{
"name": "test[data][email[]]",
"value": "arnel#personal.com"
},
{
"name": "test[field_meta][email[]]",
"value": "test.place_detail_email"
},
{
"name": "test[data][password[]]",
"value": "test"
},
{
"name": "test[field_meta][password[]]",
"value": "test.alarm_password"
},
{
"name": "test[type][email[]]",
"value": "text"
},
{
"name": "test[label][email[]]",
"value": "Email Address:"
},
{
"name": "test[type][password[]]",
"value": "text"
},
{
"name": "test[label][password[]]",
"value": "Password:"
},
{
"name": "rec[email[]]",
"value": "test.previous_address_category"
},
{
"name": "rec[password[]]",
"value": "c_test.password[]"
}
]
This is OK. But when i send it to my controller like this:
$.ajax({
type: "post",
data: data,
success: function(){<code>},
error: function(){<code>}
});
I get this on my controller:
{
"authenticity_token"=>"HRjaGFRSqX6EqTYnyohQbc9g6P6RTsDgV3qizYuoh+E=",
"test"=>{
"form_meta"=>{
"index"=>"0",
"location"=>"http://localhost/static/test/password.html",
"title"=>"Passwords Form",
"id"=>"form1"
},
"data"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"field_meta"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"type"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"label"=>{
"email"=>[
nil
],
"password"=>[
nil
]
}
},
"rec"=>{
"email"=>[
nil
],
"password"=>[
nil
]
},
"controller"=>"test",
"action"=>"create"
}
The [nil] arrays are killing me here. What can i do so don't have to change the form and to get the real entered value and not the [nil] values.
Is there any solution for this problem