Search code examples
xpagesxpages-ssjs

Moving round content dynamically


I have an xpage, where fields are created dynamically. By default, there are 3, but you can click a button to add as many as you like, naming convention "ObjectiveDetails1", "ObjectiveDetails2" and so on.

I am trying to handle blank fields... For example, there is content in fields 1 and 2, nothing in 3 and 4, but content in 5. What I want to do, is shift content from field 5 into the first available blank, in this case 3. Likewise, if there is content in fields 1, 2, 4, 5, I then need content in 4, to go into field 3, and content in 5 to go into field 4 etc. At the moment, I'm managing to shift content up 1 only.

So if fields 2, 3, 4 are blank but 5 has content, it only moves the content into 4, where-as I need it to move into field 2.

I hope I've explained this well enough..... Current code is a little messy....

for (var i = 1; i < viewScope.rows+1; i++) {
print("Starting Array.....");
if(applicationScope.get("BreakAllCode")==true){
  break;
}
var objFieldName:string = "ObjectiveDetails" +i;
print ("Field Name: " + objFieldName);

var fieldValue = document1.getItemValueString(objFieldName);

print ("Field Value: " + fieldValue);
if (fieldValue =="" || fieldValue==null){
    print("EMPTY"); 

    // We now need to delete the 3 fields related to this objective
    var updFieldName:string = "ObjectiveUpdates" +i;
    var SAFieldName:string = "ObjectiveSelfAssessment" +i;

    // Before we delete the fields, we need to check if the next field is blank
    // and if not, copy its contents into this field.

    for (var n =i+1; n < viewScope.rows+1; n++) {
    if(applicationScope.get("BreakAllCode")==true){
     break;
    }

        if(document1.hasItem("ObjectiveDetails" +n)){       
            print("Next field: " +"ObjectiveDetails" +n);
            var nextFieldValue = document1.getItemValueString("ObjectiveDetails" +n);

            if (!nextFieldValue =="" || !nextFieldValue==null){
                // Now copy the content into the field
                var nextFieldName:string = "ObjectiveDetails" +n;
                var previousNo = n-1;
                var previousFieldName:string = "ObjectiveDetails" +previousNo;
                print ("Previous field: " + previousFieldName);
                document1.replaceItemValue(previousFieldName,nextFieldValue);

                // Now clear the content from next field
                document1.replaceItemValue(nextFieldName,"");
            }else{
                // Do nothing
            }
        }else{
            print("Last field");
        }
    }
    // Remove items from the document
    //document1.removeItem(objFieldName);
    //document1.removeItem(updFieldName);
    //document1.removeItem(SAFieldName);

    // Remove fields from our arrays
    //viewScope.fields.splice(i-1, 1);
    //viewScope.fields2.splice(i-1, 1);
    //viewScope.fields3.splice(i-1, 1);

    // Update the row variable
    //viewScope.rows--;
    //document1.replaceItemValue("rows",viewScope.rows);
    //document1.save();

    // We now need to "re-index" the array so that the fields are numbered corectly

}else{
    print("We have a value");
}
}

Update with beforePageLoad:

viewScope.rows = document1.getItemValueInteger("rows");

var rowCount:integer = viewScope.rows;
var newCount:integer = 0;

while(newCount<rowCount){
if (!viewScope.fields) {
    viewScope.fields = [];
    viewScope.fields2 = [];
    viewScope.fields3 = [];
}

viewScope.fields.push("ObjectiveDetails" + (viewScope.fields.length + 1));
viewScope.fields2.push("ObjectiveUpdates" +  (viewScope.fields2.length + 1));
viewScope.fields3.push("ObjectiveSelfAssessment" +  (viewScope.fields3.length + 1));

newCount++;
}

Solution

  • This should be your core algorithm:

    var writeIndex = 0;
    for (var readIndex = 1; readIndex <= viewScope.rows; readIndex++) {
        var value = document1.getItemValueString("ObjectiveDetails" + readIndex);
        if (value) {
            writeIndex++;
            if (readIndex !== writeIndex) {
                document1.removeItem("ObjectiveDetails" + readIndex);
                document1.replaceItemValue("ObjectiveDetails" + writeIndex, value);
            }
        } else {
            document1.removeItem("ObjectiveDetails" + readIndex);
        }
    }
    viewScope.rows = writeIndex;
    

    The code

    • deletes all empty fields,
    • renames fields to ObjectiveDetails1, ObjectiveDetails2, ObjectiveDetails3,... and
    • writes the resulting number of rows back to viewScope variable "rows".