0
votes

I have the following button that can save multiple values in a for loop using computeWithForm

//to keep the code simple, I use hardcode value to save document except values in for loop  
var forloopvalues = @DbLookup(@DbName(),"CompetencyCourseViewCourseFirst", "myFieldValue1",2 );//use myFieldValue1 to lookup in the view
var date ="13/03/2017";
for(var i =0;i<forloopvalues.length;i++)
{
    var mdoc = database.createDocument();
    cdate = session.createDateTime(date);           
    mdoc.replaceItemValue("Form", "myForm");
    mdoc.replaceItemValue("myField1","myFieldValue1")
    mdoc.replaceItemValue("myField2", forloopvalues[i]); //suppose there are four values in the forloopvalues
    mdoc.replaceItemValue("myField3","myFieldValue3");
    mdoc.replaceItemValue("myField4", "myFieldValue4");
    mdoc.replaceItemValue("myField5", "myFieldValue5");

    if(mdoc.computeWithForm(false,false))
    {       
        mdoc.save(true, true);  
        getComponent("computedField1").setValue("Record saved"); 
    }
    else
    {
    }   
}

When I click the button, it can save the document. In the Lotus Notes Client, I can see there are four documents in the view. All the computed fields in the form also filled. However, I notice myField2 only saves the first value in forloopvalues not all values. So although there are four documents, both of them save the first value only in myField2. Therefore, if the computed field in the form that contains myField2 plus other values, it only show the first value in myField2 plus other values

I review the code, there is forloopvalues[i] within the for loop and I don't understand why it only saves the first value only.

For example, assume forloopvalues are valueA, valueB, valueC, valueD. The myField2 only save valueA four times. If there is a computed field in the form that connect myField2 with other values together, the computed field value show valueA+othervalues four times.

I have another attempt, if I use document.save() + On document save in Run form validation in Data tab

In Lotus Notes Client to open the view and read the saved document. It will not show computed field in the form but the loop value is correct

For example, assume forloopvalues are valueA, valueB, valueC, valueD. The myField2 save valueA, valueB, valueC, valueD for each document. If there is a computed field in the form that connect myField2 with other values together, the computed field value show each forloopvalues+othervalues four times (e.g. valueA+othervalues, valueB+othervalues, valueC+othervalues, valueD+othervalues)

I believe computeWithForm is almost near the result although it save the first value in forloopvalues only. In Help Contents, I search about computeWithForm. It's syntax is computeWithForm(dodatatypes:boolean, raiseerror:boolean) : boolean

and compare to the code in the application I think the syntax is fine. I double check the for loop and not understand why it only save the first value.

So how can I use computeWithForm to save the loop value. Thanks a lot.

update

I think computeWithForm is almost near the result because it can fill all the computed field in the form, but it saves one value in multiple times depends on the number of forloopvalues.

If forloopvalues has one value only, then it saves one time. It forloopvalues has three values, it save three times, each document (in myField2) contains the value of forloopvalues.

If I use document.save(), it can save documents for each value in forloopvalues individually but it will not fill the computed field in the form.

update

I try the following code to see if the value appears correctly inside the function

var forloopvalues = @DbLookup(@DbName(), "CompetencyCourseViewCourseFirst", "myFieldValue1", 2);
for (var index in forloopvalues) {
    if (forloopvalues.hasOwnProperty(index)) {
       makeAnewDoc(forloopvalues[index]);
    }
}

function makeAnewDoc(field2Value) {
    var mdoc = database.createDocument();
    cdate = session.createDateTime(date);
    mdoc.replaceItemValue("Form", "myForm");
    mdoc.replaceItemValue("myField1", "myFieldValue1")
    mdoc.replaceItemValue("myField2", field2Value);
    if (!viewScope.resultMessage) {
        viewScope.resultMessage = [];
    }
    if (mdoc.computeWithForm(false, false)) {
        mdoc.save(true, true);

        viewScope.resultMessage.push("Record saved " + forloopvalues[index]);
    } else {
        viewScope.resultMessage.push("Save failed for " + forloopvalues[index]);
    }
    // Bleeding memory otherwise!
    mdoc.recycle();
}

The result is when I click the button, the screen can show this message (suppose forloopvalues has four values)

Record saved valueA ,Record saved valueB ,Record saved valueC ,Record saved valueD

Due to the screen can show the forloopvalues, I feel strange why it only saves the same value four times.

2
That one is wrong: viewScope.resultMessage.push("Record saved " + forloopvalues[index]); it must read viewScope.resultMessage.push("Record saved " + fiel2Value); and your cdate needs recycling too. What @formula are in your form? Do they mess with the values? - stwissel
In the form, in myField2, it is computed field. The formula is x:= @DbLookup( "" : "NoCache" ; "" : "" ; "CompetencyCourseViewCourseFirst" ; myFieldValue1; 2 ); @If(@IsError(x);"no data";x), it just similar to var forloopvalues = @DbLookup(@DbName(), "CompetencyCourseViewCourseFirst", "myFieldValue1", 2); - Learner

2 Answers

0
votes

Your code actually would save the last value. Don't loop through the values and save the same document 4 times. ReplaceItemValue can take an array as input. So you can use your lookup result directly. No loop required. Should be faster too

Did misread your question on tiny mobile screen. You need to change your loop slightly:

    var forloopvalues = @DbLookup(@DbName(), "CompetencyCourseViewCourseFirst", "myFieldValue1", 2);
    var mdoc; // In SSJS (ES3 there are no block level variables!)
    for (var index in forloopvalues) {
        if (forloopvalues.hasOwnProperty(index)) {
            mdoc = database.createDocument();
            cdate = session.createDateTime(date);
            mdoc.replaceItemValue("Form", "myForm");
            mdoc.replaceItemValue("myField1", "myFieldValue1")
            mdoc.replaceItemValue("myField2", forloopvalues[index]);

             // Bind your UI field to a scope variable
             // don't access them directly 
             if (!viewScope.resultMessage) {
                 viewScope.resultMessage = [];
             }

            if (mdoc.computeWithForm(false, false)) {
                mdoc.save(true, true);
                viewScope.resultMessage.push("Record saved " + index);
            } else {
                viewScope.resultMessage.push("Save failed for " + index);
            }
            // Bleeding memory otherwise!
            mdoc.recycle();
        }
    }

or better: pull the function to save the document out (variables are function level in SSJS, not block level):

    var forloopvalues = @DbLookup(@DbName(), "CompetencyCourseViewCourseFirst", "myFieldValue1", 2);
    for (var index in forloopvalues) {
        if (forloopvalues.hasOwnProperty(index)) {
           makeAnewDoc(forloopvalues[index]);
        }
    }

    function makeAnewDoc(field2Value) {
        var mdoc = database.createDocument();
        cdate = session.createDateTime(date);
        mdoc.replaceItemValue("Form", "myForm");
        mdoc.replaceItemValue("myField1", "myFieldValue1")
        mdoc.replaceItemValue("myField2", field2Value);
        if (!viewScope.resultMessage) {
            viewScope.resultMessage = [];
        }
        if (mdoc.computeWithForm(false, false)) {
            mdoc.save(true, true);

            viewScope.resultMessage.push("Record saved " + index);
        } else {
            viewScope.resultMessage.push("Save failed for " + index);
        }
        // Bleeding memory otherwise!
        mdoc.recycle();
    }

Let us know how it goes.

0
votes

ComputeWithForm broke at some point in the Domino 9.0.1 fix pack cycle. Not sure which FP broke it. IBM has confirmed this issue and is looking at a fix. The onload, onsave, and both options do not work. SPR #LHEYAKALAH