Bm 3 - Bill's memento #3 for July 2023, 2 articles

591 views
Skip to first unread message

Bill Crews

unread,
Jul 4, 2023, 10:37:47 PM7/4/23
to mementodatabase

Bm 3Bill’s mementos, Jul 2023

Beginning JavaScript & Memento objects

For those in the USA, Happy Independence Day on this July 4. This is the 3rd of Bill's mementos newsletters. While I'll continue to number & date the mementos, I will no longer assume the mementos will be published monthly, as the 1st two were. I will work toward publishing monthly mementos, but I make no promises.


The two articles of this memento constitute the beginning of my discussion of JavaScript objects and of the objects provided in Memento. In the 1st of these, I'll discuss objects you may construct yourself and then the math objects of JavaScript that you may use.


In the 2nd article, I'll discuss the scripting of Memento using JavaScript and the most fundamental Memento objects & functions that enable the scripting – The Memento Library & Entry objects.


As always, if you have any question or want something clarified, please reply to this message in the forum so all will read the question and my answer.


Bm article – Jul 2023, Bill’s mementos

Beginning Memento JavaScript, Chapter 3

Objects

Aside: For years, as have many of you, I have used the var keyword to define variables, because when Memento's embedded JavaScript engine (called Rhino) was first developed, it used an old version of JavaScript, and var was the (only) way to define variables. Desktop editions of Memento have used the version of JavaScript installed on their PCs, and usually that's the latest version of JavaScript, so using relatively new JavaScript keywords was no problem, but if you wanted a script to run on both your phone and on your computer, you had to use var.


Well, I've recently discovered that the Rhino people have been slowly updating Rhino, and now there are more modern things available to us in Memento JavaScript than before, even in the mobile edition. Nowadays, while var can still be used, we use let or const to define a variable -- let when the variable is truly to be variable and const when it should never change and thus be constant. So from this point forward, I will use let or const to define variables, but var still works as it always has, if you prefer to use that. There are a few other useful new statements you can use, and I'll cover some of those in future articles.

JavaScript literals & primitives

We’ve talked about literals, like 12 and “12”, and we have talked about primitives, like a literal itself or a variable that contains a literal. But JavaScript is an object-based language. Literals & primitives make basic language features very easy to use. Since JavaScript is object-based though,JavaScript actually (in the background without us having to do anything) makes a primitive into an object before evaluating or calculating with it. This allows object methods (functions within an object) to work on primitives just as they do on objects. So in reality, everything is an object in JavaScript, but JavaScript makes it as easy for you as it can by supporting primitives. An example of this is…


let pi = 3.14159; // variable pi now contains 3.14159

pi = pi.toFixed(2); // pi now contains 3.14


… or you could just say …


let pi = 3.14159.toFixed(2); // pi is now 3.14


…or…


let pi = 3.14159.toFixed(4); // pi is now 3.1416 (it half-adjusts (rounds))


The method toFixed() is one among several instance methods within JavaScript’s Number object and is one of the most often used. So, the variable pi here is treated like a JavaScript Number object. We'll go through built-in objects below. You can look up the things you can do with a Number object, and then you'll know what you can do with numeric primitives like pi, as well. The trick is to generally understand what JavaScript is doing in the background to make things easy for you, so you know what object JavaScript is using for your primitive value.


It is often said that JavaScript is untyped, and that's sort of true, but it still notices the difference between numbers and strings and dates, among some other things. But unlike Memento or some programming languages (like Java), one doesn't declare a variable as having a specific type. Instead of coding (as in Java)...

int one = 1; float real = 1.5; string name = "Bill";

…in JavaScript, one merely codes…

let one = 1, real = 1.5, name = "Bill"; // JavaScript figures out the objects to use


In a literal, when JavaScript sees a digit (or maybe a number starting with a + or -), it knows it might be dealing with a number. If it sees a decimal point, it knows what to do with it, and when it sees quotation marks, it knows it's working with a string instead of a number or anything else.

