Change select options with other select using JSON data - JQuery - javascript

I have a json data which looks like this:
[{
"id": 9,
"category": "Baby",
"items": "[{\"value\":\"Baby Foods\"}]",
"created_at": "2022-01-08T14:28:48.000000Z",
"updated_at": "2022-01-08T14:28:48.000000Z",
"deleted_at": null
},
{
"id": 10,
"category": "Adult",
"items": "[{\"value\":\"Adult Clothes\"},{\"value\":\"Adult Bags\"},{\"value\":\"Adult Shoes\"}]",
"created_at": "2022-01-09T10:46:34.000000Z",
"updated_at": "2022-01-09T10:46:34.000000Z",
"deleted_at": null
}]
It has a list of categories with its items. Now what I am trying to do now is to populate that data on select boxes in a way that if a user change category queried from JSON will show items (as shown on JSON) to another select box as options belonging to that category selected.
Here is what I have tried so far using jquery:
let dropdown = $('#category');
dropdown.empty();
dropdown.append('<option selected="true" disabled>Choose</option>');
dropdown.prop('selectedIndex', 0);
const url = 'http://localhost:8000/admin/categories/show';
// Populate dropdown with list of categories
$.getJSON(url, function (data) {
$.each(data, function (key, entry) {
dropdown.append($('<option></option>').attr('value', entry.category).text(entry.category));
})
});
Here is the result which shows categories on category select box perfectly:
I don't have idea how to get items if certain category is selected on another select box (second one) any help will greatly appreciated.

