Run Agent from Javascript

I have searched this forum, and read the domino help, but still can’t get to grips with running an agent via JavaScript.

I have a hotspot on a form which is displayed on the web. The hotspot will, among other things, run an agent. I currently have this coded in formula language, but I want to move over to JavaScript for the alert functionality.

Can someone tell me how to do this?

Subject: Run Agent from Javascript

Its a url call

http:// … /dbname.nsf/AgentName?RunAgent

I hope this helps

Subject: RE: Run Agent from Javascript

Thanks Diane, how would I stop it saying “Agent Done” after the agent has run. Is that what the $$Return is for?

Thanks

Subject: RE: Run Agent from Javascript

I think I used a history back for my agent call.

document.forms[0].submit();

alert(“Your profile has been saved! Thank you.”)

history.back(-1);

window.close();

I haven’t done that in a while.

Subject: RE: Run Agent from Javascript

Be careful with this approach, Diane, I had problems with this scenario some time ago because the javascript ran before my agent was finished running, so the window closed too soon.

Martin Vereecken

http://www.bizzybee.be

Subject: RE: Run Agent from Javascript

You can write whatever you want as response with your agent and the Print keyword, or do a redirect with Print.

Martin Vereecken

http://www.bizzybee.be

Subject: Run Agent from Javascript

Here is the method that I use to accomplish this. It’s not difficult but you need to pay attention to the details. In essence you are taking a single process and breaking it up amongst several systems, each one working independently. The messaging between systems is the key to controlling what’s happening and maintaining the unity of the process.

This process uses an old concept called reentrant programming. This concept is used in mainframe programming. It was the method use to get a mainframe of 30 years ago to handle 1000 users. Basically, you run your program and present some interface to a user (usually a green terminal screen.) Then your program ends…completely. It may even get tossed from memory. When the user presses Enter the terminal starts your program again. At that point you figure out where you left off and continue processing. Since users spend more time thinking and typing than the computer spends processing, you can have a thousand people working while the mainframe is only processing for a few users at any given moment.

We’re going to use this concept as a method of switching between languages.

First you create a field on the form that you’ll use to transfer instructions from one language to another. I usually call it NextStep. I usually also have an ErrorMessage field to go with that. Create other fields as needed to transferring data between languages. These can be computed fields equal to themselves.

Next you create a button at the bottom of your form with the formula for running the agent. DO NOT HIDE THE BUTTON. Rather, set the HTML tag Style to display=none. Also set the HTML Name. You’ll reference this later in JavaScript. In this example the HTML Name is WebProcesses.

Enter a formula such as:

@Command( [RunAgent] ; “web_processes” )

Next you create some onload code in your form to process the response from your agent. So in the onload of the form you’ll have something like:

var NextStep = thisform.NextStep.value

if (NextStep != “” ) {

thisform.NextStep.value = ""  //reset NextStep as quickly as possible.  Don't let it linger.

switch (NextStep) {



	//Close process

	case "UpdateNotes_CloseForm":  //Closes the dialog and returns data.

		window.opener.close()

		window.close()

		break



	//Messages

	case "Error":

		alert( thisform.ErrorMessage.value )

		break



	//Refresh

	case "Refresh":

		thisform.ViewRefreshFields.click()

		break

	}

}	

Finally, write the JavaScript for your hotspot.

thisform.NextStep.value = “UpdateNotes_SaveNote”

thisform.WebProcesses.click()

Okay…now you’re ready to process this. Here’s how it works. First you click your hotspot to execute the JavaScript. The JavaScript sets the NextStep field as an instruction to the agent. Then it clicks the WebProcesses button. That’s it. The JavaScript is over.

Next the formula in the button takes over and executes the agent. The formula hangs and waits for the agent to finish.

In your LotusScript agent use NotesSession.DocumentContext to get the document and check the NextStep field. Have a Select statement to choose which sub gets executed based on the NetStep value.

NextStep = docCurrent.NextStep(0)

