Background Color:
 
Background Pattern:
Reset
Search
Home Recent Changes Show All Pages

Part 3. Choices and Conditions

Not Rated Yet

This article is the 3rd of a 5 part course in complex data-binding with namespaces, making choices, dynamic parameters and dynamic data.

 

Course Contents

 

When data-binding with the scryber library you are not just limited to looping. We can also alter the flow and generated content, by making decisions with the Choice component and the If component.

 

Article Contents

 

In our third article on binding we can cover off the way to dynamically change content based on data and context. If you have not read the previous articles it would be worthwhile catching up with Part 1. Data binding and XPath selectors and Part 2. Multiple Namespaces and Transformations first.

Using an If

 

The <data:If test="..." /> component is a simple decision point. The test xpath expression will be evaluated when the If component is data-bound. The text expression must evaluate to a boolean result. If true then the inner template content will be generated and added to the component hierarchy. There can be any content within the Template - but if the inner components cannot be added to the outer container (e.g. Divs into table rows) an error may be thrown.

 

<pdf:Div style:class="outer-wrapper" >
    <data:If test="@match = 1" >
      <Template>
        <pdf:Div style:class="inner-content" >
          This content will only be generated if the match attribute is equal to 1
        </pdf:Div>
      </Template>
    </data:If>
    <pdf:Div style:class="inner-content" >
      This content is outside of the If component and will always be generated.
    </pdf:Div>
</pdf:Div>

 

Once the template content has been created, it too will be data-bound, so nested flow, loops and decisions are fully supported.

NOTE: There must be a current data context for a test expression to be evaluated. The If component must be nested within a ForEach (even if the content is a single result)

 

Using a Choice

 

The <data:Choice > component allows for multiple decision points where the first matching test of the inner <data:When test="..." /> component will be generated, if non of the tests match then the optional <data:Otherwise /> content will be created and used.

 

  <pdf:Div style:class="outer-wrapper" >
	<data:Choose>
	  <data:When test="@match = 1" >
	    <Template>
	      <pdf:Div style:class="inner-content" >
	        This content will only be generated if the match attribute is equal to 1
	      </pdf:Div>
	    </Template>
	  </data:When>

	  <data:When test="@match = 2" >
	    <Template>
	      <pdf:Div style:class="inner-content" >
	        This content will only be generated if the match attribute is equal to 2
	      </pdf:Div>
	    </Template>
	  </data:When>

	  <data:When test="@match &gt; 2" >
	    <Template>
	      <pdf:Div style:class="inner-content" >
	        This content will only be generated if the match attribute is greater than 2
	      </pdf:Div>
	    </Template>
	  </data:When>

	  <data:Otherwise>
	    <Template>
	      <pdf:Div style:class="inner-content" >
	        This content will only be generated if the match attribute is less than or equal to 0 (Zero)
	      </pdf:Div>
	    </Template>
	  </data:Otherwise>

	</data:Choose>
  </pdf:Div>

 

NOTE: Again there must be a current data context for a test expression to be evaluated. The Choose component must be nested within a ForEach (even if the content is a single result)

Making the Changes

 

