I am new to Rich Faces and we are using richfaces 4.0. We are having an pop up requirement in our project and we used rich:popupPanel.
In the pop up we are having a form with 5 to 10 input text boxes.
We are facing the following issue:
Tab is not working in order to go the next text box.
We used tabindex property but it is not working in rich faces.
Can anyone help me on this?
Thanks in advance.
Here is a sample popup panel with tab feature enabled in Richfaces 4:
<script type="text/javascript">
jQuery('input').live("keypress", function(e) {
var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
/* ENTER PRESSED*/
if (key == 9) { // 9 for TAB
/* FOCUS ELEMENT */
var inputs = jQuery(this).parents("form").eq(0).find(":input");
var idx = inputs.index(this);
var move = (e.shiftKey) ? (-1) : (1); // for Shift+TAB
if (idx == inputs.length - 1) {
inputs[0].select()
} else {
inputs[idx + move].focus(); // handles submit buttons
inputs[idx + move].select();
}
return false;
}
});
</script>
<rich:jQuery query="focus().select()" selector="#thegrid :input:visible:enabled:first" name="focusInput"/>
<rich:popupPanel id="samplepopup" modal="true" resizeable="true" height="220" width="400"
onmaskclick="#{rich:component('samplepopup')}.hide()"
onshow="focusInput();">
<f:facet name="header">
<h:outputText value="sample"/>
</f:facet>
<h:form>
<h:panelGrid id="thegrid" columns="2" style="direction: rtl;">
<h:outputText value="Current Pass"/>
<h:inputSecret id="pass1" value="#{userBean.pass}"/>
<h:outputText value="New Pass"/>
<h:inputSecret id="pass2" value="#{userBean.newPass}"/>
<h:outputText value="New Pass Confirm"/>
<h:inputSecret id="pass3"/>
</h:panelGrid>
</h:form>
</rich:popupPanel>
<a4j:commandButton value="show sample" onclick="#{rich:component('samplepopup')}.show()"/>
A generic workaround could be to override the responsible function:
RichFaces.ui.PopupPanel.prototype.processTabindexes = function (input) {
if (!this.firstOutside) {
this.firstOutside = input;
}
if (!input.prevTabIndex) {
input.prevTabIndex = input.tabIndex;
// input.tabIndex = -1; // This line was marked out
}
if (!input.prevAccessKey) {
input.prevAccessKey = input.accessKey;
input.accessKey = "";
}
};
Related
So I'm using Nativescript to create app for both Android and iOS and I'm having some problems with iOS.
So I have a stack view where I have added a tap action, called "closeKeyboard" (currently just log message to console).
Inside the stack view I have text field.
The problem is that when I press on the text field, the stack view action also gets triggered.
On Android it works as expected - selecting text field doesn't trigger stack view action.
Here is the code for main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo">
<StackLayout tap="closeKeyboard">
<Label class="conf-button-label" text="Netto sum" />
<TextField text="{{ sum }}" hint="Type number" returnKeyType="done" keyboardType="number" keyboardPatter="[0-9]*" returnPress="done" id="sum" col="0" row="0" class=""/>
</StackLayout>
</Page>
Here is a code for main-page.js
var createViewModel = require("./main-view-model").createViewModel;
function onNavigatingTo(args) {
page = args.object;
}
function done(){
console.log('Input Done');
}
function closeKeyboard(page){
console.log('Close Keyboard Tapped');
}
exports.done = done;
exports.closeKeyboard = closeKeyboard;
exports.onNavigatingTo = onNavigatingTo;
Can anyone help me with this?
In case you want to create something like javascript blur event or just to hide keyboard, when you tap outside the TextView, you could set custom gesture for ios using native code. You could review the bellow attached example:
main-page.xml
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="loaded">
<StackLayout id="stack">
<Label text="Tap the button" class="title"/>
<Button text="TAP" tap="{{ onTap }}" />
<Label text="{{ message }}" class="message" textWrap="true"/>
<TextView id="text" text="" hint="Enter some text" backgroundColor="yellow" updateTextTrigger="focusLost"/>
</StackLayout>
</Page>
main-page.js
var createViewModel = require("./main-view-model").createViewModel;
var gestures = require("ui/gestures");
var observableModule = require("data/observable");
var observableObject = new observableModule.Observable();
var TapHandlerImpl1 = (function (_super) {
__extends(TapHandlerImpl1, _super);
function TapHandlerImpl1() {
_super.apply(this, arguments);
}
TapHandlerImpl1.initWithOwner = function (owner) {
var handler = TapHandlerImpl1.new();
handler._owner = owner;
return handler;
};
TapHandlerImpl1.prototype.tap = function () {
this._owner.ios.resignFirstResponder();
};
TapHandlerImpl1.ObjCExposedMethods = {
"tap": { returns: interop.types.void, params: [interop.types.id] }
};
return TapHandlerImpl1;
}(NSObject));
var tapHandler = null;
function loaded(args) {
var page = args.object;
var field = page.getViewById("text");
if (page.ios) {
tapHandler = TapHandlerImpl1.initWithOwner(field)
var recognizer = UITapGestureRecognizer.alloc().initWithTargetAction(tapHandler, "tap");
page.ios.view.addGestureRecognizer(recognizer);
}
field.addEventListener(observableModule.Observable.propertyChangeEvent, function(pcd){
console.log(pcd.eventName.toString() + " " + pcd.propertyName.toString() + " " + pcd.value.toString());
});
page.bindingContext = observableObject; }
exports.loaded = loaded;
However the same problem have been discussed also in this GitHub issue.
I think the only way is to move the closeKeyboard() from Stacklayout to the child view Label. Or you can try to define a separate tap action for the textfield to override the tap action of stacklayout.
JSF 2.2; PrimeFaces 5.3
My goal is to capture user closing dialog by clicking X button, go back to parent page so data can be refreshed and update form.
I was able to get p:remoteCommand to call my confirmAndCloseDialog() method in DialogBean, but the onDialogReturn() method in ParentBean is never called. Why is onDialogReturn not called? Any way I can get it to work?
BTW if a user would exit out dialog the normal way, i.e. close the dialog by clicking p:commandButton (CLOSE DIALOG), then everythign is fine.
Here are my codes.
Thank you!
Parent page:
<h:form>
...
<p:commandButton value="Open dialog"
id="openDialogButton"
actionListener="#{parentBean.openDialog()}"
update="#form">
<p:ajax event="dialogReturn"
listener="#{parentBean.onDialogReturn}"
update="#form"/>
</p:commandButton>
...
</h:form>
Dialog page:
<body style="height: 80%;" onunload="userClickOnX();" >
<h:form id="aForm">
<p:remoteCommand id="userClickOnX"
name="userClickOnX"
actionListener="#{dailogBean.confirmAndCloseDialog}"/>
......
<p:commandButton id="closeDialog"
value="CLOSE DIALOG"
actionListener="#{dialogBean.confirmAndCloseDialog}"/>
</h:form>
</body>
ParentBean
public void openDialog() {
Map<String, Object> options = new HashMap<>();
options.put("modal", true);
options.put("draggable", true);
options.put("resizable", true);
options.put("closable", true);
options.put("contentWidth", "100%");
options.put("contentHeight", "100%");
options.put("width", 1000);
options.put("height", 800);
RequestContext.getCurrentInstance().openDialog("dialog", options, null);
}
public void onDialogReturn(SelectEvent event) {
refresh data ....
}
DialogBean:
public void confirmAndCloseDialog() {
RequestContext.getCurrentInstance().closeDialog(objectForParent);
}
4 years later, Primefaces' dialog framework default closable "X" button is still just a link and uses javascript to hide the dialog, that is why the dialogReturn event isn't fired on using said button. I don't know a way to "intercept" its action. So if you don't want to have a custom button closing your dialog, you're out of luck, BUT you can always reinvent the wheel, kind of:
Copy Primefaces's button and make it better :)
<h:body>
<h:form id="formToolbar">
<a class="ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all" href="#"
role="button"
style="float: right; position: relative; top: -10px; left: -3px; color: #757575;"
onclick="close()">
<span class="ui-icon ui-icon-closethick"></span>
</a>
<p:remoteCommand id="close" name="close" action="#{dialogController.close()}">
</p:remoteCommand>
</h:form>
...
<h:body>
You can tweek the position and color to your liking
In the dialog bean:
public void close() {
PrimeFaces.current().dialog().closeDynamic(null);
}
Now you can expect the returnDialog event in the parent page and respective bean.
<p:commandButton action="#{parentBean.openDialog(param)}">
<p:ajax event="dialogReturn" listener="#{parentBean.handleReturn()}"/>
</p:commandButton>
Remember to set closable to false when opening the dialog otherwise you will have two "X" buttons:
Map<String,Object> options = new HashMap<String, Object>();
options.put("closable", false);
options.put("draggable", false);
PrimeFaces.current().dialog().openDynamic(
"dialog",
options,
null)
PS: I set draggable to false as well, you can still use draggable mode, but this creates a bar on top of the dialog that's not reachable inside the dialog's page, so your "X" button would be positioned a little more towards the bottom which isn't aesthetically pleasing. Hopefully dragging isn't a must.
Have you setup the Dialog Configurations?
As per: http://www.primefaces.org/docs/guide/primefaces_user_guide_5_3.pdf
faces-config.xml
<application>
<action-listener>
org.primefaces.application.DialogActionListener
</action-listener>
<navigation-handler>
org.primefaces.application.DialogNavigationHandler
</navigation-handler>
<view-handler>
org.primefaces.application.DialogViewHandler
</view-handler>
</application>
Also - your :
should be inside the dialog div/contruction, not inside the button you're selecting.
I have an issue here, that I want combine p:password and p:keyboard components in primefaces, I want password options like strength, on keyboard with password="true" so I can get strength meter, validations, match ,.. etc what special for p:password on keyboard of password='true' OR vice versa, adding keyboard to p:password.
I think easier to add keyboard to password field, as example password auto clear value when validation or re-enter form while keyboard save it !
Any idea how to do this, or workaround to make that?
In another word a solution for this equation :
<p:keyboard id="pwdPassword" value="#{loginManagedBean.password}" password="true" required="true" requiredMessage="Please enter your password"/>
And
<p:password id="pwd1" name="pwd1" value="#{loginManagedBean.newpassword}" match="pwd2" feedback="true" required="true" requiredMessage="Please Enter your new password">
<f:validateLength minimum="6" />
</p:password>
= ?
There is a workaround that you might find interesting.
The strategy is to synchronize the value between a keyboard and a password component and hide the input value for one of them.
If you check what's happening behind the curtains (here and here) you will be able to see some possibilities.
The first one that comes to my mind is hiding the input from the main password component and write some javascript code to make things appear and disappear as needed.
Here is the scenario I've created to test the idea:
<h:form id="mainForm">
<h:panelGrid columns="2" id="matchGrid" cellpadding="5">
<h:outputLabel for="pwd1" value="Password 1: *" />
<h:panelGroup>
<p:keyboard id="pwdPassword" widgetVar="kVar" value="#{viewMBean.password}" password="true" required="true" requiredMessage="Please enter your password"/>
<p:password id="pwd1" widgetVar="pVar" value="#{viewMBean.password2}" match="pwd2" label="Password 1" required="true" feedback="true" />
</h:panelGroup>
<h:outputLabel for="pwd2" value="Password 2: *" />
<p:password id="pwd2" value="#{viewMBean.password2}" label="Password 2" required="true" />
</h:panelGrid>
</h:form>
And here is the javascript:
function updateStrength() {
var p = PF('pVar');
var k = PF('kVar');
p.jq.val(k.jq.val());
var value = p.jq.val(),
label = null,
meterPos = null;
if (value.length === 0) {
label = p.cfg.promptLabel;
meterPos = '0px 0px';
} else {
var score = p.testStrength(p.jq.val());
if (score < 30) {
label = p.cfg.weakLabel;
meterPos = '0px -10px';
}
else if (score >= 30 && score < 80) {
label = p.cfg.goodLabel;
meterPos = '0px -20px';
}
else if (score >= 80) {
label = p.cfg.strongLabel;
meterPos = '0px -30px';
}
}
//update meter and info text
p.meter.css('background-position', meterPos);
p.infoText.text(label);
}
$(document).ready(function() {
var p = PF('pVar');
//p.jq.hide();
var k = PF('kVar');
k.jq.focus(function() {
p.show();
}).blur(function() {
if (!$.keypad._keypadShowing) {
p.hide();
}
}).keyup(updateStrength);
PrimeFaces.widget.Password.prototype.show = function() {
$(".keypad-close").click(function() {
console.log("close p");
p.hide();
});
$(".keypad-key").click(updateStrength);
//align panel before showing
if (!this.cfg.inline) {
this.panel.css({
left: '',
top: '',
'z-index': ++PrimeFaces.zindex
})
.position({
my: 'left top',
at: 'right top',
of: k.jq
});
this.panel.fadeIn();
}
else {
this.panel.slideDown();
}
};
});
I hope that will give you more "ammo" to deal with that challenge of yours.
Like below, how can we add minimize and maximize button at the upper right corner of the page in richface popup panel?
Using the below code, we can add the 'X' at the upper right corner and, on click of this, popup window gets closed.
<f:facet name="controls">
<h:outputLink value="#"
onclick="#{rich:component('simplePopup2')}.hide(); return false;">
X
</h:outputLink>
</f:facet>
Please, suggest me.
It is possible to extend jQuery with two custom functions that will do the maximize/minimize.
(function($) {
$.fn.maximize = function() {
var $this = $(this);
var viewport = $(window);
var bt = $this.css('border-top-width');
var br = $this.css('border-right-width');
var bb = $this.css('border-bottom-width');
var bl = $this.css('border-top-width');
bt = bt ? parseInt(bt) : 0;
br = br ? parseInt(br) : 0;
bb = bb ? parseInt(bb) : 0;
bl = bl ? parseInt(bl) : 0;
$this.css({
width: (viewport.width() - (bl + br)) + 'px',
height: (viewport.height() - (bt + bb)) + 'px',
top: 0,
left: 0
});
$this.find('div.rf-pp-cnt-scrlr').css({
width: 100 + '%',
height: 100 + '%'
});
}
$.fn.minimize = function() {
var $this = $(this);
var viewport = $(window);
$this.css({
width: '170px',
height: '20px',
top: (viewport.height() - 20),
left: 0
});
$this.find('div.rf-pp-shdw').hide();
$this.find('div.rf-pp-cnt-scrlr').hide();
}
})(jQuery);
Than you can use it with richfaces popupPanel
<rich:popupPanel id="window">
<f:facet name="controls">
<h:outputLink value="#" onclick="#{rich:component('window')}.cdiv.minimize(); return false;">
<h:outputText value="Minimize"/>
</h:outputLink>
<h:outputText value=" | "/>
<h:outputLink value="#" onclick="#{rich:component('window')}.cdiv.maximize(); return false;">
<h:outputText value="Maximize"/>
</h:outputLink>
<h:outputText value=" | "/>
<h:outputLink value="#" onclick="#{rich:component('window')}.hide(); return false;">
<h:outputText value="Close"/>
</h:outputLink>
</f:facet>
<h:outputText value="Window"/>
</rich:popupPanel>
Note the .cdiv before calling the maximize/minimize function. This is intended for reference to jQuery object itself so it will be possible to access the new functions.
The functions provided above is just a proof of concept so you will have to extend them in order to be able to restore to original size etc..
My requirement is to provide a tooltip for every option in the
SelectOneMenu because label of option is so large
that it's not possible to provide such a large size SelectOneMenu .So the
label is cutting. Thats why i need tooltip to show
the whole value on mouse over of the options in the SelectOneMenu .
Any ideas will be appreciated.
If you are using a list of "javax.faces.model.SelectItem" you can pass the description attribute to show a tooltip for each and every option.
You can use javascript.
Assume your selectOneMenu as below.
<h:form id="form1">
<h:selectOneMenu id="combo1">
<f:selectItem itemLabel="First Label"/>
<f:selectItem itemLabel="Second Label"/>
<f:selectItem itemLabel="Third Label"/>
</h:selectOneMenu>
</h:form>
Add this script at the top of your page.
<script>
window.onload = function() {
var options = document.getElementById("form1:combo1").options;
for(var i = 0; i < options.length; i++) {
options[i].title = options[i].innerHTML;
}
}
</script>