How to create close functionality in context menu with Syncfusion ej2 - syncfusion

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

Related

Position the dialog at the center of the screen in Fiori

I have a SAPUI5 Fiori application.
I use theme sap_fiori_3 as the base theme.
I customized this theme and only attached a background image to the theme.
The interesting part is when I activate this customized theme (that only has an extra background image in comparison to original sap_fiori_3 theme), the dialog are not centered in my app anymore.
The dialog are made with sap.m.dialog class.
I wrote a small snippet of code to center the dialog like following:
onAfterDialogOpen: function(oEvent){
var oDialog = oEvent.getSource(),
$Dialog = oDialog.$(),
oPosition = $Dialog.position(),
iTop = oPosition.top,
iLeft = oPosition.left,
iDialogWidth = $Dialog.width(),
iDialogHeight = $Dialog.height(),
iScreenWidth = sap.ui.Device.resize.width,
iScreenHight = sap.ui.Device.resize.height,
iNewTop = Math.floor((iScreenHight-iDialogHeight)/2),
iNewLeft = Math.floor((iScreenWidth-iDialogWidth)/2);
if(Math.abs(iNewLeft-iLeft) > 10 & Math.abs(iNewTop-iTop) > 10){
$Dialog.offset({top: iNewTop, left: iNewLeft});
}
},
But it is not a good solution. Why? Because it makes a motion on my screen like following:
Now the question is, how can I center the dialog without Java Script and by settings or some other tricks that when the dialog is opened, it be already centered.
Please note that using onBeforeOpen event is not possible as I need the size and position of the dialog!
I finally found out what is the source of the problem. It seems the Theme Designer of SAP is buggy and some part of the theme code does not transfer to the exported file.
When I use the theme designer to customize the theme it not only made the mentioned error, but also some other strange behavior appear in the deployed applications in the fiori launchpad which use the customized theme. However, we don't have those errors in the development time in the WEB IDE.
Therefore as I only needed to customize the following items:
background image
logo
favicon
I tried to use the standard theme like sap_fiori_3 and work around for setting these properties.
So for the first 2 issues I used the CSS hack:
div.sapUShellFullHeight {
background-image: url(../images/myBackgroundImage.svg);
background-repeat: no-repeat;
background-size: contain;
background-position: right;
}
a#shell-header-logo > img#shell-header-icon {
content:url(../images/logo.svg);
}
And for the favicon I used the promise solution. Please notice in the fiori launchpad each time that you switch between the applications fiori will reset the favicon, so I used the JavaScript promise to set it.
// Set the favicon dynamically to get read of blinking
function waitForElementAppear(selector) {
return new Promise(function(resolve, reject) {
var element = document.querySelector(selector);
if(element) {
resolve(element);
return;
}
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var nodes = Array.from(mutation.addedNodes);
for(var node of nodes) {
if(node.matches && node.matches(selector)) {
observer.disconnect();
resolve(node);
return;
}
};
});
});
observer.observe(document.documentElement, { childList: true, subtree: true });
});
}
//
function waitForElementRemoved(selector) {
return new Promise((resolve) => {
var element = document.querySelector(selector);
if(!element) {
resolve();
return;
}
var observer = new MutationObserver((mutations, observer) => {
for (const mutation of mutations) {
for (const removedNode of mutation.removedNodes) {
if (removedNode === element) {
observer.disconnect();
resolve();
}
}
}
});
observer.observe(element.parentElement, { childList: true });
});
}
//
function changeFavIcon(selector) {
waitForElementAppear(selector).then(function(element) {
element.setAttribute("href", "icon/favicon.ico");
waitForElementRemoved(selector).then(function() {
changeFavIcon(selector);
});
});
};
changeFavIcon("link[rel='shortcut icon']");
It recursively checks when the favicon is injected then it will set its href and as soon as it is removed, this function will observe the next injection!
As I know somebody may says why not used sapui5 its original solution for setting the favicon, like this:
jQuery.sap.setIcons({
'phone': '/images/cimt-logo.png',
'phone#2': '/images/cimt-logo.png',
'tablet': '/images/cimt-logo.png',
'tablet#2': '/images/cimt-logo.png',
'favicon': '/icon/favicon.ico',
'precomposed': true
});
I must say it was not working in my case!

How to show/hide dialog fields with a checkbox in AEM Touch UI

