Wednesday, 30 November 2016

IBM Notes FP7 IF1 now Available for Download on IBM Fix Central - Solved Problem Duplicate Attachment Icons


IBM released a new Interim Fix Pack for Notes FP7 on IBM Fix Central. The main problem that is resolved in this interim fix concerns the duplicate Attachment Icons When Using Ls Embedobject To Attach Files To A NotesRichTextItem (RGAUADUM59). This was a mojor problem for a lot of IBM Notes Users.
For more information about this problem see my previous blog post IBM Notes 9 FP7 - Issue Attachments Send from Windows Explorer and Hidden Attachments Fields.

Download links: IBM Notes FP7 IF1


Tuesday, 22 November 2016

Using Bootstrap Toggle a Highly Flexible Bootstrap Plugin that Converts Checkboxes into Toggles in XPages

One of the requirements for a new XPages Project constisted of a toggle functionality for checkboxes. In my search I came across the Bootstrap Toggle Plugin, a highly flexible Bootstrap plugin that converts checkboxes into toggles. Options can be passed via data attributes or JavaScript. For data attributes, it is only necessary to append the option name to data-, as in data-on="Enabled". It is also possible to use Methods to control toggles directly. Below is an example of how the Bootstrap Toggle Plugin can be used in an XPages application.
In order to use the Bootstrap Toggle Plugin, the JavaScript and CSS file(s) need to be included on the XPage / Custom Control. The latest version can be downloaded from GitHub: Bootstrap Toggle.

Adding the JS and CSS files
The JavaScript and CSS files must be added to the WebContent Folder in the Package Explorer.
In this example a Folder bootstraptoggle has been added in the WebContent Folder.
Next the JavaScript and CSS files, bootstrap-toggle.js and bootstrap-toggle.css, must be included on the XPage or Custom Control. In this example I add the files to an XPage.

<link rel="stylesheet" href="bootstraptoggle/css/bootstrap-toggle.css" />
<script type="text/javascript" src="bootstraptoggle/js/bootstrap-toggle.js"></script>

Adding the x$ jQuery selector for XPages
Furthermore I recommend to use the the great XSnippet by Mark Roden, x$ jQuery selector for XPages, to initialize the plugin. The XSnippet can be added to the Script Libraries.

The script itself can be made up as follows. In this example I use a few Options including Font Awesome.


<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:checkBox1}" ).bootstrapToggle({
on: "<i class='fa fa-play'></i> Play",
off: "<i class='fa fa-pause'></i> Pause",
onstyle:'info',
offstyle:'danger',
size:'small'
});
})
]]></xp:this.value>
</xp:scriptBlock>

Basic Setup Checkbox
In the example below I use some data-attributes which can not be included as shorthand property in the x$ jQuery selector for XPages.

<xp:checkBox text="" id="checkBox1"
value="#{document1.FIELDNAME}" checkedValue="Yes"
uncheckedValue="No">
<xp:this.attrs>
<xp:attr name="checked" value="checked"></xp:attr>
<xp:attr name="data-onstyle" value="info"></xp:attr>
</xp:this.attrs>
</xp:checkBox>

Final Result
The final result is a responsive Bootstrap Toggle functionality with some additional options in the initial setup.


Code XPage
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<style>
.slow .toggle-group { transition: left 0.7s; -webkit-transition: left 0.7s; }
.fast .toggle-group { transition: left 0.1s; -webkit-transition: left 0.1s; }
.quick .toggle-group { transition: none; -webkit-transition: none; }
</style>
<xp:this.data>
<xp:dominoDocument var="document1" formName="Visitors"></xp:dominoDocument>
</xp:this.data>
<xp:this.resources>
<xp:script src="/JQueryXSnippet.js" clientSide="true"></xp:script>
</xp:this.resources>
<link rel="stylesheet" href="bootstraptoggle/css/bootstrap-toggle.css" />
<script type="text/javascript" src="bootstraptoggle/js/bootstrap-toggle.js"></script>
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:checkBox1}" ).bootstrapToggle({
on: "<i class='fa fa-play'></i> Play",
off: "<i class='fa fa-pause'></i> Pause",
onstyle:'info',
offstyle:'danger',
size:'small'
});
})
]]></xp:this.value>
</xp:scriptBlock>
<xp:scriptBlock id="scriptBlock2">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:checkBox2}" ).bootstrapToggle({
on: 'Yes',
off: 'No',
onstyle:'primary',
offstyle:'danger',
size:'small'
});
})
]]></xp:this.value>
</xp:scriptBlock>
<xc:ccLayout>
<xp:this.facets>
<xp:panel xp:key="facetMiddle">
<h4>Bootstrap Toggle</h4>
<h5>
Bootstrap Toggle is a highly flexible Bootstrap plugin that converts checkboxes into toggles.
</h5>
<br />
<div class="row">
<div class="col-sm-2">
<xp:checkBox text="" id="checkBox1"
value="#{document1.Video}" checkedValue="Play" uncheckedValue="Pause">
<xp:this.attrs>
<xp:attr name="data-style" value="slow"></xp:attr>
<xp:attr name="checked" value="checked"></xp:attr>
</xp:this.attrs>
</xp:checkBox>
</div>
<div class="col-sm-2">
<xp:checkBox text="" id="checkBox2"
value="#{document1.Question}" checkedValue="Yes" uncheckedValue="No" defaultChecked="true">
</xp:checkBox>
</div>
</div>
<br />
<xp:button value="Save Toggle Values" id="button1" styleClass="btn btn-primary"><xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:saveDocument var="document1"></xp:saveDocument>
<xp:openPage name="/bootstraptoggle.xsp"></xp:openPage>
</xp:actionGroup>
</xp:this.action></xp:eventHandler></xp:button>
</xp:panel>
</xp:this.facets>
</xc:ccLayout>
</xp:view>

