Flyout or Menu Dropdown in Portal 8 themes - portal

I was wondering if anyone has been successful in creating and using a flyout or drop-down menu navigation for WebSphere Portal Server v8?
We are using a custom theme.
What we would like to do is keep the main pages across the top navigation bar and have it so that when you hover/click over that page/tab a menu (flyout or drop-down) displays the sub pages and their sub pages and so on.
Any suggestions and pointers are welcome.
Thanks in advance.

This example generate ul-li two level menu, of course you can generate more levels and you need make insertions of your html and javascript if you need. Put this JSP to your theme and make include to head.jsp for example or somewhere else.
Take a look on this string "your.main.page.unique.name" , change it to your top page unique name. Also there is function isHiddenPage, if you want hide pages from menu, just set property to page hide.from.menu=true
Ok, dude, let me know if you need clarification
<%#page import="com.ibm.portal.model.*"%>
<%#page import="com.ibm.portal.navigation.*"%>
<%#page import="com.ibm.portal.identification.*"%>
<%#page import="com.ibm.portal.content.ContentNodeType"%>
<%#page import="java.util.*"%>
<%#page import="java.io.*"%>
<%#page import="com.ibm.portal.ModelException"%>
<%#page import="com.ibm.portal.ObjectNotFoundException"%>
<%!
public NavigationNode getNodeByName(NavigationModel nm, NavigationNode rootNode, String nodeUniqueName) throws ModelException {
Iterator iter = nm.getChildren(rootNode);
while(iter.hasNext()){
NavigationNode node = (NavigationNode) iter.next();
String uniqueName = node.getContentNode().getObjectID().getUniqueName();
if (uniqueName!= null && uniqueName.equals(nodeUniqueName))
return node;
}
return null;
}
public List<NavigationNode> getChildrenNodes(NavigationModel nm, NavigationNode parentNode) throws ModelException{
List<NavigationNode> children = new ArrayList<NavigationNode>();
Iterator iter = nm.getChildren(parentNode);
while(iter.hasNext()){
NavigationNode node = (NavigationNode) iter.next();
children.add(node);
}
return children;
}
public String getId(Identification identification, NavigationNode node) throws com.ibm.portal.serialize.SerializationException{
return identification.serialize( ( ( com.ibm.portal.Identifiable ) node ).getObjectID());
}
public boolean isHiddenPage(NavigationNode node){
if (node instanceof com.ibm.portal.MetaDataProvider) {
com.ibm.portal.MetaData iMetaData=((com.ibm.portal.MetaDataProvider) node).getMetaData();
Object url=iMetaData.getValue("hide.from.menu");
return (url != null && url.toString().equals("true"));
}
return false;
}
%>
<%
javax.naming.Context ctx = new javax.naming.InitialContext();
NavigationModelHome nmh = (NavigationModelHome) ctx.lookup("portal:service/model/NavigationModel");;
NavigationModel nm = nmh.getNavigationModelProvider().getNavigationModel(request, response);
NavigationSelectionModelHome nsmh = (NavigationSelectionModelHome) ctx.lookup("portal:service/model/NavigationSelectionModel");
NavigationSelectionModel nsmodel = nsmh.getNavigationSelectionModelProvider().getNavigationSelectionModel(request, response);
NavigationNode rootNode = (NavigationNode) nm.getRoot();
Identification identification = (Identification) ctx.lookup( "portal:service/Identification" );
try{
if (rootNode != null && nm.hasChildren(rootNode)) {
NavigationNode myRootNode = getNodeByName(nm, rootNode, "your.main.page.unique.name");
%>
<ul>
<%
for (NavigationNode firstLevelPage: getChildrenNodes(nm, myRootNode )){
String title = firstLevelPage.getTitle(getLocale(pageContext));
String id = getId(identification, firstLevelPage);
boolean isNodeSelected = nsmodel.isNodeSelected(firstLevelPage); // if node selected you can apply css class to selected menu item
boolean isHidden = isHiddenPage(firstLevelPage); // if node is hidden from menu just continue loop
%>
<li>
<portal-navigation:urlGeneration contentNode="<%=id%>">
<a class="trigger" href="<% wpsURL.write(out);%>" ><c:out value="<%=title%>"/></a>
</portal-navigation:urlGeneration>
<%if (getChildrenNodes(nm,firstLevelPage ).size() > 0){%>
<ul>
<%
for (NavigationNode secondLevelPage: getChildrenNodes(nm,firstLevelPage )){
String childTitle = secondLevelPage.getTitle(getLocale(pageContext));
String childId = getId(identification, secondLevelPage);
%>
<portal-navigation:urlGeneration contentNode="<%=childId%>">
<li><a href="<% wpsURL.write(out);%>" ><c:out value="<%=childTitle%>"/></a></li>
</portal-navigation:urlGeneration>
<%}%>
</ul>
<%} %>
</li>
<%}%>
</ul>
<%
}
}
}catch(ModelException e){
e.printStackTrace();
}
%>
PS. maybe I wrong with brackets, check it

Example of theme that I've done
1) Simple dropdown
2) Multilevel dropdown
I use ul and li to make the dropdown and you can update the topnav.jsp. Couldn't paste the code here as it's not displaying correctly.
Good luck

Related

How to group project results by Taxonomy Terms

I have a ContentType Animal which has a Taxonomy field species.
look at this posthttp://orchardpros.net/tickets/10636 and (http://www.ideliverable.com/blog/ways-to-render-lists-of-things) for a good explanation.
I runed the code,but It have 2 erro.
1.var speciesField = item.Animal.Species;----gave erro: CS1061 ,"Orchard.ContentManagement.ContentItem' does not contain a definition Animal".
2.var items = speciesDictionary[speciesTerm];----gave erro:CS0136 " A local or parameter named 'items' cannot be declared in this scope because that name is used in an enclosing local.
please help!
#using Orchard.ContentManagement
#using Orchard.Taxonomies.Models
#{
var items = ((IEnumerable<ContentItem>)Model.ContentItems);
var speciesDictionary = new Dictionary<TermPart, IList<ContentItem>>();
// Collect categories and their items.
foreach (var item in items) {
var speciesField = item.Animal.Species; // Assumes that the species field is attached to the Animal type's implicit part (Animal).
var speciesTerms = (IEnumerable<TermPart>)speciesField.Terms;
foreach (var speciesTerm in speciesTerms) {
var list = speciesDictionary.ContainsKey(speciesTerm) ? speciesDictionary[speciesTerm] : default(IList<ContentItem>);
if (list == null) {
list = new List<ContentItem>();
speciesDictionary.Add(speciesTerm, list);
}
list.Add(item);
}
}
}
<ul>
#foreach (var speciesTerm in speciesDictionary.Keys) {
var items = speciesDictionary[speciesTerm];
<li>
#speciesTerm.Name
</li>
}
</ul>
Your first error indicates that you are trying to get a property of the ContentItem class which does not exist. This is actually partially correct, because it does exist on the ContentItem, but because you cast it to a ContentItem class, it loses the dynamic properties.
You can fix this by not casting to a ContentItem class, but just to dynamic:
var items = ((IEnumerable<dynamic>)Model.ContentItems);
The second error indicates that you are trying to create a variable while it already exists. This is obvious, because in the top of your .cshtml you already have items defined:
#{
// var items is defined here, you can not redefine it
// as always in C#
var items = ((IEnumerable<ContentItem>)Model.ContentItems);
}
So instead give it a different name in the bottom:
<ul>
#foreach (var speciesTerm in speciesDictionary.Keys) {
// Cannot use 'items' here again
var speciesItems = speciesDictionary[speciesTerm];
<li>
#speciesTerm.Name
</li>
}
</ul>

Save button with count greasemonkey

i want to add an save button with a counter
i wrote a script but its not work with greasemonkey
<button type="submit" id="save" value="Save">Save</button>
<p>The button was pressed <span id="displayCount">0</span> times.</p>
<script type="text/javascript">
var count = 0;
var button = document.getElementById("save");
var display = document.getElementById("displayCount");
function loadStats(){
if(window.localStorage.getItem('count')){
count = window.localStorage.getItem('count')
display.innerHTML = count;
} else {
window.localStorage.setItem('count', 0)
} //Checks if data has been saved before so Count value doesnt become null.
}
window.localStorage.setItem("on_load_counter", count);
button.onclick = function(){
count++;
window.localStorage.setItem("count", count)
display.innerHTML = count;
}
</script>
You have to add html elements with javascript since Greasemonkey is intended to run scripts over web pages.
See Basic method to Add html content to the page with Greasemonkey?

Looping through node created by HtmlAgilityPack

