How can I make PrimeFaces tabs "linkable"? - jsf

I would like to be able to link to individual tabs in a PrimeFaces' "tabView". In other words, if my page "test.jsf" has a tabView with a tab entitled "Example", I want to be able to click a link to "Test.jsf#Example" and have the "Example" tab loaded automatically. How can I do this?

This can be done with a wee bit of JavaScript (using jQuery). I hope I have commented the following code well-enough that it can be understood.
<script type="text/javascript">
// What this does: when the page is loaded with a URL fragment (i.e, the #abc in example.com/index.html#abc),
// load the tab (by "clicking" on the link) that has the same text value as the fragment.
// Example: if you go to test.jsf#Example, the tab called "Example" will be clicked and loaded.
// This allows individual tabs to be linked to, and puts what tab you were on in the history.
navigateToTab = function () {
if (window.location.hash) {
jQuery('ul.ui-tabs-nav li a').each(function (i, el) {
if (jQuery(el).text() === window.location.hash.replace('#', '')) {
jQuery(el).click();
return;
}
})
}
};
jQuery().ready(navigateToTab);
jQuery(window).bind('hashchange', navigateToTab);
// This makes it so that if you click a tab, it sets the URL fragment to be the tab's title. See above.
// E.g. if you click on the tab called "Example", then it sets the onclick attribute of the tab's "a" tag
// to be "#Example"
setupTabFragmentLinks = function () {
jQuery('ul.ui-tabs-nav li a').each(function (i, el) {
el.onclick = function() {window.location = '#' + jQuery(el).text()};
})
};
jQuery().ready(setupTabFragmentLinks);
</script>
All you have to do is insert that JavaScript in the page that has the tabs. Then you can get a link to a tab with the usual <a href='test.jsf#Example>Click here!</a>. An added bonus is that the tab you were on becomes part of the browser history; i.e., if you navigate away from the page that has the tabs, then press the "back" button, you are brought back to the tab you were on.
Note: if the tabView changes (e.g. you add or remove tabs), you will need to call setupTabFragmentLinks again.

Primefaces provides a javascript API for the <p:tabView/>(and many other components). You can call the select(index) method on the client side widgetVar name of your <p:tabView/>. For example, on a tab view
<p:tabView id="thePanel" widgetVar="tabPanel"/>
From a <p:CommandButton/>, you can call tabPanel.select(1) in the onclick attribute to select the first tab and so forth
<p:commandButton update=":thePanel" value="Do It " id="doIt" onclick="tabPanel.select(1)"/>

Related

Attachment links in Body field in Notes Web UI

I need to modify classical Notes Web UI application. In the UI, it shows mail data. If the data has attachments, they are shown as links in the body field.
I'd like to detect when a user clicks the links, and enable "next" button so that the user can move to the next screen. Is it possbile?
Yes, and this has nothing to do with Domino specifically: put a div around your next button, that initially has the style display: none or give itself an ID and put the display: none directly in the properties box of the button on the html tab, fields ID and style.
Then write a little JavaScript that runs in the onLoad event, selects all a tags with attachments in it (they all have $FILE in the href) and add a function to the click- event to set the style of the button to display: block or something else.
You can prevent the default event (open the attachment) by using preventDefault():
var list = document.getElementsByTagName("a");
for (el of list) {
if (el.href.includes("$FILE")) {
el.addEventListener("click", function(event){
var yourNextDiv = document.getElementById("IDOfDivWithNextButton")
yourNextDiv.style.display = "block"
event.preventDefault()
});
}
}

How to disable next/prev buttons animation in a p:wizard?

I have PrimeFaces wizard with some panels, and next/prev buttons is drawn by wizard widget itself... But there is one problem - when i press next button before the last step, it hides with animation... Is it possible to disable this animation and hide next button instantly?
So, you simply want to remove the fading effects on the wizard next button ?
These effects are done with Primefaces Javascript built-in functions, like:
PrimeFaces.widget.Wizard.prototype.showNextNav = function() {
jQuery(this.nextNav).fadeIn();
}
PrimeFaces.widget.Wizard.prototype.hideNextNav = function() {
jQuery(this.nextNav).fadeOut();
}
However, Primefaces creators have let the possibility of overriding them quite easily.
Just add this in your .xhtml page:
<script>
PrimeFaces.widget.Wizard.prototype.hideNextNav = function() {
jQuery(this.nextNav).hide();
}
PrimeFaces.widget.Wizard.prototype.showNextNav = function() {
jQuery(this.nextNav).show();
}
</script>
Tested and working on PF 5.1.

Scroll to the selected tab if the selected tab is hidden in p:tabview on initial tabview load

