Geoff_S
Geoff_S

Reputation: 5105

Getting other values from lower object/array level

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

Answers (2)

gaetanoM
gaetanoM

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

Rigoberto Ramirez Cruz
Rigoberto Ramirez Cruz

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

Related Questions