I need to parse this html code using HtmlAgilityPack and C#. I can get the
div class="patent_bibdata" node, but I don'know how to loop thru the child nodes.
In this sample there are 6 hrefs, but I need to separate them into two groups; Inventors, Classification. I'm not interested in the last two. There can be any number of hrefs in this div.
As you can see there is a text before the two groups that says what the hrefs are.
code snippet
HtmlWeb hw = new HtmlWeb();
HtmlDocument doc = m_hw.Load("http://www.google.com/patents/US3748943");
string xpath = "/html/body/table[#id='viewport_table']/tr/td[#id='viewport_td']/div[#class='vertical_module_list_row'][1]/div[#id='overview']/div[#id='overview_v']/table[#id='summarytable']/tr/td/div[#class='patent_bibdata']";
HtmlNode node = m_doc.DocumentNode.SelectSingleNode(xpath);
So how would you do this?
<div class="patent_bibdata">
<b>Inventors</b>:
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Ronald T. Lashley
</a>,
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Ronald T. Lashley
</a><br>
<b>Current U.S. Classification</b>:
84/312.00P;
84/312.00R<br>
<br>
<a href="http://www.google.com/url?id=3eF8AAAAEBAJ&q=http://patft.uspto.gov/netacgi/nph-Parser%3FSect2%3DPTO1%26Sect2%3DHITOFF%26p%3D1%26u%3D/netahtml/PTO/search-bool.html%26r%3D1%26f%3DG%26l%3D50%26d%3DPALL%26RefSrch%3Dyes%26Query%3DPN/3748943&usg=AFQjCNGKUic_9BaMHWdCZtCghtG5SYog-A">
View patent at USPTO</a><br>
<a href="http://www.google.com/url?id=3eF8AAAAEBAJ&q=http://assignments.uspto.gov/assignments/q%3Fdb%3Dpat%26pat%3D3748943&usg=AFQjCNGbD7fvsJjOib3GgdU1gCXKiVjQsw">
Search USPTO Assignment Database
</a><br>
</div>
Wanted result
InventorGroup =
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Ronald T. Lashley
</a>
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Thomas R. Lashley
</a>
ClassificationGroup
84/312.00P;
84/312.00R
The page I'm trying to scrape: http://www.google.com/patents/US3748943
// Anders
PS! I know that in this page the names of the inventors are the same, but in most of them they are different!
XPATH is your friend! Something like this will get you the inventors name:
HtmlWeb w = new HtmlWeb();
HtmlDocument doc = w.Load("http://www.google.com/patents/US3748943");
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[#class='patent_bibdata']/br[1]/preceding-sibling::a"))
{
Console.WriteLine(node.InnerHtml);
}
So it's obvious that I don't understand XPath (yet). So I came up with this solution.
Maybe not the smartest solution, but it works!
// Anders
List<string> inventorList = new List<string>();
List<string> classificationList = new List<string>();
string xpath = "/html/body/table[#id='viewport_table']/tr/td[#id='viewport_td']/div[#class='vertical_module_list_row'][1]/div[#id='overview']/div[#id='overview_v']/table[#id='summarytable']/tr/td/div[#class='patent_bibdata']";
HtmlNode nodes = m_doc.DocumentNode.SelectSingleNode(xpath);
bool bInventors = false;
bool bClassification = false;
for (int i = 0; i < nodes.ChildNodes.Count; i++)
{
HtmlNode node = nodes.ChildNodes[i];
string txt = node.InnerText;
if (txt.IndexOf("Inventor") > -1)
{
bClassification = false;
bInventors = true;
}
if (txt.IndexOf("Classification") > -1)
{
bClassification = true;
bInventors = false;
}
if (txt.IndexOf("USPTO") > -1)
{
bClassification = false;
bInventors = false;
}
string name = node.Name;
if (name.IndexOf("a") > -1)
{
if (bInventors)
{
string inventor = node.InnerText;
inventorList.Add(inventor);
}
if (bClassification)
{
string classification = node.InnerText;
classificationList.Add(classification);
}
}

C# How to set a NewLine in Label.text for a CartItem[]?

How to set a NewLine in Label.text for a CartItem[]? Environment.NewLine or \r\n does not work.
CartItem[] items = Profile.Cart.GetItems();
foreach (CartItem i in items)
Label4.Text += i.curDvd.Title + ",$" + i.curDvd.UnitPrice + "*" + i.Quantity + System.Environment.NewLine+"\r\n";
It can display everything in 1 line, but tried \r\n and Enviroment.NewLine, nothing changed.
Why?
Have you tried using more than one "\n" ?
In a web application you should use <br/> if you want new line. Unfortunately you cannot use a label in this case as it will automatically HTML encode the text. You could use a repeater at the place of this label:
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<%# Eval("Title") %>, $<%# Eval("Price") %>
<br/>
</ItemTemplate>
</asp:Repeater>
and in your code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CartItem[] items = Profile.Cart.GetItems();
rep.DataSource = items.Select(x => new
{
Title = x.curDvd.Title,
Price = x.curDvd.UnitPrice * x.Quantity
});
rep.DataBind();
}
}
Another possible template is to use divs:
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<div><%# Eval("Title") %>, $<%# Eval("Price") %></div>
</ItemTemplate>
</asp:Repeater>

