Showing posts with label proof-of-concept. Show all posts
Showing posts with label proof-of-concept. Show all posts

Tuesday, April 27, 2010

XPages: Server Side Event Delegation - In view edit

This is a continuation of the previous investigation into the possibilities of Server Side Event Delegation (SSED).

As I mentioned at the end of the previous blogpost, the demoapp didn't take advantage of Client Side Event Delegation (CSED). This resulted in having to create the same amount of client side event listeners as was generated by the server. If you have repeat controls/view events, this can amount to quite a bit of script tags (html to download). The event listeners themselves can take up quite a bit of memory, and may make the page act a little sluggish.

Here's the generated script tags for events in this demoapp:
XSP.addOnLoad(function() {
  XSP.attachPartial("view:_id1:eventDelegator", "view:_id1", null, "foo", ...
  XSP.attachPartial("view:_id1:peopleView:pager1__Group__lnk__1", null, ...
  XSP.attachPartial("view:_id1:peopleView:pager1__Group__lnk__2", null, ...
  XSP.attachPartial("view:_id1:peopleView:pager1__Group__lnk__3", null, ...
  XSP.attachPartial("view:_id1:peopleView:pager1__Group__lnk__4", null, ...
  XSP.attachPartial("view:_id1:peopleView:pager1__Next", ...
});

One for the global event delegator event handler, and one per link in the view pager. The view has thirty "click to edit" cells, and a couple of buttons from the previous version. Not bad. :)

The experiments into SSED is partially due to the aforementioned reasons, curiosity, and my eternal struggle to find smarter ways to work. Only time will show if it fulfills all of the above.

Since the previous experiment, the demoapp has grown a bit. I've added a couple of more class attributes:
  • delegate-click-parent: makes a component a clickable area
  • click-trigger: when parent has delegate-click-parent class/styleClass, elements with this class, when clicked, triggers the server side event delegator
  • refresh-[refreshId]: previously refresh-target-[refreshId], the target of the partial refresh
  • action-[name]: used by the server side event delegator to determine what action to take
  • data-[value]: can be used on the server side for various things. E.g. unid of a row in a view
The editable columns work like this:
The view has the delegate-click-parent class. This makes all the child elements with a class attribute of click-trigger activate the server side event delegator.

I created a custom column. This lets me put other controls into the column.

Inside the column, I put a panel, a field and a button. A cell is editable when a scoped variable containing unid is the same as the unid of the row that the cell belongs to.

The panel has a computed styleClass attribute. When the cell isn't editable, the panel acts as a click trigger. One of the class attributes is the previously mentioned data-class. This contains the unid of the row the cell belongs to. This unid is put into the previously mentioned scoped variable, making the cell editable.

The field has value="" and defaultValue="#{row.columnName}". This makes it possible to edit the field/have it take the value from the appropriate row/column. The field has a readonly attribute that's computed based upon if the cell is editable.

The button is hidden when the cell isn't editable. When clicked, it triggers a save and resets the editable row. The client side id of the button is passed along to the server. This makes it possible to get the name of the field/get the value from the params-map (contains all submitted values).

E.g.
component id of field/button -> field/button
client side id of button: view:_id1:button
client side id of field: view:_id1:field

No more than a simple replace to find the correct field name :)

That's more or less it. If this sounds like something interesting, take a look at the demoapp/code, and leave a comment if you're curious about something.

>> Download Demoapp

Share and enjoy!

Thursday, April 22, 2010

XPages: Server Side Event Delegation

Update 27.04.10: I've updated the demoapp with In View Edit functionality

While working on a view with in view edit functionality today, I was appalled over how much client side code was generated.

I guess my subconsciousness was working on the problem, as I came up with a hack that lets you delegate events, while eating dinner (almost forgot the comma). It's somewhat similar to the event delegation that you would do in a browser. The current implementation has its definite limits, but I think it's a nice proof of concept.

Without the Programmatically Triggering an XPages Server Side Event Handler from a Client Side Script article by Jeremy Hodge, I don't think I would have come up with this hack, so thank you for sharing, Jeremy!

The short and simple explanation of the hack:
A global event handler is added to the XPage:
<xp:eventHandler id="eventDelegator" event="foo"
  action="#{javascript:delegateEvent()}" submit="true" refreshMode="partial"
  refreshId="#{javascript:param.$$xspsubmitvalue}" />

I use foo as the event name, so that the generated client side event handler has no possibility of being triggered.

I've added some client side JavaScript that acts upon elements with certain class attributes.
delegate-click: Clicks on an element with this class triggers the server event handler.
refresh-target-componentId: The component id of the control that should be updated.

The code could easily be extended to handle other events. Out of curiosity, I tested onmouseover and onfocus. Both work great.

When an event is triggered, param.$$xspsubmitvalue is set to the id of the component I want to update. As you can see in the above XPages source code snippet, the refreshId of the event is computed to this value. This means that only the requested component is updated. The eventDelegator-function that is triggered by the event uses also uses this value to determine what server side action should be executed.

In the attached demoapp, a viewScope value is altered depending on the refreshId. This toggles a couple of panels, which have computed their visibility based upon the scoped variable.

As for the limitations..

The component that is the target of the refresh has to be visible, as its generated id (clientId) is necessary to get the partial update to work.

This version of the hack doesn't do much about the problem of a lot of active event listeners for my "in view edit" problem. It only results in less generated code. To fix this, I'd have to make the client side code smarter. E.g. add client side event delegation. The container could have a delegate-child-clicks class. The children that should fire the events could have maybe have a click-trigger class. Anyways, that's for a future proof of concept.. :)

The reason I decided to post this experiment is that I hope that it can inspire other XPages developers to make something cool, as I feel Jeremy's post did for me.

Here's the demoapp for you to probe and inspect

Share and enjoy!

Wednesday, January 20, 2010

XPages: Three ways to build a search interface with "on the fly" sortable columns

While copy/paste programmers and XPages novices might get something out of this demoapp/blogpost, it's directed towards the people that want to push XPages beyond the constraints of the drag and drop interface in Domino Designer.

I detest the "need" to have a Notes view for every kind view in XPages. Recently, at work, I've been occupied mostly by creating customizable search/filtering views in XPages.

Until today, I've used a DataTable with a SSJS function as data source (returns JS-objects). The function does an FTSearch on a NotesView, and fetch precalculated JSON strings from a view column. The DataTable can be designed to use one/all fields from the json-objects. One DataTable column can have one or more values from the JSON object (e.g. dataItem.fieldName + ' ' + dataItem.fieldName2). This has the advantage of only needing a one (unsorted) column view to generate a wide array of reports.

Julian Buss seems to have been working on/pondering solutions for "on the fly" sortable searches as well. I've implemented what I think he meant in the demoapp as well. I didn't take the time to write caching algorithms for his way, using NotesViewEntryCollection. I also didn't take the time to implement descending sort. The reason I was so lazy was that I didn't like my implementation of his idea.

The last way (default choice in demoapp), and the best way I've found so far is to do FTSearch on the db. In the demoapp, I search the entire db without restricting to a form/etc. This is because I didn't find the need for restricting the search as there are only one kind of documents in the demoapp. The result from the search is a NotesDocumentCollection. The datasource is a function that accepts what I call an array of field definitions.

E.g.
var fieldDefinitons = [{
fieldName: 'someFieldName',
dataType: 'string'
},{
fieldName: 'someFormulaString',
dataType: 'date'
}]


Supported datatypes in the demoapp are string, multi-value string, date, multi-value date, number and multi-value numbers. The field definitions are parsed into a string that can be evaluated against a document (using session.evaluate). Using session.evaluate is the fastest way I know of to get multiple values out of a document. Compared to fetching precalculated JSON strings from a view, there is no discernible difference in speed when evaluating against documents in the NotesDocumentCollection.

Regarding caching, the JSON object is stored in a viewScope-variable. When the user navigates to another page, the JSON object should be recycled from what I understand of XPages/JSF. The values are only fetched from the server when the query string is changed. When the used wants to sort the view, the cached object is resorted. This results in speedy pagination/sort.

On my local computer, with 5000 items in the result-object, re-sort is done in about 100ms on the server. It probably takes 500-1000ms before the user gets what he ordered. The initial search takes 2-4 seconds (server time).

I could probably write a tiny book on the "technology"/thought/history behind this demoapp. Instead, I'll tease you with an animated gif, and let you download a demoapp (here be messy code). The demoapp is a biggie. It's a mutilated version of Jake's FakeNames application. I chose this because I wanted to test against a "big" database. This has 40k NAB Person documents.

Screenshots (animated gif):


>> Demoapp (6 MB zip)

Share and enjoy!

Friday, September 19, 2008

Processing documents by category in categorized views

Problem: How to process documents in a category (categorized view) in a simple way?

This is a problem I've heard a couple of times at work from the Notes-guys (I'm a Domino/Web-guy). I've tried a couple of approaches/googled, but found nothing. Therefore I archived this problem in my "experiment ideas"-folder.

Today I had a little time to play around, and found a very simple solution.

When you click an item in a view, a couple of properties is set in the NotesUIView. CaretNodeId points to the NoteId of the document that is selected. The gem is that when you click a category, an "invalid" NoteId is set. If you can't get a document from from the db using that NoteId, the item clicked is probably a category.

Now you know the user clicked a category.

Combining the ViewSelection-formula of the view, and the Formula-property of the first column (the column has to point to one field in the document for this to work), you have a valid search-formula for db.search.

Now you know which documents the user want.

Of course, the user don't want to modify documents by category each time they click the category. Add a button that sets an environment variable, and test for the value of that variable in the onSelect-event in the view. If you want to make available several types of action on the documents, use more values.

Now you know when/how the user wants to modify the documents

Problem solved..? :)

As always, blogposts like this are useless without a simple demoapp..
>> DemoApp

If you like/dislike this workaround/hack, please leave a comment.

Update: The onselect event is new in Notes 8. So if you're running on older versions, I guess there's no simple solution. Thanks to Theo for giving me a heads up!

Wednesday, September 10, 2008

Fun with the WebBrowserControl - DemoApp release

I think I've cleaned up the demo-app good enough now.

I added another demo, showing the browser on the onHelp event in Notes/offline Mootools accordion.

Apart from that, I've changed the way I store JS. I now store it in a page, and use the NotesNoteCollection of the db to fetch it (look in the code). This makes it easier to implement in a Template-context.

If you test the app on something else than Notes 8, I'd appreciate feedback (preferably in the comments) on the stability of the demoapp.

To test out making friends, edit a document in the DiscworldCharacters-view (make sure the HTTP-task is running). If you're running the demo on a server, edit the Add friend-button, so that the domain is correct.

The other demos are in the BrowserDemo-form.

>> The WebBrowserControl demoapp

The flash-demos are here

Update: Martin tested the app in N6.53. That makes it at least compatible with N6.5 to N8.02.

Saturday, November 3, 2007

Templating using a NotesForm

Coding templates in an agent leads to very verbose agents/a maintenance nightmare (in my opinion). Coding them in a NotesDocument makes it hard to use them in a Design-template context.

This technique has little verbosity beyond the actual code to generate HTML, and works great in a Design Template-context. It supports modularity, as each field is a potential module. Since the templates are forms, the dynamic "modules" also work in stored documents.

You can combine Java (through LS2J), formula (through Evaluate) and LS , just like you can when you're using agents for templating web-pages. If you're a Java-guy, then you probably would need a little more code (testing field names with Regular Expression) to achieve the same.

Combine this technique with @UrlQueryString in Form Formula if you want the ability to present data in several content-types.

The technique relies on Execute, a WQO-agent and field-names following a pattern. I chose Execute because it's faster than making a testing-routine for patterns. If you're planning on putting this technique to use in real applications, I suggest you use Regular Expressions, Instr, etc. to look for valid field-names, as Execute is horrible to debug.

The demo


I have one pattern that I look for in a field-name, "wqo_actonfield_". The third token (separator = "_") is the method to be executed. The rest of the tokens are ignored to allow several fields executing the same function.

You could also have the rest of the tokens being parameters for the method being executed.

For instance field named "wqo_search_google_dontpanic" -> run a function that inserts HTML with search-results into the field.

>> Demo Application.

Screenshots


WQO-agent for demo:


Form, one demoBody-field:


Result, web


Form, six demoBody-fields:


Result, web (click for full size)



As always, comments are appreciated :)

Wednesday, October 17, 2007

Keyword/Value lookup fields

I sometimes get a bit frustrated by the lack of associative arrays in the formula language (more specifically in keyword lookup-fields). I’ve thought about ways to emulate this a couple of times, but never got anywhere.

Today, I’ve come up with one way. It’s not beautiful, and one can argue that it’s bad practice.

lupField-syntax:
standard @DbLookup( .. )

Column Value-syntax:
"Error message - keyword-list not found" :
"keyword" : value
"apple" : banana;

Syntax for getting value:
lupField[ @Member( "keyword" ; lupField ) + 1 ]

Error handling
  • Error message on "keyword value not found" maintained on a column basis.
  • First item in the Column Value list should be the error message. Reason being @Member( "itemNotInList" ) = 0 (+1=1)
  • "keyword-list not found" maintained in the lookup-field.

"Advantages":
  • Put keyword/value wherever you want in the column formula
    • Great for design-templates if you want to have configuration-settings in a logical order in the lookup-column (reorder them whenever)
  • Print all settings through a simple @For-loop
  • Readable
    • @Word( settings ; "|" ; 24 )
    • versus
    • settings[ @Member( "stylesheet" ; settings) + 1 ]
  • ..?

Disadvantages:
  • Unreadable syntax for people not aware of the technique
  • ..?

>> Ugly flash-demo
>> Ugly demo-application

If any of you have an even simpler syntax/better concept, please let me know!

Sunday, September 30, 2007

PHP-like Templating in Domino

Templating may sound confusing, since "we" have Design Templates, but I believe that is what Ruby On Rails/PHP-guys call this.

Vision:
Imagine you get a XML-spec your customer want data exported in. With my method, you may just be able to copy/paste the spec into a template-document. Add field references, and you are good to go.

The same with HTML-pages. Make a static mock-up in Aptana/DreamWeaver. Paste it into your template (maybe split it into modules), add field-references, and you have a nice-loking, valid (if that's what you're aiming for) dynamic (X)HTML-page.

To make/edit the documents, you can use the notes-generated form.

The demo
I've been wanting to do this for a while, but other experiments have overshadowed this. Thanks to this post by Michel Van Der Meiren, and a couple of beers this weekend, I finally got around to making a prototype.

Since I'm lazy, I don't take the time to make data. I use the FakeNames database, kindly provided by Jake.

I think making the templates took me about an hour, including finding out the names of the fields I was going to use. Rapid deployment..

Document in it's original form:




Simple table with header-module:


>> HTML Template source

XML:


>> XML Template source

Text:

>> Text Template source

Implementation:

Getting the correct content-type
To show the documents in a template, I have a view that opens the Person-documents in a form that has the correct content-type (Form Formula). In the demo, I look for Text or XML in the @UrlQueryString( "template" ). If XML, XML-form, text, Text form, else HTML-form. On WebQueryOpen, I run the agent that applies the template to the document. It prints its output to a NotesRichTextItem.

The template-query string decides which template to show the document in.

Processing the template
I first split UnformattedText of the body-field in the template on #%, which are used to process modules, if there are any. Example of module-reference, #%header#%.

I test each item in the resulting array, item Like "*[A-Z,a-z]". This simple testing-method should work for HTML/XML, because they containt a lot of has brackets, which are not Like A-Z. With text-templates, there may occur errors using this. For more complex content, you could make a LS2J-class that enables you to do Regular Expression tests of the content.

The reason I check for modules first, is that they can contain formula-snippets and field-references, which also should be processed.

In it's current state, it doesn't support modules within modules.

Then I look for field references, which are contained within #$, e.g. #$FirstName#$.

Finally, I look for formula-snippets, e.g. #@WebDbName#@, in the home-link of the simple table template, and pointing to a stylesheet in the application.

>> Demo application

If you're downloading the demoapp


All design-elements made for the demo have DontPanic as a comment. I cleaned out a lot of the original design-elements in the app, to make it easier to find what I made for the demo.

The agent that "renders" documents is called "RenderPage". It's not well commented, but I hope most of the code speaks for itself.

Open the db on the Web, click on one of the people to open the document in its original form.

At the top of the page, there is a button for each template I made for the demo.


All the templates are in the templates-view, modules (only one in the demo) in the modules-view.

Why should I care/You can already do this with a form+content-type HTML


If you add more advanced back-end processing, you could have inline LS/Function calls in the context of the document. e.g.
#LS
Use "MenuBuilder"
makeMenu( #@UserRoles#@ )
#LS
^^This using Execute.

I don't think you need to pass the document-object to the inline functions, since NotesSession.DocumentContext is a global object. From a little test, it seems like it's best to Update the RT-field before running each inline LS-modification to it.

Inline formula-example

#F
@For( i:=0 ; i<10 ; i := i++;
    num := @Text(i);
    html := html + "<tr><td>" + @GetField( "line" + num) + "</td></tr>"
)
"<table>" + html + "</table>"
#F

You can of course do this with a a regular form using a WQO agent + computed elements, but what I hope my proposal of "Notes Templating" can do, is to add a layer of abstraction, maybe to make it easier for notes newbies to make Domino Webapps.

I also think this way is more readable than a lot of computed text/Computed For Display fields. The downside is that it adds processing overhead.

Comments/suggestions are greatly appreciated!

Tuesday, September 18, 2007

NotesFX 0.2 - Stable, but still not perfect

Since intensive string concatenation with JS crashes the JS-engine in Notes, I moved the concatenations to the formula-engine in Notes, which is more or less rock solid.






>> Download Demo Application

To do this, I use a "proxy" (between JS and Formula) field per effect, where I set x and y values with JavaScript. I then use document.forms.nameOfButton.click() to click a hidden formula-button which makes the string needed to inflate the layer/sets fieldvalue.

The problem now, is that the mouse pointer "blinks" (between hourglass and regular pointer) when the button(s) are clicked with JS. *d'oh!*

In the flash, you can't see the mouse pointer blinking as much as it does in the app.

I'll do my best to find a perfect solution, but I'm not sure the right idea will pop up. Suggestions are appreciated :)

If you're downloading/running the demoapp:
The new demo-form is called DemoAnimation_formula.

Saturday, September 15, 2007

NotesFX 0.11

If you're coming to this post directly, NotesFX 0.2, which is stable here.

Changes since 0.1 A:
One field per effect, less JS, speedier, possibility to set speed of animation.

Dropped the alpha (still in the DB-title). It's still nothing more than a proof of concept (mostly because of instability in the Notes Client).

Will still kill JS in Notes (unable to save JS-libraries/run JS in the client). Solution, KillNotes.exe.








>> Download NotesFX 0.11 Alpha

Thanks goes out to Nathan for input on the first version. I planned on having the weekend blog-free, but when people mail me about my experiments, I sometimes get a boost in motivation.

If I ever get this stable, I came up with a couple other possible uses than I have in my demo. Layer-based progress bar, horizontal and vertical bar charts (dynamic, based on field values and animated if you wanted).

Tuesday, September 4, 2007

BlindDown-effect in the Notes Client using JavaScript

If you find this interesting, take a look at my "NotesFX", which has more effects.

I don't know if this could be considered a hack. It's probably not useful (at least not in this state), but still fun.

The BlindDown-effect is found in DHTML-libraries like Scriptaculous and Mootools. Scriptaculous demo-page







>>Download demo-application

To achieve this effect, I have a layer with a table inside. In the table, I have three computed fields. One of them contains the title of the "help message", one contains the message, and one is used to add line-breaks into (-> what looks like animation). The "line-break" field has a font-size of 3, so that the animation looks somewhat smoothly, but is not too slow.

I have a javascript-function that takes the delay between each line-break, number of line-breaks (iterations), message title, and title. The iteration-parameter is put into a global variable that decrements for each added line-break.

I use setTimeout to call the same function until iterations=0.

The messages is put into a javascript-object with arrays corresponding the parameters that should be passed to the "blind down" function. This to make it easier to maintain the messages.

I use Notes' (or rather JavaScript 1.3's) apply-method to apply the array to the blind-down function.

