Trigger - Example to copy records from one database to another one when entry is submitted

424 views
Skip to first unread message

Laura Szczuczak

unread,
Nov 8, 2016, 5:31:11 AM11/8/16
to mementodatabase
Hello,

The examples in the Wiki are very helpful and as a non-programmer I was wondering if someone had an example of the JavaScript command I shall put into my trigger. 

This is what I am trying to do:
I am using Memento to create a database of clients and then record sales for each client. I have one library to register clients (called "Registration") with quite a lot of information and another one ("ClientBase") where I would like to have an entry created automatically when a entry in "Registration" is finalised. For instance I would like to push the name and client ID from "Registration" to "ClientBase" so that when clients come back to my shop I can find them easily with the client ID and the vendors do not have to see all of the client details captured during registration, only selected fields.

Has anyone succeeded in having a trigger that pushes info from one library to another and is willing to share the JavaScript code? An example would be greatly appreciated! 

Thanks

Bill Crews

unread,
Nov 9, 2016, 3:42:36 PM11/9/16
to mementodatabase
Laura, I'm sorry I took so long to reply; I had a few things to learn along the way. Thanks for the excellent question.

I created two new libraries, Members and Applications, analogous to your ClientBase and Registration. I used very few fields:
- Members field, Name type Text single-line, role Entry Name.
- Members field Type, type Radio Buttons, items Individual, Family, and Institutional.
- Applications field Date, type Date, default current date, role Entry Name.
- Applications field City, type Text single-line autocomplete, role Entry Description.
- Applications field Years in city, type Integer, role Entry Description.
- Applications field Type, type Radio Buttons, items Individual, Family, and Institutional.

Then, here's what: did:
- I opened Applications, which took me into the Entries List screen, though there were as yet no entries.
- I tapped the menu (3-dot) menu icon and pressed Triggers on the drop-down list, taking me into the Triggers List card, though there were no triggers as yet.
- I pressed the shield icon on the top bar, opening the Permissions card.
- I set the switch for "Access to all libraries" to On and pressed OK.
- I pressed the round, blue + button in the lower-right corner to add a new trigger.
- I changed the default trigger name (Trigger 1) to "Creating, Before save".
- I set the Event to "Creating a new entry".
- I set the Phase to "Before saving the entry".
- I entered the script listed below.
- I pressed the checkmark in the upper-left corner of the card to save and exit back to the Entries List card.

Now, I'm done setting up -- time to test this out:
- I verified there were no entries in Members.
- I verified there were no entries in Applications.
- I pressed the round, blue + button in the lower-right corner of the screen to add an entry.
- I added a few. Each one completed normally; I checked frequently to confirm that entries were staying in Members.
- I tried to add one with the name "Bill Crews". When I pressed the checkmark to save it, it instead gave me the message "Not him. Try somebody else.", leaving me still in the Entry Edit card with my application data still there. I verified that no entry was created in Members for Bill Crews. That's my name; I put that code in the script as an example of data validation you could do and how it would work.

So, I suggest you do what I did. You may of course want to do it directly with your libraries instead of mine. Just make sure to set the permission as you go in to Registration to enter the trigger. While adding the trigger into Registration:
- Change the fields to your fields.
- Remove or replace the data validation with your own.

Script start ==>

// Get the application entry that's being saved and call it e (because you'll use it a lot).
// With that, you can readily reference fields in the new application entry about to be saved.
var e = entry();

// If you have any checks on the values of fields the user entered, you could do them here.
// If any validations fail, call cancel(), and the user remains in the Entry Edit card
// and will be prompted to fix something & try again.
if (e.field("Name") === "Bill Crews") {
message("Not him. Try someone else.");
cancel();
} else {

// From here on, the new application will be saved,
// so we must also create the new client entry.

// To create the entry in Members, we need to reference Members.
var members = libByName("Members");

// Start a new entry for Members.
var newMember = new Object();

// Set client fields from application data.
newMember["Name"] = e.field("Name");
newMember["Type"] = e.field("Type");
members.create(newMember);
}

Script end <==

Please let us (or just me) know how it went. Good luck.

Bill Crews

unread,
Nov 10, 2016, 4:30:20 PM11/10/16
to mementodatabase
By the way, I turned my previous message into an example in the Triggers wiki page. I could make it into a tutorial, more like I did for you, but now that I've updated the Triggers page, I'll hold off a while on that.

Let me know if you have any comments.

Alberto

unread,
Dec 26, 2016, 6:15:15 AM12/26/16
to mementodatabase
Hi This is working thank you,
But how to transfer a Date field ?

newMember["Date"] = e.field("Date");

Will give a error msg/

Bill Crews

unread,
Dec 26, 2016, 10:19:15 AM12/26/16
to mementodatabase
I know of no reason it wouldn't work. Both fields were created in the two libraries, right?

Please provide the error message.

Alberto

unread,
Dec 26, 2016, 10:48:52 AM12/26/16
to mementodatabase
Can't set string is the error msg please look at the file.
Thank you
error.png

admin

unread,
Dec 26, 2016, 12:27:38 PM12/26/16
to mementodatabase
Hi!
Try this:
newMember["Date"] = e.field("Date").getTime();

Alberto

unread,
Dec 26, 2016, 12:43:22 PM12/26/16
to mementodatabase
YES YES YES :))) Thank you its working


Laura Szczuczak

unread,
Dec 29, 2016, 5:20:37 AM12/29/16
to mementodatabase
Hello 

Thank you very much Bill for your message, it works for me. 

Though I am having a difficulty with one field type, the Javascript one.
In library Applications, I am creating a Client ID field, Javascript type, by taking for instance the first 3 letters of the name and the first 3 digits of the phone number. This field is called RegistrationClientID.

I would like to also "push" this RegistrationClientID field from the Applications library into the Members library. I have created a new field in Members, called ClientID, type text.

In my trigger I have then added one row:
newMember["ClientID"] = e.field("RegistrationClientID")

Nonetheless when I add an entry in Registration to try to see if it works, the trigger does push the name and type but for the ClientID I see " NULL". 

I suspect that it is because the field in Applications is a Javascript one and I cannot push it somewhere else. Would you have any advice on how to get this ClientID also pushed to the other library? 

Cheers

Laura

Eugene Kartoyev

unread,
Dec 29, 2016, 5:35:03 AM12/29/16
to mementodatabase
Laura, just to make a quick check of your supposition, if I correctly understood you.

I've just made a trigger, to check JS field in the process.

message(entry().field("myJavaScruptField"));

(Opening, after display)

it showed the contents of the field correctly, which means that JS does return contents if there are contents.

Might it be that you need to establish the right order of data transfer (after update and after saving), so your JS field contents be transfered only *after* they are created?

Bill Crews

unread,
Dec 29, 2016, 8:08:53 AM12/29/16
to mementodatabase
I still have my Applications and Members libraries I used when we developed this originally. So, I did it myself, and it works correctly. Here's what I did.

(Eugene, it's a Creating a new entry / Before saving the entry trigger. I would guess she uses it also during Updating an entry; I don't know.)

I edited Members and created a one-line Text field called clientID there. I then edited Applications and added a Phone field called Phone and a JavaScript field also called clientID (-: I have no imagination. :-) with the following code:

field("Name").substr(0, 3) + field("Phone").substr(0, 3)

Finally, I edited the trigger and added this line of code (same as the others):

newMember["clientID"] = e.field("clientID");

My guess is that you didn't create the clientID field in Members or maybe used a field type inconsistent with a string or something like that. The trigger script plugs the value, but the field has to be there already.

Bill Crews

unread,
Dec 29, 2016, 8:16:14 AM12/29/16
to mementodatabase
Upon rereading your post, I am reminded that you did, in fact, create a text field in Members to receive the value, so I really don't know why it wouldn't work for you. Is it as simple as leaving off the semicolon (;) in the new line in the script? Did you test the script while still in the trigger edit card? If so, did it show an error? If so, what?

Laura Szczuczak

unread,
Dec 29, 2016, 8:20:30 AM12/29/16
to mementodatabase
Hi Eugene

Yes you are right if I change the trigger to be after saving the entry it works. 

Because I would like to do data validation to check that the name does not already exist before saving the entry I want to keep the trigger to run "Before saving the entry". 

I have then separated my script into 2 smaller scripts, one with this name checking (which is still checking for Bill's names as I do not know yet how to tell it to loop through the Members to see if the name exist there..), which executes before the entry is saved; and the second script that does the data transfer of the name and client ID which executes "After saving the entry".

Thanks a lot for the advice!

Laura Szczuczak

unread,
Dec 29, 2016, 8:42:02 AM12/29/16
to mementodatabase
Hi Bill

Indeed I just checked and I forgot the semicolon at the end of the script, it now works.
I am very new to Javascript and still need to make sure I follow all the core rules...

Thanks a lot to you and Eugene for your prompt replies and assistance, it is much appreciated.

Bill Crews

unread,
Dec 29, 2016, 9:06:17 AM12/29/16
to mementodatabase
A trigger script is more of a full JavaScript thing, and it wants its semicolons.

A JavaScript field is real JavaScript too, but Memento hands off to JavaScript differently and provides the semicolon itself. As for multi-line JavaScript field expressions, I haven't explored this much, so I tend to put semicolons, but I'm not sure where/when they are needed.

Bill Crews

unread,
Dec 29, 2016, 9:25:46 AM12/29/16
to mementodatabase
You're right that data validation needs to be before saving, and inter-library data plugging can occur after saving, so that's good.

As for the sample data validation code I gave you...

if (e.field("Name") === "Bill Crews") {
message("Not him. Try someone else.");
cancel();
} else {

// From here on, the new application will be saved,

...the main thing is to avoid mismatching braces. To excise this from your After script and just do the plugging, delete precisely the code I've shown above PLUS the closing brace at the very bottom of the script. That makes 4 braces deleted - a nice even number. You might copy & paste the script somewhere first, just in case things don't work as you anticipated.

Also, do you see the Play button on the trigger edit card (triangle pointing right)? Whenever you are done editing, you can test/preview it by tapping this button. The main benefit of doing this is to see if it completes without an error, and if there is an error, to try to figure out, from the top few lines of the message, what might have gone wrong. It might even have said "missing semicolon".

Eugene Kartoyev

unread,
Dec 29, 2016, 9:39:47 AM12/29/16
to mementodatabase
One generally should use semicolons after each statement.

If you do not do it at the end of line, the environment may try to insert it itself, but there is no guarantee it will do so.
Omiting semicolons is generally a bad style that may often result in ambiguity, accidental merger of unrelated statements and hidden bugs.

The same is about html properties and quote marks. It is always more secure to write things like <font color="red"> rather than <font color=red>. If you try exporting the second code to some html parsers and analysers - it is highly likely to cause an error.

Html browsers allow omitting semicolons in JavaScript, to make messy internet pages still functional.
Nonetheless, it should be regarded as a deviation.

Like in real languages "Me ain't got no money" - may be regarded as a both correct and incorrect statement.

In Java, these frivolities are never allowed.


stephen dcosta

unread,
Aug 30, 2017, 7:19:21 AM8/30/17
to mementodatabase
Hi Bill,

that was very helpful information, I tried this in one of my application and working fine,

However I have a requirement.

I want to edit a entry  which Is already  present in  'Application' library and already added to  'Members' library by the trigger.

however the entry is not getting updated in 'Members'  library once I done the changes  in  'Application library and saved it

could you please help

Bill Crews

unread,
Aug 30, 2017, 8:51:51 PM8/30/17
to mementodatabase
I'm not following your explanation very well, but there need to be two triggers that are probably identical, or almost so -- one for Creating a new entry Before saving the entry, and one for Updating an entry Before saving the entry. If you have only the Creating trigger, that is likely your problem.

If your current script does a create() to the other library, the scripts will need to differ. The Update script will have to locate the corresponding entry in the other library, update it, and save it.

Reply all
Reply to author
Forward
0 new messages