How to display HEIGHT variable FIX header panel using JSF and Primefaces? - html

I use Primefaces 6.2 <p:layout> to display a FIX header (that is always displayed on top of page).
But the header sometimes is to high and I need reduce it DYNAMICALLY.
I decide to replace Header panel with a toggleable panel like this
<p:layout id="PageLayout" fullPage="true">
<p:layoutUnit position="north">
<p:panel id="TitlePanel" toggleable="true" header="Title">
<p:ajax event="toggle" update=":PageLayout"/>
</panel>
... others panels with context, status, date, time, etc ...
</p:layoutUnit>
<p:layoutUnit id="ContentBloc" position="center">
... web page with specific data
</p:layoutUnit>
</p:layout>
This work well except that the position of the ContentBloc is never updated.
When I click on toggle Button, the content of header's panel is hidden but the vertical position of the ContentBloc is never changed !
I used update attribute in <p:ajax> element but this has no effect.
Question: How can I do to UPDATE ContentBloc position ?
Remark: On Chrome, if after having clicked on Toggle button, I load Developer Console, the display is immediately correct !
Remark: if in maximize my Chrome Windows the display is also correct !

After searching a lot, I have found the following tricky solution
<div id="PageHeader" style="position:absolute; left:0; top:0; width:100%;">
<p:panel id="TitlePanel" toggleable="true">
<p:ajax event="toggle" oncomplete="toggleTitlePanel()"/>
<f:facet name="header">
<p:outputLabel value="#{pageTitle}" escape="false" style="font-size:200%;"/>
</f:facet>
... others panels with context, status, date, time, etc ...
</p:panel>
</div>
<div id="ContentPanel" style="position:fixed;
left:0;
overflow-x:auto;
overflow-y:auto;
">
... web page with specific data
</div>
For this code to work, I have
added "toggle" event to position ContentPanel.
added some JQuery event when page is loaded
The javascript code linked to toggle event is the following
function fixHeaderHeight()
{
var iHeight = document.getElementById("PageHeader").offsetHeight;
document.getElementById("ContentPanel").style.top = iHeight + "px";
}
function toggleTitlePanel()
{
setTimeout(function(){ fixHeaderHeight(); }, 500);
}
The fixHeaderHeight() function CANNOT be called direclty because size parameter has not been changed when toggleTitlePanel() is called. So active function is call indirectly using setTimeout() function.
To position correctly ContentPanel the first time it is displayed and when screen size is changed, mimized, maximized, I have already added some javascript code.
<script>
function setContentTopPosition(div)
{
var iHeight = document.getElementById("PageHeader").style.height;
div.style.top = iHeight;
}
function onLoadPage()
{
fixHeaderHeight();
}
function onResizeWindow()
{
fixHeaderHeight();
}
</script>
The JQuery events are initialized just before </body> element in .ready() function.
<script type="text/javascript">
jQuery(document).ready(function()
{
onLoadPage();
jQuery("#PageHeader").resize(function()
{
onResizeWindow();
});
});
jQuery(window).resize(function()
{
onResizeWindow();
});
</script>
Now, Header and Content panels are correctly displayed
when I display this page for the first time
when I change windows size
when I click on MINUS button to collapse Header panel
List item when I click pn PLUS button to expand Header panel
I hope only that this solution will be helpfull for others.

Related

Primefaces: hide tooltip after scrolling on mobile devices