Each field's onFocus code:
blindDownMessage.apply( "", messages[this.name])

Example of the messages-object:
var messages = {
name: [ 10, 10, "Your name", "Here you fill inn your name.\n\nE.g. Donald Duck, Dillbert, etc." ]
}


If you're downloading the demo:
The demo-form is named "BlindDown". Open it in the Client to test the demo.

You could also put more advanced things in the layer.

Hide the cell-content initially. After the "animation" is finished, set the value to make the cell visible, click a refresh-button (hide it with a layer/etc), using javascript. E.g. document.forms.nameOfButton.click()

I haven't tested the above suggestion, so I don't know if it's possible to do in a usable way.

Wednesday, August 29, 2007

Ajax-like live-search in the client

This one was harder than I initially had hoped, and it is still just a proof of concept at best.






>> Download Demo Application

I built this demo on top of Jake's Fake Names application. The "autocomplete" performs a DbLookup based on the value of the field the user types in. Then a HTML (Pass Through) table with links is created from the result. Since the Notes Client is sooo dynamic when it comes to HTML, I just have to restart the universe reload the frameset to refresh the generated table of results.

I couldn't get this to work in a useful manner when not in a frameset, because I can't figure out how to set the pointer to the end of the query-field when not in a frameset. This results in the pointer always going at the start of the query-field when "reloading" the form.

