logo

Accessible Ajax With Domino Forms [ROUGH CUT]

Ajax is great. Of that there's little doubt. However, it has to be used carefully in order to be most effective. In particular we need to make sure its use does not impeed users for whom it might not work.

A lot of the projects I've been involved in recently have required a degree of accessibility built in. Rather than deny the majority of users the funkiness that using Ajax can provide I've come up with a way to use a single Domino form to provide simple functionality to both Ajax actions as well as traditional methods. This article is going to look at how I did that.

Ajax is best and most often used for the simple little tasks. For example, something like adding a vote to a poll is an ideal situation to which Ajax is suited.

Imagine you were reading a document on which a vote is being taken. It might include a Vote Here link which looks something like this:

<a href="#" onclick="doVote('yes')">Vote Here</a>

It looks innocent enough, but there's a problem with this link. Once the doVote() function has run the link will still be followed and the user will end up at reloading the page at the same URL but with an empty hash (#) at the end of it.

To prevent this the link should look like this:

<a href="#" onclick="doVote('yes'); return false;">Vote Here</a>

Now the doVote() function runs and then the click of the link is effectively cancelled by returning a false statement.

If you're going to link to JavaScript calls in the onclick event of a link. Always make sure your return false after the function call!

The link is now less prone to error but there's still a problem with it. Imagine either the doVote() function causes an error — for whatever reason — or that the user has no JavaScript capability — again, for whatever reason. What do we do now?

What I've started doing and what I propose we all do from now on is cater for all cases with a link that looks something like this:

<a href="vote?CreateDocument&vote=yes" onclick="doVote('yes'); return false;">Vote Here</a>

Now, when there's no JavaScript support or when an error occurs in the JavaScript it fails-over to a good old fashioned link. In effect the two methods do the same thing. All that the doVote() function does is POST to the "vote" form and pass same value to it. Here's what the code might look like (based on Mootools here, but would be the same when using most of the libraries):

function doVote(vote){
new Ajax(
'vote?CreateDocument',
{
method: 'post',
data: {'vote':vote, 'ajax':'true'},
onComplete:function(response){
$('vote_link').innerHTML=response;
}
}
).request();
}

We're still creating a vote "form" and passing it the vote. The only difference is that we tell the form that Ajax was used. Using the information the WQS agent of the Vote form knows whether to simply return some text to the browser or to perform a redirect.

The Vote form itself is just a place holder really. It doesn't store documents (SaveOptions="0"). All it does is capture the values passed to it and then make them easily available to the WebQuerySave agent that runs. We could pass the data straight to an agent but parsing it in LotusScript is a nightmare and it's much better to let a Form do it. As well as the data passed to it we can use the Form to compute other information such as the user name, path info etc.

Fields on the form to which data are passed are auto-filled by the POST action of the Ajax request. However, when we use a ?CreateDocument GET request we have to fill the fields ourselves. To do this we set their Default Values using @URLQueryString calls to grab data from the URL.

Taking Further

What next?

Demo Database

DEMO HERE -- Download link is on the right towards to the top.

To Do On This Article

  • Talk about side-effect of web crawlers following links like this. Rel=nofollow?