Assume that there are many tabs are there in p:tabview and scroll is being shown to navigate to all the tabs.
If the active tab whose contents are shown is the right most tab then it is not visible to the user on initial p:tabview load. If we navigate to the right most using scroll button then we could see the active tab highlighted indicating it is selected tab.
How to scroll to the active tab on load so that user able to see the selected tab always.
This can be done in the following way by overriding initScrolling method in primefaces p:tabview component JavaScript file i.e. tabview.js file.
initScrolling: function() {
if(this.jq.is(':visible')) {
var overflown = (this.lastTab.position().left - this.firstTab.position().left) >
this.navscroller.innerWidth();
if(overflown) {
this.navscroller.css('padding-left', '18px');
this.navcrollerLeft.show();
this.navcrollerRight.show();
activeTab = this.navContainer.children('.ui-tabs-selected');
viewportWidth = this.navscroller.innerWidth();
activeTabPosition = activeTab.position().left + parseInt(activeTab.innerWidth());
if(activeTabPosition > viewportWidth) {
var scrollStep = activeTabPosition - viewportWidth;
scrollStep = Math.ceil(scrollStep/100) * -100;
this.scroll(scrollStep);
} else {
this.restoreScrollState();
}
}
return true;
}
else {
return false;
}
}
I would have wished to override this single method by extending tabview component widget but it is not supported. So we should have our own tabview.js file with the above method modified.
This is done in primefaces 4.0 version, more, or less the changes will be same higher versions also.

Spotify apps tabs - update cache

I'm trying to display a div inside tab playlists if the href contains a spotifyURI. This will be used to display a playlist under a tab.
Step by step this is my problem:
Click playlist tab and then click the "My playlist1".
The href is displayed in the playlist container under the tab playlists. (perfect so far)
Click the start tab and then click the playlists tab.
Instead of displaying the list of playlists the playlist container is show again. So the last used url is cached?
Then if the playlists tab is clicked again the url will be "reseted" and the list of playlists will be shown and playlist container hidden.
I'd like 4. to show the playlist list right away instead.
Is there a way to reset or what am I missing?
<script>
$(document).ready(function() {
sp = getSpotifyApi(1);
var m = sp.require("sp://import/scripts/api/models");
updateTabs();
m.application.observe(m.EVENT.ARGUMENTSCHANGED, updateTabs);
function updateTabs()
{
console.log(m.application.arguments);
var args = m.application.arguments;
$('.section').hide();
if (args[1] == "spotify") $("#playlist").html("args:"+args).show();
else $("#"+args[0]).show();
}
});
</script>
<div id="playlist" class="section">Container for playlist content</div>
<div id="start" class="section">Welcome</div>
<div id="playlists" class="section">
My playlist1
My playlist2
</div>
Thanks alot for all replys!
Here is how I will proceed using JQuery.
First of all you need to use the Localstorage :
var stor = sp.require("sp://import/scripts/storage");
Then if for exemple you get a list of playlist you can build the list like this
for (var i=0; i<d.playlists.length; i++) {
$('#playlists').append('My <a id="p' + i + '"href="'+ d.playlists[i] +'">playlist1</a>');
$('#playlists #p'+i).live('click', function(e) {
e.preventdefault();
stor.set('choosenplaylist', d.playlists[i]);
});
}
This was for the storage now for when changing tad :
if (!stor.get('choosenplaylist')=='') {
location.href=stor.get('choosenplaylist');
}
Okay this is a suggestion and it need to be tested regarding to your app.
Im trying this out now, and i can reproduce your bug (im guessing it's a bug, the tab should replace the url in my opinion)
But, until it's fixed, my best guess is to capture the playlist links in an event handler and cancelling the original event, after cancelling you replace the content with the appropriate playlist view.
Tab test code (on gist.github.com)
I've abstracted the actual view binding from the event handler, and added a click event hook that calls the abstract view binder instead of the "real" one, this also supports deep linking into the an app

Selection type changes context menu using chrome extension

I am trying to build a chrome extension. In it I want the context menu to change according to the selected text on the page.
For example, if its a number I want a menu that says divisibility test for this numbr is ...
and if it is a string, it should have a something else, but not both at the same time.
I cant figure out how to do that.
You will have to set a listener for mouse down. There is no other way to get the selected text before the menu is created.
See this SO question:
chrome extension context menus, how to display a menu item only when there is no selection?
Here is part of the code the rest is at the link.
document.addEventListener("mousedown", function(event){
//right click
if(event.button == 2) {
if(window.getSelection().toString()) {
chrome.extension.sendRequest({cmd: "createSelectionMenu"});
} else {
chrome.extension.sendRequest({cmd: "createRegularMenu"});
}
}
}, true);

Resources