<!-- 
/*
Copyright 2017 apHarmony

This file is part of jsHarmony.

jsHarmony is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

jsHarmony is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this package.  If not, see <http://www.gnu.org/licenses/>.
*/
-->
<script type="text/x-tutorial-info">
{
  "Title": "Breadcrumbs",
  "Menu": ["Models","Models Overview"],
  "Code": [
    "/models/ModelBreadcrumbs_Cust_Listing.json",
    "/models/ModelBreadcrumbs_Cust.json",
    "/models/ModelBreadcrumbs_CustContact_Listing.json",
    "/models/ModelBreadcrumbs_CustContact.json"
  ],
  "Demo": "jsHarmonyTutorials/ModelBreadcrumbs_Cust_Listing"
}
</script>

<h3>Breadcrumbs Overview</h3>
Breadcrumbs are links rendered at the top of the form, to show the hierarchy of the parents of a page, and give the user a way to navigate back up the tree.<br/>
</br>
User interface best practices recommend using breadcrumbs on all second-level pages (excluding popup windows / tabs).

<%-getScreenshot('jsHarmonyTutorials/ModelBreadcrumbs_CustContact?action=update&cust_contact_id=2&popup=1','Breadcrumbs')%>

<h3>Breadcrumbs Syntax</h3>
<pre>
{
  "breadcrumbs": {
    "parents": [ "[i]breadcrumb_expression1[/i]", ""[i]breadcrumb_expression2[/i]", ... ],
    "title": "[i]breadcrumb_expression[/i]",

    //Optional Parameters
    "sql": "select cust_id,cust_name from cust where cust_id=isnull(@cust_id,(select cust_id from cust_contact where cust_contact_id=@cust_contact_id))", //SQL statement to populate data for breadcrumbs
    "sql_params": ["cust_id","cust_contact_id"], //Array of field names used in the SQL statement - these values are automatically populated on system load
    "nodatalock": ["cust_id"]          //Disable datalocks (should not be used in most implementations as this potentially reduces security)
  }
}

[i]breadcrumb_expression[/i] :=
  "MODELID", or
  "HTML/EJS String", for example "<a href='Cust_Container?action=update&cust_id=<#=bcrumbs.cust_id#>'><#=bcrumbs.cust_name#></a>"

Any EJS in breadcrumb_expression is escaped with <# #>, and is evaluated with the following parameters:
{
  data:     Merged array of:
                forcequery (model.querystring parameters)
                Topmost Form SQL Data
                Topmost Form Binding Values
  bcrumbs:  Merged array of the breadcrumb SQL resultsets of all forms and subforms
  _GET:     Querystring parameters
  jsh:      jsHarmony Client object
  instance: Instance name of the jsHarmony Client object, ex. "jshInstance"
}
</pre>

Breadcrumb parents are generally rendered as links.  The final breadcrumb (the current page) is rendered as follows:
<ol>
  <li>Use "model.breadcrumbs.title" / "model.breadcrumbs.insert.title" / "model.breadcrumbs.browse.title" / "model.breadcrumbs.update.title", if it exists</li>
  <li>Otherwise, use "model.title" / "model.insert.title" / "model.browse.title" / "model.update.title", if it is a string and not a SQL expression</li>
</ol>

<h3 data-level="2">Different breadcrumbs for "insert", "browse", and "update" modes</h3>
Breadcrumbs can be customized based on whether the user is inserting, viewing, or updating a record:

<pre>
{
  "breadcrumbs": {
    "parents": ["Cust_Listing"],
    "insert": {
      "title": "New Customer"
    },
    "browse": {
      "sql": "select cust_name from cust where cust_id=@cust_id",
      "title": "<#=bcrumbs.cust_name#>"
    },
    "update": {
      "sql": "select cust_name from cust where cust_id=@cust_id",
      "title": "<#=bcrumbs.cust_name#>"
    }
  }
}
</pre>
On an update action, if the "update" breadcrumb is not set, the "browse" breadcrumb will be used.<br/>
Similarly, on a browse action, if the "browse" breadcrumb is not set, the "update" breadcrumb will be used.<br/>
<br/>
Any of the breadcrumb parameters for "model.breadcrumbs.insert", "model.breadcrumbs.browse" or "model.breadcrumbs.update" will fall back to "model.breadcrumbs" if they are not set.

<h3>Breadcrumb Expressions</h3>
Breadcrumbs can be defined a variety of ways:

<h4>Model ID (Linking to a Model without Parameters)</h4>
If the parent model has no parameters, link directly to the model name:
<pre>
{
  "breadcrumbs": {
    "parents": ["ModelBreadcrumbs_Cust_Listing"]
  }
}
</pre>

<h4>Custom HTML (Linking to a Model with a Custom Caption)</h4>
The breadcrumb can be custom HTML, for instance when linking to a the parent model with a custom breadcrumb caption:
<pre>
{
  "breadcrumbs": {
    "parents": ["<a href='/ModelBreadcrumbs_Cust_Listing'>All Customers</a>"]
  }
}
</pre>

<h4>Using Breadcrumb SQL Data (Linking to a Model with Parameters)</h4>
If the parent form has parameters and should open to a specific record, use an EJS expression.  Any breadcrumbs SQL results are loaded into the "bcrumbs" parameter.<br/>
<br/>
In the example below, a different SQL expression needs to be used for "insert" and "browse" breadcrumbs, because the key field is not available during an "insert" operation.
<pre>
{
  "breadcrumbs": {
    "parents": ["<a href='/ModelBreadcrumbs_Cust?action=update&cust_id=<#=bcrumbs.cust_id#>'><#=bcrumbs.cust_name#></a>"],
    "insert": {
      "sql": "select cust_id,cust_name from cust where cust_id=@cust_id",
      "title": "New Contact"
    },
    "browse": {
      "sql": "select cust_contact.cust_id,cust_name,cust_contact_name from cust_contact inner join cust on cust_contact.cust_id=cust.cust_id where cust_contact_id=@cust_contact_id",
      "title": "<#=bcrumbs.cust_contact_name#>"
    }
  }
}
</pre>

<h4>Setting tabs in a linked model</h4>
Tabs are specified as a querystring parameter, in the format: { "PARENT_MODEL": "SELECTED_TAB_MODEL" }.  The double-quotes must be escaped with a backslash \".
<pre>
{
  "breadcrumbs": {
    "parents": ["<a href='/Cust_Container?action=update&cust_id=<#=bcrumbs.cust_id#>&tabs={\"Cust_Container\":\"Cust_Contact_Listing\"}'><#=bcrumbs.cust_name#></a>"],
  }
}
</pre>

<h4>Using Form Data</h4>
If the breadcrumbs can be initialized via form / querystring data, use the "data" EJS expression.
<pre>
{
  "breadcrumbs": {
    "parents": ["<a href='/ModelBreadcrumbs_Cust?action=update&cust_id=<#=data.cust_id#>'>Edit Customer</a>"],
    "insert": {
      "title": "New Contact"
    },
    "update": {
      "title": "<#=data.cust_contact_name#>"
    }
  }
}
</pre>
The "data" expression is a merged array of:
<ul>
  <li>Querystring Parameters</li>
  <li>Topmost Form SQL Data</li>
  <li>Topmost Form Binding Values</li>
</ul>

<h4>Using GET / Querystring Data</h4>
Although not recommended since it limits how a form can be used as a subform, querystring parameters can be used in breadcrumbs via:
<pre>
{
  "breadcrumbs": {
    "parents": ["<a href='/ModelBreadcrumbs_Cust?action=update&cust_id=<#=_GET.cust_id#>'>Edit Customer</a>"],
    "insert": {
      "title": "New Contact"
    },
    "update": {
      "title": "Edit Contact"
    }
  }
}
</pre>

<h3>Using Breadcrumbs SQL Data in the Title and Model Body</h3>
Breadcrumb SQL data can be used in the model title and in the body.  This technique can be useful to optimize the number of SQL statements, or to use metadata from the database.

<h4>Using Breadcrumbs Data in the Title</h4>
The model title has access to the same "bcrumbs" object as the breadcrumbs:
<pre>
{
  "title": "Customer <#=bcrumbs.CUSTOMER_ID#>"
}
</pre>

<h4>Using Breadcrumbs Data in the Model Body</h4>
The breadcrumbs SQL data for each model is stored in the "data._bcrumbs" property:
<pre>
{
  "fields": [
    {"name":"sys_user_name_asgn","type":"varchar","actions":"BIU","control":"textbox","default":"js:data._bcrumbs.sys_user_name_asgn"}, 
  ]
}
</pre>
The canonical reference to the "_bcrumbs" property is:
<pre>
jshInstance.XModels["MODELID"].controller.GetBreadCrumbs()
</pre>