single page application - How to ajax-refresh dynamic include content by navigation menu? (JSF SPA) -


i'm learning jsf 2 site had learned lot in such short time.

my question regarding how implement common layout jsf 2 pages , have content part of page refresh not whole page whenever click link/menu different panel. using facelets approach want except each time click link panel (e.g. menu items left panel) whole page refreshed. looking way refresh content part of page. illustrate below target pagelayout.

enter image description here did not post code because i'm not sure if facelets can . there other approach more suited requirement other facelets?

a straightforward approach following view:

<h:panelgroup id="header" layout="block">     <h1>header</h1> </h:panelgroup> <h:panelgroup id="menu" layout="block">     <h:form>         <f:ajax render=":content">             <ul>                 <li><h:commandlink value="include1" action="#{bean.setpage('include1')}" /></li>                             <li><h:commandlink value="include2" action="#{bean.setpage('include2')}" /></li>                             <li><h:commandlink value="include3" action="#{bean.setpage('include3')}" /></li>                         </ul>         </f:ajax>     </h:form> </h:panelgroup> <h:panelgroup id="content" layout="block">     <ui:include src="/web-inf/includes/#{bean.page}.xhtml" /> </h:panelgroup> 

with bean:

@managedbean @viewscoped public class bean implements serializable {       private string page;       @postconstruct      public void init() {          page = "include1"; //  default include.      }       // +getter+setter.  } 

in example, actual include templates include1.xhtml, include2.xhtml , include3.xhtml in /web-inf/includes folder (folder , location free choice; files placed in /web-inf in order prevent direct access guessing url in browser's address bar).

this approach works in myfaces versions, requires minimum of mojarra 2.3.0. in case you're using mojarra version older 2.3.0, fails when <ui:include> page in turn contains <h:form>. postback fail because totally missing view state. can solve upgrading minimally mojarra 2.3.0 or script found in answer h:commandbutton/h:commandlink not work on first click, works on second click, or if you're using jsf utility library omnifaces, use fixviewstate script. or, if you're using primefaces , exclusively use <p:xxx> ajax, it's transparently taken account.

also, make sure you're using minimally mojarra 2.1.18 older versions fail in keeping view scoped bean alive, causing wrong include being used during postback. if can't upgrade, you'd need fall below (relatively clumsy) approach of conditionally rendering view instead of conditionally building view:

... <h:panelgroup id="content" layout="block">     <ui:fragment rendered="#{bean.page eq 'include1'}">         <ui:include src="include1.xhtml" />     </ui:fragment>     <ui:fragment rendered="#{bean.page eq 'include2'}">         <ui:include src="include2.xhtml" />     </ui:fragment>     <ui:fragment rendered="#{bean.page eq 'include3'}">         <ui:include src="include3.xhtml" />     </ui:fragment> </h:panelgroup> 

the disadvantage view become relatively large , associated managed beans may unnecessarily initialized though when not used per rendered condition.

as positioning of elements, that's matter of applying right css. that's beyond scope of jsf :) @ least, <h:panelgroup layout="block"> renders <div>, should enough.

last not least, spa (single page application) approach not seo friendly. pages not indexable searchbots nor bookmarkable endusers, may need fiddle around html5 history in client , provide server side fallback. moreover, in case of pages forms, same view scoped bean instance reused across pages, resulting in unintuitive scoping behavior when navigate visited page. i'd suggest go templating approach instead outlined in 2nd part of answer: how include xhtml in xhtml using jsf 2.0 facelets? see how navigate in jsf? how make url reflect current page (and not previous one).


Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -