Adding a sliding menu to your Bootstrap Application Layout control

Introduction

Since responsive webdesign (RWD) is on top of the list in most application development projects these days I assume most of us have been looking at the options within IBM Notes.

Bootstrap

In case you use the Bootstrap plugin in the Extension Library you have noticed that the menu in the left column get presented above the main column in smaller devices.

bs_desktop

Image: Display on desktop

bs_phone

Image: Display on phone

As you can see in a more advanced application the menu options already suppress the content too much at the bottom. So what are your options?

Off Canvas Slide Menu For Bootstrap

In this post I will describe how I implemented in XPages a slide menu which is described here. We still use the Application Layout control with the Bootstrap RWD functionality since it contains more functionality than just to provide a navbar.

Step 1 – Provide a Menu icon

We need something (text, button, icon) from where we can initiate the appearance of the menu. In our case I choose to include a ‘hamburger’ menu icon in the navBarLogo property:

<xe:this.configuration>
<xe:simpleResponsiveConfiguration navbar=”true”
loaded=”true” navbarLogo=”/1432224591_menu-alt.png”
navbarLogoStyleClass=”extraMenu” navbarText=”MyApp”>
</xe:simpleResponsiveConfiguration>
</xe:this.configuration>

For example iconfinder provide great icons.

Step 2 – Register Click event for Menu icon

I included “extraMenu” as an additional styleclass. This styleclass we will use when the document is ready. We do this in a Script Block control:

<xp:scriptBlock id=”onLoadScript” type=”text/javascript”>

<xp:this.value><![CDATA[
$(document).ready(function(){
$(“.extraMenu“).attr(“id”,”nav-expander“);
//Navigation Menu Slider
$(‘#nav-expander‘).on(‘click‘,function(e){
e.preventDefault();
$(‘body’).toggleClass(‘nav-expanded’);
});
$(‘#nav-close’).on(‘click’,function(e){
e.preventDefault();
$(‘body’).removeClass(‘nav-expanded’);
});

// Initialize navgoco with default options
$(“.main-menu”).navgoco({
caret: ‘<span class=”caret”></span>’,
accordion: false,
openClass: ‘open’,
save: true,
cookie: {
name: ‘navgoco’,
expires: false,
path: ‘/’
},
slide: {
duration: 300,
easing: ‘swing’
}
});
});]]></xp:this.value>
</xp:scriptBlock>

When the document is ready we assign the ID attribute to the navbarLogo since this ID is used to bind an click event on. We could have bind the event directly on the class but I am not sure if the ID is used in any other way (don’t break what isn’t broken).

Step 3 – Provide a menu that slides in.

In this example I simply provide the menu that is used in the demo:

<nav>
<ul class=”list-unstyled main-menu”>
<!–Include your navigation here–>
<li class=”text-right”>
<a href=”#” id=”nav-close”>X</a>
</li>
<li><a href=”#”>Menu One<span class=”icon”></span></a></li>
<li><a href=”#”>Menu Two<span class=”icon”></span></a></li>
<li><a href=”#”>Menu Three<span class=”icon”></span></a></li>
<li>
<a href=”#”>Dropdown</a>
<ul class=”list-unstyled”>
<li class=”sub-nav”><a href=”#”>Sub Menu One<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Two<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Three<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Four<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Five<span class=”icon”></span></a></li>
</ul>
</li>
<li><a href=”#”>Menu Four<span class=”icon”></span></a></li>
<li><a href=”#”>Menu Five<span class=”icon”></span></a></li>
</ul>
</nav>

Step 4 – Include the supporting files

The demo uses the following files which you should add to your application as resources:

js

<script
src=”/jquery.navgoco.js”>
</script>

css

<xp:this.resources>
<xp:styleSheet href=”/main.css”></xp:styleSheet>
</xp:this.resources>

The result

The image below gives you an indication what the result looks like. When you click the hamburger icon the menu appears from the right. With the X marker you can close the menu again.

result

Notice that my content is not suppressed below the menu as the Bootstrap plugin would do.

Download

An demo XPages application is available on my dropbox account

Advertisements

Adding search to our app

Introduction

In this post I will demonstrate how to apply a search to our application described in previous posts, in which we read the JSON from Domino Access Service and parse it with the Jackson library to display it thereafter with a Repeat control.