docCurrent.NextStep = ""  'Reset immediately to prevent this process from running again if there's a failure.



Select Case NextStep

Case "WebQueryOpen" 

	Call WebQueryOpen

	

Case "UpdateStatus_QueryClose"

	Call UpdateStatus_QueryClose

	

Case "UpdateNotes_SaveNote"

	Call UpdateNotes_SaveNote

	

End Select	

Execute your code. When the code need to break for a message, you set your NestStep field to the appropriate value to be processed by the form onload. For example, you might have a validation failure and set it to “ValidationError” and you might set the ErrorMessage field to “Please enter a recipient.” Then you simply end your agent.

When your agent ends, your form will reload. This happens automatically whenever a button on the form is clicked and ends processing. When it reloads the onload event will run. In the onload you simply check the NextStep field and do what’s necessary based on its contents. Refer to the JavaScript Switch statement above.

Now that you’re back in JavaScript you can click buttons and start the process all over again. In this way you can loop between JavaScript, formula, and LotusScript to accomplish anything you need to.

Subject: RE: Run Agent from Javascript

I think it’s simpler to let your agent print what should happen after the execution. That way you are sure it ran before doing anything else. In the past I let the agent print some javascript (embedded in html) to close the window from which the agent was executed.

Martin Vereecken

http://www.bizzybee.be (Notes blog)

Subject: RE: Run Agent from Javascript

The Print statement is far too limited.

I once coded a web process where upon clicking the “Submit” button, a child document would validate and save itself, check if the parent was open on the desktop, if found check the edit mode, if in edit ask the user if changes should be saved or abandoned, then save or abandon changes, then close the parent, then update the parent with data from the child doc that was just “submitted,” and then open the parent again for the user with the new data.

How you gonna do that with a print statement?

Subject: RE: Run Agent from Javascript

How you gonna do that with a print statement?

The word “Ajax” comes to mind here. Remember, this ain’t your grandma’s web anymore.

That being said, it’s disappointing to see you come so-o-o close to an accessible solution in your previous posting without actually getting there. Remember – is still an , and that means it gets submitted to the server, so your server-side agent is perfectly capable of determining which button was clicked without any JavaScript shenanigans. All you need to do is use unique values and check them with your agent (or, indeed, with the formula language used to call the agent in the WQS event). You can still do client-side validation in the onsubmit, but if JS is unavailable everything will still work.

Subject: RE: Run Agent from Javascript

The code I posted was pulled out of a working system, so I’m not sure what you mean when you say “…close to an accessible solution…without actually getting there.” The code performs the task that was requested.

My reference to “Submit” was abstract…as in submitting a request for more Mountain Dew. I don’t know how to tell, from within running LotusScript, which button on the form executed the ToolsRunMacro. But it doesn’t matter because that’s too limiting. I have actions that execute JavaScript to give a user a choice of options, and then set the NextStep based on the choice before issuing the click on the button that executes the ToolRunMacro. I would either need to create multiple hidden buttons, or multiple buttons for the user to select from (because there would be no UI for options if the buttons are now formula.) In either case, there’s no savings of programming.

What I’ve provided is a straightforward framework for any situation that allows for complex interactions between the various languages and the user, which is based on events that are going to occur anyway. In order for the LotusScript agent to get the current document you must execute a ToolsRunMacro from within the form. There’s no other way to do it (sans some crazy AJAX code.) Clicking a formula button always submits the form and that in turn always causes the onload event to run upon return. So if these events are occurring then you might as well put them to some good use…which is what I’ve done.

Subject: RE: Run Agent from Javascript

Just a few (very) small changes can turn what you posted into something that can run just as well without JS as it does with, with the penalty being nothing more than an occasional extra trip to the server for the no-JS version at worst (and that mostly for validation).

