Hovering on one sentence should highlight matching sentence in another panel in Angular - html

I have 2 different JSON arrays displayed separately using a simple *ngFor loop on the same page. Ex-
json1: [ {
"order": 1,
"similarity": 0.82,
"sentence": "I would like to speak with :name:.",
"matching_sentence": "Hello, I would like to speak with Luke.",
"matching_line": 0
}]
json2: [ {
"order": 0,
"similarity": 0.82,
"sentence": "Hello, I would like to speak with Luke.",
"matching_sentence": "I would like to speak with :name:.",
"matching_line": 1,
"channel": 1,
"timeFrom": 15,
"timeTo": 20
}]
So, order property from json1 matches matching_line property of json2 and vice versa. So, what I need to achieve is that on mouse hover of json1, json2 should also be highlighted and on mouse hover of json2, json1 should also be highlighted.
This code is written in Angular 11 so, any solution whether it is by css or typescript is welcome.

You can achieve it using mouse enter leave events and keeping track of the active class
<div
*ngFor="let item of json1"
[ngClass]="{'highlight': item.order === activeHover}"
(mouseenter)="onHoverChange(item.order)"
(mouseleave)="onHoverChange(null)">
{{item.sentence}}
</div>
<div
*ngFor="let item of json2"
[ngClass]="{'highlight': item.matching_line === activeHover}"
(mouseenter)="onHoverChange(item.matching_line)"
(mouseleave)="onHoverChange(null)">
{{item.sentence}}
</div>
// in ts file
onHoverChange(value: number | null) {
this.activeHover = value;
}
Running sandbox link

Related

How do I delete nested JSONModel row from a SAPUI5 table using dialog box?