So in our example we can apply a decision based on the actual sales value for each quarter, and alter the output accordingly. And we can also add a banner to the bottom if we are globally under target.

    <pdf:Page id="MyChoiceOutput" outline-title="Choices" >
      <Content>

        <data:ForEach select="e:wrapper" datasource-id="MyChoiceSalesData" >
          <Template>

            <!-- Separate template for the env:copy/s:sales/s:summary-->
            <data:ForEach select="e:copy/s:sales/s:summary" >
              <Template>
                <pdf:Div id="titles" style:margins="10pt">
                  <pdf:H1 id="heading" text="{xpath:s:heading}" />
                  <pdf:H3 id="subhead" text="{xpath:s:subhead}" />
                  <pdf:Div id="desc" >
                    <pdf:Label text="{xpath:s:description}" />
                  </pdf:Div>
                </pdf:Div>
              </Template>
            </data:ForEach>

            <pdf:Table id="salesgrid" style:full-width="true" style:font-size="14pt" style:margins="10pt" >
              <pdf:Header-Row >
                <pdf:Header-Cell>Region</pdf:Header-Cell>
                <pdf:Header-Cell> Q1</pdf:Header-Cell>
                <pdf:Header-Cell> Q2</pdf:Header-Cell>
                <pdf:Header-Cell> Q3</pdf:Header-Cell>
                <pdf:Header-Cell> Q4</pdf:Header-Cell>
                <pdf:Header-Cell>Total</pdf:Header-Cell>
              </pdf:Header-Row>

              <!-- All region rows in sales -->
              <data:ForEach select="e:copy/s:sales/s:data/s:region" >
                <Template>
                  <pdf:Row>
                    <pdf:Cell>
                      <pdf:Label text="{xpath:s:name}" />
                    </pdf:Cell>
                    <data:ForEach select="s:quarter" >
                      
                      <Template>
                        <!-- Using a choose component to apply styles based on sales value -->
                        <data:Choose>
                          <data:When test="@books_sold &gt; 30000" >
                            <Template>
                              <pdf:Cell style:bg-color="#88FF88">
                                <pdf:Number value="{xpath:@books_sold}" style:number-format="C" />
                              </pdf:Cell>
                            </Template>
                          </data:When>
                          <data:When test="@books_sold &lt; 20000" >
                            <Template>
                              <pdf:Cell style:bg-color="#FF8888">
                                <pdf:Number value="{xpath:@books_sold}" style:number-format="C" />
                              </pdf:Cell>
                            </Template>
                          </data:When>
                          <data:Otherwise>
                            <Template>
                              <pdf:Cell>
                                <pdf:Number value="{xpath:@books_sold}" style:number-format="C" />
                              </pdf:Cell>
                            </Template>
                          </data:Otherwise>
                        </data:Choose>
                      </Template>
                    </data:ForEach>
                    <pdf:Cell>
                      <pdf:Number value="{xpath:(s:quarter[@number='1']/@books_sold + 
								s:quarter[@number='2']/@books_sold + s:quarter[@number='3']/@books_sold + 
								s:quarter[@number='4']/@books_sold)}" style:number-format="C" />
                    </pdf:Cell>
                  </pdf:Row>
                </Template>
              </data:ForEach>

              <!-- footer row from env:totals-->
              <data:ForEach select="e:totals" >
                <Template>
                  <pdf:Footer-Row style:font-bold="true">
                    <pdf:Footer-Cell>
                      Total
                    </pdf:Footer-Cell>
                    <data:ForEach select="e:quarter" >
                      <Template>

                        <!-- Using a choose component to apply styles based on total sales value -->
                        <data:Choose>
                          <data:When test="@books_sold &gt; (30000 * 3)" >
                            <Template>
                              <pdf:Cell style:bg-color="#88FF88">
                                <pdf:Number value="{xpath:@books_sold}" style:number-format="C" />
                              </pdf:Cell>
                            </Template>
                          </data:When>
                          <data:When test="@books_sold &lt; (20000 * 3)" >
                            <Template>
                              <pdf:Cell style:bg-color="#FF8888">
                                <pdf:Number value="{xpath:@books_sold}" style:number-format="C" />
                              </pdf:Cell>
                            </Template>
                          </data:When>
                          <data:Otherwise>
                            <Template>
                              <pdf:Cell>
                                <pdf:Number value="{xpath:@books_sold}" style:number-format="C" />
                              </pdf:Cell>
                            </Template>
                          </data:Otherwise>
                        </data:Choose>

                      </Template>
                    </data:ForEach>
                    
                    <pdf:Footer-Cell>
                      <pdf:Number value="{xpath:(e:quarter[@number='1']/@books_sold + 
							e:quarter[@number='2']/@books_sold + e:quarter[@number='3']/@books_sold + 
							e:quarter[@number='4']/@books_sold)}" style:number-format="C" />
                    </pdf:Footer-Cell>
                  </pdf:Footer-Row>
                </Template>
              </data:ForEach>

            </pdf:Table>
            <data:If test="(e:totals/e:quarter[@number='1']/@books_sold + e:totals/e:quarter[@number='2']/@books_sold +
 					e:totals/e:quarter[@number='3']/@books_sold + e:totals/e:quarter[@number='4']/@books_sold) &lt; (30000 * 3 * 4)" >
              <Template>
                <pdf:Div style:border-color="red" style:padding="10" style:margins="10" 
							style:font-size="16" style:bg-color="#FFCCCC" style:fill-color="red" 
							style:h-align="Center" >
                  <pdf:Label>The total sales for the year was below the target of </pdf:Label>
                  <pdf:Number value="360000" style:number-format="C" />
                </pdf:Div>
              </Template>
            </data:If>
          </Template>
        </data:ForEach>
        
      </Content>
    </pdf:Page>

 


What is wrong with this example

 

This example shows how we can use the choice and if components to make decisions and alter the output of our document, but in this case especially we are hard coding business logic within the template to achieve the desired results.

There must be a better way to do this in scryber - and there is with Part 4. Transform Parameters

See Also.

 



  Rating
Rate This Page: Poor Great   |  Rate Content |
Average rating:  No Ratings Yet   
Number of Ratings : 0
  Comments
Add Comment
No Comments Yet