Sharepoint InputFormTextBox not working on updatepanel?

I have two panels in update panel. In panel1, there is button. If I click, Panel1 will be visible =false and Panel2 will be visible=true. In Panel2, I placed SharePoint:InPutFormTextBox. It not rendering HTML toolbar and showing like below image.
<SharePoint:InputFormTextBox runat="server" ID="txtSummary" ValidationGroup="CreateCase" Rows="8" Columns="80" RichText="true" RichTextMode="Compatible" AllowHyperlink="true" TextMode="MultiLine" />
http://i700.photobucket.com/albums/ww5/vsrikanth/careersummary-1.jpg
SharePoint rich text fields start out as text areas, and some javascript in the page load event replaces them with a different control if you are using a supported browser.
With an update panel, the page isn't being loaded, so that script never gets called.
Try hiding the section using css/javascript rather than the server side visible property. That generally lets you make whatever changes you need to the form without sharepoint seeing any changes.
<SharePoint:InputFormTextBox ID="tbComment" CssClass="sp-comment-textarea" runat="server" TextMode="MultiLine" RichText="True"></SharePoint:InputFormTextBox>
<%--textbox for temporay focus - trick the IE behavior on partial submit--%>
<input type="text" id="<%= tbComment.ClientID %>_hiddenFocusInput_" style="width: 0px; height: 0px; position: absolute; top: -3000px;" />
<%--tricking code that makes the 'SharePoint:InputFormTextBox' to work correctly in udate panel on partial podtback--%>
<script id="<%= tbComment.ClientID %>_InputFormTextBoxAfterScript" type="text/javascript">
(function () {
// where possible rich textbox only
if (browseris.ie5up && (browseris.win32 || browseris.win64bit) && !IsAccessibilityFeatureEnabled()) {
// find this script element
var me = document.getElementById("<%= tbComment.ClientID %>_InputFormTextBoxAfterScript");
if (me) {
// search for script block of the rich textbox initialization
var scriptElement = me.previousSibling;
while (scriptElement && (scriptElement.nodeType != 1 || scriptElement.tagName.toLowerCase() != "script")) {
scriptElement = scriptElement.previousSibling;
}
// get the content of the found script block
var innerContent = scriptElement.text;
if (typeof innerContent == 'undefined') {
innerContent = scriptElement.innerHTML
}
// get text with function call that initializes the rich textbox
var callInitString = "";
innerContent.toString().replace(/(RTE_ConvertTextAreaToRichEdit\([^\)]+\))/ig, function (p0, p1) { callInitString = p1; });
// register on page load (partial updates also)
Sys.Application.add_load(function (sender, args) {
setTimeout(function () {
// get the toolbar of the rich textbox
var toolbar = $get("<%= tbComment.ClientID %>_toolbar");
// if not found then we should run initialization
if (!toolbar) {
// move focus to the hidden input
$get("<%= tbComment.ClientID %>_hiddenFocusInput_").focus();
// reset some global variables of the SharePoint rich textbox
window.g_aToolBarButtons = null;
window.g_fRTEFirstTimeGenerateCalled = true;
window.g_oExtendedRichTextSupport = null;
parent.g_oExtendedRichTextSupport = null;
// call the initialization code
eval(callInitString);
setTimeout(function () {
// call 'onload' code of the rich textbox
eval("RTE_TextAreaWindow_OnLoad('<%= tbComment.ClientID %>');");
}, 0);
}
}, 0);
});
}
}
})();
</script>

Resources