E.g.:
User types: abb
Field value: abb
Refresh/lookup
User types: ie
Field value: ieabb

If you're downloading the demo:
All elements modified/created for the demo contains "DontPanic Demo" in the comments-column.

The first lookup may take some time, as the view-index has to be created in the lookup-view.

If you want to try out fixing the autocomplete when not in a frameset, I've made a non-frameset form, "AutoComplete". If you find a way to set the pointer at the end of the query-field, please let me know how, and I will fix the demo-application.

I spent WAY(!) more time than planned to make this demo (work), so please don't hate me for not cleaning up unused code, documenting code and design elements, etc.

The file-size of the demo-application is 6.66 MB according to Windows Explorer, so beware modem users and superstitious people!

Update: I originally called this post "Ajax-like Autocomplete in the client", but the functionality is most like live-search. Sorry about that.

Tuesday, August 28, 2007

Highlighting fields on "Entering" with CSS in the Notes Client

Since I have vacation now, I have more time to try out different stuff i've been wondering about.

This is one of those things.






>> Download Demo Application

For some months now, I've wanted to look at possibilities of dynamic usage of CSS in the Notes Client. It is somewhat possible, but you have to close/reopen the document you're working on (+mess with SaveOptions), and you need a subform/stylesheet per state.

Unless someone finds out how to set the id of an element dynamically, this example, with one state per field will probably require too many design-elements to be put into a real-life system.

