Writing Long Text to Table

I have a form used to send emails via mail merge. Normally, when I want to update a table, I need to send pertinent information to server via a context object, which can contained field names and values, and the server can use this to update tables (among other things).

In this case, I can put SendToAddresses, CcAddresses, BccAddresses and EmailSubject values into the context, because they are somewhat finite in length.

What I can’t figure out is how to convey the EmailBodyText to the server. It doesn’t seem safe to send the contents of a memo field via context, as it can be quite long.

Just so you know the architecture, I have an EmailTypes table, with EmailTypesKey (GENERIC, BOARD and LEADERS), EmailType (descriptive text), DefaultSubject and DefaultBody (memo).

When I show one of the email types on the form, the DefaultSubject and DefaultBody text are loaded into unbound Subject and Body form fields. Here the user can modify them before sending the email.

But again, the Body field can be quite long, so how do I get it to the server so the emails can be sent by the server?

The 3 records with defaults are fine like they are, but since this will be a multi-user application, I need a way to save the modified text along with the current UserKey, just until the email is sent, so it doesn’t collide with other users.

What is the Five-approved way to do this? Thanks…

Is it feasible to have a bound field in the table and form to store the interim email body text? that way, once I save the record, the server function will have access to the email text, and I won’t need to try and transmit it via context? The challenge with this is that it is not conducive to a multi-user system.

Is it possible somehow to copy the field value to another table immediately after saving? I could have an EmailDrafts table with UserKey, EmailType and BodyText. Then the server function could use that table and the table record wouldn’t be stepped on by another user. Would this be a good use of table triggers?

Hi Ron,

Thank you for raising this question.

A multiuser application can guarantee that records can be only accessible by a specific user or better saying accessed by a user that has created that record.

In your multiuser application, you need to check the configuration of your ‘Roles’ under the parent menu ‘Setup‘.

The four last field under this menu is responsible to make sure that a user can only see and manipulate records he/she has created.

What Five does behind the scenes is to put the user record key in the stack therefore,
any form record that contains this record key, will be automatically filtered (users can only see records that belongs to them), and you can always apply extra filtering, especially in queries using this value in the stack.

You can also use the field Menu, to make sure that role only see records under a giving/a specific menu.

With this, you can save the email information to a table linked to this user record, that only this user can see and manipulate this record. and when you query the email, you can query the email context against the current user.

The link: Introduction | Five | Low-Code For Real Developers has an explanation and a user case on how to use it.

You can use the application that I have attached instead. (I changed all credentials to have the same password ‘admin‘).

If you log in as ‘anne’, you can see that it only shows the record that belongs to her.

The same if you log in as ‘jason’, you can see that it only shows the record that belongs to him.

I have also added a new menu ‘User Books View‘ under the member menu for you, to show how you can get all the records for a user record via query using the default value in the stack.

BookClub-ForRon.fdf (3.6 MB)

Please let me if you have any further questions.

Regards,
Elton S

I’m not sure if I posed the question clearly. I don’t think it’s an issue of who can see who else’s records.

It’s an issue of how to save this long text into the table. I’m here on the client side, typing an email message. I have To, CC, BCC, Subject and Body fields. The first 4 fields should be fairly finite in length, and I should be able to put them in a context object to send to the server to actually run the reports and send the emails.

The problem with the body text is that it can be very long, including linefeeds. It doesn’t seem reliable to try and send that in a context object, unless I’m not understanding how these things work.

My initial idea was to send the entire text contents to the server. would it be possible instead to convert it to an array object containing each line of text, and send that in the context?

Failing that, my thought was to make the body text bound to the EmailTypes table, and save the record there. Unfortunately, this would override anything else there, so other users may have changed this value. It’s not multi-user friendly. that is why I asked about the possibility of a database trigger, so that when the record is saved, the contents of that field would immediately be written to a new table, using the UserKey variable to keep it unique between users. then the server function could read that key and value from the table (the context object sent to server already contains a UserKey item).

This is presuming that you can actually setup a trigger on the table field which could write the data to another table. I have no idea if this is possible.

Ignore this next part if my answer is already too long:

I’m already doing something similar when dealing with forms/tables that have pages. For example, my Reports form of course lists the different reports I have in that table. The Members page is DataView powered to list all members with those who have an entry in the ReportMembers table (join table) having their IsSelected set as true. otherwise IsSelected is false. This DataView is powered by a query that checks the SelectedMembers table. The SelectedMembers table also has UserKey in each record. So when the form is loaded, the Selected… table(s) are cleared (for the current user only) then re-loaded based on the join tables.

This is working fine, but is not exactly what I need here. I want to store the email’s body text in a table (also containing the UserKey) so I don’t step on other people’s emails and vice-versa.

I’m only asking about this because of the perceived limit of how much text can be sent to the server function via context object. If there is a better way, please advise.

thanks…

