Dynamic Render Formula in XPages Menu - javascript

I created a computed Menu in XPages with rendered rules based on users roles.
The values of my menu are calculated from a view in a computed field.
This is my menu code:
<div id='cssmenu'>
<ul><li class='active has-sub'>
<a href='#'>Title1</a>
<ul>
<xp:text escape="true" disableTheme="true" contentType="html">
<xp:this.value>
<![CDATA[#{javascript:var arr= #DbColumn(#DbName(), "vwMenu", 4);
arr.join("");}]]>
</xp:this.value>
</xp:text>
</ul>
</li>
</ul>
</div>
The value of an element from my array give for example this code :
<li class='has-sub'>
<a href=https://mylink.com>Link1</a>
<xp:panel>
<xp:this.rendered>
<![CDATA[${javascript:context.getUser().getRoles().contains('[USER1]')}]]>
</xp:this.rendered>
<ul>
<li><a href=https://MyPage.com>Link2</a></li>
</ul>
</xp:panel>
</li>
The menu appears fine so the html code is ok.But the xml part concerning the visibilty on link2 does not. link 2 is not visible, whatever the role of the connected user. I think it's a problem that happened where i use xml code into javascript code.
Maybe because The content type of my computed field is html and my code for rendering is in xml.

You forgot to enclose the href attributes with an apostrophe ':
<li class='has-sub'>
<a href='https://mylink.com'>Link1</a>
<xp:panel>
<xp:this.rendered>
<![CDATA[${javascript:context.getUser().getRoles().contains('[USER1]')}]]>
</xp:this.rendered>
<ul>
<li>
<a href='https://MyPage.com'>Link2</a>
</li>
</ul>
</xp:panel>
</li>

Method .contains() is case-sensitive. Make sure the role set in ACL is exactly [USER1]. Your rendered code works fine for me.
You might add some prints to rendered code for test purposes:
<xp:this.rendered>
<![CDATA[${javascript:
print(context.getUser());
print(context.getUser().getRoles());
context.getUser().getRoles().contains('[USER1]')}]]>
</xp:this.rendered>
You can see at server console then what really happens in your code:
The href value has to be surrounded by quotation marks or single quotation marks. Otherwise you would get a syntax error and changes you did on XPage wouldn't take effect.
Update
As you mentioned in your comments, you put the HTML and included JavaScript code into a computed field. This doesn't work because the content is sent straight to browser and this way included JavaScript code does not get executed on server.
Instead, use a repeat control to create the menu items:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<ul>
<li>
Link1
<xp:panel>
<xp:this.rendered>
<![CDATA[${javascript:
context.getUser().getRoles().contains('[USER1]')}]]>
</xp:this.rendered>
<ul>
<xp:repeat
var="link">
<xp:this.value><![CDATA[#{javascript:
["https://MyPage.com", "https://www.google.com"]
}]]></xp:this.value>
<li>
<a href="#{link}">
<xp:text escape="true"
value="#{javascript:'Link to ' + link}" />
</a>
</li>
</xp:repeat>
</ul>
</xp:panel>
</li>
</ul>
</xp:view>

Related

Materialize sidenav collapsible won't work within a separate JS file

Sorry if this has been answered previously; I've dug around but can't find it. I'm using the Materialize sidenav by calling M.AutoInit() which works for me until I try putting it in a separate Javascript file. I've been able to set up my footer this way so I don't have repeat code, but this doesn't seem to work for the sidenav. The sidenav shows up but the collapsible part will not open.
I think the problem is it doesn't like calling the collapsible part from HTML that is being inserted dynamically. But I tried separating out the collapsible portion (using 2 different querySelectors) which did not work either. If I were to put at least part of the sidenav back into my HTML page, it would defeat the purpose of me doing this.
Any thoughts or solutions? Thanks for looking at it!
document.addEventListener("DOMContentLoaded", () => {
M.AutoInit()
document.querySelector('header').insertAdjacentHTML('afterbegin',
`<ul id="slide-out" class="sidenav sidenav-fixed">
<li>
<a
href="https://www.greece.org/"
target="_blank"
rel="noopener noreferrer"
>HEC Main</a
>
</li>
<li>
<a href="index.html" class="sidenav-close" rel="noopener noreferrer"
>Home</a
>
</li>
<li class="no-padding">
<ul class="collapsible collapsible-accordion">
<li>
<button class="collapsible-header">
History<i class="material-icons">arrow_drop_down</i>
</button>
<div class="collapsible-body">
<ul class="sidenav-close">
<li>
A Brief Review
</li>
<li>Philosophers List</li>
<li>Philosophers Map</li>
<li>The Beginning</li>
<li>Socrates</li>
<li>Plato</li>
<li>Aristotle</li>
<li>
<a href="bibliography-references.html"
>Bibliograpy / References</a
>
</li>
</ul>
</div>
</li>
</ul>
</li>
<li class="divider"></li>
<li>
Media
</li>
<li>
Events
</li>
</ul>`)
document.querySelector('main').insertAdjacentHTML('afterend',
`<footer class="page-footer">
<div class="container">
<p class="center-align">
Philosophy is sponsored by
<a
href="https://www.greece.org"
target="_blank"
>
www.greece.org
</a> | © 2021 All Rights Reserved.
</p>
</div>
<div class="fixed-action-btn">
<a href="#top" class="btn-floating btn-large" style="background-color: silver;">
<i class="large material-icons">arrow_upward</i>
</a>
</div>
</footer>`)
})
Initialisation is a one time thing - it scans the document for the matching selector, and runs the initialisation on it. So, always run the initialisation AFTER any dynamic content is added. If you add stuff on the fly, just run the init again.
Codepen.
document.addEventListener('DOMContentLoaded', function() {
// Always add stuff to the page BEFORE running the init
// Anything hardcoded to the page will be fine if wrapped in a document ready.
M.AutoInit();
// Anything added after the init will NOT be initialised. It's a one time thing. Run the init at the end of any dynamic additions.
});

Seeking a selector for child elements in dom scrape

I am unable to change any html on the website in question.
Here is some html:
<ul id="utility-menu" class="menu menu--primary">
<li><a class="" href="https://www.example.com/newsstand" target="_blank">Magazines</a></li>
<li><a class="" href="https://secure.bla.com/example/promo/GiveAGift/" target="_blank">Gifts</a></li>
<li>
Français
</li>
<li><a class="" href="/signin">Sign In</a></li>
<li>
<div class="i-am-canadian">
<img alt="Canadian flag" height="23px;" src="https://secure.example.com/assets/images/icons/ui/i-canadian-c8a132ad64588dcc0b2e61cc589dfef3.png" width="40px;">
</div>
</li>
</ul>
I managed to select the menu using:
document.querySelectorAll('.menu--primary')[0]
The element I'm interested in is:
Français
This element i a language selection for the site visitor that will be either "English" or "Français".
If the user is on an English language page the value of the element will be that shown. But if they are on the French language equivalent the element will be English
I would like a selector that returns either "English" or "Français".
How would I do that?
Answer:
var el = document.querySelector('#utility-menu a[href^="/email_check?lang="').textContent;
It will select first a element with attribute href begining with /email_check?lang= in #utility-menu. Probably you can .trim() text to get rid of whitespaces.
If your html is not going to change much, you can use
var test = document.querySelector("ul > li > a[href='/email_check?lang=fr']");
console.log(test.textContent); // Français
https://jsfiddle.net/u4vjq8ah/

How do i add a hyperlink to a data-image line of code? CSS3

I'm doing some work and still fairly new to CSS,
I have some code here,
<div id='ninja-slider'>
<ul>
<li>
<div data-image="images/md/1.jpg" </div> </li>
<li>
<div data-image="images/md/2.jpg"> </div>
</li>
<li>
<div data-image="images/md/3.jpg"></div>
</li>
<li>
<div data-image="images/md/4.jpg"></div>
</li>
</ul>
</div>
I want to know how can i add a hyperlink to each of these images? I've tried however it hasn't worked for me unfortunately.
Please help, I even tried Javascript from a google search. Something to do with onclick
Cheers
wrap the div in <a> tag
<ul>
<li>
<div data-image="images/md/1.jpg"></div>
</li>
</ul>
Use <a></a> tag.
you can do this
<img src="your_image.jpg" width="" height="">
href will contain the page or wherever you want user to redirect.
This approach is better and more widely used than the one's you showed

converting html tags into jade node template

so I'm having trouble converting html tags into jade node template engine
the html output template that I want to display is this
<a href="#" class="dropdown-hover"> Dropdown
<ul class="dropdown-hover-menu">
<li>Dropdown menu</li>
<li>Dropdown menu2</li>
</ul>
</a>
I'm using html2jade.org which is a jade node templates converter for html
when I convert the HTML it went with ouput like this
a.dropdown-hover(href='#') Dropdown
ul.dropdown-hover-menu
li
a(href='#') Dropdown menu
li
a(href='#') Dropdown menu2
then I go to my IDE text editor and paste it, but somehow the output was not according to my needs at all and it goes like this...
<a class="dropdown-hover" href="#">Dropdown</a>
<ul class="dropdown-hover-menu"><a class="dropdown-hover" href="#">
</a><li><a class="dropdown-hover" href="#"></a>Dropdown menu</li>
<li>Dropdown menu2</li>
</ul>
why the output like this? please help me
and tried to use another editor, or check with any extension saves your file, checking in your editor I'm fine preserved

Create a URL based on Selection in <ul> <li>

I am trying to build url based on a user selection from a multilevel list.
The user selects four options which in turn will create the url required for retrieval of a document.
Example:
<ul id="nav">
<li>Report name
<ul>
<li>Year
<ul>
<li>2010
<ul>
<li>Jan</li>
<li>Feb</li>
<li>March</li>
</ul>
</li>
<li>2011</li>
<li>2012</li>
<li>2013</li>
<li>2014</li>
</ul>
</li>
</ul>
</li>
<!-- etc. -->
</ul>
So I would select the Report Name > Year > Month and this would build a url which equals the path to the file.
e.g. http://www.example.com/Report1/2010/Jan
Does anyone perhaps have any ideas as to how this can be done.
Here is an example of $(this) being used to get the value of what was clicked. I'm using JQuery in this example.
Had to add an id to the year value. You don't HAVE to do it this way, you can use the jquery selectors to get the proper value. It is just a lot easier.
<ul id="nav">
<li>Report name
<ul>
<li>Year
<ul>
<li id='2010'>2010
<ul>
<li>Jan</li>
<li>Feb</li>
<li>March</li>
</ul>
</li>
<li>2011</li>
<li>2012</li>
<li>2013</li>
<li>2014</li>
</ul>
</li>
</ul>
</li>
<!-- etc. -->
</ul>
<script src="http://code.jquery.com/jquery-1.11.0.js"></script>
The javascript looks like this:
$('#2010 li').click(function()
{
var year=$(this).parent().parent().attr('id');
var month=$(this).text();
console.log(month+' '+year);
//this will show you Jan and 2010 in the log. You can use this variable to append to a URL string.
});
Ok there are several options, I would suggest using javascript.
So, basically, you would check if an <li> was clicked and if it was, then add a certain value to string, the redirect the page using that built string. Here is an example of what I mean:
http://jsfiddle.net/35XDn/4/

Categories

Resources