For more information: Bootstrap Toggle Plugin

Wednesday, 16 November 2016

Tower for Windows - Version Control with Git Made Easy in a Beautiful, Efficient and Powerful App


Currently I am using SourceTree for my XPages Projects. Today I read about Tower which has finally arrived on Windows. I'm still a Windows user and not a Mac user so Tower for me was not yet available. Reading the website it seems that over 80,000 customers in companies like Google, IBM and Salesforce already have chosen Tower on the Mac. And now it is finally available on Windows. I am very curious about Tower so during the next few weeks I am going to take a look at Tower by downloading the 30 day free trail full version. Nice.


For more information about Tower for Windows, the 24-part video course, the 150-page online book, an in-depth help area and a free 30 days trail visit the Tower for Windows website.

Tuesday, 15 November 2016

Using WebUI Popover in XPages - A lightWeight jQuery Popover Plugin with some Awesome New Features

For a project I was looking for a lightweight Popover plugin with some additional options as backdrop and iframe support. In my search I came across the WebUI Popover Plugin, a lightWeight Popover Plugin using jQuery that enchances the Popover plugin of bootstrap with some awesome new features. It works well with bootstrap, but bootstrap is not necessary! In this blog post I will show how this plugin can be used in an XPages application.
In order to use the WebUI Popover Plugin, the JavaScript and CSS file(s) need to be included on the XPage / Custom Control. The latest version can be downloaded from GitHub: WebUI Popover.

Features
- Fast,lightweight
- Support more placements
- Auto caculate placement
- Close button in popover
- Multipule popovers in same page
- Different styles
- Support url and iframe
- Support async mode
- Different animations
- Support backdrop

Default options
placement:'auto' (values: auto,top,right,bottom,left,top-right,top-left,bottom-right,bottom-left,auto-top,auto-right,auto-bottom,auto-left,horizontal,vertical)
container: document.body (The container in which the popover will be added i.e. The parent scrolling area. May be a jquery object, a selector string or a HTML element.)
width:'auto' (can be set with  number)
height:'auto (can be set with  number)
trigger:'click' (values:  click,hover,manual,sticky(always show after popover is created)
selector:false (jQuery selector, if a selector is provided, popover objects will be delegated to the specified.)
style:'' (Not to be confused with inline `style=""`, adds a classname to the container for styling, prefixed by `webui-popover-`. Default '' (light theme), 'inverse' for dark theme)
animation:null (pop with animation,values: pop,fade; only take effect in the browser which support css3 transition)
delay: {show and hide delay time of the popover, works only when trigger is 'hover',the value can be number or object
show: null,
hide: 300
},
async: {
type:'GET' (ajax request method type, default is GET)
before: function(that, xhr) {} (executed before ajax request)
success: function(that, data) {} (executed after successful ajax request)
error: function(that, xhr, data) {} (executed after error ajax request)
},
cache:true (if cache is set to false,popover will destroy and recreate)
multi:false (allow other popovers in page at same time)
arrow:true (show arrow or not)
title:'' (the popover title, if title is set to empty string,title bar will auto hide)
content:'' (content of the popover,content can be function)
closeable:false (display close button or not)
direction:'' (direction of the popover content default is ltr ,values:'rtl';)
padding:true (content padding)
type:'html' (content type, values:'html','iframe','async')
url:'' (if type equals 'html', value should be jQuery selecor.  if type equels 'async' the plugin will load content by url.)
backdrop:false (if backdrop is set to true, popover will use backdrop on open)
dismissible:true (if popover can be dismissed by  outside click or escape key)
autoHide:false (automatic hide the popover by a specified timeout, the value must be false,or a number(1000 = 1s)
offsetTop:0 (offset the top of the popover)
offsetLeft:0 (offset the left of the popover)
onShow: function($element) {} (callback after show)
onHide: function($element) {} (callback after hide)

Adding the JS and CSS files
The JavaScript and CSS files must be added to the WebContent Folder in the Package Explorer.
In this example a Folder webuipopover has been added in the WebContent Folder.
Next the JavaScript and CSS files, jqueru.webui-popover.js and jquery.webui-popover.css, must be included on the XPage or Custom Control. In this example I add the files to an XPage.

<link rel="stylesheet" href="webuipopover/jquery.webui-popover.css" />
<script type="text/javascript" src="webuipopover/jquery.webui-popover.js"></script>

Adding the x$ jQuery selector for XPages
Furthermore I recommend to use the the great XSnippet by Mark Roden, x$ jQuery selector for XPages, to initialize the plugin. The XSnippet can be added to the Script Libraries.

The script itself can be made up as follows. In this example I use a few Options.

<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:button1}" ).webuiPopover({
title:'WebUI Popover',
content:'Popover trigged by mouse hover, placement right.',
trigger:'hover',
placement:'right',
closeable:true,
backdrop:false,
multi:true,
delay: {
show: 0,
hide: 9000
}
});
}
);

