info  fabercon.fi | +358 400 533 978 or +358 44 204 2029

jQuery-SPA-portletin toteutuksen avainkohdat

SPA-portletti on toteutettavissa käyttäen pelkästään jQuery-kirjastoa, tässä käydään läpi ydinkohdat.

Sivujen dynaamiseen esittämiseen on ainakin kaksi käyttökelpoista, vaihtoehtoista tapaa:

1. Ladataan sivun kaikki sisältövaihtoehdot kerralla, sivua alunperin ladattessa:

Vaihtoehtoinen sisältö sijoitetaan peräkkäisten div-elementtien sisällöksi. Toiminnan aikana hallitaan, mikä div-elementti sisältöineen näytetään, tai voidaan näyttää useitakin div-lohkoja kerralla. Latautumisvaiheessa voidaan säädellä sivujen latautumista esim. käyttäjän oikeuksien perusteella, jotka luetaan aloitussivun scriptletissa.

Koodiesimerkki div-lohkojen latautumisesta käyttäen yksinkertaista jsp-include tagia:

<% if (bPermOne) { %>
    <jsp:include page="/html/jqpure/contentOne.jsp" />
<% } %>
<% if (bPermTwo) { %>
    <jsp:include page="/html/jqpure/contentTwo.jsp" />
<% } %>

Ladattavat sivut ovat normaaleja JSP-sivuja, joissa elementien id:iden yksilöinnissä on käytetty tagia. Sivuun liittyvä alustusdata voidaan hakea Ajaxilla sivun latautumisen jälkeen, mutta mahdollista on myös tuoda data sivulle perinteisen portlet-sivun tapaan. Yksinkertaisempaa on käyttää Ajaxia tässäkin, jos sitä käytetään muualla portletin sivuilla.

Div-lohkojen näkyminen voidaan hallita HTML-elementin style.display -määrityksellä. Visibility-määritys ei käy, koska se jättää näytölle kohdalleen tyhjän tilan, vaikka sisältö häviääkin.

Koodiesimerkki div-elementin näkyvyyden hallinnasta:

var divElem = document.getElementById(gsNamespace + sActiveId);
divElem.style.display = "inline"; // piilottava on "none"

Tämä tapa on helppo ja selkeä, ja suositeltava niissä tapauksissa, missä käyttöoikeudet eivät rajoita koodin näkymistä selaimen sivukoodissa. Tämä ratkaisu mahdollistaa myös piilossa olevan sivun käytön Javascript-koodissa, piilosivulle voidaan esimerkiksi ladata dataa taustalla jo ennen sivun näyttämistä.

2. Ladataan sivu dynaamisesti käytön aikana:

Dynaaminen sivu ladataan suoravaisesti Javascriptissa jQuerylla pääsivun div-lohkon sisällöksi. Tähän jQuery käyttää omaa load-metodiaan, joka hakee sivun sisällön Ajaxilla palvelimelta, eikä sitä tarvitse koodata itse:

....
// esittele globaalit muuttujat JSP-sivulla ja tallenna ne js-muuttujiin:
var gsNamespace = "&lt;portlet:namespace /&gt;"; // jsp-pääsivulta
var gsContextPath = "&lt;%=request.getContextPath()%&gt;"; // pääsivulta jsp:n request-muuttujasta
....
var sViewPage = "/html/sovellus/jspsivu.jsp"; // jsp-sivu ladattavaksi
var sPage = gsContextPath + sViewPage;
var sDivId = gsNamespace + sDivSomeId;

// lataa sPage-sivun sDivId:n osoittaman div-elementin sisällöksi:
jQuery("#" + sDivId).load(sPage);

Sivua voi vaihtaa toiseen yksinkertaisesti, kirjoittaa vain uuden sivun vanhan päälle. Vanha sivu sisältöineen häviää. jQueryn load-metodi ei rajoitu div-elementteihin, mutta div-elementti on yleinen tapa merkitä yhtenäinen lohko HTML-sivulla.

Ongelmana tässä on, että vaikka dynaamisesti ladattava JSP-sivu prosessoidaan normaalisti JSP-sivuna, Liferay tagitusta ei prosessoida, kuten tapahtuu sivua perinteiseen tapaan portleteissa ladatessa tai vaihtoehdossa 1 edellä. Niinpä sivulla olevat elementtien id:t, jotka sisältävät <portlet:namespace /> -tagin, on esitettävä toisin: doView-metodissa kirjoitetaan portletin namespace-tieto talteen (esim. johonkin Java-luokkaan staattiseksi tiedoksi). Namespace on luettavissa vaikkapa doView-metodissa kutsulla

renderResponse.getNamespace().

Ladattavassa JSP-sivuissa portletin namespace-tieto haetaan scripletissa (tässä String tyyppiseen ns-muuttujaan). JSP-sivulla sitä käytetään normaalisti, esim.

...

Tähän JSP-sivuun liittyvässä Javascriptissa kyseiseen HTML-elementtiin viitataan normaalisti:

var elem = document.getElementById(gsNamespace + sDivSomeId).

Javascriptin gsNamespace- ja Javan ns-muuttuja sisältävät siis saman tiedon.

jQuerya käytetään myös Ajax-pohjaisten palvelinkutsujen välittämiseen. Nämä kutsut portletin Java-koodin serveResource-metodiin ovat ainoat tavat hakea dataa serverilta. JSP-sivun alkulatauksen jälkeen tarvittavat toiminnot koodataan normaalisti window.onload -eventin käsittelymeteodiin, josta sieltäkin kutsutaan Ajax-toimintoja.

Liferay SPA and Ajax with JSP-pages

Pelkästään jQuerya käytettäessä ei kannata yrittää tehdä SPA-instanceable-portlettia, joka tarkoittaa SPA-portlettia, joka esitetään useaan kertaan samalla portaalisivulla. Ratkaisu menee liian vaikeaksi. Kaksi tai useampia jQuery-SPA -portlettia voidaan kyllä laittaa samalle portaalisivulle, kunhan portlettien nimiavaruudet ovat käyttöliittymässä uniikkeja.

History-toiminto ei toimi automaattisesti siten, että se muistaisi jQuerylla dynaamisesti avatut sivut. Jos tätä tarkkuutta tarvitaan, on history-toiminto koodattava itse. Tähän tarkoitukseen voi käyttää Javascriptissa olevia window.history.pushState- ja popState-toimintoja.

Scroll to Top