No, you don’t need to use ToolsRunMacro from within the form (although that is the Designer default) – you can use the value in a Notes field that captures the value of the submit button to run an agent from the WQS event. Same result, same objects/fields available to the agent (that is, all CGI fields plus the parsed value of fields corresponding to the ones on the Designer form), no JS required. That’s not to say that JS isn’t a possible and desirable enhancement to the action, just that it ceases to be a REQUIREMENT for functionality. It’s really very easy once you wrap your head around the concept (and I’ll admit to having a little trouble with the concept at first myself).

Oddly, this approach is functionally identical to what DOmino does natively with the __Click field (the value of which determines when to run your ToolsRunMacro calls) except that it doesn’t require any JS (_doClick()). Since I ran across the technique at codestore.net, I’ve had to wonder why Domino doesn’t use a similar technique natively. Text hotspots and image maps, I guess – there’s something to be said for consistency – but there’s no need for buttons or image links to go through _doClick().

Subject: RE: Run Agent from Javascript

First of all, the whole idea of having the JavaScript is to supply a method to interface with users. The opening poster’s primary need was to send a message to the user. If you get rid of the JavaScript portions then you can’t present, for example, a prompt offering choices and then act on those choices. The JavaScript in the onload event is used to communicate messages back to the user after the agent finishes running and to initiate additional processes that might be required. One framework does it all.

You certainly do need ToolsRunMacro. Using WebQuerySave is too limiting because it only runs when you submit for save. If you create a button that executes ToolsRunMacro, then you can execute an agent at any time you want just by clicking the button. WebQuerySave does not run every time you click a formula button on a form. The onload, however, does run when any formula button completes processing.

I just built a web interface to an existing db that doesn’t open any document at all. The form that’s presented to the user is used to gather information. Upon clicking a button an agent retrieves and updates the real document (as well as creating other documents, as per the requirements of this particular process.) So in this particular case the WebQuerySave never executes because I never actually submit the form, so it couldn’t have been used.

Subject: RE: Run Agent from Javascript

ToolsRunMacro also requires a submission. There is no requirement to save in order to run WebQuerySave (although falling through the WQS agent to a save is the default). Open your mind a bit – accessibility – including dropping the requirement for JS in your applications – isn’t an afterthought anymore, it’s a requirement.

Subject: RE: Run Agent from Javascript

Create a form in a db that you can access through the web server.Create an agent that posts a message to the server console and run it in WebQuerySave of the form.

Add to the form several buttons that perform all sorts of formula, include one that performs a FileSave and one that performs a ToolRunMacro.

Compose the form and click the buttons. You’ll see that the only time the WebQuerySave agent puts a message on the console is when you click the FileSave button. It never runs on any of the other buttons.

So Either WebQuerySave only runs on a save, or my Web server is severely hosed (which I severely doubt.)

Despiite whatever ToolRunMacro may require, it doesn’t cause WebQuerySave to run.

Subject: RE: Run Agent from Javascript

You’re missing the point – a submit does not have to result in a save. The WebQuerySave agent can control that rather effectively. (I did mention that it takes a bit of head-wrapping, didn’t I?) Yes, the form is submitted as if for a save. No, the save doesn’t have to happen. No, you don’t have to go through _doClick() in order to make it happen. And no, you don’t need to run any JavaScript at all – but there is nothing stopping you from running all of the JavaScript your heart desires if the user’s browser supports JS and has JS enabled. Best of both worlds. But do try opening your mind up just a crack to see what’s possible rather than simply restating Domino’s default behaviour in an ever-louder voice.

Subject: RE: Run Agent from Javascript

Hey if you want to put a FileSave in every one of your actions even though they’re not real saves, and if you never need to present a dialog to the user or perform additional processes like refresh views, close other windows, etc…then I guess your methods are perfectly suitable.

My work tends to be a bit more complex than that.

Subject: RE: Run Agent from Javascript

I’m not saying your approach is not good, I’m only saying that in most cases it doesn’t have to be that complex or doesn’t need that many steps.

And in this case, it depends on what the writer of the question wants to achieve, right? So now he has some options to choose from :wink:

Martin Vereecken

http://www.bizzybee.be