Since I am using in our application the Application Layout control with a responsive Bootstrap UI (shameless pitch to glory the persons who delivered this great functionality to XPages) which includes a searchBar section and scrolling through 40K of person records is not something you want to anguish your thumb with, a search functionality gives the advantage to skip scrolling through unnecessary documents.

searchBar section

Here is how I set up the searchBar section in the Application Layout control:

searchbar

As you can see I have defined a result page for the search, called search.xsp.

Here is how the search bar will look like for the user:

searchbox

XPage search

beforePageLoad event

The beforePageLoad event has slightly changed compared with event in our initial XPage. This time we search for the search parameter defined in the searchBar section:

var query = context.getUrlParameter(“search”);
var persons = new Array();
persons = personsBean.getPersons(“http://dev1/fakenames40k.nsf/api/data/collections/name/people?count=25&search=” + query);
viewScope.put(“names”,persons);

Next is the result list. I have added an additional list item and added the active class:

This item will display the search query we have provided:

acgtive

The Repeat control has also changed slighty. The rows property has been adjusted. We calculate the number of documents returned by the full text search.

<![CDATA[#{javascript:database.updateFTIndex(true);
var query:string = context.getUrlParameter(“search”);
var vw:NotesView = database.getView(“people”);
var totNums:Integer = vw.FTSearch(query).toFixed();
return totNums}]]>

Also the text that indicates where we are in the result set has been modified:

Tip: since we are actually performing FT searches here perhaps it is better to put the counted results already from our initial call in a scope variable and re-use it =(

The button in our infinite scroll function/custom control has also been adapted. Here is the code:

Here is what the end result looks like after a search:

endresult

Delivering responsive web design in IBM Notes applications

The following is a re-post I originally posted on Infoware’s blog: link.

Introduction

Responsive web design (RWD) has been the talk of town the last years. In 2012 it was listed as #2 in ‘Top Web Design Trends’ by .net magazine and Mashable called 2013 the ‘Year of Responsive Web Design’. Many other sources have recommended responsive design as a cost-effective alternative to mobile applications.

responsive

While I assume that a large portion of the internet (and in some cases intranet) sites are nowadays optimized for the device that accesses them, but what about your company’s (internal) business applications? 

Business value

IT departments need to prioritize their activities and internal applications are most often accessed by a smaller audience than external applications. Historically the internal app was accessed with a desktop computer. With the trend of smartphones and tablets taking over the workspace this may no longer be the case in your company?

With a VPN connection users want to continue to execute their work on this new breed of devices, instead starting up a desktop computer for a single task. Here is where the business value of RWD comes in.

Continue to work on same device = More productive employees = Saving time and perhaps even hardware

Mobile first

A trend is to apply the progressive application strategy of ‘Mobile first’. Instead of designing a complex application for desktop computers first and thereafter gracefully degrade it for mobile devices, the user interface is initially designed for mobile devices and enhanced for desktops with more processing power.

mobile-first-icons

 

Many RWD frameworks embrace this ‘Mobile first’ concept nowadays.

Options in Notes

So what are your options in delivering RWD in your beloved Notes applications? Depending on your roadmap for the platform and personal preferences you have the following options.

  1. Build the application with XPages technologies.
  2. Build the application with common web technologies.

The XPages way

An approach for your Notes platform that is highly promoted by IBM is to deliver web interfaces for Notes applications with XPages. Not only bring you in Rapid Application Development (RAD) principles in your project also the range of capabilities is much more diverse.

Another benefit is that you can stay on the core technologies: JSF, JavaScript and Java. This you can combine with common web technologies like AJAX, HTML5, CSS and REST services. For the RWD you can use your favorite framework such as Bootstrap or Foundation.

Bootstrap framework

twitter-bootstrap

Bootstrap is a popular framework for developing responsive, mobile first projects on the web. It makes front-end web development faster and easier. Bootstrap is based upon HTML, CSS and JavaScript, technologies already well-known in Notes web apps.

Distribution

You have several options how you distribute the Bootstrap framework to your audience:

  1. Install the files on your Domino server.
  2. Embed the files in a Notes application.
  3. Install an additional XSP library on your Domino server.
  4. Install the latest extension library on your Domino server.

In case you do not utilize the OSGi runtime on your Domino server you can either install the files on centrally on the Domino server or embed the files in each Notes application. The installation on the Domino server makes the distribution of updates easier but the administrator is responsible for the distribution across servers. Embedding the files in a Notes application is less efficient (e.g. caching) but makes distribution of updates a task for the developer.

Probably the best approach would be to utilize the OSGi runtime on your Domino server and distribute the files as a library via an Update site Notes application across your servers. This makes the task even simple and small for an administrator.

If you choose to do so you have the option to either install bootstrap4xpages library as a separate library or you can install the latest extension library (from 10 november 2014). The latter give you several benefits:

  • Custom renderer for the Application Layout control, which makes it easy to define the layout structure of your application.
    • This renderer gives the control a Bootstrap look & feel, as well making the control responsive.
  • A newer version of jQuery.
  • Latest Bootstrap themes (3.2.0 normal or flat).
  • Additional configuration options in the Application Layout control wizard for the Bootstrap navigation components.

Separate Mobile devices UI alternative

The extension library (a library with additional XPages controls and functions) provides also so-called ‘Mobile controls’ which allow you to deliver a separate interface for mobile devices for your Notes apps. Via a wizard you can build a ‘single page application’ in a matter of minutes with full CRUD (create, read, update and delete) operations and infinite scrolling through document lists (aka views).

This approach does not deliver RWD but a separate user interface for mobile devices. At least it gives you the option to deliver a UI adapted for mobile devices in a very short time with little investment.

You can choose to make the UI of the app look like a native app for iPhone or Android. Alternatively you can choose to make the UI look in line with other IBM products (iNotes, Connections). A video that demonstrates the controls briefly you can find here: http://vimeo.com/99537780.

The WEB way

In case you do not walk the XPages path but instead you prefer the approach to deliver the application with more common web technologies like HTML, CSS, AJAX and REST services you can still install the files of your responsive web design framework of choice on the Domino server or embed them in a Notes application.

From there you can start to (re)write your ‘traditional’ Domino application as a Web project. In the latter case you use Notes only as a container for your data documents and design elements and use forms and views only as data schemes.

This approach dodges the RAD capabilities in Notes and will demand more development time. But you can apply this approach also to other platforms that you may have. You can later even debate why the data should be stored in Notes and not in a document-oriented database alternative? The layered security and replication capabilities are often good arguments.

Implementing RWD via the Extension Library option

In the following scenario we will describe the implementation of RWD with the Extension Library more in details.

  • Database enablement.
  • Application Layout.

Database enablement

Assuming you have installed the extensions for the Domino server and Domino Designer (DDE) client according the instructions in the readme.pdf file you can now enable a Notes application.

XSP properties

The XSP properties file allows you to configure parameters for the XPages framework. Open the file in DDE.

Screenshot_1

In the General tab you have now two more themes to select:

  • Bootstrap 3.2.0
  • Bootstrap 3.2.0 flat

The ‘flat’ theme delivers:

  • The resources and styling that comes with Bootstrap v3.2.0.
  • jQuery v2.1.1 resources.
  • Cleanup of specific XPages controls when using Bootstrap.
  • Glyphicon halflings.
  • dbootstrap resources, which provide Bootstrap styling for Dojo controls.

The ‘ordinary’ theme provides all of the same resources as the flat theme, and includes 3D effects to buttons and some other additional styling.

Select one of the two themes:

Screenshot_2

Application layout

The RWD plugin adds a new renderer for the Application Layout control which you normally use to structure the layout of your application. This renderer gives your application layout the Bootstrap look and feel, as well as responsive behavior. When the application is rendered on a smaller screen, such as on a mobile device, it will automatically re-organize the application contents for an optimal user experience.

The control also has new configuration options. Add the Application control on a custom control and open the All Properties tab. In the basics section you can choose now the xe:bootstrapResponsiveConfiguration option:

Screenshot_3

Note: in case you have already a configured Application Layout control you can change the configuration option directly in the Source panel to keep the rest of your configuration (e.g. xe:applicationConfiguration -> xe:bootstrapResponsiveConfiguration).

This configuration options give you several more properties:

  • collapseLeftColumn
  • collapseLeftMenuLabel
  • collapaseLeftTarget
  • fixedNavbar
  • invertedNavbar
  • pageWidth

With the first 3 properties you define how the left column should behave on smaller devices (collapsed for smaller devices, display text when collapsed, item the left menu should be attached to).

You can determine the behavior of the navbar (inverted, fixed (top or bottom)) and the width of the page e.g. fluid = use Bootstrap ‘fluid’ container (almost full width).

Wizard

When you initially drag on the Application Layout control on the custom control a two-step wizard is presented. In the first step you select one of available configurations. You can filter on responsive and non-responsive.

Screenshot_4

In the second you set the properties for the chosen configuration. In case you choose the Responsive Bootstrap option you will see the following screen:

Screenshot_5

Under configuration you can set the properties for the layout including the 6 additional properties mentioned earlier. Set also the other properties like you would normally do.

Voila! Your application is now ready for development.

Hiding elements for specific devices

The plugin provides only the resources and structure for responsive web design. In case you want to optimize the layout for devices by explicitly show or hide them you can use CSS classes.

Bootstrap provides some handful helper classes, for faster mobile-friendly development. These can be used for showing and hiding content by device via media query combined with large, small, and medium devices.

Classes Devices
.visible-xs Extra small (less than 768px) visible
.visible-sm Small (up to 768 px) visible
.visible-md Medium (768 px to 991 px) visible
.visible-lg Larger (992 px and above) visible
.hidden-xs Extra small (less than 768px) hidden
.hidden-sm Small (up to 768 px) hidden
.hidden-md Medium (768 px to 991 px) hidden
.hidden-lg Larger (992 px and above) hidden

Note that the elements that you hide are still being loaded, but simply not being displayed.

Data View control

Probably a typical use case is the display of table columns or lists. On a desktop you may want to show more columns than on a smaller devices.

Typical you use the Data View control from the extension library to display lists of documents. The information you want to display as a link is defined in the summaryColumn property.

Screenshot_6

Additional columns that are displayed on the right of the summaryColumn will be displayed via the extraColumns property. Each additional column is defined in a viewExtraColumn item which contains properties for styleClass and headerStyleClass. For example you could set these as followed:

<xe:this.extraColumns>

<xe:viewExtraColumn columnName=”Date” columnTitle=”Date” style=”width: 100px”  styleClass=” hidden-xs hidden-sm ” headerStyleClass=” hidden-xs hidden-sm“></xe:viewExtraColumn>

</xe:this.extraColumns>

This will show the extra column only for medium and larger devices since they will be hidden for (extra) small devices.

Screenshot_7

Wrap up

Delivering responsive web design on your Notes applications has never been as easy as it is nowadays with the RWD plugin in the extension library. It also respects the rapid application (web) development mantra of XPages.

In case you do decide to follow this path remember you need to check what information you want to show or hide for specific devices.

So what is keeping you from getting a bigger bang for the buck by delivering optimized user experiences for mobile, tablet and desktops for your Notes applications?

 

Navbar with dropdown menu from Notes view in Twitter Bootstrap (with XPages)

Introduction

Hey hey, sorry to bother you again with a post about using a Notes view in combination with Twitter Bootstrap.

In my previous post I was not sure about using nav-pills. I fear not all users will understand them. I assume that most users are common with a site header with navigational options. This navigation can be like tab bars (hihi watch some real old work) some with nested tabs in fancy drop down menus. Twitter Bootstrap have probably taken notice of this expected behavior and provided therefor the navbar component.

Implementation

I used the same conditions as in my previous post (Mark Leusink’s Bootstrap4XPages demo site and my Notes view:

notesview clean

 

Here is how the code on my XPage looks like:

<div class=”navbar navbar-inverse navbar-fixed-top”>
<div class=”navbar-inner”>
<div class=”container-fluid”>
<a data-target=”.nav-collapse” data-toggle=”collapse”
class=”btn btn-navbar”>
<span class=”icon-bar”></span>
<span class=”icon-bar”></span>
<span class=”icon-bar”></span>
</a>
<a href=”#” class=”brand”>
<xp:text escape=”true” id=”computedField1″ value=”#{javascript:@DbTitle()}”></xp:text></a>
<div class=”nav-collapse”>
<ul class=”nav”>
<li class=”dropdown”>
<a data-toggle=”dropdown” class=”dropdown-toggle” href=”#”>Site Index<b class=”caret”></b></a>
<xp:text escape=”false” disableTheme=”true” value=”#{javascript:getList()}” rendered=”true”></xp:text>
</li>
<li class=”active”>
<xp:link escape=”true” text=”Home” id=”link1″ value=”/index.xsp”></xp:link>
</li>
<li>
<a href=”#”>Static Link 1</a>
</li>
<li class=”divider-vertical”></li>
<li>
<a href=”#”>Static Link 2</a>
</li>
</ul>
<form action=”” class=”navbar-search pull-left”><input type=”text” placeholder=”Search” class=”search-query span2″ /></form>
<ul class=”nav pull-right”>
<li>
<a href=”#”>Static Link 3</a>
</li>
<li class=”divider-vertical”></li>
<li>
<a href=”#”>Static Link 4</a>
</li>
</ul>
</div><!– /.nav-collapse –>
</div>
</div>
</div>

Note: I had to set attributes for escape and disableTheme for the computed field otherwise the navbar would get messed up.

In the computed field I call a SSJS function that is similar to the one in the previous post:

function getList(){
var nav:NotesViewNavigator = database.getView(“$v-treeview-clean”).createViewNav();
var entry:NotesViewEntry = nav.getFirst();
if (entry !=null){
var countLevel:Integer = 0;
var curLevel:Integer;
var list = “<ul class=\”dropdown-menu\”>”;
while (entry !=null){
var edoc:NotesDocument = entry.getDocument();
entryValue = entry.getColumnValues().elementAt(1).toString();
var col:NotesDocumentCollection = edoc.getResponses();
curLevel = entry.getColumnIndentLevel();
if (col.getCount()>0){
//prep for new entry with response(s)
var difLevel = countLevel – curLevel ;
var closure = “”
for (var i=0; i<(difLevel); i++){
closure = closure + “</ul></li>”
}
list = list + closure;
list = list + “<li class=\”dropdown-submenu\”>”;
list = list + “<a href=\”#\”>” + entryValue + “</a>”;
list = list + “<ul class=\”dropdown-menu\”>”;
//increase counter
countLevel = curLevel + 1;
}
else{
if(curLevel==countLevel){
list = list + “<li><a href=\”#\”>” + entryValue + “</a></li>”;
}
else if(curLevel<countLevel){
var difLevel = countLevel – curLevel ;
var closure = “”
for (var i=0; i<(difLevel); i++){
closure = closure + “</ul></li>”
}
list = list + closure
countLevel = curLevel;
}
else {
//
}
}
var tmpentry:NotesViewEntry = nav.getNext(entry);
entry.recycle();
entry = tmpentry;
}
//final closure, last entry could be response doc
var closure = “”
for (var i=0; i<(countLevel); i++){
closure = closure + “</ul></li>”
}
list = list + closure
//closure nav nav-list
list = list + “</ul>”;
return list;
}
else{
return “no documents found”;
}
}

C’est tout!

Result

Here is how the result looks like for desktop:

navbar

 

Reflections

Not bad for something “out of the box”!

I placed the “Site Index” at the beginning because it appears that the expanding of the nested lists continues to the right, even when it has reached the end of your screen 😕 There is the option to set the class for nested list to dropdown-submenu pull-left but I think it will be odd if you collapse one level open to the right and the next to the left.

Mobile users

Mobile users will find it difficult accessing the nested lists as the following image demonstrates:

mobilenavbar

 

Only the first 7 entries seem to become displayed, so when you open nested lists the items below just get pushed away. Luckily they return when you close the nested lists.

Alternative

The options for providing deep-level navigation seem to be a bit limited in Twitter Bootstrap. an alternative might be a collapsible tree menu for TB which you can find an example described here.

Job Wanted

Looking for a creative brain? Choose me!

job-wanted

CALENDARIO: A responsive calendar plugin

Calendars can be a very tricky thing when it comes to their layout and responsiveness. Calendrio is a jQuery plugin to display a calendar layout for both, small and big screens and keeping the calendar structure fluid when possible.

Here follows a brief description how you can utilize the plugin in your IBM Notes – XPages application.

Resources

Copy the resources to the WebContent folder via the Package Explorer:

webfolder

Calendar display

Next I created an XPage to display the calendar:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xp:view xmlns:xp=”http://www.ibm.com/xsp/core&#8221;
pageTitle=”Responsive Calendar with calendario.js”
createForm=”false”>
<!–[if IE 9]><html class=”no-js ie9″><![endif]–>
<!–[if gt IE 9]><!–>
<xp:this.resources>
<xp:metaData name=”charset” content=”utf-8″></xp:metaData>
<xp:metaData name=”http-equiv” content=”IE=edge,chrome=1″></xp:metaData>
<xp:metaData name=”viewport” content=”width=device-width, initial-scale=1.0″></xp:metaData>
<xp:script src=”scripts/modernizr.custom.63321.js” clientSide=”true”></xp:script>
<xp:script src=”http://code.jquery.com/jquery-1.9.1.min.js&#8221; clientSide=”true”></xp:script>
<xp:script src=”http://code.jquery.com/jquery-migrate-1.1.1.min.js&#8221; clientSide=”true”></xp:script>
<xp:script src=”scripts/jquery.calendario.js” clientSide=”true”></xp:script>
<xp:script src=”data.xsp” clientSide=”true”></xp:script>
<xp:linkResource href=”styles/screen.css” rel=”stylesheet” media=”all” target=”_self” charset=”UTF-8″></xp:linkResource>
</xp:this.resources>
<html class=”no-js”><!–<![endif]–>
<script type=”text/javascript”>
$(document).ready(function(){ var cal = $( ‘#calendar’).calendario( { onDayClick : function( $el, $contentEl,
dateProperties ) {
for( var key in dateProperties ) { console.log( key + ‘ = ‘ + dateProperties[ key ] ); }}, caldata : webdesigner } ), $month = $( ‘#custom-month’).html( cal.getMonthName() ), $year = $( ‘#custom-year’).html( cal.getYear() );
$( ‘#custom-next’ ).on( ‘click’, function() {
cal.gotoNextMonth( updateMonthYear ); } ); $( ‘#custom-prev’).on( ‘click’, function() { cal.gotoPreviousMonth(updateMonthYear ); } ); $( ‘#custom-current’ ).on( ‘click’,function() { cal.gotoNow( updateMonthYear ); } );
function updateMonthYear() { $month.html( cal.getMonthName()); $year.html( cal.getYear() ); }
});
</script>
<body>
<div class=”container”>
<div class=”custom-calendar-wrap custom-calendar-full”>
<div class=”custom-header clearfix”>
<h2>Responsive Calendar</h2>
<h3 class=”custom-month-year”>
<span id=”custom-month” class=”custom-month”></span>
<span id=”custom-year” class=”custom-year”></span>
<nav>
<span id=”custom-prev” class=”custom-prev”></span>
<span id=”custom-next” class=”custom-next”></span>
<span id=”custom-current” class=”custom-current” title=”Got to current date”></span>
</nav>
</h3>
</div>
<div id=”calendar” class=”fc-calendar-container”></div>
</div>
</div><!– /container –>
</body>
</html>
</xp:view>

Data

To create content for the data I created a Notes form with 2 fields: date and title. Also create a Notes view that is sorted by the date field.

To collect the data for the calendar.xsp create another XPage that will behave like an “XAgent”:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xp:view xmlns:xp=”http://www.ibm.com/xsp/core&#8221; rendered=”false” viewState=”false”>
<xp:this.afterRenderResponse><![CDATA[#{javascript:
var externalContext = facesContext.getExternalContext();
var response = externalContext.getResponse();
var writer = response.getWriter();

response.setContentType(“application/javascript”);
response.setHeader(“Cache-Control”, “no-cache”);
var v:NotesView = database.getView(“entries”);
v.AutoUpdate = false;
var viewData = “var webdesigner = {“;
if (v.getEntryCount() != 0){
var vDoc:NotesDocument = v.getFirstDocument();
while (vDoc != null){
var nextvDoc:NotesDocument = v.getNextDocument(vDoc);

//viewDataDT:NotesDateTime = session.createDateTime(vDoc.getItemValueDateTimeArray(“date”));
//viewDataDT = vDoc.getItemValueDateTimeArray(“date”);
//viewData = viewData + viewDataDT.getDateOnly();
var dt:NotesDateTime = vDoc.getItemValueDateTimeArray(“date”).elementAt(0);
var day = @Day(dt.getDateOnly());
var str = “” + day;
var pad = “00”
var day = pad.substring(0, pad.length – str.length) + str;

var month = @Month(dt.getDateOnly());
var str = “” + month;
var pad = “00”
var month = pad.substring(0, pad.length – str.length) + str;
var year = @Year(dt.getDateOnly());
var cDate = month + “-” + day + “-” + year;

viewData = viewData + “‘” + cDate + “‘ : “;
var title = vDoc.getItemValueString(“title”);

viewData = viewData + “‘<a href=\”” + “entry.xsp?documentId=”+ vDoc.getUniversalID() + “\”>” + title + “</a>’,”;
vDoc.recycle();
var vDoc:NotesDocument = nextvDoc;
}
viewData = @LeftBack(viewData,1);
}
viewData = viewData + “};”;
writer.write( viewData);
writer.endDocument();
facesContext.responseComplete();
}]]></xp:this.afterRenderResponse>