AMD Loader Fix
Finally, the JavaScript files jquery.webui-popover.js needs to be adjusted. Reason: newer jQuery plugins try to use its AMD loader, but that doesn't play well with the Dojo implementation in XPages. The source code of the library can be adjusted in a very simple way with just a slight modification.


1.  Go to the WebContent Folder and select the JavaScript file jquery.webui-popover.js
2. Select Open With - Client/Server JS Editor
3. Removed define.amd and replace it with false
4. Save the JavaScript file jquery.webui-popover.js

Note: There are other solutions for the AMD Fix. For more information about these solutions see my blog post Bootstrap Plugins in XPages Part VI - jQuery and JavaScript AMD (Asynchronous Module Definition) Fixes (2).

The final result is a responsive WebUI Popover with some additional functionality in the initial setup.


Code XPage
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.resources>
<xp:script src="/JQueryXSnippet.js" clientSide="true"></xp:script>
</xp:this.resources>
<link rel="stylesheet" href="webuipopover/jquery.webui-popover.css" />
<script type="text/javascript" src="webuipopover/jquery.webui-popover.js">
</script>
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:button1}" ).webuiPopover({
title:'WebUI Popover',
content:'Popover trigged by mouse hover, placement right.',
trigger:'hover',
placement:'right',
closeable:true,
backdrop:false,
multi:true,
delay: {
show: 0,
hide: 9000
}
});
}
);
]]></xp:this.value>
</xp:scriptBlock>
<xp:scriptBlock id="scriptBlock2">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:button2}" ).webuiPopover({
type:'iframe',
url: "http://sandywalker.github.io/webui-popover/demo/",
title:'WebUI Popover IFrame',
placement:'bottom-right',
multi:true,
closeable:true
});
}
);
]]></xp:this.value>
</xp:scriptBlock>
<xc:ccLayout><xp:this.facets>
<xp:panel xp:key="facetMiddle">
<h5>WebUI Popover</h5>
<h5>A lightWeight popover plugin with jquery ,enchance the popover plugin of bootstrap with some awesome new features. It works well with bootstrap ,but bootstrap is not necessary!</h5>
<br />
<div class="row">
<div class="col-sm-5">
<xp:inputText id="inputText1"></xp:inputText></div>
<div class="col-sm-2">
<xp:button value="Info" id="button1" styleClass="btn btn-info"></xp:button>
</div>
</div>
<br/>
<div class="row">
<div class="col-sm-5">
<xp:inputText id="inputText2"></xp:inputText></div>
<div class="col-sm-2">
<xp:button value="Info" id="button2" styleClass="btn btn-info"></xp:button></div>
</div>
</xp:panel>
</xp:this.facets>
</xc:ccLayout>
</xp:view>

More info and examples: WebUI Popover Dev

Monday, 14 November 2016

How To Delete Documents in a View using a LotusScript Agent


