Breadcrumb on click of sap.m.Tree list item and expand collapse the tree on click of the breadcrumb - sapui5

I implemented the sap.m.Tree using below code
<Tree busyIndicatorDelay="0"
id="TreeList" select="onToggleOpenState" mode="SingleSelectMaster"
items="{treeModel>/}">
<StandardTreeItem title="{treeModel>Description}" icon="sap-icon://attachment-e-pub" />
</Tree>
Let's assume user clicks on 3.1.1.3 then I will get below breadcrumb bar
3 / 3.1 / 3.1.1 / 3.1.1.3
I have maintained nodeId as (parent~child~child~child....) to achieve breadcrumb
and below is the code for the same
onToggleOpenState: function(oEvent){
var sPath = oEvent.getParameter("listItem").getBindingContextPath();
var sNodeDesc = this._oView.getModel("treeModel").getProperty(sPath).NodeId;
var aBreadCum = sNodeDesc.split("~");
var oBreadCrumb = this._oView.byId("breadCrumb");
oBreadCrumb.removeAllLinks();
for(var i = 0; i < aBreadCum.length; i++){
if(i === (aBreadCum.length - 1)) {
oBreadCrumb.setCurrentLocationText(aBreadCum[i]);
}
else{
var oCrumbRoot = new sap.m.Link({
text: aBreadCum[i],
press: [this._crumbClick, this]
});
oBreadCrumb.addLink(oCrumbRoot);
}
}
},
_crumbClick: function (oEvent, data) {
},
I don't feel it's an appropriate way to implement the same as someone change the id (NodeId) pattern in the backend, everything will break. so is there any alternative way to do the same?
Further, if the user clicks on "3.1" in above breadcrumb, then tree should be expanded till the level 3.1 and one immediate level (all other branches should be collapsed.) like below image
any idea how to achieve this?

Related

sap.m.table multi checkbox make it READ ONLY - On Condition + SAP UI5

This is my first post to Stack, appreciate the work you guys do, amazing.
I have a sap.m.table sap ui5 and i have 4 records
out of 4, 2 are selected by default, i want to disable the preselected once based on condition.
I have tried below code but its not working, any input please?
View
/results' }" **mode="MultiSelect"**
Controller logic
//--->disable the selected department checkboxes
var tbl = that.getView().byId('idImpactTable');
var header = tbl.$().find('thead');
var selectAllCb = header.find('.sapMCb');
selectAllCb.remove();
tbl.getItems().forEach(function(r) {
var obj = r.getBindingContext("impactModel").getObject();
var oStatus = obj.COMPLETED;
var cb = r.$().find('.sapMCb');
var oCb = sap.ui.getCore().byId(cb.attr('id'));
if (oStatus === "X") {
oCb.setSelected(true);
oCb.setEnabled(false);
} else {
oCb.setEnabled(false);
}
});
Multiselect Mode Table - Make selected check box read only
Last time I tried this I found it easiest to use the updateFinished event on the table, and then use an internal property of the column list item, like so:
onTableUpdateFinished: function (oEvent) {
oEvent.getSource().getItems().forEach(function (item) {
var data = item.getBindingContext().getObject();
item._oMultiSelectControl.setEnabled(!data.IsEnabled); //whatever your check is
});
}
You'll have to find a way to keep them disabled though when using the Select All checkbox at the top of the table. I ended up extending sap.m.Table to accomplish that, there might be easier ways...
My extension is like this
sap.ui.define([
"sap/m/Table"
], function(Control) {
return Control.extend("myapp.controls.MyTable", {
updateSelectAllCheckbox: function(oEvent) {
if (this._selectAllCheckBox && this.getMode() === "MultiSelect") {
var aItems = this.getItems();
var iSelectedItemCount = this.getSelectedItems().length;
var iSelectableItemCount = aItems.filter(function(oItem) {
//standard table does not check if the item is enabled
return oItem.getSelected() || oItem._oMultiSelectControl.getEnabled();
}).length;
// set state of the checkbox by comparing item length and selected item length
this._selectAllCheckBox.setSelected(aItems.length > 0 && iSelectedItemCount === iSelectableItemCount);
}
}
});
});
And just the standard renderer
sap.ui.define([
"sap/m/TableRenderer"
], function(Control) {
return Control.extend("myapp.controls.MyTableRenderer", {
});
});
I suppose I could have extended the ColumnListItem but that was more effort than I wanted to put into the table extension
I have managed to find the solution, please find sample code to achieve.
//--->disable the selected department checkboxes
var tbl = that.getView().byId("idImpactTable");
var header = tbl.$().find("thead");
var selectAllCb = header.find(".sapMCb");
selectAllCb.remove();
var aItems = that.byId("idImpactTable").getItems();
//---> Check individual item property value and select the item
aItems.forEach(function(oItem) {
debugger;
//---> If using OData Model items Binding, get the item object
var mObject = oItem.getBindingContext().getObject();
var sPath = oItem.getBindingContextPath();
var completed = oItem.oBindingContexts.impactModel.getProperty("COMPLETED");
//--->get the id of Multi Checkbox
var cb = oItem.$().find(".sapMCb");
var oCb = sap.ui.getCore().byId(cb.attr("id"));
if (completed === "X") {
oCb.setEditable(false);
oItem.setSelected(true);
oItem.getCells()[4].setEnabled(false);
} else {
oItem.setSelected(false);
}
});
Thank you,
Jacob.Kata
//--->disable the selected department checkboxes
var tbl = that.getView().byId('idImpactTable');
tbl.getItems().forEach(function(r) {
// this makes the trick --->
var oMultiSelCtrl = r.getMultiSelectControl();
oMultiSelCtrl.setDisplayOnly( true );
});

How to create close functionality in context menu with Syncfusion ej2

I would like to create a right click context menu on my tab with close tab functionality using Syncfusion ej2. But I can't find any documentation for this particular functionality.
You can use the "removeTab" public method of tab by passing the respective index to close the tabs. We have prepared the sample based on your requirement.
<div>
<ejs-tab id="appTab" showCloseButton="true">
<e-tab-tabitems>
<e-tab-tabitem header="ViewBag.headerTextOne" content="#contentOne"></e-tab-tabitem>
<e-tab-tabitem header="ViewBag.headerTextTwo" content="#contentTwo"></e-tab-tabitem>
<e-tab-tabitem header="ViewBag.headerTextThree" content="#contentThree"></e-tab-tabitem>
</e-tab-tabitems>
</ejs-tab>
<ejs-contextmenu id="contextmenu" target="#appTab" items="ViewBag.menuItems" select="menuClick"></ejs-contextmenu>
</div>
<script>
function menuClick(args) {
if (args.item.text == "Close All") {
var tab = document.getElementById('appTab').ej2_instances[0];
for (i = $('#appTab .e-toolbar-item').length; i >= 0; i--) {
tab.removeTab(i);
}
} else if (args.item.text == "Close This Tab") {
var tab = document.getElementById('appTab').ej2_instances[0];
var activeTab = tab.selectedItem;
tab.removeTab(activeTab);
}
}
</script>
Sample: https://www.syncfusion.com/downloads/support/directtrac/298062/ze/TabComponent673764834
https://ej2.syncfusion.com/documentation/api/tab/#removetab

setSelectedButton & setSelectedKey for segmented button