</xp:view>

Result

Open the calendar.xsp. In small screen it should look like:

small

For larger screens (tablets/desktop) the calendar should look like:

large

Not bad ain’t it? I am not sure how responsive iNotes 9 is, my 8.5.3 version could use some.

Demo download

I have uploaded a sample database which can be found here.

Also look at the following site to read the options for this interesting jQuery plugin:

http://tympanus.net/codrops/2012/11/27/calendario-a-flexible-calendar-plugin/

Job Wanted

Looking for a creative brain? Try me!

job-wanted

jQuery Mobile 1.3 Panel Widget XPages demo (for download)

The last couple of days I have been ‘playing’ with jQuery Mobile and mostly with the panel widget.

I have made some kind of starter-kit (NSF) to build a great XPages app for tablets/smartphones. I have setup a subset of custom controls which accept properties. A simple form in Notes you can use to setup navigation for header, footer and a vertical menu.

You can download the (zipped) NSF on Dropbox.

Below you can see a sample result:

panelinxpages

Please let me know if you experience any problems or if you have suggestions for improvement. Happy coding!

jQuery Mobile in XPages- Panel Widget

jQuery Mobile 1.3 is recently released. This release is focused on elevating responsive web design (RWD) and brings lots of cool new widgets including panels, dual handle range sliders, and two different responsive table modes.

