FORUM PLAN UPDATE
Date revision: This forum will remain open to new posts and responses until December 1, 2018. (After that date, you will still be able to view and search the forum.) Also, we're taking a second look at the best place to host future conversation. For now, keep using this forum, and stay tuned for more news.



Oct 8, 2012, 4:30 PM
13 Posts

Order of display of JSON values in Repeat Control

  • Category: Other
  • Platform: Windows
  • Release: 8.5.3
  • Role: Developer
  • Tags: Sorting JSON Repeat RC xp:repeat
  • Replies: 4
I have a repeat control that displays values in a JSON array. My issue is that the values are displayed in the Repeat Control in a different order than they are written to the JSON array. I'm trying to determine how they are getting mis-matched, and more importantly, how to line them up.
 
Here's a link to a picture outlining the details on this:
 
Thanks in advance!
Crista   
Oct 9, 2012, 12:08 AM
366 Posts
Re: Order of display of JSON values in Repeat Control
 How are the values getting stored into the session scope variable? 
 
What is the code that produces the json stream? 
 
 
Oct 9, 2012, 1:15 PM
13 Posts
Re: Order of display of JSON values in Repeat Control
There is a lot of code... too much to include all of it here. So, I've included the key pieces (stripped of non-relevant code) below. It works *most* of the time, but every once in a while the JSON value order does not match the repeat control order. I guess I thought they always should. Thanks for offering your time to help. :)
 

<xp:repeat var="rowData" indexVar="rowIndex" repeatControls="false"

      id="docsRepeatPortfolio_OpenShops" rows="17">

<xp:this.value><![CDATA[#{javascript:

TemplateSearch.search('viewScope', 'searchQueryString', session.getServerName(), applicationScope.leasesDBPath,

[{

                  fieldName: 'OS_UNID',

                  formula: '@Text(@DocumentUniqueID)',

                  dataType: 'string'

            },{

                  fieldName: 'OS_DBA',

                  formula: 'LeaseName',

                  dataType: 'string'

            },{

                  fieldName: 'OS_DBA',

                  formula: 'LeaseName',

                  dataType: 'string'

            },{

                  fieldName: 'OS_VVFlag',

                  formula: 'VV_Flag',

                  dataType: 'string'

            }], 'jsonValuesPortfolio');

}]]></xp:this.value>

      <xp:tr id="trowPortfolio_OpenShops">

            <xp:td>

                  <xp:text escape="true"

id="dtaPortOSDBA"

value="#{rowData.OS_DBA}">

            </xp:td>

            <xp:td>

                  <xp:text escape="true"

id="dtaPortOSVVFlag"

value="#{rowData.OS_VVFlag}">

            </xp:td>

      </xp:tr>

</xp:repeat>

 

SSJS Library Template Search function:

var TemplateSearch = {

      // Templates to build the value-parts from

      "template-js-date-only": "@If( $formula='' ; 'null' ; '/Date(\"' + " + "$formula + '\")/' )",

      "template-string": "'\"' + $formula + '\"'",

      "template-multi-string": "'[\"' + @Implode( $formula ; '\",\"' ) + '\"]'",

      "template-number": "@Text( $formula )",

      "template-multi-number": "'[' + @Implode( @Text( $formula ) ; ',' ) + ']'",

      "template-date": "@If( $formula='' ; 'null' ; '/Date(\"' + "

            + "@Implode(@Text(@Year($formula):@Month($formula):@Day($formula)) ; '/' ) + ' ' + "

            + "@Implode(@Text(@Hour($formula):@Minute($formula):@Second($formula)) ; ':' ) + '\")/' )",

      "template-date-only": "@If( $formula='' ; 'null' ; '/Date(\"' + "

            + "@Implode(@Text(@Year($formula):@Month($formula):@Day($formula)) ; '/' ) + ' ' + "

            + "@Implode(@Text(0:0:0) ; ':' ) + '\")/' )",

      "template-multi-date":"@If( $formula='' ; 'null' ; '[/Date(\"' + @Implode( @Transform( $formula ; 'date' ;"

            + "@Implode( @Text(@Year(date):@Month(date):@Day(date)) ; '/' ) + ' ' + "

            + "  @Implode( @Text(@Hour(date):@Minute(date):@Second(date)) ; ':' ) ); '\")/,/Date(\"' ) + '\")/]' )",

     

      // Helper-method to build a string that can be evaluated in formula-language against a document

      buildJSONFormulaTemplate: function( fieldDefinitions ){

            var formulaTemplateItems = [];

            for( var i=0; i < fieldDefinitions.length; i++ ){

                  var field = fieldDefinitions[i];               

                  var valuePart = this['template-' + field.dataType].replace( /\$formula/g, field.formula );

                  formulaTemplateItems.push( "'\"" + field.fieldName + "\":' + " + valuePart );

                  }

                 

            return "'{' + " + formulaTemplateItems.join( " + ',' + " ) + " + '}'";

                       

      },

     

      /*

            query: The FTSearch-query

            fields: an array of objects describing the template fields with fieldName, formulaString, dataType

            dataType:   string, multi-string, number, multi-number, date, multi-date

      */

      search: function( queryScopeType:String, dbServerName:String, dbFilePath:String, fieldDefinitions, jsonVarName:String){

           

            var functionName:String = "search";

            var queryString = viewScope.get( queryScopeName );

var jsonValues = viewScope.get(jsonVarName);

 

            try {

                             

                  if( !jsonValues || scopedVariableChanged( queryScopeType, queryScopeName ) ){

                        var dbToSearch:NotesDatabase = session.getDatabase(dbServerName,dbFilePath)

                        var resultCol:NotesDocumentCollection = dbToSearch.FTSearch( queryString );

                        //viewScope.aaResultCount = resultCol.getCount();

                        var resultDoc:NotesDocument = resultCol.getFirstDocument();

                        //viewScope.aaResultDocId = resultDoc.getUniversalID();

                        var jsonFormulaTemplate = this.buildJSONFormulaTemplate( fieldDefinitions );

                        //viewScope.aaJSONFormulaTemplate = jsonFormulaTemplate;

                        var jsonItems = [];

                        var sumFields = getSummedFieldsArray(fieldDefinitions);

                        viewScope.sumFields = sumFields;

                        var averagedFields = getAveragedFieldsArray(fieldDefinitions);

                        viewScope.averagedFields = averagedFields;

                       

                        while( resultDoc !== null ){

                              var jsonFormulaTemplateJS = evaluateJSFunctions(resultDoc, jsonFormulaTemplate);

                              jsonItems.push( session.evaluate( jsonFormulaTemplateJS, resultDoc )[0] );

                              // both of these operations require the field values to be summed. Averages will be calced after looping through all docs

                             

                              resultDoc = resultCol.getNextDocument();

                        }          

                       

                        jsonValues = Lookup.parseJSONArray( jsonItems );     

                        viewScope.put( 'numValues' + jsonVarName, jsonValues.length );

                  }

            } catch (e) {

                  handleDashboardError(functionName, e);

            }

 

            var jsonValuesSorted = Lookup.sortJSONArray( jsonValues, viewScope.get(sortScopeName), viewScope.get(sortScopeName2), viewScope.get(sortScopeDirection));

     

            viewScope.put(jsonVarName, jsonValuesSorted);                    

            return jsonValuesSorted;

      }

}

 

Here is the db Search string that is set before the repeat control is loaded:

searchQueryString = "(FIELD Form = LeaseRecord) AND (FIELD LeaseStatus = Active) AND (FIELD E1_ABS_Flag = True)";

 
 
Oct 11, 2012, 8:33 AM
261 Posts
Re: Order of display of JSON values in Repeat Control
Hello Crista,
 
In the screenshot I noticed that you're using my Debug Toolbar to list the contents of the viewScope, so I had a look at the source code of it to make sure that that wasn't the problem. It does do some sorting when dumping an object, but only for the object's properties, not the order of the objects.
 
Looks like you're using the TemplateSearch method written by Tommy Valand. That script performs a sort function too on the results (the JSON array) based on parameters in the viewScope:
 
var jsonValuesSorted = Lookup.sortJSONArray( jsonValues, viewScope.get(sortScopeName), viewScope.get(sortScopeName2), viewScope.get(sortScopeDirection));
 
Are those values set at all? It might be that it doesn't sort when they're not available.
 
Another issue might be the order in which values are read from/ stored in the viewScope causing the differences. You might want add a dump of the search results to the toolbar right after they're retrieved (in the "value" attribute of the repeat) using:
 
dBar.dump( viewScope.jsonValuesPortfolio );
 
or do a  
 
var searchResults = TemplateSearch.search('viewScope', .....); 
dBar.dump(searchResults); 
return searchResults; 
 
Mark 
 

Oct 11, 2012, 2:39 PM
13 Posts
Re: Order of display of JSON values in Repeat Control
Thanks, Mark. I'll try both of your recommendations. So, I guess to answer my basic question - it does seem that the orders should match.
 
Thanks, too, for the toolbar. It is amazing! (I never knew where it came from -- someone else had found it before I came along :).
 
Cheers!
Crista

FORUM PLAN UPDATE
Date revision: This forum will remain open to new posts and responses until December 1, 2018. (After that date, you will still be able to view and search the forum.) Also, we're taking a second look at the best place to host future conversation. For now, keep using this forum, and stay tuned for more news.