Render PrimeFaces <p:focus> component only if the browser window has a certain size - jsf

Is there a way to render the PrimeFaces <p:focus> component (or let it do its job) only when the browser window has a certain size? To do this I understand that maybe I have to have access the browser window size in server code and use the component rendered attribute to access this code.
In client code, I get the window width with code like this: $(window).width() > 480.
The reason for this is that I don't want to focus the first component in mobile devices, which most of the time have small screens.
Today I'm doing this with the client code below, but I'd like to use the <p:focus> component for the task, as it also has the benefit to focus the first invalid component when validation fails.
$(
function()
{
if (bigWindow())
{
focusFirstInput();
}
}
)
function bigWindow()
{
return $(window).width() > 480;
}
function focusFirstInput()
{
$("#form input:text, #form input[type=number], #form input[type=password], #form textarea").
first().focus();
}

I've found a way using the <p:focus> component:
$(
function()
{
let primeFacesOriginalFocusFunction = PrimeFaces.focus;
PrimeFaces.focus =
function(id, context)
{
if (!isMobile())
{
primeFacesOriginalFocusFunction(id, context);
}
}
}
)
function isMobile()
{
return ...
}

Related

React Hide Component when Mobile Keyboard open

I'm wondering if there is a way to hide React components (Ex. Bottom Navigation Bar Component) while the mobile (Andriod, iOS, etc. ) Keyboard is open on the screen.
Currently I'm doing it with a:
#media (max-height: 400px) {
.navclass {
display: none;
}
}
but am wondering if there is a JS Event or similar.
When am input element is focused on devices of inbuilt keyboards, the keyboards pops up.
ReactJS allows you to write Normal JavaScript in your code.so what you can do is to
this.state = {
isNavVisible: true
}
You can now pass this dynamically as a prop on the components and set it to the style of the wrappers element as an inline style in the components main file.
You can then write a function on your inputs or elements that takes focus:
const disableNav = () => {
if(windows.innerWidth <= 400){
this.setState({isNavVisible: false})
}
}

React native props,ref value is undefined inside keyboard hide event?

i am trying to clear my Textinput focus inside keyboard hide event,but i am not able to get reference
inside keyboard hide event method.i tried to print props value it also getting undefined
constructor (props) {
this.inputs = {};
}
_keyboardDidHide () {
console.log("value"+this.props);
this.inputs['inputValue'].blur();
}
componentWillMount () {
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
}
componentWillUnmount () {
this.keyboardDidHideListener.remove();
}
<TextInput
ref={input => {
this.inputs['inputValue'] = input;
}}
autoFocus={true}
blurOnSubmit={false}
/>
let me know how to clear the TextInput focus on _keyboardDidHide method.
I'm not 100% sure what you're trying to do here, however I assume you want to at least get the info out from your input.
No need for that ref magic there though, just use simple react state changes.
class InputWrapper extends React.Component {
constructor() {
super();
this.state = {
input: ''
};
this.handleInput = this.handleInput.bind(this);
}
handleInput(input) {
this.setState({input});
}
render() {
return (
<TextInput onChangeText={this.handleInput} />
);
}
}
This will give you a TextInput Component with control over the input.
Now you should add a componentDidUpdate method as well, that prints out the current state, so you can observe what is happening when you change the input value.
componentDidUpdate() {
console.log(this.state);
}
As for bluring and such, you should definitely check out the documentation on TextInput : https://facebook.github.io/react-native/docs/textinput.html
Additionally, might I suggest to jump into the lifecycle documentation of react itself, plus checking up on props vs state in react. It is a confusing concept in the beginning and you should definitely revisit it.
As for blurring the input, simply do this:
<TextInput
ref={input => this.input = input}
/>
And then you can call:
this.input.blur();
wherever you want.
Also, do not forget to bind your _keyboardDidHide callback within your constructor or when adding it as the listener callback, like so
this._keyboardDidHide = this._keyboardDidHide.bind(this)
Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
Hope this helps

Decouple navigation and selection with JSF tree-like widget

