Copy a value from one field to another field

355 views
Skip to first unread message

Chris Brown

unread,
Nov 3, 2021, 12:17:44 AM11/3/21
to mementodatabase
So I have a library for "Movies" that I own. The title field comes from IMDB, and I have over 300 entries. I added a field to the library for "title sort", because I want all movies whose title starts with "The" to be sorted by the second word in the title not by the word "The". How would I go about copying the "title" field to the "title sort" field so I can begin to manually fix the "title sort" field for movies that begin with "The"?

Additionally, is there a way, going forward in making new entries, to automatically copy the "title" field to the "title sort" field?

Thirdly, after I get the "title sort" fields all filled out, would there be an automated way to change the "title sort" field from "The Godfather" (for example) to "Godfather, The"?

Or, alternatively, is this even the best way to go about this plan in the first place?

Thank you all.

Bill Crews

unread,
Nov 3, 2021, 3:03:13 AM11/3/21
to Chris Brown, mementodatabase

You might have a need for the title sort field to be writable, like copying the "title" field to the "title sort" field, BUT I think you don't need that in which case you can use a JavaScript (JS) field instead of a trigger, so that's my recommendation.


My 1st thought is that this problem has been addressed & solved millions of times by database authors, so try search keys like "javascript move the to end".  If you don't find something good enough there, you can do it yourself, if you know some String object methods (object functions. Try "javascript methods trim substring" or something like that.


In general, the #1 place for info on all things JavaScript is the JS Web Docs pages at Mozilla. I generally just Google "MDN JavaScript", (MDN stands for Mozilla Developer Network.) but it takes you for the time being to...

https://developer.mozilla.org/en-US/docs/Web/javascript

...so if you like URLs, go there. I suggest doing this on a PC; mobile browsers tend to be way too limiting.


The left side of the page (in a PC browser) is where it lists methods, including String object methods trim and substring, so scroll down the alphabetical list to find substring first & then trim. In Memento, a Text field's value is a JS String object, so I think you want to use a few String methods to test the "title" field for a leading "The " (skip any leading blanks); if you don't find it in an entry, just use the value of the "title" field for that of the "title sort" field; but if you do find a leading "The " in an entry, you have a bit of work to do...


First, trim the title of any leading or trailing white space (blanks, mainly) by using the trim method. The MDN page for trim says...


The trim() method removes whitespace from both ends of a string. Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.).


The 1st script line could be ("//" means the rest of the line is a comment to you)...

// The () below are for arguments (parameters).

// field has 1 argument "title",

//    but trim doesn't have any arguments,

//    but it still needs the empty ().

// var defines a variable, which is a value with a name.

// tsort will have the value of that field returns to it,

//    which is what "title" has with blanks trimmed off.

var tsort = field("title").trim();  // Finally, the first line of JS code! Does it make sense now?


The next thing is to check the 1st 4 characters to see if it matches "The ". If it doesn't match, we will just return either the value of the variable tsort or the value of the field "title". I recommend tsort's value; it keeps all the data more normalized or standard in format, but if for some reason the value of the "title" field always has to match the value in the source of the data, go for the value of the "title" field, since you must.


Stripping of the leading "The " is easy -- just use the substring method. Putting it onto the back end of the title is also just as easy. The MDN page for substring is longer. It says…


substring() extracts characters from indexStart up to but not including indexEnd. In particular:

  • If indexEnd is omitted, substring() extracts characters to the end of the string.

  • If indexStart is equal to indexEnd, substring() returns an empty string.

  • If indexStart is greater than indexEnd, then the effect of substring() is as if the two arguments were swapped; See example below.

Any argument value that is less than 0 or greater than stringName.length is treated as if it were 0 and stringName.length, respectively.

So, the next code we need will do the test and decide which of 2 things to do based on that.

// To deal with The, the, THE, tHe, and so on,

//    we convert everything for testing to lower case,

//    though the library fields still have the original case.

// substring(0,4) returns the 1st 4 characters of tsort.

// toLowerCase returns the 1st 4 characters of tsort

//    shifted to lower case.

// == tests the left side to the right side

// if evaluates the value returned by the == operator.

// If it is true, the 1st code block is executed.

// Otherwise, the 2nd block is executed instead.

if (tsort.substring(0,4).toLowerCase() == “the “) {  // Matches

tsort = tsort.substring(4) + “, “ + tsort.substring(0, 3);

}

else {  // No match

tsort;  // Return the value trimmed, case unchanged.

  // For untrimmed, return field(“title”) instead.

}


We are done. We returned one value for a match & another for no match. Put the 2 chunks of code together in a JS field called “title sort”, and you have it. I hope I don’t have any mistakes above; I have not tested it.


I’d love to hear feedback on this from you or from anyone. It’s a nice little JS instructional piece, which is what attracted me to it. I’ll be putting it into the wiki or at least into a Bill’s mementos newsletter, so please help me make sure it’s right and as good as it can be. Thanks in advance.



--
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/4dcdc0eb-75ba-4d12-b82d-f99f661a240an%40googlegroups.com.

Chad Eric Vincent

unread,
Nov 4, 2021, 5:06:51 PM11/4/21
to mementodatabase
I won't write the script for you yet the concept is that you would use the function trim which would trim the first 4 characters, the "THE " from the beginning of the values stored under whatever field you use for the name of your movies.  Then reindex  The problem with this approach would be the need to re-index more often.

A second way would be to do the same thing with the trim function and store the new value in a new field (you can even hide the field) then reindex by that name field only once for this library.  Saves time and processing power and boosts speed.

Chad Vincent

Chris Brown

unread,
Nov 6, 2021, 5:41:14 PM11/6/21
to mementodatabase
Thank you both. I was hoping for a built-in, non-scripting-related solution because I have zero knowledge of Javascript whatsoever, but you were both so thoughtful and thorough with your responses that I just may be able to tackle this.

Cheers!

Bill Crews

unread,
Nov 7, 2021, 1:52:12 AM11/7/21
to Chris Brown, mementodatabase
As I've done several times before, to remedy your lab of JS knowledge, I recommend you give the Google-owned Grasshopper Android app a try; it won't take you very long. There are 2 limitations on that...
 1. To cover the part of JS needed for Memento scripting, you need to take only the 1st 2 courses -- Fundamentals 1 & Fundamentals 2. All the rest are aimed at people building Web sites, which we're not.
 2. Grasshopper is based on modern releases of JS, such as those in the Desktop Edition platforms, while the engine used by Memento supports an older release of JS, so there are (only) a couple of features in Grasshopper that are not in the JS in the Android release of Memento.
    a. When Grasshopper refers to the let and const statements, substitute the older var statement used by Memento. For example, instead of...
            let v = 5;
        or:
          const v = 5;
     Use...
          var v = 5;
      b. Substitute the older for...in statement for the newer for...of statement. For example, instead of...
          for var value of valueArray {
          // Use value from here;
          }
      Use..
          for valueIndex in valueArray {
              var value = valueArray[valueIndex];
              // Use value from here
          }
Remember... The issue is only in the Android platform for Memento. Modern JS implementations, such as those in Desktop editions of Memento, don't need this. Now that Memento is being beta-tested on the iOS platform, I should check it out. It might very likely use modern JS, as well, and not have the limitation. It sure will be nice when Android Memento finally replaces its antiquated JS engine with a modern one (like Google's V8)! Then these limitations would be removed.

Reply all
Reply to author
Forward
0 new messages