I have following implementation of tooltip in my xhtml
<p:column id="application-column--state" width="8%" style="min-width:auto"
headerText="#{msg['page.employee-applications.table.col.state']}">
<ui:repeat value="#{applicationEntry.statesList}" var="stateEntry">
<h:outputText id="confiurationDocumentForProgramTooltip" escape="false"
styleClass="#{stateEntry.styleClass} -margin-right-5 -inline-flex"/>
<p:tooltip id="confiurationDocumentForProgramTooltipText" escape="false"
for="confiurationDocumentForProgramTooltip" showDelay="0"
value="#{msg[stateEntry.key]}" trackMouse="false"/>
</ui:repeat>
</p:column>
And i have problem with hiding this tooltip on mobile devices during scrolling.
This situation can be observed on tooltip showcase https://www.primefaces.org/showcase/ui/overlay/tooltip/tooltipOptions.xhtml?jfwid=984b1 on mobile view in developers tools on Chrome.
I tried to avoid this situation with js:
$(document).ready(function (){
hideTooltipAfterScroll()
});
function hideTooltipAfterScroll() {
$("#scrollbar_container").add(window).scroll(function () {
$( ".ui-tooltip:visible" ).css({
"z-index" : "",
"display" : "none"
});
})
}
now tooltip is gone after 'touch' scroll, but I cannot reopen closed tooltip.
Do You have any ideas how to achieve closing on scrolling with posibility to reopen closed tooltip?
I would not try to hack the tooltips to be hidden, instead use their JavaScript widget to hide them.
You can hide each tooltip widget on the page like:
PrimeFaces.getWidgetsByType(PrimeFaces.widget.Tooltip).forEach(
function(tooltip){
tooltip.hide();
}
);
See the widget documentation: https://primefaces.github.io/primefaces/jsdocs/classes/src_PrimeFaces.PrimeFaces.widget.Tooltip-1.html

How to make a paper-card scrollable

I'm using polymer's paper-card (I can't use paper-dialog because of this issue). How can I make it scrollable?
For example, in this code I would like to be able to scroll the card when it gets too large for the screen. Right now it just makes some of the content unreachable.
<paper-card>
<h2>[[someMessage]]</h2>
<div id="someReallyLongStuff"></div>
<paper-button raised on-click="doSomethingAndCloseCard">OK got it:)</paper-button>
</paper-card>
I've tried limiting the paper-card's size with max-height but that doesn't help.
EDIT
Here are photos of another example to clarify my problem:
In the first photo I have a small paper-card that fits the screen, but when it gets bigger it doesn't become scrollable, but goes out of page boundaries to make some of the content unreachable
window with small paper-card
window with longer paper-card that is too big for the page
I'm looking for something like paper-dialog-scrollable only for paper-card
!!!Update with code example at the bottom!!!
Paper-dialog
However, I used to work around that backdrop problem, related to the paper-dialog, with this answer that I found somewhere. I used this in a Polymer 1 project so I am not certain if it will still work in version 2. You definitely have to adapt the function.
<paper-dialog with-Backdrop on-iron-overlay-opened="patchOverlay"></paper-dialog>
// Fix with-backdrop for paper-doalog (Polymer1)
// https://github.com/PolymerElements/paper-dialog/issues/7
patchOverlay: function (e) {
if (e.target.withBackdrop) {
e.target.parentNode.insertBefore(e.target.backdropElement, e.target);
}
}
Paper-Card
If you are still looking to work with the paper-card Element and find yourself unable to change the width read further.
I have never tested that code but a presume that you will have to use the Polymer mixin for the paper-card. I don't think max-length is valid CSS better would be to use max-width or max-height.
paper-card {
--paper-card: {
max-width: 500px;
};
}
Update
I have added a code example using the basic paper-card provided by Polymer here
Long story short, I gave the text container a fixed height and added overflow auto to it. This way scroll bars will be added as soon as the text doesn't fit in it's container. This can be improved by adding the overflow only to the y-axes with "overflow-y: auto;"
// Load webcomponents.js polyfill if browser doesn't support native Web Components.
var webComponentsSupported = (
'registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template')
);
if (webComponentsSupported) {
// For native Imports, manually fire WebComponentsReady so user code
// can use the same code path for native and polyfill'd imports.
if (!window.HTMLImports) {
document.dispatchEvent(
new CustomEvent('WebComponentsReady', {bubbles: true})
);
}
} else {
// Load webcomponents.js polyfill
var script = document.createElement('script');
script.async = true;
script.src = 'https://cdn.rawgit.com/StartPolymer/cdn/1.8.1/components/webcomponentsjs/webcomponents-lite.min.js';
document.head.appendChild(script);
}
paper-card {
--paper-card: {
width: 100px;
box-sizing: border-box;
};
}
.card-content {
width: 200px;
height: 100px;
overflow: auto;
}
<!-- <base href="https://gitcdn.xyz/cdn/StartPolymer/cdn/v1.11.0/components/"> -->
<!-- <base href="https://cdn.rawgit.com/StartPolymer/cdn/v1.11.0/components/"> -->
<base href="https://rawcdn.githack.com/StartPolymer/cdn/v1.11.0/components/">
<link rel="import" href="iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="paper-card/paper-card.html">
<style is="custom-style">
</style>
<paper-card heading="Emmental" image="http://placehold.it/200x100/FFC107/000000" alt="Emmental">
<div class="card-content">
Emmentaler or Emmental is a yellow, medium-hard cheese that originated in the area around Emmental, Switzerland. It is one of the cheeses of Switzerland, and is sometimes known as Swiss cheese.
</div>
<div class="card-actions">
<paper-button>Share</paper-button>
<paper-button>Explore!</paper-button>
</div>
</paper-card>
<script>
window.addEventListener('WebComponentsReady', function() {
});
</script>

