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 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>