I have a SplitApp application that consists of categories and items under each category whose json structure resembles the one below:
{
"stations":[{
station_id: "1",
station_name:"Nairobi",
items: [
{
station_id: "1",
item_id: 1,
item_name: Nairobi item A
},
{
station_id: "1",
item_id: 2,
item_name: Nairobi item B
}
,
{
station_id: "1",
item_id: 3,
item_name: Nairobi item C
}
]
},
{
station_id: "2",
station_name:"Berlin"
}]
On the master page are the stations and the detail page consists of the items displayed as a table. The ColumnListItem is active and hence it opens a dialog box where am performing other actions, one of which includes an update to MySQL database which necessitates the need for the clicked row to disappear.
The dialog box is correctly displayed with the table bindings.
I want to upon clicking a button in the dialog box to update the database, the row is deleted from the json model. My model is nested and most of the examples such as this,this,this,this appear to show deleting a row where json is non-nested.
Here is my code which deletes a whole nested structure instead of a single path of a whole nested structure. E.g.if I want to delete station_id 1-item_id 3, the whole of station_id 1 together with all the items under it is deleted.
var that = this;
var stationModel= that.getView().getModel("station")
var oModel = stationModel.getData();
var oTable = this.getView().byId("oList");
var oSelectedItemPath = oDialog.getBindingContext("station").getObject();
//the oDialog was bound through the following when a table row is clicked
//var path = evt.getSource().getBindingContext("station").getPath();
//oDialog.bindElement("station>"+path);
var index = $.map(oModel.stations, function(obj, index) {
if (obj === oSelectedItemPath) {
return index;
}
});
oModel.stations.splice(index, 1);
that.getView().getModel("station").setData(oModel);
How can I tweak the code so that I only delete the selected path only through the dialog box. Example if I delete item 3 station 1, only that item should be deleted.
No deletion is happening in the database.

Rendering HTML in PySimpleGUI?

Does anyone know if it's possible to have PySimpleGUI render HTML?
I am not after a full-blown browser, just an HTML viewer that lives in a PySimpleGUI window.
I know tkinter has a module called tk_html_widgets, I'm also investigating what webview module can do.
I know it is possible with Qt as PySide comes with a widget of this nature, though I'm really enjoying PySimpleGUI.
I was just wondering if anyone has a suggestion to achieve this.
For example, could I somehow import a TK widget such as tk_html_widgets into PySimpleGUI.
Maybe I'm missing something and pysimpleGUI already has an HTML element that I am unaware of.
Here, just for reference, library tkhtmlview used for HTML parser and builder.
You can call set_html(advertise, html) to update new advertise/html when timeout event, it may hold there when loading something from internet.
from tkhtmlview import html_parser
import PySimpleGUI as sg
def set_html(widget, html, strip=True):
prev_state = widget.cget('state')
widget.config(state=sg.tk.NORMAL)
widget.delete('1.0', sg.tk.END)
widget.tag_delete(widget.tag_names)
html_parser.w_set_html(widget, html, strip=strip)
widget.config(state=prev_state)
html = """
<td colspan="2" class="infobox-image"><a href="https://en.wikipedia.org/wiki/RoboCop" class="image">
<img alt="RoboCop (1987) theatrical poster.jpg" src="https://upload.wikimedia.org/wikipedia/en/thumb/1/16/RoboCop_%281987%29_theatrical_poster.jpg/220px-RoboCop_%281987%29_theatrical_poster.jpg" decoding="async" width="250" height="386" class="thumbborder" srcset="//upload.wikimedia.org/wikipedia/en/1/16/RoboCop_%281987%29_theatrical_poster.jpg 1.5x" data-file-width="248" data-file-height="374"></a>
<div class="infobox-caption" style="text-align:center">Directed by Paul Verhoeven<br>Release date July 17, 1987</div></td>
"""
font = ("Courier New", 12, 'bold')
sg.theme("DarkBlue3")
sg.set_options(font=font)
layout_advertise = [
[sg.Multiline(
size=(25, 10),
border_width=2,
text_color='white',
background_color='green',
disabled=True,
no_scrollbar=True,
expand_x=True,
expand_y=True,
key='Advertise')],
]
keypad = [
["Rad/Deg", "x!", "(", ")", "%", "AC"],
["Inv", "sin", "ln", "7", "8", "9", "÷" ],
["Pi", "cos", "log", "4", "5", "6", "x" ],
["e", "tan", "√", "1", "2", "3", "-" ],
["Ans", "EXP", "POW", "0", ".", "=", "+" ],
]
layout_calculator = [
[sg.Button(
key,
size=(7, 4),
expand_x=key=="Rad/Deg",
button_color=('white', '#405373') if key in "1234567890" else sg.theme_button_color(),
) for key in line]
for line in keypad]
layout = [
[sg.Frame("Calculator", layout_calculator, expand_x=True, expand_y=True),
sg.Frame("Advertise", layout_advertise, expand_x=True, expand_y=True)],
]
window = sg.Window('Title', layout, finalize=True, use_default_focus=False)
for element in window.key_dict.values():
element.block_focus()
advertise = window['Advertise'].Widget
html_parser = html_parser.HTMLTextParser()
set_html(advertise, html)
width, height = advertise.winfo_width(), advertise.winfo_height()
while True:
event, values = window.read()
if event in (sg.WINDOW_CLOSED, 'Exit'):
break
print(event, values)
window.close()
It looks like you can do this with tkhtmlview widgets. I think the key is to get a handle to the tk root node using the TKroot attribute of the PySimpleGUI Window. You should be able to draw most tk widgets using that handle. Here's a simple example that draws an HTML label in a PySimpleGUI window:
import PySimpleGUI as sg
from tkhtmlview import HTMLLabel
layout = [[]]
window = sg.Window('Canvas test', layout, finalize=True)
my_label = HTMLLabel(window.TKroot, html='<h1>foobar</h1>')
my_label.pack()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break

Is nesting tables with bootstrap Vue a good way to achieve this?

I had to solve a specific problem that I'm going to explain using an image to better understand the question.
Basically the result that I wanted to obtain is this:
The white rows are the main items and the gray ones are subitems of the main. To achieve this with Bootstrap Vue tables I pass to the main table (the one contained in every accordion tab) the array with all the main items, and every main item has his subItems set contained in an array. Now to render the grey rows for every white row I used the row details slot in which I put another b-table that receives as items the subItems of the main row.
This solution looks fine but it comes with some important problems:
first of all I had to reset the row-details padding in order to align the outer table with the inner table, but it still has some differences in width (if you look close between the TDs there are some differences)
as second point, the most important one, every row has to be selectable only one per time, in order to modify the infos contained inside. At the moment I set the outer table selectable with only one row per time, and same for the inner tables, but since these are more than one it creates conflicts every time I select rows on different subitems or if I select a main item together with one or more subitems.
Now my question is:
before I proceed finding a solution maintaining the actual structure that I built, I was wondering if there is a better way to achieve this without nesting tables and at the same time maintaining the actual look of the entire table.
If this can help, I post the piece of code related to the result seen in the above image:
// OUTER TABLE
<b-table
:items="dataTable.itemsOnDesktop"
:fields="billOfMaterialsType == '2' ? dataTable.fields : dataTable.fieldsA1"
:selectable="isSelectable"
#row-selected="onRowSelected"
ref="selectableTable"
outlined
sticky-header="700px"
head-variant="light"
select-mode="single"
stacked="md"
selected-variant="danger"
details-td-class="row-details-styling"
id="outer-project-table"
bordered
fixed
:busy="tableBusy"
>
.
.
.
<template
v-if="billOfMaterialsType == '2'"
#row-details="row"
>
// INNER TABLE
<b-table
id="inner-project-table"
hover
table-variant="secondaryLight"
selected-variant="danger"
select-mode="single"
#row-selected="onRowSelected"
:selectable="isSelectable"
thead-class="hidden_header"
:fields="dataTable.fields"
:items="row.item.node.bomiteminfoSet.edges"
:ref="`innerTable-${row.item.node.id}`"
bordered
small
fixed
>
.
.
.
</b-table>
</template>
</b-table>
And here it is a short example of the dataTable.itemsOnDesktop json structure:
[{
"node": {
"id": "Qk9NSXRllE2vZGU6MjA2MzU=",
"code": "1.4.7.2.a",
"description": " INTONACO COMPLETO AL CIVILE PREMISCELATO A PROIEZIONE ...",
"quantity": "1290.00",
"unitOfMeasurement": "m2",
"bomiteminfoSet": {
"edges": [{
"node": {
"id": "Qk9YinRlbUalk87230mGlOjExOTkx",
"code": null,
"description": "PORZIONE BURLOTTI\npiano interrato, piano terra",
"parts": "955.00",
"length": null,
"width": null,
"heightOrWeight": null,
"unitOfMeasurement": null,
"quantity": "955.00"
}
},
{
"node": {
"id": "Qk9ld5RlSXRlbUaOb2RlOjExOTky",
"code": null,
"description": "PORZIONE LAZZARINI\npiano terra",
"parts": "335.00",
"length": null,
"width": null,
"heightOrWeight": null,
"unitOfMeasurement": null,
"quantity": "335.00"
}
}]
}
},
"isActive": true,
"_showDetails": true
}]
Let me know your ideas about this, I would really appreciate it.

Query on feature layer and draw a point on feature with matching OBJECTID

I have a JSON file with data as:
[{
"data": [{
"assetID": 1,
"colorCode": 3
}, {
"assetID": 2,
"colorCode": 1
}, {
"assetID": 3,
"colorCode": 4
}, {
"assetID": 4,
"colorCode": 2
}, {
"assetID": 5,
"colorCode": 3
}, {
.
.
.
"assetID": 1000,
"colorCode": 2
}]
}]
where,
assetID is unique (upto 1000)...
colorCode is a random number between 1 to 4... and each colorCode corresponds to any unique color.Like,
colorCode 1, color Green...
colorCode 2, color Orange...
colorCode 3, color Yellow...
colorCode 4, color Red...
I have created a simple webmap in ArcGIS online with one tile layer and one feature layer. Now, I have to write a code in JS where when the feature's OBJECTID matches the assetID, a point should be drawn there in the color corresponding to the colorCode on the map.
Like, for assetID 1 colorCode is 3, so at feature with OBJECTID 1 on the map, a point should be drawn there in green color and so on.
I have created the JSON file and the webmap, but I am really new to all this ArcGIs and dojo and I am really at a loss where to proceed next.
How are you hosting the application. Is it just a webmap in ArcGIS online or you using WebAppBuilder or you have a custom web application. All these factor determine whether you can customize your map or not.
Also, your layer is it a FeatureLayer or a Map Service. or just graphic data. If it is graphic data its lot easier to make the customization. Let me know more details so that I can provide you with specific answer.
Take a look at this post https://gis.stackexchange.com/questions/50558/customizing-arcgis-online-application-template-and-uploading-it-back-to-arcgis-o
it provides information on how you can customize webmap.
Hope this was helpful.

How to do a match with div with a custom-data of 'x' to a json object with the same value of 'x'?

I am not sure if this is achievable.
I have a list of li that all has a custom attribute with an unique value. I also have a JSON file that has a list of objects. Each object has a specific field that has the same value
Problem: I am trying to match the li attribute 'x' with the value 'x' inside the JSON. If that match is correct I want to grab all the fields inside the same object as 'x' and place it inside the li with attribute 'x'.
Please help, I am not sure how to start this. I will need some sample or even a jsfiddle example.
JSON Structure
[
{
"word": "hello",
"favnumber": "0070",
"item": "item1",
"color": "red"
},
{
"word": "hello world",
"favnumber": "0233070",
"item": "item2",
"color": "blue"
},
{
"word": "hello mom",
"favnumber": "0070",
"item": "item3",
"color": "pink"
},
{
"word": "hello dad",
"favnumber": "0070",
"item": "item4",
"color": "silver"
}
]
HTML Structure
<div>
<li data-item="item1">1</li>
<li data-item="item2">2</li>
<li data-item="item3">3</li>
<li data-item="item4">4</li>
</div>
HTML New Structure
<div>
<li data-item="item1">hello , 0070, item1, red</li>
<li data-item="item2">hello world, 0233070, item2, blue</li>
<li data-item="item3">hello mom, 231213, item3, pink</li>
<li data-item="item4">hello dad, 007021312, item4, silver</li>
</div>
You can split the overall task into simple sub-steps:
Query the DOM tree to extract the elements that have certain attributes (in your case, [data-item=*]).
For each of those elements, get the data-item attribute's value.
Loop through the JSON object, that represents an array, to find the element of this array respective to the DOM element found at the previous step.
Replace the DOM element's child text node to arbitrary value.
Let's walk through it.
Query the DOM tree to find elements with certain attributes
This is achieved with the help of document.querySelectorAll DOM API. The method takes the selector as its first parameter, pretty similar to what you'd write in CSS:
var items = document.querySelectorAll('[data-item]');
Now, inside items variable, you have a NodeList of elements. First step done.
Get the attribute value for every element
This is simple and can be done with something like
var name = items[0].getAttribute('data-item');
Now the name var stores a string that represents the [data-item]'s attribute value.
Since you have an array of NodeList elements, you have to loop through it:
for (var e in items) {
var element = items[e];
var name = element.getAttribute('data-item');
//...
}
Find the element in data array by element's property value
Now you have to put a loop into a loop so you can find an element that concurs with the element.
Like this:
for (var e in items) {
var element = items[e];
var name = element.getAttribute('data-item');
for (var i in data) {
var item = data[i];
// ...
}
}
Here, the item variable stores an object, one of many within the initial JSON array (named data in this particular example).
Next, you have to check if the item is one you need or not. In you case,
if (name == item.item) {
//...
}
because item's property item stores the value that has to concur with the value of [data-item] attribute of the DOM element.
Now, finally...
Replace the value
You may need something more specific to your task, but this example shows a simple element.innerText replacement.
Let's pretend you're within the if statement and its condition evaluated to true. Next, you want to do something like
var text = [];
text.push(item.word);
text.push(item.favnumber);
text.push(item.item);
text.push(item.color);
element.innerText = text.join(", ");
And that's it, basically.
You can see how the whole snippet works in this fiddle: http://jsfiddle.net/3r4rmLth/