Feedback

  1. Ajax With Domino Forms Rough Cut

    Great article. You may want to correct the typo "impeed" to "impede"

    Mike.

    • avatar
    • Patrick
    • Thu 12 Jul 2007

    RE: Accessible Ajax With Domino Forms

    another "simple yet useful" tip brought to you by Jake Howlett... :D

  2. Good approach

    Good approach Jake. Graceful fail over is so important to good UI design and this is a sensible pattern for achieving that.

    As for crawlers following the link, most crawlers drop the values after the ? to avoid false submissions of data. You just need a graceful way to respond to GETs that come with no ?CreateDocument&vote=yes.

    It's worth noting - what I am describing is GOOD practice for the more well behaved crawlers. Once upon a time a poorly written crawler trawled my blog and created about 300 bogus empty comments. Input validation eventually solved that problem for me. So, hindsight, even if we assume crawlers will drop the queryparms, there may need to be some other counter measure such as a bot rule or meta tag.

  3. Close...

    But I wouldn't want a GET request to cause an action like that - I would prefer the action only be taken with a POST, so I deally you'd be using a button to cause a submit. This can complicate things, but you've even posted about it before:

    http://www.codestore.net/store.nsf/unid/BLOG-20051118?OpenDocument

      • avatar
      • Jake Howlett
      • Thu 12 Jul 2007

      Re: Close...

      I know it's not ideal and I was aware of that post when I wrote this. However it's all horses for courses isn't it. It depends where you application is going to be used and if crawlers will ever visit.

      I want to add to the demo/article a form as well as a link, which does the same thing. In the same way you can "return false" in the onclick of an <a> link you can in the onclick of an <input type="submit"> button as well. So we can use the same approach for a real form as well.

      Jake

  4. Ajax and Mac

    Jake,

    I've converted JSLister to a menu with some modifications to the the JavaScript library, the forms and the views. It works great in IE on my PC, however when I test it on my Mac using Safari it only returns 'undefined'.

    Does Safari know Ajax? ;)

  5. 555

  6. 555

  7. 555

  8. 555

  9. 555

  10. 555

  11. 555

  12. 555

  13. 555

  14. 555

  15. 555

  16. 555

  17. 555

  18. 555

  19. 555

  20. 555

  21. 555

  22. -1' OR 2+814-814-1

  23. (select(0)from(select(sleep(15)))v)/*'+(select(0)from(select(sleep(15)))v)+'"+(select(0)from(select(sleep(15)))v)+"*/

  24. -1; waitfor delay '0:0:15' --

  25. -1); waitfor delay '0:0:15' --

  26. 1 waitfor delay '0:0:15' --

  27. hcFhl51J'; waitfor delay '0:0:15' --

  28. 555*DBMS_PIPE.RECEIVE_MESSAGE(CHR(99)||CHR(99)||CHR(99),15)

  29. 555'||DBMS_PIPE.RECEIVE_MESSAGE(CHR(98)||CHR(98)||CHR(98),15)||'

  30. 1'"

  31. @@i2plT

  32. 555

  33. 555

  34. 555

  35. 555

  36. 555

  37. 555

  38. 555

  39. 555

  40. 555

  41. 555

  42. 555

  43. 555

  44. 555

  45. 555

  46. 555

  47. 555

  48. 555

  49. 555

    • avatar
    • -1 OR 2+714-714-1
    • Thu 22 Apr 2021

    555

  50. 555

    • avatar
    • -1 OR 2+590-590-1
    • Thu 22 Apr 2021

    555

    • avatar
    • -1' OR 2+226-226-1
    • Thu 22 Apr 2021

    555

  51. 555

    • avatar
    • -1" OR 2+928-928-1
    • Thu 22 Apr 2021

    555

    • avatar
    • if(now()
    • Thu 22 Apr 2021

    555

    • avatar
    • 0'XOR(if(now()
    • Thu 22 Apr 2021

    555

    • avatar
    • 0"XOR(if(now()
    • Thu 22 Apr 2021

    555

  52. 555

  53. 555

  54. 555

    • avatar
    • hLqFKPXY' OR 169
    • Thu 22 Apr 2021

    555

    • avatar
    • lK1IWwJ4') OR 216
    • Thu 22 Apr 2021

    555

    • avatar
    • BB6xx7dN')) OR 421
    • Thu 22 Apr 2021

    555

  55. 555

    • avatar
    • 1'"
    • Thu 22 Apr 2021

    555

    • avatar
    • 1
    • Thu 22 Apr 2021

    555

  56. 555

  57. 555

  58. 555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

  59. 555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

  60. 555

  61. 555

  62. 555

  63. 555

  64. 555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

  65. 555

  66. 555

  67. 555

    • avatar
    • wUmrLVWz
    • Thu 22 Apr 2021

    555

  68. 555

  69. 555

  70. 555

  71. 555

  72. 555

  73. 555

  74. 555

  75. 555

  76. 555

  77. 555

  78. 555

  79. 555

  80. 555

  81. 555

  82. 555

  83. 555

  84. 555

  85. 555

  86. 555

  87. 555

  88. 555

  89. 555

  90. 555

  91. 555

  92. 555

  93. 555

  94. 555

  95. 555

  96. 555

  97. 555

  98. 555

  99. 555

  100. 555

  101. 555

  102. 555

  103. 555

  104. 555

  105. 555

  106. 555

  107. 555

  108. 555

  109. 555

  110. 555

  111. 555

  112. 555

  113. 555

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


Navigate other articles in the category "Forms"

« Previous Article Next Article »
Form Validator R3.0   Cut down on all those formulae...

About This Article

Author: Jake Howlett
Category: Forms
Keywords: Ajax; Accessibilty;

Attachments

ajaxaces-v0.3.zip (124 Kbytes)

Options

View Online Demo
Feedback
Print Friendly

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »