Can I set a field to copy its value to others if I populate it?

611 views
Skip to first unread message

Colin M

unread,
Sep 14, 2021, 7:04:07 PM9/14/21
to mementodatabase
Hi - today I found the Android version of Memento after a long search through various apps and services, trying to find something that will do what I need. After some experimentation, I think perhaps Memento can help me.

I'm trying to work out if the following is possible, when I create a new entry to my library:
I have fields A, B, C and D. Each set up as a "rating".
B, C, and D are the important values, the ones I want to be available in my database.
Most of the time I want to put different values in B, C and D. Perhaps B gets 2 stars and C gets 3 stars and D gets 5 stars. 
However, sometimes I want just to put the same value in B, C and D. In this case, I want to be able to put a value into A, and this will then be copied automatically to B, C and D. So, if I put 4 stars into A, then B, C and D will all change to 4 stars, without me having to go and enter the value into each of them.

Is this something that is fairly easy to set up? I have tried looking through the wiki, and it looks like maybe I need to use "triggers" or "actions" but I don't know how to write Javascript, and I'm also not really any expert in using databases, so I don't want to embark on anything too complex that will cause me headaches in the future.

Many thanks in advance for any help.


Bill Crews

unread,
Sep 15, 2021, 1:45:55 AM9/15/21
to Colin M, mementodatabase
In the destination library, link it to the source library with a Link to Entry field (I'll call this field "source").

In the destination library,
> define fields A as a Rating field, B-D as JavaScript fields. Use the following JavaScript (JS) script for each of B-D...

field("source").field("A");

That's it. That's one of the simplest JS scripts there are for running in Memento. You're right to learn JS before getting into much JS, but how much is much? Well that's gonna be different for different people based on how much JS is needed (the key here), how much JS you know (now you know just a smidgen of JS), and other factors. I'd say the script above is less than a smidgen, so you're golden.



--
You received this message because you are subscribed to the Google Groups "mementodatabase" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mementodataba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mementodatabase/30b95b0a-ab8f-4236-b9e8-40496167cd19n%40googlegroups.com.

Colin M

unread,
Sep 15, 2021, 4:28:01 AM9/15/21
to mementodatabase
Thanks for the quick reply!

I am falling at the first hurdle though, because I want fields A, B, C and D all to exist in the same library, so I don't understand why there needs to be a "source library" and a "destination library".

Do I need to set up a "source library" in addition to my already existing library to make something like this work?

Bill Crews

unread,
Sep 15, 2021, 7:39:30 AM9/15/21
to Colin M, mementodatabase
Something made me think you have 2 libraries. If they are all in the same library, then in that library, define B-D as JS fields with this script...

field("A");

Because you have only 1 library & everything's together, it simplifies things, and you don't need that link field (source) and the code -- field("source") -- that goes with it.

Does that make sense?

If you'd like to learn JS, I recommend you install the Grasshopper app from the Google Play store (Google bought Grasshopper. It's safe.) on your Android device & take only the 1st 2 courses (Fundamentals 1 & 2). That minor subset of JS is all you need to use it with Memento, since there's no Web browsing going on. That Web browsing stuff is most of what JS was designed for, but all we need are the basic programming language statements out of it.

Note if you take the Grasshopper courses: Grasshopper teaches a more recent JS than Memento supports. There are 3 statements that don't apply to Memento JS (As you read this now, you shouldn't understand all this. Just hold my info below until you get to these statements in Grasshopper. It'll make sense to you then.):
  • The let statement. Just use the var statement instead. It works the same way for our purposes.
  • The const statement. Just use the var statement instead. It works the same way for our purposes.
  • The for...of statement. Use the older for...in statement instead. Here's an example of how they're different, so you can still use it in the course:
    • The for...of statement improved & simplified the older for...in statement.
    • Using for...of (in newer, modern JS):
      • for var x in arrayOfEntries {
      •     (Your JS code here for your for loop referencing x)
      • }
    • Using the for...in statement that Memento uses:
      • for var y in arrayOfEntries {
      •     var x = ArrayOfEntries[y];
      •     (Your JS code here for your for loop referencing x)
      • }
Just save this message until you get far enough in the Grasshopper courses where you'll need them. At that point this info will make sense to you, and you can complete the courses using either the newer statements (like in a Web browser or other newer JS) or the older statements in Memento. The differences above don't amount to much, but if you don't know this info, you'll trip over them, if you try to use that newer JS code in Grasshopper with Memento.

If you continue with Memento or other apps or browsers, many of them use JS; it's very popular, so I hope you'll take the courses, maybe get back to forum people like me to share your experiences with your new programming.

Final thing...
Read the Memento Help (most for simple stuff, not for JS). Then read the Memento wiki (wiki.mementodatabase.com) & look for whatever you need. I founded the wiki & am about to renovate it (next few weeks) after 5 years before I retire. Beth Dixon will take it over. Locate the Scripting pages in the index (indexes in the new wiki). Quick hint on it: As of today, there are 4 places JS is used in Memento: JS fields, Actions, Triggers, & Custom Data Sources. The last one of those isn't used nearly as much as the others.

With a JS field, you can access other fields in your library or, if the libraries are linked, fields in the linked libraries as well. A JS field accesses fields, maybe calculates something (like a discounted price), and displays it or uses it in further JS field calculations. JS fields are designed to be very easy to learn & to use. With an action, you can make your own button in the entries list screen or in the entry view screen and have it do what you want. In the entries list, the action script usually goes through all your entries, finds what you want in there, and maybe does something you say to do with them. With a trigger, you can have your JS script invoked when something happens, like when an entry is saved after editing or when a library is opened, and you can do things at that point in the process. With actions & triggers, you have more power, but to be able to use that power, you may have to learn some more things.

Enjoy, and keep us posted, Colin.

Colin M

unread,
Sep 15, 2021, 9:34:01 AM9/15/21
to mementodatabase
Thank you!

yes, that makes sense now, and I have successfully made some JS fields that update to whatever I put in my source field. So, I put a 3 star rating in "A", and B, C and D all change to a value of "3".

This doesn't quite get me what I want, though, because fields B, C and D are not fields that I can input directly. I want to be able to choose to do nothing with A, and then input different values to each of B C and D (which ideally would be star rating fields).

From what you have written, it sounds like I probably have to achieve this with an action or a trigger, and obviously I have to learn a bit more about JS to do this. Thank you for the advice about how to go about learning some basics. I might follow this - I have to decide how useful it will be to me, because I only have so much brain-space and time.

In the meantime I am wondering if it's possible to have a simple JS field X which gets filled according to these rules:
- if field A=0 then fill field X with the value in field B
- if A>0 then fill field X with the value in A.

I assume it is, once I understand the relevant JS code?

Thanks again

Colin

Er Mo

unread,
Sep 15, 2021, 1:53:43 PM9/15/21
to mementodatabase
Hallo Colin
Sie sind auf den Richtigen Weg . Sie brauchen einen Trigger " Erstellen eines Eintrages ---> Bevor der Eintrag gespeichert wird " . In Script komt der Text . Feld A ist "A" . Wenn sie den Feldnamen ändern müssen sie den Namen in den Anfürungsstrichen ändern .

Hello Colin
You are on the right track. You need a trigger "Create an entry ---> Before the entry is saved". The text comes in script. Field A is "A". If you change the field name you have to change the name in the quotation marks.

Skript

var e = entry()
var a = e.field("A")
if ( a!= 0){
e.set("B",a)
e.set("C",a)
e.set("D",a)
}

Bill Crews

unread,
Sep 15, 2021, 2:16:31 PM9/15/21
to Colin M, mementodatabase
Ok, you need to list the range of possibilities. I hope it not all combinations, cuz that would be a lot of possibilities. If you want everything, maybe we can come up with an algorithmic way to get it done without using dozens of scripts.

Try to imagine each use case; for each, what button would you push to do what? Be specific enough, & maybe we'll get a solution for you.

Bill Crews

unread,
Sep 15, 2021, 2:17:27 PM9/15/21
to Colin M, mementodatabase
We're talking trigger scripts now.

Colin M

unread,
Sep 15, 2021, 6:50:28 PM9/15/21
to mementodatabase
Thank you Ernst - I managed to create a trigger using the script you provided, and it worked. 

I found that it would work if I entered a rating to field A, and then saved the entry, but if I then went to edit that entry, and changed the rating in field A, it would not be copied to the other fields.

However, I made a copy of the trigger, but changed "create an entry-->" to "updating an entry-->" so now I have two triggers, and fields B, C and D are given the value of A when I initially make the entry but also if I go back and edit "A"...which is the behaviour I want.

But... now I realise I need to be able to deal with this scenario:
1. I make a new entry, and I put a value in A. 
2. I save the entry, and the value in A is copied to B, C and D (which is what I want)
2. But now I want to edit the entry, and change it so that there are different values in each of B, C and D.
4. However, now if I change these values, they will revert to copies of the value in A when I save the entry (because that's what the trigger script tells them to do). I need to work out how to make A reset to 0 if I edit any of B, C or D.

Going to see if I can work out how to do this, myself. 

Bill Crews

unread,
Sep 15, 2021, 9:31:44 PM9/15/21
to Colin M, mementodatabase
This is precisely the reason I asked you to list the use cases. You've now got a start on that; this is good.

Now, the reason why we need more use cases is to determine the various combinations you will need. Until you finish ask the possibilities, we won't know how many set statements, how many loops, or how many scripts you will need.

To me, the trick will be not only to identify the use cases, but to determine at what times or how often the combination of use cases there will be. I don't know how fast you're likely to learn JS; everyone is different. But you (we, I think) are going to have to do it in such a way that it's both easy & timely to use & feasible to support it over time.

Ultimately, we'll need to understand how complex it will become, and whether you'll need actions, as well. I know it probably seems like I'm repeatedly trying to suggest the solution will be bigger than we currently think, but it's starting to look like we're peeling an onion and don't know how big it is.

Colin M

unread,
Sep 16, 2021, 4:25:46 AM9/16/21
to mementodatabase
Hello Bill,
Yes, I need to clarify to myself what the use cases are and what I'd ultimately like it to do. That's a bit easier for me to do now that I have a broad idea of what's possible.
I noted via a pop-up that the free version of Memento (which is what I'm currently trying out) only allows me one trigger/action per library (although it actually seems to let me have two?) and that I'd have to upgrade to the "Pro" version if I want to use more. So this is another incentive for me to keep things simple.
One question at the moment is whether it's possible to have these trigger scripts run "live" as it were - so the changes happen as soon as I change the rating in one of the fields, rather than only after I save the entry. As far as I can see, it's not.

Er Mo

unread,
Sep 16, 2021, 12:59:39 PM9/16/21
to mementodatabase
Hallo Colin
Habe mal eine Test Bibliothek erstellt . Du kannst diese installieren : " Öffnen mit URL --> http://libs.mobi/s/M9YJRgTVB eintragen --> Herunter laden " und Öffnen . Wenn du da auf einen Eintrag gehst hast du rechts oben die Schaltfläche "set 2 " . Diese öffnet ein Fenster in den du die 4 lerren Bewertungen hast . So kann A 0 sein . Auch habe ich ein Feld mit Namen " A auf 0 " eingebaut . Wenn das Feld einen Hackerl hat werden die Werte von B,C,D beibehalten .

Hello Colin
I once created a test library. You can install this: "Open with URL -> enter http://libs.mobi/s/M9YJRgTVB -> Download" and open it. If you go to an entry there you have the button "set 2" in the top right corner. This opens a window in which you have the 4 incorrect ratings. So A can be 0. I also added a field with the name "A to 0". If the field has a hack, the values of B, C, D are retained.

Colin M

unread,
Sep 16, 2021, 7:21:21 PM9/16/21
to mementodatabase
Thank you; it's kind of you to take the time to create the test library. I will have a close look at it and it will help me understand how the scripts work.

Colin M

unread,
Sep 20, 2021, 10:45:22 AM9/20/21
to mementodatabase
Ok... I have now got my library nearly working as I want it to.

Essentially the arrangement is:
- I have a boolean tick box which I use to choose to copy values from certain fields into other fields
- I have managed to set up trigger scripts that copy the values over if that box is ticked, and don't copy them over if that box isn't ticked.

I just have one small remaining problem to solve... I also have some "calculation" fields. These are mostly just doing fairly basic arithmetic (taking averages of values entered into groups of fields, and similar). These are to produce numbers that I will use to produce charts, etc. 

I noticed some strange things going on with these numbers... coming out with different results than what I expected, which seemed to be fixed when I went to "edit" the relevant entry and then saved it again.

I think that what is causing this, is that the calculation fields do their calculations before I save the entry...but the way the trigger scripts work, they don't copy the values between fields until the last minute, when I save and exit from the entry. This means that the calculation fields are doing their work before the trigger script has put the correct numbers into certain fields.

Does that make sense?

It seems that I need to add something to the trigger script that tells it to recalculate the "calculation fields" *after* it has copied values between fields ... or is it that I need to do the calculations themselves as part of the trigger script, instead of within the "calculations" fields?

Thanks again
Colin


Colin M

unread,
Sep 20, 2021, 12:29:37 PM9/20/21
to mementodatabase
An update to my previous message...

I worked out that i can add the line

e.recalc()

to my trigger script

This seems to have the desired effect in recalculating the calculation fields to what they should be - but each time I create an entry now I get an error message:
 
"Script Error: Wrapped android.database.sqliteSQLiteConstraintException:NOT NULL constraint failed:tbl_flex_content2.ownerUUID (code 1299 SQLITE_CONSTRAINT_NOTNULL)"

I have no idea what this means!

Colin

Er Mo

unread,
Sep 20, 2021, 1:27:11 PM9/20/21
to mementodatabase
Hallo
Zu deine Fehler : Da Rechnest du mit einer NULL ( 5 / 0 = error)
Wann löst dein Skript aus ? Vor den Speichern oder Nach den Speichern  . Versuche " Vor den Speichern " . Wenn das nicht geht muss du die Berechnung in das Skript aufnehmen .

Hello
To your mistakes: You are calculating with a NULL (5/0 = error)
When does your script trigger? Before Save or After Save. Try "Before Save". If that doesn't work, you have to include the calculation in the script.

Colin M

unread,
Sep 20, 2021, 1:57:37 PM9/20/21
to mementodatabase
I am calculating "before save".

So it looks like I have to put the calculations into the trigger script.

Reply all
Reply to author
Forward
0 new messages