Maximize gmap in dialog primefaces

I want to display a dialog which has a gmap as element, it works fine when I set height and width, but what I need is show it as maximized full screen map. The Dialog is shown in fullscreen, but map is empty, only when I back to default size it is shown.
My code is
<p:commandLink id="id" value="Modal" onclick="PF('dlg').show(); PF('dlg').toggleMaximize();"/>
<p:dialog appendTo="#(body)" id="dlg" widgetVar="dlg" maximizable="true" width="1920" height="1080">
<p:gmap id="gmap" center="41.381542, 2.122893" zoom="15" type="HYBRID" style="width:100%;height:100%;">
</p:gmap>
</p:dialog>
How can I solve my problem?
You can add following JavaScript on your page
<script>
function resizeElement(elementId,width,height){
console.log("Resizing element " + elementId + " W/H="+ width + "/" + height);
var element = document.getElementById(elementId);
element.style.width=width+"px";
element.style.height=height+"px"
}
function resizePfGmapInsideWrapperElement(wrapperElementId){
var wrapperElement=document.getElementById(wrapperElementId);
var width=wrapperElement.clientWidth-40;
var height=wrapperElement.clientHeight-60;
resizeElement("gmap",width,height);
}
function resizePfGmapInsideDialog(){
resizePfGmapInsideWrapperElement("dlg");
}
</script>
and then add resizePfGmapInsideDialog() into p:commandLink onclick
<p:commandLink id="id"
value="Modal"
onclick="PF('dlg').show(); PF('dlg').toggleMaximize(); resizePfGmapInsideDialog();"/>
Actually whenever you call PF('dlg').toggleMaximize(); also call resizePfGmapInsideDialog() right after and p:gmap will automatically resize inside dialog's content area.

ionic: Can I disable the swipe action in a certain area <div> in <ion-slide>?