I am relatively new to AEM and I am trying to hide/show dialog fields on checkbox click. I have tried some ways but failed to achieve this functionality. This is just for my own learning. How can I achieve this?
I have tried adding the js clientlib and adding some classes and target to the checkbox and target fields respectively as suggested in other answers but it didn't seem to work. Please help.
First you need to create a clientLibs and add categories as cq.authoring.dialog.all, see the code below:
(function($, $document) {
$document.on("dialog-ready", function() {
Coral.commons.ready($document, function () {
dispalyOrHideTabs();
$(document).on('change', '#showText', function() {
if($('#showText').attr('checked')){
show('1');
}else{
hide('1');
}
});
$(document).on('change', '#showTable', function() {
if($('#showTable').attr('checked')){
show('2');
}else{
hide('2');
}
});
function hide(index){
var tab = $document.find("[id='compareImgId-"+index+"']").closest(".coral3-Panel");
var tab2 = tab.attr("aria-labelledby");
var tab3 = $document.find("[id='"+tab2+"']");
tab3.addClass("hide");
}
function show(index){
var tab = $document.find("[id='compareImgId-"+index+"']").closest(".coral3-Panel");
var tab2 = tab.attr("aria-labelledby");
var tab3 = $document.find("[id='"+tab2+"']");
tab3.removeClass("hide");
}
function dispalyOrHideTabs(){
var editable = Granite.author.DialogFrame.currentDialog.editable;
if(editable){
var node = Granite.HTTP.eval(Granite.author.DialogFrame.currentDialog.editable.path + ".json");
if(node){
var storedTextValue = node.showText;
var storedTableValue = node.showTable;
if(storedTextValue){
show('1');
}else{
hide('1');
}
if(storedTableValue){
show('2');
}else{
hide('2');
}
}
}
}
});
});
})($, $(document));
Add granite:id property as showText of the checkbox resource type.
And below is the dialog tabs which will be hidden and shown:

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

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?

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');
}
}
});
});

can I build a css class on the fly in tiny mce?

I'm using tiny mce, but I found it adds multiple spans with inline styles to the content for any applied style. Inline styles are not W3c Compliant, so must avoid inline css. Is it possible to create css class on the fly and apply to the selection, while editing content in tiny mce ?
Yes that is possible, but it took me some effort. What needs to be done is to write the class into the head of the editors iframe. Here is some example code which should work for IE,FF, Safari and point you into the right direction:
fonturl = "http://myfonts.com/arial.ttf"
csstext_to_add = '#font-face {font-family: "ownfont";src: url("'+fonturl+'");}'; // example
iframe_id = ed.id;
with(document.getElementById(iframe_id).contentWindow){
var h=document.getElementsByTagName("head");
if (!h.length) {
return;
}
var newStyleSheet=document.createElement("style");
newStyleSheet.type="text/css";
h[0].appendChild(newStyleSheet);
try{
if (typeof newStyleSheet.styleSheet !== "undefined") {
newStyleSheet.styleSheet.cssText = csstext_to_add;
}
else {
newStyleSheet.appendChild(document.createTextNode(csstext_to_add));
newStyleSheet.innerHTML=csstext_to_add;
}
}
catch(e){}
}
It is also possible to add that class as option into a dropdown (what takes some effort).
Thariama's answer was perfect. I'm using the tinyMCE jQuery connector for some of my pages and I have multiple instances of tinyMCE on the page. I made some modifications, but essentially its the same thing. I've created a text area field on the page that people can provide their own CSS. Also, I needed to change some CSS rules on the fly...
// function to change tinyMCE css on the fly
function checkCustomCSS() {
var $css = $('#page_css'),
newcss;
if ($css.val().length > 0) {
// since front end, we are wrapping their HTML in a wrapper and
// the tinyMCE edit iFrame is just using <body>, we need to change
// some rules so they can see the changes
newcss = $css.val().replace('#content_wrapper', 'body');
// loop through each tinyMCE editor and apply the code changes
// You could check the editor.id to make sure that the correct
// editor gets the appropriate changes.
$.each(tinyMCE.editors, function() {
var $this = $(this),
editorID = $this[0].id,
$ifrm = $('#' + editorID+ '_ifr'),
cwin, head, sheet;
if ($ifrm.length > 0 /* && editorID === 'OUR_EDITOR_ID_NAME' */) {
cwin = $ifrm[0].contentWindow;
head = cwin.document.getElementsByTagName("head");
if (!head.length) {
return;
}
sheet = cwin.document.createElement("style");
sheet.type = "text/css";
head[0].appendChild(sheet);
try {
if (typeof sheet.styleSheet !== "undefined") {
sheet.styleSheet.cssText = newcss;
} else {
sheet.appendChild(cwin.document.createTextNode(newcss));
sheet.innerHTML = newcss;
}
} catch (e) {}
}
});
}
}
Then in the tinyMCE init call I added and onInit call to setup changes to the #page_css , like this:
oninit: function() {
$('#page_css').on('change', function() {
checkCustomCSS();
});
}
Works like a charm.