Panel widget

One of the most common mobile UI patterns you see today are Facebook-style panels that open to reveal a menu, form or other content.

The flexible panel widget  allows panels to be positioned on the left or right of the screen. To take this widget responsive, it’s easy to add media queries to make the panel stay open at wider widths instead of auto-closing when you click on the page content. A great demo can be found here.

Currently I am working on a sort of development template that will allow to quickly build an XPages app using the panel widget.

I noticed however some steps you need to take to prepare your XPage application:

  • xsp.html.doctype=html in the xsp properties file sets your doctype.
  • xsp.theme=<empty> in the xsp properties files disables server default theming.
  • createForm=”false” in the XPage will not create the form element. This is important otherwise your relative links will not work.

Below is a sample code you can copy & paste in your XPage to get started:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xp:view xmlns:xp=”http://www.ibm.com/xsp/core&#8221; createForm=”false”>
<head>
<meta charset=”utf-8″ />
<meta name=”viewport”
content=”width=device-width, initial-scale=1″ />
<title>Panel fixed positioning – jQuery Mobile Demos</title>
<link rel=”stylesheet”
href=”http://view.jquerymobile.com/1.3.0/css/themes/default/jquery.mobile.css&#8221; />
<link rel=”stylesheet”
href=”http://view.jquerymobile.com/1.3.0/docs/_assets/css/jqm-demos.css&#8221; />
<link rel=”shortcut icon”
href=”http://view.jquerymobile.com/1.3.0/docs/favicon.ico&#8221; />
<link rel=”stylesheet”
href=”http://fonts.googleapis.com/css?family=Open+Sans:300,400,700&#8243; />
<script src=”http://view.jquerymobile.com/1.3.0/js/jquery.js&#8221; />
<script
src=”http://view.jquerymobile.com/1.3.0/docs/_assets/js/&#8221; />
<script src=”http://view.jquerymobile.com/1.3.0/js/&#8221; />
<style>
.nav-search .ui-btn-up-a { background-image:none;
background-color:#333333; } .nav-search .ui-btn-inner {
border-top: 1px solid #888; border-color: rgba(255, 255,
255, .1); } .nav-search .ui-btn.ui-first-child {
border-top-width: 0; background: #111; } .userform {
padding: .8em 1.2em; } .userform h2 { color: #555; margin:
0.3em 0 .8em 0; padding-bottom: .5em; border-bottom: 1px
solid rgba(0,0,0,.1); } .userform label { display: block;
margin-top: 1.2em; } .switch .ui-slider-switch { width:
6.5em !important; } .ui-grid-a { margin-top: 1em;
padding-top: .8em; margin-top: 1.4em; border-top: 1px solid
rgba(0,0,0,.1); }
</style>
</head>
<body>
<div data-role=”page” class=”jqm-demos ui-responsive-panel”
id=”panel-fixed-page1″>
<div data-role=”header” data-theme=”f”
data-position=”fixed”>
<h1>Fixed header</h1>
<a href=”#nav-panel” data-icon=”bars”
data-iconpos=”notext”>
Menu
</a>
<a href=”#add-form” data-icon=”plus”
data-iconpos=”notext”>
Add
</a>
</div><!– /header –>