Basically, I want to put a inside . However, the ion-slide swipe is so sensitive, so I cannot scroll the content in . It just swipes to the next slide.
Is it possible to disable the swipe action in a certain area in ?
As shown in the picture, I want to disable the swipe action on the B area. I guess (if possible) I need to put some class in ion-scroll and/or div under it, but I could not figure it out.
This is my partial HTML code:
<ion-slide-box on-slide-changed="slideHasChanged($index)">
<ion-slide>
... // A area content
<ion-scroll direction="x" ...>
<div style="width: 5000px; height: 100px" ...>
// B area. Very wide content
</div>
</ion-scroll>
... // C area content
</ion-slide>
</ion-slide-box>
I really appreciate your help.
Here's another approach:
add these to the wide element:
<div on-touch="mouseoverWideDiv()" on-release="mouseleaveWideDiv()">
then in your controller:
$scope.mouseoverWideDiv = function() {
$ionicSlideBoxDelegate.enableSlide(false);
};
$scope.mouseleaveWideDiv = function() {
$ionicSlideBoxDelegate.enableSlide(true);
};
Here is another way of doing this:
In your controller add a function:
$scope.disableSwipe = function() {
$ionicSlideBoxDelegate.enableSlide(false);
};
In your view add the ng-init attribute on the slide-box element
<ion-slide-box ng-init="disableSwipe()">
This will disable the slide-event.
You can now use a controller function to slide to a given index like this:
Since google sent me here when i was searching for solutions using ion-slides (instead of ion-slide-box) i will leave here the solution i ended up using.
One thing first: ion-slide-box is currently deprecated, so you should use ion-slides now.
First set options variable in ion-slides element:
<ion-slides options="options">
Then inside your controller you should configure the options variable with the noSwiping options as follows:
$scope.options = {
noSwiping: true,
noSwipingClass: 'do_not_swipe',
}
And then, in an element inside your ion-slide-page add the "do_not_swipe" class to the element you want swipe to be disabled.
Taking your code as an example, you should have your html like this:
<ion-slides options="options">
<ion-slide-page>
... // A area content
<ion-scroll class='do_not_swipe' direction="x" ...>
<div style="width: 5000px; height: 100px" ...>
// B area. Very wide content
</div>
</ion-scroll>
... // C area content
</ion-slide-page>
</ion-slides>

zoomin/zoomout of an image in html5

i have simple application which should work on keyboard events like onfocus and onblur instead of onmouseover and onmouseout.
here is my code snippet to zoomin/zoomout:
<script>
var nW,nH,oH,oW;
function zoom(iWideSmall,iHighSmall,iWideLarge,iHighLarge,whichImage)
{
oW=whichImage.style.width;oH=whichImage.style.height;
if((oW==iWideLarge)||(oH==iHighLarge))
{
nW=iWideSmall;nH=iHighSmall;
}
else
{
nW=iWideLarge;nH=iHighLarge;
}
whichImage.style.width=nW;whichImage.style.height=nH;
}
</script>
calling this function in this way:
<td align=center valign=middle >
<figure>
<button style="background-color:black; height:160px;width:160px ; border:none"><img src="F:\rashmi\icons_tv\Help_Normal.png" onfocus="zoom('57px','120px','96px','136px',this);"
onblur="zoom('57px','120px','57px','120px',this);" > </button>
<figcaption><font size="5" color="white" style="font-weight:bold"><center>help</center></font></figcaption>
</figure>
</td>
but problem is when i select image using tab key i cant see any zoomin/zoomout effect. if i replace onfocus/onblur with onmouseover/onmouseout respectively it works well.
please some one help me where i am going wrong.
regards
rashmi
You will not get focus on an img element by tabbing but on the button element instead. Move your onblur/onfocus events to the button element. This will change your button's size each time you focus/lose focus on it, but it will not change your image size. What you have to do then is to modify your code so the change is mapped on the button's contained image dimensions as well. Something that I can think of right now is
<script type="text/javascript">
var nW,nH,oH,oW;
function zoom(iWideSmall,iHighSmall,iWideLarge,iHighLarge,whichElement)
{
theImage = whichElement.firstChild;
theImage.style.width=nW;theImage.style.height=nH;
oW=whichElement.style.width;oH=whichElement.style.height;
if((oW==iWideLarge)||(oH==iHighLarge))
{
nW=iWideSmall;nH=iHighSmall;
}
else
{
nW=iWideLarge;nH=iHighLarge;
}
whichElement.style.width=nW;whichElement.style.height=nH;
theImage.style.width=nW;theImage.style.height=hH;
}
</script>
Here, the first child of the button element, which happens to be the image, takes the same height and width with the button, whenever that changes.