Actions
Form CRUD - Orders¶
- Table of contents
- Form CRUD - Orders
JSON Schema¶
{
"display": "form",
"components": [
{
"title": "<strong>New Order</strong>",
"collapsible": false,
"key": "NewEmployee",
"type": "panel",
"label": "Panel",
"input": false,
"tableView": false,
"components": [
{
"label": "Order ID",
"applyMaskOn": "change",
"tableView": true,
"customDefaultValue": "value = `ORD${moment().unix().toString().slice(-7)}`;",
"allowCalculateOverride": true,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "OrderID",
"type": "textfield",
"input": true
},
{
"label": "Customer",
"widget": "choicesjs",
"tableView": true,
"dataSrc": "custom",
"data": {
"custom": "values = $ds.Customers;"
},
"idPath": "Col1",
"template": "<span>{{ item['Company Name'] }}</span>",
"clearOnRefresh": true,
"clearOnHide": false,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "Customer",
"type": "select",
"input": true
},
{
"label": "Employee",
"widget": "choicesjs",
"tableView": true,
"dataSrc": "custom",
"data": {
"custom": "values = $ds.Employees;\n"
},
"idPath": "Col0",
"template": "<span>{{ item.FirstName }} {{item.LastName }}</span>",
"clearOnRefresh": true,
"clearOnHide": false,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "Employee",
"type": "select",
"input": true
},
{
"label": "Order Date",
"format": "yyyy-MM-dd HH:mm:ss",
"tableView": false,
"datePicker": {
"disableWeekends": false,
"disableWeekdays": false
},
"timePicker": {
"showMeridian": false
},
"defaultDate": "moment()",
"validate": {
"required": true
},
"enableMinDateInput": false,
"enableMaxDateInput": false,
"validateWhenHidden": false,
"key": "OrderDate",
"type": "datetime",
"input": true,
"widget": {
"type": "calendar",
"displayInTimezone": "viewer",
"locale": "en",
"useLocaleSettings": false,
"allowInput": true,
"mode": "single",
"enableTime": true,
"noCalendar": false,
"format": "yyyy-MM-dd HH:mm:ss",
"hourIncrement": 1,
"minuteIncrement": 1,
"time_24hr": true,
"minDate": null,
"disableWeekends": false,
"disableWeekdays": false,
"maxDate": null
}
},
{
"label": "Required Date",
"format": "yyyy-MM-dd",
"tableView": false,
"datePicker": {
"disableWeekends": false,
"disableWeekdays": false
},
"enableTime": false,
"enableMinDateInput": false,
"enableMaxDateInput": false,
"validateWhenHidden": false,
"key": "RequiredDate",
"type": "datetime",
"input": true,
"widget": {
"type": "calendar",
"displayInTimezone": "viewer",
"locale": "en",
"useLocaleSettings": false,
"allowInput": true,
"mode": "single",
"enableTime": false,
"noCalendar": false,
"format": "yyyy-MM-dd",
"hourIncrement": 1,
"minuteIncrement": 1,
"time_24hr": false,
"minDate": null,
"disableWeekends": false,
"disableWeekdays": false,
"maxDate": null
}
},
{
"label": "Shipped Date",
"format": "yyyy-MM-dd",
"tableView": false,
"datePicker": {
"disableWeekends": false,
"disableWeekdays": false
},
"enableTime": false,
"enableMinDateInput": false,
"enableMaxDateInput": false,
"validateWhenHidden": false,
"key": "ShippedDate",
"type": "datetime",
"input": true,
"widget": {
"type": "calendar",
"displayInTimezone": "viewer",
"locale": "en",
"useLocaleSettings": false,
"allowInput": true,
"mode": "single",
"enableTime": false,
"noCalendar": false,
"format": "yyyy-MM-dd",
"hourIncrement": 1,
"minuteIncrement": 1,
"time_24hr": false,
"minDate": null,
"disableWeekends": false,
"disableWeekdays": false,
"maxDate": null
}
},
{
"label": "Ship Via",
"widget": "choicesjs",
"tableView": true,
"dataSrc": "custom",
"data": {
"custom": "values = $ds.Shippers;\n"
},
"idPath": "Col0",
"template": "<span>{{ item['CompanyName'] }}</span>",
"clearOnRefresh": true,
"clearOnHide": false,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "ShipVia",
"type": "select",
"input": true
},
{
"label": "Freight",
"applyMaskOn": "change",
"mask": false,
"tableView": false,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"validateWhenHidden": false,
"key": "Freight",
"type": "number",
"input": true
},
{
"title": "<strong>Shipment</strong>",
"collapsible": false,
"key": "shipment",
"type": "panel",
"label": "Panel",
"input": false,
"tableView": false,
"components": [
{
"label": "Name",
"applyMaskOn": "change",
"tableView": true,
"calculateValue": "var customer = _.find($ds.Customers, {'Customer ID': data.Customer['Customer ID']});\nvalue = customer ? customer['Contact Name'] : '';\n",
"allowCalculateOverride": true,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "ShipName",
"type": "textfield",
"input": true
},
{
"label": "Address",
"applyMaskOn": "change",
"tableView": true,
"calculateValue": "var customer = _.find($ds.Customers, {'Customer ID': data.Customer['Customer ID']});\nvalue = customer ? customer['Address'] : '';\n",
"allowCalculateOverride": true,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "ShipAddress",
"type": "textfield",
"input": true
},
{
"label": "City",
"applyMaskOn": "change",
"tableView": true,
"calculateValue": "var customer = _.find($ds.Customers, {'Customer ID': data.Customer['Customer ID']});\nvalue = customer ? customer['City'] : '';\n",
"allowCalculateOverride": true,
"validateWhenHidden": false,
"key": "ShipCity",
"type": "textfield",
"input": true
},
{
"label": "Region",
"applyMaskOn": "change",
"tableView": true,
"calculateValue": "var customer = _.find($ds.Customers, {'Customer ID': data.Customer['Customer ID']});\nvalue = customer ? customer['Region'] : '';\n",
"allowCalculateOverride": true,
"validateWhenHidden": false,
"key": "ShipRegion",
"type": "textfield",
"input": true
},
{
"label": "Postal Code",
"applyMaskOn": "change",
"tableView": true,
"validateWhenHidden": false,
"key": "ShipPostalCode",
"type": "textfield",
"input": true
},
{
"label": "Country",
"widget": "choicesjs",
"tableView": true,
"dataSrc": "json",
"data": {
"json": [
{
"name": "Afghanistan",
"code": "AF"
},
{
"name": "Åland Islands",
"code": "AX"
},
{
"name": "Albania",
"code": "AL"
},
{
"name": "Algeria",
"code": "DZ"
},
{
"name": "American Samoa",
"code": "AS"
},
{
"name": "AndorrA",
"code": "AD"
},
{
"name": "Angola",
"code": "AO"
},
{
"name": "Anguilla",
"code": "AI"
},
{
"name": "Antarctica",
"code": "AQ"
},
{
"name": "Antigua and Barbuda",
"code": "AG"
},
{
"name": "Argentina",
"code": "AR"
},
{
"name": "Armenia",
"code": "AM"
},
{
"name": "Aruba",
"code": "AW"
},
{
"name": "Australia",
"code": "AU"
},
{
"name": "Austria",
"code": "AT"
},
{
"name": "Azerbaijan",
"code": "AZ"
},
{
"name": "Bahamas",
"code": "BS"
},
{
"name": "Bahrain",
"code": "BH"
},
{
"name": "Bangladesh",
"code": "BD"
},
{
"name": "Barbados",
"code": "BB"
},
{
"name": "Belarus",
"code": "BY"
},
{
"name": "Belgium",
"code": "BE"
},
{
"name": "Belize",
"code": "BZ"
},
{
"name": "Benin",
"code": "BJ"
},
{
"name": "Bermuda",
"code": "BM"
},
{
"name": "Bhutan",
"code": "BT"
},
{
"name": "Bolivia",
"code": "BO"
},
{
"name": "Bosnia and Herzegovina",
"code": "BA"
},
{
"name": "Botswana",
"code": "BW"
},
{
"name": "Bouvet Island",
"code": "BV"
},
{
"name": "Brazil",
"code": "BR"
},
{
"name": "British Indian Ocean Territory",
"code": "IO"
},
{
"name": "Brunei Darussalam",
"code": "BN"
},
{
"name": "Bulgaria",
"code": "BG"
},
{
"name": "Burkina Faso",
"code": "BF"
},
{
"name": "Burundi",
"code": "BI"
},
{
"name": "Cambodia",
"code": "KH"
},
{
"name": "Cameroon",
"code": "CM"
},
{
"name": "Canada",
"code": "CA"
},
{
"name": "Cape Verde",
"code": "CV"
},
{
"name": "Cayman Islands",
"code": "KY"
},
{
"name": "Central African Republic",
"code": "CF"
},
{
"name": "Chad",
"code": "TD"
},
{
"name": "Chile",
"code": "CL"
},
{
"name": "China",
"code": "CN"
},
{
"name": "Christmas Island",
"code": "CX"
},
{
"name": "Cocos (Keeling) Islands",
"code": "CC"
},
{
"name": "Colombia",
"code": "CO"
},
{
"name": "Comoros",
"code": "KM"
},
{
"name": "Congo",
"code": "CG"
},
{
"name": "Congo, The Democratic Republic of the",
"code": "CD"
},
{
"name": "Cook Islands",
"code": "CK"
},
{
"name": "Costa Rica",
"code": "CR"
},
{
"name": "Cote D\"Ivoire",
"code": "CI"
},
{
"name": "Croatia",
"code": "HR"
},
{
"name": "Cuba",
"code": "CU"
},
{
"name": "Cyprus",
"code": "CY"
},
{
"name": "Czech Republic",
"code": "CZ"
},
{
"name": "Denmark",
"code": "DK"
},
{
"name": "Djibouti",
"code": "DJ"
},
{
"name": "Dominica",
"code": "DM"
},
{
"name": "Dominican Republic",
"code": "DO"
},
{
"name": "Ecuador",
"code": "EC"
},
{
"name": "Egypt",
"code": "EG"
},
{
"name": "El Salvador",
"code": "SV"
},
{
"name": "Equatorial Guinea",
"code": "GQ"
},
{
"name": "Eritrea",
"code": "ER"
},
{
"name": "Estonia",
"code": "EE"
},
{
"name": "Ethiopia",
"code": "ET"
},
{
"name": "Falkland Islands (Malvinas)",
"code": "FK"
},
{
"name": "Faroe Islands",
"code": "FO"
},
{
"name": "Fiji",
"code": "FJ"
},
{
"name": "Finland",
"code": "FI"
},
{
"name": "France",
"code": "FR"
},
{
"name": "French Guiana",
"code": "GF"
},
{
"name": "French Polynesia",
"code": "PF"
},
{
"name": "French Southern Territories",
"code": "TF"
},
{
"name": "Gabon",
"code": "GA"
},
{
"name": "Gambia",
"code": "GM"
},
{
"name": "Georgia",
"code": "GE"
},
{
"name": "Germany",
"code": "DE"
},
{
"name": "Ghana",
"code": "GH"
},
{
"name": "Gibraltar",
"code": "GI"
},
{
"name": "Greece",
"code": "GR"
},
{
"name": "Greenland",
"code": "GL"
},
{
"name": "Grenada",
"code": "GD"
},
{
"name": "Guadeloupe",
"code": "GP"
},
{
"name": "Guam",
"code": "GU"
},
{
"name": "Guatemala",
"code": "GT"
},
{
"name": "Guernsey",
"code": "GG"
},
{
"name": "Guinea",
"code": "GN"
},
{
"name": "Guinea-Bissau",
"code": "GW"
},
{
"name": "Guyana",
"code": "GY"
},
{
"name": "Haiti",
"code": "HT"
},
{
"name": "Heard Island and Mcdonald Islands",
"code": "HM"
},
{
"name": "Holy See (Vatican City State)",
"code": "VA"
},
{
"name": "Honduras",
"code": "HN"
},
{
"name": "Hong Kong",
"code": "HK"
},
{
"name": "Hungary",
"code": "HU"
},
{
"name": "Iceland",
"code": "IS"
},
{
"name": "India",
"code": "IN"
},
{
"name": "Indonesia",
"code": "ID"
},
{
"name": "Iran, Islamic Republic Of",
"code": "IR"
},
{
"name": "Iraq",
"code": "IQ"
},
{
"name": "Ireland",
"code": "IE"
},
{
"name": "Isle of Man",
"code": "IM"
},
{
"name": "Israel",
"code": "IL"
},
{
"name": "Italy",
"code": "IT"
},
{
"name": "Jamaica",
"code": "JM"
},
{
"name": "Japan",
"code": "JP"
},
{
"name": "Jersey",
"code": "JE"
},
{
"name": "Jordan",
"code": "JO"
},
{
"name": "Kazakhstan",
"code": "KZ"
},
{
"name": "Kenya",
"code": "KE"
},
{
"name": "Kiribati",
"code": "KI"
},
{
"name": "Korea, Democratic People\"S Republic of",
"code": "KP"
},
{
"name": "Korea, Republic of",
"code": "KR"
},
{
"name": "Kuwait",
"code": "KW"
},
{
"name": "Kyrgyzstan",
"code": "KG"
},
{
"name": "Lao People\"S Democratic Republic",
"code": "LA"
},
{
"name": "Latvia",
"code": "LV"
},
{
"name": "Lebanon",
"code": "LB"
},
{
"name": "Lesotho",
"code": "LS"
},
{
"name": "Liberia",
"code": "LR"
},
{
"name": "Libyan Arab Jamahiriya",
"code": "LY"
},
{
"name": "Liechtenstein",
"code": "LI"
},
{
"name": "Lithuania",
"code": "LT"
},
{
"name": "Luxembourg",
"code": "LU"
},
{
"name": "Macao",
"code": "MO"
},
{
"name": "Macedonia, The Former Yugoslav Republic of",
"code": "MK"
},
{
"name": "Madagascar",
"code": "MG"
},
{
"name": "Malawi",
"code": "MW"
},
{
"name": "Malaysia",
"code": "MY"
},
{
"name": "Maldives",
"code": "MV"
},
{
"name": "Mali",
"code": "ML"
},
{
"name": "Malta",
"code": "MT"
},
{
"name": "Marshall Islands",
"code": "MH"
},
{
"name": "Martinique",
"code": "MQ"
},
{
"name": "Mauritania",
"code": "MR"
},
{
"name": "Mauritius",
"code": "MU"
},
{
"name": "Mayotte",
"code": "YT"
},
{
"name": "Mexico",
"code": "MX"
},
{
"name": "Micronesia, Federated States of",
"code": "FM"
},
{
"name": "Moldova, Republic of",
"code": "MD"
},
{
"name": "Monaco",
"code": "MC"
},
{
"name": "Mongolia",
"code": "MN"
},
{
"name": "Montserrat",
"code": "MS"
},
{
"name": "Morocco",
"code": "MA"
},
{
"name": "Mozambique",
"code": "MZ"
},
{
"name": "Myanmar",
"code": "MM"
},
{
"name": "Namibia",
"code": "NA"
},
{
"name": "Nauru",
"code": "NR"
},
{
"name": "Nepal",
"code": "NP"
},
{
"name": "Netherlands",
"code": "NL"
},
{
"name": "Netherlands Antilles",
"code": "AN"
},
{
"name": "New Caledonia",
"code": "NC"
},
{
"name": "New Zealand",
"code": "NZ"
},
{
"name": "Nicaragua",
"code": "NI"
},
{
"name": "Niger",
"code": "NE"
},
{
"name": "Nigeria",
"code": "NG"
},
{
"name": "Niue",
"code": "NU"
},
{
"name": "Norfolk Island",
"code": "NF"
},
{
"name": "Northern Mariana Islands",
"code": "MP"
},
{
"name": "Norway",
"code": "NO"
},
{
"name": "Oman",
"code": "OM"
},
{
"name": "Pakistan",
"code": "PK"
},
{
"name": "Palau",
"code": "PW"
},
{
"name": "Palestinian Territory, Occupied",
"code": "PS"
},
{
"name": "Panama",
"code": "PA"
},
{
"name": "Papua New Guinea",
"code": "PG"
},
{
"name": "Paraguay",
"code": "PY"
},
{
"name": "Peru",
"code": "PE"
},
{
"name": "Philippines",
"code": "PH"
},
{
"name": "Pitcairn",
"code": "PN"
},
{
"name": "Poland",
"code": "PL"
},
{
"name": "Portugal",
"code": "PT"
},
{
"name": "Puerto Rico",
"code": "PR"
},
{
"name": "Qatar",
"code": "QA"
},
{
"name": "Reunion",
"code": "RE"
},
{
"name": "Romania",
"code": "RO"
},
{
"name": "Russian Federation",
"code": "RU"
},
{
"name": "RWANDA",
"code": "RW"
},
{
"name": "Saint Helena",
"code": "SH"
},
{
"name": "Saint Kitts and Nevis",
"code": "KN"
},
{
"name": "Saint Lucia",
"code": "LC"
},
{
"name": "Saint Pierre and Miquelon",
"code": "PM"
},
{
"name": "Saint Vincent and the Grenadines",
"code": "VC"
},
{
"name": "Samoa",
"code": "WS"
},
{
"name": "San Marino",
"code": "SM"
},
{
"name": "Sao Tome and Principe",
"code": "ST"
},
{
"name": "Saudi Arabia",
"code": "SA"
},
{
"name": "Senegal",
"code": "SN"
},
{
"name": "Serbia and Montenegro",
"code": "CS"
},
{
"name": "Seychelles",
"code": "SC"
},
{
"name": "Sierra Leone",
"code": "SL"
},
{
"name": "Singapore",
"code": "SG"
},
{
"name": "Slovakia",
"code": "SK"
},
{
"name": "Slovenia",
"code": "SI"
},
{
"name": "Solomon Islands",
"code": "SB"
},
{
"name": "Somalia",
"code": "SO"
},
{
"name": "South Africa",
"code": "ZA"
},
{
"name": "South Georgia and the South Sandwich Islands",
"code": "GS"
},
{
"name": "Spain",
"code": "ES"
},
{
"name": "Sri Lanka",
"code": "LK"
},
{
"name": "Sudan",
"code": "SD"
},
{
"name": "Suriname",
"code": "SR"
},
{
"name": "Svalbard and Jan Mayen",
"code": "SJ"
},
{
"name": "Swaziland",
"code": "SZ"
},
{
"name": "Sweden",
"code": "SE"
},
{
"name": "Switzerland",
"code": "CH"
},
{
"name": "Syrian Arab Republic",
"code": "SY"
},
{
"name": "Taiwan",
"code": "TW"
},
{
"name": "Tajikistan",
"code": "TJ"
},
{
"name": "Tanzania, United Republic of",
"code": "TZ"
},
{
"name": "Thailand",
"code": "TH"
},
{
"name": "Timor-Leste",
"code": "TL"
},
{
"name": "Togo",
"code": "TG"
},
{
"name": "Tokelau",
"code": "TK"
},
{
"name": "Tonga",
"code": "TO"
},
{
"name": "Trinidad and Tobago",
"code": "TT"
},
{
"name": "Tunisia",
"code": "TN"
},
{
"name": "Turkey",
"code": "TR"
},
{
"name": "Turkmenistan",
"code": "TM"
},
{
"name": "Turks and Caicos Islands",
"code": "TC"
},
{
"name": "Tuvalu",
"code": "TV"
},
{
"name": "Uganda",
"code": "UG"
},
{
"name": "Ukraine",
"code": "UA"
},
{
"name": "United Arab Emirates",
"code": "AE"
},
{
"name": "United Kingdom",
"code": "GB"
},
{
"name": "United States",
"code": "US"
},
{
"name": "United States Minor Outlying Islands",
"code": "UM"
},
{
"name": "Uruguay",
"code": "UY"
},
{
"name": "Uzbekistan",
"code": "UZ"
},
{
"name": "Vanuatu",
"code": "VU"
},
{
"name": "Venezuela",
"code": "VE"
},
{
"name": "Viet Nam",
"code": "VN"
},
{
"name": "Virgin Islands, British",
"code": "VG"
},
{
"name": "Virgin Islands, U.S.",
"code": "VI"
},
{
"name": "Wallis and Futuna",
"code": "WF"
},
{
"name": "Western Sahara",
"code": "EH"
},
{
"name": "Yemen",
"code": "YE"
},
{
"name": "Zambia",
"code": "ZM"
},
{
"name": "Zimbabwe",
"code": "ZW"
}
]
},
"valueProperty": "name",
"template": "<span>{{ item.name }}</span>",
"calculateValue": "var customer = _.find($ds.Customers, {'Customer ID': data.Customer['Customer ID']});\nvalue = customer ? instance.setValue(customer['Country']): '';",
"allowCalculateOverride": true,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "ShipCountry",
"type": "select",
"input": true
}
]
},
{
"label": "<strong>Orders</strong>",
"tableView": false,
"templates": {
"footer": "<div class=\"row\">\n <div class=\"col-sm-6\"></div>\n <div class=\"col-sm-2\"><strong>TOTAL</strong></div>\n <div class=\"col-sm-2\"><strong>{{ _.sumBy(data.Orders, 'Discount') }}</strong></div>\n <div class=\"col-sm-2\"><strong>{{ _.sumBy(data.Orders, 'Subtotal') }}</strong></div>\n</div>"
},
"validateWhenHidden": false,
"rowDrafts": false,
"key": "Orders",
"type": "editgrid",
"displayAsTable": false,
"input": true,
"components": [
{
"label": "Product",
"widget": "choicesjs",
"tableView": true,
"dataSrc": "custom",
"data": {
"custom": "values = $ds.Products;"
},
"idPath": "ProductID",
"template": "<span>{{ item.ProductName }}</span>",
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "Product",
"type": "select",
"input": true
},
{
"label": "Supplier",
"applyMaskOn": "change",
"disabled": true,
"tableView": true,
"calculateValue": "var product = _.find($ds.Products, {ProductID: row.Product.ProductID});\nvalue = product ? product.Supplier : '';",
"validateWhenHidden": false,
"key": "Supplier",
"type": "textfield",
"input": true
},
{
"label": "Category",
"applyMaskOn": "change",
"disabled": true,
"tableView": false,
"calculateValue": "var product = _.find($ds.Products, {ProductID: row.Product.ProductID});\nvalue = product ? product.Category : '';\n",
"validateWhenHidden": false,
"key": "Category",
"type": "textfield",
"input": true
},
{
"label": "Unit Price ($)",
"applyMaskOn": "change",
"disabled": true,
"tableView": true,
"calculateValue": "var product = _.find($ds.Products, {ProductID: row.Product.ProductID});\nvalue = product ? product.UnitPrice : '';",
"validateWhenHidden": false,
"key": "UnitPrice",
"type": "textfield",
"input": true
},
{
"label": "Quantity",
"applyMaskOn": "change",
"mask": false,
"tableView": true,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "Quantity",
"type": "number",
"input": true
},
{
"label": "Discount ($)",
"applyMaskOn": "change",
"mask": false,
"tableView": true,
"defaultValue": 0,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"validateWhenHidden": false,
"key": "Discount",
"type": "number",
"input": true
},
{
"label": "Subtotal ($)",
"applyMaskOn": "change",
"mask": false,
"disabled": true,
"tableView": true,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"calculateValue": "value = (row.UnitPrice - row.Discount) * row.Quantity",
"validateWhenHidden": false,
"key": "Subtotal",
"type": "number",
"input": true
}
]
}
]
},
{
"label": "Save",
"showValidations": false,
"disableOnInvalid": true,
"tableView": false,
"key": "submit",
"type": "button",
"saveOnEnter": false,
"input": true
}
]
}
HTML Template¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport"
content="user-scalable=no, initial-scale=1.0001, maximum-scale=1.0001, width=device-width, minimal-ui shrink-to-fit=no">
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Northwind</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/awesome-notifications/3.1.0/style.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/w2ui@2.0.0/w2ui-2.0.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/awesome-notifications/3.1.0/modern.var.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/localstorage-slim"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.form.io/js/formio.embed.js"></script>
</head>
<body>
<style>
button[type="submit"] {
background-color: #007bff;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1em;
width: 100%;
}
</style>
<div id="toolbar"></div>
<div id="formio"></div>
<script type="module">
import { w2toolbar } from "https://cdn.jsdelivr.net/npm/w2ui@2.0.0/w2ui-2.0.es6.min.js";
var $ds = {};
var email = ls.get("email");
var notifier = new AWN({ option: "top-right" });
var sid = ls.get("sid");
$(function () {
if (sid) {
google.script.run
.withSuccessHandler(onCheckSidSuccess)
.withFailureHandler(onInvalidSid)
.checkSid(sid);
}
else {
onInvalidSid();
}
});
function onInvalidSid(err) {
if (err) {
notifier.warning(err.message);
}
else {
let url = "<?!= base ?>?url=/form/login&callback=<?!= url ?>";
notifier.modal(`<b>You need to login to access this page.</b><br><a href="${url}">👉 <b>Login</b></a>`)
}
}
function onCheckSidSuccess(valid) {
new w2toolbar({
box: "#toolbar",
name: "toolbar",
items: [
{
type: "menu", id: "sales", icon: "w2ui-icon-info", text: "Sales",
items: [
{ id: "customers", text: "Customers", icon: "fa fa-user" },
{ id: "orders", text: "Orders", icon: "fa fa-file-text" },
]
},
{ type: "break" },
{
type: "menu", id: "operations", icon: "w2ui-icon-settings", text: "Operations",
items: [
{ id: "employees", text: "Employees", icon: "fa fa-address-card" },
{ id: "products", text: "Products", icon: "fa fa-archive" },
{ id: "categories", text: "Product Categories", icon: "fa fa-sitemap" },
{ id: "suppliers", text: "Suppliers", icon: "fa fa-user" },
{ id: "shippers", text: "Shippers", icon: "fa fa-shopping-cart" }
]
},
{ type: "spacer" },
{
type: "menu", id: "auth", text: email,
items: [
{ text: "Logout", id: "logout", icon: "fa fa-sign-out" }
]
}
],
onClick(event) {
switch (event.target) {
case "sales:customers": {
window.open("<?= base ?>?url=/form/customers", "_top");
break;
}
case "sales:orders": {
window.open("<?= base ?>?url=/form/orders", "_top");
break;
}
case "operations:employees": {
window.open("<?= base ?>?url=/form/employees", "_top");
break;
}
case "operations:products": {
window.open("<?= base ?>?url=/form/products", "_top");
break;
}
case "operations:categories": {
window.open("<?= base ?>?url=/form/categories", "_top");
break;
}
case "operations:suppliers": {
window.open("<?= base ?>?url=/form/suppliers", "_top");
break;
}
case "operations:shippers": {
window.open("<?= base ?>?url=/form/shippers", "_top");
break;
}
case "auth:logout": {
ls.remove("sid");
ls.remove("email");
window.open("<?= base ?>?url=/form/login&callback=<?!= url ?>", "_top");
break;
}
}
}
});
if (valid) {
google.script.run.withSuccessHandler(showForms)
.loadDatasources("<?!= datasource ?>");
} else {
onInvalidSid();
}
}
function showForms(ds) {
$ds = ds;
let rec = <?!= (data) ?>;
Formio.createForm(document.getElementById("formio"), <?!= template ?>)
.then(function (form) {
// Prevent the submission from going to the form.io server.
form.noAlerts = true;
form.nosubmit = true;
form.submission = rec.Document ? { data: JSON.parse(rec.Document) } : {};
// Triggered when they click the submit button.
form.on("submit", function (submission) {
google.script.run
.withFailureHandler((err) => {
notifier.warning("Successfully saved.");
form.emit("submitError");
})
.withSuccessHandler((id) => {
if (!id) {
form.emit("submitError");
notifier.warning("An error occurred while saving the entry.");
}
else {
form.emit("submitDone");
<? if (!id) { ?>
form.submission = {};
form.refresh();
<? } ?>
notifier.success("Successfully saved.");
}
})
<? if (id) { ?>
.update("<?!= id ?>", "<?!= form.Id ?>", { Document: JSON.stringify(submission.data) }, null, sid)
<? } else { ?>
.create("<?!= form.Id ?>", { Document: JSON.stringify(submission.data) }, sid);
<? } ?>
});
});
}
</script>
</body>
</html>
Giải thích Code¶
Form List Customers sử dụng cácthư viện sau:
- jQuery để khởi tạo grid sau khi page load xong.
- localstorage-slim để đọc sid & email để bỏ qua bước login nếu trước đó đã login thành công. Trường hợp login không thành công thì sẽ thông báo và điều hướng đến trang login.
- Notyf hiển thị thông báo.
- w2ui cung cấp các thành phần UI cơ bản và nâng cao, ví dụ: toolbar và grid, dialog...
- Các thư viện đều được load từ CDN để tối ưu tốc độ, đơn giản hóa HTML Templated. Các bạn cần có kiến thức trong phần yêu cầu để hiểu logic của code JS + templated nhúng trong page.
- Trong page này gọi đến
- Hàm backend checkSid sid lưu trữ có khớp với giá trị trên server, nếu đúng thì sẽ sử dụng email trả về, còn sai sẽ điều hướng đến trang login
- Hàm backend loadDatasources để tải các dữ liệu tham chiếu phía client, ví dụ danh sách Products
- Hàm backend create để lưu form submission dưới dạng document trong database NoSQL
- Hàm backend update để cập nhật record đã tồn tại với record id được truyền vào từ url theo định dạng form-id/record-id. Trong trường hợp này record-id chính là column Id của document.
- Form CRUD Order tham chiếu đến các datasource Customers, Employees, Shippers, Products Các datasource sẽ phục làm data các thành phần FormIO UI.
Demo¶
Updated by Lê Sĩ Quý 8 months ago · 1 revisions