jsf render components with js - jsf

Let's say I have
<p:outputPanel/>
What I want to do is to specify rendered attr using js method not serverside.
This is for improving performance.
So I need something like :
<p:outputPanel rendered = "someJsFunction()"/>
What is the solution?

rendered propery is processed at server side and if it resolves to false, the element is not added into the html document. So javascript can't even find the element to display or hide because it is not created.
The only thing you can do is to remove the rendered property and change the display property of the element with javascript.
<div id="myDiv">My Content</div>
<button onclick="myFunction()">Click Me</button>
<script>
function myFunction() {
document.getElementById("myDIV").style.display = "none";
}
</script>

Well, you can have the same effect at page load cause rendered attribute is resolved at Server Side only , So using jQuery you can do it like
$(document).ready(function() {
document.getElementById("YourPanelIdHere").style.display = "none";
});
and it will be not displayed.

Related

POST FORM in node and receive data response back to same webpage

I have a webpage that takes form details, POSTS the data and should then show the results. I'm using express for my routing.
This all works fine by resending the data with the HTML template after the POST but I think there must be a better way by hiding the "results" HTML section then just showing it once the data is known from the form. I've shown a cutdown version of my pages below.
On first load, the page says "your result is undefined", which I would expect but is ugly.
I could remove the "result" section and create a 2nd HTML page to resend from the POST route with it in which would work but I think there must be a better way.
I want to hide the result section on 1st page load then make it appear on the button submit with the result data. I can get the section hide/unhide but I can't get the data results back to display them. On button submit the form results just appear in the weburl www.mywebsite.com/?data almost like a GET request
I have tried using FormData and npm 'form-data' in a POST but can't get it working following these examples https://javascript.info/formdata and https://www.npmjs.com/package/form-data.
My structure in Node is
Router.js file
return res.send(htmlFormTemplate({}));
});
router.post('/css',
[],
async (req, res) => {
let {data} = req.body;
///
result= do some calculation on {data}
///
return res.send(htmlFormTemplate({result}));
});
The htmlFormTemplate is a js file
module.exports = ({result}) => {
return `
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form class="box" method ="POST">
<inputname="data" />
<button>Submit</button>
</form>
<script>
///tried form processing here
</script>
<section id="Results">
<ul><li>Your result is ${result}</li></ul>
</section>
</body>
</html>
`;
};
I'm self-taught and new so hope this makes sense and thanks for any help/ideas
You can check if the result variable is null before it gets to the section div:
${ result === null ? '' :
`<section id="Results">
<ul><li>Your result is ${result}</li></ul>
</section>`}
Like this, it wont show the result div if result if null.
There is a very simple to solve this problem,
just use some templating engine for ex EJS, its very easy to use and will help you better,
and your result is undefined because your using a promise and it might have happened that the response might have not come and you loaded the page. Just use await
return await res.send(htmlFormTemplate({result}));

How to render the HTML into react component

I want to render the pure HTML coming from some external source into react component. I saw few solutions where people are talking about some conversion tools (HTML to JSX) but I want to handle everything in my component so while mounting it will get the HTML response and that needs to render.
You can use dangerouslySetInnerHTML for this:
function createMarkup() { return {__html: 'First ยท Second'}; };
<div dangerouslySetInnerHTML={createMarkup()} />
But as the method name suggests: you should be very sure of what you are doing there and the security implications it has.
This shouldn't be difficult to do . Assign your HTML to a div and then render it using {variable name} JSX allows you to do this and with ES6 integration you can also use class instead of className.
var Hello = React.createClass({
render: function() {
var htmlDiv = <div>How are you</div>
return <div>Hello {this.props.name}
{htmlDiv}
</div>;
}
});
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>

meteor with flow router layout is rendered twice

I don't know why but my layout is rendered two times.
Here is my index.html:
<head>
<title>title</title>
</head>
<body>
{{>layout}}
</body>
Here is my layout:
<template name="layout">
{{#if canShow}}
{{>Template.dynamic template=content}}
{{else}}
{{> loginButtons}}
{{/if}}
</template>
So here without route my template is display just one time.
Here is my route:
FlowRouter.route('/', {
action() {
BlazeLayout.render("layout", {
content: "home"
});
}
});
But with this route my template is display a second time.
This is my helpers, I think there is nothing to do with this problem but we never know.
Template.home.onCreated(function() {
this.autorun(() => {
this.subscribe('post');
});
});
Template.layout.helpers({
canShow() {
return !!Meteor.user();
}
});
Template.home.helpers({
cats() {
return Posts.find({});
}
});
you don't need to render layout in the body.
The router will take care of the rendering.
so, just have
<body>
</body>
or don't even have it at all.
Edit: Thanks to Keith, I have a better understanding of my problem. Here is his comment:
one thing to keep in mind, all the html you write in meteor isn't kept as html. It all gets converted to javascript. Things like index.html do not get pushed to the browsesr. Meteor just takes all the html you write converts it to javascript and renders what it needs to based on what your code says. This is how it knows todynamically change and rerender html
For things like changing title of the head or add meta etc, we can do it directely in the javascript.
ex: Meteor - Setting the document title

How to get client side portlet-id in liferay?

I'm using AlloyUI in my liferay portlet.
I want to use my <input>'s id in javascript. The problem is that the id of the elements are changed in client side.
For example:
If I set an <input>'s Id to "username" it is changed to _hospital_WAR_hospitalportlet_userName i.e. _hospital_WAR_hospitalportlet_ is appended to the Id, where Hospital is my portlet name.
How can I get client-side Id so that I can use it in jquery?
The string _hospital_WAR_hospitalportlet_ prepended to the Id of the <input> is nothing but the portlet-namespace.
This is only prepended to your <input>'s name & id attribute if you use <aui:input> tag and the name & id attributes are not changed if you just use plain-vanilla html <input> tag.
But as it is a good practice to use <aui:input> you can do the following to get the portlet-namespace in your javascript code:
If you are using javascripts inside a JSP i.e. using within <script> .. </script> or <aui:script> .. </aui:script> then you can use <portlet:namespace /> or <%= renderResponse.getNamespace() %> to get the string _hospital_WAR_hospitalportlet_ inside your javascript, something like.
jQuery("#<portlet:namespace />username").val();
// Or
jQuery("#<%= renderResponse.getNamespace() %>username").val();
But if you are using a *.js file then I suggest you pass the namespace as an argument to the javascript function in the js file:
function changeValues(portletNamespace) { // this function is in a js file
jQuery("#" + portletNamespace + "username").val("Lets change");
}
calling this function from the JSP:
<input type="button" onClick="changeValues('<portlet:namespace />')" />
Hope this helps. I don't know if there is a way to get the namespace or portletId directly through some javascript function defined by Liferay. If you get something like that you can post it here and that would be very helpful.
Try this:
Liferay.Portlet.ready(
/*
This function gets loaded after each and every portlet on the page.
portletId: the current portlet's id
node: the Alloy Node object of the current portlet
*/
function(portletId, node) {
}
);

Getting the co-ordinates of a component

How to get the co-ordinates of a JSF component after onclick event ? I need to place an overlay just below an icon that was clicked.
Is there any such in-built facility provided by JSF rather than manually writing a javascript function for that ?
No, there isn't. The position is browser (client) dependent. In the client side there is also totally no means of JSF, it's all just plain HTML/CSS/JS. The location can only be extracted from the HTML DOM element. You'd have to pass it from JS to JSF or do the business job fully in JS instead of JSF.
As PrimeFaces ships with jQuery, your best way to retrieve the element position relative to the document is using jQuery.offset().
var $element = jQuery('#someid');
var offset = $element.offset();
var x = offset.left;
var y = offset.top;
// ...
In addition to BalusC's answer, here is an example, where a click on a component with id=placeholder (maybe a link or button) will open another component (id=menu) directly below the triggering component. If the mouse is moved away from the triggering component, the menu will disappear:
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#placeholder").click(function(event) {
//get the position of the placeholder element
var pos = jQuery(this).offset();
var height = jQuery(this).height();
//show the menu directly below the placeholder
jQuery("#menu").css( { "left": pos.left + "px", "top": (pos.top + height) + "px" } );
jQuery("#menu").show();
});
// hide the menu on mouseout
jQuery("#placeholder").mouseout(function(event) {
jQuery("#menu").hide();
});
});
</script>
The component with id=menu can be a div or a jsf h:panelGroup or any other component. The style attribute with display: none will initially hide the component:
<h:panelGroup style="position: absolute; display: none;" id="menu">
<!-- content here -->
</h:panelGroup>
Make sure that the jQuery id selector gets the correct id of the component. E.g. if your elements are inside a form with id=form1, the jQuery call has to look something like this:
jQuery("#form1\\:placeholder").click(function(event)
Notice the double backslash.
I'd recommend using a JSF component library like RichFaces or IceFaces. Many of them have AJAX capabilities and JavaScript library integration, and therefore have components for doing that kind of thing.

Resources