How can I verify that a clicked element is a GoJS picture part and not an overlaid element? - onclick

I'm trying to implement a mask over my GoJS diagram when a details sidepanel is shown. This requires stopping propagation of click events to diagram parts beneath. How can I verify that the event target is the picture part and not the mask element which overlays it?
I've tried using the pointer-events CSS property, but that doesn't do the job.
Simplified markup:
<div id="diagramWrapper"></div>
<div id="sidebar-mask"></div>
Script snippet:
buildGo(go.Picture, {
source: 'images/icons/simplify-icon.png',
...,
click: function (e, node) {
if (e.diagram === node.part) { <-- this, right here, isn't right
let nodesToRemove = getLinkedNodes(e, node.part.data.key);
removeNodes(nodesToRemove);
}
}
})
I haven't gotten my head around the two-letter object properties that GoJS uses, which prevents me from easily finding the right property. Any insight into that would help greatly.

I suggest that you just set Diagram.isEnabled to false when you show a modal dialog. Be sure to set it back to true when the modal UI goes away for any reason. More possibilites are listed at https://gojs.net/latest/intro/permissions.html.
As documented at https://gojs.net/latest/intro/index.html#DevelopingYourDiagram, you should only be using documented API names in your code -- not the minified two character names which will change with each build.

Related

Azure maps drawing module breaks hover style

Using the samples, I have the simple case of setting the cursor to pointer when the user hovers over a pin on the map; something akin to:
this.map.events.add('mouseover', layer, () => this.map.getCanvasContainer().style.cursor = 'pointer');
And a similar mouseout event for putting it back to grab. This works, no problems.
However, when I load the drawing module, this no longer works. If I inspect the elements, I can see the style is still switching between pointer and grab as I hover in the DOM, but it has no effect on the pointer at all any more...
Drawing module is loaded with something similar to:
this.drawingManager = new azDrawing.drawing.DrawingManager(this.map, {...});
The drawing stuff itself works fine. Though, actually, 'fine' is an operative word, because whist I'm drawing a polygon, the line rendering between the point and the cursor doesn't actually render properly. It doesn't update and render until I stop moving the mouse.
The samples have it nice and smooth and clearly rendering and following the mouse as it moves, but my implementation doesn't render that line until I stop moving the mouse.
I programmatically enter drawing mode with the simple:
this.drawingManager.setOptions({
mode: azDrawing.drawing.DrawingMode.drawPolygon
});
Omitted from the above module loading are just the options for enabling dragging and rotation that I have turned on.
It's a fairly simple setup, but there seem to be side effects and I don't really know where to look for what might be causing them to fix them.
Oh, additional version information...
This is using an Angular (12) SPA, and the following map imports in my index:
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.css" type="text/css" />
<script type="text/javascript" src="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-drawing.min.js" async defer></script>
Any ideas on where I can look and/or more information required?
Thanks.
I went through and managed to reproduce your issue with the mouse cursor. Digging into this I eventually found the issue. The drawing manager sets the cursor on the map canvas element, while in most samples and your code, the cursor is set on the map container for the canvas (DIV element that the canvas is inside of). As such, the drawing manager sets the cursor to it's default state on the canvas when loaded, and that cursor takes priority over the parent map container. The solution if fairly simple, use map.getCanvas() instead of map.getCanvasContainer(). So the following should work:
this.map.events.add('mouseover', layer, () => this.map.getCanvas().style.cursor = 'pointer');
However, I did find that this ends up overriding the drawing managers behavior. With this in mind a solution is to check to see if the drawing manager is actively being used to draw. If it is, then don't set the cursor. Here is a sample that demonstrates this.
//Create an instance of the drawing manager and display the drawing toolbar.
drawingManager = new atlas.drawing.DrawingManager(map, {
toolbar: new atlas.control.DrawingToolbar({ position: 'top-right' })
});
//Load some source data.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);
datasource.importDataFromUrl('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson');
//Create a layer.
layer = new atlas.layer.SymbolLayer(datasource);
map.layers.add(layer);
//Add mouse events to power hover experience.
map.events.add('mouseover', layer, () => {
if(drawingManager.getOptions().mode === 'idle'){
map.getCanvas().style.cursor = 'pointer';
}
});
map.events.add('mouseout', layer, () => {
if(drawingManager.getOptions().mode === 'idle'){
map.getCanvas().style.cursor = 'grab';
}
});

what is the proper way to interact with inner components within the shadowDom using lit-element?