<div data-role=”content” class=”jqm-content”>
<h1>Panel</h1>
<h2>Fixed positioning</h2>
<p>
This is a typical page that has two buttons in the
header bar that open panels. The left button opens a
left menu with the reveal display mode. The right
button opens a form in a right overlay panel. We
also set position fixed for the header and footer on
this page.
</p>
<p>
The left panel contains a long menu to demonstrate
that the framework will check the panel contents
height and unfixes the panel so its content can be
scrolled.
</p>
<h2>Responsive</h2>
<p>
To make this responsive, the panel stays open and
causes the page to re-flow at wider widths. This
allows both the menu and page to be used together
when more space is available. This behavior is
controlled by CSS media queries. You can create a
custom one for a specific breakpoint or use the
breakpoint preset by adding the
<code>class=”ui-responsive-panel”</code>
to the page container. We have added this class on
this demo page.
</p>

<a href=”./” class=”jqm-button” data-ajax=”false”
data-role=”button” data-mini=”true” data-inline=”true”
data-icon=”arrow-l” data-iconpos=”left”>
Back to Panels
</a>

<div data-demo-html=”#panel-fixed-page1″
data-demo-css=”true” />
<!–/demo-html –>

</div><!– /content –>

<div data-role=”footer” data-position=”fixed”
data-theme=”f”>
<h4>Fixed footer</h4>
</div><!– /footer –>

