Dojo: multiple right-click Menus on a large Tree - menu

I am trying to define multiple right click Menus on a large Tree. ( using dojo 1.8).
I've got 20+ different type of data items in the tree. For each of this data items type there is a specific right-click menu.
I've tried to attach the Menu to the TreeNode with the 'selector' of the Menu as explained in http://dojotoolkit.org/reference-guide/1.9/dijit/Menu.html#attaching-to-multiple-nodes. I've added to each treeNode a class with the name of the type and defined the menu selector accordingly.
One of the 20+ menu:
var personMenu = new dijit.Menu({
targetNodeIds: ["theTree"],
selector: ".type_person",
menutype: 'person'
});
personMenu.addChild(new dijit.MenuItem({
label: "person properties",
onClick: function(){ createDialog('edit');}
}));
The TreeNode creation with the type added as className:
_createTreeNode: function(args){
//Logger.info("_createTreeNode "+args.item.type+";");
args.className = 'type_'+args.item.type;
console.dir(args);
var node = new dijit._TreeNode(args);
My problem is that used in a tree, it does not work properly: the menu for some treeNode of type A sometimes appears on all its children. It seems related to the order of the definition of the Menus. There is a little bit less problems if I define first the menus for the data items used as parent to others. Unfortunately I've got data items that can be parent and/or child of others, those types may appear at all depth in the tree, so changing the order of the menu creation is not enough to solve the problem...
Am I doing sth wrong ? Is there any 'selector' trick to handle this case ? ( as the tree is quite large, I would prefer to avoid using TreeNode id's )
Thanks for any help,

Try this way but remember if you get store is not avaialble please declare your store globally like _store:store. for menuitems this should work try it out, it works for my case
onClick: function (evt){
idCount = idCount +1;
var newItem = {};
newItem.id = idCount;
newItem.main = selectedItemId;
store.newItem(newItem);
sel.setStore(store,'',{query:{main: 0}});
/* mytree.update();*/
},
<ul dojoType="dijit.Menu" id="ba" style="display: none;">
<li dojoType="dijit.MenuItem" onClick="function (evt)">Add a new folder</li></ul>

Related

MDC-Web: Multiple simple menu

I use google MATERIAL COMPONENTS FOR THE WEB and have problems with the "Simple Menu". Check my codepen: [Multiple menus per page?][1]
[1]: https://codepen.io/QJan84/pen/govRmg
The first menu works, the others do not.
What do I have to do to have multiple menus per page?
You’re using document.querySelector for menu and toggle, but it will return only the first node elements matching “.mdc-simple-menu” and “.js--toggle-dropdown” respectively.
Instead, you should use document.querySelectorAll that will return the NodeList, which you’ll need to convert to array to iterate with its elements.
I wrapped your example menus and toggles into containers for selecting toggles easier with Node.parentElement.
So, the final result might look like this:
const menuEls = Array.from(document.querySelectorAll('.mdc-simple-menu'));
menuEls.forEach((menuEl) => {
// Initialize MDCSimpleMenu on each ".mdc-simple-menu"
const menu = new mdc.menu.MDCSimpleMenu(menuEl);
// We wrapped menu and toggle into containers for easier selecting the toggles
const dropdownToggle = menuEl.parentElement.querySelector('.js--dropdown-toggle');
dropdownToggle.addEventListener('click', () => {
menu.open = !menu.open;
});
});
You can view the demo on Codepen.

How to add an absolute element in a NativeScript page

I want to be able to just place a View component (plugin) into the page through code and have it appear at some X\Y on the page... but I'm a bit stumped.
Any attempt to add via page.content kinda adds it to the layout\render pass so it occupies space.
So this would get injected into "any" page at "any" time, I have no control over the markup this would be used in (know what I mean?) There is no XML for it and unfortunately the answer can't just be wrap everything in an AbsoluteLayout because one can't mandate that on users apps\layouts.
Thoughts, even possible?
Basically the simplest way to do this is to dynamically and be fully cross platform compatible is to create a AbsoluteLayout item in your JavaScript code, and dynamically insert your item and the AL into the page container.
Code would be something like this:
var AbsoluteLayout = require('ui/layouts/absolute-layout').AbsoluteLayout;
var myAL = new AbsoluteLayout();
var myItem = new myPluginItem();
// Set you left, right, top, bottom coords.
myItem.top = x;
// Add our item to the AbsoluteItem
myAL.addChild(myItem);
var frame = require('ui/frame');
var page = frame.topmost().currentPage;
var LayoutBase = require('ui/layouts/layout-base').LayoutBase;
page._eachChildView(function(view) {
if (view instanceof LayoutBase) {
view.addChild(myAL);
return false;
}
return true;
});
However, if you don't want to do this the really simple way; the only other way is to actually go a bit lower level. You can natively access the iOS view controller (page._ios.view) and the android view (page._nativeView), and then manually add it to the view by using things like addView (https://developer.android.com/reference/android/view/ViewManager.html) or addSubview (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/).
I would like to add you can set the Top and Left properties in TypeScript by importing AbsoluteLayout like so
import {AbsoluteLayout} from 'ui/layouts/absolute-layout';
and then using the exposed functions setLeft or setTop
AbsoluteLayout.setLeft(YourItem, LeftValue);
or
AbsoluteLayout.setTop(YourItem, TopValue);

How to add button + to subgrid of hierarchical relation?

I have a hierarchical relation inside an entity X, I Have parent lookup which allow to give parent to a record of this entity, and I have created a Subgrid attached to this lookup within the same form of the entity:
The problem is that the display of the button + is unstable in this subgrid, sometimes it appears sometimes no. I dont know if this problem is related to some setting or it is a bug of dynamics crm online last version?
For information, I don't have this problem with other sub-grids.
Thanks in advance,
if you want to add a custom button you may do this as follows
function CreateButton() {
var connectionSubGridPlusBtn = document.getElementById("Connections_addImageButton").parentNode.parentNode;
//Connections_addImageButton is the id of + button
if (connectionSubGridPlusBtn != null) {
//New Button
var div = document.createElement("div");
div.className = "ms-crm-contextButton";
div.innerHTML = "<button id='newButton' type='button' style='width:80px;cursor: pointer;padding:0px' >New Button</button>";
connectionSubGridPlusBtn.appendChild(addVendorDiv);
//Event and url for new
document.getElementById("newButton").onclick = function () {
//Write codefor the button click event
}
}
}
call this function on load of the form
The entity has to be created before you're able to add related entities. You can add disable all required fields, and perform a save in the onload, and you should always see the plus sign.
A slightly better solution is to override the create button for the entity, and rather than directing to the create form, perform a rest entity creation, then direct to that form. Then you don't have to perform a save in the on load.

How to create layout elements in Orchard 1.9

Can someone please guide me on how to create layout elements in Orchard 1.9. I couldn't find any resource online.
In general, creating a new layout element is similar to creating a new part. There is a driver and a few views involved in the process. To the point - you need to implement as follows:
An element class.. Class that inherits from Element, which contains all the element data. A model, so to speak.
A driver. Class that inherits from ElementDriver<TElement>, where TElement is the type you created above. Each element has it's own driver that handles displaying admin editor (and the postback) and frontend display views.
Shapes. All shapes should be placed under /Views/Elements/ folder, by convention.
Display shape. Named after your element, ie. MyElement.cshtml. This one renders your element on frontend.
Design display shape.. Named after your element, with .Design suffix, ie. MyElement.Design.cshtml. This one renders your element inside the layout editor.
Editor shape.. This one should be put in /Views/EditorTemplates/ folder instead. Default naming convention is Elements.MyElement.cshtml. It renders the editor shown when you drop a new element on layout editor canvas.
With all above done, your new element should appear in the list of elements on the right side of the layout editor, ready to use.
If you want to do some more complex elements, please check the existing implementations. Layouts module has a very decent architecture so you should get up to speed pretty quickly. Just keep in mind the necessary steps I wrote above.
To create a custom layout element first create a class that inherits from Element. Element is found in the Orchard.Layouts namespace so you need to add a reference. To follow Orchard standards put this file in a folder called Elements.
public class MyElement : Element
{
public override string Category
{
get { return "Content"; }
}
public string MyCustomProperty
{
get { return this.Retrieve(x => x.MyCustomProperty); }
set { this.Store(x => x.MyCustomProperty, value); }
}
}
Next, create a driver class in a folder called Drivers. This class inherits from ElementDriver<TElement> and likely you will want to override the OnBuildEditor and OnDisplaying methods. OnBuildEditor is used for handling creating our editors shape and updating our database when the editor is saved. OnDisplaying is used when we need to do things when displaying our element. Oftentimes, you will want to add properties to the shape which can be done with context.ElementShape.MyAdditionalProperty = "My Value";
public class MyElementDriver : ElementDriver<MyElement>
{
protected override EditorResult OnBuildEditor(MyElement element, ElementEditorContext context)
{
var viewModel = new MyElementEditorViewModel
{
MyCustomProperty = element.MyCustomProperty
};
var editor = context.ShapeFactory.EditorTemplate(TemplateName: "Elements.MyElement", Model: viewModel);
if (context.Updater != null)
{
context.Updater.TryUpdateModel(viewModel, context.Prefix, null, null);
element.MyCustomProperty = viewModel.MyCustomProperty;
}
return Editor(context, editor);
}
protected override void OnDisplaying(Reddit element, ElementDisplayContext context)
{
context.ElementShape.MyAdditionalProperty = "My Value";
}
}
We then just need our views. Our editor view goes into Views/EditorTemplates. The file name needs to be what we set the template name of the editor shape. In our case the view name will be Elements.MyElement.cshtml.
#model MyNameSpace.ViewModels.MyElementEditorViewModel
<fieldset>
<div>
#Html.LabelFor(m => m.MyCustomProperty, T("My Custom Property"))
#Html.TextBoxFor(m => m.MyCustomProperty, new { #class = "text medium" })
</div>
</fieldset>
Finally, we just need a view for our frontend. This view goes into the following folder Views/Elements. The name of the view file is the same as our element class name. For this example the file would be called MyElement.cshtml.
#using MyNameSpace.Elements
#using MyNameSpace.Models
#{
var element = (MyElement)Model.Element;
}
<h1>#element.MyCustomProperty</h1>
You will then have a new element that you can drag into your layout with the layout editor.
For more details on creating an element from start to finish check out my blog post on creating a Reddit element.

How can you control visibility of datasource in Cesiumjs?

I want to display multiple datasources in a cesiumjs viewer but need to allow the user to select which ones they want to see at any given time. For example, if I load a kml and a czml file, how do I hide one and show the other? I can't find the cesiumjs way to do this with its API.
Update Feb 2016: A show flag has been proposed and may be added to a future version of Cesium.
Original answer:
Currently there is no show flag on the dataSource, however it is easy to add and remove the dataSource from the list of available dataSources, and this is used to get the show/hide functionality.
Here's a working demo: Load the Cesium Sandcastle Hello World example, and paste the following code into the left side, then hit Run (F8). It should display a checkbox in the upper-left with show/hide functionality.
var viewer = new Cesium.Viewer('cesiumContainer');
// Create a typical CzmlDataSource.
var dataSource1 = new Cesium.CzmlDataSource();
dataSource1.load('../../SampleData/simple.czml');
// Add a checkbox at the top.
document.getElementById('toolbar').innerHTML =
'<label><input type="checkbox" id="showCheckbox" /> Show CZML</label>';
var checkbox = document.getElementById('showCheckbox');
checkbox.addEventListener('change', function() {
// Checkbox state changed.
if (checkbox.checked) {
// Show if not shown.
if (!viewer.dataSources.contains(dataSource1)) {
viewer.dataSources.add(dataSource1);
}
} else {
// Hide if currently shown.
if (viewer.dataSources.contains(dataSource1)) {
viewer.dataSources.remove(dataSource1);
}
}
}, false);
This code could be improved, for example it could be a "lazy load" where the dataSource.load does not get called until the first time it's shown. Also if a dataSource has been hidden a while, you have to consider at what point should you be saving memory by destroying the dataSource rather than continuing to hold onto it (triggering a new lazy load if it is later shown again).
as of now, show is a property of the data source, you can control it by accessing the property in dot or bracket notation:
https://cesiumjs.org/Cesium/Build/Documentation/CzmlDataSource.html#show
const src = new Cesium.CzmlDataSource();
src.show = false;

Resources