I'm looking for a good approach to realize a tree-like JSF widget with the following requirements:
means to expand and collapse tree branches
ajax navigation through clicking on a tree node
multi-selection of nodes / branches via tri-state checkboxes
the former three features must work independent from each other
the solution must be compatible with PrimeFaces
I don't want to fork the framework in terms of writing a custom component
What I've come across:
PrimeFaces p:tree and p:treeTable
built-in selection feature provides a nice implementation with tri-state checkboxes but is tightly coupled to clicking on a node, which makes it unusable in terms of navigation (the selection also changes)
alternatively a custom implementation of the checkbox-column must reinvent the whole tri-state checkbox logic even with pe:triStateCheckbox (PrimeFaces Extensions)
OmniFaces o:tree seems to offer a high level of customization, but also leaves a lot of needle crafting remaining
Any hints, experiences are welcome.
I ended up with a solution build on p:treeTable with selectionMode="checkbox" and p:commandLink for navigation.
To disable the 'full row' mouse click trigger also causing selection changes the JavaScript has been adjusted like this (PrimeFaces 5.3):
<script type="text/javascript">
//<![CDATA[
PrimeFaces.widget.TreeTable.prototype.bindSelectionEvents = function() {
var $this = this,
rowSelector = '> tr.ui-treetable-selectable-node';
this.tbody.off('mouseover.treeTable mouseout.treeTable click.treeTable', rowSelector)
.on('mouseover.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.addClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').addClass('ui-state-hover');
}
}
})
.on('mouseout.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.removeClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').removeClass('ui-state-hover');
}
}
})
.on('click.treeTable', rowSelector, null, function(e) {
//$this.onRowClick(e, $(this));
e.preventDefault();
});
if(this.isCheckboxSelection()) {
var checkboxSelector = this.cfg.nativeElements ? '> tr.ui-treetable-selectable-node > td:first-child :checkbox':
'> tr.ui-treetable-selectable-node > td:first-child div.ui-chkbox-box';
this.tbody.off('click.treeTable-checkbox', checkboxSelector)
.on('click.treeTable-checkbox', checkboxSelector, null, function(e) {
var node = $(this).closest('tr.ui-treetable-selectable-node');
$this.toggleCheckboxNode(node);
});
//initial partial selected visuals
if(this.cfg.nativeElements) {
this.indeterminateNodes(this.tbody.children('tr.ui-treetable-partialselected'));
}
}
};
//]]>
</script>
I also changed some CSS, mainly:
.ui-treetable .ui-treetable-data tr.ui-state-highlight,
.ui-treetable .ui-treetable-data tr.ui-state-hover {
cursor: default;
}

What events are available for PrimeFaces DataList [duplicate]

This question already has answers here:
Using the page event with p:dataList in PrimeFaces
(2 answers)
Closed 8 years ago.
I'm trying to capture the Page event when users click through pages using the Paginator on a DataList. The user guide doesn't mention any Ajax behaviors for this component, but I tried <p:ajax event="page"> anyway and found that event "page" is not supported.
Are there any events available for DataList? If not, has anyone got an idea how I can save each page as the user pages through?
Thanks :)
Neil
You can hook into the the component's rendering lifecycle (the component is rerendered with each pagination operation) with the generic preRenderComponent event on the datalist. Just add the following to your datalist:
<p:dataList>
<f:event type="preRenderComponent" listener="#{yourBean.operation}"/>
</p:dataList>
Its possible to override the standard PrimeFaces javascript function which is called if you click the pagelinks. From there you may call a remoteCommand or whatever you want to...
I know it´s not the best practice, but a possibility ;)
PrimeFaces.widget.Paginator.prototype.bindPageLinkEvents = function(){
var $this = this;
this.pagesContainer.children('.ui-paginator-page').on('click.paginator', function(e) {
var link = $(this);
if(!link.hasClass('ui-state-disabled')&&!link.hasClass('ui-state-active')) {
$this.setPage(parseInt(link.text()) - 1);
}
// your code goes here
})
.on('mouseover.paginator', function() {
var item = $(this);
if(!item.hasClass('ui-state-disabled')&&!item.hasClass('ui-state-active')) {
item.addClass('ui-state-hover');
}
})
.on('mouseout.paginator', function() {
$(this).removeClass('ui-state-hover');
})
.on('focus.paginator', function() {
$(this).addClass('ui-state-focus');
})
.on('blur.paginator', function() {
$(this).removeClass('ui-state-focus');
})
.on('keydown.paginator', function(e) {
var key = e.which,
keyCode = $.ui.keyCode;
if((key === keyCode.ENTER||key === keyCode.NUMPAD_ENTER)) {
$(this).trigger('click');
e.preventDefault();
}
});
};
Or look at this answer. I like it very much!
https://stackoverflow.com/a/25930991/2265727

Backbone events applied to an el that is an svg element

I have an SVG canvas with text that I would like to respond to clicks. The code below isn't getting the job done:
var MyView = Backbone.View.extend({
tagName : "text",
events : {
"click" : "clickhandler"
},
initialize : function() {
this.centerX = this.options.centerX;
this.centerY = this.options.centerY;
this.svg = this.options.svg;
this.tagText = this.model.get("tag_name");
this.render();
},
clickhandler : function(event) {
console.log("I was clicked!"); //This is not firing on click
},
render : function() {
this.el = this.svg.text(this.centerX, this.centerY, this.tagText, {});
return this;
}
});
This is being called in the render function of another view as such :
container.svg({
onLoad : function(svg) {
for ( var i = 1; i < that.relatedTags.length; i++) {
tagView = new MyView({
model : this.relatedTags.at(i),
centerX : 100,
centerY : 200,
svg : svg
});
}
container.append(tagView);
}
});
It shows up just fine and if I throw this in at the end of the for loop :
$(tagView.el).click(function() {
alert("xx");
});
Then the clicking works but I need to access the Backbone Model associated with the view so I'd much prefer the backbone event to a straight JQuery event.
The problem here is, that you set the element of the view in the render method. But backbone tries to add the events on initialization. So when backbone tries to add the events there is no element in you case. So either you have to start your view with your svg text, or you add the events by hand in your render method.
Maybe you can add the events on the svg itself and jquery is clever enough to handle the delegation. But I'm not sure in this case.

Resources