hey guys not sure if this is a bug or theres something I'm doing wrong, or the CSS style sheets im using are making this error, but im racking my brain on how to fix this.
I have the following code bellow in a loop, ever since I put it in a loop it no longer works as setting the selected button I had a search and some one said try set selected key, I also tried this and no luck. Now I have put them both in and it sets the selected value to neither button. I'll show you screenshots of what I mean. Any ideas on fixing it would be great.
for(var i = 0; i < results.length; i++) {
//Create buttons dynamically
var segmentItemYes = new sap.m.SegmentedButtonItem({text :"Yes", press: [this.onSEYesPress, this]});
var segmentItemNo = new sap.m.SegmentedButtonItem({text :"No", press: [this.onSENoPress, this]});
var segmentedButton = new sap.m.SegmentedButton({items : [segmentItemYes, segmentItemNo]});
//TODO:Doesn't work currently - How do we set default state?
segmentedButton.setSelectedButton(segmentItemNo);
segmentedButton.setSelectedKey(segmentItemNo);
Below is the Image the top part is what I'm getting (I clicked on no to show you what exactly happens. The bottom one is with the setSelectedKey removed but still set to no. any ideas? This is in a JS controller and it gets placed in to an xml fragment if this makes a difference or not.
I got it to work as follows, by binding the selected key to a model:
var segmentItemYes = new sap.m.SegmentedButtonItem( {
text: "Yes",
key: "foo"
});
var segmentItemNo = new sap.m.SegmentedButtonItem( {
text: "No",
key: "bar"
});
var segmentedButton = new sap.m.SegmentedButton( {
items: [segmentItemYes, segmentItemNo],
selectedKey: {
path: "test>/key"
}
});
var model = new sap.ui.model.json.JSONModel({
key: "bar"
});
sap.ui.getCore().setModel(model, "test");

Customizing fullpage.js to skip section(s) dynamically

The question is simple but i'm not able to make a script by myself for what i need...
I am actually using a script ( fullpage.js ) who toggle some classes into a container ( in my case switching from fp-viewing-1 to fp-viewing-x ) when you scroll down/up between sections.
I need to make a script that listen from this container and toggle a new class into a div ONLY when a class ( in my case fp-viewing-3 ) is added to this container ( from the fullpage.js script of course ).
Any way to make it?
I need to make a script that listen from this container
That's not the way to go for it.
If you want to use the status class, then just create a new class based on the previous ones as explained in this fullpage.js tutorial.
Create a conditional CSS class that will only get applied when its parent class matches your requirement.
Something like this, for example, would only apply the red color to element with myClass when you are in section 1 slide 0.
.fp-viewing-1-0 .myClass{
color: red;
}
Having:
<div id="fullpage">
<div class="section"></div>
<div class="section myClass"></div>
<div class="section"></div>
<div>
If for some other reason (use of plugins etc) you really need to add the class dynamically, then go for fullpage.js callbacks onLeave or afterLoad:
$('#fullpage').fullpage({
onLeave: function(index, nextIndex, direction){
var destination = $('.section').eq(nextIndex - 1);
destination.find('.my-element').addClass('myClass');
}
});
This is the solution to my problem.
Fullpage works as intended except for section 2.
Section 2 will be usable only scrolling down, the script ignore it when scrolling up.
$(document).ready(function() {
$('#application').fullpage({
onLeave: function(index, nextIndex, direction){
var destinationToIgnore = $('.fp-section').hasClass('ignore');
if(destinationToIgnore && direction =='up'){
var destination = nextIndex = 1
$.fn.fullpage.moveTo(destination);
}
},
afterLoad: function(anchorLink, index){
var loadedSection = $(this);
if(index !== 1){
$('.section-intro').removeClass('ignore');
}
if(index == 3){
$('.section-intro').addClass('ignore');
}
}
});
});

Class prefix as selector for each function

I am able to do this using an ID prefix as the selector, but I need to be able to do it with classes instead. It's an each function for opening up different modal windows on the same page. I need to avoid using ID names because I have some modal windows that will have multiple links on the same page, and when using IDs, only the first link will work.
So here's the function as it works with IDs:
$('div[id^=ssfamodal-help-]').each(function() {
var sfx = this.id,
mdl = $(this),
lnk = $('.link-' + sfx),
cls = $('.ssfamodal-close'),
con = $('.ssfamodal-content');
lnk.click(function(){
mdl.show();
});
cls.click(function(){
mdl.hide();
});
mdl.click(function() {
mdl.hide();
});
con.click(function() {
return false;
});
});
and I'm trying to change it to classes instead, like:
$('div[class^=ssfamodal-help-]').each(function() {
var sfx = this.attr('class'),
etc.
But I cannot get it to work without using IDs. Is it possible?
EDIT Fixed error with semi-colon at end of Vars, and updated Fiddle with the fix. Still not working though.
Here's a Fiddle
** UPDATE **
To be clearer, I need to be able to refer to the same modal more than once on the same page. E.g.:
MODAL 1
MODAL 2
MODAL 3
MODAL 4
LINK TO MODAL 1
LINK TO MODAL 2
LINK TO MODAL 3
LINK TO MODAL 4
OTHER STUFF
LINK TO MODAL 1
LINK TO MODAL 4
LINK TO MODAL 3
OTHER STUFF
LINK TO MODAL 2
ETC.
When using classes get rid of the ID habit :
className1, className2, className3 ... etc
simply use
className
HTML:
<div class="ssfamodal-help-base ssfamodal-backdrop">
<div id="help-content" class="ssfamodal-content">
<span class="ssfamodal-close">[x]</span>
Howdy
</div>
</div>
<div class="ssfamodal-help-base ssfamodal-backdrop">
<div id="help-content" class="ssfamodal-content">
<span class="ssfamodal-close">[x]</span>
Howdy Ho
</div>
</div>
<span class="link-ssfamodal-help-base">One</span>
<span class="link-ssfamodal-help-base">Two</span>
LIVE DEMO
var $btn = $('.link-ssfamodal-help-base'),
$mod = $('.ssfamodal-help-base'),
$X = $('.ssfamodal-close');
$btn.click(function(i) {
var i = $('[class^="link-"]').index(this); // all .link-** but get the index of this!
// Why that?! cause if you only do:
// var i = $('.link-ssfamodal-help-base').index();
// you'll get // 2
// cause that element, inside a parent is the 3rd element
// but retargeting it's index using $('className').index(this);
// you'll get the correct index for that class name!
$('.ssfamodal-help-base').eq(i).show() // Show the referenced element by .eq()
.siblings('.ssfamodal-help-base').hide(); // hide all other elements (with same class)
});
$X.click(function(){
$(this).closest('.ssfamodal-help-base').hide();
});
From the DOCS:
http://api.jquery.com/eq/
http://api.jquery.com/index/
http://api.jquery.com/closest/
Here I created a quite basic example on how you can create a jQuery plugin of your own to handle modals: http://jsbin.com/ulUPIje/1/edit
feel free to use and abuse.
The problem is that class attributes can consist of many classes, rather than IDs which only have one value. One solution, which isn't exactly clean, but seems to work is the following.
$('div').filter(function () {
var classes = $(this).attr('class').split(/\s+/);
for (var i = 0; i < classes.length; i++)
if (classes[i].indexOf('ssfamodal-help-') == 0)
return true;
return false;
}).each(function() {
// code
});
jsFiddle
Or, equivalently
$('div').filter(function () {
return $(this).attr('class').split(/\s+/).some(function (e) {
return e.indexOf('ssfamodal-help-') == 0;
});
}).each(function() {
// code
});
jsFiddle
If there is one-to-one relationship between the modal helps and the modal links which it appears there is...can simplfy needing to match class values by using indexing.
For this reason you don't need unique class names, rather they just overcomplicate things. Following assumes classes stay unique however
var $helps=$('div[id^=ssfamodal-help-]');
var $help_links=$('div[id^=link-ssfamodal-help-]');
$help_links.click(function(){
var linkIndex= $help_links.index(this);
$helps.hide().eq( linkIndex ).show();
});
/* not sure if this is what's wanted, but appeared original code had it*/
$helps.click(function(){
$(this).hide()
})
/* close buttons using traverse*/
$('.ssfamodal-close').click(function(){
$(this).closest('div[id^=ssfamodal-help-]' ).hide();
});
Also believe that this code is a little more readable than original apporach
DEMO
Can you try this,
$('div[class^=ssfamodal-help-]').each(function() {
var sfx = $(this).attr('class');
console.log(sfx);
/*console log:
ssfamodal-help-base ssfamodal-backdrop
ssfamodal-help-base2 ssfamodal-backdrop
*/
});
Demo: http://jsfiddle.net/xAssR/51/
why don't you write like
$('div.classname').each(function() {
// you can write your desired code here
var sfx = this.attr('class');
var aa= this.attr('id');
});
or
$('.classname').each(function() {
// you can write your desired code here
var sfx = this.attr('class');
var aa= this.attr('id');
});
where classname is the name of the class used for the div in html
Thanks.