What I have to do for this demo, as previously stated, is to have one CSS-file/subform per field (since each field-focus is a different state) in the form. This because I only want to highlight the field when it has focus. To do this without a dynamic parent class or id, seems impossible.

Inline CSS for Notes WYSIWYG tables doesn't work. Putting a Pass-Through-HTML element around Notes WYSIWYG elemements doesn't work. With WYSIWYG, I mean Create->Field/Table/Button/etc.

It seems Notes first renders one, then the other. E.g. first render P-T-HTML, then WYSIWYG. This makes it impossible to wrap WYSIWYG elements with other elements with dynamic id's and classes.

My example:


The name-field has focus -> load css for field1 (computed subform containing resource=Environment( "fieldName" ).

Every CSS-file has this structure:
#nameOfField{
/* where #nameOfField is a TD that contains the input element */
background-color: #ffd;
/*
Strange that Notes has different shorthand order than the W3C spec.
Notes, border: color style width;
W3C, border: width style color;
*/
border: #555 solid 1px;
}

What I want:


field1 gets focus. Set environment variable. Containing element of a part of the form has computed "class=\"" + @Environment("name") + "\"".

In form:
<div class=<computed value>>
##WYSIWYG BLOCK##
</div>

In CSS:

.field1 #field1 {/* CSS for td containing field1, when it has focus */}
.field2 #field2 {/* CSS for td containing field2, when it has focus */}