I am trying to use paper-dialog within my custom component.
I want to be able to open the dialog from outside the component. What is the best way to do this? (all the examples work directly on the component)
Also the dialog requires me to call "open()" on it to open it.
In the examples I found I found:
this.$.dialog.open();
But this doesn't seem to work with lit-element
I got it to work using shadowRoot, not sure this is the best option:
render() {
return html`
<style>
</style>
<paper-dialog id="dialog">
<h2>Content</h2>
</paper-dialog>
`;
}
firstUpdated(changedProperties) {
console.log("firstUpdated called")
if (this.shown == "true")
{
// this.$.dialog.open();
this.shadowRoot.getElementById("dialog").open()
}
}
I added a property to my element called "shown"
static get properties() {
return {
shown: Boolean,
Thinking I could pass this from the outside into my component, but it doesnt seem to do the trick either (I can set it once with the custom element propery, but changes to it from the out side dont seem to work.
Generally, if you are aggregating a dialog within an element that has other UI elements then you shouldn't be showing/hiding the dialog from outside the element - the event that triggers the dialog should be raised and handled with the containing element.
That said, if it's absolutely necessary, then I prefer a "showDialog" method (not a property). Closing the dialog should be triggered by a dialog button or loss of focus, so you don't need to expose a close method.

Custom CSS Class for dijit/layout/ContentPane

I want to add a custom CSS Class to a dijit/layout/ContentPane so I'm able to style it myself.
This is cause I got more than one tab in my TabContainer where my ContentPanes are located and I don't want to double the borders. Using a border all around the Tab will double the border so I removed the left border of the tabs. In the first tab in the TabContainer I need the left border, too.
To get this I tried to assume the first ContentPane a custom CSS class which will do it.
As you see me writing here, I didn't find a way to do this.
I tried it within the data-dojo-props with
<div data-dojo-type="dijit/layout/ContentPane" title="FunnyTitle" data-dojo-props="class:'firstTab'">
So this didn't work. I tried to add it like I do it in a simple HTML element with class="firstTab"
<div data-dojo-type="dijit/layout/ContentPane" title="FunnyTitle" class="firstTab">
Both ways didn't add my class to the ContentPane.
So how is it done?
The class property is actually not used for that kind of purpose, but it used for identifying of which type the widget is.
However, the class attribute should work, because declarative widgets usually keep their parent attributes. If I have the following HTML:
It eventually gets rendered into:
<div class="dijitContentPane test" data-dojo-type="dijit/layout/ContentPane" id="myContent" widgetid="myContent">
Hello
</div>
However, please note that when using a dijit/layout/ContentPane inside a dijit/layout/TabContainer a lot of additional CSS is added, possibily overriding your own CSS.
For example, for overriding the background color of a tab inside a dijit/layout/TabContainer, I had to use the following CSS selector:
.dijitTabContainerTop-dijitContentPane.test2 {
background-color: #D4D4D1;
}
Demo: http://jsfiddle.net/Lcog9saj/
But also, be aware that the borders generated by the TabContainer are not applied to the ContentPane itself, but to an element with classname .dijitTabContainerTop-container (part of the TabContainer itself).
If this really doesn't work, then you can always access the domNode property of the widget you're trying to alter, for example:
require(["dijit/registry", "dojo/ready", "dojo/dom-class"], function(registry, ready, domClass) {
ready(function() {
domClass.add(registry
.byId("myContentPane")
.get("domNode"), "test2");
});
});
It's that simple that I didn't get it.
All you need to do is adding an ID to the ContentPane.
Dojo generates a widgetID with it like "dijit_layout_TabContainer_0_tablist_myID"
If the TabContainer itself has an ID, it could be different. Just have a look at the generated code.
Now you're able to get it with dijit.byId.
At the end it looks something like:
var tab = dijit.byId("dijit_layout_TabContainer_0_tablist_myID");
domClass.add(tab.domNode,"myClassName");
domClass is a part of dojo. For using it you just need to require it "dojo/dom-class"

How to convert this to onClick vs regular hover?

Here is a Fiddle, to show my current state: (attempting onClick())
http://jsfiddle.net/D5N4f/7/
$('.associationLinks').click(function () {
alert("I've been clicked"); //test to see if click is working
//$(this).next().toggle();
$(this.content).toggle();
//$(this .content').css("display", "block");
});
here is a version of the working HOVER, that I need to convert to onClick:
http://jsfiddle.net/D5N4f/6/
This is working fine.. however.. on HOVER is just not practical for my use.. I need to change it to onClick..but have the same behavior.
Do I need to use jQuery for this? (I havent been able to get it to work)
the content I want displayed starts off as display:none..
I have tried to show(), toggle() and even .css("display", "block"); (maybe Im not targeting things correctly?)
the last part of this (since there will be MANY links set-up like this) is to close the previous 'SHOW' content.. when I click on a new link.. (ie: only having one content box displayed at a time vs. having several open at same time!)
Please use the fiddle example instead of just random code suggestions! Thanks!
I removed the following CSS:
/*.associationLinks:hover .content {
display:block;
}*/
I also use a .children() selector to get the content div to display, and I change it's CSS on a click.
Is this closer to what you want? Hiding the image is a bit tricker, and I have an idea for that but I'm not sure if you need it.

Replicate chrome webstore a element effect

This one is bit tricky ,
I created jsfiddle here
http://jsfiddle.net/WXmcL/10/
to kinda replicate the https://chrome.google.com/webstore/category/home
addons containers. all is fine except that a element link.
I need to position the
<a class="link" href="linktoapp"></a>
correctly but also let the users reach the
Info1
since I cant have any ul or divs inside the a element I am not able to achieve this effect. Yes I can do spans but my ratings contain ul , divs etc and I would have more markup inside it. If you check on chrome store you can always link to the app and in same time reach the rating. They put all the elements inside the a tag but the page validation is not seeing it. So it seems to me that is being done with js on load or ?
Thank you!
you should forget about validation whilst you are building your effects for a while. get it to work with the markup you need, then you can sit back and take away what won't validate and inject it via javascript.
mootools has a wonderful Element constructor.
new Element("a.linktoinfo[html=Info]").inject(element);
you can pass on any property into it via the constructor options object.
eg.
new Element("a", {
"class": "foo",
"href": "#",
"events" : {
click: function() {
showInfo(this.getParent());
}
}
}).inject(element.getElement("a.link", 'after');
etc etc.
btw when you morph classes, just make sure it morphs the properties you differ. in your case, it makes sense to make .myInfoOn / .myInfoOff that have the different heights. there is no point in assigning a morph between other values that have not been changed.
that type of morph parses all the css rules defined in the class that you pass on every event and in reality, you are better off setting it manually. it will scale less if it's hardwired, I realise that - but you can set as a variable into your class.

Resources