Archive | XPages RSS for this section

getFragment() Doesn’t

The XSPUrl object that you can access via the XPages context has a lot of handy methods. getFragement() isn’t one of them.

I was looking through the help documentation for XSPUrl recently and noticed that the object includes a method for getting the url fragment (i.e. the part of the URL after the hash). It was unexpected, but I figured it could be handy since I was working with some (non-XPages) tabs on pages in a recent application.

However, as shown on Dave Leedy’s helpful XPages URL Cheatsheet, getFragment() doesn’t return anything when referring to the URL gleaned from the current context!

This makes sense, as the hash is a client-side redirect and is not even sent to the server, so a server-side method wouldn’t be able to see it. But it’s included in the XPages Documentation which, hilariously, references Chris Toohey’s post about this from several years ago.

Fortunately, if you need to work with the hash, you can use client-side Javascript’s location.hash property and pass it to server-side code as needed.

Advertisements

Transferring a Bitbucket Repository

I recently needed to move control of a source control repository on Bitbucket from a personal account to a company account. Fortunately, there’s a relatively easy built-in process to transfer it between accounts. In this post, I’ll show how it’s done.

  1. Open the repository in Bitbucket
  2. Click on Settings at the bottom of the left navigation
  3. TransferBitbucket1

  4. Click on Transfer repository under General
  5. TransferBitbucket2

  6. Choose the new owner and click the Transfer Ownership button
  7. TransferBitbucket3

  8. Login to Bitbucket as with the account of the new owner
  9. Click on the user icon in the upper right and select “Inbox”
  10. TransferBitbucket4

  11. You’ll see a message with the transfer request. (It will also be e-mailed to the account owner.)
  12. TransferBitbucket5

  13. Open the message and click the link that it contains
  14. TransferBitbucket6

  15. Click the Accept button to transfer the repository
  16. TransferBitbucket7

  17. Now that the repository has been transferred, it takes you to the Access management screen so you can add users to the repository as needed.
  18. If anyone already had Source Tree set up to use the repository, they will need to update the repository settings to point to the new location.
    • If you try to commit to the original repo url, you get a 404 error when trying to push:
    • TransferBitbucket8

    • Open the repository in Source Tree
    • Click on the Settings button in the upper right hand corner (or select Repository > Repository Settings)
    • Click on the default repository to select it
    • TransferBitbucket11

    • Click the Edit button
    • Update the URL to replace the previous Bitbucket account name to the new one in two places in the URL
    • TransferBitbucket12

      TransferBitbucket13

Handling Errors in an XPages RPC Method

The Remote Service (aka xe:jsonRPCService) is an extremely useful control in XPages because it examples client- and server-side code interaction, runs asynchronously, performs well, and is easy to use. But if you don’t handle errors well, it can fail quietly and the user may never know. In this post, I’ll show how to handle client- and server-side JavaScript errors with an RPC method.

Remote Procecure Example

As a starting point, let’s look at an example of a simple RPC method that returns the date and time and displays it for the user.

RPC Control

Here’s the XPages component source:

<xe:jsonRpcService id="jsonRpcService1" serviceName="myRPCService">
  <xe:this.methods>
    <xe:remoteMethod name="myMethod" script="return myLibraryFunction();">
    </xe:remoteMethod>
  </xe:this.methods>
</xe:jsonRpcService>

The service name is myRPCService. The method, myMethod takes no parameters and just calls an SSJS library function named myLibraryFunction().

SSJS Library Function

Here’s the SSJS function that it calls:

function myLibraryFunction() {
  var d = new Date();
  return d.toLocaleString();
}
Client-Side JavaScript

Here’s the code that calls the RPC method:

myRPCService.myMethod().addCallback(function (response) {
  alert('response: ' + response);
})

It calls the method in the RPC service and attaches a callback function to wait for the response. It then displays the response to the user in an alert.

RPC Error Handling - A

Handling Client-Side Errors

This works well and RPC functionality is awesome, but you have to be careful about how you handle errors.

Take for example, this problematic update. This code ignores the response, but tries to display an invalid value (an undeclared variable) in an alert.

myRPCService.myMethod().addCallback(function (response) {
  console.log('before');
  alert ('Invalid variable: ' + myUndeclaredVariable);
  console.log('after');
})

When you run the code, it appears that nothing happens. The console shows the ‘before’ statement, but it then fails quietly.

Putting a try-catch block around it like this doesn’t help at all.

try {
  myRPCService.myMethod().addCallback(function (response) {
    console.log('before');
    alert ('Invalid variable: ' + myUndeclaredVariable);
    console.log('after');
  })
} catch (e) {
	alert('Error: ' + e.toString());
}

This may seem a bit confusing, but it actually makes sense. The callback effectively runs in its own scope, so the error handling needs to be within the callback in order to fire when dealing with an RPC call.

This code does the trick:

myRPCService.myMethod().addCallback(function (response) {
  try {
    console.log('before');
    alert ('Invalid variable: ' + myUndeclaredVariable);
    console.log('after');
  } catch (e) {
    alert('Error: ' + e.toString());
  }
})

RPC Error Handling - B

Handling Server-Side Errors

If there’s an unhandled exception on the server-side code that runs (such as an error or forgetting to return a response), it also fails quietly, although it will show a few errors in the browser console.

RPC Error Handling - C

If you expand the POST, you’ll see that it returns a stack trace for an RPC error.

In this case, error handling in the client-side callback function doesn’t help at all, so it’s important to handle the error in the server-side code and return something that the callback can deal with.