You can define an eventHandler for your category change event, and whenver it changes, you can read related items from the source data, and put items in the target option, like this:
let data = [{
"category": "Baby",
"items": "[{\"value\":\"Baby Foods\"}]",
},
{
"category": "Adult",
"items": "[{\"value\":\"Adult Clothes\"},{\"value\":\"Adult Bags\"},{\"value\":\"Adult Shoes\"}]",
}
]
let categories = $('#category');
let items = $('#items')
function fillDropdown(target, {data, prop}) {
$.each(data, function(key, data) {
target.append($('<option></option>').attr('value', data[prop]).text(data[prop]));
})
}
fillDropdown(categories, {data, prop: 'category'})
categories.on('change', function(e) {
items.html('');
let value = $(this).val();
if (value) {
let dataItem = data.find(v => v.category == value);
const options = JSON.parse(dataItem.items);
fillDropdown(items, {data: options, prop: 'value'})
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="category">
<option></option>
</select>
<select id="items"></select>

Related

Create dynamic form with parameters

On a grid I have to create a (popup) form dynamically, based on a JSON that has the data for what type of input goes on the form.
For the select type, the options are different for every form, and all the options are in another JSON that is called based on the name on the previous JSON.
example.
I click on button "create report" for row number 1 on grid. popup open up with form to get the filter of the report. the button call the 1st JSON that is like this:
[
{
"name": "Report Users residence",
"input": [{
"type": "select",
"name": "city",
},
{
"type": "select",
"name": "address",
}]
}
]
In this case the cities are in another JSON called "city.json".
[
{
"code": "000000",
"description": "City1"
},
{
"code": "000001",
"description": "City2",
}
]
I was able to create the form, but i don't know how to get the option of the 2nd JSON on the select "city".Can someone give me an example on how to do it?
First, city data have to converted into object. After that using jQuery $.each method, you can loop over city object to create option for select and append into the select.
This is an example of the idea :
<select name="city"></select>
<script>
var city = [{"code":"000000","description":"City1"},{"code":"000001","description":"City2",}];
var citySelect = $(document).find('select[name="city"]');
$(city).each(function(key,item){
var cityOption = new Option(item.description,item.code);
citySelect.append(cityOption);
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name="city"></select>
<script>
var city = [{"code":"000000","description":"City1"},{"code":"000001","description":"City2",}];
var citySelect = $(document).find('select[name="city"]');
$(city).each(function(key,item){
var cityOption = new Option(item.description,item.code);
citySelect.append(cityOption);
});
</script>

Vue mapping or filtering array based on UI selections,

I have JSON data hundreds of entries like this:
{
"product":"Protec",
"type":"Central Opening",
"attribute":"Triple Lock",
"height":"2100",
"width":"1600",
"price":"3000"
},
{
"product":"Protec",
"type":"Sliding Door",
"attribute":"Single Lock",
"height":"2100",
"width":"1600",
"price":"3000"
},
{
"product":"ForceField",
"type":"Hinge Door",
"attribute":"Triple Lock",
"height":"2300",
"width":"1200",
"price":"100"
},
my vue component
var distinct_product = new Vue({
el: '#distinct',
data:{
distinct_product: [],
all_products: []
},
I fetch it and store it in my vue component and store it in a second data so when I render it to the ui the user only sees distinct elements.
mounted: async function(){
fetch("/Data/products.json")
.then(res => res.json())
.then(res => {
this.all_products = res
this.distinct_product = res
var disProduct = [...new Set(this.distinct_product.map(x => x.product))]
var disType = [...new Set(this.distinct_product.map(x => x.type))]
var disAttribute = [...new Set(this.distinct_product.map(x => x.attribute))]
this.distinct_product.productArray = disProduct;
this.distinct_product.typeArray = disType;
this.distinct_product.attributeArray = disAttribute;
My problem is, it also renders elements that aren't available to certain products.
for example a product : 'Window' can't have the attribute : 'triple locks'
I was wondering if I could filter/map the all_products array as the user selects a product.
I looked into computed properties mainly but I'm not sure of a good way to do it. this is my first attempt at a web app and I'm fairly new to JS too.
I aimed to iterate through the array pushing only objects containing the product selected in the UI
atm this is what I've attempted with no luck:
this.distinct_product.product which is bound to the UI
for (var i = 0; i < this.all_products.length; i++){
if (this.all_products[i] === this.distinct_product.product){
this.product.push(i);
return this.product;
}
}
so it would iterate over all_products looking for objects containing this.distinct_product.product which would contain 'Protec' or another product
Am I going at this the wrong way? should I step back in general and try and work with that data a different way?
Sorry if the question is structured poorly it's a skill I'm trying to work on, criticism is welcomed.
You are on the right track. I'll share a simple example so you can understand and make changes to your code accordingly.
var productdata = [
{
"product": "Protec",
"type": "Central Opening",
"attribute": "Triple Lock",
"height": "2100",
"width": "1600",
"price": "3000"
},
{
"product": "Protec",
"type": "Sliding Door",
"attribute": "Single Lock",
"height": "2100",
"width": "1600",
"price": "3000"
},
{
"product": "ForceField",
"type": "Hinge Door",
"attribute": "Triple Lock",
"height": "2300",
"width": "1200",
"price": "100"
},
];
//setTimeout(function () {
distinct_productVue = new Vue({
el: '#distinct',
data: {
//selected: {},
distinct_products: [],
all_products: productdata.map(function (x, index) {
return { text: x.product, value: index + 1 };
}),
selected: '0'
},
computed: {
},
mounted: function () {
this.all_products.unshift({ text: 'Please select a product', value: 0 });
},
methods: {
getDistinctProduct: function () {
var self = this;
self.distinct_products = productdata.filter(function (x, index) {
if (x.product === self.all_products[self.selected].text) {
return { text: x.product, value: index };
}
else { return false; }
});
}
}
});
<html>
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.0/vue.min.js'></script>
</head>
<body>
<div id="distinct">
<select v-model="selected" v-on:change="getDistinctProduct">
<option v-for="option in all_products" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<!--<span>Selected: {{ selected }}</span>-->
<div v-show="selected != 0" style="margin-top:15px;">
<b>Available products</b>
<div v-for="pro in distinct_products" style="margin-top:15px;">
<div>product: {{pro.product}}</div>
<div>type: {{pro.type}}</div>
<div>attribute: {{pro.attribute}}</div>
<div>height: {{pro.height}}</div>
<div>width: {{pro.width}}</div>
<div>price: {{pro.price}}</div>
</div>
</div>
</div>
</body>
</html>

Drop-down empty selection from the menu

I work with a JavaScript app and populate the drop-down menu with a JSON list.
$("#address").append($('<option></option>').attr("value", "1").text(""));
$.each(wallets, function (index, wallet) {
if (selectedCurrency === wallet["currency"].toString().trim()) {
$("#address").append($('<option></option>').attr("value", "1").text(wallet["address"]));
}
})
The UI looks like this,
If I select the empty item (like in the picture), I would like to print empty in the console. Otherwise, I want to print the address value. My intention is to write more code, but, this is where I would like to get started. The code I have,
$("#address").change(function () {
if($(this).val()===""){
console.log('empty');
}
else{
console.log($(this).val());
}
}
However, it only prints 1 in the console and can't distinguish between the empty bar and the address in concern. If I use console.log("The value is " + $(this).text()); inside the change function, it prints every info all together in the console,
The value is mp51mPC38Wtcmybdyd9MPEB2bKnw6eYbCsmqXjM7Mmg6B5LWMad7mHJi339ddaj7xXdBmvXxP1GmXXKojWQJKjgeoASnXVNXCS47z6n41jE2BKKpV6LsPb7dDdStjtuJf1FrYvMMmw1jtrWU5DADxvNR421MKFW1fposgzVMBymnzcZVF4jtZtGAggM5GuLog3Y5o52Mx4xMmq5Rgggfgy2TiRsvtcGm3rxx12R8XbYi9omkdt7ouyJnDXUp4LzdRSRP3ZhU57gUDKy6n2F2QEKk6Fqqk2yMTope5MYp1RtpT949kemrkdfp6qoVN3YiyJhq6nXPvgr3f7YpkS9j
The JSON data I have is something like,
[
{
"id": 1,
"code": "BTC",
"address": "mp51mPC38Wtcmybdyd9MPEB2bKnw6eYbCs",
"currency": "Bitcoin"
},
{
"id": 2,
"code": "BTC",
"address": "mqXjM7Mmg6B5LWMad7mHJi339ddaj7xXdB",
"currency": "Bitcoin"
},
{
"id": 4,
"code": "BTC",
"address": "mvXxP1GmXXKojWQJKjgeoASnXVNXCS47z6",
"currency": "Bitcoin"
}
// some more data
]
What the issue here? My guess is I do something wrong to append the data to the drop-down list and needs to be changed.
I can provide more info if required ....
Just change the value 1 to "" in first option.
$("#address").append($('<option></option>').attr("value", "").text(""));
$.each(wallets, function (index, wallet) {
if (selectedCurrency === wallet["currency"].toString().trim()) {
$("#address").append($('<option></option>').attr("value", "1").text(wallet["address"]));
}
});
check this example.
$("#address").append($('<option></option>').attr("value", "").text(""));
$("#address").append($('<option></option>').attr("value", "1").text("123"));
$("#address").append($('<option></option>').attr("value", "2").text("456"));
$("#address").change(function () {
if($(this).val()===""){
console.log('empty');
}
else{
console.log($(this).val());
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="address">
</select>

dependent dropdownlist with json and python

So I am making a dialog panel for my chat bot in django framework. The Dialog panel consists of intent and entities dropdown list and a dialog textarea. The dropdown list will be dependent on my training data which is in json format.
I want the dropdownlist so that if I choose intent, the entities dropdown list create itself automatically and show all the entities related to selected intent.
I have tried and I am able to show intent dropdown but that too had duplicate intents(which i removed using python set function).But I am unable to figure out how to show all entities based on one particular intent.
Help me. Here's my example json:
{"rasa_nlu_data": {
"common_examples": [
{
"text": "hey",
"intent": "greet",
"entities": []
},
{
"text": "yep",
"intent": "affirm",
"entities": []
},
{
"text": "i'm looking for a place to eat",
"intent": "restaurant_search",
"entities": []
},
{
"text": "i'm looking for a place in the north of town",
"intent": "restaurant_search",
"entities": [
{
"start": 31,
"end": 36,
"value": "north",
"entity": "location"
}
]
},
{
"text": "show me chinese restaurants",
"intent": "restaurant_search",
"entities": [
{
"start": 8,
"end": 15,
"value": "chinese",
"entity": "cuisine"
}
]
},
{
"text": "bye",
"intent": "goodbye",
"entities": []
}
]}}
Basically, all you have to do is loop over the items inside common_examples and check if the intent matches the selected value in the dropdown. If it does, add the entities to entities dropdown.
Since you haven't provided much info about your HTML, I'll try to answer with a few assumptions:
You've a select element with id intentDropdown to show intents.
You've a select element with id entitiesDropdown to show entities.
You're using jQuery.
The code contains some comments to explain what it does.
<!-- intents dropdown -->
<select id="intentsDrowpdown">
<!-- intent options-->
</select>
<!-- entities dropdown -->
<select id="entitesDrowpdown"></select>
<!-- Javascript -->
<script>
var data = {"rasa_nlu_data": { ... }}; // the json data
var totalExamples = data.rasa_nlu_data.common_examples.length; // total items inside common_examples
// listen to the event when selected value in
// the intent dropdown changes
$("#intentsDropdown").on('change', function() {
$("#entitiesDropdown").empty(); // clear the previously added entities from entities drowpdown
var selectedIntent = this.value; // currently selected intent
// loop over the items in common_examples
for (var i = 0; i < totalExamples; i++) {
var currentExample = data.rasa_nlu_data.common_examples[i] // current example in the loop
// see if the selected intent matches the
// intent of the current example in the loop
if (currentExample.intent == selectedIntent) {
// if intent matches
// loop over the items inside entities
// of the current example
for (var j = 0; j < currentExample.entities.length; j++) {
// add the option in the dropdown
$("#entitiesDropdown").append($('<option>', {
value: currentExample.entities[j].value,
text: currentExample.entities[j].entity
}));
}
}
}
});
</script>
Finally, I'd like to bring one thing to your notice. Conside the example below:
"entities": [
{
"start": 8,
"end": 15,
"value": "chinese",
"entity": "cuisine"
}
The entities list has one item in it. And that item has 4 sub-items in it. In your question, you haven't made it clear if you want to show all the sub-items in one dropdown option (e.g. start: 8, end: 15, value: chinese, entity: cuisine) or if you want a separate option for each sub-item.
The JS code that I've posted will create a dropdown option like this:
<option value="chinese">cuisine</option>.
If you want to display other items, you can just create another loop and keep adding the items to dropdown.

<optgroup> with JSON on $.each loop

I’m trying to parse the JSON file in such way that the subsectors of JSON are shown in an <optgroup label=""> (don’t want them to be selectable).
I have this JSON file:
{
"sectors": [
{
"title": "Business, Finance & Technology",
"subsectors": [
{
"title": "Finance and insurance",
"industries": [
{"name": "Retail banking"},
{"name": "Insurance"},
{"name": "Investment banking"}
]
},
{
"title": "Business Services",
"industries": [
{"name": "Accounting & Audit"},
{"name": "Recruitment"},
{"name": "Legal services"}
]
}
]
},
// extra code omitted for brevity
And I populate the <select> options with this:
// populate <select> with available choices
$.getJSON('models/industries.json', function (data) {
$.each(data.sectors, function (i, sector) {
$.each(sector.subsectors, function (i, subsector) {
$('<option />').html('#' + subsector.title).appendTo('.js-industries-select');
$.each(subsector.industries, function (i, industry) {
$('<option />').html(industry.name).appendTo('.js-industries-select');
})
});
});
});
Then I call the Chosen plugin to change the <select> into a dynamic input. You can see which elements I want as label being marked with #.
See demo here: http://jsfiddle.net/qaczD/
I basically need to create an <optgroup> before the last $.each, assign the label="" as subsector.title and then populate that group with the choices. Once the last $.each has finished, close the ` somehow and start a new one.
Any ideas?
Try thisone:
http://jsfiddle.net/qaczD/2/
// populate <select> with available choices
$.getJSON('http://dl.dropboxusercontent.com/u/48552248/websites/timewasted/new/industries.json', function (data) {
$.each(data.sectors, function (i, sector) {
$.each(sector.subsectors, function (i, subsector) {
var optGroup=$('<optgroup />').attr('label','#' + subsector.title).appendTo('.js-industries-select');
$.each(subsector.industries, function (i, industry) {
// if (industry.name.search(regex) != -1) {
$(optGroup).append( $('<option />').html(industry.name));
// }
})
});
});
console.log('yes');
});
// call chosen plugin that prettifies the Industry options
setTimeout(function() {$(".js-industries-select").chosen({
placeholder_text_multiple: 'e.g. Retail banking…'
});}, 1000);
The solution
$.each(sector.subsectors, function (i, subsector) {
var group = $('<optgroup />').attr('label','#' + subsector.title).appendTo('.js-industries-select');
$.each(subsector.industries, function (i, industry) {
$('<option />').html(industry.name).appendTo(group);
})
});

Categories