How about I have an EmailDrafts table instead, and bind the GenerateEmails form to that instead of EmailTypes? I can create a new record by tapping the + in the list. Then I would need to add a drop-down lookup of EmailTypes (currently GENERIC, BOARD and LEADERS). When this is chosen, the change or ListSelect event can cause a server function to write a record to the EmailDrafts table using data from EmailTypes, including the type, UserKey, DefaultSubject and DefaultBody. Then do a refresh of the form. Now I have some bound fields that contain current default values. Once this is saved, the function called when I click the Generate action button can do the actual emailing. then I would need to remove the record I just created in the EmailDrafts table on successful sending of the email.

Do you think this is doable?

Can I cause the record itself to be saved first thing when I click the GenerateEmail button, and hide the checkmark / save button?

I don’t think I can have a form with NO fields showing in list, but I could have a create date/time and a status field showing in the list, right? Then I could retry if an email failed.

Thanks…

Hi Ron,

Apologies for the earlier misunderstanding—I misinterpreted your question.

You should not encounter any issues with the context’s length when sending it to a server function. If you’re able to share an example that includes more data, that would be greatly appreciated and would help provide more precise guidance.

Note:
If you send the data via executeFunction or five.setVariable, you can also simply JSON.stringify any JavaScript object and re-parse it on the server. We have also sent 10MB+ via setVariable without any issues.

The data type (array, object, text, etc.) sent to the server can be any type supported by JavaScript. For example, splitting the data into an array and then rejoining it on the server is completely acceptable.

Regarding using a trigger and a table event to save a new record in another table: the application I referenced in my previous response includes an example of this functionality. Specifically, there is a function called SaveBookBeforeUpdate that is triggered before an update occurs on the Book table. This function inserts a new record into the BorrowHistory table.

Please note that when using table events, the values from the table that triggered the function are always available in the context.new object, which contains the current values being saved from the form.

Additionally, the context.old object is available when triggering Before Insert, Before Update, or Before Delete events.

Please let me know if you have any questions or need further clarification.

Best regards,
Elton S

Hi Ron,

Your proposed solution appears to be feasible. However, I’m unable to fully confirm whether it is the best approach, as I don’t have complete visibility into the overall context or the specific setup of your application.

Regarding your questions:

  • I ususally do not recomment hide the Save button dynamically, but you can try to use five.variable, like in this example:

    • 1 - Create a function to set it to a variable to true. This function will be triggered on the form event ‘On Show‘; anytime you access this form/record, the Save/Edit button will be there.

    • 2 - Add another function to clear this variable. I suggest adding it to the event ‘On Finish‘ that will be triggered after the form saves the data in the back end.

    • 3 - In the form, you can add a condition on teh field ‘Show Title If‘, this is one example if your variable is called ‘CreateRecord‘.
      =(five.getVariable(“CreateRecord”))

    • What it will do is always show the title bar, which contains the Save and Edit buttons, and when you save the record, the title will disappear. However, if you return to this record, you can still edit and save again (teh condition to hide the title bar is only after clicking on the Save button).

      You can also try a different logic where the variable should be set, but it depends on how you want it to work.

  • A form must contain at least one field in the list.

Please let me know if you have any additional questions or need further clarification.

Regards,
Elton S

Thanks for this answer Elton.

If I can send large text to the server then that will solve my issue. All of the other ideas I mentioned were because I thought there was a smaller limit to what I could send via context to the server.

To clarify, are you saying that I should use a variable to send the email body text to the server rather than assigning it to a context member?

I can reasonably predict that the body text will be less than 10 mb, even if I’m sending HTML encoded text.

This question may be more opinion and styling: do you think I should send To, Cc, Bcc and Subject via context because they are more finite in length, and send Body via a variable, or send everything via variables for consistency?

Thanks…

Ron Mittelman

Hi Ron,

Passing the data via the server is the right way to go.

I believe your current version does not support setting a variable in the client and returning it from the server.

Regards,

Elton S

You are right, the server function did not recognize the client variable. but when I created the JSON object and instead passed it as a context member, then it worked. Is this method still ok for large amounts of text?

Hi Ron,

It should be ok to send the data (JSON.stringify) to the server via context and re-parse it on the server.

Please let me know if you face any issues.

Regards,

Elton S

Thanks Elton

I got that part working. But ChatGPT told me that you can send any valid JavaScript object via context, so I pass that payload as a JSON object. So far it’s working.

Can you advise on the pros and cons of doing it that way vs stringified?

Thanks…

Ron Mittelman

Hi Ron,

The choice between using an object and a stringified depends on where you want to use it, especially if you are crossing system boundaries, and whether the data should be mutable or not.

This is a JavaScript concept; therefore, if you paste this prompt on ChatGPT, it should give a good explanation: ”Pros and Cons of using an object vs stringified in JavaScript”.

Regards,
Elton S

Thanks Elton,

ChatGPT seems to think objects should be stringified if being put into variables or stored in tables. But so far, when in a client function and building a context object, a member can be assigned to the object and it seems to work. I presume five serializes the entire context and deserializes it behind the scenes when calling the server function.