function myLibraryFunction() {
  try {
    print (myUndeclaredVariable);
    var d = new Date();
    return d.toLocaleString();	
  } catch (e) {
    return 'Error: ' + e.toString();
  }
}

RPC Error Handling - D

Now, I’m returning a more informative message to the user about what went wrong.

I generally like to set up my server-side methods to return an object to the callback function, because that way I can add as many properties as I want in order to return all of the information that I need. I generally include a property for a boolean value for whether the method was successful and another value that contains a success or error message. In the callback, those values can be checked and appropriate action can be taken accordingly.

IBM Connect Presentation Uploaded

At Connect last week, I presented a session on using grids in XPages with Paul Calhoun. Here’s a link to the slide deck

AD-1207: The Grid, the Brad, and The Ugly: Using Grids to Improve Your Applications

Do you want better features, better performance, and a better UI in your XPages applications? Then display your data in grids instead of built-in controls. In this session, Paul and Brad will demonstrate why grids are a significant improvement in general and cover why one size does not fit all. They will review the features of commonly-used JavaScript grid frameworks (including Dojo, jQuery, Kendo UI, and Sencha) in order to help you determine which is the best fit for your applications.

Speaking at Connect

At Connect next week, I’ll be co-presenting two Best Practices sessions, one on grids in XPages with Paul Calhoun and the other on web apps and IBM Digital Experience with John Head.

AD-1207: The Grid, the Brad, and The Ugly: Using Grids to Improve Your Applications

Tuesday @ 5:15pm

Do you want better features, better performance, and a better UI in your XPages applications? Then display your data in grids instead of built-in controls. In this session, Paul and Brad will demonstrate why grids are a significant improvement in general and cover why one size does not fit all. They will review the features of commonly-used JavaScript grid frameworks (including Dojo, jQuery, Kendo UI, and Sencha) in order to help you determine which is the best fit for your applications.

 

AD-1539: Bringing Your Web Apps to IBM Digital Experience

Tuesay @ 10:45am

For too long, WebSphere portal has been seen as the realm of the back end developer with specialized Java skills. This has been a barrier to entry to the IBM Domino community. IBM has transformed the product to the IBM Digital Experience platform – and it’s not just a name change! With the inclusion of the Script Portlet & IBM Portal on Cloud option, it’s time to look again. We will show you how to integrate your XPages applications, Bluemix and even Microsoft SharePoint. We will show content re-purpose without migration. If you are looking for a single point of integration for all your apps, this session is for you!

 

Hope to see you there!

Domino Designer Tip – RegEx Searching for a String with Single or Double Quotes

If you’re looking for a string value in code throughout your application, it can sometimes be frustrating to weed through extraneous results. If you know the exact string, you can make the search more efficient by including the quotes in the search. However, if you’re working on someone else’s (because you would never do that) application where there’s inconsistent usage of single and double quotes throughout the code, you either have to search twice or you may miss some results. In this post, I’ll show how to do a single search to find all instances in single or double quotes.

Example

Here’s a bad example that I can easily use as a straw man to illustrate the point.

I created an empty NSF and added two script libraries.

One has this line:
var x = 'doc';

The other has this line:
var x = "doc";

A search for doc (without quotes) brings back 13 results because it’s part of a bunch of words. And this is in an otherwise empty NSF.

RegexSearch_A

In order to narrow the results, I can limit the search by wrapping the search term in quotes to find only instances of the full string. In this example, I searched for "doc"

RegexSearch_B_DocDblQuotes

This search only found the instance that used double quotes, but it misses the other instance in single quotes.

RegEx to the Rescue

Fortunately, Eclipse search can handle regular expressions. (H/T to Jessie Gallagher for that tip awhile back.)

Just check the ‘Regular expression’ box and use regex syntax for finding one of multiple characters (square brackets) to build a search string that will find the value with either single or double quotes.

["']doc["']

RegEx_SearchBox

And now I get the results I was looking for, including the term in both single and double quotes.

RegexSearch_C_BothQuotes

Note: If you only know part of the term, you can use wildcards or just include the quote search on one end of the term.

Fixing the Width of a Select 2 with a Long Value in a Bootstrap Form Group or Input Group

If you have a Select2 control within a form-group or input-group div in a Bootstrap UI, a long value can cause the Select2 to grow to become wider than its container. In this post, I’ll show how to fix the issue.

The Problem with Large Values

In this demo, I have a form with two columns of fields, each within a well (which makes the container size very clear).

Select2 Long Values - A

In one field, there is a very long value. This usually isn’t an issue when you have explicit control over the options, but if you have an application where a drop-down box’s choices come from a plain text field on other documents, it’s possible.

Select2 Long Values - B

When I select the long value, it limits the amount of text displayed in the box to what will fit on one line, but it expands the size of the Select2 outside of its container.

Select2 Long Values - C

If I remove the second column of fields and re-test, it looks like the Select2 was enlarged to be the same the size as the parent container, which is too big for the area that it’s supposed to be in.

Select2 Long Values - C2

Fixing with CSS

This is a known issue with Select2 inside of a form-group or input-group within Bootstrap.

Fortunately, there’s a simple CSS fix, adapted from this post on github

.form-group .select2-container {
  position: relative;
  z-index: 2;
  float: left;
  width: 100%;
  margin-bottom: 0;
  display: table;
  table-layout: fixed;
}

If you’re using an input-group instead of a form-group, then change the first line to this:

.input-group .select2-container {

Select2 Long Values - D