Reputation: 5105
I have a working snippet below where if you start typing Cat in the first input, the dropdown populates correctly and if you click on one it fills the first box with the "Name" value, which is right. But how can I get the lower level attributes to fill other inputs as well?
Basically, I want to be able to assign multiple array values in inputs from this object below.
Attributes is at the same level as "name" within source, it's just a new array Any help much appreciated
$('#productInput').on('input', function() {
let _this = $(this);
let foundOption;
let optSelector = `option[value='${_this.val()}']`;
if (_this.val() === '') {
return;
} else if ($('#returnedProducts').find(optSelector).length) {
//this one works
$("#groupName").val(_this.val());
//I want to fill these with _source.attributes.groupColor and groupCategory
$("#groupColor").val();
$("#groupCategory").val();
} else {
const searchResult = $(this).val();
$("#returnedProducts").empty();
var result = [{
_source: {
"name": "cat",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}, {
_source: {
"name": "cat1",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}, {
_source: {
"name": "cat2",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}, {
_source: {
"name": "cat33",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}];
for (let i = 0; i < result.length; i++) {
$("#returnedProducts").append("<option srindex=" + [i] + " value=" + result[i]._source.name + ">" + result[i]._source.name + "</option>");
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="productInput" list="returnedProducts">
<datalist id="returnedProducts"></datalist>
<input id="groupName">
<input id="groupColor">
<input id="groupCategory">
Upvotes: 0
Views: 55
Reputation: 42054
I suggest to change the way you create the options:
$("#returnedProducts").append("<option srindex=" + [i] + " value=" + result[i]._source.name + ">" + result[i]._source.name + "</option>");
Use the jQuery way and add a data attribute:
$("#returnedProducts").append($("<option/>",
{
"srindex": i,
"data-attributes": JSON.stringify(result[i]._source.attributes),
"value": result[i]._source.name,
"html": result[i]._source.name,
}
));
In this way you get your attributes:
var attributes = $('#returnedProducts').find(optSelector).data('attributes');
Now, you can get the values:
$("#groupColor").val(attributes.groupColor);
$("#groupCategory").val(attributes.groupCategory);
The example:
$('#productInput').on('input', function () {
let _this = $(this);
let foundOption;
let optSelector = `option[value = '${_this.val()}']`;
if (_this.val() === '') {
return;
} else if ($('#returnedProducts').find(optSelector).length) {
//this one works
$("#groupName").val(_this.val());
//I want to fill these with _source.attributes.groupColor and groupCategory
var attributes = $('#returnedProducts').find(optSelector).data('attributes');
$("#groupColor").val(attributes.groupColor);
$("#groupCategory").val(attributes.groupCategory);
} else {
const searchResult = $(this).val();
$("#returnedProducts").empty();
var result = [{
_source: {
"name": "cat",
attributes: {
"groupColor": "blue1",
"groupCategory": "Misc1",
},
},
}, {
_source: {
"name": "cat1",
attributes: {
"groupColor": "blue2",
"groupCategory": "Misc2",
},
},
}, {
_source: {
"name": "cat2",
attributes: {
"groupColor": "blue3",
"groupCategory": "Misc3",
},
},
}, {
_source: {
"name": "cat33",
attributes: {
"groupColor": "blue4",
"groupCategory": "Misc4",
},
}
}];
for (let i = 0; i < result.length; i++) {
$("#returnedProducts").append($("<option/>",
{
"srindex": i,
"data-attributes": JSON.stringify(result[i]._source.attributes),
"value": result[i]._source.name,
"html": result[i]._source.name,
}
));
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="productInput" list="returnedProducts">
<datalist id="returnedProducts"></datalist>
<input id="groupName">
<input id="groupColor">
<input id="groupCategory">
Upvotes: 1
Reputation: 380
You can project your array in order to just retrieve the item for the selected element, use map and filter to achieve that.
$('#productInput').on('input', function() {
// Moved here because of the variable scope
var result = [{
_source: {
"name": "cat",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}, {
_source: {
"name": "cat1",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}, {
_source: {
"name": "cat2",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}, {
_source: {
"name": "cat33",
attributes:{
"groupColor": "blue",
"groupCategory": "Misc",
},
},
}];
let _this = $(this);
let foundOption;
let optSelector = `option[value='${_this.val()}']`;
if (_this.val() === '') {
return;
} else if ($('#returnedProducts').find(optSelector).length) {
//this one works
var name = _this.val();
$("#groupName").val(_this.val());
// Project and filter the array
var selected = result.map(item => item["_source"])
.filter(item => item["name"] == name)
.map(item => item["attributes"])[0];
console.log(selected)
//I want to fill these with _source.attributes.groupColor and groupCategory
$("#groupColor").val(selected["groupColor"]);
$("#groupCategory").val();
} else {
const searchResult = $(this).val();
$("#returnedProducts").empty();
for (let i = 0; i < result.length; i++) {
$("#returnedProducts").append("<option srindex=" + [i] + " value=" + result[i]._source.name + ">" + result[i]._source.name + "</option>");
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="productInput" list="returnedProducts">
<datalist id="returnedProducts"></datalist>
<input id="groupName">
<input id="groupColor">
<input id="groupCategory">
Upvotes: 1