Here is my html component:
<div *ngFor="let chart of barChartTypeSelect">
{{chart.mainChart}}
<select [(ngModel)]="selectedRepositoryName" (ngModelChange)="onRepositorySelected()">
<option *ngFor=" let repository of barChartTypeSelect" [value]="repository.mainChart">
{{repository.mainChart}}
</option>
</select>
</div>
In my typescript file, I defined the following:
private onRepositorySelected() {
this.selectedRepository = this.barChartTypeSelect.find(repository => repository.mainChart === this.selectedRepositoryName);
}
What I am trying to achieve is to create dynamic divs based on a json file that I parsed. Each div contains a chart with a conditional selects to adjust it. By parsing the json file and being aware of each object, we can actually decide if we need to attach a selects or not (if the object only contains a key but without any value, then there is no selects).
In other words, the json object maps for each key on the first level to a chart. Every secondary level is a select option that redraws the chart on select, every third level is also a select option that only gets displayed if the second select is checked, and so on.
Here is the object parsed:
{
"consumerPriceIndex": [],
"grossDomesticProductPercentage": [],
"inflationRate": [],
"newUnderCons": [
"apartment",
"building",
"villa"
],
"population": [
"quarter",
"year"
],
"populationChange": [
"quarter",
"year"
],
"transactionVolume": {
"apartment": [
"quarter",
"year"
],
"total": [
"quarter",
"year"
],
"villa": [
"quarter",
"year"
]
},
"transactionVolumeOilIndex_total_quarter": []
}
I can always hard code the values, but I want to achieve the mvc structure as closely as possible. Thank you.
Related
I want to generate a table from a JSON objects array. Each object represents an application and has 4 properties: name, package, versions, and users.
name and package are textual, and users is numeric. versions, however, is an array of arrays: each internal array contains a version name and a version code. Here is a sample JSON:
[{
"name": "Angry Birds",
"package": "oldgames",
"versions": [
["alpha", 0.1],
["beta", 0.2],
["release", 1]
],
"users": 800
},
{
"name": "Temple Run",
"package": "oldgames",
"versions": [
["beta", 0.7],
["release", 2]
],
"users": 130
},
{
"name": "Snake",
"package": "veryoldgames",
"versions": [
["release", 0]
],
"users": 2
}]
The table requirements are as follows:
There should be 4 columns corresponding to the mentioned properties: Name, Package, Version (singular), and Users.
The Version column should contain a dropdown (an HTML select), with each option referring to a specific version. In addition, each dropdown contains an "All" option to refer to all the versions of the app.
The text of each option is the version name, and the value is the version code.
When a specific version is selected, an external function is called and returns the number of users that uses this specific version. Then, the row's Users cell is updated with the new number.
(I know it's a bit convoluted, and that there are probably better ways to visualize the data, but right now this is the architecture I have to implement and I can't change it)
To create the dropdown, I tried using the built-in List editor. I soon found out this is the wrong approach since the List editor is constructed with predefined values - identical values for each and every row in the table, while I need every row to have a unique dropdown.
After researching a bit, I realized I needed to use a Custom Formatter. I take the versions array and manually construct a select. Here is a demo:
const data = [
{
"name": "Angry Birds",
"package": "oldgames",
"versions": [["alpha", 0.1], ["beta", 0.2], ["release", 1]],
"users": 800
},
{
"name": "Temple Run",
"package": "oldgames",
"versions": [["beta", 0.7], ["release", 2]],
"users": 130
},
{
"name": "Snake",
"package": "veryoldgames",
"versions": [["release", 0]],
"users": 2
}
];
new Tabulator("#example-table", {
data: data,
layout: "fitColumns",
height: 107,
columns: [
{
title: "Name",
field: "name",
},
{
title: "Package",
field: "package"
},
{
title: "Versions",
field: "versions",
formatter: function (cell, formatterParams, onRendered) {
const select = document.createElement("select");
const options = select.options;
options.add(new Option("all", "all"));
const value = cell.getValue();
for (let i = 0; i < value.length; i++) {
options.add(new Option(value[i][0], value[i][1]));
}
return select;
}
},
{
title: "Users",
field: "users"
}
],
});
<script src="https://unpkg.com/tabulator-tables/dist/js/tabulator.min.js"></script>
<link href="https://unpkg.com/tabulator-tables/dist/css/tabulator.min.css" rel="stylesheet"/>
<div id="example-table"></div>
The data is displayed properly. Initially, I planned to bind a change event listener to the select, but the documentation recommends not doing that:
...it is a bad idea to try to use code outside of Tabulator to
directly alter or bind events to DOM elements inside the table,
because there is a good chance that the element you are trying to
manipulate will be destroyed on the next scroll.
Instead, the documentation recommends using its predefined events:
Tabulator has a wide range of callbacks, formatters and other
functions that allow you to manipulate the table contents in a way
that is safe and won't be affected by the rows being recreated.
The closest event I could find is cellEditing. However, I don't know how to trigger it when the value of the select changes.
What is the recommended way to implement these requirements?
I'm building a simple search for my application and am wondering if there is way to dynamically set the values of forms based on JSON
I send a query to the API which returns a bit of JSON along with the results which indicates what the filtered dropdown boxes should be. So for example, if I'm searching for cars and in the make, I select 'Ford' this is what a typical response would look like to indicate what the other dropdown fields should look like:
{
"make": [
"Ford"
],
"model": [
"ECOSPORT",
"Fiesta",
"Focus",
"Transit"
],
"colour": [
"Blue",
"White",
"Red",
"Black"
],
"fuel": [
"Petrol",
"Diesel"
],
"transmission": [
"Manual"
],
"bodystyle": [
"Suv",
"Hatchback",
"Bus"
],
"engine": [
998,
1498,
1242,
1499,
2198
],
"door": [
5,
3
],
"interior": [
"Part leather",
"Not set",
"Cloth"
],
"age": [
"2016",
"2017",
"2011"
]
}
The original query is also returned which looks like this, (it could have multiple if more than one option was selected for the original query, for example, make and model)
[
{
"name": "make",
"value": "Ford"
}
]
What I'm looking to do is loop through the first JSON which contains the dropdown filters and loop through each form element (by name) and update the value (Except for the one in the original query, so in this case the make)
The form elemets input names match the names returned by the query:
<select name="make">
<option value="">Make (All)</option>
</select>
</div>
<div class="col span_2_of_12">
<select name="model">
</select>
</div>
<select name="transmission"></select>
In this example, I would like the code to add options to the select for 'model' and 'transmission' whilst not updating the values for 'make' as that was in the original query
I've tried to do it as a loop but it doesn't seem to do anything
var dropdown = data.dropdown;
$.each(dropdown, function (key, value) {
var item = $("input[name=" + key + "]")
item.empty()
$.each(value, function (x, y) {
item.append(new Option(y + ' (All)', ""));
item.append("<option value=" + y + ">" + y + "</option>");
});
});
I am looking out methods of Extracting only portion of JSON document with REST API search call in MarkLogic using JavaScript or XQuery.
I have tried using query options of re extract-document-data but was not successful. Tried checking my extract path using CTS.validextract path but that function was not recognised in Marklogic 9.0-1
Do I have to using specific search options like constraints or structured query.
Could you please help out? TIA.
I have below such sample document
{
"GenreType": {
"Name": "GenreType",
"LongName": "Genre Complex",
"AttributeDataType": "String",
"GenreType Instance Record": [
{
"Name": "GenreType Instance Record",
"Action": "NoChange",
"TitleGenre": [
"Test1"
],
"GenreL": [
"Test1"
],
"GenreSource": [
"ABC"
],
"GenreT": [
"Test1"
]
},
{
"Name": "GenreType Instance Record",
"Action": "NoChange",
"TitleGenre": [
"Test2"
],
"GenreL": [
"Test2"
],
"GenreSource": [
"PQR"
],
"GenreT": [
"Test2"
]
}
]
}
}
in which i need to search a document with attribute "TitleGenre" WHERE GenreSource = “ABC” in the GenreType complex attribute. It's an array in json document.
I was using the search option as below, (writing search option in XML, but searching the in json documents)
<extract-path>/GenreType/"GenreType Instance Record"[#GenreSource="ABC"]</extract-path>
I am still facing the issues. If possible could you please let me know how json documents can be searched for such specific requirement? #Wagner Michael
You can extract document data by using the extract-document-data option.
xquery version "1.0-ml";
let $doc := object-node {
"GenreType": object-node {
"Name": "GenreType",
"LongName": "Genre Complex",
"AttributeDataType": "String",
"GenreType-Instance-Record": array-node {
object-node {
"TitleGenre": array-node {
"Test1"
},
"GenreSource": array-node {
"ABC"
}
},
object-node {
"TitleGenre": array-node {
"Test2"
},
"GenreSource": array-node {
"PQR"
}
}}
}
}
return xdmp:document-insert("test.xml", $doc);
import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
search:search(
"Genre Complex",
<options xmlns="http://marklogic.com/appservices/search">
<extract-document-data>
<extract-path>/GenreType/GenreType-Instance-Record[GenreSource = "ABC"]</extract-path>
</extract-document-data>
</options>
)
In this case /GenreType/GenreType-Instance-Record is the xpath to the extracted element.
Relating to your comment, i also added a predicate [GenreSource = "ABC"]. This way only GenreType-Instance-Record which have a GenreSource of "ABC" are being extracted!
Result:
....
<search:extracted kind="array">[{"GenreType-Instance-Record":{"TitleGenre":["Test1"], "GenreSource":["ABC"]}}]
</search:extracted>
....
Note:
You can add multiple <search:extract-path> elements!
I had to change the name of GenreType Instance Record to GenreType-Instance-Record. I am not sure if you can have property names with whitespaces and access them with xpath. I couldn't get it working this way.
Please post your search options, if this does not work for you.
Edit: Added a predicate to the extract-path.
Thank you so much Wagner, for your prompt trials. Helped me look out for accurate solution to my problem as of now. I have used below extract path, as i could not modify the names in documents. /GenreType/array-node("GenreType Instance Record")/object-node()/TitleGenre[following-sibling::GenreSource="ABC"]
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.
I am trying to follow this example on how to setup a combo-box using dojo, but wondering how one can specify name and value programmatically. The example presented uses the same values for label and value - which is probably not one wants in most cases.
{
"identifier": "abbreviation",
"label": "name",
"items": [
{ "abbreviation": "AL", "name": "Alabama" },
... other 48 states here ...
{ "abbreviation": "WY", "name": "Wyoming" }
]
}
If you are asking how to replace the hard coded list in the example then here is what you have to do. In the above scenario items was used to specify the data which is an array (abbreviations and names) of values.
In your case you will need to get the data / object from your data source. Once you have that data/object expose it to the view. Once this has been done you can now do the following structure.
You store is really your items above however stateStore will be a java script array which contains the data from your data source.
stateStore = [{"abbreviation": "AL", "name": "Alabama"},
... other 48 states here ...,
{ "abbreviation": "WY", "name": "Wyoming" }]
// create FilteringSelect widget, populating its options from the store
var select = new dijit.form.FilteringSelect({
name: "stateSelect",
placeHolder: "Select a State",
store: stateStore
}, "stateSelect");
HTML
<div style="width:50%;float: left;">
<h1>dijit.form.Select</h1>
<label for="stateSelect">State:</label>
<div id="stateSelect"></div>
</div>