This blog post I write as a reminder to myself following a number of problems I've encountered when deleting documents in a view in which I use a LotusScript Agent. In LotusScript there are different ways to delete documents in a View using a LotusScript Agent. Below two examples to delete documents in a View using LotusScript. Both scripts work but the first method has a greater risk of errors causing the Agent to fail as I experienced myself last week.

In case the script below is used the first document  in the View is removed and in the next step the handle is refreshed by getting the first document in the view again.
This script may cause problems because the view index needs to be kept up to date while processing the script. In case the index is not kept up to date by Domino the next statement will get the same document that was just removed causing the Agent to fail as I have experienced myself this week. There is also a possibility (large amount of documents) for a view index corruption causing an infinite loop because the document can not be deleted (doc).

Set view = db.GetView("VIEWNAME")
Set doc = view.GetFirstDocument
While Not doc Is Nothing
   Call doc.Remove(True)
   Set doc = view.GetFirstDocument
Wend

The current manner I use is to get a handle to the next document in the View before the first document in the View is deleted. The View index never needs to be updated in the case because the script isn't forcing the index to be refreshed (the refresh will take place on its own schedule instead of on the script's schedule). Index corruption (large amout of documents) is also limited to a minimum.

Sub Initialize

' init
Dim s As New NotesSession
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
Dim nextdoc As NotesDocument
Dim View As NotesView
Dim agentName As String

agentName = "Delete documents from ViewName"

' Start Agent
Print "Start '" + agentName + "' ..."

' Get Database
Set db = s.CurrentDatabase

' Get View
Set view = db.GetView("VIEWNAME")
Set doc = view.GetFirstDocument
While Not doc Is Nothing
Print "Document deleted: " + doc.FIELDNAME(0)
Set nextdoc = view.GetNextDocument(doc)
Call doc.Remove(True)
Set doc = nextDoc
Wend

' Agent End
Print "End '" + agentName + "' ..."

End Sub

Another possibility is to make use of the NotesDocumentCollection class which has a 'RemoveAll' method that deletes all the documents in the collection based on a Search Formula. In case Readers or Authors fields are used the script needs to be tested because the Agent will not work in all sutuaties as I noticed during testing.

Sub Initialize

' init
Dim s As New NotesSession
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
Dim searchFormula As String
Dim agentName As String
Dim errorMsg As String

agentName = "Delete documents"

' Start Agent
Print "Start '" + agentName + "' ..."

' Get Database
Set db = s.CurrentDatabase

' Build Query
searchFormula = {(Form = "FORMNAME") &
        (FIELDNAME = "FIELDVALUE")}

' Execute Query / Get Document Collection
Set dc = db.Search(searchFormula, Nothing, 0)

' Check if documents has been found
If dc.Count > 0 Then

' Remove documents from the database
Call dc.Removeall(True)
End If

' Agent End
Print "End '" + agentName + "' ..."

End Sub

Monday, 7 November 2016

Upcoming XPages Webinar: Marty, You're Just Not Thinking Fourth Dimensionally

On December 13th a very interesting webinar will be organized by T.L.C.C and Team Studio, Marty, You're Just Not Thinking Fourth Dimensionally by IBM Champion Paul Withers. The registration for this webinar is now available on the T.L.C.C website.


Content Webinar
When XPages code doesn't work as expected it is often because the expectation was wrong. With the various phases of the XPages lifecycle, validation, the various event handler settings, embedding Server-Side JavaScript within Client-Side JavaScript or scoped variables, understanding what's really there when your code wants it is key troubleshooting XPages.
In this webinar Paul Withers will help you think fourth dimensionally to better pre-empt the outcomes and troubleshoot when things don't work out like you expect. You'll realise whether or not the bridge over Clayton...Shonash Ravine will be there to ensure your XPages make it Back to the Future.

For more information: XPages Webinar Series with TLCC and Teamstudio.

Missed a Webinar? Look here for the recorded webinars.
Below a recording of the webinar from November 3rd, The Future of Notes and Domino from IBM.



Friday, 4 November 2016

The Future of IBM Notes - IBM Domino and XPages Presented by IBM

Yesterday a very interesting webinar was organized by T.L.C.C and Team Studio, IBM Presents the IBM Notes and Domino Roadmap. For those who missed this webinar below the content, slides and video.

Content
Barry Rosen, IBM Offering Manager, and Uffe Sorensen, IBM Social Collaboration Director, reviewed the latest updates on IBM Notes and Domino as well as IBM Verse On-premises and related Cloud solutions. They discussed the future directions and support for IBM Notes and Domino and the deliverables over the next 12 to 18 months as IBM transitions to using Feature Packs for delivering future enhancements. Plus, Martin Donnelly discussed IBM's plans for XPages enhancements.