JavaScript objects

Definition: An object is a collection of related data and/or functionality in the form of properties & methods. These usually consist of several variables and functions. The most basic object in JavaScript is the Object object. It's this object that is created when an object is created from an object literal, as in the example below.

Let's work through an example to understand what they look like…


let person = {

  name: ["Bob", "Smith"],

  age: 32,

  bio: function() {

    message(this.name[0] + “ “ + this.name[1] + “ is “ + this.age + “ years old.”);

  },

  introduceSelf: function() {

    message(“Hi! I'm “ + this.name[0]);

  },

};


In this example of an object, name and age are properties of the object -- of the person. They are essentially variables that are hidden inside an object. Then there are 2 methods, bio() and introduceSelf(), which are essentially functions hidden within the object. The name property is an array (like a list) of 2 strings, and age is a number. Methods can have arguments (sometimes called parameters), just as functions do, but neither of these has any arguments. The bio() method builds a biographical sentence about the person and sends it to the user via the Memento message() global function. (It appears for 2 or 3 seconds near the bottom of the screen in the mobile edition and appears in a popped-up bar near the top of the window in the desktop edition. The introduceSelf() method issues a greeting to the user via a similar message.


Instead of types, JavaScript has categories of objects and it has objects instead of types, and JavaScript automatically figures out a primitive's object when it prepares to perform operations with it. That's very convenient, but it is also sometimes mistaken, as we've seen in the forum when a member codes amount + 20 and finds the result to be 123.4520 instead of 143.45, as was expected. JavaScript had originally determined that amount was a string of text characters, so when it encountered the + operator and then 20, it converted 20 into "20" (a String object's value) and, now finding 2 strings and a + operator between them, it concatenated the strings, resulting in another concatenated string.


So, for each category of objects, JavaScript provides one or more objects one can use to work with to eliminate the guesswork, and each of these objects has a number of useful methods one can use to do stuff with such things. Each object also may have properties that can be accessed based on the property's name (some call it a key). JavaScript has many objects within it, but this series of chapters discusses only the basic ones (many of which are analogous to the categories of functions provided with the Calculation field type) plus a few others.


Since JavaScript does this automatically with primitives, what I personally do is use primitives routinely and use object notation only when necessary or convenient, as with the custom person object in the example above, and I recommend you consider doing the same. 


You'll likely most often use self-created objects only to create new entries with specified field values, because, in Memento, lib().create() uses object properties as field names and their lproperty values as field values. Otherwise, you'll likely find little need to deal with objects of your own creation.


Since Memento's create() uses properties as fields, the names of those properties will often include spaces and maybe other characters that are not normally proper in property names, rather than using the normal JavaScript dot notation (like person.name), use the JavaScript bracket notation (like person["name"]). Then you could change the first field name to "first name", and it would still work (person["first name"]); in this case, dot notation wouldn’t work.

Use in Memento

In Memento, the main case where a literal object is used in in Memento’s Library object for the create() method. You create an object whose properties are each field’s names & values, and when you call create() on the library you’re wanting to create an entry in, it used those properties & their values to create a corresponding entry in the library. For instance…


If the variable journal contains the Library object, and you want to create a new entry in there, and if the fields in that library are Customer name (text), Date (date), Item (single-choice list), Quantity (integer), and Unit Price (real or currency), you’d do the following…


let sale = {

    Customer name: "John Smith",

    Date: new Date().getTime(),

    Item: "Screw",

    Quantity: 3,

    “Unit Price”: 1.25

}


Then…

journal.create(sale);    // Actually create the entry

Category: JavaScript objects for math

Now let's start with the math category, which contains the Number object and the Math object. The explicit object way of getting x as a Number is…

JavaScript object: Number

let x = new Number; // Equivalent to let x or var x, but an explicit object


Let's initialize y…


let y = new Number(1.23456); // Equivalent to let y = 1.23456


Either way, you can immediately start using x or y as numbers (x = y) or as objects (x = y.toFixed(1); // Now x = 1.2 & y = 1.23456).


For those interested in doing general math with numbers in JavaScript, here are JavaScript's Number & Math objects and their methods.


Here are examples of numbers created using the Number() object constructor function using an argument of a string. You wouldn't normally do it this way; this for illustration. JavaScript will convert the argument to a Number object automatically.


Number("123"); // 123 (converted to numeric 123)

Number(123) === 123; // true (same type (number), same value)

Number(12.3); // 12.3

Number(12.00); // 12 (Whole numbers are called fixed, but not a different type)

Number(123e-1); // 12.3 (exponential/scientific notation)

Number(""); // 0

Number(null); // 0

Number(0x11); /* Hexadecimal (base 16). In decimal (base 10), 1*16 + 1 == 17. Hex digits are numbered 0 through F (which is 15 in decimal), 0123456789ABCDEF */

Number(0b11); // 3 (binary (base 2), digits are bits, 0 or 1)

Number(0o11); // 1 * 8 + 1 = 9 (octal (base 8), digits are 0-7)

Number("foo"); // NaN (Not a Number)

Number("100a"); // NaN

Number(-Infinity); // -Infinity (special global constant number)


Number constructor

  • Number(#) // Constructor

    • To make a new Number object, type one of the following…

let n = new Number; // n is a Number object that has no value (yet)

let n = new Number(); // n is a Number object that has no value (yet)

let n = new Number(23); // n is a Number object with the (initial) value of 23


Examples: let x = Number(123);


Number instance methods

  • toFixed(#)

    • To set a Number value to a specific number of decimal points, type one of the following…

n = n.toFixed(2); // Round the value of n to 2 decimal digits of precision

n = n.toFixed(); // Round the value of n to an integer value (same as n.toFixed(0))

  • toString()

To put the value of a Number object into a String object, type the following…

let s = n.toString(); // If n is 12.34, s is “12.34”

JavaScript object: Math

The Math object provides a wealth of methods that you might want to use with numbers, many of which you may be accustomed to using with Calculation fields. They are static in nature, so to use them, you code Math.something rather than using a variable to contain a reference to a specific number and a Number object method.


as follows: var num = Math.abs(-3); // Math.abs() returns the absolute value of the value in num, which will be +3.



Predefined static properties

Property

Returns

Math.E

Euler's number and the base of natural logarithms; approximately 2.718

Math.PI

Ratio of a circle's circumference to its diameter; approximately 3.14159


There are more static properties, but they are seldom used.

Predefined static methods

Example: let arctangent = Math.atan2(Math.PI, Math.PI / 2); // See atan2 below.


Function

Argument(s)

Returns

Math.abs

number

Absolute value of number

Math.acos

radians

Arc cosine of the angle

Math.asin

radians

Arc sine of the angle

Math.atan

radians

Arc tangent of the angle

Math.atan2

numberx, numbery

Arc tangent of an angle, given its rectangular coordinates

Math.ceil

number

Integer >= number

Math.cos

radians

Cosine of the angle

Math.exp

integer

Exponential number e raised to the power of the integer

Math.floor

number

Integer <= number

Math.log

number

Natural logarithm (base e) of number

Math.max

number1, number2, …

The maximum value among the numbers given

Math.min

number1, number2, …

The minimum value of the numbers given

Math.pow

number, integer

The number raised to the power of integer

Math.round

real

The closest integer to the real number

Math.sin

radians

Sine of the angle

Math.sqrt

number

Square root of number

Math.tan

radians

Tangent of the angle

Math.toDegrees

radians

Angle in degrees

Math.toRadians

degrees

Angle in radians


There are a few more Math methods, but they are less often used, like the hyperbolic trigonometric functions. If there is interest, I could document those, as well, but you can look them up on the Web.


Another JavaScript math object we can discuss in the future is the BigInt object, which is intended to handle extremely large integers. Since the Number object handles very large numbers itself, you likely will have no need for the BigInt object. If you think you might need it, you can look it up by that name or contact me.


We will soon be discussing other built-in objects, such as the String object and the Date object. Please stay tuned for that. The Logical category of functions supported by the Calculation field is not needed in Memento JavaScript, as JavaScript has those capabilities built into the language itself, so no functions or methods are needed for logical operations.



Bm article – Jul 2023, Bill’s mementos

Beginning Memento JavaScript, Chapter 1

Library & Entry objects

In parallel with explaining objects of the JavaScript language, I want to explain the additional objects provided by Memento for use in scripting databases. There are 2 primary such objects whose use makes up 95% of the use of Memento scripting – the Library object & the Entry object. This article will explain those.


There are only another half dozen or so other Memento JavaScript objects, and those will be explained in a subsequent article in a future memento. They have to do with ancillary things that can be done in Memento JavaScript.

Review – JavaScript objects

As you know from reading my previous articles, an object is a container for data (properties & their values, like variables & their values) and behavior (methods, like functions). That's all they are, so there's no further mystery. Just like you can make a variable to contain a price (let price = 1.99;), you can decide to make it an object and keep more info…


let product = {

    name: "nail file",

    price = 1.99,

    salePrice = 1.99

}


If you want the ability for a product to be discounted, you could add a method for that, so the object grows to become…


let product = {  // info…

    name: "nail file",  // property

    price: 1.99,  // property

    salePrice: 1.99,  // property

    discount(percent) { // behavior…

        this.salePrice = (this.price * (1 - (percent / 100); // method

    }

}


So, an object contains the info & behavior that defines the object.

Going About Scripting Memento

In the Memento wiki, in the past, I've written a couple of tutorial pages about scripting Memento. They are…

  1. https://wiki.mementodatabase.com/index.php?title=How:Write_scripts_in_JavaScript_for_Memento

  2. https://wiki.mementodatabase.com/index.php?title=Tips:Using_JavaScript_in_Memento


As reference material, you can read 4 other pages I wrote regarding…

  1. https://wiki.mementodatabase.com/index.php?title=Actions

  2. https://wiki.mementodatabase.com/index.php?title=Triggers

  3. https://wiki.mementodatabase.com/index.php?title=Trigger_Examples

  4. https://wiki.mementodatabase.com/index.php?title=Data_Sources


In this article, as in all Bill’s mementos articles, I'm assuming no previous knowledge whatever of scripting or programming, so this could be easier for you to comprehend.


As of this writing, if you want to add scripting to your database, you have in each library 4 choices…

  1. Add an action (reference #1 above)

    1. Add a library action when you want a button on the entries list screen within a library and when pressed have a script run that likely pertains to all entries or the library as a whole.

Often, a library action script will access all the entries in a library and process them in some way one-by-one, maybe calculating a total of the values of some field.

  1. Add an entry action when you want a button in an entry view screen and when pressed have a script run that likely pertains only to that entry.

Often, an entry action will operate on the current entry or on those to which the entry may be linked.

  1. Add a trigger (reference #2 & #3 above)

    1. Triggers may be triggered at various places in your process of working with a library or an entry. In reference #2 above, there is a table of events and phases identifying when & where these triggers should take place. If you want a script to run when any of these events & phases take place, set up a trigger of that type and put your script into the script editor. Don't forget to check reference #3 above for examples.

    2. Triggers for events associated with a library, like upon opening the library, are called library triggers.

Generally, a library trigger will establish some default value(s) for some field(s) or access the most recent previously saved entry and use it to establish a field value.

  1. Triggers for events associated with an entry, like saving the current entry, are called entry triggers.

Usually, an entry trigger will perform something related to the current entry just before or after saving the entry or upon opening the entry in an entry edit card.

  1. Add a custom data source (reference #4 above)

A data source is used by the Autofill feature in the Edit Library screen and specifies the source of the data to be used to populate the fields of an entry. The source is frequently one of the provided data sources for things like books, music, movies, and so on, but a custom data source can be scripted to source the data from other Memento libraries or files or wherever.

  1. Add a Button field (No reference above, read below)

Subsequent to my retirement from active work on the Memento wiki, some new field types have been released by the developer, and one of these is a Button field. A Button field is essentially identical to an entry action except that, instead of the user pressing a Play button at the top of the entry view card, the user presses a labeled button in a field within the entry. There is no hyperlink reference here to the wiki for this field type because a page for this field type has not been created in the wiki (I retired). However, since it behaves just like an entry action, using the same objects & methods as an entry action, you can just write the script as if it were an entry action, but the script is placed within the Button field definition within Edit Library.

Note

All the scripting discussed in this article implicitly uses the Memento JavaScript Library (the MJL). A reference for this library (or API) is located at…

https://wiki.mementodatabase.com/index.php?title=Memento_JavaScript_Library


If you've scripted in the past using a JavaScript field, note that there are a few differences between a JavaScript field script and an MJL script, like those covered in this article. Those differences are…

  1. A JavaScript field implicitly works within an entry. To keep things as simple as possible for JavaScript field scripters, Memento makes an assumption that references to functions like field() refer to the current entry. For instance, let price = field("Price");.

However, in MJL scripts, the scripter specifies the object explicitly rather than assuming the current object. If you want to refer to the current object, all that needs to be done is to obtain the current object (like let e = entry();) and use it when calling methods like field() (like let price = e.field("Price");).

  1. Scripts for JavaScript fields can reference entries in libraries other than the current library only by accessing them through link-to-entry fields. Otherwise, access is only to fields within the current entry.

  2. JavaScript field scripts return values, whereas MJL scripts might do almost anything, like setting values using objects & methods that are in the MJL.

The Library object

The Memento Library object refers to a Memento library, as defined in Edit Library. See the following wiki page for details…


https://wiki.mementodatabase.com/index.php?title=Memento_JavaScript_Library#Object_Library


Library objects have only two properties. They both have the same value, but each has its own name. If you have a library object in a variable called lib, you can reference the library's name in two ways – lib.name or lib.title. (For years, a library name and an entry name was referred to as a name. That seems logical. Around the time the desktop edition was first released, the word title started to be used for some reason. Now, we can use either, but I still use name. Why not? Library names and entry names are still called names.)


But the Library object does have a number of methods (functions within the object). Probably the most commonly used method of these is entries(); you call it by writing let ents = lib.entries();. You pass it no arguments; you just call it, and it returns to you all the entries in the entire library into an array (essentially a list) that can be readily indexed in memory. Most library action scripts include a for loop that goes through the entries in this array one-by-one.


You can use the Library object's create() method to create new entries. The technique is to create a new object, add a property for each field (The property name is the field name. The property value is the field's value.) You then call lib.create(), passing it the new object you just created. So, if the new object is called obj, you would call lib.create(obj).


The linksTo() method allows you to get a list (a JavaScript array) of the entries (Entry objects) in various libraries that are currently linking to the entry you ask about when you call it. So, if you have an Entry object called ent, then linksTo(ent) will return that list of entries to you, and you can go through them one-by-one, if you like.


There are 3 find methods: find(), findById(), and findByKey(). To search all library field values, use find(). To search only the entry names, use findByKey(). If you have an ID from an ID field (column in Google Sheets, if synced), you can search for that using findById().


There is also a method fields() that returns a list (a JavaScript array, actually) of the names of all the fields on the MAIN page of a library. Only those on the MAIN page are available using fields(), which limits its usefulness considerably.

The Entry object

The Memento Entry object defines a library entry. See the following wiki page for details…


https://wiki.mementodatabase.com/index.php?title=Memento_JavaScript_Library#Object_Entry


Entry objects have the following properties…


Property name

Property value

author

the id of the user who created the entry

creationTime

date & time the entry was created

deleted

true, if the entry is deleted (it is in the Recycle Bin)

description

entry description

favorites

true, if the entry is in Favorites

id

entry identifier

lastModifiedTime

date & time the entry was last modified

name

entry name

title

entry name


The Entry object has the following methods. See the following wiki page for details…


https://wiki.mementodatabase.com/index.php?title=Memento_JavaScript_Library#Object_Entry


The most often-used Entry object method is field(). It's used to get the value of a field. If the variable containing the Entry object is called e, then to get the value of the Date field of that entry into a variable called date, you'd write let date = e.field("Date");.


The value of each Memento field is returned to the scripter based on its type. See the field() method under Entry object for a table defining the way each field type is interpreted and the kind of value it returns. The most recently released field types might not be found in that table, since I'm now retired and haven't been updating it.


Note

By now, it should be apparent that variables, properties, and Memento fields are very similar to each other. A variable is merely something in JavaScript with a name and a value. A property is something with a name and a value within a JavaScript object. And a field is something with a name and a value within a Memento entry, as defined in a Memento library.

It should also be apparent by now that to get a list of things in JavaScript, a JavaScript array is used, and to access the 1st element in an array named things, you refer to things[0] and for the 3rd element, you reference things[2]. I'll cover arrays in the next chapter of the Beginning JavaScript series in a memento soon to come. There, you will learn that you can get the number of elements in an array called things by referring to the things.length property – in this case, the length is 3.


Going through the other Entry object methods, the link() method adds a link to the array of links from a link-to-entry field to the specified entry.


The recalc() method causes the values of all the entry's fields to be recalculated. So it's e.recalc();.


The trash() method causes the deleted property to be set for the entry. This effectively removes the entry from the library, but the Library object's find methods may ignore this property and include them in results. So, it's e.trash();.


The untrash() method causes the deleted property to be reset, thus effectively returning the entry to the library from the entry recycle bin. So, it's e.untrash();.


A frequently used method is the set() method, which sets the value of the field whose name you give to the value in the 2nd argument. So, it's e.set("Discount", 0);.


The show() method causes the entry view card for the entry to be displayed. So, it's e.show();.


The unlink() method results in the removal of the entry from the array of links in the specified link-to-entry field. So, to have entry ent removed from the lte link-to-entry field in entry e, it's e.unlink(lte, ent);.

Scenarios & examples

Remember that for examples of triggers scripts, see…


https://wiki.mementodatabase.com/index.php?title=Trigger_Examples


What follows is some explanation of the general approach to using Library & Entry objects to script Memento…

Going through all entries

Usually in action scripts, but also occasionally in trigger scripts or Button field scripts, one might want to sift through the library entries to either access or do something to them all or else identify certain ones and access or do something only to those entries. The skeleton code to go through all the entries is…


let lib = lib();  // Or libByName(“Other library”);

let entries = lib.entries();

// Now all the entries are in the array called entries

// Now we can loop through the entries in the array

// using the for..in form of looping…

for (ex in entries) {  // ex is an index to each entry in the entries array

    let e = entries[ex];  // Now we have the entry itself

    // Fields can now be referenced with e.field(fieldName)

    //  to do what you want. To set a field value, use e.set(fieldName).

    e.set("Total price", e.field("Unit price") * e.field("Quantity");

}


An alternate way to do the for loop…


for (ex = 0; ex < entries.length; ex++) {

    let e = entries[ex];  // Now we have the entry itself

    // Do what you like with entry e

}


To operate on only some entries, use an if statement within the for loop to identify those fields…


if (e.field("Type") == "Debit") {  // For example

    // Do your e.set() or other statements here

}

Using a find-style Library method to identify the interesting entries

Another alternative is to use find(), findByKey(), or findById() to locate the entry or entries you want to work with…


Using find() is similar to the above, since it also returns an array of entries…


let lib = lib();

let entries = lib.find("query");

// Now, process this subset of the library's entries

//    in similar fashion to the above using a for loop.


Using findByKey() or findById() is similar except that only one entry is returned, so there need to be no loop. For this to work, the key or entry name must be unique within the library…


let lib = lib();  // Or libByName(“Other library”);

let serialNumber = "0182QX";  // For example, or other unique value

let e = findByKey(serialNumber);

if (e == null) {

    message("No item found");  // Or some other way of announcing a message

    exit();  // Stops running the script

}

else {

    // Now do what you like with the fields of the entry and/or of linked entries

}


dan.ca...@icloud.com

unread,
Jul 6, 2023, 11:18:04 AM7/6/23
to mementodatabase
Many thanks for this newsletter Bill. I look forward to studying it fully.

Regards, Dan

Bill Crews

unread,
Jul 6, 2023, 12:30:38 PM7/6/23
to dan.ca...@icloud.com, mementodatabase
You're welcome. Don't forget the sequence starting from Bm 1 & Bm 2 in January & February. Questions & comments are always welcome. I'm working on JavaScript (arrays, conditionals, more objects) & Memento JavaScript (more Memento objects & examples), as soon as I can.

dan.ca...@icloud.com

unread,
Jul 9, 2023, 10:04:01 PM7/9/23
to mementodatabase
Hello Bill,

I’m developing a client exercise database in which a script creates new records and also switches between an A and B exercise routine. It does this to a small extent by hiding the Subheader for the exercises not performed during the separate routines with Dependencies. However, Dependencies only go so far. I’m wondering if there is a script function which will allow me to hide/unhide fields via a script.

Many Thanks, Dan

Bill Crews

unread,
Jul 10, 2023, 1:58:39 AM7/10/23
to dan.ca...@icloud.com, mementodatabase
The hiding & inhiding of fields is a function of the app's user interface, and Memento JavaScript gives us functionality related to the database, the file system, Web access, and such, but none of it addresses the way things look on the screen. I didn't even know you could hide a subheader.

So, I guess the answer is unfortunately no.

Er Mo

unread,
Jul 10, 2023, 2:22:56 PM7/10/23
to mementodatabase
Hallo Dan
Ich verwende für solche Aus Ein Blendungen ein Einzelliesten Feld . Auf dieses bezied sich die Sichtbarkeit des Gewünschten Feld . Mittels Skript kann ich das Einzelliesten Feld änder und somit die Sichtbarkeit von den Abhänigen Feldern .

Hi Dan
I use a single reading field for such off on glares. The visibility of the desired field relates to this. Using a script I can change the single reading field and thus the visibility of the dependent fields.

Ernst

Bill Crews

unread,
Jul 10, 2023, 4:43:34 PM7/10/23
to Er Mo, mementodatabase
That's true. A script can turn on or off a Boolean or similar field that has field dependencies defined for it. This would alternate the visibility of the dependent field.

entry().set("Show", false);  // to hide

dan.ca...@icloud.com

unread,
Jul 10, 2023, 7:19:39 PM7/10/23
to mementodatabase
Many thanks Bill & Ernst. I’ve almost solved this challenge. After I run it through a few cycles I’ll share my process.

Bill Crews

unread,
Jul 11, 2023, 1:53:09 PM7/11/23
to mementodatabase
I've received the following message...

I'm trying to wrap my brain around the placement of code. How to decide whether to create a Javascript field in a library vs right click on library name and inserting code there.

Can you clear this up for me?

My objective is to create a last update date/time field that is updated with current date & time each time I update a record in the library.

Here's my response...

First, directly on point...

If I understand the requirement correctly, just set the default time and/or date to the current time and/date. This will cause current time to fill in automatically when you start to enter your entry fields.

Now, you said "update a record", so I gather you want it to update to the current time when you update an entry without having to take explicit action. To do that, the time value can be a value returned by a JavaScript field. Alternatively, a trigger script can automatically set the value of the time field upon saving the entry. That involves a little more script code, so if you're fine with that, you could do that. If you're not, let's do a JavaScript field, which just returns a value -- in this case a time value. The script could be...

new Date();  // That's all

So, the default value of the Date constructor (method) in the Date object is the current time, so the value of the JavaScript field will be the current time. The only problem I can think of there might be with that is that it might update at other times besides initial entry and update? I don't think so, so it should work.

If that doesn't work, the script for the Updating an entry Before saving the entry trigger would be pretty short also...

entry().set("Time", new Date());

If you use the current time default on the time field, you shouldn't need to do anything else, but you could copy the script above to a Creating an entry Before saving the entry trigger.

Not too bad. For that, instead of a JavaScript field for time, you'd define a Date, Time, or DateTime field, and the trigger script will provide its value. Just match up the field name you define with the name you use in the script.

For a more general response, I'll include an article in the next memento on the way one should think about the approach to use for each type of requirement, and compare several approaches.

dan.ca...@icloud.com

unread,
Jul 12, 2023, 10:32:53 AM7/12/23
to mementodatabase
Hello Bill,

I’ve studied your 3 Mementos and used them to solve several of my scripting issues. I wonder if you could explore scripting to add/modify records in linked libraries. For example automatically adding line items to an invoice.

Thank you for you continuing assistance.
Dan

On Tuesday, July 4, 2023 at 7:37:47 PM UTC-7 bill....@gmail.com wrote:

Bill Crews

unread,
Jul 12, 2023, 1:27:00 PM7/12/23
to dan.ca...@icloud.com, mementodatabase
Thank you for your input. I'll try to include that in my next article. This is helpful.

dan.ca...@icloud.com

unread,
Jul 21, 2023, 6:44:35 PM7/21/23
to mementodatabase
Hello Bill,

I’ve been reading through the Memento Script Wiki and am not how to begin a script for a feature I’d like.

I have a one to many link from Clients to Exercise Sessions. These sessions have increasing exercise weight as clients grow stronger. I’d like a script to look at all of a linked clients Exercise Sessions in order to create fields for Minimum and Maximum exercise weights. It would basically be like creating aggregates but in record fields.

Many Thanks, Dan

On Tuesday, July 4, 2023 at 7:37:47 PM UTC-7 bill....@gmail.com wrote:

Bill Crews

unread,
Jul 21, 2023, 7:41:47 PM7/21/23
to dan.ca...@icloud.com, mementodatabase
Why in entry fields? That can be wise, but it normally isn't. What will you then do with those fields?

Er Mo

unread,
Jul 22, 2023, 2:14:15 PM7/22/23
to mementodatabase
Hallo
Ich verstehen das so : Eine Kundern Bibliothek und einen Sitzungs Bibliothek . In Kunden sind 2 Felder mit Min und Max die von den Sitzungs Bibliothek stammen . Alle Sitzungen das Min und Max Suchen und in den Kunden eintragen . Ein Auslöser der den Aktuellen Kunden nimmt und damit die Sitzung durchläuft . Die Variablen " min " und " max " werden bei Über / Unter schreiten mit den Wert überschriben . Am Ende die Variablen in die Bibliothek für Kunden schreiben .

Hello
I understand it like this: A client library and a session library. In clients are 2 fields with min and max coming from the session library. All meetings the min and max search and enter in the customer. A trigger that takes the current customer and cycles through the session with it. The variables "min" and "max" are overwritten with the value if they are exceeded or not reached. At the end write the variables in the library for customers.

Ernst

dan.ca...@icloud.com

unread,
Jul 22, 2023, 6:32:28 PM7/22/23
to mementodatabase
Thank you for responding Ernst.

You’re very close in the way you understand this. Actually there is a field which contains the most current weight used. I envision this field being used to scan all records belonging to a particular client, then returning the minimum and maximum weight used over time. It would be exactly like creating Min and Max Aggregates but would allow further calculations such as percent of increase.

Many thanks, Dan

Reply all
Reply to author
Forward
0 new messages