<div data-role=”panel” data-position-fixed=”true”
data-theme=”a” id=”nav-panel”>
<ul data-role=”listview” data-theme=”a”
class=”nav-search”>
<li data-icon=”delete”>
<a href=”#” data-rel=”close”>Close menu</a>
</li>
<li>
<a href=”#panel-fixed-page2″>Accessibility</a>
</li>
<li>
<a href=”#panel-fixed-page2″>Accordions</a>
</li>
</ul>
</div><!– /panel –>

<div data-role=”panel” data-position=”right”
data-position-fixed=”true” data-display=”overlay” data-theme=”b”
id=”add-form”>
<form class=”userform”>
<h2>Create new user</h2>
<label for=”name”>Name</label>
<input type=”text” name=”name” id=”name” value=””
data-clear-btn=”true” data-mini=”true” />
<label for=”email”>Email</label>
<input type=”email” name=”email” id=”status”
value=”” data-clear-btn=”true” data-mini=”true” />
<label for=”password”>Password:</label>
<input type=”password” name=”password” id=”password”
value=”” data-clear-btn=”true” autocomplete=”off”
data-mini=”true” />
<div class=”switch”>
<label for=”status”>Status</label>
<select name=”status” id=”slider”
data-role=”slider” data-mini=”true”>
<option value=”off”>Inactive</option>
<option value=”on”>Active</option>
</select>
</div>
<div class=”ui-grid-a”>
<div class=”ui-block-a”>
<a href=”#” data-rel=”close”
data-role=”button” data-theme=”c” data-mini=”true”>
Cancel
</a>
</div>
<div class=”ui-block-b”>
<a href=”#” data-rel=”close”
data-role=”button” data-theme=”b” data-mini=”true”>
Save
</a>
</div>
</div>
</form>

</div><!– /panel –>

</div><!– /page –>

<div data-role=”page” id=”panel-fixed-page2″>

<div data-role=”header” data-theme=”f”>
<h1>Landing page</h1>
</div><!– /header –>
<div data-role=”content” class=”jqm-content”>
<p>This is just a landing page.</p>
<a href=”#panel-fixed-page1″ data-role=”button”
data-inline=”true” data-mini=”true” data-icon=”back”
data-iconpos=”left”>
Back
</a>
</div><!– /content –>
</div><!– /page –>
</body>
</xp:view>