With a dynamically named parent element, I should be able to put all CSS into one file.

If any of you find out more elegant ways of doing this particular functionality, please let me know.

Good CSS-in-Notes resource I stumbled upon (german):
Description of possibilities/limitations of CSS in the Notes-Client

Partially translated by Google (I don't speak german)

Sunday, August 12, 2007

Sexifying the client with DHTML

I don't know why, but I've been really motivated program/test out different ideas this weekend. This is another product of my brainstorming.






Full size

I tried putting this video up on Google Video, but it got so compressed that it was impossible to see what was going on. This means that the front page currently is about 3-5MB heavy.. Sorry..

As I've stated a couple of times before, I'm not an expert programmer, and I'm quite lazy. Because of that, my demos are never production ready (stability, speed, etc). This demo is FAR from production ready. It is a proof of concept.

What I do in the demo is passing javascript commands ( e.g. javascript:doStuff() ) to a web-document inside a "Microsoft Web Browser" control. The commands are coded per field, "entering".

I use mootools' Fx.Scroll class to get the smooth scrolling.

Current issues with the OLE object:

  • I get OLE Automation Error when I try to resize the control (works with the debugger on)

  • Passing browser.navigate( url ), where browser is the browser object variable, is slow when not running on localhost (I only tried on one external server)

Maybe there is a faster way/more efficient object (mozilla, webkit, etc) to use.

To run the demo yourself (only tested in Windows XP):

  1. Download the Demo-db zip file

  2. Extract the db onto your hard-drive, and copy it to where you want to run it from

  3. Alter the postopen (in the member form) url to fit with the location you put the db. Make sure the HTTP-task is running

  4. Open the member form in the Client


Let me know if it doesn't work..