jstree preselect node and open all parents needed - jstree

I use the Jstree 1.0RC3 and do not get it to work to have a node selected and to let the tree open so that this node is visible.
My code is this:
.jstree({
// List of active plugins
"plugins" : [
"themes","json_data","ui","crrm","dnd","search","types","hotkeys","contextmenu"
//"themes","json_data","ui","crrm","cookies","dnd","types","hotkeys"
],
"json_data" : {
"ajax" : {
"url" : $path + "/server.php",
"data" : function (n) {
return {
"operation" : "get_children",
"id" : n.attr ? n.attr("id").replace("node_","") : <?php echo($jstree_root); ?>
};
}
}
},
},
"core" : {
// just open those two nodes up
// as this is an AJAX enabled tree, both will be downloaded from the server
"initially_open" : [ <?php echo($jstree_root_node); ?> ]
The UI-plugin is empty. The php echo($jstree_root_node) opens the first hierarchical level below the root for better overview. Sometimes I would like to pass an ID of a Node that should be selected. This node is not always visible by opening the tree by default. What I see is that the node will be selected if it is visible in the first hierarchical level. If it is deeper, it is not selected.
I found in the forums to use this before the JSTREE call but it is not working:
.bind("reopen.jstree", function () {
$("#demo").jstree("select_node", "#node_1637");
$("#node_1637").parents(".jstree-closed").each(function () {
$("#demo").jstree("open_node", this, false, true);
});
})
Any ideas on this one? It seems to be right in front of my nose, but I dont see it....
gb5256

I think there are 2 ways to handle it.
First option - Using "initially_open" you need to specify all nodes going from root to selected node. The jsTree will go through this sequence, open each one node, load it's content, open next node, load it's content etc.
Some basic idea of the script:
"core" : {
"initially_open" : [ < ?php echo implode(',', $path_to_node) ?> ]
}
Second option - Using "search" plugin you need to create a php script that will be called by ajax request and should return the path to searched node.
So you define search plugin:
'search' : {
'case_insensitive' : true,
'ajax' : {
'url' : 'search_script.php',
'data' : function(n) {
return { search_id : n };
}
}
},
Then you bind the search action after tree is loaded:
$('#tree').bind('loaded.jstree', function(e, data){
$('#tree').jstree('search', <?php echo($jstree_searched_node); ?>);
});
The search_script.php should return the array of node-keys to be opened the same way as in first option.
It's not the complete copy&paste solution, but I hope this will take you to the right way to finish it successfully.

you could use open_all to open all available nodes.
$("#TreeID").jstree('open_all');

Related

Fancybox how to open dynamically with a variable

so right now I'm trying to load a fancybox modal with a javascript string I got back from an Ajax call. What ends up happening is the modal opens up with this code inside rather than converting them to the appropriate images/thumbnails.
[{ src : 'e2121a1caf564e92be14cfb38d094901/9234b96c09_640.jpg', opts : { thumb: 'e2121a1caf564e92be14cfb38d094901/9234b96c09_640.jpg' } }]
It is not clear what version are you using, here is an example for v3:
$.fancybox.open([
{
src : 'https://source.unsplash.com/i-FqQIkJMqg/1536x2304',
thumb : 'https://source.unsplash.com/i-FqQIkJMqg/200x200'
},
{
src : 'https://source.unsplash.com/z55CR_d0ayg/1279x853',
thumb : 'https://source.unsplash.com/z55CR_d0ayg/200x200'
}
]);

SAP UI5 Cross Application Navigation without FLP

I have two apps. The first app has a view. There I push a button and then it should change to the second application. I don't want to navigate to the first view, but to the second with a parameter.
I use this:
oCrossAppNavigator.toExternal({
target : {
semanticObject : "Z_APP2",
action : "onPress"
},
params : {
param1 : param1
}
In APP2 I write this in the Component.js:
var oRouter = this.getRouter().initialize();
var oComponentData = this.getComponentData();
if (oComponentData.startupParameters) {
oRouter.navTo("Detail", {
param1 : oComponentData.startupParameters.param1[0],
}, false);
It doesn't switch to the other app. Which action should I write here ?
Do I have to implement something else in App2?
The answer is:
window.location.replace("-- url with parameters here --")
The right system is : window.location.host
I have a same issue.
SAPUI5 provide sap.m.URLHelper which contains redirect method :
sap.m.URLHelper.redirect(sURL, bNewWindow?)
I think SAPUI5 do the same thing than window.location.replace() but more SAPUI5-friendly.

SAP UI5 issue, render Calling two time in Custom Control

In view
var oData = {
"SavedSearch" : [
{ name : "Save1" },
{ name : "Save2" },
{ name : "Save3" },
{ name : "Save4" },
{ name : "Save5" }
]
}
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(oData);
sap.ui.getCore().setModel(oModel,"ModelData");
var oTest = new test({
manageSavedSearch :{
path : "ModelData>/SavedSearch",
template: new sap.ui.commons.Button({
text : "{ModelData>name}"
})
},
});
oTest.placeAt(this);
In Custom Control
sap.ui.core.Control.extend("test",{
metadata:{
properties : {},
aggregations:{
manageSavedSearch : {type : "sap.ui.commons.Button", multiple :true },
layout : {type : "sap.ui.layout.VerticalLayout", multiple :false }
}
},
init : function(){
},
renderer : {
render : function(oRm, oControl) {
// Come two Times Here
var manageSavedSearch = oControl.getManageSavedSearch();
var oSavedButtonHLyt = new sap.ui.layout.VerticalLayout();
for(var index = 0 ; index < manageSavedSearch.length ; index++){
oSavedButtonHLyt.addContent(manageSavedSearch[index]);
}
oControl.setAggregation("layout",oSavedButtonHLyt);
oRm.renderControl(oControl.getAggregation("layout"));
}
}
},
onAfterRendering: function(){}
});
If I don't use any layout then It doesn't come two time in render otherwise it comes two time in render. This issues is happening from version 1.24.4. please Can I have any guidance here.
Changing aggregation(e.g. add/remove/insert/set/removeAll) invalidates the control. You should never invalidate a control during the rendering. In your case it can be an infinite loop.
To debug rendering invalidation there is a url parameter test.html?sap-ui-xx-debugRendering=true then you can see the rendering stack trace and who is responsible for the rendering.
In your code sample, there are two aggregations update. setAggregation and addContent.
Aggregation mutatators uses 3rd parameter to suppress invalidation. So following will insert the aggregation but suppress the invalidation since whole control will be rendered at the end it will not be a problem.
oControl.setAggregation("layout",oSavedButtonHLyt, true); // suppress invalidate
I guess you assume same should work for addContent
oSavedButtonHLyt.addAggregation("content", manageSavedSearch[index], true);
But it does not because here manageSavedSearch[index], so your template clone's parent is oTest initially, but you are changing the parent with addAggregation because layout will be the parent. But UI5 cannot determine automatically for the previous parent's suppress since its aggregation will be moved to somewhere else. So we go with
oControl.removeAggregation("manageSavedSearch", manageSavedSearch[index], true);
oSavedButtonHLyt.addAggregation("content", manageSavedSearch[index], true);
Here is the jsbin http://jsbin.com/rezayebada/1/edit?js,output
BTW, as you mentioned this is just an example do not take this as a reference for building composite controls.
Basically, property/aggregation/association changes invalidates the control if the control does not overwrite its mutator methods. I see it is not easy to understand what invalidates when but sap-ui-xx-debugRendering=true helps you to understand with stack trace.
This problem I was also facing, you can do one thing try using local resources
rather than online resources.

Get passed data on next page after calling "to" from NavContainer

I am on my way building a Fiori like app using SAPUI5. I have successfully built the Master page, and on item click, I pass the context and navigate to Detail page.
The context path from Master page is something like /SUPPLIER("NAME"). The function in App.controoler.js is as follows:
handleListItemPress: function(evt) {
var context = evt.getSource().getBindingContext();
this.myNavContainer.to("Detail", context);
// ...
},
But I would like to know how I can access this context in the Detail page. I need this because I need to use $expand to build the URL and bind the items to a table.
There is an example in the UI5 Documentation on how to deal with this problem using an EventDelegate for the onBeforeShow function which is called by the framework automatically. I adapted it to your use case:
this.myNavContainer.to("Detail", context); // trigger navigation and hand over a data object
// and where the detail page is implemented:
myDetailPage.addEventDelegate({
onBeforeShow: function(evt) {
var context = evt.data.context;
}
});
The evt.data object contains all data you put in to(<pageId>, <data>). You could log it to the console to see the structure of the evt object.
Please refer the "shopping cart" example in SAP UI5 Demo Kit.
https://sapui5.hana.ondemand.com/sdk/test-resources/sap/m/demokit/cart/index.html?responderOn=true
Generally, in 'Component.js', the routes shall be configured for the different views.
And in the views, the route has to be listened to. Please see below.
In Component.js:
routes: [
{ pattern: "cart",
name: "cart",
view: "Cart",
targetAggregation: "masterPages"
}
]
And in Cart.controller.js, the route has to be listened. In this example, cart is a detail
onInit : function () {
this._router = sap.ui.core.UIComponent.getRouterFor(this);
this._router.attachRoutePatternMatched(this._routePatternMatched, this);
},
_routePatternMatched : function(oEvent) {
if (oEvent.getParameter("name") === "cart") {
//set selection of list back
var oEntryList = this.getView().byId("entryList");
oEntryList.removeSelections();
}
}
Hope this helps.

Jstree : dblclick binding parameter data is undefined

I try to use good lib jstree but i have some strange problem with dblclick binding.
Here is my code
$("#basic_html").jstree({
themes: {
url: "http://mywork/shinframework/shinfw/themes/redmond/css/jstree/default/style.css"
},
"plugins" : ["themes","html_data","ui","crrm","hotkeys", "core"],
});
$("#basic_html").bind("dblclick.jstree", function (e, data) {
alert(e);
alert(data);
});
When this code runs and i make dblclick for some node i can see 2 alerts. The first is object -right, the second is undefined - BUT i want receive data information.
Please, if some specialist solve this problem give me right way for correct use dblclick and receive "data" information about node who is i clicked.
Thanks
I recommend this approach . . .
$("#basic_html li").live("dblclick", function (data) {
//this object is jsTree node that was double clicked
...
});
First, you usually only need to know if the li was clicked so monitoring the event on the li will give you everything you need. Secondly, use live or delegate for the event binding so you can manipulate the tree without breaking the event.
Once you have the node that was double clicked (the this object) you can then use the built-in functions like this . . .
if (!jsAll.is_selected(this)) { return false; } //cancel operation if dbl-clicked node not selected
Where . . .
jsAll = $.jstree._reference("basic_html")
$("#basic_html").bind("dblclick.jstree", function (event) {
var node = $(event.target).closest("li");//that was the node you double click
});
that's the code you want.