<!-- 
/*
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": "Default Values",
  "Menu": ["Models","Fields / Controls"],
  "Code": [
    "/models/FieldDefault_Standard.json"
  ],
  "Demo": [
    { "url": "jsHarmonyTutorials/FieldDefault_Standard?action=insert&cust_parent_id=1", "title": "Field Default Values - New Child Customer" }
  ]
}
</script>

<h3>Overview</h3>
Default values can be applied to:
<ul>
  <li>Bound database fields during an insert operation</li>
  <li>Unbound fields on page load</li>
  <li>Bound database fields on page load, if the model.layout is "report" or "exec"</li>
</ul>
There are five ways to apply default values:
<ul>
  <li>Using field.default with a static value</li>
  <li>Using field.default with a client-side JavaScript-generated value</li>
  <li>Using field.default with a SQL-generated value</li>
  <li>Sending the default value in the URL querystring</li>
  <li>Returning the default value in the model.sqlselect query (for unbound fields only)</li>
</ul>

Default values are applied in the following priority (highest first):
<ul>
  <li>Querystring</li>
  <li>field.default</li>
  <li>model.sqlselect</li>
</ul>

<h3>Default Value Example</h3>
The following example adds a child customer based on a parent customer ID.  The parent customer ID is passed in the "cust_parent_id" querystring parameter.  Each field has the default value applied in a different way:
<%-getScreenshot('jsHarmonyTutorials/FieldDefault_Standard?action=insert&cust_parent_id=1&popup=1','Field Default Value - Standard')%>
<pre>
{
  "layout":"form",
  "table":"cust",
  "onecolumn":true,
  "breadcrumbs":{"sql":"select (select cust_start_dt from cust where cust_id=@cust_parent_id) parent_start_dt"},
  "title":{ "insert":"Add Child Customer" },
  "caption":["Customer","Customers"],
  "fields":[
    {"name":"cust_id","caption": "ID"},
    {"name":"cust_parent_id","caption": "Parent Customer","lov":{"sql":"select cust_id code_val,cust_name code_txt from cust order by cust_name"}},
    {"name":"cust_name","caption":"Name","default":{ "sql": "select cust_name||' :: Child' from cust where cust_id = @cust_parent_id" }},
    {"name":"cust_sts","caption":"Status","default":"ACTIVE"},
    {"name":"cust_update_dt","caption":"Update Date","control":"date","default":"js:new Date()"},
    {"name":"cust_start_dt","caption":"Start Date","control":"date","default":"js:(function(){ var rslt = new Date(); var parent_start_dt = data && data._bcrumbs && data._bcrumbs.parent_start_dt && new Date(data._bcrumbs.parent_start_dt); if(rslt > parent_start_dt) rslt = parent_start_dt; return rslt; })()"},
  ]
}
</pre>

<h3>field.default</h3>
The syntax of field.default is as follows:
<pre>
//Static default value
"default": "VALUE"

//Client-side JavaScript in-line
"default": "js:'value'"

//Client-side JavaScript function
"default": "js:(function(){ return 'value'; })()"

//SQL-generated value
"default": {
  "sql": "select 'value' from table where key=@key",
  "sql_params": ["cust_id"] //(Optional) Array of parameters.  This is automatically generated by the system.
  "nodatalock":["cust_id"]  //Do not apply datalocks for these datalock keys, if applicable
}
</pre>

<h3 data-level="2">Static</h3>
Static default values always set the default value to the same value:
<pre>
//Static default value
"default": "VALUE"
</pre>
The following example defaults the Customer Status to ACTIVE on insert:
<pre>
{"name":"cust_sts","caption":"Status","default":"ACTIVE"}
</pre>


<h3 data-level="2">Client-side JavaScript</h3>
Client-side JavaScript default values are evaluated each time a record is created.  The JavaScript can either be evaluated as an in-line expression, or as a function:
<pre>
//Client-side JavaScript in-line
"default": "js:'value'"

//Client-side JavaScript function
"default": "js:(function(){ return 'value'; })()"
</pre>
The following two examples use either the in-line or function syntax:
<pre>
{"name":"cust_update_dt","caption":"Update Date","control":"date","default":"js:new Date()"}
{"name":"cust_start_dt","caption":"Start Date","control":"date","default":"js:(function(){ var rslt = new Date(); var parent_start_dt = data && data._bcrumbs && data._bcrumbs.parent_start_dt && new Date(data._bcrumbs.parent_start_dt); if(rslt > parent_start_dt) rslt = parent_start_dt; return rslt; })()"}
</pre>

The following variables are available during evaluation:
<pre>
data      //The current data instance being initialized
jsh       //The jsHarmony instance
XExt      //The jsHarmony JavaScript XExt Client-side Extensions
XForm     //The jsHarmony JavaScript XForm AJAX/CRUD Library
XValidate //The jsHarmony JavaScript XValidate Form Validation Library
XFormat   //The jsHarmony JavaScript XFormat Formatting Library
XPage     //The jsHarmony JavaScript Page controller
_         //Lodash library
$         //jQuery library
moment    //Moment.js library
async     //Async.js library
_GET      //The GET parameters
XModels   //An associative array of the jsHarmony Models currently active on the client browser
xmodel    //The current jsHarmony Model's instance
_this     //The current jsHarmony Model's Class instance (used in Custom Forms / Custom JS)
modelid   //The current jsHarmony Model's ID
</pre>

Client-side JavaScript defaults are evaluated twice - when an internal record is created, and when the metadata is returned from the database.  If additional metadata is returned, the following properties can be available on the data object:
<pre>
data._bcrumbs   //Breadcrumbs SQL results returned from the server
data._LOVs      //List of Values arrays returned from the server
data._defaults  //Default values returned from the server
data._title     //Title returned from the server
</pre>

<h3 data-level="2">SQL</h3>
The default values can also be generated server-side via SQL:
<pre>
//SQL-generated value
"default": {
  "sql": "select 'value' from table where key=@key",
  "sql_params": ["cust_id"] //(Optional) Array of parameters.  This is automatically generated by the system.
  "nodatalock":["cust_id"]  //Do not apply datalocks for these datalock ids, if applicable
}
</pre>
The field.default.sql command can use input parameters, if they are defined as fields in the model.  Parameters start with an "@" sign.  For example, to use the field named "cust_id" in the SQL expression, the parameter would be "@cust_id".<br/>
<br/>
The field.default.sql_params property contains an array of the parameters that will be passed to field.default.sql.  When a parameter is used in the field.default.sql command, it is automatically added to the field.default.sql_params array.  All sql_params must be defined as fields in the model.  Values will be pulled from the querystring or bindings.<br/>
<br/>
When using the default values in a site with datalocks, it is necessary to add a %%%DATALOCKS%%% expression to the where clause of field.default.sql.  If datalocks can safely be ignored for the field, the datalock id can instead be added to the field.default.nodatalock array.<br/>
<br/>
The following example uses a SQL default value to set the default value for the Customer Name based on the parent Customer Name.
<pre>
{"name":"cust_name","caption":"Name","default":{ "sql": "select cust_name||' :: Child' from cust where cust_id = @cust_parent_id" }}
</pre>

<h3>Querystring</h3>
If a field name is in the URL's querystring, the value will be automatically applied as the default value.  The field will then be set as read-only, unless field.locked_by_querystring is set to false.

<h3>Using model.sqlselect</h3>
The model.sqlselect statement can be used to populate default values for unbound fields.  Since the model.sqlselect is used during a Browse or Update action, the bound fields will all have data returned from the database.  Unbound fields are not bound to the database, however if the field name is found in the database results, it will be applied to the field.<br/>
<br/>
An example of using model.sqlselect with unbound fields is available in the <a href="/tutorials/field_unbound#unbound_initial_default_values">Unbound Controls</a> tutorial.