Kod skripte: /srv/disk16/3266814/www/phporacle.eu5.net/fwphp/glomodul/mkd/01/001_db/03_1oracle_apex_sales_module.txt šđčćž
Kod skripte /home/www/phporacle.eu5.net/zinc/showsource.php koja prikazuje kod (za vlastiti kod ne slati joj param. "file=...", ne inkludira se view_fn.inc)
    1 
    2 
    3 
    4 
    5 
    6 
    7 
    8 
    9 
   10 
   11 
   12 
   13 
   14 
   15 
   16 
   17 
   18 
   19 
   20 
   21 
   22 
   23 
   24 
   25 
   26 
   27 
   28 
   29 
   30 
   31 
   32 
   33 
   34 
   35 
   36 
   37 
   38 
   39 
   40 
   41 
   42 
   43 
   44 
   45 
   46 
   47 
   48 
   49 
   50 
   51 
   52 
   53 
   54 
   55 
   56 
   57 
   58 
   59 
   60 
   61 
   62 
   63 
   64 
   65 
   66 
   67 
   68 
   69 
   70 
   71 
   72 
   73 
   74 
   75 
   76 
   77 
   78 
   79 
   80 
   81 
   82 
   83 
   84 
   85 
   86 
   87 
   88 
   89 
   90 
   91 
   92 
   93 
   94 
   95 
   96 
   97 
   98 
   99 
  100 
  101 
  102 
  103 
  104 
  105 
  106 
  107 
  108 
  109 
  110 
  111 
  112 
  113 
  114 
  115 
  116 
  117 
  118 
  119 
  120 
  121 
  122 
  123 
  124 
  125 
  126 
  127 
  128 
  129 
  130 
  131 
  132 
  133 
  134 
  135 
  136 
  137 
  138 
  139 
  140 
  141 
  142 
  143 
  144 
  145 
  146 
  147 
  148 
  149 
  150 
  151 
  152 
  153 
  154 
  155 
  156 
  157 
  158 
  159 
  160 
  161 
  162 
  163 
  164 
  165 
  166 
  167 
  168 
  169 
  170 
  171 
  172 
  173 
  174 
  175 
  176 
  177 
  178 
  179 
  180 
  181 
  182 
  183 
  184 
  185 
  186 
  187 
  188 
  189 
  190 
  191 
  192 
  193 
  194 
  195 
  196 
  197 
  198 
  199 
  200 
  201 
  202 
  203 
  204 
  205 
  206 
  207 
  208 
  209 
  210 
  211 
  212 
  213 
  214 
  215 
  216 
  217 
  218 
  219 
  220 
  221 
  222 
  223 
  224 
  225 
  226 
  227 
  228 
  229 
  230 
  231 
  232 
  233 
  234 
  235 
  236 
  237 
  238 
  239 
  240 
  241 
  242 
  243 
  244 
  245 
  246 
  247 
  248 
  249 
  250 
  251 
  252 
  253 
  254 
  255 
  256 
  257 
  258 
  259 
  260 
  261 
  262 
  263 
  264 
  265 
  266 
  267 
  268 
  269 
  270 
  271 
  272 
  273 
  274 
  275 
  276 
  277 
  278 
  279 
  280 
  281 
  282 
  283 
  284 
  285 
  286 
  287 
  288 
  289 
  290 
  291 
  292 
  293 
  294 
  295 
  296 
  297 
  298 
  299 
  300 
  301 
  302 
  303 
  304 
  305 
  306 
  307 
  308 
  309 
  310 
  311 
  312 
  313 
  314 
  315 
  316 
  317 
  318 
  319 
  320 
  321 
  322 
  323 
  324 
  325 
  326 
  327 
  328 
  329 
  330 
  331 
  332 
  333 
  334 
  335 
  336 
  337 
  338 
  339 
  340 
  341 
  342 
  343 
  344 
  345 
  346 
  347 
  348 
  349 
  350 
  351 
  352 
  353 
  354 
  355 
  356 
  357 
  358 
  359 
  360 
  361 
  362 
  363 
  364 
  365 
  366 
  367 
  368 
  369 
  370 
  371 
  372 
  373 
  374 
  375 
  376 
  377 
  378 
  379 
  380 
  381 
  382 
  383 
  384 
  385 
  386 
  387 
  388 
  389 
  390 
  391 
  392 
  393 
  394 
  395 
  396 
  397 
  398 
  399 
  400 
  401 
  402 
  403 
  404 
  405 
  406 
  407 
  408 
  409 
  410 
  411 
  412 
  413 
  414 
  415 
  416 
  417 
  418 
  419 
  420 
  421 
  422 
  423 
  424 
  425 
  426 
  427 
  428 
  429 
  430 
  431 
  432 
  433 
  434 
  435 
  436 
  437 
  438 
  439 
  440 
  441 
  442 
  443 
  444 
  445 
  446 
  447 
  448 
  449 
  450 
  451 
  452 
  453 
  454 
  455 
  456 
  457 
  458 
  459 
  460 
  461 
  462 
  463 
  464 
  465 
  466 
  467 
  468 
  469 
  470 
  471 
  472 
  473 
  474 
  475 
  476 
  477 
  478 
  479 
  480 
  481 
  482 
  483 
  484 
  485 
  486 
  487 
  488 
  489 
  490 
  491 
  492 
  493 
  494 
  495 
  496 
  497 
  498 
  499 
  500 
  501 
  502 
  503 
  504 
  505 
  506 
  507 
  508 
  509 
  510 
  511 
  512 
  513 
  514 
  515 
  516 
  517 
  518 
  519 
  520 
  521 
  522 
  523 
  524 
  525 
  526 
  527 
  528 
  529 
  530 
  531 
  532 
  533 
  534 
  535 
  536 
  537 
  538 
  539 
  540 
  541 
  542 
  543 
  544 
  545 
  546 
  547 
  548 
  549 
  550 
  551 
  552 
  553 
  554 
  555 
  556 
  557 
  558 
  559 
  560 
  561 
  562 
  563 
  564 
  565 
  566 
  567 
  568 
  569 
  570 
  571 
  572 
  573 
  574 
  575 
  576 
  577 
  578 
  579 
  580 
  581 
  582 
  583 
  584 
  585 
  586 
  587 
  588 
  589 
  590 
  591 
  592 
  593 
  594 
  595 
  596 
  597 
  598 
  599 
  600 
  601 
  602 
  603 
  604 
  605 
  606 
  607 
  608 
  609 
  610 
  611 
  612 
  613 
  614 
  615 
  616 
  617 
  618 
  619 
  620 
  621 
  622 
  623 
  624 
  625 
  626 
  627 
  628 
  629 
  630 
  631 
  632 
  633 
  634 
  635 
  636 
  637 
  638 
  639 
  640 
  641 
  642 
  643 
  644 
  645 
  646 
  647 
  648 
  649 
  650 
  651 
  652 
  653 
  654 
  655 
  656 
  657 
  658 
  659 
  660 
  661 
  662 
  663 
  664 
  665 
  666 
  667 
  668 
  669 
  670 
  671 
  672 
  673 
  674 
  675 
  676 
  677 
  678 
  679 
  680 
  681 
  682 
  683 
  684 
  685 
  686 
  687 
  688 
  689 
  690 
  691 
  692 
  693 
  694 
  695 
  696 
  697 
  698 
  699 
  700 
  701 
  702 
  703 
  704 
  705 
  706 
  707 
  708 
  709 
  710 
  711 
  712 
  713 
  714 
  715 
  716 
  717 
  718 
  719 
  720 
  721 
  722 
  723 
  724 
  725 
  726 
  727 
  728 
  729 
  730 
  731 
  732 
  733 
  734 
  735 
  736 
  737 
  738 
  739 
  740 
  741 
  742 
  743 
  744 
  745 
  746 
  747 
  748 
  749 
  750 
  751 
  752 
  753 
  754 
  755 
  756 
  757 
  758 
  759 
  760 
  761 
  762 
  763 
  764 
  765 
  766 
  767 
  768 
  769 
  770 
  771 
  772 
  773 
  774 
  775 
  776 
  777 
  778 
  779 
  780 
  781 
  782 
  783 
  784 
  785 
  786 
  787 
  788 
  789 
  790 
  791 
  792 
  793 
  794 
  795 
  796 
  797 
  798 
  799 
  800 
  801 
  802 
  803 
  804 
  805 
  806 
  807 
  808 
  809 
  810 
  811 
  812 
  813 
  814 
  815 
  816 
  817 
  818 
  819 
  820 
  821 
  822 
  823 
  824 
  825 
  826 
  827 
  828 
  829 
  830 
  831 
  832 
  833 
  834 
  835 
  836 
  837 
  838 
  839 
  840 
  841 
  842 
  843 
  844 
  845 
  846 
  847 
  848 
  849 
  850 
  851 
  852 
  853 
  854 
  855 
  856 
  857 
  858 
  859 
  860 
  861 
  862 
  863 
  864 
  865 
  866 
  867 
  868 
  869 
  870 
  871 
  872 
  873 
  874 
  875 
  876 
  877 
  878 
  879 
  880 
  881 
  882 
  883 
  884 
  885 
  886 
  887 
  888 
  889 
  890 
  891 
  892 
  893 
  894 
  895 
  896 
  897 
  898 
  899 
  900 
  901 
  902 
  903 
  904 
  905 
  906 
  907 
  908 
  909 
  910 
  911 
  912 
  913 
  914 
  915 
  916 
  917 
  918 
  919 
  920 
  921 
  922 
  923 
  924 
  925 
  926 
  927 
  928 
  929 
  930 
  931 
  932 
  933 
  934 
  935 
  936 
  937 
  938 
  939 
  940 
  941 
  942 
  943 
  944 
  945 
  946 
  947 
  948 
  949 
  950 
  951 
  952 
  953 
  954 
  955 
  956 
  957 
  958 
  959 
  960 
  961 
  962 
  963 
  964 
  965 
  966 
  967 
  968 
  969 
  970 
  971 
  972 
  973 
  974 
  975 
  976 
  977 
  978 
  979 
  980 
  981 
  982 
  983 
  984 
  985 
  986 
  987 
  988 
  989 
  990 
  991 
  992 
  993 
  994 
  995 
  996 
  997 
  998 
  999 
 1000 
 1001 
 1002 
 1003 
 1004 
 1005 
 1006 
 1007 
 1008 
 1009 
 1010 
 1011 
 1012 
 1013 
 1014 
 1015 
 1016 
 1017 
 1018 
 1019 
 1020 
 1021 
 1022 
 1023 
 1024 
 1025 
 1026 
 1027 
 1028 
 1029 
 1030 
 1031 
 1032 
 1033 
 1034 
 1035 
 1036 
 1037 
 1038 
 1039 
 1040 
 1041 
 1042 
 1043 
 1044 
 1045 
 1046 
 1047 
 1048 
 1049 
 1050 
 1051 
 1052 
 1053 
 1054 
 1055 
 1056 
 1057 
 1058 
 1059 
 1060 
 1061 
 1062 
 1063 
 1064 
 1065 
 1066 
 1067 
 1068 
 1069 
 1070 
 1071 
 1072 
 1073 
 1074 
 1075 
 1076 
 1077 
 1078 
 1079 
 1080 
 1081 
 1082 
 1083 
 1084 
 1085 
 1086 
 1087 
 1088 
 1089 
 1090 
 1091 
 1092 
 1093 
 1094 
 1095 
 1096 
 1097 
 1098 
 1099 
 1100 
 1101 
 1102 
 1103 
 1104 
 1105 
 1106 
 1107 
 1108 
 1109 
 1110 
 1111 
 1112 
 1113 
 1114 
 1115 
 1116 
 1117 
 1118 
 1119 
 1120 
 1121 
 1122 
 1123 
 1124 
 1125 
 1126 
 1127 
 1128 
 1129 
 1130 
 1131 
 1132 
 1133 
 1134 
 1135 
 1136 
 1137 
 1138 
 1139 
 1140 
 1141 
 1142 
 1143 
 1144 
 1145 
 1146 
 1147 
 1148 
 1149 
 1150 
 1151 
 1152 
 1153 
 1154 
 1155 
 1156 
 1157 
 1158 
 1159 
 1160 
 1161 
 1162 
 1163 
 1164 
 1165 
 1166 
 1167 
 1168 
 1169 
 1170 
 1171 
 1172 
 1173 
 1174 
 1175 
 1176 
 1177 
 1178 
 1179 
 1180 
 1181 
 1182 
 1183 
 1184 
 1185 
 1186 
 1187 
 1188 
 1189 
 1190 
 1191 
 1192 
 1193 
 1194 
 1195 
 1196 
 1197 
 1198 
 1199 
 1200 
 1201 
 1202 
 1203 
 1204 
 1205 
 1206 
 1207 
 1208 
 1209 
 1210 
 1211 
 1212 
 1213 
 1214 
 1215 
 1216 
 1217 
 1218 
 1219 
 1220 
 1221 
 1222 
 1223 
 1224 
 1225 
 1226 
 1227 
 1228 
 1229 
 1230 
 1231 
 1232 
 1233 
 1234 
 1235 
 1236 
 1237 
 1238 
 1239 
 1240 
 1241 
 1242 
 1243 
 1244 
 1245 
 1246 
 1247 
 1248 
 1249 
 1250 
 1251 
 1252 
 1253 
 1254 
 1255 
 1256 
 1257 
 1258 
 1259 
 1260 
 1261 
 1262 
 1263 
 1264 
 1265 
 1266 
 1267 
 1268 
 1269 
 1270 
 1271 
 1272 
 1273 
 1274 
 1275 
 1276 
 1277 
 1278 
 1279 
 1280 
 1281 
 1282 
 1283 
 1284 
 1285 
 1286 
 1287 
 1288 
 1289 
 1290 
 1291 
 1292 
 1293 
 1294 
 1295 
 1296 
 1297 
 1298 
 1299 
 1300 
 1301 
 1302 
 1303 
 1304 
 1305 
 1306 
 1307 
 1308 
 1309 
 1310 
 1311 
 1312 
 1313 
 1314 
 1315 
 1316 
 1317 
 1318 
 1319 
 1320 
 1321 
 1322 
 1323 
 1324 
 1325 
 1326 
 1327 
 1328 
 1329 
 1330 
 1331 
 1332 
 1333 
 1334 
 1335 
 1336 
 1337 
 1338 
 1339 
 1340 
 1341 
 1342 
 1343 
 1344 
 1345 
 1346 
 1347 
 1348 
 1349 
 1350 
 1351 
 1352 
 1353 
 1354 
 1355 
 1356 
 1357 
 1358 
 1359 
 1360 
 1361 
 1362 
 1363 
 1364 
 1365 
 1366 
 1367 
 1368 
 1369 
 1370 
 1371 
 1372 
 1373 
 1374 
 1375 
 1376 
 1377 
 1378 
 1379 
 1380 
 1381 
 1382 
 1383 
 1384 
 1385 
 1386 
 1387 
 1388 
 1389 
 1390 
 1391 
 1392 
 1393 
 1394 
 1395 
 1396 
 1397 
 1398 
 1399 
 1400 
 1401 
 1402 
 1403 
 1404 
 1405 
 1406 
 1407 
 1408 
 1409 
 1410 
 1411 
 1412 
 1413 
 1414 
 1415 
 1416 
 1417 
 1418 
 1419 
 1420 
 1421 
 1422 
 1423 
 1424 
 1425 
 1426 
 1427 
 1428 
 1429 
 1430 
 1431 
 1432 
 1433 
 1434 
 1435 
 1436 
 1437 
 1438 
 1439 
 1440 
 1441 
 1442 
 1443 
 1444 
 1445 
 1446 
 1447 
 1448 
 1449 
 1450 
 1451 
 1452 
 1453 
 1454 
 1455 
 1456 
 1457 
 1458 
 1459 
 1460 
 1461 
 1462 
 1463 
 1464 
 1465 
 1466 
 1467 
 1468 
 1469 
 1470 
 1471 
 1472 
 1473 
 1474 
 1475 
 1476 
 1477 
 1478 
 1479 
 1480 
 1481 
 1482 
 1483 
 1484 
 1485 
 1486 
 1487 
 1488 
 1489 
 1490 
 1491 
 1492 
 1493 
 1494 
 1495 
 1496 
 1497 
 1498 
 1499 
 1500 
 1501 
 1502 
 1503 
 1504 
 1505 
 1506 
 1507 
 1508 
 1509 
 1510 
 1511 
 1512 
 1513 
 1514 
 1515 
 1516 
 1517 
 1518 
 1519 
 1520 
 1521 
 1522 
 1523 
 1524 
 1525 
 1526 
 1527 
 1528 
 1529 
 1530 
 1531 
 1532 
 1533 
 1534 
 1535 
 1536 
 1537 
 1538 
 1539 
 1540 
 1541 
 1542 
 1543 
 1544 
 1545 
 1546 
 1547 
 1548 
 1549 
 1550 
 1551 
 1552 
 1553 
 1554 
 1555 
 1556 
 1557 
 1558 
 1559 
 1560 
 1561 
 1562 
 1563 
 1564 
 1565 
 1566 
 1567 
 1568 
 1569 
 1570 
 1571 
 1572 
 1573 
 1574 
 1575 
 1576 
 1577 
 1578 
 1579 
 1580 
 1581 
 1582 
 1583 
 1584 
 1585 
 1586 
 1587 
 1588 
 1589 
 1590 
 1591 
 1592 
 1593 
 1594 
 1595 
 1596 
 1597 
 1598 
 1599 
 1600 
 1601 
 1602 
 1603 
 1604 
 1605 
 1606 
 1607 
 1608 
 1609 
 1610 
 1611 
 1612 
 1613 
 1614 
 1615 
 1616 
 1617 
 1618 
 1619 
 1620 
 1621 
 1622 
 1623 
 1624 
 1625 
 1626 
 1627 
 1628 
 1629 
 1630 
 1631 
 1632 
 1633 
 1634 
 1635 
 1636 
 1637 
 1638 
 1639 
 1640 
 1641 
 1642 
 1643 
 1644 
 1645 
 1646 
 1647 
 1648 
 1649 
 1650 
 1651 
 1652 
 1653 
 1654 
 1655 
 1656 
 1657 
 1658 
 1659 
 1660 
 1661 
 1662 
 1663 
 1664 
 1665 
 1666 
 1667 
 1668 
 1669 
 1670 
 1671 
 1672 
 1673 
 1674 
 1675 
 1676 
 1677 
 1678 
 1679 
 1680 
 1681 
 1682 
 1683 
 1684 
 1685 
 1686 
 1687 
 1688 
 1689 
 1690 
 1691 
 1692 
 1693 
 1694 
 1695 
 1696 
 1697 
 1698 
 1699 
 1700 
 1701 
 1702 
 1703 
 1704 
 1705 
 1706 
 1707 
 1708 
 1709 
 1710 
 1711 
 1712 
 1713 
 1714 
 1715 
 1716 
 1717 
 1718 
 1719 
 1720 
 1721 
 1722 
 1723 
 1724 
 1725 
 1726 
 1727 
 1728 
 1729 
 1730 
 1731 
 1732 
 1733 
 1734 
 1735 
 1736 
 1737 
 1738 
 1739 
 1740 
 1741 
 1742 
 1743 
 1744 
 1745 
 1746 
 1747 
 1748 
 1749 
 1750 
 1751 
 1752 
 1753 
 1754 
 1755 
 1756 
 1757 
 1758 
 1759 
 1760 
 1761 
 1762 
 1763 
 1764 
 1765 
 1766 
 1767 
 1768 
 1769 
 1770 
 1771 
 1772 
 1773 
 1774 
 1775 
 1776 
 1777 
 1778 
 1779 
 1780 
 1781 
 1782 
 1783 
 1784 
 1785 
 1786 
 1787 
 1788 
 1789 
 1790 
 1791 
 1792 
 1793 
 1794 
 1795 
 1796 
 1797 
 1798 
 1799 
 1800 
 1801 
 1802 
 1803 
 1804 
 1805 
 1806 
 1807 
 1808 
 1809 
 1810 
 1811 
 1812 
 1813 
 1814 
 1815 
 1816 
 1817 
 1818 
 1819 
 1820 
 1821 
 1822 
 1823 
 1824 
 1825 
 1826 
 1827 
 1828 
 1829 
 1830 
 1831 
 1832 
 1833 
 1834 
 1835 
 1836 
 1837 
 1838 
 1839 
 1840 
 1841 
 1842 
 1843 
 1844 
 1845 
 1846 
 1847 
 1848 
 1849 
 1850 
 1851 
 1852 
 1853 
 1854 
 1855 
 1856 
 1857 
 1858 
 1859 
 1860 
 1861 
 1862 
 1863 
 1864 
 1865 
 1866 
 1867 
 1868 
 1869 
 1870 
 1871 
 1872 
 1873 
 1874 
 1875 
 1876 
 1877 
 1878 
 1879 
 1880 
 1881 
 1882 
 1883 
 1884 
 1885 
 1886 
 1887 
 1888 
 1889 
 1890 
 1891 
 1892 
 1893 
 1894 
 1895 
 1896 
 1897 
 1898 
 1899 
 1900 
 1901 
 1902 
 1903 
 1904 
 1905 
 1906 
 1907 
 1908 
 1909 
 1910 
 1911 
 1912 
 1913 
 1914 
 1915 
 1916 
 1917 
 1918 
 1919 
 1920 
 1921 
 1922 
 1923 
 1924 
 1925 
 1926 
 1927 
 1928 
 1929 
 1930 
 1931 
 1932 
 1933 
 1934 
 1935 
 1936 
 1937 
 1938 
 1939 
 1940 
 1941 
 1942 
 1943 
 1944 
 1945 
 1946 
 1947 
 1948 
 1949 
 1950 
 1951 
 1952 
 1953 
 1954 
 1955 
 1956 
 1957 
 1958 
 1959 
 1960 
 1961 
 1962 
 1963 
 1964 
 1965 
 1966 
 1967 
 1968 
 1969 
 1970 
 1971 
 1972 
 1973 
 1974 
 1975 
 1976 
 1977 
 1978 
 1979 
 1980 
 1981 
 1982 
 1983 
 1984 
 1985 
 1986 
 1987 
 1988 
 1989 
 1990 
 1991 
 1992 
 1993 
 1994 
 1995 
 1996 
 1997 
 1998 
 1999 
 2000 
 2001 
 2002 
 2003 
 2004 
 2005 
 2006 
 2007 
 2008 
 2009 
 2010 
 2011 
 2012 
 2013 
 2014 
 2015 
 2016 
 2017 
 2018 
 2019 
 2020 
 2021 
 2022 
 2023 
 2024 
 2025 
 2026 
 2027 
 2028 
 2029 
 2030 
 2031 
 2032 
 2033 
 2034 
 2035 
 2036 
 2037 
 2038 
 2039 
 2040 
 2041 
 2042 
 2043 
 2044 
 2045 
 2046 
 2047 
 2048 
 2049 
 2050 
 2051 
 2052 
 2053 
 2054 
 2055 
 2056 
 2057 
 2058 
 2059 
 2060 
 2061 
 2062 
 2063 
 2064 
 2065 
 2066 
 2067 
 2068 
 2069 
 2070 
 2071 
 2072 
 2073 
 2074 
 2075 
 2076 
 2077 
 2078 
 2079 
 2080 
 2081 
 2082 
 2083 
 2084 
 2085 
 2086 
 2087 
 2088 
 2089 
 2090 
 2091 
 2092 
 2093 
 2094 
 2095 
 2096 
 2097 
 2098 
 2099 
 2100 
 2101 
 2102 
 2103 
 2104 
 2105 
 2106 
 2107 
 2108 
 2109 
 2110 
 2111 
 2112 
 2113 
 2114 
 2115 
 2116 
 2117 
 2118 
 2119 
 2120 
 2121 
 2122 
 2123 
 2124 
 2125 
 2126 
 2127 
 2128 
 2129 
 2130 
 2131 
 2132 
 2133 
 2134 
 2135 
 2136 
 2137 
 2138 
 2139 
 2140 
 2141 
 2142 
 2143 
 2144 
 2145 
 2146 
 2147 
 2148 
 2149 
 2150 
 2151 
 2152 
 2153 
 2154 
 2155 
 2156 
 2157 
 2158 
 2159 
 2160 
 2161 
 2162 
 2163 
 2164 
 2165 
 2166 
 2167 
 2168 
 2169 
 2170 
 2171 
 2172 
 2173 
 2174 
 2175 
 2176 
 2177 
 2178 
 2179 
 2180 
 2181 
 2182 
 2183 
 2184 
 2185 
 2186 
 2187 
 2188 
 2189 
 2190 
 2191 
 2192 
 2193 
 2194 
 2195 
 2196 
 2197 
 2198 
 2199 
 2200 
 2201 
 2202 
 2203 
 2204 
 2205 
 2206 
 2207 
 2208 
 2209 
 2210 
 2211 
 2212 
 2213 
 2214 
 2215 
 2216 
 2217 
 2218 
 2219 
 2220 
 2221 
 2222 
 2223 
 2224 
 2225 
 2226 
 2227 
 2228 
 2229 
 2230 
 2231 
 2232 
 2233 
 2234 
 2235 
 2236 
 2237 
 2238 
 2239 
 2240 
 2241 
 2242 
 2243 
 2244 
 2245 
 2246 
 2247 
 2248 
 2249 
 2250 
 2251 
 2252 
 2253 
 2254 
 2255 
 2256 
 2257 
 2258 
 2259 
 2260 
 2261 
 2262 
 2263 
 2264 
 2265 
 2266 
 2267 
 2268 
 2269 
 2270 
 2271 
 2272 
 2273 
 2274 
 2275 
 2276 
 2277 
 2278 
 2279 
 2280 
 2281 
 2282 
 2283 
 2284 
 2285 
 2286 
 2287 
 2288 
 2289 
 2290 
 2291 
 2292 
 2293 
 2294 
 2295 
 2296 
 2297 
 2298 
 2299 
 2300 
 2301 
 2302 
 2303 
 2304 
 2305 
 2306 
 2307 
 2308 
 2309 
 2310 
 2311 
 2312 
 2313 
 2314 
 2315 
 2316 
 2317 
 2318 
 2319 
 2320 
 2321 
 2322 
 2323 
 2324 
 2325 
 2326 
 2327 
 2328 
 2329 
 2330 
 2331 
 2332 
 2333 
 2334 
 2335 
 2336 
 2337 
 2338 
 2339 
 2340 
 2341 
 2342 
 2343 
 2344 
 2345 
 2346 
 2347 
 2348 
 2349 
 2350 
 2351 
 2352 
 2353 
 2354 
 2355 
 2356 
 2357 
 2358 
 2359 
 2360 
 2361 
 2362 
 2363 
 2364 
 2365 
 2366 
 2367 
 2368 
 2369 
 2370 
 2371 
 2372 
 2373 
 2374 
 2375 
 2376 
 2377 
 2378 
 2379 
 2380 
 2381 
 2382 
 2383 
 2384 
 2385 
 2386 
 2387 
 2388 
 2389 
 2390 
 2391 
 2392 
 2393 
 2394 
 2395 
 2396 
 2397 
 2398 
 2399 
 2400 
 2401 
 2402 
 2403 
 2404 
 2405 
 2406 
 2407 
 2408 
 2409 
 2410 
 2411 
 2412 
 2413 
 2414 
 2415 
 2416 
 2417 
 2418 
 2419 
 2420 
 2421 
 2422 
 2423 
 2424 
 2425 
 2426 
 2427 
 2428 
 2429 
 2430 
 2431 
 2432 
 2433 
 2434 
 2435 
 2436 
 2437 
 2438 
 2439 
 2440 
 2441 
 2442 
 2443 
 2444 
 2445 
 2446 
 2447 
 2448 
 2449 
 2450 
 2451 
 2452 
 2453 
 2454 
 2455 
 2456 
 2457 
 2458 
 2459 
 2460 
 2461 
 2462 
 2463 
 2464 
 2465 
 2466 
 2467 
 2468 
 2469 
 2470 
 2471 
 2472 
 2473 
 2474 
 2475 
 2476 
 2477 
 2478 
 2479 
 2480 
 2481 
 2482 
 2483 
 2484 
 2485 
 2486 
 2487 
 2488 
 2489 
 2490 
 2491 
 2492 
 2493 
 2494 
 2495 
 2496 
 2497 
 2498 
 2499 
 2500 
 2501 
 2502 
 2503 
 2504 
 2505 
 2506 
 2507 
 2508 
 2509 
 2510 
 2511 
 2512 
 2513 
 2514 
 2515 
 2516 
 2517 
 2518 
 2519 
 2520 
 2521 
 2522 
 2523 
 2524 
 2525 
 2526 
 2527 
 2528 
 2529 
 2530 
 2531 
 2532 
 2533 
 2534 
 2535 
 2536 
 2537 
 2538 
 2539 
 2540 
 2541 
 2542 
 2543 
 2544 
 2545 
 2546 
 2547 
 2548 
 2549 
 2550 
 2551 
 2552 
 2553 
 2554 
 2555 
 2556 
 2557 
 2558 
 2559 
 2560 
 2561 
 2562 
 2563 
 2564 
 2565 
 2566 
 2567 
 2568 
 2569 
 2570 
 2571 
 2572 
 2573 
 2574 
 2575 
 2576 
 2577 
 2578 
 2579 
 2580 
 2581 
 2582 
 2583 
 2584 
 2585 
 2586 
 2587 
 2588 
 2589 
 2590 
 2591 
 2592 
 2593 
 2594 
 2595 
 2596 
 2597 
 2598 
 2599 
 2600 
 2601 
 2602 
 2603 
 2604 
 2605 
 2606 
 2607 
 2608 
 2609 
 2610 
 2611 
 2612 
 2613 
 2614 
 2615 
 2616 
 2617 
 2618 
 2619 
 2620 
 2621 
 2622 
 2623 
 2624 
 2625 
 2626 
 2627 
 2628 
 2629 
 2630 
 2631 
 2632 
 2633 
 2634 
 2635 
 2636 
 2637 
 2638 
 2639 
 2640 
 2641 
 2642 
 2643 
 2644 
 2645 
 2646 
 2647 
 2648 
 2649 
 2650 
 2651 
 2652 
 2653 
 2654 
 2655 
 2656 
 2657 
 2658 
 2659 
 2660 
 2661 
 2662 
 2663 
 2664 
 2665 
 2666 
 2667 
 2668 
 2669 
 2670 
 2671 
 2672 
 2673 
 2674 
 2675 
 2676 
 2677 
 2678 
 2679 
 2680 
 2681 
 2682 
 2683 
 2684 
 2685 
 2686 
 2687 
 2688 
 2689 
 2690 
 2691 
 2692 
 2693 
 2694 
 2695 
 2696 
 2697 
 2698 
 2699 
 2700 
 2701 
 2702 
 2703 
 2704 
 2705 
 2706 
 2707 
 2708 
 2709 
 2710 
 2711 
 2712 
 2713 
 2714 
 2715 
 2716 
 2717 
 2718 
 2719 
 2720 
 2721 
 2722 
 2723 
 2724 
 2725 
 2726 
 2727 
 2728 
 2729 
 2730 
 2731 
 2732 
 2733 
 2734 
 2735 
 2736 
 2737 
 2738 
 2739 
 2740 
 2741 
 2742 
 2743 
 2744 
 2745 
 2746 
 2747 
 2748 
 2749 
 2750 
 2751 
 2752 
 2753 
 2754 
 2755 
 2756 
 2757 
 2758 
 2759 
 2760 
 2761 
 2762 
 2763 
 2764 
 2765 
 2766 
 2767 
 2768 
 2769 
 2770 
 2771 
 2772 
 2773 
 2774 
 2775 
 2776 
 2777 
 2778 
 2779 
 2780 
 2781 
 2782 
 2783 
 2784 
 2785 
 2786 
 2787 
 2788 
 2789 
 2790 
 2791 
 2792 
 2793 
 2794 
 2795 
 2796 
 2797 
 2798 
 2799 
 2800 
 2801 
 2802 
 2803 
 2804 
 2805 
 2806 
 2807 
 2808 
 2809 
 2810 
 2811 
 2812 
 2813 
 2814 
 2815 
 2816 
 2817 
 2818 
 2819 
 2820 
 2821 
 2822 
 2823 
 2824 
 2825 
 2826 
 2827 
 2828 
 2829 
 2830 
 2831 
 2832 
 2833 
 2834 
 2835 
 2836 
 2837 
 2838 
 2839 
 2840 
 2841 
 2842 
 2843 
 2844 
 2845 
 2846 
 2847 
 2848 
 2849 
 2850 
 2851 
 2852 
 2853 
 2854 
 2855 
 2856 
 2857 
 2858 
 2859 
 2860 
 2861 
 2862 
 2863 
 2864 
 2865 
 2866 
 2867 
 2868 
 2869 
 2870 
 2871 
 2872 
 2873 
 2874 
 2875 
 2876 
 2877 
 2878 
 2879 
 2880 
 2881 
 2882 
 2883 
 2884 
 2885 
 2886 
 2887 
 2888 
 2889 
 2890 
 2891 
 2892 
 2893 
 2894 
 2895 
 2896 
 2897 
 2898 
 2899 
 2900 
 2901 
 2902 
 2903 
 2904 
 2905 
 2906 
 2907 
 2908 
 2909 
 2910 
 2911 
 2912 
 2913 
 2914 
 2915 
 2916 
 2917 
 2918 
 2919 
 2920 
 2921 
 2922 
 2923 
 2924 
 2925 
 2926 
 2927 
 2928 
 2929 
 2930 
 2931 
 2932 
 2933 
 2934 
 2935 
 2936 
 2937 
 2938 
 2939 
 2940 
 2941 
 2942 
 2943 
 2944 
 2945 
 2946 
 2947 
 2948 
 2949 
 2950 
 2951 
 2952 
 2953 
 2954 
 2955 
 2956 
 2957 
 2958 
 2959 
 2960 
 2961 
 2962 
 2963 
 2964 
 2965 
 2966 
 2967 
 2968 
 2969 
 2970 
 2971 
 2972 
 2973 
 2974 
 2975 
 2976 
 2977 
 2978 
 2979 
 2980 
 2981 
 2982 
 2983 
 2984 
 2985 
 2986 
 2987 
 2988 
 2989 
 2990 
 2991 
 2992 
 2993 
 2994 
 2995 
 2996 
 2997 
 2998 
 2999 
 3000 
 3001 
 3002 
 3003 
 3004 
 3005 
 3006 
 3007 
 3008 
 3009 
 3010 
 3011 
 3012 
 3013 
 3014 
 3015 
 3016 
 3017 
 3018 
 3019 
 3020 
 3021 
 3022 
 3023 
 3024 
 3025 
 3026 
 3027 
 3028 
 3029 
 3030 
 3031 
 3032 
 3033 
 3034 
 3035 
 3036 
 3037 
 3038 
 3039 
 3040 
 3041 
 3042 
 3043 
 3044 
 3045 
 3046 
 3047 
 3048 
 3049 
 3050 
 3051 
 3052 
 3053 
 3054 
 3055 
 3056 
 3057 
 3058 
 3059 
 3060 
 3061 
 3062 
 3063 
 3064 
 3065 
 3066 
 3067 
 3068 
 3069 
 3070 
 3071 
 3072 
 3073 
 3074 
 3075 
 3076 
 3077 
 3078 
 3079 
 3080 
 3081 
 3082 
 3083 
 3084 
 3085 
 3086 
 3087 
 3088 
 3089 
 3090 
 3091 
 3092 
 3093 
 3094 
 3095 
 3096 
 3097 
 3098 
 3099 
 3100 
 3101 
 3102 
 3103 
 3104 
 3105 
 3106 
 3107 
 3108 
 3109 
 3110 
 3111 
 3112 
 3113 
 3114 
 3115 
 3116 
 3117 
 3118 
 3119 
 3120 
 3121 
 3122 
 3123 
 3124 
 3125 
 3126 
 3127 
 3128 
 3129 
 3130 
 3131 
 3132 
 3133 
 3134 
 3135 
 3136 
 3137 
 3138 
 3139 
 3140 
 3141 
 3142 
 3143 
 3144 
 3145 
 3146 
 3147 
 3148 
 3149 
 3150 
 3151 
 3152 
 3153 
 3154 
 3155 
 3156 
 3157 
 3158 
 3159 
 3160 
 3161 
 3162 
 3163 
 3164 
 3165 
 3166 
 3167 
 3168 
 3169 
 3170 
 3171 
 3172 
 3173 
 3174 
 3175 
 3176 
 3177 
 3178 
 3179 
 3180 
 3181 
 3182 
 3183 
 3184 
 3185 
 3186 
 3187 
 3188 
 3189 
 3190 
 3191 
 3192 
 3193 
 3194 
 3195 
 3196 
 3197 
 3198 
 3199 
 3200 
 3201 
 3202 
 3203 
 3204 
 3205 
 3206 
 3207 
 3208 
 3209 
 3210 
 3211 
 3212 
 3213 
 3214 
 3215 
 3216 
 3217 
 3218 
 3219 
 3220 
 3221 
 3222 
 3223 
 3224 
 3225 
 3226 
 3227 
 3228 
 3229 
 3230 
 3231 
 3232 
 3233 
 3234 
 3235 
 3236 
 3237 
 3238 
 3239 
 3240 
 3241 
 3242 
 3243 
 3244 
 3245 
 3246 
 3247 
 3248 
 3249 
 3250 
 3251 
 3252 
 3253 
 3254 
 3255 
 3256 
 3257 
 3258 
 3259 
 3260 
 3261 
 3262 
 3263 
 3264 
 3265 
 3266 
 3267 
 3268 
 3269 
 3270 
 3271 
 3272 
 3273 
 3274 
 3275 
 3276 
 3277 
 3278 
 3279 
 3280 
 3281 
 3282 
 3283 
 3284 
 3285 
 3286 
 3287 
 3288 
 3289 
 3290 
 3291 
 3292 
 3293 
 3294 
 3295 
 3296 
 3297 
 3298 
 3299 
 3300 
 3301 
 3302 
 3303 
 3304 
 3305 
 3306 
 3307 
 3308 
 3309 
 3310 
 3311 
 3312 
 3313 
 3314 
 3315 
 3316 
 3317 
 3318 
 3319 
 3320 
 3321 
 3322 
 3323 
 3324 
 3325 
 3326 
 3327 
 3328 
 3329 
 3330 
 3331 
 3332 
 3333 
 3334 
 3335 
 3336 
 3337 
 3338 
 3339 
 3340 
 3341 
 3342 
 3343 
 3344 
 3345 
 3346 
 3347 
 3348 
 3349 
 3350 
 3351 
 3352 
 3353 
 3354 
 3355 
 3356 
 3357 
 3358 
 3359 
 3360 
 3361 
 3362 
 3363 
 3364 
 3365 
 3366 
 3367 
 3368 
 3369 
 3370 
 3371 
 3372 
 3373 
 3374 
 3375 
 3376 
 3377 
 3378 
 3379 
 3380 
 3381 
 3382 
 3383 
 3384 
 3385 
 3386 
 3387 
 3388 
 3389 
 3390 
 3391 
 3392 
 3393 
 3394 
 3395 
 3396 
 3397 
 3398 
 3399 
 3400 
 3401 
 3402 
 3403 
 3404 
 3405 
 3406 
 3407 
 3408 
 3409 
 3410 
 3411 
 3412 
 3413 
 3414 
 3415 
 3416 
 3417 
 3418 
 3419 
 3420 
 3421 
 3422 
 3423 
 3424 
 3425 
 3426 
 3427 
 3428 
 3429 
 3430 
 3431 
 3432 
 3433 
 3434 
 3435 
 3436 
 3437 
 3438 
 3439 
 3440 
 3441 
 3442 
 3443 
 3444 
 3445 
 3446 
 3447 
 3448 
 3449 
 3450 
 3451 
 3452 
 3453 
 3454 
 3455 
 3456 
 3457 
 3458 
 3459 
 3460 
 3461 
 3462 
 3463 
 3464 
 3465 
 3466 
 3467 
 3468 
 3469 
 3470 
 3471 
 3472 
 3473 
 3474 
 3475 
 3476 
 3477 
 3478 
 3479 
 3480 
 3481 
 3482 
 3483 
 3484 
 3485 
 3486 
 3487 
 3488 
 3489 
 3490 
 3491 
 3492 
 3493 
 3494 
 3495 
 3496 
 3497 
 3498 
 3499 
 3500 
 3501 
 3502 
 3503 
 3504 
 3505 
 3506 
 3507 
 3508 
 3509 
 3510 
 3511 
 3512 
 3513 
 3514 
 3515 
 3516 
 3517 
 3518 
 3519 
 3520 
 3521 
 3522 
 3523 
 3524 
 3525 
 3526 
 3527 
 3528 
 3529 
 3530 
 3531 
 3532 
 3533 
 3534 
 3535 
 3536 
 3537 
 3538 
 3539 
 3540 
 3541 
 3542 
 3543 
 3544 
 3545 
 3546 
 3547 
 3548 
 3549 
 3550 
 3551 
 3552 
 3553 
 3554 
 3555 
 3556 
 3557 
 3558 
 3559 
 3560 
 3561 
 3562 
 3563 
 3564 
 3565 
 3566 
 3567 
 3568 
 3569 
 3570 
 3571 
 3572 
 3573 
 3574 
 3575 
 3576 
 3577 
 3578 
 3579 
 3580 
 3581 
 3582 
 3583 
 3584 
 3585 
 3586 
 3587 
 3588 
 3589 
 3590 
 3591 
 3592 
 3593 
 3594 
 3595 
 3596 
 3597 
 3598 
 3599 
 3600 
 3601 
 3602 
 3603 
 3604 
 3605 
 3606 
 3607 
 3608 
 3609 
 3610 
 3611 
 3612 
 3613 
 3614 
 3615 
 3616 
 3617 
 3618 
 3619 
 3620 
 3621 
 3622 
 3623 
 3624 
 3625 
 3626 
 3627 
 3628 
 3629 
 3630 
 3631 
 3632 
 3633 
 3634 
 3635 
 3636 
 3637 
 3638 
 3639 
 3640 
 3641 
 3642 
 3643 
 3644 
 3645 
 3646 
 3647 
 3648 
 3649 
 3650 
 3651 
 3652 
 3653 
 3654 
 3655 
 3656 
 3657 
 3658 
 3659 
 3660 
 3661 
 3662 
 3663 
 3664 
 3665 
 3666 
 3667 
 3668 
 3669 
 3670 
 3671 
 3672 
 3673 
 3674 
 3675 
 3676 
 3677 
 3678 
 3679 
 3680 
 3681 
 3682 
 3683 
 3684 
 3685 
 3686 
 3687 
 3688 
 3689 
 3690 
 3691 
 3692 
 3693 
 3694 
 3695 
 3696 
 3697 
 3698 
 3699 
 3700 
 3701 
 3702 
 3703 
 3704 
 3705 
 3706 
 3707 
 3708 
 3709 
 3710 
 3711 
 3712 
 3713 
 3714 
 3715 
 3716 
 3717 
 3718 
 3719 
 3720 
 3721 
 3722 
 3723 
 3724 
 3725 
 3726 
 3727 
 3728 
 3729 
 3730 
 3731 
 3732 
 3733 
 3734 
 3735 
 3736 
 3737 
 3738 
 3739 
 3740 
 3741 
 3742 
 3743 
 3744 
 3745 
 3746 
 3747 
 3748 
 3749 
 3750 
 3751 
 3752 
 3753 
 3754 
 3755 
 3756 
 3757 
 3758 
 3759 
 3760 
 3761 
 3762 
 3763 
 3764 
 3765 
 3766 
 3767 
 3768 
 3769 
 3770 
 3771 
 3772 
 3773 
 3774 
 3775 
 3776 
 3777 
 3778 
 3779 
 3780 
 3781 
 3782 
 3783 
 3784 
 3785 
 3786 
 3787 
 3788 
 3789 
 3790 
 3791 
 3792 
 3793 
 3794 
 3795 
 3796 
 3797 
 3798 
 3799 
 3800 
 3801 
 3802 
 3803 
 3804 
 3805 
 3806 
 3807 
 3808 
 3809 
 3810 
 3811 
 3812 
 3813 
 3814 
 3815 
 3816 
 3817 
 3818 
 3819 
 3820 
 3821 
 3822 
 3823 
 3824 
 3825 
 3826 
 3827 
 3828 
 3829 
 3830 
 3831 
 3832 
 3833 
 3834 
 3835 
 3836 
 3837 
 3838 
 3839 
 3840 
 3841 
 3842 
 3843 
 3844 
 3845 
 3846 
 3847 
 3848 
 3849 
 3850 
 3851 
 3852 
 3853 
 3854 
 3855 
 3856 
 3857 
 3858 
 3859 
 3860 
 3861 
 3862 
 3863 
 3864 
 3865 
 3866 
 3867 
 3868 
 3869 
 3870 
 3871 
 3872 
 3873 
 3874 
 3875 
 3876 
 3877 
 3878 
 3879 
 3880 
 3881 
 3882 
 3883 
 3884 
 3885 
 3886 
 3887 
 3888 
 3889 
 3890 
 3891 
 3892 
 3893 
 3894 
 3895 
 3896 
 3897 
 3898 
 3899 
 3900 
 3901 
 3902 
 3903 
 3904 
 3905 
 3906 
 3907 
 3908 
 3909 
 3910 
 3911 
 3912 
 3913 
 3914 
 3915 
 3916 
 3917 
 3918 
 3919 
 3920 
 3921 
 3922 
 3923 
 3924 
 3925 
 3926 
 3927 
 3928 
 3929 
 3930 
 3931 
 3932 
 3933 
 3934 
 3935 
 3936 
 3937 
 3938 
 3939 
 3940 
 3941 
 3942 
 3943 
 3944 
 3945 
 3946 
 3947 
 3948 
 3949 
 3950 
 3951 
 3952 
 3953 
 3954 
 3955 
 3956 
 3957 
 3958 
 3959 
 3960 
 3961 
 3962 
 3963 
 3964 
 3965 
 3966 
 3967 
 3968 
 3969 
 3970 
 3971 
 3972 
 3973 
 3974 
 3975 
 3976 
 3977 
 3978 
 3979 
 3980 
 3981 
 3982 
 3983 
 3984 
 3985 
 3986 
 3987 
 3988 
 3989 
 3990 
 3991 
 3992 
 3993 
 3994 
 3995 
 3996 
 3997 
 3998 
 3999 
 4000 
 4001 
 4002 
 4003 
 4004 
 4005 
 4006 
 4007 
 4008 
 4009 
 4010 
 4011 
 4012 
 4013 
 4014 
 4015 
 4016 
 4017 
 4018 
 4019 
 4020 
 4021 
 4022 
 4023 
 4024 
 4025 
 4026 
 4027 
 4028 
 4029 
 4030 
 4031 
 4032 
 4033 
 4034 
 4035 
 4036 
 4037 
 4038 
 4039 
 4040 
 4041 
 4042 
 4043 
 4044 
 4045 
 4046 
 4047 
 4048 
 4049 
 4050 
 4051 
 4052 
 4053 
 4054 
 4055 
 4056 
 4057 
 4058 
 4059 
 4060 
 4061 
 4062 
 4063 
 4064 
 4065 
 4066 
 4067 
 4068 
 4069 
 4070 
 4071 
 4072 
 4073 
 4074 
 4075 
 4076 
 4077 
 4078 
 4079 
 4080 
 4081 
 4082 
 4083 
 4084 
 4085 
 4086 
 4087 
 4088 
 4089 
 4090 
 4091 
 4092 
 4093 
 4094 
 4095 
 4096 
 4097 
 4098 
 4099 
 4100 
 4101 
 4102 
 4103 
 4104 
 4105 
 4106 
 4107 
 4108 
 4109 
 4110 
 4111 
 4112 
 4113 
 4114 
 4115 
 4116 
 4117 
 4118 
 4119 
 4120 
 4121 
 4122 
 4123 
 4124 
 4125 
 4126 
 4127 
 4128 
 4129 
 4130 
 4131 
 4132 
 4133 
 4134 
 4135 
 4136 
 4137 
 4138 
 4139 
 4140 
 4141 
 4142 
 4143 
 4144 
 4145 
 4146 
 4147 
 4148 
 4149 
 4150 
 4151 
 4152 
 4153 
 4154 
 4155 
 4156 
 4157 
 4158 
 4159 
 4160 
 4161 
 4162 
 4163 
 4164 
 4165 
 4166 
 4167 
 4168 
 4169 
 4170 
 4171 
 4172 
 4173 
 4174 
 4175 
 4176 
 4177 
 4178 
 4179 
 4180 
 4181 
 4182 
 4183 
 4184 
 4185 
 4186 
 4187 
 4188 
 4189 
 4190 
 4191 
 4192 
 4193 
 4194 
 4195 
 4196 
 4197 
 4198 
 4199 
 4200 
 4201 
 4202 
 4203 
 4204 
 4205 
 4206 
 4207 
 4208 
 4209 
 4210 
 4211 
 4212 
 4213 
 4214 
 4215 
 4216 
 4217 
 4218 
 4219 
 4220 
 4221 
 4222 
 4223 
 4224 
 4225 
 4226 
 4227 
 4228 
 4229 
 4230 
 4231 
 4232 
 4233 
 4234 
 4235 
 4236 
 4237 
 4238 
 4239 
 4240 
 4241 
 4242 
 4243 
 4244 
 4245 
 4246 
 4247 
 4248 
 4249 
 4250 
 4251 
 4252 
 4253 
 4254 
 4255 
 4256 
 4257 
 4258 
 4259 
 4260 
 4261 
 4262 
 4263 
 4264 
 4265 
 4266 
 4267 
 4268 
 4269 
 4270 
 4271 
 4272 
 4273 
 4274 
 4275 
 4276 
 4277 
 4278 
 4279 
 4280 
 4281 
 4282 
 4283 
 4284 
 4285 
 4286 
 4287 
 4288 
 4289 
 4290 
 4291 
 4292 
 4293 
 4294 
 4295 
 4296 
 4297 
 4298 
 4299 
 4300 
 4301 
 4302 
 4303 
 4304 
 4305 
 4306 
 4307 
 4308 
 4309 
 4310 
 4311 
 4312 
 4313 
 4314 
 4315 
 4316 
 4317 
 4318 
 4319 
 4320 
 4321 
 4322 
 4323 
 4324 
 4325 
 4326 
 4327 
 4328 
 4329 
 4330 
 4331 
 4332 
 4333 
 4334 
 4335 
 4336 
 4337 
 4338 
 4339 
 4340 
 4341 
 4342 
 4343 
 4344 
 4345 
 4346 
 4347 
 4348 
 4349 
 4350 
 4351 
 4352 
 4353 
 4354 
 4355 
 4356 
 4357 
 4358 
 4359 
 4360 
 4361 
 4362 
 4363 
 4364 
 4365 
 4366 
 4367 
 4368 
 4369 
 4370 
 4371 
 4372 
 4373 
 4374 
 4375 
 4376 
 4377 
 4378 
 4379 
 4380 
 4381 
 4382 
 4383 
 4384 
 4385 
 4386 
 4387 
 4388 
 4389 
 4390 
 4391 
 4392 
 4393 
 4394 
 4395 
 4396 
 4397 
 4398 
 4399 
 4400 
 4401 
 4402 
 4403 
 4404 
 4405 
 4406 
 4407 
 4408 
 4409 
 4410 
 4411 
 4412 
 4413 
 4414 
 4415 
 4416 
 4417 
 4418 
 4419 
 4420 
 4421 
 4422 
 4423 
 4424 
 4425 
 4426 
 4427 
 4428 
 4429 
 4430 
 4431 
 4432 
 4433 
 4434 
 4435 
 4436 
 4437 
 4438 
 4439 
 4440 
 4441 
 4442 
 4443 
 4444 
 4445 
 4446 
 4447 
 4448 
 4449 
 4450 
 4451 
 4452 
 4453 
 4454 
 4455 
 4456 
 4457 
 4458 
 4459 
 4460 
 4461 
 4462 
 4463 
 4464 
 4465 
 4466 
 4467 
 4468 
 4469 
 4470 
 4471 
 4472 
 4473 
 4474 
 4475 
 4476 
 4477 
 4478 
 4479 
 4480 
 4481 
 4482 
 4483 
 4484 
 4485 
 4486 
 4487 
 4488 
 4489 
 4490 
 4491 
 4492 
 4493 
 4494 
 4495 
 4496 
 4497 
 4498 
 4499 
 4500 
 4501 
 4502 
 4503 
 4504 
 4505 
 4506 
 4507 
 4508 
 4509 
 4510 
 4511 
 4512 
 4513 
 4514 
 4515 
 4516 
 4517 
 4518 
 4519 
 4520 
 4521 
 4522 
 4523 
 4524 
 4525 
 4526 
 4527 
 4528 
 4529 
 4530 
 4531 
 4532 
 4533 
 4534 
 4535 
 4536 
 4537 
 4538 
 4539 
 4540 
 4541 
 4542 
 4543 
 4544 
 4545 
 4546 
 4547 
 4548 
 4549 
 4550 
 4551 
 4552 
 4553 
 4554 
 4555 
 4556 
 4557 
 4558 
 4559 
 4560 
 4561 
 4562 
 4563 
 4564 
 4565 
 4566 
 4567 
 4568 
 4569 
 4570 
 4571 
 4572 
 4573 
 4574 
 4575 
 4576 
 4577 
 4578 
 4579 
 4580 
 4581 
 4582 
 4583 
 4584 
 4585 
 4586 
 4587 
 4588 
 4589 
 4590 
 4591 
 4592 
 4593 
 4594 
 4595 
 4596 
 4597 
 4598 
 4599 
 4600 
 4601 
 4602 
 4603 
 4604 
 4605 
 4606 
 4607 
 4608 
 4609 
 4610 
 4611 
 4612 
 4613 
 4614 
 4615 
 4616 
 4617 
 4618 
 4619 
 4620 
 4621 
 4622 
 4623 
 4624 
 4625 
 4626 
 4627 
 4628 
 4629 
 4630 
 4631 
 4632 
 4633 
 4634 
 4635 
 4636 
 4637 
 4638 
 4639 
 4640 
 4641 
 4642 
 4643 
 4644 
 4645 
 4646 
 4647 
 4648 
 4649 
 4650 
 4651 
 4652 
 4653 
 4654 
 4655 
 4656 
 4657 
 4658 
 4659 
 4660 
 4661 
 4662 
 4663 
 4664 
 4665 
 4666 
 4667 
 4668 
 4669 
 4670 
 4671 
 4672 
 4673 
 4674 
 4675 
 4676 
 4677 
 4678 
 4679 
 4680 
 4681 
 4682 
 4683 
 4684 
 4685 
 4686 
 4687 
 4688 
 4689 
 4690 
 4691 
 4692 
 4693 
 4694 
 4695 
 4696 
 4697 
 4698 
 4699 
 4700 
 4701 
 4702 
 4703 
 4704 
 4705 
 4706 
 4707 
 4708 
 4709 
 4710 
 4711 
 4712 
 4713 
 4714 
 4715 
 4716 
 4717 
 4718 
 4719 
 4720 
 4721 
 4722 
 4723 
 4724 
 4725 
 4726 
 4727 
 4728 
 4729 
 4730 
 4731 
 4732 
 4733 
 4734 
 4735 
 4736 
 4737 
 4738 
 4739 
 4740 
 4741 
 4742 
 4743 
 4744 
 4745 
 4746 
 4747 
 4748 
 4749 
 4750 
 4751 
 4752 
 4753 
 4754 
 4755 
 4756 
 4757 
 4758 
 4759 
 4760 
 4761 
 4762 
 4763 
 4764 
 4765 
 4766 
 4767 
 4768 
 4769 
 4770 
 4771 
 4772 
 4773 
 4774 
 4775 
 4776 
 4777 
 4778 
 4779 
 4780 
 4781 
 4782 
 4783 
 4784 
 4785 
 4786 
 4787 
 4788 
 4789 
 4790 
 4791 
 4792 
 4793 
 4794 
 4795 
 4796 
 4797 
 4798 
 4799 
 4800 
 4801 
 4802 
 4803 
 4804 
 4805 
 4806 
 4807 
 4808 
 4809 
 4810 
 4811 
 4812 
 4813 
 4814 
 4815 
 4816 
 4817 
 4818 
 4819 
 4820 
 4821 
 4822 
 4823 
 4824 
 4825 
 4826 
 4827 
 4828 
 4829 
 4830 
 4831 
 4832 
 4833 
 4834 
 4835 
 4836 
 4837 
 4838 
 4839 
 4840 
 4841 
 4842 
 4843 
 4844 
 4845 
 4846 
 4847 
 4848 
 4849 
 4850 
 4851 
 4852 
 4853 
 4854 
 4855 
 4856 
 4857 
 4858 
 4859 
 4860 
 4861 
 4862 
 4863 
 4864 
 4865 
 4866 
 4867 
 4868 
 4869 
 4870 
 4871 
 4872 
 4873 
 4874 
 4875 
 4876 
 4877 
 4878 
 4879 
 4880 
 4881 
 4882 
 4883 
 4884 
 4885 
 4886 
 4887 
 4888 
 4889 
 4890 
 4891 
 4892 
 4893 
 4894 
 4895 
 4896 
 4897 
 4898 
 4899 
 4900 
 4901 
 4902 
 4903 
 4904 
 4905 
 4906 
 4907 
 4908 
 4909 
 4910 
 4911 
 4912 
 4913 
 4914 
 4915 
 4916 
 4917 
 4918 
 4919 
 4920 
 4921 
 4922 
 4923 
 4924 
 4925 
 4926 
 4927 
 4928 
 4929 
 4930 
 4931 
 4932 
 4933 
 4934 
 4935 
 4936 
 4937 
 4938 
 4939 
 4940 
 4941 
 4942 
 4943 
 4944 
 4945 
 4946 
 4947 
 4948 
 4949 
 4950 
 4951 
 4952 
 4953 
 4954 
 4955 
 4956 
 4957 
 4958 
 4959 
 4960 
 4961 
 4962 
 4963 
 4964 
 4965 
 4966 
 4967 
 4968 
 4969 
 4970 
 4971 
 4972 
 4973 
 4974 
 4975 
 4976 
 4977 
 4978 
 4979 
 4980 
 4981 
 4982 
 4983 
 4984 
 4985 
 4986 
 4987 
 4988 
 4989 
 4990 
 4991 
 4992 
 4993 
 4994 
 4995 
 4996 
 4997 
 4998 
 4999 
 5000 
 5001 
 5002 
 5003 
 5004 
 5005 
 5006 
 5007 
 5008 
 5009 
 5010 
 5011 
 5012 
 5013 
 5014 
 5015 
 5016 
 5017 
 5018 
 5019 
 5020 
 5021 
 5022 
 5023 
 5024 
 5025 
 5026 
 5027 
 5028 
 5029 
 5030 
 5031 
 5032 
 5033 
 5034 
 5035 
 5036 
 5037 
 5038 
 5039 
 5040 
 5041 
 5042 
 5043 
 5044 
 5045 
 5046 
 5047 
 5048 
 5049 
 5050 
 5051 
 5052 
 5053 
 5054 
 5055 
 5056 
 5057 
 5058 
 5059 
 5060 
 5061 
 5062 
 5063 
 5064 
 5065 
 5066 
 5067 
 5068 
 5069 
 5070 
 5071 
 5072 
 5073 
 5074 
 5075 
 5076 
 5077 
 5078 
 5079 
 5080 
 5081 
 5082 
 5083 
 5084 
 5085 
 5086 
 5087 
 5088 
 5089 
 5090 
 5091 
 5092 
 5093 
 5094 
 5095 
 5096 
 5097 
 5098 
 5099 
 5100 
 5101 
 5102 
 5103 
 5104 
 5105 
 5106 
 5107 
 5108 
 5109 
 5110 
 5111 
 5112 
 5113 
 5114 
 5115 
 5116 
 5117 
 5118 
 5119 
 5120 
 5121 
 5122 
 5123 
 5124 
 5125 
 5126 
 5127 
 5128 
 5129 
 5130 
 5131 
 5132 
 5133 
 5134 
 5135 
 5136 
 5137 
 5138 
 5139 
 5140 
 5141 
 5142 
 5143 
 5144 
 5145 
 5146 
 5147 
 5148 
 5149 
 5150 
 5151 
 5152 
 5153 
 5154 
 5155 
 5156 
 5157 
 5158 
 5159 
 5160 
 5161 
 5162 
 5163 
 5164 
 5165 
 5166 
 5167 
 5168 
 5169 
 5170 
 5171 
 5172 
 5173 
 5174 
 5175 
 5176 
 5177 
 5178 
 5179 
 5180 
 5181 
 5182 
 5183 
 5184 
 5185 
 5186 
 5187 
 5188 
 5189 
 5190 
 5191 
 5192 
 5193 
 5194 
 5195 
 5196 
 5197 
 5198 
 5199 
 5200 
 5201 
 5202 
 5203 
 5204 
 5205 
 5206 
 5207 
 5208 
 5209 
 5210 
 5211 
 5212 
 5213 
 5214 
 5215 
 5216 
 5217 
 5218 
 5219 
 5220 
 5221 
 5222 
 5223 
 5224 
 5225 
 5226 
 5227 
 5228 
 5229 
 5230 
 5231 
 5232 
 5233 
 5234 
 5235 
 5236 
 5237 
 5238 
 5239 
 5240 
 5241 
 5242 
 5243 
 5244 
 5245 
 5246 
 5247 
 5248 
 5249 
 5250 
 5251 
 5252 
 5253 
 5254 
 5255 
 5256 
 5257 
 5258 
 5259 
 5260 
 5261 
 5262 
 5263 
 5264 
 5265 
 5266 
 5267 
 5268 
 5269 
 5270 
 5271 
 5272 
 5273 
 5274 
 5275 
 5276 
 5277 
 5278 
 5279 
 5280 
 5281 
 5282 
 5283 
 5284 
 5285 
 5286 
 5287 
 5288 
 5289 
 5290 
 5291 
 5292 
 5293 
 5294 
 5295 
 5296 
 5297 
 5298 
 5299 
 5300 
 5301 
 5302 
 5303 
 5304 
 5305 
 5306 
 5307 
 5308 
 5309 
 5310 
 5311 
 5312 
 5313 
 5314 
 5315 
 5316 
 5317 
 5318 
 5319 
 5320 
 5321 
 5322 
 5323 
 5324 
 5325 
 5326 
 5327 
 5328 
 5329 
 5330 
 5331 
 5332 
 5333 
 5334 
 5335 
 5336 
 5337 
 5338 
 5339 
 5340 
 5341 
 5342 
 5343 
 5344 
 5345 
 5346 
 5347 
 5348 
 5349 
 5350 
 5351 
 5352 
 5353 
 5354 
 5355 
 5356 
 5357 
 5358 
 5359 
 5360 
 5361 
 5362 
 5363 
 5364 
 5365 
 5366 
 5367 
 5368 
 5369 
 5370 
 5371 
 5372 
 5373 
 5374 
 5375 
 5376 
 5377 
 5378 
 5379 
 5380 
 5381 
 5382 
 5383 
 5384 
 5385 
 5386 
 5387 
 5388 
 5389 
 5390 
 5391 
 5392 
 5393 
 5394 
 5395 
 5396 
 5397 
 5398 
 5399 
 5400 
 5401 
 5402 
 5403 
 5404 
 5405 
 5406 
 5407 
 5408 
 5409 
 5410 
 5411 
 5412 
 5413 
 5414 
 5415 
 5416 
 5417 
 5418 
 5419 
 5420 
 5421 
 5422 
 5423 
 5424 
 5425 
 5426 
 5427 
 5428 
 5429 
 5430 
 5431 
 5432 
 5433 
 5434 
 5435 
 5436 
 5437 
 5438 
 5439 
 5440 
 5441 
 5442 
 5443 
 5444 
 5445 
 5446 
 5447 
 5448 
 5449 
 5450 
 5451 
 5452 
 5453 
 5454 
 5455 
 5456 
 5457 
 5458 
 5459 
 5460 
 5461 
 5462 
 5463 
 5464 
 5465 
 5466 
 5467 
 5468 
 5469 
 5470 
 5471 
 5472 
 5473 
 5474 
 5475 
 5476 
 5477 
 5478 
 5479 
 5480 
 5481 
 5482 
 5483 
 5484 
 5485 
 5486 
 5487 
 5488 
 5489 
 5490 
 5491 
 5492 
 5493 
 5494 
 5495 
 5496 
 5497 
 5498 
 5499 
 5500 
 5501 
 5502 
 5503 
 5504 
 5505 
 5506 
 5507 
 5508 
 5509 
 5510 
 5511 
 5512 
 5513 
 5514 
 5515 
 5516 
 5517 
 5518 
 5519 
 5520 
 5521 
 5522 
 5523 
 5524 
 5525 
 5526 
 5527 
 5528 
 5529 
 5530 
 5531 
 5532 
 5533 
 5534 
 5535 
 5536 
 5537 
 5538 
 5539 
 5540 
 5541 
 5542 
 5543 
 5544 
 5545 
 5546 
 5547 
 5548 
 5549 
 5550 
 5551 
 5552 
 5553 
 5554 
 5555 
 5556 
 5557 
 5558 
 5559 
 5560 
 5561 
 5562 
 5563 
 5564 
 5565 
 5566 
 5567 
 5568 
 5569 
 5570 
 5571 
 5572 
 5573 
 5574 
 5575 
 5576 
 5577 
 5578 
 5579 
 5580 
 5581 
 5582 
 5583 
 5584 
 5585 
 5586 
 5587 
 5588 
 5589 
 5590 
 5591 
 5592 
 5593 
 5594 
 5595 
 5596 
 5597 
 5598 
 5599 
 5600 
 5601 
 5602 
 5603 
 5604 
 5605 
 5606 
 5607 
 5608 
 5609 
 5610 
 5611 
 5612 
 5613 
 5614 
 5615 
 5616 
 5617 
 5618 
 5619 
 5620 
 5621 
 5622 
 5623 
 5624 
 5625 
 5626 
 5627 
 5628 
 5629 
 5630 
 5631 
 5632 
 5633 
 5634 
 5635 
 5636 
 5637 
 5638 
 5639 
 5640 
 5641 
 5642 
 5643 
 5644 
 5645 
 5646 
 5647 
 5648 
 5649 
 5650 
 5651 
 5652 
 5653 
 5654 
 5655 
 5656 
 5657 
 5658 
 5659 
 5660 
 5661 
 5662 
 5663 
 5664 
 5665 
 5666 
 5667 
 5668 
 5669 
 5670 
 5671 
 5672 
 5673 
 5674 
 5675 
 5676 
 5677 
 5678 
 5679 
 5680 
 5681 
 5682 
 5683 
 5684 
 5685 
 5686 
 5687 
 5688 
 5689 
 5690 
 5691 
 5692 
 5693 
 5694 
 5695 
 5696 
 5697 
 5698 
 5699 
 5700 
 5701 
 5702 
 5703 
 5704 
 5705 
 5706 
 5707 
 5708 
 5709 
 5710 
 5711 
 5712 
 5713 
 5714 
 5715 
 5716 
 5717 
 5718 
 5719 
 5720 
 5721 
 5722 
 5723 
 5724 
 5725 
 5726 
 5727 
 5728 
 5729 
 5730 
 5731 
 5732 
 5733 
 5734 
 5735 
 5736 
 5737 
 5738 
 5739 
 5740 
 5741 
 5742 
 5743 
 5744 
 5745 
 5746 
 5747 
 5748 
 5749 
 5750 
 5751 
 5752 
 5753 
 5754 
 5755 
 5756 
 5757 
 5758 
 5759 
 5760 
 5761 
 5762 
 5763 
 5764 
 5765 
 5766 
 5767 
 5768 
 5769 
 5770 
 5771 
 5772 
 5773 
 5774 
 5775 
 5776 
 5777 
 5778 
 5779 
 5780 
 5781 
 5782 
 5783 
 5784 
 5785 
 5786 
 5787 
 5788 
 5789 
 5790 
 5791 
 5792 
 5793 
 5794 
 5795 
 5796 
 5797 
 5798 
 5799 
 5800 
 5801 
 5802 
 5803 
 5804 
 5805 
 5806 
 5807 
 5808 
 5809 
 5810 
 5811 
 5812 
 5813 
 5814 
 5815 
 5816 
 5817 
 5818 
 5819 
 5820 
 5821 
 5822 
 5823 
 5824 
 5825 
 5826 
 5827 
 5828 
 5829 
 5830 
 5831 
 5832 
 5833 
 5834 
 5835 
 5836 
 5837 
 5838 
 5839 
 5840 
 5841 
 5842 
 5843 
 5844 
 5845 
 5846 
 5847 
 5848 
 5849 
 5850 
 5851 
 5852 
 5853 
 5854 
 5855 
 5856 
 5857 
 5858 
 5859 
 5860 
 5861 
 5862 
 5863 
 5864 
 5865 
 5866 
 5867 
 5868 
 5869 
 5870 
 5871 
 5872 
 5873 
 5874 
 5875 
 5876 
 5877 
 5878 
 5879 
 5880 
 5881 
 5882 
 5883 
 5884 
 5885 
 5886 
 5887 
 5888 
 5889 
 5890 
 5891 
 5892 
 5893 
 5894 
 5895 
 5896 
 5897 
 5898 
 5899 
 5900 
 5901 
 5902 
 5903 
 5904 
 5905 
 5906 
 5907 
 5908 
 5909 
 5910 
 5911 
 5912 
 5913 
 5914 
 5915 
 5916 
 5917 
 5918 
 5919 
 5920 
 5921 
 5922 
 5923 
 5924 
 5925 
 5926 
 5927 
 5928 
 5929 
 5930 
 5931 
 5932 
 5933 
 5934 
 5935 
 5936 
 5937 
 5938 
 5939 
 5940 
 5941 
 5942 
 5943 
 5944 
 5945 
 5946 
 5947 
 5948 
 5949 
 5950 
 5951 
 5952 
 5953 
 5954 
 5955 
 5956 
 5957 
 5958 
 5959 
 5960 
 5961 
 5962 
 5963 
 5964 
 5965 
 5966 
 5967 
 5968 
 5969 
 5970 
 5971 
 5972 
 5973 
 5974 
 5975 
 5976 
 5977 
 5978 
 5979 
 5980 
 5981 
 5982 
 5983 
 5984 
 5985 
 5986 
 5987 
 5988 
 5989 
 5990 
 5991 
 5992 
 5993 
 5994 
 5995 
 5996 
 5997 
 5998 
 5999 
 6000 
 6001 
 6002 
 6003 
 6004 
 6005 
 6006 
 6007 
 6008 
 6009 
 6010 
 6011 
 6012 
 6013 
 6014 
 6015 
 6016 
 6017 
 6018 
 6019 
 6020 
 6021 
 6022 
 6023 
 6024 
 6025 
 6026 
 6027 
 6028 
 6029 
 6030 
 6031 
 6032 
 6033 
 6034 
 6035 
 6036 
 6037 
 6038 
 6039 
 6040 
 6041 
 6042 
 6043 
 6044 
 6045 
 6046 
 6047 
 6048 
 6049 
 6050 
 6051 
 6052 
 6053 
 6054 
 6055 
 6056 
 6057 
 6058 
 6059 
 6060 
 6061 
 6062 
 6063 
 6064 
 6065 
 6066 
 6067 
 6068 
 6069 
 6070 
 6071 
 6072 
 6073 
 6074 
 6075 
 6076 
 6077 
 6078 
 6079 
 6080 
 6081 
 6082 
 6083 
 6084 
 6085 
 6086 
 6087 
 6088 
 6089 
 6090 
 6091 
 6092 
 6093 
 6094 
 6095 
 6096 
 6097 
 6098 
 6099 
 6100 
 6101 
 6102 
 6103 
 6104 
 6105 
 6106 
 6107 
 6108 
 6109 
 6110 
 6111 
 6112 
 6113 
 6114 
 6115 
 6116 
 6117 
 6118 
 6119 
 6120 
 6121 
 6122 
 6123 
 6124 
 6125 
 6126 
 6127 
 6128 
 6129 
 6130 
 6131 
 6132 
 6133 
 6134 
 6135 
 6136 
 6137 
 6138 
 6139 
 6140 
 6141 
 6142 
 6143 
 6144 
 6145 
 6146 
 6147 
 6148 
 6149 
 6150 
 6151 
 6152 
 6153 
 6154 
 6155 
 6156 
 6157 
 6158 
 6159 
 6160 
 6161 
 6162 
 6163 
 6164 
 6165 
 6166 
 6167 
 6168 
 6169 
 6170 
 6171 
 6172 
 6173 
 6174 
 6175 
 6176 
 6177 
 6178 
 6179 
 6180 
 6181 
 6182 
 6183 
 6184 
 6185 
 6186 
 6187 
 6188 
 6189 
 6190 
 6191 
 6192 
 6193 
 6194 
 6195 
 6196 
 6197 
 6198 
 6199 
 6200 
 6201 
 6202 
 6203 
 6204 
 6205 
 6206 
 6207 
 6208 
 6209 
 6210 
 6211 
 6212 
 6213 
 6214 
 6215 
 6216 
 6217 
 6218 
 6219 
 6220 
 6221 
 6222 
 6223 
 6224 
 6225 
 6226 
 6227 
 6228 
 6229 
 6230 
 6231 
 6232 
 6233 
 6234 
 6235 
 6236 
 6237 
 6238 
 6239 
 6240 
 6241 
 6242 
 6243 
 6244 
 6245 
 6246 
 6247 
 6248 
 6249 
 6250 
 6251 
 6252 
 6253 
 6254 
 6255 
 6256 
 6257 
 6258 
 6259 
 6260 
 6261 
 6262 
 6263 
 6264 
 6265 
 6266 
 6267 
 6268 
 6269 
 6270 
 6271 
 6272 
 6273 
 6274 
 6275 
 6276 
 6277 
 6278 
 6279 
 6280 
 6281 
 6282 
 6283 
 6284 
 6285 
 6286 
 6287 
 6288 
 6289 
 6290 
 6291 
 6292 
 6293 
 6294 
 6295 
 6296 
 6297 
 6298 
 6299 
 6300 
 6301 
 6302 
 6303 
 6304 
 6305 
 6306 
 6307 
 6308 
 6309 
 6310 
 6311 
 6312 
 6313 
 6314 
 6315 
 6316 
 6317 
 6318 
 6319 
 6320 
 6321 
 6322 
 6323 
 6324 
 6325 
 6326 
 6327 
 6328 
 6329 
 6330 
 6331 
 6332 
 6333 
 6334 
 6335 
 6336 
 6337 
 6338 
 6339 
 6340 
 6341 
 6342 
 6343 
 6344 
 6345 
 6346 
 6347 
 6348 
 6349 
 6350 
 6351 
 6352 
 6353 
 6354 
 6355 
 6356 
 6357 
 6358 
 6359 
  <a name="top"></a>2020.08.17  Oracle Application Express 20.1.0.00.13  Copyright © 1999, 2020
 ## 1. Intro, content
 I. BASICS **Top**.....2.1 [Apexws_cloud](#Apexws_cloud).....2.2 [App. builder](#app_builder).....2.3 [Page](#page)  
 .....2.5 [Environm](#environm) .....2.7 [URL](#url)  
 
 II. APP .....**2.9 [Sales web app - DDL, add data](#sales)**
 
 III. SHARED COMPOMENTS .....**3.2  [SHARED C. (lists) 3.2.1 Menu](#shared)**......3.2.2 [Rep.List](#rep_list).....3.2.3 [Ord.WizList](#ord_wiz_list)  
 .....3.3 [Top. right Navig](#top_navig).....3.4 [LOVs](#lov)....3.5 [IMGs](#img)
 
 IV. APP PAGES .....4. [Home p.](#home).....4.4 [Buttons](#buttons).....4.5 [PgStyles](#pgstyles).....5. [Cust](#cust).....6. [Product](#prod).....7. [Order](#order)  
 .....8. [Graph. & Mobile](#gra_mob).....9. [Adv. Rep](#advrep)  
 .....10. [Authoriz](#authoriz).....11. [Search--Style--Calendar](#searchstylecal).....12. **[ Deploy](#deploy)**  
 
 >This txt on my Github :   https://github.com/slavkoss/fwphp/blob/master/fwphp/glomodul/mkd/01/001_db/oracle_apex.txt  (in Markdown format) is based on https://drive.google.com/drive/my-drive    **2020_Riaz_Oracle_APEX_20_For_Beginner.pdf : **,  URL to Download Book Code (no DDL)  https://tinyurl.com/oracleapex20  
 
 >[MD to HTML converters on inet](#md2html)  
 
 
 <br /><br /><br /><a name="Apexws_cloud"></a>
 ## Own Workspace to execute exercises online on  Ora. servers (free)
 [Top](#top).....**Apexws_cloud**.....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm).....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)   ......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img).....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 ### Sales APEX app in Oracle Cloud
 1. **Cloud Dev APEX : https://apex.oracle.com/pls/apex/f?p=4500:1000** is opened  (APEX add  :722441254522763:::::)  
    or dev URL https://apex.oracle.com/pls/apex/f?p=4550  
    To sign in Cloud Dev APEX : https://apex.oracle.com/en/  -> "Sign in" button which opens Login page  
    After "p=" is app alias 4500 (appID) means eg sales-web-app4, possys is workspace.   1000 is pageID.
 2. **To leave APEX dev. envir**, click your name (appearing at top-right) and select Sign Out.    
     
 3.  ** Cloud run Cloud APEX Sales app : https://apex.oracle.com/pls/apex/possys/r/sales-web-app4/home**  (APEX add  ?session=710994255959550)  
 
 
 1.  https://apex.oracle.com/en/ Oracle APEX site
 2.  click  "Get Started for Free" button
 3.  click "Request a Free Workspace" button    
    On the  Identification   wizard  screen,  enter :   Request a Workspace   
    First Name     Slavko    Last Name      Srakocic   
    Email          **slavkoss22@gmail.com**    
    Workspace      **possys**       Country        Croatia       Usage          Personal   
    Confirm. email : Workspace Request Approved  
    Environment: https://apex.oracle.com/pls/apex/   
 
    Click "Create Workspace" button to complete the approval process and set your psw.   
    Workspace Successfully Created Your request for an account has been approved.   
    Button "Continue to Sign in screen" psw=**MYLONGPSW** opens page :  
 
    **Cloud Dev APEX : https://apex.oracle.com/pls/apex/f?p=4500:1000**    (+ :722441254522763:::::) is opened    
    
 
 ## App builder
 1. https://apex.oracle.com/pls/apex/
    (+ f?p=4550:1:117485610537637:::::)
 2. button "Sign in" opens same URL, **page "App Builder"** 
    
    Click on APEX opens **page "APEX"** contans  "Top menus" of page  "App Builder" as icons, instead "Dashboard" is "Team development". 
        
 
 
 <br /><a name="goAPEXConcepts"></a>
  # 2. Oracle APEX Concepts 
 
 ### 2.1 Exercises online on  Ora. servers (free) [Own APEX Workspace on Oracle cloud](#Apexws_cloud) 
 
  ### [2.2-2.8](#app_builder)
 
 <br /><a name="sales"></a>
 # 2.9  Start Building Sales app. 80858
 
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm).....[URL](#url).....**Sales**.....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 https://apex.oracle.com/pls/apex/possys/r/sales-web-app4/home  (+ eg ?session=706440515653484)
 
 1. https://apex.oracle.com/pls/apex/    + eg f?p=4550
 2. Sign In form : Username (your e-mail  address)  and  Password  (you  provided  in  Section  2.3.1) 
 3. Click   App  Builder  icon ->click some  app  -> "App home page" appears. Use App home page to run, edit, import, export, copy, or delete apps
 4. On  App Builder page, click "Create" icon
 5. Select first "New App" option -  Create an App page is displayed
 5. In Appearance section, click "Set Appearance" icon 
 6. Enter **Sales Web Application** in Name box (A)
 7. On Appearance page, in  Navigation section, select **Mega Menu** option (or Shared Components  |  Edit  App  Definition  |  User  Interface  | Navigation  Menu). Click  Choose  New  Icon button  (E),  and select an icon (F) and its color (G). By default, App Builder process creates Home page  along with a couple of pages (Login and Global). Since  you  will  create  other  pages  for  your app in subsequent chapters, **you do not need to add any page** at the moment.
 8. In Features section, click Check All link (K). In  **Settings  section**,  accept  all  default  values.  Here, **Application ID = 80858** (K) .  
    In **default APEX Accounts authentication scheme** (M) users are managed and maintained in Oracle APEX repository.
 9. Click Create App button (N), app  will  be  created  with  default  pages,  including  **Page  1 Home,  Page 9999 Login Page and Page 0 Global Page** (A).  
       Using buttons (View Icons and View Report - B), you can get **different views of this interface**.      
       To **modify** properties of your app (for example, **app name or menu position**), click Edit Application Properties button (D).        
       See  **Delete  this App** link  (E). See **Copy  this  App**  link  (F) -  makes  an  exact  copy  of  app under different ID.  
 10. **Click  Run  App**  (H) -  type same username (your e-mail ID) and password you entered earlier to access development environment.  
      Home page bottom is **Developer Toolbar** :
      1. Application option (D) takes you to the App Builder page, where you can select a different page to work on.
      2. Edit Page  option (E) in this toolbar takes you to Page Designer to edit the current page
      3. Session  option  brings  up  a  page  (see  Figure  2-6)  that displays current state of app so that you can verify its behavior
      4. Sign Out option (F top page right) exits app.
      5. Administration  menu  option  (G)  -  Administration  page  that  lists  all  the  features  you selected  in  step 9. Features section.
 
  
 
  
 <br /><br /><br /><a name="goDBobjects"></a>
 ## 2.10 Create DB Objects interactively (no SQL) for Sales app
 
 Five  tables : DEMO_STATES,  DEMO_CUSTOMERS,  DEMO_PRODUCT_INFO, DEMO_ORDER,  and  DEMO_ORDER_ITEMS.  
 in folder J:\awww\www\fwphp\glomodul\mkd\01\001_db  
 
 app 4500, pg 3002 is SQL workshop :     https://apex.oracle.com/pls/apex/f?p=4500:3002     
 
 app 4500, pg 1001 is SQL workshop Object browser :     https://apex.oracle.com/pls/apex/f?p=4500:1001    
 
 **See at end this txt [DB Objects](#DBobjects)**
 
  
 <br /><br /><br /><a name="goDBobjectsData"></a>
 ## 2.11 Add Data to tbl, see oracle_apex_....csv files
 1. From main APEX  menu, select  SQL Workshop | Utilities | Data Workshop
 2. On Get Started page, click Load Data button
 3. On next  screen,  click Choose  File  button.  In Open dialog box, select DEMO_CUSTOMERS csv 
 4. Load Data page will appear on your screen. Select options on this screen. By selecting Existing Table option you are informing that you want to upload the csv file data to eg existing DEMO_CUSTOMERS table. Once you select the database table, **APEX will automatically map columns**. Click Load  Data  button  on  this  page.  A  message  " Data  in table DEMO_CUSTOMERS appended with 7 new rows! " should appear on your screen. Click the View Table button to browse data.
 
 **See at end this txt [DB Objects data](#DBobjectsData)** 
 
 
 <br /><br /><br />
 ### Next
 
 In chapter 3, we create building blocks (**shared components**) of  app. 
 
 Shared  Components  wizards  allow  us  to  define components we can re-use in pages (better name "modules" like Ora. Forms) throughout our app.  (common, global on app level).
 
 Work in detail on Home page in Chapter 4 to convert  it  into dashboard. Chapter 5 - Customers. Chapter 6 - Products. Chapter 7 -Orders. 
 
 <br /><br /><br /><br /><a name="shared"></a>
 # 3. Create (shared, common, appglobal) App Components
 You  can  see  a  list  of  all  Shared  Components utilized on some  app page by accessing its "**Shared Components" tab   in the Page Designer**. 
 
 **See  [3.1 About Shared Components](#shared_about)**
  
 # 3.2 Create Lists - collections of links rendered using template
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm).....[URL](#url).....[Sales](#sales).....**SHARED C.**......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 ### Shared Components you will use (create) for Sales Web app
 1. Lists
 2. List of Values (LOV)
 3. app Logo
 
 **To access Shared Components page** :
 1.  Select Database apps from the App Builder menu.
 2.  Click Edit icon (A) under Sales Web app.
 3.  On the next screen, use either of the two Shared Components icons (pyramid of 3).
 
 For each list entry, you specify **display text, a target URL**, and other properties to control **when and how the list entry displays**. You control the display of the list and the appearance of all list entries by **linking the list to a template**.
  
 
 <br />
 ## List 1 Main top menu (Desktop Navigation Menu List)
 APEX  App  Builder  wizard created default Home and Administration mnuitems.
 
 Main top menu is hierarchical list of navigation, which appears either as a  **responsive side bar or at top of  window**.  Based on available space, navigation bar either displays a **full menu or collapses to a narrow icon bar**. 
 
 Modify Desktop Navigation Menu List list to add app submenu level1 entries **Setup, Orders, Reports** : 
 1.  In Shared Components -> Navigation section -> click "Navigation Menu" option
 2.  On  Lists  page,  click "Desktop Navigation Menu" option, which carries two entries Home and Administration
 3.  On  List  Details  page,  click  **Create  Entry  button**  (A) to create **new menu item named Setup**. This menu entry **will have sub-entries** that will allow you to **access Products and Customers modules**. 
    
    Fill in **values for Setup menu submenu level1 entry** :
    1. Do not select anything in the first attribute (Parent  List  Entry), because  initially  you  will  create  level  one entries
    2. Click pop-up LOV icon representing **Image/Class** attribute.    
       1. From Show list, select Font APEX, and from Category, select Web app
       2. Click Go button to refresh the view
       3. Scroll down to the middle of the icons list and select **fa-database** icon. This image will be displayed for Setup  submenu  at  run  time.  Note  that  you  can  select  any  **image from list or input its name** directly in the Image/Class attribute.     
    3. Type Setup in **List Entry Label field**. This label will appear in app menu.    
    4. In **Target Type attribute** you specify a **page in current app** or any valid **URL**.  Target Type and Page properties inform Oracle APEX where to land when a menu item is clicked, eg Orders entry will take you to page 4.     
 
 
 4.  Using button labeled Create and Create Another, create **two more level-1 entries** to form the **main menu of our app** because we set No Parent List Item for all three entries.    
 
        | Parent List Entry      | Image/Class                    | List Entry Label | Target Type             | PgID               | Help |
        | :----------------------- | :-------------------------: | :---------------- | :----------------------- | --------------: | :----------------------- | 
        | No Parent List Item | eg fa-database             | **Setup**      | No Target                     |    |not  associated  to  any  app  page |
        | No Parent List Item | eg fa-send-o                  | **Orders**    | Page in this app         | [4](#order)  | |
        | No Parent List Item | eg fa-table-arrow-up | **Reports**  |  Page in this app        | 1                       | |
 
    After adding last entry (Reports), **click Create List Entry** button.
 
 5. Using same process create **submenus level-2 menu entries**.  First two entries will come under the main Setup menu item, while Reports menu will contain two child entries (Graphical Reports and Advance Reports).
 
    | Parent List Entry     | Image/Class | List Entry Label                    | Target Type          | PageID        | Help |
    | :----------------------- | :-------------: | :------------------------------ | :------------------- | -------------: | :----------------------- | 
    | **Setup**                 | eg ...               | **Manage Customers** | Page in this app | [2](#cust) | |
    | Setup                            | eg ...               | **Manage Products**     | Page in this app | [3](#prod)  | |
    | **Reports**             | eg ..                | **Graphical Reports**    | Page in this app | 1   | |
    | Reports                        | eg ...               | **Advance Reports**      | Page in this app | 1  | |
 
    TIP: If you make a mistake while creating these menu entries, you can rectify it. After creating the last entry, click Create List Entry button on Create/Edit page to move back to the List Details page. On this page, click menu entry you want to modify (under Name column) to call its definition in Create/Edit page. Rectify the error and click Apply Changes button.
 
 6. Create l**level 3 entries**. First 5 entries will appear as submenu choices under Graphical Reports menu. Similarly, Monthly Review Report and Customer Invoice will be placed under Advance Reports. All the settings will set up a hierarchical navigation for your app.
 
    | Parent List Entry     | Image/Class     | List Entry Label | Target Type             | PageID | Help |
    | :----------------------- | :----------------: | :-------------- | :---------------------------- | -------: | :----------------------- | 
    | **Graphical Reports** | eg ...| **Customer Orders** | Page in this app | 1 | |
    | Graphical Reports | eg ...| **Sales By Category/Products** | Page in this app | 1 | |
    | Graphical Reports | eg ...| **Sales By Category/Month** | Page in this app | 1 | |
    | Graphical Reports | eg ...| **Order Calendar** | Page in this app | 1 | |
    | Graphical Reports | eg ...| **Product Order Tree** | Page in this app | 1 | |
    | **Advance Reports** | eg ...| **Monthly Review Report** | Page in this app | 0 |**set to zero**, because it will be invoked through a print request that will be configured in Chapter 9.|
    | Advance Reports | eg ...| **Customer Invoice** | Page in this app | 1 | |
 
    TIP: After making any modification in your app you can test it immediately. For example, after creating the navigation menu, hit Run Page button (at top-right) to see the app menu.
 
  
 
 <br /><br /><br /><a name="rep_list"></a>
 ## List 2 Reports List
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm).....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared).....**Rep.List**.....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home) 
   
 List "Reports List" will have several links that will lead to different reports in your app.  Note that you created the same links in the navigation menu in the previous section **to call some of these reports from app menu**. Reports List being created here will be used on a **dedicated report page** to call respective reports - see Chapter 8 section 8.2.
 
 1. Go to **App 80858 -> Sales Web App -> Shared Components -> Navigation -> Lists**. There are 7 default (APEX created) lists.  
    Click Create button to create a new list.  
 2. Select **From Scratch** on the Source wizard screen and click Next.    
    On the next screen, enter **Reports List** for Name, select **Static** as the list Type, and click Next.    
    When you create a static list you define a list entry label and a target (either a page or URL).  
 3. Enter the following values in Query or Static Values screen.  
    Initially, the wizard allows you to create five entries. The remaining entries and Image/Class properties are created and set after saving the first five.  
 
    | List Entry Label                                  | Target PageID | Image/Class |
    | :--------------------------------------- | ----------------: | :--------------|
    | Customer Orders                               | 17                    |  |
    | Sales by Category and Product   | 16                    | |
    | Sales by Category / Month           | 5                     | |
    | Order Calendar                                 | 10                   | |
    | Product Order Tree                         | 19 | |
    | **Gantt Chart**                            | 20 | |
    | Box Plot                                               | 21 | |
    | Pyramid Chart                                  | 22 | |
    | List View (Mobile)                           | 23 | |
    | Column Toggle Report (Mobile) | 24 | |
    | **Reflow Report (Mobile)**   | 25 | |
    | Monthly Review Report               | 0 | |
    | Customer Invoice                           | 50 | |
 
 4. **After entering the first five list entries** 
    1. click Next, accept default values in next screen, and click Create List button.    
    2. You will be taken back to the Lists page, where you will see new list "Reports List"  
    3. Modify list by clicking Reports List link in the Name column  
    4. Click Create Entry button to add the sixth entry. Enter Product Order Tree in List Entry Label. Set Target Type to Page in this app and enter 19 in the Page attribute.   
    5. Click Create and Create Another button to add the remaining entries, as shown in the table above   
    7. Modify each entry by clicking its name in the List Details interface and add image references. Click the Apply Changes button after adding the image reference  
 
 
 
 <br /><br /><br /><a name="ord_wiz_list"></a>
 ## List 3 "Order Wizard" List (wizard steps to create an order)
    [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm).....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared).....[Rep.List](#rep_list).....**Ord.WizList**.....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home) 
    
 List 3 is another utilization of lists. Rather than associating list items to pages in the app, you will use it for visual representation. It will be used while creating orders in Chapter 7. In our app, we will create an order using a set of wizard steps in the following sequence:  
 1.    Identify Customer
 2.    Select Items
 3.    Order Summary   
    
 <br />
 So :
 1.  Go to Shared Components | Navigation | Lists and click Create button
 2.  Select the first From Scratch option and click Next
 3.  Type **Order Wizard** in the Name box, set Type to Static, and click Next
 4.  On the Query or Static Values screen, enter the following  values and click Next
 
    | List Entry Label        | Target Page ID or custom URL | Help |
    | :----------------------- | :------------------------------------: | :------------------------ | 
    | Identify Customer   | 11                                                          |        |
    | Select Items               | 12                                                         |        | 
    | Order Summary       | 14                                                         |        |
 
 5.  Click Create List button on the Confirm screen.
 
 6.  Modify the newly created Order Wizard list.
 
 7.  Edit each list item, set **Target Type attribute to No Target** for all 3 list items.  
    1. The No Target value is set because this list is intended to **display the current order  wizard step** where the user is **within the order processing module**, and **not to call a page** in the app.    
    2. In  Current  List  Entry  section, set "List  Entry Current for Pages Type" to **Comma  Delimited  Page  List**  for  all 3  list  items,         and  set  "List Entry Current for Condition" attribute  to **11, 12, 14**.   
    3. Click Apply  Changes  button  to  save  the modifications.
 
 **List Entry Current for Pages Type** attribute specifies **when this list entry should be current**. Based on the value of this attribute, you define a **condition to evaluate**. When this condition is true then the list item becomes current. The template associated with list item gives users a visual indication about the active list item. The following figure illustrates the use of Order Wizard list. Being the first step in the order wizard, the Identify Customer list item is marked as current (when Page 11 is called to enter a new order), while the remaining  two  are  displayed  as  non-current.    After  selecting  a  customer, when you move on to the next step to select ordered items, the Select Items entry becomes current and the first and last entries become inactive.
 ```
                      -------------------------------
                      |                             |
                      |                             |
         Non current  -------------------------------
 
         -------------------------------
         |                             |
         |                             |
 Current -------------------------------
 ```
 
  
 
 
 
 
 <br /><br /><br /><br /><br /><a name="top_navig"></a>
 # 3.3 Desktop Navigation Bar eg top right
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm).....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared).....[Rep.List](#rep_list).....[Ord.WizList](ord_wiz_list).....**Top. Navig**.....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home) 
 
 Also used to link various pages within app eg  Help pages, Sign Out. **Location eg top right** of navigation bar depends upon associated page template. When you create a navigation bar, you specify an image name, label, display sequence, and target location (a URL or a page). Navigation bar used in our app will show :
 
 **feedback page icon, Page Help entry, About Page entry, id of logged in user and a Sign Out link**.
 
 All these entries are created automatically when you create  new app.
 
  
 
  
  
  
  <br /><br /><br /><br /><br /><a name="lov"></a>
 # 3.4 List of Values (LOV)
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm).....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared).....[Rep.List](#rep_list).....[Ord.WizList](ord_wiz_list).....[Top. Navig](top_navig).....**LOVs**.....[Home p.](#home)
 
 Used to control input values and **limit users selection**. You can define two types of lists: 
 1. static list of values is based on **predefined display and return values**
 2. dynamic LOV is based on a **SQL query**  and it is executed at runtime.
 
 ## 3.4.1 LOV CATEGORIES (U, T) - STATIC
 See 6.4.2 Attach Categories LOV.
 
 
 ## 3.4.2 LOV PRODUCTS WITH PRICE - DYNAMIC    
 You will use this LOV in Chapter 7 section 7.4.2.
 1. Shared Components -> Other Components section -> Lists of Values  APEX page -> Click Create button
 2. Select From Scratch and click Next.
 3. Enter **Products with Price** in the Name box. Select Dynamic Type and click Next.
 4. On the List of Values Source screen, select SQL Query for the Source Type, and enter the following query in the Enter a SQL SELECT statement box.
    ```
    select apex_escape.html(product_name) || ' [$' || list_price || ']' d
         , product_id r
    from demo_product_info
    where product_avail = 'Y'
    order by 1
    ```
 5. On the final Column Mappings screen, select R for Return Column, D for Display Column  and click the Create button to finish the wizard.
 
  
 
 **APEX_ESCAPE.HTML function** is used to protect against XSS (Cross Site Scripting) attacks. It replaces characters that have special meaning in HTML with their escape sequence. It converts occurrence of :
 
     ```
     & to &
     “ to "
     < to <
     > to >
     ```
 
  
 
 ## 3.4.3 LOV STATES (države) - DYNAMIC (used in crUD form Customers)
 See 5.4.2 Change cust. column "P7_CUST_STATE" to hold predefined LOV! States list.
 
  
 
 ## 3.4.4 LOV NEW OR EXISTING CUSTOMER - STATIC
 Will be incorporated in initial Order Wizard step (Chapter 7 Section 7.5.4) to select an existing customer for a new order or to create new one.
 1. Shared Components -> Other Components section -> Lists of Values  APEX page -> Click Create button
 2. Select From Scratch and click Next.
 3. Enter **NEW OR EXISTING CUSTOMER** in Name box, select Static as its Type and click Next
 4. Fill in display and return values as shown in following tbl and click Create LOV button.
 
    | Sequence | Display value | Rerturn value |
    | :------- | :------------ | :------------ | 
    | 1 | Existing customer    | EXISTING      |
    | 2 | New customer         | NEW           |
 
  
 
 
 
 <br /><br /><br /><br /><br /><a name="img"></a>
 # 3.5 Images
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page)   [Environm](#environm).....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....**IMGs**....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 You can reference images within your app by uploading them to Images Repository. When you upload an image, you can specify whether it is available to all apps or a specific app. Images **uploaded as shared components** can be referenced throughout an app. They may 
 1. include images for application menus or buttons 
 2. or may represent icons that, when clicked, allow users to modify or delete data.
  
 **Images uploaded to the images repository should not be directly related to the app data** such as images of products and employees. Such images must be stored in the apps schema alongside the data to which the image is related. You will follow this approach **in Chapter 6 to save each products image along with other information in a DB table**.  
 
 APEX images are divided into two categories:  
 1. Workspace images are available to all applications for a given workspace
 2. App images are available for only one app
 
 ### Add your app logo to images repository.
 Logo appears at every page top in app.
 1. Shared Components -> Files section -> click Static Application Files
 2. Click the Upload File button.
 3. Click the Choose Files button and select logo.ico file, available in the book code
 4. Click the upload button. After uploading the image, you need to **tell Oracle APEX to use this file as your app logo** :
 5. Shared Components -> User Interface section -> **User Interface Attributes**
 6. Logo section -> Image and Text for Logo
 7. Enter **#APP_IMAGES#oracle_apex.ico** in Image URL box,  
    and enter **Sales Web App** in the Text box. An application logo can be an image, text, image and text, or based on custom markup.
 
 When you select a type for your app logo, additional attributes appear depending upon your selection. With this selection, your app logo and app name both will be displayed on each app page. The built-in substitution string (APP_IMAGES) is used to reference uploaded images, JavaScript, and cascading style sheets that are specific to a given app and are not shared over many apps. You must use this substitution string if you upload a file and make it specific to an app. Note that you must use the correct case for the image file name and extension, else the logo will not be displayed at runtime. Click the Apply Changes button.
 
 Run the app. 
 
  
 <br /><br /><br /><br /><br /><br /><a name="home"></a>
 # 4. Page Home (App Dashboard, default page)
 with 6 stacked canvases (blocks)
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page)   [Environm](#environm).....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)....**Home page**.....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
  
 **4.1 About Home Page**    
    Represents objective of app (module). Is created as a blank slate and needs to be populated with **content relevant to your app (module) **-  stuff related to sales is :   
    6 regions to present different views of sales data (see 2.6 and 2.9 Page Designer interface and how to access your workspace).  
 
 **4.2 Modify Home Page - 2 properties that are usually enough to set for the main page**   
 1. Sign in to your workspace -> in main menu click App Builder option -> click Edit icon under Sales Web App - see Figure 3-3 in chapter 3.  
     
 2. Click Home page icon (if you’re browsing the page in Icon view). This action will **open definitions of Home page in Page Designer interface**.  
 Modify Page Attributes **Home page Name and Title properties** with meaningful labels.  
 Rendering tab to your left -> click root node  to refresh Property Editor (on the right side) with the main page properties. Set the properties mentioned in the following table and click the Save button (at the top-right corner).  
 
    | Property | Value         | Note |
    | :------- | :------------ | -----------------------------------  |
    | Name     | Sales Web App |  |
    | Title    | Sales Web App | APEX engine uses title in place of **#TITLE# substitution string** used in page template inserted between the HTML tags <TITLE> and </TITLE>  |
 
 **Use help** :    Click a property in the Property Editor and then click the Help tab (in the Central pane).
 
  
 
 ## 4.3 Create Regions (stacked canvases - blocks) in Home Page   
 You put page items (Text Field, Select List, Radio Group, report, chart, static HTML content, buttons...) on a page under a specific region (page area, section that serves as a container for content ee to group page elements). Each region can have its **own template**, which controls its appearance.
 
 Some of our regions will use **Oracle JET Charts**. Oracle JET Charts (charting library) is a component of JET. These charts work on any modern browser regardless of platform, screen size, or features. JET is integrated Oracle JavaScript and CSS3 and HTML5 Extension, open source Toolkit 
 
 **To remove a component** (such as a region or an item) from a page, right-click the desired component in the Rendering section, and select Delete from the context menu. If you just created the component, click Undo (A) on the Toolbar to remove it from the page.
 
 
 
 <br /><br /><br /><a name="homereg1"></a>
 ## Home Page region 1 : "Top Orders by Date"
 [Top](#top).....[Home reg.1](#homereg1).....[Home reg.2](#homereg2).....[Home reg.3](#homereg3).....[Home reg.4](#homereg4).....[Home reg.5](#homereg5).....[Home reg.6](#homereg6).....[Home buttons](#hbuttons).....[Home styles](#hstyles)
 
 Displays top five orders by date from DB using a **bar chart - horizontal bars=months and sumsales on x axe** - SQL (or PL/SQL function) populated - summarized sales figures (bars) for each date from Orders table. 
 
 !!!!! ***Rendering tab -> right-click Regions -> select Create Region*** to place new region = </> New under Content Body.
 
 **Click "</> New node" ** (future "Top Orders by Date" stacked canvas) and set common region properties in **Property Editor**. 
 
 Property Editor is **declarative (ee functional programming)** above some prog.language procedural code.
 
 <br /><br />
 ### Set common region properties (attributes)**
 
 |  | Property | Value         | Help |
 |-:| :------- | :------------ | :-------------------------------- |
 | 1 | Title   | <span style="color:blue"><i><b>Top Orders by Date</b></i></span> |  Title should be unique to every region - **region purpose** . Region has **child node - component - named Attributes** - contains **region-specific properties** (region properties are common to all regions). Eg properties of a Static Content type region are different from a Chart region. |
 | 2 | Type    | Chart | = **page or page component purpose**. Default type is "**Static Content = HTML max 33.8 kB**" region with an empty source text eg **About section** on the right side of the App Builder interface region whose source is displayed text. After setting the second attribute (Type), you will be informed through the Messages tab that there **are some errors** on the page. These messages relate to some mandatory properties you will set accordingly in subsequent sections. |
 |   | Location |**Local Database** | or sourced from : 2.  **Remote DB**, connection is defined using REST Enabled SQL  or from 3. **Web Source eg RESTful web service** defined using Web Source Modules |
 |   | Type | SQL Query | or PL/SQL fn - how the data is queried  |
 | 3  | SQL Query | select order_day, sales from (select to_char(o.order_timestamp,'Mon DD, YYYY') order_day, SUM(o.order_total) sales from demo_orders o group by to_char(o.order_timestamp,'Mon DD, YYYY'), order_timestamp order by 2 desc nulls last) where rownum < 6 | order by 2 desc nulls last is in 11g DB, but order by 2 desc nulls last **fetch first 5 rows only**    - not in 11g DB  |
 | 4 | Start New Row | On (default) | DB apps created in Oracle APEX use **layout comprising rows with 12 columns** to position page elements. "On"  **puts region on a new row**.  Next region "Sales for This Month"  - Start New Row attribute it is set to Off to place that **region adjacent to this one**.  |
 | 5 | Column | Automatic  (default) | **Automatically finds a column position (col_ordnum 1 to 12) for the region**. There are **three regions on a single row, each region spans 4 columns**. Region1 will span from column number 1 to 4,  R2 from 5 to 8, R3 from 9 to 12  |
 | 6 | Column Span | 4 | narrows "Top Orders by Date" region |
 | 7 | Show Region Icon |  check mark to select this option | Under Template Options |
 |    | Body Height | 240px | Under Template Options  (Click OK to close dialog screen) |
 |    | Icon | fa-lg fa-apex | If **Template property** is set to default "Standard" value for a region, you can place an icon in region header. First, select Show Region Icon option (under Template Options) to display region icon in region header beside region title. Then, click the LOV for the Icon property (under Appearance), select a Style (for example, Large), and choose and icon from provided list.  |
 
 <br /><br />
 ### Set region-specific properties
 Click Attributes node under new region and set the following region-specific properties :
 
 Set Type of this chart region to horizontal bar :
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 8 | Type   | Bar |
 | 9 | Orientation   | Horizontal |
 
 **Click the New sub-node under Series and set the following properties:**
 
 |  | Property | Value         | Help         |
 |-:| :------- | :------------ |:-------------- |
 | 10| Location (under Source) | Region Source | When you set the region type to Chart (2), a Series node is placed underAttributes with a New sub-node under it. In this node you specify Location (10) for the Series. Since an SQL Query has already been defined, we set it to Region Source, which points to the region’s SQL Query defined in the third attribute. By default, a chart is created with **one series (named New)**, but you can add more (see Chapter 8 section 8.3 steps 5 and 6).  |
 | 11| Label   | ORDER_DAY | Label attribute (11) is set to ORDER_DAY column to display values from this column as labels |
 | 12| Value   | SALES | to show sales figures (bars) |
 | 13| Type (under Link) | Redirect to Page in this application | |
 
 **Click No Link Defined under Target and set props in Link Builder dialog box:**
 
  Define links on charts is done in properties 13-15. Links let you **call another app page for browsing details**.
 
 |  | Property | Value         |          Help      |
 |-:| :------- | :-------------- |:---------------- |
 | 14| Type   | Page in this application | When you click "No Link Defined" under Target prop., a small window titled Link Builder comes up, where you specify **target page details**. Once you set the link type to "Redirect to Page in this Application", a property named Target appears, where you provide the ID of the target application page you want to link with the chart (properties 14 and 15). The Template property (not indicated in the previous table) is set to Standard by default, which forms a **border around the region and displays the regions title across the top**.  |
 | 15| Page   | 4    (Click OK to close the dialog screen) | |
 
 
 To test your work from time to time eg after completing this region you can **save and run page** (by clicking the Save and Run Page button  at the top-right corner) to check how the region appears on it. At this stage, your Home page will show just **one region (Top Orders by Date)**. If you **click any bar in the chart, app tries to open Page 4 (Orders)** and throws an error, because Orders page does not exist. After completing Page 4 (Orders) in Chapter 7, when you run the Home page and click any of these links, Page 4 will be rendered carrying a list of orders.
 
  
  
  <br /><br /><br /><a name="homereg2"></a>
 ## Home Page region 2 : "Sales For This Month"
 [Top](#top).....[Home reg.1](#homereg1).....[Home reg.2](#homereg2).....[Home reg.3](#homereg3).....[Home reg.4](#homereg4).....[Home reg.5](#homereg5).....[Home reg.6](#homereg6)....[Home buttons](#hbuttons).....[Home styles](#hstyles)
 
 Page region 2 uses a **Badge List - 2 circles "Tot.sales and Tot.orders"**.  List is dynamically rendered based on a SQL Statement (or PL/SQL function) each time the page is viewed. Later on, we will transform it to present  fetched data in graphical format. 
 
 Create another region as previous region.
 
 <br /><br />
 ### Set common region properties (attributes)**
 
 **Rendering tab to your left App builder -> Home icon (App 80858) -> Page Designer** -> right-click Regions -> select **Create Region** from context menu. New region will be created under previous one. Set  following properties for this region in Property Editor.  
 TIP:  If a region is not created in the desired location, **drag and drop it to the appropriate location** in the rendering tree.
 
 |  | Property | Value         |   Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Title   | **Sales for This Month** | |
 | 2 | Type   | Classic Report | |
 |  | Location   | Local Database (default) | |
 |  | Type   | SQL Query | or **PL/SQL function** to fetch the desired data set. All columns you define in the query appear in a separate node (Columns) under region |
 | 3 | SQL Query   | select sum(o.order_total) total_sales,  count(distinct o.order_id) total_orders, count(distinct o.customer_id) total_customers from demo_orders o where order_timestamp >= to_date(to_char(sysdate,'YYYYMM') \|\| '01','YYYYMMDD') | |
 | 4 | Start New  Row   | Off | |
 | 5 | Column   | 5 | |
 | 7 | Body Height  (under Appearance -> Template  Options) | 240px | |
 
 
 ### Create hidden page item to store first day of currmonth for behind processing
 
 **right-click Sales for this Month region and select Create Page Item** from the context menu. A **new node named Items** will be created with a new item named **P1_NEW**.  Hidden items can be seen in the **Page Designer**, but they do not appear on the page at run time.
 
 Click the new item and set the following properties:
 
 | Property         | Value         |          Help                              |
 | :--------------- | :------------ | :---------------------------------- |
 | Name             | P1_THIS_MONTH |  was P1_NEW |
 | Type             | Hidden        | |
 | Value Protected  | On (default)  | prevents item value from being manipulated when page is posted |
 | Type (under Source) | PL/SQL Expression | |
 | PL/SQL Expression   | to_char(sysdate ,'MM') \|\| '01'\|\| to_char(sysdate ,'YYYY') | or if Order Date column on Page 4 is rendered as 09-JAN-2017 :  '01-'\|\|to_char(sysdate ,'MON')\|\|'-'\|\|to_char(sysdate ,'YYYY') |
 
 Select **TOTAL_CUSTOMERS** column and set the Type attribute of this column to **Hidden Column** (invisible at run-time). 
 
 ### TOTAL_SALES to transform it into a link
 
 **How to refer to a page item in links - present it as a substitution string : &P1_THIS_MONTH.  - terminated with a period !!** - see Value property in serial 6 in the following table. 
 
 Rendering section -> expand Columns node under the Sales for This Month region -> click TOTAL_SALES column - Figure 4-4.  Set following props :
 
 |  | Property | Value         |          Help                              |
 |-:| :------- | :------------ | :----------------------------------- |
 | 1 | Type   | Link | column is to be displayed as a link |
 | 2 | Format Mask   | in LOV select 5,234.10 | produces the mask 999G999G999G999G990D00 from list of values that shows  some common currency and date/time formats, 9 is optional digit, 0 is required digit, G is thousand separator, and D is for decimal point |
 
 Define link : Click **No Link Defined** under Target -> Link Builder dialog is opened -> set following properties.  To call another app page, it is suffice to transform a column into a link by setting  three values : Link, Page in this application, and Page Number. Recall that **in previous region you formed a similar kind of link**. 
 
 |  | Property | Value         |    Help               |
 |-:| :------- | :------------ | :-------------------- |
 | 3 | Type   | Page in this app | link should call a page in current app |
 | 4 | Page   | 4 | Target page number. Next prop. Name (5) and Value (6)  are values to be passed from currpg to targetpg. They form a filter argument to display current month's order on the target page (Page 4 - Orders, to be created in Chapter 7). Values for properties (5) and (6) are **usually picked from LOVs** using Page attribute, but due to **absence of Page 4 of our app**, we entered them  manually.  |
 | 5 | **Name** (under Set Items)   | IRGTE_ORDER_DATE | to specify session state for an item |
 | 6 | **Value** (under Set Items)   | &P1_THIS_MONTH.  (do not forget to add the trailing period) | to specify session state for an item |
 | 7 | Clear Cache   | RIR,4 | resets the interactive report on Page 4 |
 | 8 | Action   | Reset Pagination | resets pagination of the target page |
 
 **Click OK to close the Link Builder - Target dialog box**
 
 |  | Property | Value         | |
 |-:| :------- | :------------ | |
 | 9 | Link Text   | Text #TOTAL_SALES#  (select this value using the **Quick Pick button**) | column to be displayed as a link |
 
 In the current scenario, we used one name/value pair to **filter interactive report on the target page**. However, this section **allows you to set as many filters as you want**. **Each time you provide a value, another row is appended**, thus allowing you to enter another pair of name/value. You can use this section to also specify **target pages items in the Name column** and can set their values using the Value box.  
 
 For example, to set a customers  credit limit items value on the target page, enter the name of that item :  
 (P7_CREDIT_LIMIT) in the Name box and type the corresponding value (5000) in the Value box. This way, **when you call the target page, the value (5000) appears in the credit limit item**.
 
 Note that **column names are enclosed in # symbol when you specify them in Link Text attribute**. This is a **mandatory attribute** whose value can be selected using the Quick Pick button appearing next to it.
 
 At run-time the link is formed like this (if the application's Friendly URL attribute is turned off):  
 **f?p=145615:4:8824748217892::NO:RP,RIR,4:IRGTE_ORDER_DATE:01012018**  
 using the following syntax:  
 **f?p=&APP_ID.:Page:Sessionid::NO:RP,RIR,4:IRGTE\_(itemname):itemvalue** (stored in &P1_THIS_MONTH item). Table URL parameters :  
 
 | Argument      | Explanation         |
 | :--------------- | :-------------------- |
 | &APP_ID. | eg 80858.  The  expression  used here  is  called  a  **substitution  string  that  holds the  application  ID** used to make app more  portable.
 | :  |  colon  special  character  is argument  separator.  Since the URL contains no REQUEST argument, the position of this argument is left empty - see additional  colon  before  the  debug  argument (NO). |
 | 4 | target page 4 = Orders we are calling in URL |
 | Sessionid | number  (8824748217892)  appearing  in the URL is session ID of our app and is used **to create links between app pages**  by  maintaining  the  same  session  state among  them.  Note  that  session  ids  are managed automatically by Oracle APEX. |
 | NO | = do not enter the debug mode. References  debug  flag,  which  is  used  to display  app  processing  details. |
 | RP,RIR,4 | Placed in URL's ClearCache position, this argument **RP (Resets Pagination) for interactive report  on  Page  4**.  RIR=Reset  Interactive Report. Pagination =**info about numrows and currrownum  within result set**. You control  how  pagination  displays  by  making selections  from  **Pagination  Type  attribute**  in  Property  Editor (prop palete u F6i) -  style of links or buttons used to navigate to the next or previous page.  Clear  cache  section can have RIR or CIR or RP to reset, **clear, or reset**  pagination of primary default reports of all interactive report regions on the target page. |
 | IRGTE_ORDER_DATE | is  used  in itemNames position. IR (Interactive Report) string is used along with greater than and equal to operator  (GTE),  followed  by  an  item  name (ORDER_DATE  -  an  item  on  Page  4).  This argument  acts  as  a  filter  and  is  used  in conjunction  with itemValue (&P1_THIS_MONTH. mentioned underneath) to  only  display  current  month's  orders.  In simple  words  it  says:  **Order  date  of interactive  report  is  greater  than  or  equal  to item value**. |
 | &P1_THIS_MONTH. | Used  in  the  itemValue  position,  the  value stored in this hidden item is forwarded to the target page. **To create a filter** on an interactive report  in  a  link,  use  the  string IR\<operator>\_\<target  column  alias>  in  the ItemNames  section  of  the  URL  and  pass  the filter value in corresponding location in the IORDER_DATEtemValues  section  of  the  URL.  See  section 2.7 in Chapter 2 for further details on Oracle APEX f?p syntax. Other operators you can use to filter an interactive report include: EQ = Equals (the default operator) LT = Less than GT = Greater than LTE = Less than or equal to GTE = Greater than or equal to LIKE = SQL LIKE operator N = Null To apply the filter, you must use correct date format  mask  in  the  SQL  query  for order_timestamp column. For example, if the Order Date column on Page 4 appears as  01-JAN-2017,  then  you  must  use 'DD/MON/YYYY' format mask. |
 
 
 <br /><br />
 ### Set region-specific properties
 
 "Sales for This Month" region -> Click Attributes node -> Switch its **Template from "Standard" to "Badge List"** -> click **Template  Options**  ->  set  **Badge  Size  to  128px**,  **Layout  to  Span Horizontally** -> click OK.
 
 By setting these region properties, the derived one  row  summarized  report  will  be  presented  as  a  badge  list,  spanned horizontally.
 
 Also set Pagination Type to **No Pagination (Show All Rows)**.
       
 Click Save and **Run Page button** to see this **region with two badges (circles) on it displaying 1. current month's sales and 2. number of orders placed**. 
 
 First badge - Current month's sales - acts as a link and leads you to Page 4 to display details of the summarized data. Since Page 4 will be created in Chapter 7,  you will get Page Not Found message if you click this badge.
 
  
  
  
 <br /><br /><br /><a name="homereg3"></a>
 ## Home Page region 3 :  "Sales by Product region" - pie chart
 [Top](#top).....[Home reg.1](#homereg1).....[Home reg.2](#homereg2).....[Home reg.3](#homereg3).....[Home reg.4](#homereg4).....[Home reg.5](#homereg5).....[Home reg.6](#homereg6)....[Home buttons](#hbuttons).....[Home styles](#hstyles)
 
 Page region 3 shows **sale figures (sums as pie slices) visible when you move the mouse pointer over pie slices of pie chart** for individual products.
 
 Create another region as previous region.
 
 
 <br /><br />
 ### Set common region properties (attributes)**
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 1 | Title   | **Sales by Product **|
 | 2 | Type   | Chart |
 |  | Location   | Local Database |
 |  | Type   | SQL Query |
 | 3 | SQL Query   | SELECT   p.product_name \|\| ' [$' \| \| p.list_price \|\| ']' product, SUM(oi.quantity * oi.unit_price) sales FROM     demo_order_items oi, demo_product_info p WHERE   oi.product_id = p.product_id GROUP BY p.product_id, p.product_name, p.list_price ORDER BY p.product_name desc |
 | 4 | Start New  Row   | Off |
 | 5 | Column   | 9 |
 | 5 | Column span  | 4 |
 | 7 | Body Height  (under Template  Options) | 240px |
 
 <br /><br />
 ### Set region-specific properties
 Click the Attributes sub-node under new region and set following properties.
 
 |  | Property | Value         | Help         |
 |-:| :------- | :------------ | :------------ |
 | 8 | Type   | Pie | |
 | 9 | Show  (under Legend)   | Off  (default) | If you are creating a multi-series chart, then you can use legend (9) to identify each series on the chart. Using legend properties you can specify whether to display it, and if so, where it should be placed on the chart. You will use these properties in Chapter 8. |
 
 **Click the New sub-node under Series and set the following properties:**
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 10 | Location (under Source)  | Region Source |
 | 11 | Label   | PRODUCT |
 | 12 | Value   | SALES |
 | 13 | Show  (under Label)   | On (Specifies **whether the label(s) should be rendered on the chart**) |
 
 
 
  
  
  <br /><br /><br /><a name="homereg4"></a>
 ## Home Page region 4 : "Sales by Category" region
 [Top](#top).....[Home reg.1](#homereg1).....[Home reg.2](#homereg2).....[Home reg.3](#homereg3).....[Home reg.4](#homereg4).....[Home reg.5](#homereg5).....[Home reg.6](#homereg6)....[Home buttons](#hbuttons).....[Home styles](#hstyles)
 
 Page region 4 will present sale figures - **bars for each product category : Men, Women, and Accessories**.
 
 This time, we will add a region using the drag and drop APEX  feature. ***Drag Chart icon from Regions gallery and drop it under "Top Orders by Date region***. **Chart region will appear**.  Place  chart region at its proper location, if needed.
 
 
 <br /><br />
 ### Set common region properties (attributes)**
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 1 | Title   | **Sales by Category**|
 | 2 | Type   | Chart |
 |  | Location   | Local Database |
 |  | Type   | SQL Query |
 | 3 | SQL Query   | SELECT p.category Category, sum(o.order_total) Sales FROM demo_orders o, demo_order_items oi, demo_product_info p WHERE o.order_id = oi.order_id AND oi.product_id = p.product_id GROUP BY category ORDER BY 2 desc |
 | 4 | Start New  Row   | On |
 | 5 | Column   | 1 |
 | 5 | Column span  | 4 |
 | 7 | Body Height  (under Template  Options) | 480px |
 
 
 <br /><br />
 ### Set region-specific properties
 Click Attributes sub-node under new region and set following properties.
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 8 | Type   | Bar |
 | 9 | Show  (under Legend)   | Off  (default) |
 
 **Click the New sub-node under Series and set the following properties:**
 
 |  | Property | Value         |   Help         |
 |-:| :------- | :------------ | :------------ |
 | 10 | Location (under Source)  | **Region Source** | |
 | 11 | Label   | CATEGORY | |
 | 12 | Value   | SALES | |
 | 13 | Color  (under Appearance)  | #18A0C2 | or **Color Picker tool** - to change default chart color. |
 
 
 
 
 
 
 <br /><br /><br /><a name="homereg5"></a>
 ## Home Page region 5 : "Top Customers" region
 [Top](#top).....[Home reg.1](#homereg1).....[Home reg.2](#homereg2).....[Home reg.3](#homereg3).....[Home reg.4](#homereg4).....[Home reg.5](#homereg5).....[Home reg.6](#homereg6)....[Home buttons](#hbuttons).....[Home styles](#hstyles)
 
 **Top  six  customers**  with  highest  orders  and  will present info **in text format**. 
 
 Create a new region by **dragging Classic Report icon**   from gallery and dropping it under  "Sales by Category" region. Source of a Classic Report is **SQL query**. Each time page is rendered, APEX evaluates query and displays result within  the  region.  Once  you  specify  row  and  column  properties  using following table, region will appear next to the Sales by Category region.
 
 
 <br /><br />
 ### Set common region properties (attributes)**
  
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 1 | Title   | **Top Customers**|
 | 2 | Type   | Classic Report    (should be already set) |
 |  | Location   | Local Database |
 |  | Type   | SQL Query |
 | 3 | SQL Query   | SELECT b.cust_last_name \|\| ', ' \|\| b.cust_first_name \|\| ' - '\|\| count(a.order_id) \|\|' Order(s)' customer_name, SUM(a.ORDER_TOTAL) order_total,  b.customer_id id FROM   demo_orders a, DEMO_CUSTOMERS b WHERE a.customer_id = b.customer_id GROUP BY b.customer_id, b.cust_last_name \|\| ', ' \|\| b.cust_first_name ORDER BY NVL(SUM(a.ORDER_TOTAL),0) DESC |
 | 4 | Start New  Row   | Off |
 | 5 | Column   | 5 |
 | 5 | Column span  | 4 |
 | 7 | Body Height  (under Template  Options) | 240px |
 
 Rendering tab -> expand Columns node under "Top  Customers" region,  and **click CUSTOMER_NAME column**.  Set following properties to **transform this column into a link to  provide  drill-down**  capability. **APEX  specifies  CUSTOMER_NAME column in Link Text attribute**.
  
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 8 | Type   | Link |
 
 **Click No Link Defined under Target and set the following properties:**
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 9 | Type  | Page in this app | |
 | 10 | Page | 7 | |
 | 11 | Name   | P7_CUSTOMER_ID | This value refers to an item on Page 7 that will be populated with the value held in #ID# . It is forwarded to  Page 7 from the Home page to display **selected customer profile**. |
 | 12 | Value   | #ID# | references third column in above SELECT query. Standard procedure in APEX to **refer to a column value** is to enclose it between # symbols. To **refer page item we use substitution strings**. |
 | 13 | Clear Cache | 7 | |
  
 When we run this page,  each  customer's  name  appears  as  a  hyperlink,  clicking  which  calls customer's  profile  page  (Page  7).  We  set  Page  attribute  to  7,  which  is  the page we want to navigate to. We also forwarded the customer’s ID (#ID#) to Page 7. 
 
 Click  **ORDER_TOTAL**  column  and  set  Format  Mask  to  $5,234.10 = FML999G999G999G999G990D00. 
 
 Select  ID  column  and  set  **Type  property  (under  Identification)  to Hidden Column** to hide this column at run-time.
 
 
 <br /><br />
 ### Set region-specific properties
 Click the Attributes sub-node under new region and set following properties.
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 1 | Pagination Type  | No Pagination (Show All Rows) |
 | 2 | Maximum Row to Process  (under Performance)  | 6 |
 | 3 | Type  (under Heading)  | None |
 
 **Pagination is suppressed** since we want to see only six records in the region. We also set Heading Type to None to **suppress column headings**.
 
 Click Save and Run Page button to test the progress.
 
 
 
 
 
 <br /><br /><br /><a name="homereg6"></a>
 ## Home Page region 6 : "Top Products" region 
 [Top](#top).....[Home reg.1](#homereg1).....[Home reg.2](#homereg2).....[Home reg.3](#homereg3).....[Home reg.4](#homereg4).....[Home reg.5](#homereg5).....[Home reg.6](#homereg6)....[Home buttons](#hbuttons).....[Home styles](#hstyles)
 
 Similar to Top  Customers  region - **create this  region  by  copying  the  Top  Customers  region**. Displays  **six  top selling products**.
 
 **Right-click Top Customers region** -> **Duplicate** from context menu. Copy of source region will be appended just under it.
 
 
 <br /><br />
 ### Set common region properties (attributes)**
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 1 | Title   | **Top Products**|
 | 2 | Type   | Classic Report    (should be already set) |
 |  | Location   | Local Database |
 |  | Type   | SQL Query |
 | 3 | SQL Query   | SELECT p.product_name\|\|' - '\|\|SUM(oi.quantity)\|\|' x' \|\|to_char(p.list_price,'L999G99')\|\|'' product, SUM(oi.quantity * oi.unit_price) sales, p.product_id FROM demo_order_items oi,    demo_product_info p WHERE oi.product_id = p.product_id GROUP BY p.Product_id, p.product_name, p.list_price ORDER BY 2 desc |
 | 4 | Start New  Row   | Off |
 | 5 | Column   | 9 |
 | 5 | Column span  | 4 |
 | 7 | Body Height  (under Template  Options) | 240px |
 
 Expand the Columns node and **click PRODUCT column** to set the following properties:
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 8 | Type   | Link |
 
 **Click No Link Defined under Target and set the following properties:**
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 9 | Type  | Page in this app | |
 | 10 | Page | 6 | |
 | 11 | Name   | P6_PRODUCT_ID | This value refers to an item on Page 7 that will be populated with the value held in #ID# . It is forwarded to  Page 7 from the Home page to display **selected customer profile**. |
 | 12 | Value   | #PRODUCT_ID# | references third column in above SELECT query. Standard procedure in APEX to **refer to a column value** is to enclose it between # symbols. To **refer page item we use substitution strings**. |
 | 13 | Clear Cache | 6 | |
 
 Click **SALES column** and set its Format Mask to $5,234.10. Select **PRODUCT_ID column** and set its Type property to **Hidden Column**.
 
 
 <br /><br />
 ### Set region-specific properties
 Click the Attributes sub-node under new region and set following properties.
 
 |  | Property | Value         |
 |-:| :------- | :------------ |
 | 1 | Pagination Type  | No Pagination (Show All Rows) |
 | 2 | Maximum Row to Process  (under Performance)  | 6 |
 | 3 | Type  (under Heading)  | None |
 
 Click Save and Run Page button to see how all six regions appear on Home page.
 
 
 
 
 
 **END creating all regions.**
 
 <br /><br /><br /> <a name="buttons"></a>
 ## 4.4 Create Buttons on top of each region
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....**Buttons**.....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 These buttons provide **drill-down** functionality and take user to relevant pages to dig further **details for summarized information**.  Eg buttons **add, view...** - click "Add Order" btn in "Top Order by Date" region -> redirect to page 11 to add new order.
 
 ### 4.4.1 Button View Orders 
 To view a list of all customer orders.
 
 **Right-click Top Orders by Date region** -> select Create Button from context menu. This way, **button will be created in selected region**. A **new node "Region Buttons"** will be added with a button.
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Button Name | VIEW_ORDERS |  |
 | 2 | Label | View Orders | appears as tooltip when you move over button at run-tim |
 | 3 | Region | Top Orders by Date | region where button will appear |
 | 4 | Button Position | **Edit** | over dozen values, try other options as well to observe different positions |
 | 5 | Button Template | Icon | button will be displayed as an icon |
 | 6 | Icon | **fa-chevron-right** | name of icon **">"** from the APEX's repository |
 | 7 | Action | Redirect to Page in this App | |
 | 8 | Target | Type = Page in this app    Page = 4 | |
 |  |  |  | |
 
 If we click new button ">" : Sorry, this page isn't available  Application "80858" Page "4" not found.
 
 
 ### 4.4.2 Button Add Order 
 Calls Order Wizard (to be created in Chapter 7) to place a new order.
 
 **Right-click Region Buttons under the Top Orders by Date region** -> select Create Button. A new button will be added under previous one. 
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Button Name | ADD_ORDER |  |
 | 2 | Label | Enter New Order | appears as tooltip when you move over button at run-tim |
 | 3 | Region | Top Orders by Date | region where button will appear |
 | 4 | Button Position | Edit | over dozen values, try other options as well to observe different positions |
 | 5 | Button Template | Icon | button will be displayed as an icon |
 | 6 | Icon | **fa-plus** | name of icon **"+"** from the APEX's repository |
 | 7 | Action | Redirect to Page in this App | |
 | 8 | Target | Type = Page in this app    Page = 11   Clear Cache=11 | |
 |  |  |  | |
 
 
 ### 4.4.3 Button View Orders For This Month 
 Drill-down into current month's order details. 
 
 1. drag "Icon" button from Buttons gallery
 2. drop it under Sales for this Month region in EDIT position
 
 A new button will be added to this region. 
 
 Link  properties  set  here  are  similar  to  those  set earlier in section 4.3.2.Figure 4-7
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Button Name | VIEW_MONTH_ORDERS |  |
 | 2 | Label | View Orders for This Month | appears as tooltip when you move over button at run-tim |
 | 3 | Region | Sales for This Month | region where button will appear |
 | 4 | Button Position | Edit | (already set) over dozen values, try other options as well to observe different positions |
 | 5 | Button Template | Icon | (already set) button will be displayed as an icon |
 | 6 | Icon | **fa-chevron-right** | name of icon **">"** from the APEX's repository |
 | 7 | Action | Redirect to Page in this App |  |
 | 8 | Target | Type = Page in this Application   Page = 4   Name = IRGTE_ORDER_DATE   Value = &P1_THIS_MONTH.  Clear Cache = RIR,4  | |
 |  |  |  | |
 
 
 
 ### 4.4.4 Button View Customers on Page 2 of app.
 You’ll place two buttons in the Top Customers region. **Create these buttons using either of the two methods applied above**.
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Button Name | VIEW_CUSTOMERS |  |
 | 2 | Label | View Customers | appears as tooltip when you move over button at run-tim |
 | 3 | Region | Top Customers | region where button will appear |
 | 4 | Button Position | **Edit** | over dozen values, try other options as well to observe different positions |
 | 5 | Button Template | Icon | button will be displayed as an icon |
 | 6 | Icon | **fa-chevron-right** | name of icon **">"** from the APEX's repository |
 | 7 | Action | Redirect to Page in this App | |
 | 8 | Target | Type = Page in this app    Page = 2 | |
 |  |  |  | |
 
 
 
 ### 4.4.5 Button Add Customer call Page 7 "Customers" blank form
 Target page will appear **on top of the Home page (as a modal dialog)**.
 
 **Right-click  VIEW_CUSTOMERS button** -> select **Create Button**. Set following properties for new button.
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Button Name | ADD_CUSTOMER |  |
 | 2 | Label | Add Customer | appears as tooltip when you move over button at run-tim |
 | 3 | Region | Top Customers | region where button will appear |
 | 4 | Button Position | **Edit** | over dozen values, try other options as well to observe different positions |
 | 5 | Button Template | **Icon** | button will be displayed as an icon |
 | 6 | Icon | **fa-plus** | name of icon **"+"** from the APEX's repository |
 | 7 | Action | Redirect to Page in this App | |
 | 8 | Target | Type = Page in this app    Page = 11   Clear Cache=11 | |
 |  |  |  | |
 
 
 
 ### 4.4.6 Button View Products leads to main products page 3 - list of all products
 Two buttons in the Top Products region (same as in Top Customers region).
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Button Name | VIEW_PRODUCTS |  |
 | 2 | Label | View Products | appears as tooltip when you move over button at run-tim |
 | 3 | Region | Top Products | region where button will appear |
 | 4 | Button Position | **Edit** | over dozen values, try other options as well to observe different positions |
 | 5 | Button Template | **Icon** | button will be displayed as an icon |
 | 6 | Icon | **fa-chevron-right** | name of icon ">" from the APEX's repository |
 | 7 | Action | Redirect to Page in this App | |
 | 8 | Target | Type = Page in this app    Page = 3 | |
 |  |  |  | |
 
 
 
 ### 4.4.7  Add Product Button calls Page 6 to add a new product
 
 |  | Property | Value         |  Help
 |-:| :------- | :------------ | :------------ |
 | 1 | Button Name | ADD_PRODUCT |  |
 | 2 | Label | Add Product | appears as tooltip when you move over button at run-time |
 | 3 | Region | Top Products | region where button will appear |
 | 4 | Button Position | **Edit** | over dozen values, try other options as well to observe different positions |
 | 5 | Button Template | **Icon** | button will be displayed as an icon |
 | 6 | Icon | **fa-plus** | name of icon "+" from the APEX's repository |
 | 7 | Action | Redirect to Page in this App | |
 | 8 | Target | Type = Page in this app    Page = 6   Clear Cache=6 | |
 |  |  |  | |
 
 At this stage, all the seven buttons are placed at their proper locations with  expected  functionalities  and  are  ready  for  partial  test.  
 
 These buttons **will be productive after creating pages indicated in their Target properties**.
  
  
  
  
  
  
  
 <br /><br /><br /> <a name="pgstyles"></a>
 ## 4.5 Styling Page Elements - 6 regions light gray
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....**PgStyles**.....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 
 CSS provides way to control style of a web page  without  changing  its  structure.  When  used  properly,  a  CSS  separates visual properties such as color, margins, and fonts from the structure of the HTML  document.   APEX  includes  themes  containing  templates  to reference their own CSS. The style rules defined in each CSS for a particular theme also determine the way reports and regions display. 
 
 CSS can be added to APEX apps inline, as CSS file(s) or through ThemeRoller.
 
 Depending on your requirements, you can add CSS to your app at the:
 1. Page Level
 2. Page Template Level
 3. Theme Style Level
 4. Theme Level
 5. **User Interface Level** - In  this  exercise  
    Here you’ll upload a custom CSS file carrying just one rule to style all six regions of the home page. The file named **AppCss.css** available in the source code contains **following rule, which creates a rounded border and places inset shadow around   regions**.  For  more  details  on  CSS,  see  Chapter  7 section 7.6.1.
 
 .region {background:white;border-radius:10px 10px 10px 10px;box-shadow: inset 0px 0px 30px #dfdbdf}
 
 To apply CSS at user interface level:
 
 1. **Shared Components page**  ->  Files section -> Static App Files
 2. Click Upload File button
 3. click **Choose Files**, select **AppCss.css** file from the source code and click Upload. The css file will be added to the static app files listing. **Copy Reference  URL entry  #APP_IMAGES#AppCss.css** appearing  on  this  page to your  clipboard. 
 
    **APP_IMAGES substitution string** is used to **reference uploaded  images,  JS,  and  CSS  specific  to given  app**  and  are  not  shared  over  many apps. Recall that you used this substitution string earlier in chapter 3 to reference app logo.
 
 4. Add the CSS file to User Interface : **Shared Components User Interface section** -> **User Interface Attributes**.
 5.  On User Interface tab, click **Cascading Style Sheets sub-tab** and press Ctrl+V to append the reference text in File URLs box **under existing URL** :
     ```
     #APP_IMAGES#app-icon.css?version=#APP_VERSION#
     #APP_IMAGES#AppCss.css
     ```
 6.  Click Apply Changes.
 
 7.  Finally, you have to **apply the CSS rule to your region**. Open home  page  (Page1)  of  your  app  and select first region - **Top Orders by Date**. In the properties pane, scroll  down  to  the  **Appearance  section**  and  enter  **region**  (a  class defined in the AppCss.css file) in **CSS Classes attribute**.
 
    CSS allows you  to  specify  your  own  selectors  called  "id"  and  "class".
    1. **id selector**  is  used  to  specify **style for single, unique element**. It uses id attribute of HTML element, and is defined with **"#" identifier**.
   2. **class selector** is used to specify a **style for a group of elements**. This means you can set a particular style  for  many  HTML  elements  with  the  same  class.  It  uses  HTML class attribute, and is defined with **"." identifier.**
 
  Add the region class  to  the  CSS  Classes  property  of  the  remaining  five regions.
 
 
 Test Your Work
 
 Click the Save and Run Page button to see the Home page, which should now look similar to the one illustrated in Figure 4-1 at the beginning of this chapter.
 
 
 <br /><br /><br />
 ### Summary of chapter 4 "Home page" declarative (functional) development
 We  added  contents  to  a  blank  page, modified properties to customize look and feel of this page. This is uniqueness and beauty of Oracle APEX that allows you to **create pages rapidly without writing tons of code**. Oracle APEX features you learned :
 1. Region  -  We added  **six  regions (stacked canvases)**  to  display different  types  of  contents : different  types  of  charts, badge list, and classic reports to populate these regions via simple SQL statements.
 2. **12 columns grid Layout** - to arrange multiple regions on a page.
 
 3. **URL  &  Links**  -  link **app pages** together by setting some properties. How APEX formulates URL and passes values to target page using some link properties.
 4. Buttons can also be used to link application pages. You created a few buttons to access different application pages.
 
 5. Apply  Styles  -  You  learned  how  to  **add  custom  styles  to  page elements through user interface level**.
 
 In the next chapter, you will learn about **Interactive Grid** and how to create **web forms** to receive user input.
 
 
 
 <br /><br /><br /><br /><br /><br /><a name="cust"></a>
 # 05. Module Customers 2 pages 
 tbl ID=2 CRud & form ID=7 crUD - profile   page 133/419
 
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....**Cust**.....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
  
 ## 5.1 CRUD DEMO_CUSTOMERS tbl
 1. R Browse and search customer records
 2. U Modify customers profiles
 3. C Add record of a new customer to DB
 4. D Remove a customer from the database
 
 Customers info  is used  in other  app segments (**app modules**)  eg customer  orders  and  invoices. You can evaluate how much business you have done with your customers either by **location or by product**, as you did in previous chapter where you created Customers region on **page ID=1 **Sales web app.
 
 ## 5.2 Page Customers tbl  ID=2 - CRud - main page of Cus. module - IG (interactive grid)
 Page ID=1 Sales web app - was created by App Builder wizard at the  time  when  app  was  created.  Other  pages  in  this app  will  be  created  manually  with help of **wizards  and  copy utility**. 
 
 Customers  who  have  some  existing  orders cannot be Deleted - see chapter 2 section 2.10 step 11.
 
 Each  **customers  name  appears  as  link in interactive grid** -> form page profile of selected customer.
 
 Create two module pages via built-in wizard:
 
 1. Main App Builder interface ->  click  "**Sales Web Application's Edit icon**" (A) -> click "**Create Page**"  button  (B). 
    ### Create tbl IG page ID=2, Editing Enabled=Off (for "On" see [Sample Interactive Grids](#sampleIG))
    
    >TIP:  To  **delete page**,  open page in  Page Designer by clicking its name -> select **Delete from top-right Utils menu**.
 
 2.  On   first  wizard  screen,  select  **"Report"**  option ->  **report  of customers in an interactive grid**.
 
 3.  On next wizard screen, **click Interactive Grid**. This screen presents  sub-categories  of  reports  and  requires  a  single  selection the  report  will  base  on.  The  option  you  selected  here  means  an **interactive grid will act as a report** to display all customers from DB.
    
 >Up to version 5.0 APEX used **IR (Interactive Report)** feature to present data tbl. Since version 5.1 - new feature **IG (Interactive Grid)**  similar to IR  + **clicking on a cell**  and  editing  its value (Clipper Dbedit !). IG  introduces  fixed  headers,  frozen  columns,  scroll pagination, multiple filters, **sorting**, aggregates, computations... Supports all **item types and item type plug-ins**. You can **create master-detail relationships to any number of levels deep and across**. See section 5.6.
 
 4.  On  the  next  wizard  screen,  set  following  
    ### Properties of IG page
 
    |  | Property | Value         |  Help
    |-:| :------- | :------------ | :------------ |
    | 1 | Page Number | 2 | Main page of this module (form page to be created next will have number 7) |
    | 2 | Page Name | Customers |  |
    | 3 | Page Mode | Normal | How you want to see page. It has two options: 1. **Normal** Dialog. New pages default  to  Normal.  When  you  call  a  normal  page, it replaces an existing page appearing in your browser. 2. **Modal** Dialog is stand-alone page, which appears on top of its calling page and doesn't allow users to do anything else unless it is closed. A modal page can be displayed only on top of another page. |
    | 4 | Breadcrumb | Breadcrumb | Breadcrumb shared component was created by the App Builder when you  created  this  app  earlier  (see  Shared  Components  -> Navigation  >  Breadcrumbs).  In  this  step,  you  selected  the  same breadcrumb component and added an entry name (Customers) to it. Take a look at Figure 5-1 and see where the provided entry name appears in the breadcrumb region. We use breadcrumbs as a **second level of navigation** at the top of each page - hierarchical list of links indicates where the user is within the app from a hierarchical perspective to **switch  to any level**. |
    | 5 | Parent Entry | Home (Page 1) | To create hierarchy in this app, you selected Home menu entry as Parent Entry for this page. |
    | 6 | Entry Name | Customers |  |
 
 5.  On **Navigation Menu wizard screen**
    ### Set menu item to call this page
    1. set Navigation Preference = Identify an existing navigation menu entry for this page
    2. set Existing  Navigation  Menu  Entry  =  Setup
    3. click  Next.
 
    This step will make **Setup entry active in the main navigation menu** (created in Chapter 3, section 3.2.1) **when this page is accessed**.
 
 6.  On **Report Source screen**, set following properties.  
 
    |  | Property | Value         |  Help
    |-:| :------- | :------------ | :------------ |
    | 1 | Editing Enabled | **Off** |  form pg ID=7 edits cust records. Examples of editing rec. in interactive grid see later in this ch. |
    | 2 | Source Type  | Table | Tbl data to populate  this  interactive  grid |
    | 2 | Table/View Owner  |  | accept displayed value of Oracle **schema** (POSSYS) to  which you are connected.  |
    | 2 | Table/View Name  | DEMO_CUSTOMERS (table)  | Once  you  select  a  schema,  all tables within that schema are populated in  Table/View Name drop-down list from where you select a table - DEMO_CUSTOMERS in the current  scenario  whose  data  will  be  displayed  in  the  interactive  grid. Note that in the current scenario **you can select only one table** from the provided list.  |
 
    If not visible, click the arrow icon next to the Column section to see the table columns. When you choose a table, **all the columns from that table are selected (moved to the right pane in the Columns section)**. For this exercise,  leave  the  following  columns  in  the  right  pane  and  **exclude others  by  moving  them  to  the  left  pane  using  Ctrl+click  and  the  left arrow icon**. Here are the columns we want to show in the interactive grid. Cust_First_Name, Cust_Last_Name, Cust_Street_Address1, Cust_Street_Address2, Cust_City, Cust_State,  and Cust_Postal_Code.
 
 7.  Click **Create button** to finish report page creation process.
 
 Page Customers tbl ID=2 is created and its structure is presented in Page Designer. Only significant aspect of this page is **"Customers"** Interactive Grid region under  :
 
 **Rendering -> Regions -> Content Body node** to your left. Wizard created this region with all columns you specified in step 6 - see **SQL Query box**  in  Page  Designer.  All  these  columns  appear  under  Columns node.
 
 Properties  in  the  **Interactive  grid's  Attributes**  node  control  how  an interactive  grid  works.  For  example,  developers  use  these  properties  to determine  if  end-users  can  edit  the  underlying  data,  configure  report pagination,  create  error  messages,  configure toolbar, use  download options, control if and how users can save an interactive grid, and add Icon and Detail Views to the toolbar. You will go through these properties later in this  chapter.  For  now,  walk  around  the  Page  Designer  to  observe  page components and relevant properties.
 
 Click  Application eg 145615(=appID)  breadcrumb  at  top-left  to  **leave Page Designer interface**.
 
 
 
 ## Create Page ID=7 to carry form "CrUD Customers"
 
 1.  Click **Create Page button** -> select **"Form"**  option -> click another Form option on next wizard screen -> creates form page based on DB  table. 
 
    |  | Property | Value         |  Help
    |-:| :------- | :------------ | :------------ |
    | 1 | Page Number | 7 | **Page to carry form to CrUD Customers** |
    | 2 | Page Name | Customer Details |  |
    | 3 | Page Mode | **Modal** Dialog | stand-alone page, which appears on top of the calling page. Oracle APEX page can be created as dialog, which supports for all the functionality of a normal page, including computations, validations, processes, and branches. |
    | 4 | Breadcrumb |  |
    | 5 | Parent Entry | Customers (Page 2) | called  from  Page  2 |
    | 6 | Entry Name | Customers Details |  |
 
 2.  On  the  Navigation  Menu  screen,  set  "Navigation  Preference"  = **Identify an existing navigation menu entry**  for  this  page,  set "Existing Navigation Menu Entry" = Setup, and click Next.
 
 3.  On the Source screen, set the following properties and click Next.  
 
    |  | Property | Value         |  Help
    |-:| :------- | :------------ | :------------ |
    | 1 | Data Source | Local DB |  |
    | 2 | Source Type  | Table |  |
    | 2 | Table/View Owner  |  | accept displayed value of Oracle **schema** (POSSYS) to  which you are connected.  |
    | 2 | Table/View Name  | DEMO_CUSTOMERS (table)  |   |
 
 4. This time, select all columns from DEMO_CUSTOMERS tbl to display **all of them in the input form (Page 7)** to populate backend DB tbl. For "Primary Key Type", select second option **Select Primary Key Column(s)**. Then, set first "Primary Key Column"  attribute  to  **CUSTOMER_ID**.  **Click "Create" button** to complete form page creation process.
    
    >In this step, you specified PK (primary key) column col or set of cols that uniquely identify record in tbl. Note that in current scenario PK  col for cust tbl will be populated using  DEMO_CUSTOMERS_SEQ  Sequence object through BI_DEMO_CUSTOMERS **trigger**. Trigger fires when  you  insert  a  new  customer.  To  browse  this  trigger,  select SQL  Workshop  ->  Object  Browser  ->  Tables  ->  click  on DEMO_CUSTOMERS  table  and  then  click  the  SQL  tab.  **Sequence** is a database object that automatically generates PK values for  every new cust row. Rows are identified using either PK defined on tbl, or **ROWID pseudo column**, which uniquely identifies row in a tbl. **Forms support up to 2 columns in PK**. For tables  using  primary  keys  with  more  than  two  columns,  ROWID option should be used. For further details, see Chapter 2.
 
 5. Access main App Builder interface by **clicking application ID breadcrumb** to see **two new pages** (Customers and Customer Details) with their respective page numbers. **Click Customer Details (Page  7)**  to  open  its  definitions  in  Page  Designer. 
 
    **Expand Pre-Rendering node** and rename process  **Initialize form Customer Details as "Initialize Customer Details"**. 
 
    Click Processing  tab  and rename process **Process form Customer Details to "Process Customer Data"**. NOTE: If you see a different process name, then there is nothing to worry about as it sometimes happens due to change in APEX version. 
 
 APEX  is  a  low-code  application  development  platform.  Two pages you just created have everything you need to view and manipulate data. Customers Page 2 contains Interactive Grid in which you can view all customers data. 
 
 Click Customer Details Page 7 to open it in  Page  Designer.  On  Rendering  tab,  expand Pre-Rendering  node. Here,  you  will  see  an  auto-generated  process  named  **Initialize  Customer Details of Form Initialization type**. This Process is responsible to initialize form region items. Initialization can either be **fetching data from region source**,  using PK  value(s)  or  **simple  initialization** of form region items. Process fetches and displays data in page items when you select customer by clicking corresponding **edit icon on the reports page** and it initializes page items **when you create a new customer record**. 
 
 Customer Details region is a **Form type region**, which connects to local DB  and  fetches  data  from  DEMO_CUSTOMERS  table  into  relevant page  items  listed  under  Items  node. Same  page  items  are  used  to receive  user  input  when new  customer  record  is  created.  
 
 In Buttons section, you will see a **bunch of auto-generated buttons** (Cancel, Delete, Save, and  Create).  **DB Action**  property  of  these  buttons  specify  function  each  button  performs.  When  you  click  button  (eg CREATE),  corresponding  DB action  is  submitted  to  process named **Process Customer Data**, which resides under the Processing tab. This process  is  of  Automatic  Row  Processing  (DML)  type  and  performs CrUD action on form region - Customer Details region in current scenario.
 
 ## 5.3 Modify Tbl Customers Page ID=2
 Main page of this module (Page 2) holds interactive grid generated  by wizard with some default data source values.
 
 In next steps we  **change  default data source values**  and **produce custom output using SQL query**.
 
 ### 5.3.1 Modify Customers Region Prop.
 Cols hdr, order, filter and cust name as link 
 
 1.  In App Builder, click Customers page (Page 2) to open it in the Page Designer for modification.
    ## Cols hdr, cols order, cols filter in tbl Customers
 2.  **Click  Customers  region under Content  Body node**.  Standard  method  to  modify properties  of page component is to click corresponding node. This action refreshes Properties section (located to your right) with properties of selected page component for alteration. 
 3. Change **Type (under Source section)** = SQL Query to see **default query generated  for interactive  grid**.
    ```
 select ROWID,        CUSTOMER_ID,        CUST_FIRST_NAME,        CUST_LAST_NAME,        CUST_STREET_ADDRESS1,
        CUST_STREET_ADDRESS2,        CUST_CITY,        CUST_STATE,        CUST_POSTAL_CODE,        CUST_EMAIL,
        PHONE_NUMBER1,        PHONE_NUMBER2,        URL,        CREDIT_LIMIT,        TAGS
 from DEMO_CUSTOMERS
    ```
    Enter  following  SQL  statement  in  SQL  Query  text  area,  replacing  existing one:  
    ```
 SELECT customer_id, cust_last_name || ', ' || cust_first_name customer_name
       , CUST_STREET_ADDRESS1||decode(CUST_STREET_ADDRESS2, null, null, ', '||CUST_STREET_ADDRESS2) customer_address
       , cust_city, cust_state, cust_postal_code
 FROM demo_customers
    ```
    Decode Syntax: decode( expression , search , result [, search , result]... [, default] )  
    If default is omitted, Oracle returns null.  
 
 4. Expand Customers region -> expand Columns node. Click column eg CUSTOMER_NAME and **change its heading (under Heading section in Properties pane) to Name**. Change headings of other cols : Address, City, State,  and  Postal Code
 5.  In  Columns  node,  click  the  **CUSTOMER_ID**  column,  and change it Type property from **Number Field to Hidden** to hide col  at runtime. PK cols are added to DB tbls  to  enforce  data  integrity  and  are  not  displayed  in apps.  This  is  why  such  column's  Type  property  is  set  to hidden to make them invisible at runtime.
 
 6.  **Run page**.  **Click Actions menu**  (A) - select Columns. When  you click column in left pane, right pane (D) shows its name and width. You can input a numeric value to **change width of col**. Using arrow icons (E), arrange selected columns in following  **order**:  Name,  Address,  City,  State,  and   Postal Code
 7.  Click Save  button  in  the  Columns  window  to  apply  the changes.
 8.  **After you modify interactive grid in runtime save  it :**  Click Actions menu -> Save from Report option, otherwise you’ll lose the applied settings when you access it later.
 
 9.  **Click Edit  Page2  (F)  in  the  Developer  Toolbar  at  the  bottom  of page** to access  Page Designer.
 
 
    ## Cust name as link in tbl Customers
 10.  Click  CUSTOMER_NAME  column  to  set properties: **transforming cust name col into link that will lead to Page 7 cust. form**.  
    >When you click customer's name in interactive grid report at runtime:
        1.  ID of that cust is stored in substitution string (&CUSTOMER_ID.) (G)
        2.  and is forwarded to corresponding page item (P7_CUSTOMER_ID) (H) on Page 7, which displays cust profile using  this  ID.  
    
    >You  created similar  kind  of link in Chapter 4 for region "Sales for this Month".
 
    Scroll down to Link section and **click "No Link Defined"** under Target to bring up **Link Builder dialog box** -> set link properties :
  
    |  | Property | Value         |  Help
    |-:| :------- | :------------ | :------------ |
    | 1 | Type  | Page in this app | |
    | 2 | Page | 7 | |
    | 3 | Name   | P7_CUSTOMER_ID | This value refers to an item on Page 7 that will be populated with the value held in #ID# . It is forwarded    to  Page 7 from the Home page to display **selected customer profile**. |
    | 4 | Value   | &CUSTOMER_ID. | references third column in above SELECT query. Standard procedure in APEX to **refer to a column value** is to enclose it between # symbols. To **refer page item we use substitution strings**. |
    | 5 | Clear Cache | 7 | |
  
    Use LOVs (I) in Set Items section to select item name (3) and value (4).
 
 11.  **Close  Link  Builder  dialog  box using OK button**.
 12.  **Save and run page**.   **Cust Name col will now appear as link**.  Click  any  customer  name  to  see  details  on Page 7, which pops up on top of Page 2.
 
 ### 5.3.2 Button "Create" in tbl Customers
 To call Page 7 with a blank form from Page 2 - Customers :
 
 1.  Rendering tab to your left click Customers interactive grid region -> set its **Template property to Standard** (was Interactiv). Selected template  **will place title and border for interactive grid region**.
 
   Right-click Customers region and  from context menu select **Create Button**. Button named New will be added. Set properties for new button :
 
    |  | Property | Value         |  Help
    |-:| :------- | :------------ | :------------ |
    | 1 | Button Name | CREATE |  |
    | 2 | Label | Create Customer | appears as tooltip when you move over button at run-time |
    | 3 | Button Position | **Copy** | over dozen values, try other options as well to observe different positions |
    | 4 | Hot | On | renders the button in dark color |
    | 5 | Action | Redirect to Page in this App |  (under Behavior) - **Creates link** to call Page 7. |
    | 6 | Target | Type = Page in this app    Page = 7   Clear Cache =7 | **Creates link** to call Page 7. Clear Cache prop. makes  all items on target pg 7  blank |
 
 2.  **Save and run Page 2**, which should look similar to Figure 5-1.
 3.  Click  Create  Customer  button to call Customer Details Page 7 on top of calling page as a modal dialog.
 
 
 ### 5.3.3 Button "Call PHP page" to Call PHP script - report from APEX
 https://www.youtube.com/watch?v=WLE9_1I_nA0
 
 Like 5.3.2, properties are :
 
    |  | Property | Value         |  Help
    |-:| :------- | :------------ | :------------ |
    | 1 | Button Name | CallPHPpge |  |
    | 2 | Label | **Call PHP page** | appears as tooltip when you move over button at run-time |
    | 3 | Button Position | **Copy** | over dozen values, try other options as well to observe different positions |
    | 4 | Hot | Off | if On : renders the button in dark color |
    | 5 | Action | Redirect to URL |  (under Behavior) - **Creates link** to call PHP Page |
    | 6 | URL  | "http://192.168.../"  or "http://dev1:8083/fwphp/www"   ?param1=&P26_PARAM | **Creates link** to call PHP Page  |
 
 Open in new tab : ?
 
 
 ## 5.4 Modify properties of crUD form Customer Details - Page 7
 With  Page  7  cust. form being  displayed in browser,  **click  Edit  Page  7  in  Developer Toolbar** at pge bottom to call this pge in PageDesigner.
 
 ### 5.4.1 Modify Page Items Properties
 >**Like region placement** in 12 cols grid layout, done for six Home pge  regions, pge  items  can  also  be  placed using APEX's grid layout, as follows.  
 >**Width** property sets items width on page.  
 >If **Value Required** is set to Yes and **page item is visible**,  APEX **automatically performs NOT NULL validation when page is submitted** and  **you are asked to input a value** for field. If you set Value Required to No, no validation is performed and a NULL value is accepted. Value Required  attribute  works  in  conjunction  with  **Template  =  Required**  to  signify (označi) mandatory items visually. 
 
 ### Page Id=7 Customer Details (profile) items properties and values
 Page flds are in 2 columns, only "Tags" fld spans both cols. Save  your  changes  and  call  this  Page 7  by  **clicking  any  customer's  name**  on Page  2.  It  should  come  up  with selected  customer profile (Figure 5-6 Customer Details Page). Click each item under Items node and apply following properties. 
 
 1. P7_CUST_FIRST_NAME Label=**First Name**.....Sequence=20.....Start New Row=On.....Column=Automatic.....Column Span=Automatic  
 .....Template=Required.....**Label Column Span=2  (becomes visible in Layout section only after setting Template property) ** 
 .....Width=50.....Value Required=On
 2. P7_CUST_LAST_NAME Label=**Last Name**.....Sequence=30.....Start New Row=**Off**.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Required.....**Label Column Span=2**
 .....Width=**50**.....Value Required=On
 3. P7_CUST_STREET_ADDRESS1 Label=**Street Address**.....Sequence=40.....Start New Row=On.....Column=Automatic
 .....Column Span=Automatic.....Template=**Optional**.....Label Column Span=2
 .....Width=50.....Value Required=Off
 4. P7_CUST_STREET_ADDRESS2 Label=**Line 2**.....Sequence=50.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=50.....Value Required=Off
 5. P7_CUST_CITY Label=City.....Sequence=60.....Start New Row=On.....Column=Automatic
 .....**Column Span=6**.....Template=Optional.....Label Column Span=2
 .....Width=50.....Value Required=Off
 6. See 5.4.2 Change cust. column "P7_CUST_STATE" to hold predefined LOV! States list
 7. P7_CUST_POSTAL_CODE Label=Zip Code.....Sequence=80.....Start New Row=On.....Column=Automatic
 .....Column Span=6.....Template=Required.....Label Column Span=2
 .....Width=8.....Value Required=On
 8. P7_CREDIT_LIMIT Label=Credit Limit.....Sequence=90.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Required.....Label Column Span=2
 .....Width=8.....Value Required=On
 9. P7_PHONE_NUMBER1 Label=Phone Number.....Sequence=100.....Start New Row=On.....Column=Automatic.....Column Span=Automatic
 .....Template=Optional.....Label Column Span=2.....Width=12.....Value Required=Off
 10. P7_PHONE_NUMBER2 Label=Alternate No.....Sequence=110.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=12.....Value Required=Off
 11. P7_CUST_EMAIL Label=Email.....Sequence=120.....Start New Row=On.....Column=Automatic
 .....Column Span=Automatic.....Template=Required.....Label Column Span=2
 .....Width=50.....Value Required=On
 12. P7_URL Type=Text Field.....Label=URL.....Sequence=130.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=50.....Value Required=Off
 13. P7_TAGS Type=Textarea.....Label=Tags.....Sequence=140.....Start New Row=On.....Column=Automatic
 .....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=100.....Value Required=Off
 
 
 ## 5.4.2 Customer's page column "P7_CUST_STATE"
 to hold app-shared dynamic LOV! States list. app-shared means defined in app shared componebts in one place and reusable in all app modules pages.
 
 ### 1. In Shared Components to fetch State names from DEMO_STATES table
 1. **Shared Components** -> Other Components section -> **"Lists of Values" APEX page** -> Click Create button
 2. Select **From Scratch** option and click Next
 3. Enter **States** in Name box, select **Dynamic for its type**, and click Next
 4. On List of Values Source screen, select **SQL Query for Source Type**, and enter  following query in **Enter SQL SELECT statement** box. Click Next
    ```
    both VARCHAR2    30 :
    select state_name display_value, st return_value from demo_states order by 1
    --select state_name display_value, state_id return_value from demo_states order by 1
    ```
 5. On final Column Mappings screen, select RETURN_VALUE for Return Column, DISPLAY_VALUE for Display Column and **click Create button** to create the LOV.
 
 
 <br /><br />
 ### 2. P7_CUST_STATE prop. 
 Label=**State**.....Sequence=70.....Start New Row=**Off**.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=**Required**.....**Label Column Span=2**
 .....Width=make it **null**  (this item will be transformed into a select list).....Value Required=On
 
 
 <br /><br />
 ### 3. Type Text Field change to -> Select List and Attach STATES LOV! to it (was created in 3.4.3)
 1.  In Page Designer interface, **click P7_CUST_STATE item**.
 2.  Change its Type property from **Text Field to Select List**.
 3.  Set Type (under List of Values) to **Shared Components** and **select STATES for LOV**. This step ***attaches States LOV to page item***.
 4.  **Turn  off  "Display  Extra  Values"  property**.  An  item  may  have  a **session  state  value**,  which  does  not  occur  in  its  LOV definition.  Select  whether  this  LOV  should  display  this extra  session  state  value.  If  you  choose  not  to  display  this  extra session  state  value  and  there  is  no  matching  value  in  list  of values  definition, first  value  will  be   selected  value.  Eg  while  creating new  customer  record  you  will  see - Choose a State - as the first value in the list. This value is added to the list in following steps.
 5.  **Turn  on  Display  Null  Value  property**,  which  is default.  Display Null Value property makes it possible for a user to choose a null value instead of one of the list items. If you set this property to Yes, additional properties appear on the screen for you to specify display value for this new entry. Eg "Choose State".
 6.  **Enter - Choose State - in Null Display Value**. This step, along with the previous one, **generates a placeholder** that appears on top of the LOV asking for a selection whenever you call this page to create a new customer record. 
 7.  Save your work.
 
 
 
 <br /><br />
 ### 5.4.3 Apply Input Mask to Items
 Modify the **two phone number items in cust. form pgID=7** and set their **Value Placeholder property** (under Appearance) to 999-999-9999. When a new customer record is added, this placeholder is shown in the two phone number items to receive input in the specified format. As you type in values, the placeholders will be replaced by the numbers entered.
 
 ### 5.4.4 Create Validation 1 (logic control of  user input) - Check Customer field "P7_CREDIT_LIMIT"
 Field  "Credit  Limit"  is  used  to assign a credit cap to each customer with a figure of $5,000. **If you enter a value  more  than  the  assigned  cap**,  you'll  be  prevented  by  presenting  an appropriate message. NOTE: Validation  error  messages display when :
 1. validation fails the equality test
 2. or evaluates to FALSE
 3. or non-empty text string is returned.
 
 In  left  pane  of  Page  7 cust.form : click  **Processing  icon (was tab)**  ->  **right-click Validating node** -> **Create Validation** from context menu (Figure 5-7) ->  Set following  properties  for  this  new  validation :
 
 |  | Property | Value                         |  Help
 |-:| :------------------------ | :----------------------- | :------------ |
 | 1 | Name                            | **Check Credit Limit** | should be meaningful ! |
 | 2 | Type                              | PL/SQL Expression | expression  in  valid  PL/SQL  syntax  **that evaluates  to  true  or  false** |
 | 3 | PL/SQL Expression | **:P7_CREDIT_LIMIT <= 5000** | If true customer record is saved to DB. Note that **you use bind variables** (item name preceded with a colon) when you reference value of a session state variable from within PL/SQL code. |
 | 4 | Error Message | Customer's Credit Limit must be less than or equal to $5,000   |  |
 
 
 
 ### 5.4.5 Create Validation 2 - "Can't Delete Customer with Orders"
 This check is performed to **retain DB integrity from front-end**. Validation is performed using custom PL/SQL function, which  returns  either  a  true  or  false (deletion  process  is  aborted)  value. Validation  is  **associated  to DELETE button in last attribute in following table**, which means that validation will be performed only **when Delete button is pressed**. 
 
 In  left  pane  of  Page  7 cust.form : click  **Processing  icon (was tab)**  ->  **right-click Validating node** -> **Create Validation** from context menu (Figure 5-7) ->  Set following  properties  for  this  new  validation :
 
 Setting a condition type involves selecting a condition  from  list  that  **must  be  met  in  order  for  a  validation  to  be processed**. 
 
 |  | Property | Value                         |  Help
 |-:| :------------------------ | :----------------------- | :------------ |
 | 1 | Name                            | **Can't Delete Customer with Orders** | should be meaningful ! |
 | 2 | Type                              | PL/SQL Function Body (Returning Boolean) | fn PL/SQL  **that returns true  or  false** |
 | 3 | PL/SQL Fn Body (Ret. Boolean) | SEE BELOW | If true customer record is deleted in DB. Note that **you use bind variables** (item name preceded with a colon) when you reference value of a session state variable from within PL/SQL code. |
 | 4 | Error Message | Can't Delete Customer with Orders  |  |
 | 5 | When Button Pressed | DELETE  | You can control **when and if validation (or process) is performed by configuring When Button Pressed and Condition Type  attributes  of  validation**.  If  you  want  a  validation  to  execute  **only when specified button is clicked**, select a button from the list. |
 
 **| 3 | PL/SQL Fn Body :**  
 ```
 begin
 for c1 in (
    select 'x' from demo_orders
    where customer_id = :P7_CUSTOMER_ID
 ) loop
    RETURN FALSE;
 end loop;
 RETURN TRUE;
 end;
 ```
 
 ### wbp cre_row
 >"Customer Details" - Page 7 - observe **auto-generated buttons (Cancel, Delete, Save, and Create)** with default  functionalities.  Eg  when  you  fill  in form  with  new customer's  record  and  click  Create  button, record  is  **added  to  DB table using a built-in process** - discussed in a while. 
 
 ### In Pre-Rendering (pre_form crUD costomer) we read_by_id
 Expand **Pre-Rendering** node (under root node - Page 7: Customer Details). Here, you will  see **process  of  Form  Initialization  type  created  by wizard** - purpose  of  which  is  to  fetch row from DB by key, and put row values into  pge items Px\_.... Eg when you click customer name in Interactive Grid on Page ID=2, ID of that customer is used by this process to fetch and display details of the selected customer on page ID=7. 
 
 ### Px\_... flds are F[orm] flds
 Wizard also created individual **input items** (under Customer  Details region)  for  each  tbl column.
 1. Source  **Type **  property of  these cols is set to **DB Column**
 2. **DB Column property is set to column  name  in table**.  Eg  two  properties  set  for  P7_CUST_FIRST_NAME  page  item  tells  the  ARF  process  to  set  item with value retrieved from CUST_FIRST_NAME table column.
 
 ### Shared Component confirmation  dialog  box  before  deleting
 Click root  node  (Page  7:  Customer  Details)  and  scroll  down  to Function  and  Global  Variable  Declaration  section  in Property  Editor, you'll  see  a  **global  variable  defined  as  var  htmldb_delete_message**.  This variable  was  generated  automatically  along  with  a  corresponding  **shortcut named  DELETE  CONFIRM  MSG**  (in  **Shared  Components**  >  Other Components > Shortcuts) to control  record deletion process by presenting a  **confirmation  dialog  box  before  deleting**  a  customer’s  record (other app pages will also use it). 
 
 ### crUD process of form items with source of type DB Column
 Note that Delete button was created by wizard with **SQL DELETE DB action**. Similarly, INSERT and UPDATE DB actions were set automatically for Create and Save buttons, respectively - see **DB Action  attribute under  Behavior**.  When  clicked,  these  buttons  perform  selected  SQL  operations  to  trigger specified  DB  action  within  **built-in Automatic Row Processing  (DML) type process**,  also  created automatically  by wizard on Processing  tab.  This  process  is  located under **Processing > Processes node** and it is responsible to CrUD rows  into backend  database  table.  This  process  is  used  to process form items with source of type DB Column. This process has three  advantages :
 1. you  are  not  required  to  provide  any  SQL  coding
 2. APEX performs DML processing for you
 3. this process automatically performs **lost update detection** which ensures data integrity in apps where **data can be accessed concurrently**
 
 In addition, wizard created **Dynamic Action (Cancel Dialog)** to close this form when Cancel button is clicked. These are some of the beauties of declarative development that not only generates **basic functionalities of an app**, but on the same time **doesn't limit our abilities to manually enter specific and tailored code (demonstrated in subsequent chapters), both on the client and server sides** to answer our specific needs.
 
 ### Test Your Work
 Save  and  run  app.  Access  this  module  by  clicking  **"Manage Customers"  menu  item  (under  "Setup")**.  You’ll  see  Page  2  -  Customers (Figure 5-1), carrying an interactive grid. Grid has :
 1. **search bar** (search  string  in report ) comprising : 
 2. magnifying glass - drop  down  list to  limit  your  search  to  a specific column
 3. text area
 4. Go button - Type eg albert in text area and click Go button - shows rows. **Click remove filter icon** to reinstate the grid to its previous state. Alternatively, you can **click Reset button** appearing on top-right of the grid. 
 
 #### Actions menu in runtime
 See Chapter 7. Couple of save options under Actions -> Report in runtime :
 1. First  one **Save** is  used  when  you  customize report  by **applying filters or moving columns**. Otherwise  you'll  lose applied  settings  when  you subsequently  view same  report.
 2. Clicking  second  option **Save  As** presents  a  window  with  **Type  drop-down  list**  and  **Name  text  box**. Developers can save **four types of reports** Primary, Alternative, Private, and Public :
    1. **Primary report** is initial interactive grid report rendered in your browser. Default Primary report (you are looking at) is created by app developer. It **cannot be renamed or deleted**. Primary  report  is displayed on   toolbar under heading Default. 
    2. **Alternative  report**  enables  developers  to  create  **multiple  report  layouts**. **Only  developers**  can  save,  rename,  or  delete  an  Alternative  Report.  An alternative report is based on default primary report and is rendered in a different layout (see Section 7.3.3 in Chapter 7). 
    3. **Private report** can be viewed, saved, renamed, or deleted **by user who created it**. 
    4. In contrast, when you save a report as **public**, **all users can view it**. By default, end-users cannot save Public reports. To enable support for Public  reports, developers  edit  the  report  attribute  and  enables  users  to  save  it  as  public report - see step 7 Section 7.3.1 in Chapter 7. After saving, all these reports display  on  the  Saved  Reports  list  on   toolbar. 
 
 Customer name column appears as a link in Page 2 -click it to modify row (Figure 5-6).Check credit limit validation by entering more than 5000 in Credit Limit box.
 
 NOTE: You might encounter a **primary key violation message while creating first customer record**. This is because the **Sequence object for this table is created with an initial value of 1**. When you try to save the first customer record, 1 is assigned as its primary key, which already exists in the table. To cope with this situation, developers drop and re-create auto-generated sequence objects with a **higher START WITH value**. To keep things simple, I'd suggest beginners to **click the Create button on the form page several times**. After few clicks row will be saved.
 
 ## 5.5 When_window_closed - refresh Viewtbl after crUD Viewfrm is closed
 Add Dynamic Action to refresh interactive grid region (Customers, Page 2) when modal dialog page (Page 7) is closed. When_window_deactivated is when mouse clicks on other window.
 
 After  C customer row  or  U existing  one, **interactive grid doesn't reflect CrUD**, page  doesn't  get  refreshed. Manually refresh  your  browser  window eg F5.  More  professional  approach is to  refresh  page automatically  using  dynamic  action.
 1.  Open Page 2 (Customers) in Page Designer and click **Dynamic Actions icon (was tab)** appearing in left pane.
 2.  Right-click **Dialog Closed**  node  and  select  Create  Dynamic Action from context menu. Figure 5-8. Set following properties for this dynamic action.  
    **Property Value**
    1. Name Refresh Interactive Grid
    2. Selection Type Region
    3. Region Customers
 3.  **Click Refresh sub-node** and set Region to Customers. Refresh is an **action which executes when the condition evaluates to true** - ee, **when modal dialog page is closed**. 
 
 Save page and run it. Now you will see immediate reflection of your modifications in interactive grid.
 
 
 
 
 <br /><a name="gosampleIG"></a>
 ## 5.6 IG : Learn IG - install app "[Sample Interactive Grids](#sampleIG)" from App Gallery
 
 
 
 
 
 <br /><br /><br /><br /> <a name="prod"></a>
 # 06. Page Set Up Products Catalog
 page 177/419
 
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....**Prod**.....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 ## 6.1 About Products Setup
 **Main  Products  Page  3,  CRud product**  -  Figure  6-1  Products Interactive Report Page - will  have **3  different  views:  Icon,  Report,  and  Details**.  Initially,  wizard  will create  the  Report  View  version  that  you'll  modify  with  a  custom  SQL statement. Remaining two views (Detail and Icon) are placed on the page by  enabling  respective  properties  found  under   main  Products  region. Once  you  enable  Detail and Icon  views,  their **icons  appear on main Search  bar**.  Using  these  icons  you  can  switch  among  different  views  to browse  products  information.  
 
 **Product  Details  Page  6, CrUD product** .
 
 To create these two pages follow same approach as you did for Customers.
 
 >New stuff added to this module 
 >   1.  technique to **incorporate style sheet in APEX page**
 >   2.  **image handling and styling**. This module  is  based  on DEMO_PRODUCT_INFO  table. Among  conventional  columns  exists  the  following  **four  special  columns  to handle images** in DB. Normally, specialized processing is required to  handle  images  in DB.  APEX  environment  has **eliminated  need  of  specialized  processing**  with  these additional columns to properly process images in BLOB column. 
 
 ### Image handling and styling columns :
 
 1. PRODUCT_IMAGE: This column uses BLOB data type. **BLOB** (Binary Large Object) is Oracle data type that can hold **up to 4 GB** data. BLOBs we use for storing digitized information eg **images, audio, video, document files : PDF, MS Word, MS Excel, MS PowerPoint, CSV...**.
 
 2. MIMETYPE:  **Multipurpose  Internet  Mail  Extension**  (MIME)  type **identifies file format**. MIME type **enables apps (Internet browsers, e-mail apps...) to read (handle) file**. Eg  e-mail app  can  use MIME  type  to  detect  what  type is file attached to e-mail. MIME types are composed of a top-level media  type  followed  by  a  subtype  identifier,  separated  by  a  forward  slash character (/) eg image/jpeg. The top-level media type  is  a  general  categorization  about  **content of file**,  while subtype identifier specifically identifies **format of file**. 
 
 You can view via Object Browser in SQL Workshop after uploading such file types to BLOB column in your table :
 
 | File Type | MIMETYPE Metadata| 
 | :------------------------- | :------------------- | 
 | JPEG | image/jpeg | 
 | PNG | image/png | 
 | PDF | application/pdf | 
 | WORD | application/vnd.openxmlformats-officedocument.wordprocessingml.document | 
 | EXCEL | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | 
 | POWERPOINT | application/vnd.openxmlformats-officedocument.presentationml.presentation | 
 | CSV | application/vnd.ms-excel | 
 
 3. FILENAME: A case-sensitive column name  used to store **filename of BLOB, such as bag.jpg or CV.pdf**.
 
 4. IMAGE_LAST_UPDATE: A case-sensitive column name used to store the last update date of BLOB.
 
 
 
 
 ## 6.2 Create 2 Pgs for Products - tbl CRud report ID=3 & crUD form ID=6
 Same  approach  as for Customers. 
 
 1. Main App Builder interface -> click "**Sales Web Application's Edit icon**" -> click "**Create Page**" button
    ### Create tbl IG page ID=3, Editing Enabled=Off (for "On" see [Sample Interactive Grids](#sampleIG))
    >TIP: To **delete page**, open page in Page Designer by clicking its name -> select **Delete from top-right Utils menu**.
 
 2. On  first wizard screen, select **"Report"**  means  report of products in an interactive grid
 
 3. On next wizard screen, **click Interactive Grid**. This screen presents sub-categories of reports and requires a single selection the report will base on. The option you selected here means an **interactive grid will act as a report** to display all customers from DB.
   
 4. On the next wizard screen, set following 
    ### Properties of IG tbl page 3
     | | Property | Value     | Help
     |-:| :------- | :------------ | :------------ |
     | 1 | Page Number | 3 | Main page of this module (form page to be created next will have number 6) |
     | 2 | Page Name | **Products** | |
     | 3 | Page Mode | **Normal** | How you want to see page. Or  **Modal** = Dialog is stand-alone page, appears only on top of its calling page and doesn't allow users to do anything else unless it is closed.  |
     | 4 | Breadcrumb | Breadcrumb | = hierarchical list of links. **Breadcrumb shared component was created** by App Builder when you created this app (see Shared Components -> Navigation > Breadcrumbs). In this step, you selected same breadcrumb component and **added an entry name (Customers) to it**.  |
     | 5 | Parent Entry | Home (Page 1) |  |
     | 6 | Entry Name | Products | |
 
 
 5. On **Navigation Menu wizard screen**
   ### Set menu item to call this page
   1. set Navigation Preference = **Identify an existing navigation menu** entry for this page
   2. set Existing Navigation Menu Entry = **Setup** - This step will make **Setup entry active in the main navigation menu** (created in Chapter 3, section 3.2.1) **when this page is accessed**.
   3. click Next.
 
 6. On **Report Source screen**, set following properties. 
 
     | | Property | Value     | Help
     |-:| :------- | :------------ | :------------ |
     | 1 | Editing Enabled | **Off** | form pg ID=6 edits cust records. Examples of editing rec. in interactive grid see later in this text |
     | 2 | Source Type | **Table** | Tbl data to populate this interactive grid |
     | 2 | Table/View Owner | | accept displayed value of Oracle **schema** (**POSSYS**) to which you are connected. |
     | 2 | Table/View Name  drop-down list (from selected schema) | **DEMO_PRODUCT_INFO** (table) |  whose data will be displayed in IG.  **You can select only one table** from provided list. |
 
    **Click arrow icon next to the Column section** to see table columns - **all columns from that table are selected (moved to the right pane in the Columns section)**. Columns we want to show in IG :  ...
 
    Click **Create button** to finish report page creation process.
    
    Click Application eg 145615(=appID) breadcrumb at top-left to **leave Page Designer interface**
 
 
 
 
 ## Create Page ID=6 to carry form "CrUD Products"
 
 1. Click **Create Page button** -> select **"Form"** option -> click another Form option on next wizard screen -> creates form page based on DB table. 
 
   | | Property | Value     | Help
   |-:| :------- | :------------ | :------------ |
   | 1 | Page Number | 6 | **Page to carry form to CrUD Products** |
   | 2 | Page Name | **Product Details** | |
   | 3 | Page Mode | **Modal** Dialog | stand-alone page, appears on top of calling page |
   | 4 | Breadcrumb | Breadcrumb |
   | 5 | Parent Entry | Products (Page 3) | called from Page 3 |
   | 6 | Entry Name | Product Details | |
 
 2. On **Navigation Menu** screen, set "Navigation Preference" = **Identify an existing navigation menu entry** for this page, set "Existing Navigation Menu Entry" = **Setup**, and click Next.
 
 3. On **Source screen**, set following properties and click Next. 
 
   | | Property | Value     | Help
   |-:| :------- | :------------ | :------------ |
   | 1 | Data Source | Local DB | |
   | 2 | Source Type | Table | |
   | 2 | Table/View Owner | | accept displayed value of Oracle **schema** (POSSYS) to which you are connected. |
   | 2 | Table/View Name | **DEMO_PRODUCT_INFO** (table) |  |
 
 4. This time, select all columns from DEMO_PRODUCT_INFO tbl to display **all of them in the input form (Page 6)** to populate backend DB tbl. For "Primary Key Type", select second option **Select Primary Key Column(s)**. Then, set first "Primary Key Column" attribute to **PRODUCT_ID**. **Click "Create" button** to complete form page creation process.
   
   >**Forms support up to 2 cols in PK**. For tbls using PK with more than two columns, ROWID option should be used. For further details, see Chapter 2.
 
 5. Access main App Builder interface by **clicking application ID breadcrumb** to see **two new pages** (Customers and Customer Details) with their respective page numbers. **Click Products Details (Page 6)** to open its definitions in Page Designer. 
 
    **Expand Pre-Rendering node** and rename process **Initialize form Products Details as "Initialize Products Details"**. 
 
    Click Processing tab and rename process **Process form Products Details to "Process Products Data"**. NOTE: If you see a different process name, then there is nothing to worry about as it sometimes happens due to change in APEX version. 
 
    APEX is a low-code app dev. platform. Two pages you just created have** everything you need to view and manipulate data**. Products Page 2 contains IG in which you can view all customers data. 
 
 Click Product Details Page 6 to open it in Page Designer. On Rendering tab, expand Pre-Rendering node. Here, you will see an auto-generated process named **Initialize Products Details of Form Initialization type**. This Process is responsible to initialize form region items. Initialization can either be **fetching data from region source**, using PK value(s) or **simple initialization** of form region items. Process fetches and displays data in page items when you select product by clicking corresponding **edit icon on the reports page** and it initializes page items **when you create a new product record**. 
 
 Product Details region is a **Form type region**, which connects to local DB and fetches data from DEMO_PRODUCT_INFO table into relevant page items listed under Items node. Same page items are used to receive user input when new customer record is created. 
 
 In Buttons section, you will see a **bunch of auto-generated buttons** (Cancel, Delete, Save, and Create). **DB Action** property of these buttons specify function each button performs. When you click button (eg CREATE), corresponding DB action is submitted to process named **Process Customer Data**, which resides under Processing tab. This process is of Automatic Row Processing (DML) type and performs CrUD action on form region - Product Details region in current scenario.
 
 ## 6.3 Modify Main page of module Products Page ID=3 tbl
 Holds interactive grid generated by wizard with some default data source values.
 
 ### 6.3.1 Modify region Products Properties
 1.  click region Products of page 3 -> change Type "Table / View" to SQL Query
 2.  In SQL Query, replace existing SELECT statement with following to select (same in pge 6 crUD form) :  
    ```
    select PRODUCT_ID,  PRODUCT_NAME ,  PRODUCT_DESCRIPTION,  CATEGORY,  PRODUCT_AVAIL
       , LIST_PRICE,  UNITS,         SALES,                CUSTOMERS, LAST_DATE_SOLD
       , IMG,         ICON_LINK,     DETAIL_IMG,  DETAIL_IMG_NO_STYLE
    from (
       select p.product_id, p.product_name, p.product_description, p.category
       , decode(p.product_avail, 'Y','Yes','N','No') product_avail
       , p.list_price
       , (select sum(quantity) from demo_order_items where product_id = p.product_id) units
       , (
           select sum(quantity * p.list_price) 
           from demo_order_items where product_id = p.product_id
       ) sales
       , (
           select count(o.customer_id) from demo_orders o, demo_order_items t 
           where o.order_id = t.order_id and t.product_id = p.product_id group by p.product_id
       ) customers
       , (
           select max(o.order_timestamp) od 
           from demo_orders o, demo_order_items i 
           where o.order_id = i.order_id and i.product_id = p.product_id
       ) last_date_sold
       , p.product_id img
       , apex_util.prepare_url(p_url=>'f?p='||:app_id||':6:'||:app_session||'::::P6_PRODUCT_ID:'||p.product_id) icon_link
       , decode( nvl(dbms_lob.getlength(p.product_image),0)
           ,0,null,
           '<img alt="'||p.product_name||'" title="'||p.product_name
           ||'" style="border: 4px solid #CCC; -moz-border-radius: 4px; -webkit-border-radius: 4px;" '
           ||'src="'||apex_util.get_blob_file_src('P6_PRODUCT_IMAGE',p.product_id)||'" height="75" width="75" />'
       ) detail_img
       , decode( nvl(dbms_lob.getlength(p.product_image),0)
          ,0,null,
          apex_util.get_blob_file_src('P6_PRODUCT_IMAGE',p.product_id)
       ) detail_img_no_style
       from  demo_product_info p
    )
 
    ```
    p.product_id is **img** column in query above
   
    ### "icon_link"  to Product Details Page 6 (read_byprodID)
    is  formed  using  **PREPARE_URL function** which is : 
    1. used **to form links**
    2. is part of **APEX_UTIL package**
    3. **returns f?p=URL**. p_url is VARCHAR2 parameter  passed on to this fn  
       apex_util.prepare_url(**p_url**=>'f?p='||:app_id||':6:'||:app_session||'::::**P6_PRODUCT_ID**:'||p.product_id) **icon_link**  
    
    ### "detail_img"  (and detail_img_no_style)
    **holds products img**.  HTML img tag is used to display images of products in conjunction with **built-in APEX function  APEX_UTIL.GET_BLOB_FILE_SRC** - which enables us to format img display with **height and width** properties. Image is styled using CSS inline styling method. **getlength fn of dbms_lob package (dbms_lob.getlength)** is used to estimate BLOB column size in table to facilitate inclusion of download link in report. **If BLOB column size length is 0, BLOB is NULL and no download link is displayed**.
 
 3.  Products region -> Content Body -> **Expand Columns** node  and set meaningful column headings as follows:  
    Product, Description, Category, Available, Price, Units, Sales, Customers, Last Sold, Image, Icon Link, Image Detail, and Detail Image No Style
 
 4.  Modify following columns. **We  can  use Ctrl+click  or  Shift+click  to  select  multiple cols to change Type properties at once**. 
    
    **Column : Property = Value...Help**
    1. PRODUCT_ID : Type = **Hidden** Column...hidden to make it invisible at runtime
    2. IMG :  Type = **Hidden** Column
    3. ICON_LINK : Type = **Hidden** Column
    4. DETAIL_IMG : **Escape special characters (under Security)** = Off (otherwise image will not appear)...**Each report column IN IR (not in IG)  !!** has property  **Escape  special  characters** by  default set  to  Yes - prevents Cross-Site Scripting (XSS) attacks and selecting **No renders** HTML tags stored in page item or in entries of **list of value**. 
    5. DETAIL_IMG_NO_STYLE : Type = **Hidden** Column
  
 5.  By selecting Product Name column in Link Text  attribute you specify this report column to appear as a link. You created a **similar  kind  of  link to  call Customer Details  page**.  
    ### **Click PRODUCT_NAME column to transform it into a link**
    >1. **In  Interactive  Reports,  you  forward  a  value  to  target  page**  using  special  **substitution  strings  (enclosed  in  # symbols) **
    >2.  as  compared  to  &Item.  notation  (for  example, &CUSTOMER_ID.), which you use in the Interactive Grid - see Chapter 5 Section 5.3.1 Step 10.
 
    **Property Value**
    1. **Click Link -> "Target"**  attribute
    2. In opened dialog : Type = Page In this application,  Page = 6,  Name = P6_PRODUCT_ID,  Value = #PRODUCT_ID#
    3. Link Text = **#PRODUCT_NAME# not &PRODUCT_NAME.**
 
 6.  If you **save and run** report page at this stage, **you will see an EDIT column** (represented with a **pencil icon**), which leads to details page. Since we have already created a link (on the Product Name column), we will eliminate this column so : 
 
    Under **Products region, click its Attributes node, and set  in Properties pane "Link" Column = Exclude Link Column**. Figure 6-3
 
 7.  In same Attributes node, scroll down to **Icon View section** and  set following  properties.
    
    >By  default,  **most  interactive reports display as a report**. You can optionally display **columns as icons**.  When  configured,  an  **icon  (View  Icons)  appears  on  Search  bar**.  To  use  this  view,  you  must  specify  columns  to identify **icon, label, and target (that is link)**. As a best practice Type attribute of these columns is set to **hidden** (as you  did  in  step  4),  because  they  are  typically  **not  useful  for  end users**. Image Attributes property will style height and width of images.
 
    **Property Value**
    1. Show = On
    2. Columns Per Row = 5     (to display 5 images on a single row in View Icons interface)
    3. Link Column = ICON_LINK
    4. Image Source Column = DETAIL_IMG_NO_STYLE
    5. Label Column = PRODUCT_NAME
    6. Image Attributes = width="75" height="75"
 
 8. ** Section "Detail View" under Icon View section** ->  turn  on Show property.  When  configured,  **View  Details  icon  appears  on  Search bar**.
 
 9.  In  **Before Rows attribute**  of Detail View you enter  HTML  code  to  be  displayed before  report  rows. Eg  you  can  use  **TABLE element to put DB content  in row/column format**. Besides adding HTML code, styling information can also be incorporated using  this  attribute. Code below uses custom CSS rules to override default Oracle APEX Interactive Report (**apexir**) styles.
    ```
    <style>
     table.apexir_WORKSHEET_CUSTOM { 
        border: none !important; 
        box-shadow: none; 
        -moz-box-shadow: none; 
        -webkit-box-shadow: none;}
 
     .apexir_WORKSHEET_DATA td {
      border-bottom: none !important;}
 
     table.reportDetail td {
        padding: 2px 4px !important;
        border: none !important;
        font: 11px/16px Arial, sans-serif;}
 
     table.reportDetail td.separator {
        background: #F0F0F0 !important;
        padding: 0 !important;
        height: 1px !important;
        padding: 0;
        line-height: 2px !important;
        overflow: hidden;}
 
     table.reportDetail td h1 {margin: 0 !important}
 
     table.reportDetail td img {
        margin-top: 8px; 
        border: 4px solid #CCC; 
        -moz-border-radius: 4px; 
        -webkit-border-radius: 4px;}
    </style>
    <table class="reportDetail">
    ```
    NOTE: Remember that all **APEX pages are HTML pages** controlled by HTML properties and cascading style sheet (CSS) settings. When you create an interactive report, Oracle APEX renders it based on CSS classes associated with current theme. Each APEX interactive report component has a CSS style definition that may be changed by applying standard CSS techniques to override defaults. CSS changes may be applied to :
    1. single interactive report
    2. page template to effect changes across several interactive reports
    3. all page templates of a theme to enforce a common look and feel for all reports in an  application
 
 In the current step, **you are changing report appearance** by overriding built-in styles for table and subordinate elements.
 
 10.  **In "For Each Row" (post_query)**, enter following code applied to each record. **In every td element** you are **referencing interactive report  columns  and  labels  with substitution string (#)** and are **styling each record using inline CSS method**. 
    
    You used  **substitution  string  to  reference  table  column  names  and labels  of  page  items  as  #PRODUCT_NAME#  and #CATEGORY_LABEL#**.
    ```
     <tr><td rowspan="5" valign="top">
        <img width="75" height="75" src="#DETAIL_IMG_NO_STYLE#"></td>
        <td colspan="6"><h1><a href="#ICON_LINK#"><strong>#PRODUCT_NAME#</strong></a></h1></td>
     </tr>
 
     <tr>
        <td><strong>#CATEGORY_LABEL#:</strong></td><td>#CATEGORY#</td>
        <td><strong>#PRODUCT_AVAIL_LABEL#:</strong></td><td>#PRODUCT_AVAIL#   </td>
        <td><strong>#LAST_DATE_SOLD_LABEL#:</strong></td><td>#LAST_DATE_SOLD#</td>
     </tr>
 
     <tr>
        <td align="left"><strong>#PRODUCT_DESCRIPTION_LABEL#:</strong></td>
        <td colspan="5">#PRODUCT_DESCRIPTION#</td>
     </tr>
 
     <tr>
        <td style="padding-bottom: 0px;"><strong>#LIST_PRICE_LABEL#</strong></td>
        <td style="padding-bottom: 0px;"><strong>#UNITS_LABEL#</strong></td>
        <td style="padding-bottom: 0px;"><strong>#SALES_LABEL#</strong></td>
        <td style="padding-bottom: 0px;"><strong>#CUSTOMERS_LABEL#</strong></td>
     </tr>
 
     <tr>
        <td style="padding-top: 0px;">#LIST_PRICE#</td>
        <td style="padding-top: 0px;">#UNITS#</td>
        <td style="padding-top: 0px;">#SALES#</td>
        <td style="padding-top: 0px;">#CUSTOMERS#</td>
     </tr>
 
     <tr>
        <td colspan="7" class="separator"></td>
     </tr>
    ```
 
 11.  **In After Rows, enter `</table>`** to complete HTML code = HTML to be displayed after report rows. It is closing table tag to end HTML table. 
 
 12.  **Save  and  run page  3 products tbl from Manage Products  option  in Setup menu**
    1. Click View Reports icon (1st left to Actions list)
    2. Note that **Image Detail column is blank at the moment**, because **we do not have any product  image in tbl**.  This is column  which  will  hold images  of  products. 
    
    ### Add (upload) image  of  product
    1. ** Click some link  in Product name column**  to  add  image  of  this  product.  
    2. **On Product  Details page**, **???click "folder icon" representing Product Img field at page bottom**. This will bring up Open dialog box. 
    3. Go to BookCode\Chapter6 folder and select **1_AirMax2090.png** file, and click Open
    4. image name will be displayed in **Product Image  field**.
    5. Click Apply  Changes  button  on Product Details  form  to  save  image.  The  image  will  appear  on  the  interactive  report  page.  Repeat  this  step  to  add  images  of  remaining products. Click **View Icons  (3rd left from "Actions list")** and **View Details (1st left from "Actions list")** options on the interactive report toolbar and see output (Fig. 6-4).
 
 13.  **Filter and order cols : **Click View  Reports  icon.  **Click Actions  menu**  in  interactive  report  and  select  Columns.  Make  sure  **all  columns (except  Description  and  Last  Sold)**  appear  in  Display  in  Report section.  You can use arrow  icons  to arrange  columns  in a desired **order**.  Click Apply  button.  Only columns  you selected will appear in interactive report.
 
 14.  Click Actions  menu  again  and  select  **Save  Report  (under Report)**. From Save drop-down list, select **As Default Report Settings**.  Set  Default  Report  Type  to  **Primary**  and  click  Apply. After modifying an interactive report  you must save it using this procedure,  otherwise  you’ll  lose  the  applied  settings  when  you subsequently  view  this  report.  Developers  can  save  two  types  of default  interactive  report:  **primary**  and  **alternative**.  Both  reports display on Report list on Search bar. **Primary default report (you just saved) cannot be renamed or deleted**.
 
 
 
 
 
 
 In next steps we **change default data source values** and **produce custom output using SQL query**.
 
 ### 6.3.1 Modify Products Region Prop.
 Cols hdr, order, filter and cust name as link 
 
 1. In App Builder, click Customers page (Page 2) to open it in the Page Designer for modification.
   ## Cols hdr, cols order, cols filter in tbl Products
 2. **Click Customers region under Content Body node**. Standard method to modify properties of page component is to click corresponding node. This action refreshes Properties section (located to your right) with properties of selected page component for alteration. 
 3. Change **Type (under Source section)** = SQL Query to see **default query generated for interactive grid**.
   ```
 select ROWID,    CUSTOMER_ID,    CUST_FIRST_NAME,    CUST_LAST_NAME,    CUST_STREET_ADDRESS1,
     CUST_STREET_ADDRESS2,    CUST_CITY,    CUST_STATE,    CUST_POSTAL_CODE,    CUST_EMAIL,
     PHONE_NUMBER1,    PHONE_NUMBER2,    URL,    CREDIT_LIMIT,    TAGS
 from DEMO_CUSTOMERS
   ```
   Enter following SQL statement in SQL Query text area, replacing existing one: 
   ```
 SELECT customer_id, cust_last_name || ', ' || cust_first_name customer_name
    , CUST_STREET_ADDRESS1||decode(CUST_STREET_ADDRESS2, null, null, ', '||CUST_STREET_ADDRESS2) customer_address
    , cust_city, cust_state, cust_postal_code
 FROM demo_customers
   ```
   Decode Syntax: decode( expression , search , result [, search , result]... [, default] ) 
   If default is omitted, Oracle returns null. 
 
 4. Expand Customers region -> expand Columns node. Click column eg CUSTOMER_NAME and **change its heading (under Heading section in Properties pane) to Name**. Change headings of other cols : Address, City, State, and Postal Code
 5. In Columns node, click the **CUSTOMER_ID** column, and change it Type property from **Number Field to Hidden** to hide col at runtime. PK cols are added to DB tbls to enforce data integrity and are not displayed in apps. This is why such column's Type property is set to hidden to make them invisible at runtime.
 
 6. **Run page**. **Click Actions menu** (A) - select Columns. When you click column in left pane, right pane (D) shows its name and width. You can input a numeric value to **change width of col**. Using arrow icons (E), arrange selected columns in following **order**: Name, Address, City, State, and  Postal Code
 7. Click Save button in the Columns window to apply the changes.
 8. **After you modify interactive grid in runtime save it :** Click Actions menu -> Save from Report option, otherwise you’ll lose the applied settings when you access it later.
 
 9. **Click Edit Page2 (F) in the Developer Toolbar at the bottom of page** to access Page Designer.
 
 
   ## Cust name as link in tbl Customers
 10. Click CUSTOMER_NAME column to set properties: **transforming cust name col into link that will lead to Page 7 cust. form**. 
   >When you click customer's name in interactive grid report at runtime:
     1. ID of that cust is stored in substitution string (&CUSTOMER_ID.) (G)
     2. and is forwarded to corresponding page item (P7_CUSTOMER_ID) (H) on Page 7, which displays cust profile using this ID. 
   
   >You created similar kind of link in Chapter 4 for region "Sales for this Month".
 
   Scroll down to Link section and **click "No Link Defined"** under Target to bring up **Link Builder dialog box** -> set link properties :
  
   | | Property | Value     | Help
   |-:| :------- | :------------ | :------------ |
   | 1 | Type | Page in this app | |
   | 2 | Page | 7 | |
   | 3 | Name  | P7_CUSTOMER_ID | This value refers to an item on Page 7 that will be populated with the value held in #ID# . It is forwarded  to Page 7 from the Home page to display **selected customer profile**. |
   | 4 | Value  | &CUSTOMER_ID. | references third column in above SELECT query. Standard procedure in APEX to **refer to a column value** is to enclose it between # symbols. To **refer page item we use substitution strings**. |
   | 5 | Clear Cache | 7 | |
  
   Use LOVs (I) in Set Items section to select item name (3) and value (4).
 
 11. **Close Link Builder dialog box using OK button**.
 12. **Save and run page**.  **Cust Name col will now appear as link**. Click any customer name to see details on Page 7, which pops up on top of Page 2.
 
 ### 5.3.2 Button "Create" in tbl Customers
 To call Page 7 with a blank form from Page 2 - Customers :
 
 1. Rendering tab to your left click Customers interactive grid region -> set its **Template property to Standard** (was Interactiv). Selected template **will place title and border for interactive grid region**.
 
  Right-click Customers region and from context menu select **Create Button**. Button named New will be added. Set properties for new button :
 
   | | Property | Value     | Help
   |-:| :------- | :------------ | :------------ |
   | 1 | Button Name | CREATE | |
   | 2 | Label | Create Customer | appears as tooltip when you move over button at run-time |
   | 3 | Button Position | **Copy** | over dozen values, try other options as well to observe different positions |
   | 4 | Hot | On | renders the button in dark color |
   | 5 | Action | Redirect to Page in this App | (under Behavior) - **Creates link** to call Page 7. |
   | 6 | Target | Type = Page in this app  Page = 7  Clear Cache =7 | **Creates link** to call Page 7. Clear Cache prop. makes all items on target pg 7 blank |
 
 2. **Save and run Page 2**, which should look similar to Figure 5-1.
 3. Click Create Customer button to call Customer Details Page 7 on top of calling page as a modal dialog.
 
 
 ### 5.3.3 Button "Call PHP page" to Call PHP script - report from APEX
 https://www.youtube.com/watch?v=WLE9_1I_nA0
 
 Like 5.3.2, properties are :
 
   | | Property | Value     | Help
   |-:| :------- | :------------ | :------------ |
   | 1 | Button Name | CallPHPpge | |
   | 2 | Label | **Call PHP page** | appears as tooltip when you move over button at run-time |
   | 3 | Button Position | **Copy** | over dozen values, try other options as well to observe different positions |
   | 4 | Hot | Off | if On : renders the button in dark color |
   | 5 | Action | Redirect to URL | (under Behavior) - **Creates link** to call PHP Page |
   | 6 | URL | "http://192.168.../" or "http://dev1:8083/fwphp/www"  ?param1=&P26_PARAM | **Creates link** to call PHP Page |
 
 Open in new tab : ?
 
 
 ## 5.4 Modify properties of crUD form Customer Details - Page 7
 With Page 7 cust. form being displayed in browser, **click Edit Page 7 in Developer Toolbar** at pge bottom to call this pge in PageDesigner.
 
 ### 5.4.1 Modify Page Items Properties
 >**Like region placement** in 12 cols grid layout, done for six Home pge regions, pge items can also be placed using APEX's grid layout, as follows. 
 >**Width** property sets items width on page. 
 >If **Value Required** is set to Yes and **page item is visible**, APEX **automatically performs NOT NULL validation when page is submitted** and **you are asked to input a value** for field. If you set Value Required to No, no validation is performed and a NULL value is accepted. Value Required attribute works in conjunction with **Template = Required** to signify (označi) mandatory items visually. 
 
 ### Page Id=7 Customer Details (profile) items properties and values
 Page flds are in 2 columns, only "Tags" fld spans both cols. Save your changes and call this Page 7 by **clicking any customer's name** on Page 2. It should come up with selected customer profile (Figure 5-6 Customer Details Page). Click each item under Items node and apply following properties. 
 
 1. P7_CUST_FIRST_NAME Label=**First Name**.....Sequence=20.....Start New Row=On.....Column=Automatic.....Column Span=Automatic 
 .....Template=Required.....**Label Column Span=2 (becomes visible in Layout section only after setting Template property) ** 
 .....Width=50.....Value Required=On
 2. P7_CUST_LAST_NAME Label=**Last Name**.....Sequence=30.....Start New Row=**Off**.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Required.....**Label Column Span=2**
 .....Width=**50**.....Value Required=On
 3. P7_CUST_STREET_ADDRESS1 Label=**Street Address**.....Sequence=40.....Start New Row=On.....Column=Automatic
 .....Column Span=Automatic.....Template=**Optional**.....Label Column Span=2
 .....Width=50.....Value Required=Off
 4. P7_CUST_STREET_ADDRESS2 Label=**Line 2**.....Sequence=50.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=50.....Value Required=Off
 5. P7_CUST_CITY Label=City.....Sequence=60.....Start New Row=On.....Column=Automatic
 .....**Column Span=6**.....Template=Optional.....Label Column Span=2
 .....Width=50.....Value Required=Off
 6. See 5.4.2 Change cust. column "P7_CUST_STATE" to hold predefined LOV! States list
 7. P7_CUST_POSTAL_CODE Label=Zip Code.....Sequence=80.....Start New Row=On.....Column=Automatic
 .....Column Span=6.....Template=Required.....Label Column Span=2
 .....Width=8.....Value Required=On
 8. P7_CREDIT_LIMIT Label=Credit Limit.....Sequence=90.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Required.....Label Column Span=2
 .....Width=8.....Value Required=On
 9. P7_PHONE_NUMBER1 Label=Phone Number.....Sequence=100.....Start New Row=On.....Column=Automatic.....Column Span=Automatic
 .....Template=Optional.....Label Column Span=2.....Width=12.....Value Required=Off
 10. P7_PHONE_NUMBER2 Label=Alternate No.....Sequence=110.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=12.....Value Required=Off
 11. P7_CUST_EMAIL Label=Email.....Sequence=120.....Start New Row=On.....Column=Automatic
 .....Column Span=Automatic.....Template=Required.....Label Column Span=2
 .....Width=50.....Value Required=On
 12. P7_URL Type=Text Field.....Label=URL.....Sequence=130.....Start New Row=Off.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=50.....Value Required=Off
 13. P7_TAGS Type=Textarea.....Label=Tags.....Sequence=140.....Start New Row=On.....Column=Automatic
 .....Column Span=Automatic.....Template=Optional.....Label Column Span=2
 .....Width=100.....Value Required=Off
 
 
 ## 5.4.2 Customer's page column "P7_CUST_STATE"
 to hold app-shared dynamic LOV! States list. app-shared means defined in app shared componebts in one place and reusable in all app modules pages.
 
 ### 1. In Shared Components to fetch State names from DEMO_STATES table
 1. **Shared Components** -> Other Components section -> **"Lists of Values" APEX page** -> Click Create button
 2. Select **From Scratch** option and click Next
 3. Enter **States** in Name box, select **Dynamic for its type**, and click Next
 4. On List of Values Source screen, select **SQL Query for Source Type**, and enter following query in **Enter SQL SELECT statement** box. Click Next
   ```
   both VARCHAR2    30 :
   select state_name display_value, st return_value from demo_states order by 1
   --select state_name display_value, state_id return_value from demo_states order by 1
   ```
 5. On final Column Mappings screen, select RETURN_VALUE for Return Column, DISPLAY_VALUE for Display Column and **click Create button** to create the LOV.
 
 
 <br /><br />
 ### 2. P7_CUST_STATE prop. 
 Label=**State**.....Sequence=70.....Start New Row=**Off**.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=**Required**.....**Label Column Span=2**
 .....Width=make it **null** (this item will be transformed into a select list).....Value Required=On
 
 
 <br /><br />
 ### 3. Type Text Field change to -> Select List and Attach STATES LOV! to it (was created in 3.4.3)
 1. In Page Designer interface, **click P7_CUST_STATE item**.
 2. Change its Type property from **Text Field to Select List**.
 3. Set Type (under List of Values) to **Shared Components** and **select STATES for LOV**. This step ***attaches States LOV to page item***.
 4. **Turn off "Display Extra Values" property**. An item may have a **session state value**, which does not occur in its LOV definition. Select whether this LOV should display this extra session state value. If you choose not to display this extra session state value and there is no matching value in list of values definition, first value will be  selected value. Eg while creating new customer record you will see - Choose a State - as the first value in the list. This value is added to the list in following steps.
 5. **Turn on Display Null Value property**, which is default. Display Null Value property makes it possible for a user to choose a null value instead of one of the list items. If you set this property to Yes, additional properties appear on the screen for you to specify display value for this new entry. Eg "Choose State".
 6. **Enter - Choose State - in Null Display Value**. This step, along with the previous one, **generates a placeholder** that appears on top of the LOV asking for a selection whenever you call this page to create a new customer record. 
 7. Save your work.
 
 
 
 <br /><br />
 ### 5.4.3 Apply Input Mask to Items
 Modify the **two phone number items in cust. form pgID=7** and set their **Value Placeholder property** (under Appearance) to 999-999-9999. When a new customer record is added, this placeholder is shown in the two phone number items to receive input in the specified format. As you type in values, the placeholders will be replaced by the numbers entered.
 
 ### 5.4.4 Create Validation 1 (logic control of user input) - Check Customer field "P7_CREDIT_LIMIT"
 Field "Credit Limit" is used to assign a credit cap to each customer with a figure of $5,000. **If you enter a value more than the assigned cap**, you'll be prevented by presenting an appropriate message. NOTE: Validation error messages display when :
 1. validation fails the equality test
 2. or evaluates to FALSE
 3. or non-empty text string is returned.
 
 In left pane of Page 7 cust.form : click **Processing icon (was tab)** -> **right-click Validating node** -> **Create Validation** from context menu (Figure 5-7) -> Set following properties for this new validation :
 
 | | Property | Value             | Help
 |-:| :------------------------ | :----------------------- | :------------ |
 | 1 | Name              | **Check Credit Limit** | should be meaningful ! |
 | 2 | Type               | PL/SQL Expression | expression in valid PL/SQL syntax **that evaluates to true or false** |
 | 3 | PL/SQL Expression | **:P7_CREDIT_LIMIT <= 5000** | If true customer record is saved to DB. Note that **you use bind variables** (item name preceded with a colon) when you reference value of a session state variable from within PL/SQL code. |
 | 4 | Error Message | Customer's Credit Limit must be less than or equal to $5,000  | |
 
 
 
 
 
 
 
 ## IR (Interactive report) (see  2.3.3) to display a list of products **instead of an interactive grid**.
 
 2.  1.  **Click Create  Page button**  in  App  Builder interface -> Sales web App 80858
 2.  **Click Form option, followed by Report with Form**  option. These two selections will create a report page (Figure 6-1) to display all product records from the table (selected in step 5) and a form page (Figure 6-6) to add, modify, and delete products. 
 3.  On the Page Attributes wizard screen, set the following properties and click Next.  The  form page (Page 6) is named Product Details and it will be linked to the report page (Products - Page 3).
    
    **Property Value**
    1. Report Type = **Interactive Report**
    2. Report Page Number  = 3
    3. Report Page Name = **Products**
    
    4. Form Page Number = 6
    5. Form Page Name = **Product Details**
    6. Form Page Mode = Modal Dialog
    7. Breadcrumb = Breadcrumb
    8. >Parent Entry = Home (Page 1)
    9. >Entry Name = Products
 
 4.  On Navigation  Menu  screen,  set  Navigation  Preference  to **"Identify  an  existing  navigation  menu  entry  for  this  page"**,  **set "Existing  Navigation  Menu  Entry"  to  Setup (šifrarnici)**,  and  click  Next.  This step  will  **highlight  Setup  entry**  in main  navigation  menu when you access products setup.
 
 5.  On Data Source screen, select **Table for Source Type**,  accept  default  schema  in  Table/View  Owner,  and  **select "DEMO_PRODUCT_INFO  (table)"  for  Table/View  Name**.  **Columns**  from  the  selected  table  to  be  shown  in  the  interactive report will appear. **Accept all table columns** and click Next.
 
 6.  On  Form  Page  screen,  add  all  columns  (A)  from  the DEMO_PRODUCT_INFO  table  to  Page  6,  **except :  MIMETYPE, FILENAME,  and  IMAGE_LAST_UPDATE  (B)**.  These  three columns are **used in background** to handle images of products.
 
    For  Primary  Key  Type,  choose  Select  **"Primary  Key  Column(s)"** (C).  **Set  "PK  Column  1"  attribute  to  PRODUCT_ID (Number)  (D)**.  PRODUCT_ID is  populated  behind  the  scene using **DB  sequence  object** (DEMO_PRODUCT_INFO_SEQ)  via BI_DEMO_PRODUCT_INFO **trigger** when you add a new product -  see  the  two  objects  by  accessing  **Object  Browser**.
 
 Click  Create button to complete wizard.This time, **wizard creates two pages (3 and 6) as an initial structure for this  module**. 
 
 
 ## 6.3 Modify Products tbl Page 3 
 
 ### 6.3.1 Modify Region Properties
 1.  Click region named Report 1 and set its **Title to Products**
 2.  In SQL Query, replace existing SELECT statement with following to select :  
  Was :
    ```
    select PRODUCT_ID,        PRODUCT_NAME,        PRODUCT_DESCRIPTION,        CATEGORY,        PRODUCT_AVAIL,
          LIST_PRICE,    PRODUCT_IMAGE,        MIMETYPE,        FILENAME,        IMAGE_LAST_UPDATE
    from DEMO_PRODUCT_INFO
    ```
    
    Demo app :
    ```
    PRODUCT_ID    PRODUCT_NAME    PRODUCT_DESCRIPTION    CATEGORY    PRODUCT_AVAIL    
    LIST_PRICE    UNITS    SALES    CUSTOMERS    LAST_DATE_SOLD
    IMG    ICON_LINK    DETAIL_IMG    DETAIL_IMG_NO_STYLE    TAGS
    
    select p.product_id,
        p.product_name, 
        p.product_description, 
        p.category, 
        decode(p.product_avail, 'Y','Yes','N','No') product_avail,
        p.list_price,
        (select sum(quantity) from demo_order_items where product_id = p.product_id) units,
        (select sum(quantity * p.list_price) from demo_order_items where product_id = p.product_id) sales,       
        (select count(o.customer_id) from demo_orders o, demo_order_items t where o.order_id = t.order_id and t.product_id = p.product_id group by p.product_id) customers,
        (select max(o.order_timestamp) od from demo_orders o, demo_order_items i where o.order_id = i.order_id and i.product_id = p.product_id) last_date_sold,
        p.product_id img,
        apex_util.prepare_url(p_url=>'f?p='||:app_id||':6:'||:app_session||'::::P6_PRODUCT_ID,P6_BRANCH:'||p.product_id||','||3,p_dialog=> 'null') icon_link,
        decode(nvl(dbms_lob.getlength(p.product_image),0),0,null,
        '<img alt="'||apex_escape.html_attribute(p.product_name)||'" title="'||apex_escape.html_attribute(p.product_name)
               ||'" style="border: 4px solid #CCC; -moz-border-radius: 4px; -webkit-border-radius: 4px;" '
               ||'src="'||apex_util.get_blob_file_src('P6_PRODUCT_IMAGE',p.product_id)||'" height="75" width="75" />') detail_img,
        decode(nvl(dbms_lob.getlength(p.product_image),0),0,null,
        apex_util.get_blob_file_src('P6_PRODUCT_IMAGE',p.product_id))
        detail_img_no_style,
        tags
 from demo_product_info p
    ```   
    
    ```
    select PRODUCT_ID,  PRODUCT_NAME ,  PRODUCT_DESCRIPTION,  CATEGORY,  PRODUCT_AVAIL
       , LIST_PRICE,  UNITS,         SALES,                CUSTOMERS, LAST_DATE_SOLD
       , IMG,         ICON_LINK,     DETAIL_IMG,  DETAIL_IMG_NO_STYLE
    from (
       select p.product_id, p.product_name, p.product_description, p.category
       , decode(p.product_avail, 'Y','Yes','N','No') product_avail
       , p.list_price
       , (select sum(quantity) from demo_order_items where product_id = p.product_id) units
       , (
           select sum(quantity * p.list_price) 
           from demo_order_items where product_id = p.product_id
       ) sales
       , (
           select count(o.customer_id) from demo_orders o, demo_order_items t 
           where o.order_id = t.order_id and t.product_id = p.product_id group by p.product_id
       ) customers
       , (
           select max(o.order_timestamp) od 
           from demo_orders o, demo_order_items i 
           where o.order_id = i.order_id and i.product_id = p.product_id
       ) last_date_sold
       , p.product_id img
       , apex_util.prepare_url(p_url=>'f?p='||:app_id||':6:'||:app_session||'::::P6_PRODUCT_ID:'||p.product_id) icon_link
       , decode( nvl(dbms_lob.getlength(p.product_image),0)
           ,0,null,
           '<img alt="'||p.product_name||'" title="'||p.product_name
           ||'" style="border: 4px solid #CCC; -moz-border-radius: 4px; -webkit-border-radius: 4px;" '
           ||'src="'||apex_util.get_blob_file_src('P6_PRODUCT_IMAGE',p.product_id)||'" height="75" width="75" />'
       ) detail_img
       , decode( nvl(dbms_lob.getlength(p.product_image),0)
          ,0,null,
          apex_util.get_blob_file_src('P6_PRODUCT_IMAGE',p.product_id)
       ) detail_img_no_style
       from  demo_product_info p
    )
 
    ```
    p.product_id is **img** column in query above
   
    ### "icon_link"  to Product Details Page 6 (read_byprodID)
    is  formed  using  **PREPARE_URL function** which is : 
    1. used **to form links**
    2. is part of **APEX_UTIL package**
    3. **returns f?p=URL**. p_url is VARCHAR2 parameter  passed on to this fn  
       apex_util.prepare_url(**p_url**=>'f?p='||:app_id||':6:'||:app_session||'::::**P6_PRODUCT_ID**:'||p.product_id) **icon_link**  
    
    ### "detail_img"  (and detail_img_no_style)
    **holds products img**.  HTML img tag is used to display images of products in conjunction with **built-in APEX function  APEX_UTIL.GET_BLOB_FILE_SRC** - which enables us to format img display with **height and width** properties. Image is styled using CSS inline styling method. **getlength fn of dbms_lob package (dbms_lob.getlength)** is used to estimate BLOB column size in table to facilitate inclusion of download link in report. **If BLOB column size length is 0, BLOB is NULL and no download link is displayed**.
 
 3.  Expand Columns node (under Content Body | Products region) and set meaningful column headings as follows:  
    Product, Description, Category, Available, Price, Units, Sales, Customers, Last Sold, Image, Icon Link, Image Detail, and Detail Image No Style
 
 4.  Modify following columns using specified properties. 
    
    **We  can  use Ctrl+click  or  Shift+click  to  select  multiple cols to change Type properties at once**. 
    
    **Column : Property = Value...Help**
    1. PRODUCT_ID : Type = **Hidden** Column...hidden to make it invisible at runtime
    2. IMG :  Type = **Hidden** Column
    3. ICON_LINK : Type = **Hidden** Column
    4. DETAIL_IMG : **Escape special characters (under Security)** = Off (otherwise image will not appear)...Each report column has property  **Escape  special  characters** by  default set  to  Yes - prevents Cross-Site Scripting (XSS) attacks and selecting **No renders** HTML tags stored in page item or in entries of **list of value**. 
    5. DETAIL_IMG_NO_STYLE : Type = **Hidden** Column
  
 5.  **Click PRODUCT_NAME column to transform it into a link**. By selecting Product Name column in Link Text  attribute you specify this report column to appear as a link. You created a **similar  kind  of  link  in previous  chapter  to  call Customer Details  page**.  
    1. **In  Interactive  Reports,  you  forward  a  value  to  target  page**  using  special  **substitution  strings  (enclosed  in  # symbols) **
    2.  as  compared  to  &Item.  notation  (for  example, &CUSTOMER_ID.), which you use in the Interactive Grid - see Chapter 5 Section 5.3.1 Step 10.
 
    **Property Value**
    1. Type = Link
    2. Target  (under Link)  : Type = Page In this application,  Page = 6,  Name = P6_PRODUCT_ID,  Value = #PRODUCT_ID#
    3. Link Text = #PRODUCT_NAME#
 
 6.  If you **save and run** report page at this stage, **you will see an EDIT column** (represented with a **pencil icon**), which leads to details page. Since we have already created a link (on the Product Name column), we will eliminate this column so : 
 
    Under **Products region, click its Attributes node, and set  in Properties pane "Link" Column = Exclude Link Column**. Figure 6-3
 
 7.  In same Attributes node, scroll down to **Icon View section** and  set following  properties.
    
    >By  default,  **most  interactive reports display as a report**. You can optionally display **columns as icons**.  When  configured,  an  **icon  (View  Icons)  appears  on  Search  bar**.  To  use  this  view,  you  must  specify  columns  to identify **icon, label, and target (that is link)**. As a best practice Type attribute of these columns is set to **hidden** (as you  did  in  step  4),  because  they  are  typically  **not  useful  for  end users**. Image Attributes property will style height and width of images.
 
    **Property Value**
    1. Show = On
    2. Columns Per Row = 5     (to display 5 images on a single row in View Icons interface)
    3. Link Column = ICON_LINK
    4. Image Source Column = DETAIL_IMG_NO_STYLE
    5. Label Column = PRODUCT_NAME
    6. Image Attributes = width="75" height="75"
 
 8. ** Section "Detail View" under Icon View section** ->  turn  on Show property.  When  configured,  **View  Details  icon  appears  on  Search bar**.
 
 9.  In  **Before Rows attribute**  of Detail View you enter  HTML  code  to  be  displayed before  report  rows. Eg  you  can  use  **TABLE element to put DB content  in row/column format**. Besides adding HTML code, styling information can also be incorporated using  this  attribute. Code below uses custom CSS rules to override default Oracle APEX Interactive Report (**apexir**) styles.
    ```
    <style>
     table.apexir_WORKSHEET_CUSTOM { 
        border: none !important; 
        box-shadow: none; 
        -moz-box-shadow: none; 
        -webkit-box-shadow: none;}
 
     .apexir_WORKSHEET_DATA td {
      border-bottom: none !important;}
 
     table.reportDetail td {
        padding: 2px 4px !important;
        border: none !important;
        font: 11px/16px Arial, sans-serif;}
 
     table.reportDetail td.separator {
        background: #F0F0F0 !important;
        padding: 0 !important;
        height: 1px !important;
        padding: 0;
        line-height: 2px !important;
        overflow: hidden;}
 
     table.reportDetail td h1 {margin: 0 !important}
 
     table.reportDetail td img {
        margin-top: 8px; 
        border: 4px solid #CCC; 
        -moz-border-radius: 4px; 
        -webkit-border-radius: 4px;}
    </style>
    <table class="reportDetail">
    ```
    NOTE: Remember that all **APEX pages are HTML pages** controlled by HTML properties and cascading style sheet (CSS) settings. When you create an interactive report, Oracle APEX renders it based on CSS classes associated with current theme. Each APEX interactive report component has a CSS style definition that may be changed by applying standard CSS techniques to override defaults. CSS changes may be applied to :
    1. single interactive report
    2. page template to effect changes across several interactive reports
    3. all page templates of a theme to enforce a common look and feel for all reports in an  application
 
 In the current step, **you are changing report appearance** by overriding built-in styles for table and subordinate elements.
 
 10.  **In "For Each Row" (post_query)**, enter following code applied to each record. **In every td element** you are **referencing interactive report  columns  and  labels  with substitution string (#)** and are **styling each record using inline CSS method**. 
    
    You used  **substitution  string  to  reference  table  column  names  and labels  of  page  items  as  #PRODUCT_NAME#  and #CATEGORY_LABEL#**.
    ```
     <tr><td rowspan="5" valign="top">
        <img width="75" height="75" src="#DETAIL_IMG_NO_STYLE#"></td>
        <td colspan="6"><h1><a href="#ICON_LINK#"><strong>#PRODUCT_NAME#</strong></a></h1></td>
     </tr>
 
     <tr>
        <td><strong>#CATEGORY_LABEL#:</strong></td><td>#CATEGORY#</td>
        <td><strong>#PRODUCT_AVAIL_LABEL#:</strong></td><td>#PRODUCT_AVAIL#   </td>
        <td><strong>#LAST_DATE_SOLD_LABEL#:</strong></td><td>#LAST_DATE_SOLD#</td>
     </tr>
 
     <tr>
        <td align="left"><strong>#PRODUCT_DESCRIPTION_LABEL#:</strong></td>
        <td colspan="5">#PRODUCT_DESCRIPTION#</td>
     </tr>
 
     <tr>
        <td style="padding-bottom: 0px;"><strong>#LIST_PRICE_LABEL#</strong></td>
        <td style="padding-bottom: 0px;"><strong>#UNITS_LABEL#</strong></td>
        <td style="padding-bottom: 0px;"><strong>#SALES_LABEL#</strong></td>
        <td style="padding-bottom: 0px;"><strong>#CUSTOMERS_LABEL#</strong></td>
     </tr>
 
     <tr>
        <td style="padding-top: 0px;">#LIST_PRICE#</td>
        <td style="padding-top: 0px;">#UNITS#</td>
        <td style="padding-top: 0px;">#SALES#</td>
        <td style="padding-top: 0px;">#CUSTOMERS#</td>
     </tr>
 
     <tr>
        <td colspan="7" class="separator"></td>
     </tr>
    ```
 
 11.  **In After Rows, enter `</table>`** to complete HTML code = HTML to be displayed after report rows. It is closing table tag to end HTML table. 
 
 12.  **Save  and  run page  3 products tbl from Manage Products  option  in Setup menu**
    1. Click View Reports icon (1st left to Actions list)
    2. Note that **Image Detail column is blank at the moment**, because **we do not have any product  image in tbl**.  This is column  which  will  hold images  of  products. 
    
    ### Add (upload) image  of  product
    1. ** Click some link  in Product name column**  to  add  image  of  this  product.  
    2. **On Product  Details page**, **???click "folder icon" representing Product Img field at page bottom**. This will bring up Open dialog box. 
    3. Go to BookCode\Chapter6 folder and select **1_AirMax2090.png** file, and click Open
    4. image name will be displayed in **Product Image  field**.
    5. Click Apply  Changes  button  on Product Details  form  to  save  image.  The  image  will  appear  on  the  interactive  report  page.  Repeat  this  step  to  add  images  of  remaining products. Click **View Icons  (3rd left from "Actions list")** and **View Details (1st left from "Actions list")** options on the interactive report toolbar and see output (Fig. 6-4).
 
 13.  **Filter and order cols : **Click View  Reports  icon.  **Click Actions  menu**  in  interactive  report  and  select  Columns.  Make  sure  **all  columns (except  Description  and  Last  Sold)**  appear  in  Display  in  Report section.  You can use arrow  icons  to arrange  columns  in a desired **order**.  Click Apply  button.  Only columns  you selected will appear in interactive report.
 
 14.  Click Actions  menu  again  and  select  **Save  Report  (under Report)**. From Save drop-down list, select **As Default Report Settings**.  Set  Default  Report  Type  to  **Primary**  and  click  Apply. After modifying an interactive report  you must save it using this procedure,  otherwise  you’ll  lose  the  applied  settings  when  you subsequently  view  this  report.  Developers  can  save  two  types  of default  interactive  report:  **primary**  and  **alternative**.  Both  reports display on Report list on Search bar. **Primary default report (you just saved) cannot be renamed or deleted**.
 
 
 ## 6.4 Modify Product Details (form) Page 6
 ### Adjust dimension of Product Details page
 Page Designer toolbar carries a section called **Page Selector** - **fld** : enter page number and click Go. Navigate to **Next/prev Page (up/down arrow)** -  Figure 6-5. Using Page Selector **call Page 6** in Page Designer. **Click root node**  and set following properties.
 
 **Property Value**
 1. Title = Product Details
 2. Width (under Dialog) = 900
 3. Height = 620
 4. Maximum Width = 1000
 5.  Img rule in inline CSS property (under CSS) to make  products  images  responsive.  ::before  selector  (used in second rule) will insert word 'Nike' before images of products - see Figure 6-6.
    ```
     img {
     width: 100%;
     max-width: 100%;
     height: auto;
     }
     .imgItem::before
     {
     content: 'Nike';
     position: absolute;
     top: 30px;
     left: 20px;color: #000;
     opacity: 0.1;
     font-size: 8em;
     font-weight: 800;
     }
    ```
 
 ### 6.4.1 Making Page Item Mandatory
 P6_PRODUCT_NAME, P6_CATEGORY, P6_PRODUCT_AVAIL,  and  P6_LIST_PRICE 
 1.  Click  on  P6_PRODUCT_NAME  item,  **press  and  hold  the  Ctrl  key** , and then **click the other items to select them all**
 
    **Property Value**
    1. Template  (under Appearance) Required
    2. Value Required  (under Validation) On
 
 2.  Set Template property of P6_PRODUCT_DESCRIPTION and P6_PRODUCT_IMAGE page items to Optional.
 
 
 ### 6.4.2 Attach Categories LOV! to page item P6_CATEGORY
 
 ### 1. In Shared Components 3.4.1 LOV CATEGORIES (U, T) - STATIC to fetch Product categories from list
 1. Shared Components (pyramid of 3) -> Other Components section -> **Lists of Values APEX page**
 2. Click Create button (9 LOVs are created by APEX).
 3. Select From Scratch option and click Next.
 4. LOV Name = **Categories**, select LOV type = **Static**, click Next.
 5. Fill in values as shown in following table. At runtime these entries will display in order they are entered. Return Value does not display, but is the value that is returned to APEX engine as user selection (user event).  
 
    | Sequence | Display val | Rerturn val (user event) | Help                                        |
    | -: | :----------------------- | :---------------------------- | :----------------------------- |
    | 1 | Mens                               | Mens                                     | Men ?|
    | 2 | Womens                        | Womens                              | Women ? |
    | 3 | Accessories                  | Accessories                        | Kids ? |
 
 6. Click Create LOV button
 
 
 <br /><br />
 ### 2. P6_CATEGORY prop. 
 Label=**Category**.....Sequence=70.....Start New Row=**On**.....Column=Automatic
 .....New Column=On.....Column Span=Automatic.....Template=**Required**.....**Label Column Span=2**
 .....Width=make it **null**  (this item will be transformed into a select list).....Value Required=On
 
 
 <br /><br />
 ### 3. Type Text Field change to -> Select List and Attach Categories LOV! to it
 Here we're going to use LOV Categories to which page item P6_CATEGORY will bound, to display  predefined values of categories in Select List  - see Manage Customers module to display STATES LOV.
 1. Page Designer interface -> Items node under Product Details region **click P6_CATEGORY item**.
 2. In Property Editor (right pane) change its Type property  (under Identification)  from **Text Field to Select List**.
 3.  Set Type (under List of Values) to **Shared Components** and **select CATEGORIES for LOV**. This step ***attaches Categories LOV to page item P6_CATEGORY***.
 4.  **Turn  off  "Display  Extra  Values"  property**
 5.  **Turn  off  Display  Null  Value  property**
 6.  Save your work.
 
 
 
 
 ### 6.4.3 Attach LOV to Product Available Column
 Next, you will change the Product Available field to a Switch comprising two options:  On  and  Off.  Just  like  the  previous  steps,  here  as  well,  you’re changing the item type from Text to Switch. At runtime, this item will show two options to specify whether the selected product is available or not. If you ignore  this  exercise  and  leave  the  item  to  its  default  type,  users  can  enter whatever value they like, resulting in compromising application’s integrity. This  is  a  good  example  to  restrict  users  to  select  valid  values.  Select  the P6_PRODUCT_AVAIL item and set the following properties. Note that the last two properties in the table sets Y (which stands for On) as the default value for this item.
 
 **Property Value**
 1. Type  (under Identification) = Switch
 2. Label = Product Available
 3. Type  (under Default) = Static
 4. Static Value = Y
 
 ### 6.4.4 Handling Image (Handle Image Exercise A)
 Modify following  properties  (in  Settings  section)  for  the** P6_PRODUCT_IMAGE  item  to  map  table  columns**.  This  mapping  is necessary to display product images on details form. 
 
 **Property Value**
 1. MIME Type Column = MIMETYPE
 2. Filename Column = FILENAME
 3. BLOB Last Update Column = IMAGE_LAST_UPDATE
 
 In  the  Settings  section,  the  Storage  Type  attribute  is  set  to  BLOB  column specified  in  item  Source  attribute  by  default.  The  Storage  Type  attribute specifies where the uploaded file should be stored at. It has two values: BLOB  column  specified  in  item  source  attribute.  Stores  the uploaded file in the table used by the "Automatic Row Processing (DML)"  process  and  the  column  specified  in  the  item  sourceattribute. The column has to be of data type BLOB. 
 Table  APEX_APPLICATION_TEMP_FILE.  Stores  the  uploaded
 file in a table named APEX_APPLICATION_TEMP_FILE.
 
 ### 6.4.5 Create Region - Product Image  (Handle Image Exercise B)
 To show images of selected products on Product Details page, we will create a Static Content sub-region. Note that this section will only create a blank region to hold an image. The image will be added to this region in a subsequent section. Right-click the Regions node and select Create Region from  the  context  menu.  Select  the  new  region  and  modify  the  following properties. The region will have a blue background and it will be displayed only when there exists an image for a product and this evaluation is made using a condition based on a PL/SQL function. 
 
 **Property Value**
 1. Title = Product Image
 2. Type = Static Content
 3. Sequence = 5  (to place this region before the Product Details region)
 4. Custom Attributes = style="background: #006bdc;"
   5. Type  (under Server-side Condition) = PL/SQL Function Body
 5. PL/SQL Function Body
 ```
 declare
 begin
    if :P6_PRODUCT_ID is not null then
       for c1 in (
          select nvl(dbms_lob.getlength(product_image),0) A
          from demo_product_info
         where product_id = :P6_PRODUCT_ID
       ) loop
           if c1.A > 0 then return true; end if;
        end loop;
    end if;
 return false;
 end;
 ```
 Click the Product Details region and turn off the Start New Row property to place this region beside the Product Image region you just added.
 
 NOTE: Page items are referenced in a PL/SQL block using bind variables inwhich a colon(:) is prefixed to the item name – :P6_PRODUCT_ID, for example.
 
 Code Explained
 
 In Oracle APEX you make use of conditions to control the appearance of page components. The ability to dynamically show or hide a page component is referred to as conditional rendering. You define  conditional  rendering  for  regions,  items,  and  buttons.  These  page  components  have  a Condition section in the property editor, where you select a condition type from a list. In the current scenario, you set a condition based on a PL/SQL function, which returns a single Boolean value:  True or False. If the code returns True, the region is displayed carrying the image of the selected product.
 
 After selecting a condition type, you inform Oracle APEX to execute the defined PL/SQL code. The code first executes an IF condition (line 3) to check whether the product ID is not null by evaluating the value of the page item P6_PRODUCT_ID. If the value is null, the flow of the code is transferred to line 13, where a false value is returned and the function is terminated. If there exists a value for the product ID, then line 4 is executed, which creates a FOR loop to loop through all records in the DEMO_PRODUCT_INFO  table  to  find  the  record  (and  consequently  the  image)  of  the  selected product (line 4-11). On line 8, another IF condition is used to assess whether the image exists. If so, a true value is returned on line 9 and the function is terminated.
 
 
 ### 6.4.6 Create Item (Handle Image Exercise C)
 In this section, you will create a new item named P6_IMAGE to display the product image in the Product Image region. Right-click the Product Image region and select Create Page Item from the context menu. Set the following properties for the new item. The code defined in the PL/SQL Function Body fetches  image  of  the  selected  product  using  a  function (apex_util.get_blob_file_src).  By  setting  the  Rows  Returned  condition  and using a SQL query we ensured the existence of an image in the table. The imgItem  class  defined  for  this  page  item  was  referenced  in  section  6.4  to show some content before product images.
 
 **Property Value**
 1. Name = P6_IMAGE
 2. Type = Display Only
 3. Label = Clear the Label box to make it empty
 4. Region = Product Image
 5. Template = No template  (Set it to  -Select-  placeholder)
 6. CSS Classes = imgItem
 7. Type (under Source)  = PL/SQL Function Body
 8.  PL/SQL Function Body =
    ```
    return '<img src="'||apex_util.get_blob_file_src('P6_PRODUCT_IMAGE',:P6_PRODUCT_ID)||'" />';
    ```
 9. Type (under Server- side Condition) = Rows Returned
 10. SQL Query
    ```
    SELECT  mimetype from demo_product_info
    WHERE product_id = :P6_PRODUCT_ID AND mimetype like 'image%'
    ```
 10 Escape special characters = Off   (Otherwise the image won’t appear)
 
 ### 6.4.7 Create Button to Remove Image (Handle Image Exercise D)
 An image can be removed from the Product Details page and consequently from the underlying table by clicking this button. It is attached to a process (Delete Image) defined in the next section. Right-click the Product  Image region  and  select  Create  Button.  Set  the  following  properties  for  the  new button. The button will appear on top of the region. The Target value calls a confirmation  box.  This  call  is  made  using  an  Oracle  APEX  function (apex.confirm) by passing a message and the name of the Delete button. If you click Yes in the confirmation box, the process associated with the Delete button removes image references from the products table.
 
 **Property Value**
 1. Name DELETE_IMAGE
 2. Label Remove Image
 3. Region Product Image
 4. Button Position Copy
 5. Button Template Icon
 6. Hot On
 7. Icon fa-image
 8. Action (under Behavior)
 9. Redirect to URL
 10. URL (under Target)
 ```
 javascript:apex.confirm('Are you sure you want to delete this image? It will no longer be available for others to see if you continue.','DELETE_IMAGE');
 ```
 
 
 ## 6.5 Create a Process Under Processing to Delete Image (Handle Image Exercise E)
 This is the process I mentioned in the previous section. It is associated with the Delete button to remove a product image. To remove an image stored in a database  table,  you  are  required  to  just  replace  the  content  of  the  relevant columns  with  a  null.  Click  the  Processing  tab  and  then  right-click  the Processing  node.  From  the  context  menu  select  Create  Process.  Set  the following properties for the new process:
 
 **Property Value**
 1. Name Delete Image
 2. Type PL/SQL Code
 3. PL/SQL Code
    ```
    UPDATE demo_product_info
    SET product_image=null, mimetype=null, filename=null, image_last_update=null
    WHERE product_id = :P6_PRODUCT_ID;
    ```
 4. Sequence 15  (to place it before the Close Dialog process)
 5. Success Message Product image deleted
 6. When Button Pressed DELETE_IMAGE
 
 NOTE: The Processing node contains two processes (Process form Product Details and Close Dialog) that were created by the page creation wizard. The first one is created to handle DML operations, while the second one closes Page 6 when you click Create, Save, or Delete button. The values of these buttons  are  mentioned  in  Server-side  Condition  of  the  process,  which specifies that the dialog is to be closed only when any of the three buttons are clicked. Clicking the DELETE_IMAGE button won't close the page, because the name of this button is not in the Value list. Similarly, the Delete Image process will only be executed when the DELETE_IMAGE button is pressed. 
 
 Test Your Work
 
 Save  your  work  and  run  the  application.  From  the  main  navigation  menu, select Manage Products from the Setup menu. On the main interactive report page  (Figure  6-1),  click  the  three  report  icons    individually  to  see different views of products information. Clicking View Icons    will  present small icons of products. Each product is presented as a linked icon. If you click any icon, you'll be taken to the form page (Page 6 - Figure 6-6) where you'll  see  details  of  the  selected  product.  Click  the  Report  View  icon.  TheReport View presents data in a table. Here, you can access the details page by clicking  products’  names.  Click  the  Detail  View  icon.  This  View  presents products information from a different perspective. You can access details of a product by clicking its name. This is the view that was styled in section 6.3.1 steps 8-11. 
 
 Click any product's name to call its details page (as illustrated in Figure 6-6). The form region (Product Details) was created by the wizard incorporating all  relevant  fields.  The  Product  Image  region  was  created  in  section  6.4.5. Also,  note  that  the  Remove  Image  button  (you  created  in  section  6.4.7) appears within this region. Figure 6-6 Product Details Page 
 
 Create a new product record using the Add Product button on the Products report page. Click the Browse button and select any small image file to test  image upload. You can use an existing product image by right-clicking the image  and  selecting  Save  Image  As  from  the  context  menu.  Or,  use  the Download  link  provided  on  the  Product  Details  form  page  to  get  one  for testing.Once you have an image in place, fill in all the fields except List Price. Try to save this record by clicking the Create button. A message “Please fill out this field”  will  appear  informing  you  to  provide  some  value  for  the  List  Price. Now, provide some alpha-numeric value like abc123 in the List Price. Again, a message will come up reminding you to put a numeric value. Finally,  input  a  numeric  value  in  the  List  Price  field  and  save  the  record. You'll see the new product appears on the Products page among others with the  image  you  uploaded.  Edit  this  record  and  see  the  image.  Change  the category  of  this  product,  switch  availability  to  the  other  option  and  apply changes. Call the product again and observe the changes you just made to it. Click  the  Remove  Image  button  and  see  what  happens.  Click  the  Delete button followed by OK in the confirmation box. The product will vanish from the list. 
 
 NOTE: You might encounter a primary key violation message (ORA-00001: unique  constraint  (DEMO_PRODUCT_INFO_PK)  violated)  while  creating first  product  record.  This  is  because  the  Sequence  object  for  this  table  is created  with  an  initial  value  of  1.  When  you  try  to  save  the  first  product record, 1 is assigned as the first primary key value, which already exists in the table. To cope with this situation, just click the Create button on the form page several times. After ten clicks the record will be save. 
 
 
 ## 6.6 Uploading and Viewing PDF and Other Types of Files
 As  mentioned  earlier  in  this  chapter,  you  can  store  different  types  of  files (upto  4  GB),  such  as  images,  audio,  video,  PDF,  CSV,  XLSX,  DOC  and more, in the BLOB column of your table. In this exercise, I’ll demonstrate how to save and view a PDF. As far as the uploading is concerned, you are not  required  to  perform  any  special  steps  to  handle  PDF  or  any  other  file type.  You  have  already  set  the  stage  in  the  previous  sections  where  you handled JPEG images. Here, you will just create two new pages that will be apart from your application.
 1.  Click the Create Page button in the App Builder interface.
 2.  Click the Report option.
 3.  Select Interactive Report.4.  On Page Attributes wizard screen, enter 303 for Page Number and Products Catalog for Page Name. Click Next.
 5.  On the Navigation Menu screen, set Navigation Preference to Do not associate this page with a navigation menu entry and click Next.
 6.  On Report Source screen, select SQL Query for Source Type and enter  the  following  statement  in  the  Enter  a  SQL  SELECT statement area.
    ```
    select p.product_id, p.product_name,
    dbms_lob.getlength(p.product_image) document
    from  demo_product_info p
    ```
 7.  Click the Create button to complete the page creation process.
 
 ### 6.6.1 Modify BLOB Column
 Execute the following steps to modify the BLOB column attributes.
 
 In the Page Designer, expand the Columns node (under the Products Catalog interactive report region), click the Document column and set the following attributes for this column. In the Download Text property you set a string used for the download link. If nothing is provided, Download is used. The Content Disposition specifies how the browser handles the content when downloading. If a MIME type is provided and the file is a type that can be displayed, the file is displayed. If MIME type is not provided, or the file cannot be displayed inline, the user is prompted to download.
 
 **Property Value**
 1. Type = Download BLOB
 2. Table Name (under BLOB Attributes) = DEMO_PRODUCT_INFO
 3. BLOB Column = PRODUCT_IMAGE
 4. Primary Key Column 1 = PRODUCT_ID
 5. Mime Type Column = MIMETYPE
 6. Filename Column = FILENAME
 7. Last Updated Column = IMAGE_LAST_UPDATE
 8. Download Text  (under Appearance) = View
 9. Content Disposition = Inline
 
 ### 6.6.2 Upload and View PDF
 As just mentioned the product setup module created earlier in this chapter is ready to upload any type of file, so to save some precious time we are going to use that module to upload a PDF.
 1.  Run the application and select Setup | Manage Products.
 2.  Click the Create button on the main Products interactive report page.
 3.  Fill in the mandatory fields. Click the Choose File button, select product_catalog.pdf file, which is available in the source code, and click Create. The pdf will be uploaded to the DEMO_PRODUCT_INFO table. Take some time to verify the upload from SQL Workshop | Object Browser.
 4.  Switch back to Page Designer. With Page 303 appearing on your screen click the Save and Run page button. The Product Catalog page will appear displaying data from the corresponding table. Click the View link for the Product Catalog PDF document. The PDF will be opened in your browser.Figure 6-7
 
 
 Play  around  with  this  module  by  tweaking  the  saved  properties  to  see resulting effects on two pages. You can always **restore properties** to their original values by referencing exercises provided in the chapter.
 
 
 
 
 
 <br /><br /><br /><br /><br /><br /> <a name="order"></a>
 # 07. Taking Orders
 page 201/419
 
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....**Order**.....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
  
 ## 7.1 About Sale Orders
 This chapter will teach you how to create professional looking order forms.
 Orders from customers will be taken through a sequence of wizard steps. The
 first wizard step will allow you to select an existing customer or create a new
 one. In the second step, you will select ordered products. After placing the
 order, the last step will show summary of the placed order. Once an order is
 created, you can view, modify, or delete it through Order Details page using a
 link in orders main page. The list presented below displays the application
 pages you will create in this chapter:
 Page
 No.
 Page Name Purpose
 4 Orders The main page to display all existing orders
 29 Order Details Display a complete order with details for modification
 11
 Identify Customer (Wizard
 Step 1)
 Select an existing customer or create a new one
 12
 Select Order Items  (Wizard
 Step 2)
 Add products to an order
 14
 Order Summary (Wizard Step
 3)
 Show summary of the placed order
 You’ll build this module sequentially in the sequence specified above. The
 first two pages (Page 4 and 29) will be created initially using a new wizard
 option: Master Detail. Both these pages are not part of the Order Wizard and
 will be utilized for order modification and deletion after recording an order.
 Page 4 is similar to the pages you created in Customer and Product modules
 and lists all placed orders, while Page 29 will be used to manipulate order
 details.  For  example,  you  can  call  an  order  in  the  usual  way  using  the
 provided link in the master page. The called order will appear in the details
 page where you can:
 Add/Remove products to and from an order
 Delete the order itself
 The purpose of each chapter in this book is to teach you some new features.
 Here as well, you’ll get some new stuff. This chapter will walk you through
 to  get  detailed  practical  exposure  to  the  techniques  this  module  contains.
 After completing the two main pages, you will work on actual order wizardsteps to create other pages of the module. Recall that in the previous chapter
 you modified the main interactive report (Page 3) to create a couple of views
 (Icon and Detail) and used the Actions menu to select and sort table columns.
 In this chapter, many other utilities provided under the Actions menu will be
 exposed.  But  first,  let’s  create  the  two  main  pages  using  the  conventional
 route.
 
 ## 7.2 Create Order Master and Order Detail Pages
 1.  Click the Create Page button in the App Builder.
 2.  On  the  first  wizard  screen,  click  the  Master  Detail  option.  A
 master detail page reflects a one-to-many relationship between two
 tables  in  a  database.  Typically,  a  master  detail  page  displays  a
 master row and multiple detail rows within a single HTML form.
 With this form, users can insert, update, and delete values from two
 tables  or  views.  On  the  Master  Detail  page,  the  master  record
 displays  as  a  standard  form  and  the  detail  records  appear  in  an
 interactive grid region under the master section.
 3.  On  the  next  wizard  screen,  select  the  Drill  Down  option,  which
 opens input form in a separate page.
 4.  Fill in the next screen (Page Attributes) as illustrated below, and
 click Next.Figure 7-1
 5.  On  the  Navigation  Menu  screen,  set  Navigation  Preference  to
 Identify  an  existing  navigation  menu  entry  for  this  page,  set
 Existing Navigation Menu Entry to Orders, and click Next.
 6.  Select  the  values  in  the  Master  Source  screen  (as  shown  in  the
 following figure), and click Next. In this step, you select the parent
 table, which contains the master information for each order. You
 also  specify  the  primary  key  column,  which  will  be  populated
 automatically  behind  the  scene  using  a  trigger  named
 BI_DEMO_ORDERS  via  a  sequence  named
 DEMO_ORDERS_SEQ. You can view both these database objects
 from SQL Workshop > Object Browser interface. The ORDER_ID
 column  selected  in  the  Form  Navigation  Order  list  is  the
 navigation order column used by the previous and next buttons on
 the Order Details page to navigate to a different master record.Figure 7-2
 7.  Set properties on the Detail Source screen as illustrated below and
 click Create to finish the wizard. On this screen, you specify the
 relational child table, which carries line item information for each
 order.  The  primary  key  column  of  this  table  will  be  populated
 automatically  via  a  trigger  named  BI_DEMO_ORDER_ITEMS,
 which  gets  the  next  primary  key  values  from  a  sequence  named
 DEMO_ORDER_ITEMS_SEQ. In the Master  Detail  Foreign  Key
 list you select the sole auto-generated foreign key, which creates a
 relationship between the master and detail tables.Figure 7-3
 Before running these pages, let’s see what the wizard has done for us. The
 master page (Page 4) is created with an Interactive Report to display a list of
 all  order  from  the  Orders  Mater  table.  The  details  page  (Page  29),  on  the
 other  hand,  has  many  things  to  reveal.  The  following  table  lists  all  those
 components  created  automatically  by  the  wizard  with  complete
 functionalities to manage this module.
 Component: Pre-Rendering Process
 Name: Initialize form Form on DEMO_ORDERS
 Description:  Fetches  master  row  from  DEMO_ORDERS  table.  This
 process  was  briefed  in  Chapter  5  Section  5.4.5.  If  you  see  a  different
 process  name,  then  there  is  nothing  to  worry  about  as  it  sometimes
 happens due to change in APEX version.
 Component: Region
 Name: Form on DEMO_ORDERSDescription: The page has two regions. The Form on DEMO_ORDERS
 region, which is a Static Content region, displays master information like
 customer  ID,  order  date,  and  so  on.  The  lower  region  shows  product
 details along with quantity and price in an Interactive Grid.
 Component: Buttons
 Names: GET_PREVIOUS_ORDER_ID and GET_NEXT_ORDER_ID
 Description:  These  buttons  are  added  to  the  master  region  to  fetch
 previous and next orders, respectively. For example, when you click the
 Next button  , the page is submitted to get the next order record from
 the  server  by  triggering  the  Initialize  form  Form  on  DEMO_ORDERS
 process using the value set for Next Primary Key Item(s) property in this
 process. The Next Primary Key Item(s) and Previous Primary Key Item(s)
 properties in this process are associated with respective hidden page items
 to fetch next and previous order ids. Based on the currently fetched order
 number,  which  is  held  in  the  page  item  P29_ORDER_ID,  the  process 
 dynamically obtains the next and previous order numbers and stores them
 in  two  hidden  page  items:  P29_ORDER_ID_NEXT  and
 P29_ORDER_ID_PREV. The visibility of the Next and Previous buttons
 is controlled by a Server-side Condition (Item is NOT NULL), which says
 that these buttons will be  visible only when their corresponding hidden
 items  have  some  values.  If  you  make  any  modification  to  an  order  on
 Page 29 and navigate to another order record using any of these buttons,
 the  changes  are  saved  to  the  two  database  tables.  This  is  because  the
 Action property of the two buttons is set to Submit Page. When the page is
 submitted, two processes (Process form Form on DEMO_ORDERS  and
 Order Details - Save Interactive Grid Data defined later in this section)
 are executed to make the changes permanent.
 Component: Button
 Name: Cancel
 Description:  The  Cancel  button  closes  Page  29  and  takes  you  back  to
 Page 4 without saving an order. For this, a redirect action is generated in
 the Behavior section with Page 4 set as the target.
 Component: ButtonName: Delete
 Description:  The  Delete  button  removes  a  complete  order.  When  this
 button is clicked, a confirmation dialog pops up using its Target property,
 which  is  set  to:
 javascript:apex.confirm(htmldb_delete_message,'DELETE');
 When  you  confirm  the  deletion,  a  SQL  DELETE  action  (specified  in
 Database Action property for this button) is executed within the built-in
 Automatic  Row  Processing  (DML)  processes–Process  form  Form  on
 DEMO_ORDERS and Order Details - Save Interactive Grid Data.
 Component: Button
 Name: Save
 Description: The Save button records updates to an existing order in the
 corresponding  database  table.  This  button  is  visible  when  you  call  an
 order for modification, in other words, P29_ORDER_ID is NOT NULL.
 The process behind this button is controlled by a SQL  UPDATE  action
 within the two built-in Automatic Row Processing (DML) processes.
 Component: Button
 Name: Create
 Description:  The  Create  button  is  used  for  new  orders  to  handle  the
 INSERT  operation.  This  button  is  visible  when  you  are  creating  a  new
 order – that is, the page item P29_ORDER_ID is NULL. It uses the SQL
 INSERT action within the two built-in Automatic Row Processing (DML)
 processes.
 Component: Region
 Name: Order Details
 Description:  This  is  an  Interactive  Grid  region,  which  is  generated  to
 view, add, modify, and delete line items using the parameters set in step 7.
 The  information  you  provided  in  this  interactive  grid  is  saved  to  the
 DEMO_ORDER_ITEMS table through a process named Order Details -
 Save Interactive Grid Data – discussed next.
 Component: Process
 Name: Process form Form on DEMO_ORDERSDescription:  This  Automatic  Row  Processing  (DML)  type  process  is
 generated  by  the  wizard  to  handle  DML  operations  performed  on  the
 master  row  of  an  order,  which  gets  into  the  DEMO_ORDERS  table.  It
 comes  into  action  when  you  click  Delete,  Save,  or  Create  buttons.  The
 three  buttons  and  their  associated  actions  are  depicted  in  the  following
 figure.
 Component: Process
 Name: Order Details – Save Interactive Grid Data
 Description: The Save Interactive Grid Data process  is responsible  to
 handle DML operations on the details table (DEMO_ORDER_ITEMS).
 This  process  is  associated  with  the  details  section  (Interactive  Grid)  to
 insert, update, or delete Interactive Grid rows.
 Component: Branches
 Name: Go To Page 29, Go To Page 29, and Go To Page 4
 When  you  submit  a  page,  the  Oracle  APEX  server  receives  a  submit
 request  and  performs  the  processes  and  validations  associated  with  that
 request. After this, it evaluates where to land in the application via these
 branches. By default, it selects the current page as the target page. For
 example, when you click the Next or Previous buttons on Page 29, you
 stay on the same page. If you want to land users to some other page, youcan do this as well by creating branches. In the current scenario, you are
 moved back to Page 4 when you click any other button on Page 29. A
 branch has two important properties: Behavior and Server-side Condition.
 In the Behavior section you specify the page (or URL) to redirect to, and
 in Condition you specify when the branch is to be fired. Here, the first
 two  branches  are  created  to  keep  you  on  Page  29.  These  branches  are
 associated  with  Next  and  Previous  buttons–see  When  Button  Pressed
 properties of these branches. The third one takes you back to Page 4 when
 you click any other button on this page – see the Behavior section that
 specifies the redirect.
 Run  this  module  from  the  Orders  navigation  menu  entry.  The  first  page
 (Page 4) you see is an interactive report. It is similar to the one you created in
 Chapter 6. It has a Create button, which is used to create a new order. Click
 the edit link (represented with a pencil icon) in front of any record to call the
 Order Details page (Page 29).
 The Order Details page has two regions. The upper region, which is called
 the  master  region,  displays  information  from  the  DEMO_ORDERS  table,
 while the lower interactive grid region shows relevant line item information
 from  the  DEMO_ORDER_ITEMS  table.  Besides  usual  buttons,  the  master
 region has two navigational buttons at the top. These buttons help you move
 forward  and  backward  to  browse  orders.  The  Order  Timestamp  field  is
 supplemented with a Date Picker control. You can add more products to the
 details section by clicking the Add Row button.
 From a professional viewpoint this page is not user friendly. If you try to add
 a new product, you have to enter its ID manually. Moreover, if you try to
 create a new order, you won’t see the interactive grid. By default, this grid is
 visible only when you modify an existing order and it hides when you try to
 create  a  new  order.  This  behavior  is  controlled  by  a  server  side  condition
 (Item is NOT NULL) set for the Interactive Grid region (Order Details). With
 this  condition  set,  the  region  is  rendered  only  when  the  page  item
 P29_ORDER_ID has some value. Choosing the – Select – placeholder for the
 Server-side Condition Type property removes this condition and makes the
 interactive  grid  visible  every  time  you  access  Page  29.  Even  after  this
 adjustment, you will face some constraint issues related to a backend table.
 To avoid all such problems, execute the instructions provided in subsequentsections to make the module user-friendly.
 
 ## 7.3 Modify Orders Page - Page 4
 Execute the instructions provided in the following sub-sections to modify the
 Orders page.
 7.3.1 Modify the Orders Interactive Report Region on Page 4
 The  Orders  interactive  report  region  on  Page  4  fetches  orders  information
 from  the  DEMO_ORDERS  table.  Let’s  replace  the  existing  auto-generated
 data  fetching  mechanism  with  a  custom  SQL  query,  which  incorporates
 customers information from the DEMO_CUSTOMERS table.
 1.  Open Page 4 in the Page Designer, and click the Orders  region.
 Modify the region using the values set in the following table:
 Property Value
 Location Local Database
 Type SQL Query
 SQL Query
 select lpad(to_char(o.order_id),4,'0000') order_number, o.order_id,
 to_char(o.order_timestamp,'Month YYYY') order_month,
 trunc(o.order_timestamp) order_date,
 o.user_name sales_rep, o.order_total,
 c.cust_last_name||', '||c.cust_first_name customer_name,
 (select count(\*) from demo_order_items oi where oi.order_id = o.order_id and oi.quantity != 0) order_i
 o.tags tags
 from demo_orders o, demo_customers c
 where o.customer_id = c.customer_id
 2.  Expand the Columns node under the Orders region and set the Type
 property for the ORDER_ID column to Hidden Column.
 3.  Set  meaningful  headings  for  all  interactive  report  columns  as
 follows.
 Order  #,  Order  Month,  Order  Date,  Customer,  Sales  Rep,  Order
 Items, Order Total, and Tags
 4.  Edit the ORDER_TOTAL column and select the value $5,234.10
 for its Format Mask property.5.  Select the Order Number column (not Order ID) and turn it into a
 link using the following properties:
 Property Value
 Type Link
 Target  (in Link section)
 Type = Page in this application
 Page = 29
 Name = P29_ORDER_ID
 Value = #ORDER_ID#
 Clear Cache = 29
 Link Text #ORDER_NUMBER#
 6.  Click  the  Attributes  node  under  the  Orders  interactive  report
 region. Select Exclude Link Column for Link Column property in
 the  Property  Editor.  This  action  will  exclude  the  default  link
 column (denoted with a pencil icon) from the report as we have a
 custom link created in the previous step.
 7.  In  the  Attribute  node,  scroll  down  to  the  Actions  Menu  section,
 and turn on the Save Public Report option, to include this option in
 the  Actions  menu  at  runtime.    By  enabling  this  option  you  can
 create a public report – see section 7.3.4.
 8.  Click  the  Create  button  and  set  the  following  properties  for  this
 button. New customer orders in this module will be recorded via
 some  wizards  steps,  and  Page  11  (to  be  created  in  a  subsequent
 section) will be the first order wizard step. 
 Property Value
 Label Enter New Order
 Target  (in Behavior section)
 Type = Page in this application
 Page = 11
 Clear Cache = 11
 9.  Save your modifications.
 7.3.2 Modify Interactive Report
 Perform  the  following  steps  to  change  the  look  and  feel  of  the  default
 interactive report. After performing these steps, the interactive report will besaved as the Default Primary Report, which cannot be renamed or deleted.
 Note that these modifications are made using the Actions menu at runtime.
 1.  Click the Save and Run Page button to run Page 4.
 2.  Click  the  Actions  menu,  select  the  Columns  option,  arrange  the
 report columns as depicted in the following screen shot, and click
 Apply. This action will arrange the report columns in the specified
 order.
 Figure 7-4
 3.  Click  the  Actions  menu  again,  and  select  Data  followed  by  the
 Sort option.
 4.  In the Sort grid, select the Order # column in the first row, set the
 corresponding  Direction  to  Descending,  and  click  Apply.  This
 action will display most current orders on top.Figure 7-5
 4.  Click Actions | Report | Save Report. In the Save Report  dialog
 box, select As Default Report Settings from the Save list, select
 Primary for Default Report Type, and click Apply.
 NOTE:  Always  save  a  report  via  the  Actions  menu  whenever  you  make
 changes  to  it;  otherwise,  your  modifications  will  not  be  reflected  the  next
 time  you  log  in  to  the  application.  In  Interactive  Reports,  you  can  apply  a
 number of filters, highlights, and other customizations. Rather than having to
 re-enter  these  customizations  each  time  you  run  the  report,  you  tell  Oracle
 APEX to remember them so that they are applied automatically on every next
 run.  The  application  users  can  save  multiple  reports  based  on  the  default
 primary report, as discussed in the next couple of sections.
 7.3.3 Create Alternative Report
 Alternative report enables developers to create multiple report layouts. Only
 developers  can  save,  rename,  or  delete  an  Alternative  Report.  This  report
 (named Monthly Review) is based on the default primary report and will be
 rendered in a different layout using the Control Break utility on Order Month
 column.  Execute  the  following  steps  on  the  primary  interactive  report  on
 Page 4 to create three different views of the report.
 A. Report View
 1.  From the Actions menu, select Save Report (under Report). In the
 Save Report dialog box, select As Default Report Settings  from
 the Save list. This time, select the Alternative option for Default
 Report Type, enter Monthly  Review  in  the  Name  box,  and  click
 Apply. You will see a drop down list between the Search bar andthe  Actions  menu  carrying  two  reports:  Primary  Report  and
 Monthly Review.
 2.  From the list, select the Monthly Review alternative report.
 3.  Click  Actions  |  Format  |  Control  Break.  Under  Column,  select
 Order Month in the first row (A), set Status to Enabled (B), and
 click  Apply.  The  Control  Break  feature  enables  grouping  to  be
 added  to  your  report  on  one  or  more  columns.  The  Column
 attribute defines which column to group on and the Status attribute
 determines whether the control break is active. When you click the
 Apply  button,  you  will  see  the  report  results  are  grouped  by  the
 Order  Month  column  and  the  Control  Break  column  rule  (C)  is
 listed under the toolbar. A checkbox (D) is displayed next to the
 Control Break column and it is used to turn the control break rule
 on  or  off.  The  control  break  can  be  deleted  from  the  report  by
 clicking the small cross icon (E).
 4.  Click  Actions  |  Format  |  Highlight.  Type  Display  Orders  >$1000 (A) in the Name box, set Highlight Type to Cell (B), select
 green (C) for Background Color, and click red (D) for Text Color.
 In the Highlight Condition section, set Column to Order Total (E),
 Operator to > greater than (F), Expression to 1000 (G), and click
 Apply. To distinguish important data from the rest, Oracle APEX
 provides  you  with  conditional  highlighting  feature  in  interactive
 reports. The highlight feature in the Actions menu enables users to
 display  data  in  different  colors  based  on  a  condition.  You  can
 define multiple highlight conditions for a report. In this step, you're
 instructing to highlight the Order Total column in the report with
 green background and red text color where the value of this column
 is greater than 1000. Since you set the Highlight Type to Cell, the
 condition will apply only to the Order Total column. To modify an
 existing highlight rule, click its entry under the interactive  report
 toolbar.
 5.  Click  Actions  |  Format  |  Highlight.  Type  Display  Orders  <=
 $999 in the Name field, set Highlight Type to Row, click yellow for
 Background  Color,  click  Red  for  Text  Color,  in  HighlightCondition set Column to Order Total, Operator to <= (less than or
 equal to), Expression to 999 and click Apply. This step is similar to
 the  previous  one  with  different  parameters.  In  contrast  to  the
 previous action, where only a single cell was highlighted, this one
 highlights  a  complete  row  with  yellow  background  and  red  text
 color and applies it to all rows in the report that have Order Total
 equaling $999 or less.
 The resulting output should resemble the following figure.
 Figure 7-8 Monthly Order Review ReportB. Chart View
 You  can  generate  charts  in  Interactive  Reports  based  on  the  results  of  a
 report. You can specify the type of chart together with the data in the report
 you want to chart. In the following exercise, you will create a horizontal bar
 chart to present monthly sales figures using the Order Month column for the
 chart labels and a sum of the Order Total column for the chart values.
 Figure 7-9
 1.  Click Actions | Chart.
 2.  Select the first option (Bar) for the Chart Type.
 3.  Select Order Month for Label.
 4.  Enter Month in Axis Title for Label.
 5.  Select Order Total for Value. 
 6.  Enter Sales in Axis Title for Value.7.  Select Sum for Function.
 8.  Set Orientation to Horizontal.
 9.  Select Label-Ascending for Sort.
 10.  Click Apply.
 The chart should resemble the following figure. Note that the toolbar now has
 two icons: View Report and View Chart. If the chart doesn’t appear, click the
 View Chart icon   in the toolbar. Move your mouse over each bar to see
 total amount for the month.
 Figure 7-10 Chart View
 C. Group By View
 Group By enables users to group the result set by one or more columns and
 perform mathematical computations against the columns. Once users define
 the group by, a corresponding icon is placed in the toolbar, which they can
 use to switch among the three report views.1.  Click the View Report icon   in the interactive report toolbar to
 switch back to the report view interface.
 2.  Click Actions | Group By.
 3.  Set the properties as show in the following figure and click Apply.
 Use the Add Function button to add the second function (Count).
 The first function calculates the monthly average of orders, while
 the  second  function  counts  the  number  of  orders  placed  in  each
 month.
 Figure 7-11
 4.  Click Actions | Report | Save Report. Select As Default Report
 Setting  from  the  Save  list.  Select  Alternative  for  the  Default
 Report  Type.  The  Name  box  should  display  Monthly  Review.
 Click Apply.
 The output of this view is illustrated in the following figure. Note that a third
 icon (View Group By) is also added to the toolbar.Figure 7-12 Group By View
 7.3.4 Create Public Report
 This  type  of  report  can  be  saved,  renamed,  or  deleted  by  end  users  who
 created  it.  Other  users  can  view  and  save  the  layout  as  another  report.
 Execute  the  following  instructions  to  create  the  three  views  Report,  Chart,
 and  Group  by  of  a  public  report.  The  Alternative  report  created  in  the
 previous section focused on orders, while this one is created from customers
 perspective.
 A. Report View
 1.  Select the default 1. Primary Report from the Reports drop-down
 list in the toolbar.
 2.  From the Actions menu, select Save Report (under Report).
 3.  From the Save drop-down list select As Named Report. For report
 Name, enter Customer Review, put a check on Public and  click
 the Apply button. A new report group (Public) will be added to the
 reports list in the toolbar, carrying a new report named Customer
 Review. Users can create multiple variations of a report and save
 them as named reports for either public or private viewing. When
 you click the Apply button, the report is displayed on your screen.
 4.  With the Customer Review report being displayed on your screen,
 click Actions | Format | Control Break. Select Customer in the
 first row under Column, set Status to Enabled, and click Apply to
 see the following output.Figure 7-13
 B. Chart ViewFigure 7-14
 1.  Click Actions | Chart.
 2.  Set parameters for the chart as illustrated in the figure 7-14.
 3.  Click the Apply button. The output is illustrated in figure 7-15.
 NOTE:  The  chart  uses  the  Average  function  (as  compared  to  the  Sum
 function  used  in  the  previous  exercise).  William  Hartsfield  has  placed  two
 orders amounting to $2,370. The average for this customer comes to $1,185
 (2,370/2) and this is what you see when you move your mouse over the bar
 representing this customer.Figure 7-15 Chart View
 C. Group By View
 1.  Click the View Report icon to switch back.
 2.  Click Actions | Group By.
 3.  Set parameters for this view as show in the following illustration.
 Turn  on  the  Sum  switch  for  all  three  functions  to  display  grand
 totals.Figure 7-16
 4.  Click Apply.
 5.  Save your work using the Actions menu. Select As Named Report
 from the Save list. The Name box should be displaying Customer
 Review. Click Apply.
 Select  Customer  Review  from  the  report  list  in  the  toolbar,  and  click  the
 View  Group  By  icon.  The  following  figure  displays  the  output  for  the
 selections you just made. In this view, you utilized Sum and Count functions
 on  two  columns:  Order  Total  and  Order  Items.  This  view  displays  total
 amount  of  orders  placed  by  each  customer  with  number  of  orders  and  the
 total number of items ordered.Figure 7-17 Group By View
 D. Pivot View
 The Pivot option is the Actions menu is used to create a cross tab view based
 on the data in the report. Let's see an instance of this option as well.
 1.  Click the View Report icon to switch back.
 2.  Click Actions | Pivot.
 3.  Set parameters as show in the following illustration. Don’t forget to
 turn on the Sum switch to produce grand totals on the page.Figure 7-18
 4.  Click Apply.
 5.  Save your work using the Actions menu.
 The following figure illustrates the output of these actions.
 Figure 7-19 Pivot ViewIn the previous few sections you used some options from the Actions menu to
 customize the interactive report. However, the menu contains a few more, as
 listed below:
 Filter  focuses  the  report  by  adding  or  modifying  the  WHERE
 clause on the query.
 Rows Per Page determines how many rows display in the current
 report.
 Data contains the following submenu:
 Sort - Changes the columns to sort on and determines whether to
 sort in ascending
 or descending order.
 Compute - Enables users to add computed columns to a report.
 Flashback enables you to view the data as it existed at a previous
 point in time by specifying number of minutes. To use this option,
 the Oracle database FLASHBACK feature must be turned on.
 Reset  is  used  to  reorganize  the  report  back  to  the  default  report
 settings.
 Help provides descriptions of how to customize interactive reports.
 Download enables users to download a report. Available download
 formats depend upon your installation and report definition. To see
 these  formats,  click  a  region's  Attribute  node  and  check  the
 Download section in the Property Editor.
 
 ## 7.4 Modify Order  Details Page - Page 29
 Execute the instructions provided in the following sub-sections to modify the
 Order Details Page.
 7.4.1 Modify Master Region Properties
 Page  29  contains  two  regions.  The  master  region  (Form  on
 DEMO_ORDERS)  is  of  Form  type  and  carries  order  header  information,
 while the second region (Order Details) is an interactive grid, which containsline item details. Modify the master region using the following steps:
 1.  Open Page 29 in the Page Designer, click the root node (Page 29:
 Order Details) and set the Page Mode property to Modal Dialog
 to open it on top of Page 4. Set Width, Height, and Maximum Width
 properties  to  900,  700,  and  1200,  respectively.  Also,  set  Dialog
 Template  (in  the  Appearance  section)  to  Wizard  Modal  Dialog.
 Dialog  templates  are  defined  in  the  application  theme.  When  a
 dialog page is created, the template is automatically set to Theme
 Default, which will render the page using the default page template
 defined in the current theme. The Wizard Modal Dialog provides a
 streamlined  user  interface  suitable  for  input  forms.  When  you
 switch  to  this  template,  the  name  of  Content  Body  changes  to
 Wizard Body and a new node named Wizard Buttons is added. We
 will  use  this  node  to  place  all  our  page  buttons  to  make  them
 visible all the time.
 2.  Click  the  Form  on  DEMO_ORDERS  region  and  enter  Order
 #&P29_ORDER_ID.  (including  the  terminating  period)  for  its
 Title. The expression consists of two parts. The first one (Order #)
 is a string concatenated to a page item (P29_ORDER_ID), which
 carries  the  order  number.  The  string,  when  combined,  would  be
 presented as: Order # 1. Make sure that region’s Template attribute
 (under Appearance) is set to Standard to show this title.
 3.  Create a new page item in the Items node under the master region
 and set the following properties. This item will present customer
 information on each order as display-only text. Display Only items
 are  shown  as  non-enterable  text  item.  Note  that  you  may  get  an
 error  message  (ORA-20999)  when  you  enter  the  SQL  query
 specified  in  the  table  below.  Save  the  page  by  clicking  the  Save
 button to get rid of this message. Moreover, if you keep the default
 value (On) for Escape Special Characters property, the customer
 information appears on a single line with <br/> tags
 Property Value
 Name P29_CUSTOMER_INFO
 Type Display OnlyLabel Customer
 Template Optional
 Type  (under Source) SQL Query (return single value)
 SQL Query
 select apex_escape.html(cust_first_name) || ' ' ||
 apex_escape.html(cust_last_name) || '<br />' ||
 apex_escape.html(cust_street_address1) ||
 decode(cust_street_address2, null, null, '<br />' ||
 apex_escape.html(cust_street_address2)) || '</br>' ||
 apex_escape.html(cust_city) || ', ' ||
 apex_escape.html(cust_state) || '  ' ||
 apex_escape.html(cust_postal_code)
 from demo_customers
 where customer_id = :P29_CUSTOMER_ID
 Escape Special Characters Off
 NOTE: If you see an error message after providing the SQL query, ignore it
 and click the Save button to save the page. The error will vanish.
 1.  Using drag and drop arrange page items in the master region as
 illustrated in the following screenshot.
 Figure 7-20
 2.  Edit  the  following  items  individually  and  set  the  corresponding
 properties shown under each item.a.  P29_ORDER_TIMESTAMP
 Property Value
 Type Display Only
 Label Order Date
 Template Optional
 Format Mask DD-MON-YYYY HH:MIPM
 b.  P29_ORDER_TOTAL
 Property Value
 Type Display Only
 Template Optional
 Format Mask $5,234.10
 c.  P29_USER_NAME
 Property Value
 Type Select List
 Label Sales Rep
 Template Optional
 Type  (List of Values) SQL Query
 SQL Query
 select distinct user_name d, user_name r
 from demo_orders
 union
 select upper(:APP_USER) d, upper(:APP_US
 from dual
 order by 1
 Display Extra Values Off
 Display Null Value Off
 Help Text Use this list to change the Sales Rep associate
 In the Help  Text  attribute  you  specify  help  text  for  an  item.
 The  help  text  may  be  used  to  provide  field  level,  context
 sensitive help. At run-time you will see a small help icon 
 in-front of this item. When you click this icon, a window pops
 up to show the help text.d.  P29_TAGS
 Property Value
 Template Optional
 e.  P29_CUSTOMER_ID
 Property Value
 Type Hidden
 Value Protected Off
 f.  P29_ORDER_ID
 Property Value
 Type Hidden
 Value Protected Off
 6.  In the Region Buttons node, set Button  Position  property  to  Edit
 for GET_PREVIOUS_ORDER_ID and GET_NEXT_ORDER_ID
 buttons to place them on top of the region.
 7.4.2 Modify Details Region’s Properties
 After  setting  the  master  region,  let’s  modify  the  details  region  to  give  it  a
 desirable look.
 1.  Click the Order Details interactive grid region and set its Title to
 Items for Order #&P29_ORDER_ID. – including the terminating
 period.
 2.  Replace the auto-generated source attributes of the region with the
 followings:
 Property Value
 Location Location Database
 Type SQL Query
 SQL Query select  oi.order_item_id,  oi.order_id,  oi.product_id,  oi.uni
 oi.quantity,
 (oi.unit_price * oi.quantity) extended_price
 from DEMO_ORDER_ITEMS oi, DEMO_PRODUCT_INFO piwhere oi.ORDER_ID = :P29_ORDER_ID
 and oi.product_id = pi.product_id (+)
 3.  Save the page.
 4.  Under  the  Columns  node,  edit  the  following  columns  using  the
 specified properties.
 Column Property Value
 ORDER_ITEM_ID
 Type
 Value Protected
 Primary Key
 Hidden
 On
 On
 ORDER_ID
 Type
 Value Protected
 Hidden
 On
 PRODUCT_ID
 Type
 Heading
 Alignment
 Type  (LOV)
 List of Values
 Display Null Value
 Select List
 Product
 Select the left icon
 Shared Components
 Products With Price
 Off
 UNIT_PRICE
 Alignment
 Column Alignment
 Format Mask
 Select the right icon
 Select the right icon
 $5,234.10
 QUANTITY
 Width  (under Appearance)
 Type  (under Default)
 PL/SQL Expression
 5
 PL/SQL Expression
 1   (sets 1 as the default quan
 EXTENDED_PRICE
 Type
 Heading
 Alignment
 Column Alignment
 Format Mask
 Query Only ( under Source )
 Display Only
 Price
 Select the right icon
 Select the right icon
 $5,234.10
 On
 After modifying an interactive grid query you must specify a primary
 column,  which  is  required  for  editing  and  to  specify  master  detail
 relationship. If not defined, you will encounter " Interactive Grid doesn't have a
 primary key column defined which is required for editing or in a master detail relationship "
 message . By setting the ORDER_ITEM_ID column as the primary key
 you eliminate this error.
 The Alignment property sets the heading alignment, while the ColumnAlignment  specifies  the  column  display  alignment.  For  product  ID
 column, we changed two properties. First, we set its Type property to
 Select List. Secondly, we associated an LOV (Products with Price) to it.
 This  LOV  was  created  in  Chapter  3  section  3.4.2  to  display  a  list  of
 products along with respective prices.
 The Query Only property (under Source  section)  set  for  the  Extended
 Price  column  specifies  whether  to  exclude  the  column  from  DML
 operations. If set to On, Application Express will not utilize the column
 when  executing  the  Interactive  Grid  -  Automatic  Row  Processing
 (DML)  process.  In  the  current  scenario,  you  excluded  the  Extended
 Price column, because it is not a physical table column and is calculated
 in the SELECT query stated above. If you keep the default value of this
 property for the Extended Price column, you will get “Virtual  column
 not allowed here” error message when you try to save an existing order.
 All  columns  whose  definitions  include  concatenations,  inner  selects,
 functions call, or a column in an updateable view that is based on an
 expression should be excluded. All columns that need to be included in
 any INSERT or UPDATE statements must have this option set to Off.
 Note  that  columns  of  type  Display  Only  are  also  included  in  the
 Automatic Row Processing unless this option is turned on.
 5.  Using  drag  and  drop  arrange  the  five  visible  columns  in  the
 following order:
 PRODUCT_ID, UNIT_PRICE, QUANTITY, and
 EXTENDED_PRICE
 6.  Right-click the Wizard Buttons node and select Create Region. Set
 Title  of  the  new  region  to  Buttons  and  Template  to  Buttons
 Container. In the Region Buttons node, click the Cancel  button,
 and set its Region property to Buttons. Set the same Buttons region
 for Delete, Save, and Create  buttons,  too.  This  action  will  place
 the four buttons under the Buttons region in the interactive grid.
 7.  On the Processing tab, make sure that the process “Process form
 Form on DEMO_ORDERS” sits before the Order Details – Save
 Interactive Grid Data process. If not, drag and place it before the
 Order  Details  –  Save  Interactive  Grid  Data  process  or  set  itsSequence  property  to  a  number  lower  than  that  of  the  Save
 Interactive Grid Data process. Note that this process must precede
 the Save Interactive Grid Data process; otherwise, you will get the
 error “Current version of data in database has changed since user
 initiated update process” when you try to manipulate data in the
 interactive grid.
 8.  Save the changes.
 NOTE: If you see a different process name, then there is nothing to worry
 about as it sometimes happens due to change in APEX version.
 Test Your Work
 Run the application and click the Orders option in the main navigation menu.
 The page that comes up should look like Figure 7-21. Click any order number
 to  call  the  Order  Details  page  (Figure  7-22).  Try  to  navigate  forward  and
 backward using the Next and Previous   buttons. At the moment, you can
 only use these two pages to manipulate existing orders. In the next sections,
 you will create some more pages to enter new orders.
 Call  order  number  0002  and  click  the  Add  Row  button  appearing  in  the
 Interactive Grid's toolbar. A new row will be added to the grid just under the
 first row with the Product column appearing as a list of values carrying all
 products with their respective prices. Select Air Max 2090 (A) from this list,
 enter 1500 (B) in the Unit Price column, and put some value in the Quantity
 column  (or  accept  the  default  quantity  1).  Now,  remove  the  checkmark
 appearing  in  the  first  column  of  the  new  record  and  put  a  check  on  the
 previous Air Max 2090 record (C). From the Row Actions menu (D), select
 Delete Row (E). The previous record will be marked as deleted (F). Click the
 Apply  Changes  button  (G).  Call  the  order  again.  The  new  record  will  be
 added  to  the  table  with  the  correct  price  of  the  product  and  the  previous
 record will be removed.Figure 7-21 – Orders Interactive Report Page
 Figure 7-22 – Order Details 
 
 ## Page7.5 Create a Page to Enter a New Order -  Page 11
 As mentioned earlier, you will go through a series of steps to enter a new
 order. You identified and created these steps in Order Wizard list in Chapter
 3 section 3.2.3. The top section (A) in Figure 7-23 reflects these steps. Each
 step will be associated to an application page. The rest of this chapter will
 guide  you  to  create  the  three  pages  individually.  In  this  exercise,  you  will
 create Page 11 - Enter New Order.
 The order recording process initiates when you click the button Enter  New
 Order  on  the  Orders  page  (Page  4).  The  button  calls  Page  11,  where  you
 select  a  customer  who  placed  the  order.  Besides  selecting  an  existing
 customer,  you  can  also  create  record  of  a  new  customer  on  this  page.  The
 Customer LOV button (B) calls a list of existing customers from which you
 can select one for the order. If you select the New Customer  option  (C),  a
 region (New Customer Details) will be shown under the existing region. By
 default, this region is hidden and becomes visible when you click the New
 Customer option. This functionality is controlled by a dynamic action (Hide /
 Show Customer), which will also be created for this page.
 In addition to various techniques taught in this part, you’ll create this page
 from  an  existing  page  -  Customer  Details  (Page  7)  -  to  generate  a  new
 customer record. Here, you’ll make a copy of that page and will tweak it for
 the current scenario. Let’s see how it is done.
 Figure 7-23 Identify Customer Page1.  In the App Builder interface, click the Customer Details - Page 7
 to open its definitions in Page Designer.
 2.  Click the Create menu   at top-right in the toolbar and select
 Page as copy.
 3.  On  the  first  wizard  screen,  select  the  option  Page  in  this
 application for Create a page as a copy of and click Next.
 4.  Fill  in  the  following  values  on  Page  To  Copy  screen  and  click
 Next.
 Figure 7-24
 5.  On  the  Navigation  Menu  screen  select  Identify  an  existing
 navigation menu entry for this page, select Orders for Existing
 Navigation Menu, and click Next.
 6.  Accept the names of existing page buttons and items on the New
 Names screen and click the Copy button to finish the wizard.
 Look at the Page Designer. All the elements from Page 7 appear on the new
 page, especially the items section, which carries all input elements (with P11
 prefix) to create a new customer record. This is the section we needed on our
 new page to spare some time.
 7.5.1 Modify Page Properties
 1.  In Page 11, click the root node (Page 11: Identify Customer). In
 the  Properties  pane,  set  Dialog  Template  (under  Appearance)  toWizard  Modal  Dialog.  The  template  creates  a  region  (Wizard
 Progress  Bar)  to  hold  the  order  progress  list  (A),  as  shown  in
 Figure 7-23, and alters the name of the main region from Content
 Body to Wizard Body.
 2.  Set Width and Height properties to 700 and 500, respectively.
 3.  Remove  htmldb_delete_message  variable  from  Function  and
 Global  Variable  Declaration  property.  Save  the  page  after
 removing  the  variable.  This  is  an  auto-generated  variable
 associated  with  the  customer  record  deletion  process  handled
 transparently by Oracle APEX. It is removed because the customer
 record deletion process is not required here.
 4.  Change  Maintain  Session  State  property  (in  Source  section)  of
 P11_CUST_FIRST_NAME,  P11_CUST_LAST_NAME,
 P11_CUST_STREET_ADDRESS1,
 P11_CUST_STREET_ADDRESS2,  P11_CUST_CITY,  and
 P11_CUST_STATE,P11_CUST_POSTAL_CODE,
 P11_CREDIT_LIMIT,  P11_PHONE_NUMBER1,
 P11_PHONE_NUMBER2,  P11_CUST_EMAIL,  P11_URL,  and
 P11_TAGS  page  items  to  Per  Session  (Disk).  Switching  to  this
 value  maintains  the  item  value  to  access  it  across  requests.  See
 PL/SQL code line 22-30 in section 7.6.3 and Place Order process
 in  section  7.6.8  later  in  this  chapter  where  these  items  are
 referenced.  If  you  keep  the  default  Per  Request  (Memory  Only)
 value  for  this  property,  none  of  the  page  item  values  can  be
 referenced on other module pages and will not be inserted in the
 database table.
 7.5.2 Create Region – Order Progress
 Right-click the Wizard Progress Bar node (under Regions) and select Create
 Region. Set the following properties for the new region. The Order Wizard
 list used here was created in Chapter 3 - section 3.2.3. The Wizard Progress
 value specified for the List Template property displays a progress train based
 on the list items and is well suited for wizards and multi-step flows.
 Property ValueTitle Order Progress
 Type List
 List Order Wizard
 Template Blank with Attributes
 List Template  (under Attributes node) Wizard Progress
 Label Display ( under Attributes |Template
 Options )
 All Steps ( displays labels of all wizard steps )
 7.5.3 Create Region – Identify Customer
 Right-click the Wizard Body node and select Create Region. Drag the new
 region  and  place  it  above  the  Customer  Details  region.  Set  the  following
 properties for it. This region is created to act as a main container to hold  a
 radio group item and a couple of sub-regions.
 Property Value
 Title Identify Customer
 Type Static Content
 Template Standard
 7.5.4 Create Item
 Right-click the new Identify Customer region and select Create Page Item.
 Set the following properties for the new item, which is a Radio Group. The
 list  of  values  attached  to  this  radio  group  item  (NEW  OR  EXISTING
 CUSTOMER) was created in Chapter 3 - section 3.4.4 with two static values
 to create a new customer or select an existing one for a new order. The value
 set for the Number of Columns property displays these values in two separate
 columns. The first Type and Static Value  properties  (under  Source)  specify
 the  source  type  the  value  of  this  item  will  based  on  when  you  access  this
 page, whereas the second pair sets the EXISTING value as the default choice.
 
 **Property Value**
 
 Name P11_CUSTOMER_OPTIONS
 Type Radio Group
 Label <b>Create Order for:</b>
 Number of Columns 2
 Template Required
 Label Column Span 3
 Type  (under List of Values) Shared ComponentList of Values NEW OR EXISTING CUSTOMER
 Display Null Value Off
 Type  (under Source) Static Value
 Static Value  (under Source) EXISTING
 Type  (under Default) Static
 Static Value  (under Default) EXISTING
 7.5.5 Create a Sub Region – Existing Customer
 Right-click the Identify Customer region and select Create Sub Region. This
 will add a sub region under the page item P11_CUSTOMER_OPTIONS. Set
 the following properties from the sub region.
 Property Value
 Title Existing Customer
 Type Static Content
 Template Blank with Attributes
 7.5.6 Modify Item – P11_CUSTOMER_ID
 In the Items section, click P11_CUSTOMER_ID. Set the Name property of
 this hidden item to P11_CUSTOMER_ID_XYZ. Set Server-side Condition
 Type to Never (last in the list). This item is renamed and suppressed from
 being rendered because a new item (of Popup LOV type) with the same name
 is  created  in  the  next  section  to  display  a  list  of  customers,  instead.  By
 selecting the Never value for the Server-side Condition  Type  property,  you
 permanently  disable  a  page  component.  That  is,  the  component  is  never
 rendered.
 7.5.7 Add LOV
 Right-click the Existing Customer sub-region and select Create Page Item.
 Set the following properties for this item. The Type value (under Source) is
 set  to  Null,  because  the  IDs  and  names  of  customers  are  retreived  using  a
 SQL query and displayed in a Popup LOV.
 Property Value
 Name P11_CUSTOMER_ID
 Type Popup LOV
 Label Customer
 Template Required
 Width 70Value Required Off
 Type  (under List of Values) SQL Query
 SQL Query
 select cust_last_name || ', ' || cust_first_name d, customer_id r
 from demo_customers
 order by cust_last_name
 Display Extra Values Off
 Display Null Value Off
 Type  (under Source) Null
 Help Text
 Choose a customer using the pop-up selector, or to create a new
 customer, select the <strong>New customer</strong> option.
 7.5.8 Modify Customer Details Region
 Click the Customer Details region and set the following properties for this
 region. When you specify a parent region you make a region child of a parent
 region.
 Property Value
 Title New Customer Details
 Parent Region Identify Customer
 7.5.9 Delete Validation, Processes, and Buttons
 1.  On  the  Processing  tab,  right-click  the  entry  Can’t  Delete
 Customer with Orders under Validations, and select Delete from
 the context menu. Similarly, delete the process Process Customer
 Data.
 2.  Also, remove Delete, Save, and Create buttons from the Buttons
 region on the Rendering tab.
 7.5.10 Delete Process
 On the Rendering tab, expand the Pre-Rendering | Before Header | Processes
 node  and  delete  the  process  named  Initialize  Customer  Details.  This  is  a
 default process created in the Customers module and is not required in the
 current scenario.
 7.5.11 Create Button
 Create a new button in the Buttons region and set the following properties for
 it. After identifying a customer, you click this button to advance to the secondorder  wizard  step.  This  button  will  appear  under  the  Cancel  button  in  the
 Page Designer. When this button is clicked, the Action property submits the
 page and a branch (created in section 7.5.18) takes control of the application
 flow and moves you on to the next wizard step.
 Property Value
 Button Name NEXT
 Label Next
 Button Position Next
 Button Template Text with Icon
 Hot On
 Icon fa-chevron-right
 Action Submit Page  (default)
 7.5.12 Create Process - Create or Truncate Order Collection
 When  developing  web  applications  in  Oracle  APEX,  you  often  need  a
 mechanism  to  store  an  unknown  number  of  items  in  a  temporary  location.
 The most common example of this is an online shopping cart where a user
 can add a large number of items. To cope with this situation in Oracle APEX,
 you use Collections to store variable information. Before using a collection, it
 is necessary to initialize it in the context of the current application session.
 After clicking the Enter New Order button, you’re brought to this page (Page
 11) and this is where your collection (named ORDER) is initialized using a
 PL/SQL  process  that  fires  Before  Header  when  the  user  enters  into  the
 interface  of  Page  11.  See  sections  7.6.7  and  7.6.8  for  relevant  details  on
 collections.
 On  the  Rendering  tab,  expand  the  Pre-Rendering  node.  Right-click  the
 Before Header node and select Create Process. Set the following properties
 for the new process.
 Property Value
 Name Create or Truncate ORDER Collection
 Type PL/SQL Code
 PL/SQL Code apex_collection.create_or_truncate_collection (p_collection_name =>
 'ORDER');Figure 7-25
 7.5.13 Create Dynamic Action (Hide / Show Customer)
 Click  the  Dynamic  Actions  tab.  Right-click  the  Change  node  and  select
 Create  Dynamic  Action.  Click  the  New  node  and  set  the  following
 properties. The following settings inform Oracle APEX to fire the dynamic
 action  when  user  changes  (Event)  the  radio  group  item  (Selection  Type)
 P11_CUSTOMER_OPTIONS (Item) from New Customer to Existing.
 Property Value
 Name Hide / Show Customer
 Event Change
 Selection Type Item(s)
 Item(s) P11_CUSTOMER_OPTIONS
 Type  (under Client-side
 Condition)
 Item = value
 Item  (under Client-side
 Condition)
 P11_CUSTOMER_OPTIONS
 Value EXISTING
 Click  the  Show  node  to  set  the  following  properties.  The  values  for  these
 properties are set to show the Existing Customer region when the EXISTING
 option  is  selected  from  the  radio  group.  The  On  value  set  for  the  Fire  on
 Initialization property specifies to fire the action when the page loads.
 Property Value
 Action Show
 Selection Type Region
 Region ..Existing Customer
 Fire When Event Result is True
 Fire on Initialization OnRight-click  the  Show  node  and  select  Create  Action.  Another  Show  node
 will be added just under the previous one. Set the following properties for it.
 This action is also assoicated with the previous two and is added to hide New
 Customer Details region when the EXISTING option is selected.
 Property Value
 Action Hide
 Selection Type Region
 Region ..New Customer Details
 Fire When Event Result is True
 Fire on Initialization On
 Right-click the Show node again and select  Create  Opposite  Action.  This
 will add an opposite Hide action under the False node (with all properties set)
 to hide the Existing Customer region.
 Right-click the Hide node under the True node and select Create Opposite
 Action. This will add a Show action under the False node to show the New
 Customer Details region.
 If you run the page at this stage (by clicking the Enter New Order button on
 Page 4), you'll see the P11_CUSTOMER_ID item (in the Existing Customer
 region)  is  shown  on  the  page.  Now,  select  the  New  Customer  option.  The
 item P11_CUSTOMER_ID disappears from the page and the New Customer
 Details  region  becomes  visible.  Select  the  Existing  Customer  option  again,
 the item becomes visible and the New Customer Details region hides.
 7.5.14 Modify Validation – Check Credit Limit
 On  the  Processing  tab,  click  the  Check  Credit  Limit  validation.  Set  its
 Sequence  to  100  and  save  the  change  to  place  this  validation  in  a  proper
 sequence  after  the  following  validations.  Note  that  the  Sequence  property
 determines the order of evaluation.
 7.5.15 Create Validation – Customer ID Not Null
 Right-click  the  Validations  node  and  select  Create  Validation.  Set  the
 following  properties  for  the  new  validation.  You  can  control  when  a
 validation  is  performed  by  configuring  its  Server-side  Condition  property.
 Select a condition type from the list that must meet in order for a validation to
 process.  In  the  current  scenario,  the  condition  (item=value)  is  formed  likethis:  P11_CUSTOMER_OPTIONS = EXISTING . The validation fires when you select
 the  Existing  Customer  option  on  the  application  page,  and  do  not  select  a
 customer from the provided list. In case of an error at runtime, the  #LABEL#
 substitution string specified in the Error Message property is replaced with
 the label of the associated item P11_CUSTOMER_ID – that is, Customer.
 Property Value
 Name Customer ID Not Null
 Sequence 10
 Type  (Validation) Item is NOT NULL
 Item P11_CUSTOMER_ID
 Error Message Select a #LABEL# from the provided list.
 Associated Item P11_CUSTOMER_ID
 Type  (Server-side Condition) Item = Value
 Item P11_CUSTOMER_OPTIONS
 Value EXISTING
 7.5.16 Create Validation – First Name Not Null
 Create another validation. This validation will check whether the first name
 of a new customer is provided. It is fired only when the New Customer option
 is selected.
 Property Value
 Name First Name is Not Null
 Sequence 20
 Type  (Validation) Item is NOT NULL
 Item P11_CUST_FIRST_NAME
 Error Message #LABEL# must have some value.
 Associated Item P11_CUST_FIRST_NAME
 Type  (Server-side Condition) Item = Value
 Item P11_CUSTOMER_OPTIONS
 Value NEW
 Using  the  previous  table,  create  NOT  NULL  validations  for  Last  Name,
 State, Postal Code, and Credit Limit items.
 7.5.17 Create Validation – Phone Number
 Create  the  following  validation  to  check  input  of  proper  phone  numbers.Regular Expressions enable you to search for patterns in string data by using
 standardized  syntax  conventions,  rather  than  just  a  straight  character
 comparisons. The validation passes if the phone numbers matches the regular
 expression  attribute  and  fails  if  the  item  value  does  not  match  the  regular
 expression.  The  last  three  properties  inform  Oracle  APEX  to  execute  the
 validation only when a new customer is created.
 Property Value
 Name Phone Number Format
 Type  (Validation) Item matches Regular Expression
 Item P11_PHONE_NUMBER1
 Regular Expression ^\(?[[:digit:]]{3}\)?[-. ][[:digit:]]{3}[-. ][[:digit:]]{4}$
 Error Message Phone number format not recognized
 Associated Item P11_PHONE_NUMBER1
 Type  (Server-side Condition) Item = Value
 Item P11_CUSTOMER_OPTIONS
 Value NEW
 Create a similar validation for P11_PHONE_NUMBER2 item.
 Next, you have to turn off the Value Required attribute for  P11_CUSTOMER_ID
 (in Existing Customer region) , and P11_CUST_FIRST_NAME, P11_CUST_LAST_NAME,
 P11_CUST_STATE, P11_CUST_POSTAL_CODE, P11_CREDIT_LIMIT and
 P11_CUST_EMAIL  (in New Customer Details region). The Value Required
 properties for these items were inherited from Page 7 where they were set to
 On, to mark them as mandatory. In the previous two sections, you used an
 alternate method to manually control the validation process for these items. If
 you don’t reverse the Value Required status, then the application will throw
 NOT NULL errors for these items, even if you select an existing customer.
 7.5.18 Create Branch
 When  the  Next  button  is  clicked,  the  defined  button  action  (Submit  Page)
 triggers  after  performing  all  validations.  The  submit  page  process  executes
 instructions  specified  in  this  branch  and  moves  the  user  to  the  next  order
 wizard step. On the Processing tab, right-click the After Processing node and
 select Create Branch. Set the following properties for the new branch.
 Property ValueName Go To Page 12
 Type  (under Behavior) Page or URL (Redirect)
 Target
 Type = Page in this Application
 Page = 12
 Clear Cache = 12
 When Button Pressed NEXT
 Test Your Work
 From the main menu, select Orders and click the Enter New Order button.
 Your page should look like Figure 7-23. Select Existing Customer and click
 the LOV button    to call list of customers. Click the name of a customer
 from  the  list.  The  name  of  the  selected  customer  appears  in  the  Customer
 box. This is how an existing customer is selected for an order. Now, click the
 New Customer option, the Dynamic Action created in section 7.5.13 invokes
 and  performs  two  actions.  First,  it  hides  the  Customer  box  and  the  LOV.
 Second, it shows a form similar to the one you created in Chapter 5 to add a
 new customer record. Click the Next button without putting any value in the
 provided form. An inline message box will appear with six errors. This is the
 procedure you handled in the validation sections. After correcting all the form
 errors if you click  Next, the message “Sorry, this page isn't available“ pops
 up indicating that Page 12 doesn’t exist. Your next task is to create Page 12
 where you’ll select products for an order.
 
 ## 7.6 Create Select Items Page - Pages 12
 Having identified the customer, the second step in the order wizard is to add
 products  to  the  order.  In  this  exercise,  you  will  create  Page  12  of  the
 application to select ordered items and input the required quantities.
 1.  Click the Create Page button in the App Builder interface.
 2.  This time, select the Blank Page option. This option is selected to
 create an application page from scratch. Using this option you can
 create and customize a page according to your own specific needs. 
 3.  Complete the first Page Attributes screen as show in the following
 figure and click Next.Figure 7-26
 4.  On  the  Navigation  Menu  screen,  set  Navigation  Preference  to
 Identify  an  existing  navigation  menu  entry  for  this  page,
 Existing Navigation Menu Entry to Orders, and click Next.
 5.  Click Finish to end the wizard.
 ### 7.6.1 Modify Page Properties
 You styled the Detail View of an interactive report in the previous chapter to
 customize its look. Here as well, you will apply some styling rules to give the
 page  a  professional  touch.  Previously,  you  added  rules  to  a  single  page
 element:  HTML  table.  In  the  following  exercise  you’ll  apply  rules  to  the
 whole page. Before getting your feet wet, go through the following topic to
 understand Cascading Style Sheets (CSS).
 Cascading Style Sheets
 A cascading style sheet (CSS) provides a way to control the style of a web
 page  without  changing  its  structure.  When  used  properly,  a  CSS  separates
 visual properties such as color, margins, and fonts from the structure of the
 HTML document.
 In this chapter, you will use CSS to style Page 12 (Select Items - Figure 7-
 27).  On  this  page  you  will  add  class  properties  to  PL/SQL  code  and  will
 reference  them  in  CSS  in  the  HTML  Head  section.  Before  moving  on  to
 understand the actual functionality, let’s first take a look at a simple example
 on how to use class attribute in an HTML document. The class attribute is
 mostly  used  to  point  to  a  class  in  a  style  sheet.  The  syntax  is 
 ```
 <element class="classname">.
 <html><head>
 <style type="text/css">
 h1.header {color:blue;}
 p.styledpara {color:red;}
 </style>
 </head>
 <body>
 <h1 class="header">Class Referenced in CSS</h1>
 <p>A normal paragraph.</p>
 <p class="styledpara">Note that this is an important paragraph.</p>
 </body>
 </html>
 The body of this web page contains three sections:
 <h1 class="header">Class Referenced in CSS</h1>
 ```
 The text
 “Class Referenced in CSS” is enclosed in h1 html tag. It is called
 level 1 heading and is the most important heading in a document. It
 is  usually  used  to  indicate  the  title  of  the  document.  The  text  is
 preceded by a class named “header”. 
 Considering the class syntax, h1 is the element and header is the
 classname. This class is referenced in the style section using a CSS
 rule  –  h1.header  {color:blue;}    –  to  present  the  heading  in  blue
 color. A CSS rule has two main parts: a selector and one or more
 declarations. The selector is normally the HTML element you want
 to style. Each declaration consists of a property and a value. The
 property is the style attribute you want to change. Each property
 has a value. In the h1.header {color:blue;} rule, h1 is the selector,
 header is the classname, and {color:blue;} is the declaration.
 <p>A normal paragraph.</p> – It is a plain paragraph without
 any  style  applied  to  it.  HTML  documents  are  divided  into
 paragraphs and paragraphs are defined with the <p> tag. The <p>
 tag is called the start tag or opening tag, while </p> is called the
 end or closing tag.
 <p  class="styledpara">Note  that  this  is  an  importantparagraph.</p>  –  It  is  a  paragraph  with  a  class  named
 “styledpara”.  In the style section, the selector “p” followed by the
 classname  “styledpara”  with  the  declaration{color:red;}  is
 referencing this section to present the paragraph text in red color. 
 Now that you have understood how CSS is used in web pages, let’s figure out
 how it is used in Oracle APEX.
 1.  Click the root node – Page 12: Order Items.
 2.  Set Dialog Template to Wizard Modal Dialog.
 3.  Set Width and Height to 500 and 600, respectively.
 4.  Enter the following code for inline property under CSS section and
 
 save  your  work.  You  can  find  this  code  in BookCode\Chapter7\7.6.1.txt  file.  CSS  rules  entered  in  this  box will be applied to all the referenced elements on the current page, as illustrated in Figure 7-27.
 ```
 div.CustomerInfo{margin: 10px 10px 0;}
 div.CustomerInfo strong{font:bold 12px/16px Arial,sans-serif;display:block;width:120px;}
 div.CustomerInfo p{display:block;margin:0; font: normal 12px/16px Arial, sans-serif;}
 div.Products{clear:both;margin:16px 0 0 0;padding:0 8px 0 0;}
 div.Products table{border:1px solid #CCC;border-bottom:none;}
 div.Products table th{background-color:#DDD;color:#000;font:bold 12px/16px Arial,sans-serif;padding:4px 10px;text-align:right;border-bottom:1px solid #CCC;}
 div.Products table td{border-bottom:1px solid #CCC;font:normal 12px/16px Arial,sans-serif; padding:4px 10px;text-align:right;}
 div.Products table td a{color:#000;}
 div.Products .left{text-align:left;}
 div.CartItem{padding:8px 8px 0 8px;font:normal 11px/14px Arial,sans-serif;} 
 div.CartItem a{color:#000;} 
 div.CartItem span{display:block;text-align:right;padding:8px 0 0 0;} 
 div.CartItem span.subtotal{font-weight:bold;} 
 div.CartTotal{margin-top:8px;padding:8px;border-top:1px dotted #AAA;} 
 div.CartTotal span{display:block;text-align:right;font:normal 11px/14px Arial,sans-serif;padding:0 0 4px 0;} 
 div.CartTotal p{padding:0;margin:0;font:normal 11px/14px Arial,sans-serif;position:relative;} 
 div.CartTotal p.CartTotal{font:bold 12px/14px Arial,sans-serif;padding:8px 0 0 0;} 
 div.CartTotal p.CartTotal span{font:bold 12px/14px Arial,sans-serif;padding:8px 0 0 0;} 
 div.CartTotal p span{padding:0;position:absolute;right:0;top:0;} 
 ```
 ### 7.6.2 Create Region – Order Progress
 Right-click the Wizard Progress Bar node and select Create Region. Set the
 following  properties  for  the  new  region.  A  similar  region  was  added
 previously to Page 11 to display the Order Progress bar.
 Property ValueTitle Order Progress
 Type List
 List Order Wizard
 Template Blank with Attributes
 List Template  (under Attributes node) Wizard Progress
 
 
 ### 7.6.3 Create Region – Select Items
 The region being created in this section is based on a custom PL/SQL code. The code references CSS rules (defined in the previous section) to design the
 Select Items page, as illustrated in Figure 7-27.
 
 What is PL/SQL?
 
 PL/SQL stands for Procedural Language/Structured Query Language. It is a programming  language  that  uses  detailed  sequential  instructions  to  process data.  A  PL/SQL  program  combines  SQL  command  (such  as  Select  and Update) with procedural commands for tasks, such as manipulating variable values, evaluating IF/THEN logic structure, and creating loop structures that repeat  instructions  multiple  times  until  the  condition  satisfies  the  defined criteria. PL/SQL was expressly designed for this purpose. The structure of a PL/SQL program block is:
 ```
 Declare
    Variable declaration
 Begin
    Program statements
 Exception
    Error-handling statements
 End;
 ```
 PL/SQL program variables are declared in the program’s declaration section. The beginning of the declaration section is marked with the reserved word DECLARE . You can declare multiple variables in the declaration section. The body  of  a  PL/SQL  block  consists  of  program  statements,  which  can  be assigned statements, conditional statements, loop statements, and so on. The body  lies  between  the  BEGIN   and  EXCEPTION   statements.  The  exception section  contains  program  statements  for  error  handling.  Finally,  PL/SQL programs end with the  END;  statement. Comments in PL/SQL code are added by prefixing them with double hyphens.In a PL/SQL program block, the DECLARE and EXCEPTION sections are optional.  If  there  are  no  variables  to  declare,  you  can  omit  the  DECLARE section and start the program with the BEGIN command.
 1.  Right-click  the  Order  Progress  region  and  select  Create  Sub Region from the context menu.
 2.  Enter  Select  Items  for  its  Title  and  set  its  Type  to  PL/SQL Dynamic Content to display the page content using PL/SQL code. PL/SQL  Dynamic  Content  displays  the  HTML  output  from  the PL/SQL code.
 3.  Add the code defined in the PL/SQL Code column (Table 7-1) in the PL/SQL Code  property  (in  the  Source  section).  You  can  find this  code  in  BookCode\Chapter7\7.6.3.txt  file.  The  first  column (CSS Rule) in the following table references the rules defined in the previous section. These rules are applied to the injected HTML elements  in  the  PL/SQL  code.  The  second  table  column  is populated  with  a  serial  number  assigned  to  each  PL/SQL  code. These  numbers  are  referenced  in  the  explanation  section underneath.
 4.  Do not set any option for the Template property (in other words, change  it  from  the  default  Standard  value  to  the  -Select- placeholder).
 
 ```
 declare
   l_customer_id varchar2(30) := :P11_CUSTOMER_ID;
 begin
 --
 -- display customer information
 --
 sys.htp.p('<div class="CustomerInfo">');
 if :P11_CUSTOMER_OPTIONS = 'EXISTING' then
   for x in (select * from demo_customers where customer_id = l_customer_id) loop
     sys.htp.p('<div class="CustomerInfo">');
     sys.htp.p('<strong>Customer:</strong>');  
     sys.htp.p('<p>');
     sys.htp.p(sys.htf.escape_sc(x.cust_first_name) || ' ' ||
     sys.htf.escape_sc(x.cust_last_name) || '<br />');
     sys.htp.p(sys.htf.escape_sc(x.cust_street_address1) || '<br />');
     if x.cust_street_address2 is not null then
       sys.htp.p(sys.htf.escape_sc(x.cust_street_address2) || '<br />');        
     end if;
     sys.htp.p(sys.htf.escape_sc(x.cust_city) || ', ' ||
     sys.htf.escape_sc(x.cust_state) || '  ' ||
     sys.htf.escape_sc(x.cust_postal_code));
     sys.htp.p('</p>');
   end loop;
 else
   sys.htp.p('<strong>Customer:</strong>');  
   sys.htp.p('<p>');
   sys.htp.p(sys.htf.escape_sc(:P11_CUST_FIRST_NAME) || ' ' ||
                 sys.htf.escape_sc(:P11_CUST_LAST_NAME) || '<br />');
   sys.htp.p(sys.htf.escape_sc(:P11_CUST_STREET_ADDRESS1) || '<br />');
   if :P11_CUST_STREET_ADDRESS2 is not null then
     sys.htp.p(sys.htf.escape_sc(:P11_CUST_STREET_ADDRESS2) || '<br />');    
   end if;
   sys.htp.p(sys.htf.escape_sc(:P11_CUST_CITY) || ', ' ||
   sys.htf.escape_sc(:P11_CUST_STATE) || '  ' ||
   sys.htf.escape_sc(:P11_CUST_POSTAL_CODE));
   sys.htp.p('</p>');
 end if;
 sys.htp.p('</div>');
 
 -- display products
 --
 sys.htp.p('<div class="Products" >');
 sys.htp.p('<table width="100%" cellspacing="0" cellpadding="0" border="0">
 <thead>
 <tr><th class="left">Product</th><th>Price</th><th></th></tr>
 </thead>
 <tbody>');
 for c1 in (select product_id, product_name,  list_price, 'Add to Cart' add_to_order
 from demo_product_info
 where product_avail = 'Y'
 order by product_name) loop
 sys.htp.p('<tr><td class="left">'||sys.htf.escape_sc(c1.product_name)||'</td>
 <td>'||trim(to_char(c1.list_price,'999G999G990D00')) || '</td>
 <td><a href="'||apex_util.prepare_url('f?p=&APP_ID.:12:'||:app_session||':ADD:::P12_PRODUCT_ID:'|| c1.product_id)||'" class="t-Button t-Button--simple t-Button--hot"><span>Add<i class="iR"></i></span></a></td>
 </tr>');
 end loop;
 sys.htp.p('</tbody></table>');
 sys.htp.p('</div>');
 
 --
 -- display current order
 --
 sys.htp.p('<div class="Products" >');
 sys.htp.p('<table width="100%" cellspacing="0" cellpadding="0" border="0">
 <thead>
 <tr><th class="left">Current Order</th></tr>
 </thead>
 </table>
 <table width="100%" cellspacing="0" cellpadding="0" border="0">
 <tbody>');
 declare
     c number := 0; t number := 0;
 begin
 -- loop over cart values
 for c1 in (select c001 pid, c002 i, to_number(c003) p, count(c002) q, sum(c003) ep,  'Remove' remove
 from apex_collections
 where collection_name = 'ORDER'
 group by c001, c002, c003
 order by c002)
 loop
 sys.htp.p('<div class="CartItem">
 <a href="'||apex_util.prepare_url('f?p=&APP_ID.:12:&SESSION.:REMOVE:::P12_PRODUCT_ID:'||sys.htf.escape_sc(c1.pid))||'"><img src="#IMAGE_PREFIX#delete.gif" alt="Remove from cart" title="Remove from cart" /></a>  
 '||sys.htf.escape_sc(c1.i)||'
 <span>'||trim(to_char(c1.p,'$999G999G999D00'))||'</span>
 <span>Quantity: '||c1.q||'</span>
 <span class="subtotal">Subtotal: '||trim(to_char(c1.ep,'$999G999G999D00'))||'</span>
 </div>');
 c := c + 1;
 t := t + c1.ep;
 end loop;
 sys.htp.p('</tbody></table>');
 if c > 0 then
     sys.htp.p('<div class="CartTotal">
     <p>Items: <span>'||c||'</span></p>
     <p class="CartTotal">Total: <span>'||trim(to_char(t,'$999G999G999D00'))||'</span></p>
     </div>');
 else
    sys.htp.p('<div class="alertMessage info" style="margin-top: 8px;">');
      sys.htp.p('<img src="#IMAGE_PREFIX#f_spacer.gif">');
      sys.htp.p('<div class="innerMessage">');
        sys.htp.p('<h3>Note</h3>');
        sys.htp.p('<p>You have no items in your current order.</p>');
      sys.htp.p('</div>');
    sys.htp.p('</div>');
 end if;
 end;
 sys.htp.p('</div>');
 end;
 
 ```
 
 NOTE: The ELSE block (lines 70-76) executes when the user tries to move on without selecting a product in the current order. The block uses a built-in class (alertMessage info) that carries an image (f_spacer.gif) followed by the message specified on lines 73-74. In this PL/SQL code you merged some HTML elements to deliver the page in your  browser.  Before  getting  into  the  code  details,  let’s  first  acquaint ourselves with some specific terms and objects used in the PL/SQL code. Using HTML in PL/SQL Code Oracle APEX installs with your Oracle database and is comprised of data in tables  and  PL/SQL  code.  Whether  you  are  running  the  Oracle  APEX development environment or an application you built using Oracle APEX, the process is the same. Your browser sends a URL request, which is translated into an appropriate Oracle APEX PL/SQL call. After the database processes the  PL/SQL,  the  results  are  relayed  back  to  your  browser  as  HTML.  This cycle happens each time you either request or submit a page. Specific  HTML  content  not  handled  by  Oracle  APEX  (forms,  reports,  and charts) are generated using the PL/SQL region type. You can use PL/SQL to have more control over dynamically generated HTML within a region, as you do here. Let’s see how these two core technologies are used together. 
 
 htp and htf Packages:
 
 htp  (hypertext procedures) and htf (hypertext functions) are part of PL/SQL Web  Toolkit  package  to  generate  HTML  tags.  These  packages  translate PL/SQL  into  HTML  understood  by  a  web  browser.  For  instance,  the htp.anchor  procedure  generates  the  HTML  anchor  tag  a.  The  following PL/SQL block generate a simple HTML document:
 ```
 CREATE OR REPLACE PROCEDURE hello AS
 BEGIN
 htp.htmlopen;              -- generates <HTML>
 htp.headopen;             -- generates <HEAD>
 htp.title('Hello');          -- generates <TITLE>Hello</TITLE>
 htp.headclose;             -- generates </HEAD>
 htp.bodyopen;             -- generates <BODY>
 htp.header(1, 'Hello'); -- generates <H1>Hello</H1>
 htp.bodyclose;             -- generates </BODY>
 htp.htmlclose;              -- generates </HTML>
 END;
 ```
 Oracle provided the htp.p tag to allow you to override any PL/SQL-HTML procedure or even a tag that did not exist. If a developer wishes to use a new HTML tag or simply is unaware of the PL/SQL analog to the html tag, s/he can use the htp.p procedure. For every htp procedure that generates HTML tags, there is a corresponding htf function with identical parameters. The function versions do not directly generate output in your web page. Instead, they pass their output as return values to the statements that invoked them.   
 
 htp.p / htp.print: Generates the specified parameter as a string
 ```
 htp.p(‘<p>’):
 Indicates that the text coming after the tag is to be formatted as a paragraph
 <strong>Customer:</strong>:
 Renders the text they surround in bold
 htf.escape_sc:
 Escape_sc is a function, which replaces characters that have special meaning
 in HTML with their escape sequence.
 converts occurrence of & to &
 converts occurrence of “ to "
 converts occurrence of < to <
 converts occurrence of > to >
 ```
 To  prevent  XSS  (Cross  Site  Scripting)  attacks,  you  must  call SYS.HTF.ESCAPE_SC  to  prevent  embedded  JavaScript  code  from  being  executed when you inject the string into an HTML page. The SYS prefix isused to signify Oracle’s SYS schema. The HTP and HTF packages normally exist in the SYS schema and Oracle APEX relies on them. 
 
 Cursor FOR LOOP Statement
 
 The  cursor  FOR  LOOP  statement  implicitly  declares  its  loop  index  as  a record variable of the row type that a specified cursor returns and then opens a cursor. With each iteration, the cursor FOR LOOP statement fetches a row from the result set into the record. When there are no more rows to fetch, the cursor  FOR  LOOP  statement  closes  the  cursor.  The  cursor  also  closes  if  a statement  inside  the  loop  transfers  control  outside  the  loop  or  raises  an exception.
 
 The cursor FOR LOOP statement lets you run a SELECT statement and then immediately loop through the rows of the result set. This statement can use either an implicit or explicit cursor. If you use the SELECT statement only in the cursor FOR LOOP statement, then specify the SELECT statement inside the cursor FOR LOOP statement, as  in  Example  A.  This  form  of  the  cursor  FOR  LOOP  statement  uses  an implicit  cursor  and  is  called  an  implicit  cursor  FOR  LOOP  statement. 
 
 Because the implicit cursor is internal to the statement, you cannot reference it with the name SQL.
 
 Example A - Implicit Cursor FOR LOOP Statement
 ```
 BEGIN
 FOR item IN (
 SELECT last_name, job_id
 FROM employees
 WHERE job_id LIKE '%CLERK%' AND manager_id > 120
 ORDER BY last_name
 )
 LOOP
 DBMS_OUTPUT.PUT_LINE ('Name = ' || item.last_name || ', Job = ' || item.job_id);
 END LOOP;
 END;
 /
 ```
 If you use the SELECT statement multiple times in the same PL/SQL unit, define  an  explicit  cursor  for  it  and  specify  that  cursor  in  the  cursor  FOR LOOP  statement,  as  shown  in  Example  B.  This  form  of  the  cursor  FOR LOOP statement is called an explicit cursor FOR LOOP statement. You can use the same explicit cursor elsewhere in the same PL/SQL unit.
 
 Example B - Explicit Cursor FOR LOOP Statement
 ```
 DECLARE
 CURSOR c1 IS
 SELECT last_name, job_id FROM employees
 WHERE job_id LIKE '%CLERK%' AND manager_id > 120
 ORDER BY last_name;
 BEGIN
 FOR item IN c1
 LOOP
 DBMS_OUTPUT.PUT_LINE ('Name = ' || item.last_name || ', Job = ' || item.job_id);
 END LOOP;
 END;
 /
 ```
 TABLE 7-1 PL/SQL CODE EXPLAINED
 
 Display Customer Information (Lines 7-32)
 
 This procedure fetches information of the selected customer and presents it in a  desirable  format  (as  shown  in  Figure  7-27)  using  the  CSS  rules  defined under the class CustomerInfo. 
 
 Declare (Line: 1)
 
 This  is  the  parent  PL/SQL  block.  A  nested  block  is  also  used  under  the Display Current Order section on line:48.l_customer_id varchar2(30) := :P11_CUSTOMER_ID; (Line: 2) Assigns customer ID, which is retrieved from the previous order wizard step (Page  11),  to  the  variable  l_customer_id.  This  variable  is  used  in  a  SQL statement  (on  Line  No.  9)  to  fetch  details  of  the  selected  customer.  In PL/SQL, the symbol := is called the assignment operator. The variable, which is being assigned the new value, is placed on the left side of the assignment operator and the value is placed on the right side of the operator. 
 
 :P11_CUSTOMER_ID  is  called  a  bind  variable.  Bind  variables  are substituion  variables  that  are  used  in  place  of  literals.  You  can  use  bind variables  syntax  anywhere  in  Oracle  APEX  where  you  are  using  SQL  or PL/SQL to reference session state of a specified item. For example: 
 
     SELECT * FROM employees WHERE last_name like '%' || :P99_SEARCH_STRING || '%' 
 
 In this example, the search string is a page item. If the region type is defined as  SQL  Query,  then  you  can  reference  the  value  using  standard  SQL  bind variable syntax. Using bind variables ensures that parsed representations of SQL  queries  are  reused  by  the  database,  optimizing  memory  usage  by  the server. 
 
 The use of bind variables is encouraged in Oracle APEX. Bind variables help you protect your Oracle APEX application from SQL injection attacks. Bind variables work in much the same way as passing data to a stored procedure. Bind  variables  automatically  treat  all  input  data  as  “flat”  data  and  never mistake  it  for  SQL  code.  Besides  the  prevention  of  SQL  injection  attacks, there are other performance-related benefits to its use.
 
 You declare a page item as a bind variable by prefixing a colon character (:) like this:
 
 :P11_CUSTOMER_OPTIONS.
 
 When using bind variable syntax, remember the following rules:
 1. Bind variable names must correspond to an item name
 2. Bind variable names are not case-sensitive
 3. Bind variable names cannot be longer than 30 characters
 
 Although page item and application item names can be up to 255 characters, if  you  intend  to  use  an  application  item  within  SQL  using  bind  variablesyntax, the item name must be 30 characters or less. 
 
 Begin (Line: 3)  Read What is PL/SQL at the beginning of this section.
 
 The code block from line number 7 to 32 creates the first section on the page (marked as A in Figure 7-27) using div HTML element and styles it using Rule 1 and 2. The code between lines 9-20 is executed when the user selects an existing customer from the previous wizard step.
 ```
 sys.htp.p('<div class="CustomerInfo">'); (Line: 7)
 The <div> tag defines a division or a section in an HTML document. This is
 the  opening  tag,  which  references  the  CustomerInfo  class  in  CSS  rules  to
 format the following elements. The ending tag is defined on Line 32.
 for  x  in  (select  *  from  demo_customers  where  customer_id  =
 l_customer_id) loop (Line: 9)
 Initiates  the  FOR  loop  to  locate  and  fetch  record  of  the  selected  customer
 from the demo_customers table.
 sys.htp.p('<strong>Customer:</strong>'); (Line: 11)
 Displays the label “Customer:” in bold.
 sys.htp.p('<p>'); (Line: 12)
 The paragraph opening tag. It ends on Line 19.
 sys.htp.p(sys.htf.escape_sc(x.cust_first_name) || ' '
 ||sys.htf.escape_sc(x.cust_last_name) || '<br />'); (Line: 13)
 Concatenates  customer’s  first  and  last  names  using  the  concatenation
 characters (||). The <br /> tag inserts a single line break.
 sys.htp.p(sys.htf.escape_sc(x.cust_street_address1) || '<br />'); (Line: 14)
 Show customer’s first address on a new line.
 if x.cust_street_address2 is not null then  (Lines: 15-17)
 sys.htp.p(sys.htf.escape_sc(x.cust_street_address2) || '<br />');
 end if;
 It’s a condition to check whether the customer’s second address is not null. If
 it’s not, print it on a new line.
 sys.htp.p(sys.htf.escape_sc(x.cust_city)  ||  ',  '  ||
 sys.htf.escapte_sc(x.cust_state)  ||  '    '  ||sys.htf.escape_sc(x.cust_postal_code)); (Line: 18)
 Displays  city,  state,  and  postal  code  data  on  the  same  row  separating  each
 other with a comma and a blank space.
 sys.htp.p('</p>'); (Line: 19)
 The paragraph end tag.
 end loop; (Line: 20)
 The loop terminates here after fetching details of an existing customer from
 the database table.
 sys.htp.p('</div>'); (Line: 32)
 The div tag terminates here. The output of this section is illustrated in Figure
 7-27:  A  -  CustomerInfo.  The  ELSE  block  (line  22-30)  is  executed  when  a
 new  customer  is  added  to  the  database  from  the  order  interface.  In  that
 situation, all values on the current page are fetched from the previous wizard
 step (Page 11).
 Display Products (Lines: 36-42)
 Here you create a section on your web page to display all products along with
 their prices and include an option, which allows users to add products to their
 cart.
 sys.htp.p('<div class="Products" >'); (Line: 36)
 Creates a division based on the Products class. HTML elements under this
 division are styled using rules 4-9.
 sys.htp.p('<table  width="100%"  cellspacing="0"  cellpadding="0"
 border="0"> (Line: 37)
 Here you are initiating to draw an HTML table. The <table> tag defines an
 HTML  table.  An  HTML  table  consists  of  the  <table>  element  and  one  or
 more <tr>, <th>, and <td> elements. The <tr> element defines a table row,
 the <th> element defines a table header, and the <td> element defines a table
 cell. The Width attribute specifies the width of the table. Setting 100% width
 instructs  the  browser  to  consume  the  full  screen  width  to  display  the  table
 element.
 <thead> (Line: 37)
 <tr><th class="left">Product</th><th>Price</th><th></th></tr>
 </thead>The  <thead>  tag  is  used  to  group  header  content  in  an  HTML  table.  The
 <thead>  element  is  used  in  conjunction  with  the  <tbody>  and  <tfoot>
 elements to specify each part of a table (header, body, footer). The <tr> tag
 creates a row for column heading. The three <th> tags specify the headings.
 The first two columns are labeled Product and Price, respectively. The third
 column heading is left blank. A specific declaration (class=”left”) is included
 that points toward the CSS rule (9) div.Products .left{text-align:left;} to align
 the title of the first column (Product) to the left. The second column (Price) is
 styled using a general rule (6).
 <tbody>’); (Line: 37)
 The <tbody> tag is used to group the body content in an HTML table. This
 section spans up to line 41 and is marked as B in Figure 7-27.
 for  c1  in  (select  product_id,  product_name,    list_price,  'Add  to  Cart'
 add_to_order
 from demo_product_info
 where product_avail = 'Y'
 order by product_name) loop  (Line: 38)
 The  FOR  loop  fetches  Product  ID,  Product  Name,  and  List  Price  columns
 from the products table. To display a  button (Add) in the table, we appended
 a column aliased add_to_order and populated all rows with a constant value
 'Add to Cart'. For further information on FOR LOOP, see the Cursor  FOR
 LOOP Statement section earlier in this section.
 sys.htp.p('<tr><td  class="left">'
 ||sys.htf.escape_sc(c1.product_name)||'</td>
 <td>'||trim(to_char(c1.list_price,'999G999G990D00')
 || '</td>
 <td><a  href="  '||apex_util.prepare_url('f?
 p=&APP_ID.:12:'||:app_session||'
 :ADD:::P12_PRODUCT_ID:'||
 c1.product_id)||' "
 class="t-Button  t-Button--simple
 t-Button--hot">
 <span>Add<i  class="iR"></i>
 </span></a></td>
 </tr>'); (Line: 39)
 ```
 
 This  line  displays  product  names  with  respective  prices  in  two  separate columns. The product column is styled using Rule 9, while the price column is styled using Rule 6. There is an Add button in the third column of the table, which is presented as a link using the HTML anchor tag \<a> and is styled #using a built-in class (t-Button). An anchor can be used in two ways: 
 1.  To create a link to another document by using the href attribute.
 2.  To  create  a  bookmark  inside  a  document  by  using  the  name attribute.
 
 It is usually referred to as a link or a hyperlink. The most important attribute of  \<a> element is the href attribute, which specifies the URL of the page to which the link goes. When this button is clicked, the product it represents is  moved  to  the  Current  Order  section  with  the  help  of  a  process  (Add Product to the Order Collection) defined in section 7.6.7. 
 
 c1 prefix in front of column names, points to the FOR LOOP cursor. The TRIM  function  in  the  expression, trim(to_char(c1.list_price,'999G999G990D00')), takes a character expression and  returns  that  expression  with  leading  and/or  trailing  pad  characters removed.  This  expression  initially  formats  the  list  price  column  to  add thousand separators and decimal place.  Next, it converts the numeric price value to text expression using the TO_CHAR function and finally applies the TRIM function. The TO_CHAR function converts a DATETIME, number, or NTEXT  expression  to  a  TEXT  expression  in  a  specified  format.  The  table that  follows  lists  the  elements  of  a  number  format  model  with  some examples.
 
 Element Example Description  
 
 0 0999 Returns leading zeros.
 
 9990 Returns trailing zeros.
 
 9 9999 Returns value with the specified number of digits with a leading space if positive or with a leading minus if negative. Leading zeros are blank, except for a zero value, which returns a zero for the integer part of the fixed-point number.
 
 D 99D99 Returns  in  the  specified  position  the  decimal  character,  which  is  the current  value  of  the  NLS_NUMERIC_CHARACTER  parameter.  The default is a period (.).G 9G999 Returns the group separator (which is usually comma) in the specified position. You can specify multiple group separators in a number format model. Use the following SQL statement to check the current value for decimal and group separator characters:
 ```
 SELECT value FROM v$nls_parameters
 WHERE parameter='NLS_NUMERIC_CHARACTERS';
 The code,
 <a href="'||apex_util.prepare_url('f?p=&APP_ID.:12:'||:app_session||':ADD:::P12_PRODUCT_ID:'||
 c1.product_id)||'" class="t-Button t-Button--simple t-Button--hot"> <span>Add<iclass="iR"></i>
 </span></a>,
 ```
 creates a link with an ADD request. The value of REQUEST is the name of the  button  the  user  clicks.  For  example,  suppose  you  have  a  button  with  a name of CHANGE and a label Apply Changes. When a user clicks the button, the  value  of  REQUEST  is  CHANGE.  In  section  7.6.7,  you  will  create  the following process named Add Product to the order collection.
 ```
 for x in (select p.rowid, p.* from demo_product_info p where product_id=:P12_PRODUCT_ID)
 loop
 select count(*)
 into l_count
 from wwv_flow_collections
 where collection_name = 'ORDER'
 and c001 =  x.product_id;
 if l_count >= 10 then
 exit;
 end if;
 apex_collection.add_member(p_collection_name => 'ORDER',
 p_c001 => x.product_id,
 p_c002 => x.product_name,
 p_c003 => x.list_price,
 p_c004 => 1,
 p_c010 => x.rowid);
 end loop;
 ```
 During the process creation, you’ll select Request=Value in Condition Type and will enter ADD for Value. The ADD request in the \<a> tag is referencing the same expression. When a user clicks the ADD button on the web page, the  URL  sends  the  ADD  request  to  the  process  along  with  the  selected product ID using a hidden item named P12_PRODUCT_ID to be created in section  7.6.4.  In  turn,  the  process  adds  the  product  to  the  Current  Order section.  The  URL  generated  from  this  code  looks  something  like  this  at runtime:
 ```
 f?p=18132:12:13238397476902:ADD:::P12_PRODUCT_ID:10end loop; (Line: 40)
 End of FOR loop.
 sys.htp.p('</tbody></table>'); (Line: 41)
 Table and body closing tags.
 sys.htp.p('</div>'); (Line: 42)
 The closing div tag.
 
 Display Current Order (Lines: 46-79)
 This  section  acts  as  a  shopping  cart.  The  products  selected  by  a  user  are
 placed in this section.
 sys.htp.p('<div class="Products" >'); (Line: 46)
 Defines the <div> tag and utilizes the Products class referenced in rules 4-9.
 sys.htp.p('<table  width="100%"  cellspacing="0"  cellpadding="0"
 border="0">
 <thead>
 <tr><th class="left">Current Order</th></tr>
 </thead>
 </table> (Line: 47)
 
 Displays section heading as follows in the first row of a separate table.
 Declare (Line: 48)
 This is a nested or child block. To nest a block means to embed one or more
 PL/SQL  block  inside  another  PL/SQL  block  to  have  better  control  over
 program’s execution.
 c number := 0; t number := 0; (Line: 49)
 Declared two numeric counter variables and initialized them with zero. The
 variable c is used to evaluate whether any product is selected in the current
 order, while the variable t stores total value for the order.
 Begin (Line: 50)
 for  c1  in  (select  c001  pid,  c002  i,  to_number(c003)  p,  count(c002)  q,
 sum(c003) ep,  'Remove' remove
 from apex_collections
 where collection_name = 'ORDER'group by c001, c002, c003
 order by c001)
 loop (Line: 52)
 ```
 
 APEX Collection enables you to temporarily capture one or more non-scalar values.  You  can  use  collections  to  store  rows  and  columns  currently  in session  state  so  they  can  be  accessed,  manipulated,  or  processed  during  a user’s specific session. You can think of a collection as a bucket in which you temporarily store and name rows of information. Every collection contains a named list of data elements (or members), which can have up to 50 character properties (varchar2 (4000)), 5 number, 5 date, 1 XML type, 1 BLOB, and 1 CLOB attribute. You insert, update, and delete collection information using the PL/SQL API APEX_COLLECTION. 
 
 When  you  create  a  new  collection,  you  must  give  it  a  name  that  cannot exceed 255 characters. Note that collection names are not case-sensitive and will be converted to uppercase. Once the collection is named, you can access the  values  (members  of  a  collection)  in  the  collection  by  running  a  SQL query against the database view APEX_COLLECTIONS.
 
 The APEX_COLLECTIONS view has the following definition:
 ```
 COLLECTION_NAME    NOT NULL VARCHAR2(255)
 SEQ_ID             NOT NULL NUMBER
 C001               VARCHAR2(4000)
 C002               VARCHAR2(4000)
 C003               VARCHAR2(4000)  
 C004               VARCHAR2(4000)  
 C005               VARCHAR2(4000)
 ...
 C050               VARCHAR2(4000)
 N001               NUMBER
 N002               NUMBER
 N003               NUMBER
 N004               NUMBER
 N005               NUMBER    
 CLOB001            CLOB
 BLOB001            BLOB
 XMLTYPE001         XMLTYPEMD5_ORIGINAL       VARCHAR2(4000)
 ```
 Use the APEX_COLLECTIONS view in an application just as you would use any other table or view in an application, for example: 
 ```
 SELECT c001, c002, c003, n001, clob001  
 FROM APEX_collections
 WHERE collection_name = 'DEPARTMENTS'
 ```
 The  CREATE_OR_TRUNCATE_COLLECTION  method  creates  a  new collection  if  the  named  collection  does  not  exist.  If  the  named  collection already exists, this method truncates it. Truncating a collection empties it, but leaves it in place. 
 
 In  section  7.5.12,  we  created  a  process  named  Create  or  Truncate  Order Collection under the page rendering section and used the following statement to create a collection named ORDER:
 
     apex_collection.create_or_truncate_collection (p_collection_name => 'ORDER');
 
 In  the  “For  C1  in”  loop,  we’re  selecting  records  from  the  same  ORDER collection.  Columns  from  apex_collections  in  the  SELECT  statement correspond to:
 ```
 Column Corresponds To
 C001 – pid Product ID (9)
 C002 – i Product Name (Men Shoes)
 C003 – p List Price (110)
 C002 - q Quantity (1)
 C003 - ep Extended Price (110) This value will increase with each Add button click to accumulate total cost of a product.
 
 sys.htp.p('<div class="CartItem"> (Line: 53)
 This line references another class (CartItem) to style the actual Current Order
 section.
 <a href="'||apex_util.prepare_url('f?
 p=&APP_ID.:12:&SESSION.:REMOVE:::P12_PRODUCT_ID:'||sys.htf.
 <img src="#IMAGE_PREFIX#delete.gif" alt="Remove from cart"
 title="Remove from cart" />
 </a>   (Line: 54)
 ```
 \<a>  tag  creates  a  link  with  a  REMOVE  request.  This  time,  it  usesproduct ID from the collection. In section 7.6.7 (B), there is a process named
 
 Remove  product  from  the  Order  Collection  (as  shown  below)  where  the request expression is set to REMOVE.
 ```
 for x in
 (select seq_id, c001 from apex_collections
 where collection_name = 'ORDER' and c001 = :P12_PRODUCT_ID)
 loop
 apex_collection.delete_member(p_collection_name => 'ORDER', p_seq => x.seq_id);
 end loop;
 ```
 In  HTML,  images  are  defined  with  the  \<img>  tag.  The  \<img>  tag  has  no closing tag. To display an image on a page, you need to use the src attribute. 
 
 Src stands for "source". The value of the src attribute is the URL of the image you want to display.
 
 Syntax for defining an image:
      <img src="url" alt="some_text"/>
 
 The  URL  points  to  the  location  where  the  image  is  stored.  The  value  of IMAGE_PREFIX determines the virtual path the web server uses to point to the images directory distributed with Oracle APEX. We used “delete.gif” that is displayed in front of the product name. The required alt attribute specifies an alternate text for an image, if the image cannot be displayed. When a user clicks the remove link [X] in the Current Order section, the URL sends  a  REMOVE  request  to  the  process  along  with  the  product  ID.  The DELETE_MEMBER  procedure  deletes  a  specified  member  from  a  given named  collection  using  the  p_seq  =>  x.seq_id  parameter,  which  is  the sequence ID of the collection member to be deleted.
 ```
 '||sys.htf.escape_sc(c1.i)||' (Line: 55)
 Displays name of the selected product in the Current Order section.  
 <span>'||trim(to_char(c1.p,'$999G999G999D00'))||'</span> (Line: 56)
 <span>Quantity: '||c1.q||'</span> (Line: 57)
 <span class="subtotal">Subtotal:
 '||trim(to_char(c1.ep,'$999G999G999D00'))||'</span> (Line: 58)
 The three lines display price, quantity, and sub-total of the selected product in
 the Current Order section, as shown below:</div>'); (Line: 59)
 The ending div tag.
 c := c + 1; (Line: 60)
 This counter increments the value of c with 1 at the end of each loop. The
 variable c is used to calculate number of items selected in the current order.
 t := t + c1.ep; (Line: 61)
 Similar  to  the  variable  c,  t  is  also  incremented  to  sum  up  extended  price
 (c1.ep) to calculate total order value.
 
 if c > 0 then
 sys.htp.p('<div class="CartTotal">
 <p>Items: <span>'||c||'</span></p>
 <p class="CartTotal">Total:
 <span>'||trim(to_char(t,'$999G999G999D00'))||'</span></p>
 </div>');
 else
    sys.htp.p('<div class="alertMessage
 info" style="margin-top: 8px;">');
 sys.htp.p('<img src="#IMAGE_PREFIX#f_spacer.gif">');
        sys.htp.p('<div class="innerMessage">');
 sys.htp.p('<h3>Note</h3>');
 sys.htp.p('<p>You have no items in your current order.</p>');
        sys.htp.p('</div>');
    sys.htp.p('</div>');
 end if;
 ```
 (Line: 64-77) The condition (IF c > 0) evaluates whether a product is selected in the current order.  A  value  other  than  zero  in  this  variable  indicates  addition  of product(s). If the current order has some items added, the label Total: along with the value is displayed, which is stored in the variable t. If no items are selected, the message defined in the else block is shown using a couple of built-in classes.
 
 
 ### 7.6.4 Create Hidden Item
 Create  a  hidden  item  in  the  Select  Items  region.  When  you  click  the  Add button  on  Page  12  to  add  a  product  to  an  order,  the  ID  of  that  product  is stored in this hidden item using a URL specified in the PL/SQL code on line 39.
 
 Property  Value
 1. Name P12_PRODUCT_ID
 2. Type Hidden
 
 
 ### 7.6.5 Create Region to hold Buttons
 Right-click  the  Wizard  Buttons  node  and  select  Create  Region.  Enter Buttons  for  the  Title  of  this  region  and  set  its  Template  to  Buttons Container. The region will hold three buttons: Cancel, Previous, and Next. These buttons are created in the next section.
 
 
 ### 7.6.6 Create Buttons
 All the three buttons created in this section have one thing in common, the Action property, which is set to Submit Page. When you click any of these three buttons, the page is submitted and a corresponding branch (to be created in section 7.6.9) is fired to take you to the specified location. For example, if you click the Cancel button, the corresponding branch takes you back to the main  Orders  page  (Page  4).  Right-click  the  new  Buttons  region  and  select Create Button. Set the following properties for the new button:  
 
 Property Value
 1. Button Name CANCEL
 2. Label Cancel
 3.  Button Position Close
 4.  Action Submit Page 
 
 Create another button under the Cancel button and set the following properties:
 
 Property Value
 1. Button Name PREVIOUS
 2. Label Previous
 3. Button Position Previous
 4. Button Template Icon
 5. Icon fa-chevron-left
 6. Action Submit Page
 
 Create the final button under the Previous button and set the following properties:
 
 Property Value
 1. Button Name NEXT
 2. Label Place Order
 3. Button Position Next
 4. Button Template Text with Icon
 5. Hot On
 6. Icon fa-chevron-right
 7. Action Submit Page
 
 
 ### 7.6.7 Create Processes
 The two processes created in this section handle the routine to either add a product  to  the  Current  Order  section  or  remove  one  from  it.  The add_member  function  references  the  collection  (ORDER  created  in  section 7.5.12) to populate the collection with a new product. In Table 7-1, the link defined on line 39 in the PL/SQL code forwards an ADD request, which is entertained here after evaluating the request in step 4 below. 
 
 A. Add Product to the Order Collection
 1.  On  Page  12,  expand  the  Pre-Rendering  node  (on  the  Rendering tab) and create a process under Before Header node.
 2.  Enter Add Product to the ORDER Collection for the name of this new process and set its Type to PL/SQL Code.Figure 7-28
 3.  Enter the following code in the PL/SQL Code box. Locate this code under BookCode\Chapter7\7.6.7A.txt file.
 ```
 declare
   l_count number := 0;
 begin
 for x in (select p.rowid, p.* from demo_product_info p where product_id = :P12_PRODUCT_ID)
 loop
   select count(*) 
   into l_count
   from wwv_flow_collections
   where collection_name = 'ORDER'
   and c001 =  x.product_id;
   if l_count >= 10 then
     exit;
   end if;
   apex_collection.add_member(p_collection_name => 'ORDER', 
     p_c001 => x.product_id, 
     p_c002 => x.product_name,
     p_c003 => x.list_price,
     p_c004 => 1,
     p_c010 => x.rowid);
 end loop;
 end;
 ```
 4.  In Server-side Condition section, set Type to Request=Value, and enter ADD in the Value property box.
 
 B. Remove Product from the Order Collection
 
 The delete_member function is just opposite to the add_member function. It is called by a link (Table 7-1 line 54), which carries a REMOVE request. Therequest  is  evaluated  by  a  condition  set  in  Step  3  below.  If  the  request matches, the selected product is deleted from the ORDER collection.
 1.  Create another process under the previous one. Name it Remove Product from the ORDER Collection and set its Type to PL/SQL Code.
 2.  Enter  the  following  code  in  the  PL/SQL  Code  property  box.  Get this code from BookCode\Chapter7\7.6.7B.txt file.
 ```
 for x in 
   (select seq_id, c001 from apex_collections 
     where collection_name = 'ORDER' and c001 = :P12_PRODUCT_ID)
 loop
 apex_collection.delete_member(p_collection_name => 'ORDER', p_seq => x.seq_id);
 end loop;
 ```
 3.  In Server-side Condition section, set Type to Request=Value, and enter REMOVE in the Value property box.
 
 ### 7.6.8 Create Process - Place Order
 After selecting products for an order, you click the Next button. The process defined  in  this  section  is  associated  with  this  button.  The  PL/SQL  code  specified in this process adds new customer and order information in relevant database tables using a few SQL INSERT statements. After committing the DML statement, the process truncates the ORDER collection. 
 1.  On the Processing tab, create a new process under the Processing node.Figure 7-29
 2.  Enter Place Order    for  the  name  of  this  new  process  and  set  its Type to PL/SQL  Code.  Enter  the  following  code  in  the  PL/SQL Code box. Also, select NEXT for When Button Pressed property. The code is stored under BookCode\Chapter7\7.6.8.txt file.
 ```
 declare
     l_order_id    number;
     l_customer_id varchar2(30) := :P11_CUSTOMER_ID;
 begin
     
     -- Create New Customer
     if :P11_CUSTOMER_OPTIONS = 'NEW' then
         insert into DEMO_CUSTOMERS (
             CUST_FIRST_NAME, CUST_LAST_NAME, CUST_STREET_ADDRESS1,
             CUST_STREET_ADDRESS2, CUST_CITY, CUST_STATE, CUST_POSTAL_CODE,
             CUST_EMAIL, PHONE_NUMBER1, PHONE_NUMBER2, URL, CREDIT_LIMIT, TAGS)
         values (
             :P11_CUST_FIRST_NAME, :P11_CUST_LAST_NAME, :P11_CUST_STREET_ADDRESS1,
             :P11_CUST_STREET_ADDRESS2, :P11_CUST_CITY, :P11_CUST_STATE,
             :P11_CUST_POSTAL_CODE, :P11_CUST_EMAIL, :P11_PHONE_NUMBER1,
             :P11_PHONE_NUMBER2, :P11_URL, :P11_CREDIT_LIMIT, :P11_TAGS)
         returning customer_id into l_customer_id;
         :P11_CUSTOMER_ID := l_customer_id;
     end if;
 
     -- Insert a row into the Order Header table
     insert into demo_orders(customer_id, order_total, order_timestamp, user_name) 
     values  (l_customer_id, null, systimestamp, upper(:APP_USER)) 
     returning order_id into l_order_id;
     commit;
 
     -- Loop through the ORDER collection and insert rows into the Order Line Item table
     for x in (select c001, c003, sum(c004) c004 from apex_collections 
                where collection_name = 'ORDER' group by c001, c003) loop
        insert into demo_order_items(order_item_id, order_id, product_id, unit_price, quantity)
        values (null, l_order_id, to_number(x.c001), to_number(x.c003),to_number(x.c004));
     end loop;
     commit;
 
     -- Set the item P14_ORDER_ID to the order which was just placed
     :P14_ORDER_ID := l_order_id;
 
     -- Truncate the collection after the order has been placed
     apex_collection.truncate_collection(p_collection_name => 'ORDER');
 end;
 ```
 
 
 ### 7.6.9 Create Branches
 Create the following three branches under the After Processing node on the Processing  tab.  The  buttons  referenced  in  these  branches  were  created  in section 7.6.6.
 
 Property Value
 1. Name Go To Page 14
 2. Type  (under Behavior) Page or URL (Redirect)
 3. Target   Type = Page in this Application  Page = 14
 4. When Button Pressed NEXT
 
 Property Value
 1. Name Go To Page 4
 2. Type  (under Behavior) Page or URL (Redirect)
 3. Target Type = Page in this Application Page = 4
 4. When Button Pressed CANCEL
 
 Property Value
 1. Name Go To Page 11
 2. Type  (under Behavior) Page or URL (Redirect)
 3. Target  Type = Page in this Application   Page = 11
 4. When Button Pressed PREVIOUS
 
 Test Your Work
 
 Navigate to the Orders page using the main menu route and click the Enter New  Order  button.  Select  a  customer  using  the  Existing  Customer  option and click Next. Click the Add button next to Air Jordan 6 shoes to add this product  to  the  Current  Order  pane.  Click  the  Add  button  again  for  this product and see increase in Quantity and Total. Add some more products and observe the change in the Current Order section. Click the cross sign   to remove a product from the Current Order section. Click Cancel to return to Page 4 without saving the order.
 
 ## 7.7 Create Order Summary Page - Page 14
 After adding products to the Order form, you click the Place Order button.
 The  next  page,  Order  Summary,  comes  up  to  show  details  of  the  placed
 order. In this section, you will create this page. It is the last step in the order
 creation wizard.
 1.  Create one more Blank Page.
 2.  Complete the first wizard step as show in the following figure and
 click Next.
 3.  On  the  Navigation  Menu  screen,  set  Navigation  Preference  to
 Identify an existing navigation menu entry for this page, and set
 Existing Navigation Menu Entry to Orders. Click Next.
 4.  Click Finish to end the wizard.
 5.  Click the root node (Page 14: Order Summary) and set Dialog
 Template to Wizard Modal Dialog.
 
 ### 7.7.1 Create Region – Order Progress
 Right-click the Wizard Progress Bar node and select Create Region. Set following properties for the new region.
 
 Property Value
 1. Title Order Progress
 2. Type List
 3. List Order Wizard
 4. Template Blank with Attributes
 5. List Template  (under Attributes node) Wizard Progress
 
 ### 7.7.2 Create Region – Order Header
 Right-click  the  Wizard  Body  node  and  select  Create  Region.  Set  the following  properties  for  this  region.  Just  like  section  7.6.3,  you  define  the  region as PL/SQL Dynamic Content, which is based on PL/SQL that enables you to render any HTML or text.
 
 Property Value
 1. Title Order Header
 2. Type PL/SQL Dynamic Content
 3. PL/SQL Code
 ```
 begin
 for x in (
      select c.cust_first_name, c.cust_last_name, cust_street_address1,
          cust_street_address2, cust_city, cust_state, cust_postal_code from demo_customers c, demo_orders o
      where c.customer_id = o.customer_id and o.order_id = :P14_ORDER_ID
 ) 
 loop
    htp.p('<span style="font-size:16px;font-weight:bold;">ORDER #' ||sys.htf.escape_sc(:P14_ORDER_ID) || '</span><br />');
    htp.p(sys.htf.escape_sc(x.cust_first_name) || ' ' ||sys.htf.escape_sc(x.cust_last_name) || '<br />');
    htp.p(sys.htf.escape_sc(x.cust_street_address1) || '<br />');
    
    if x.cust_street_address2 is not null then
       htp.p(sys.htf.escape_sc(x.cust_street_address2) || '<br />');
    end if;
    htp.p(sys.htf.escape_sc(x.cust_city) || ', ' || sys.htf.escape_sc(x.cust_state) || '  ' ||sys.htf.escape_sc(x.cust_postal_code) || '<br /><br />');
 end loop;
 end;
 ```
 
 ### 7.7.3 Create Region – Order Lines
 Add  another  region  under  the  Wizard  Body  node  and  set  the  following properties for this region. After creating this region expand its Columns node and  set  suitable  heading  for  each  column.  This  region  will  carry  line  item information. 
 
 Property Value
 1. Title Order LinesType Classic Report
 2. Location Local Database
 3. Type SQL Query
 4.  SQL Query
 ```
 select p.product_name, oi.unit_price, oi.quantity, (oi.unit_price * oi.quantity) extended_price  
 from demo_order_items oi, demo_product_info p
 where oi.product_id = p.product_id and oi.order_id = :P14_ORDER_ID
 ```
 
 
 ### 7.7.4 Create Item
 Right-click  the  Order  Lines  region  and  select  Create  Page  Item.  Set  the
 following properties for the new item. The value for this item was set in the
 PL/SQL code defined in section 7.6.8 and was utilized in the codes defined in
 section 7.7.2 and in section 7.7.3 to fetch order information.
 Property Value
 Name P14_ORDER_ID
 Type Hidden
 7.7.5 Create Region – Buttons
 Right-click  the  Wizard  Buttons  node  and  select  Create  Region.  Enter
 Buttons for its Name and set its Template to Buttons Container. The region
 will hold the following button.
 7.7.6 Create Button
 Right-click the new Buttons region node and select Create Button. Set the
 following properties for the new button:
 Property Value
 Button Name BACK
 Label Back To Orders
 Button Position Next
 Hot On
 Action Redirect to Page in this Application
 Target
 Type = Page in this application
 Page = 4
 7.7.7 Create Trigger
 As the final step of this module, add the following trigger to your schema.
 The trigger will fire to write order total to the DEMO_ORDERS table when
 any order item is changed.1.  From the main Oracle APEX menu, select SQL Workshop | SQL
 Commands.
 Figure 7-31
 2.  In the SQL Commands interface, enter the code for the new trigger
 named DEMO_ORDER_ITEMS_AIUD_TOTAL, as illustrated in
 the following figure, and hit the Run button. The trigger will  be
 created  and  you  will  see  a  confirmation  on  the  Results  tab.  The
 code  for  this  trigger  is  available  in  BookCode\Chapter7\7.7.7.txt
 file.Figure 7-32
 Complete Testing
 Congratulation!  You  have  completed  the  most  tiresome  but  interesting
 chapter of the book in which you learned numerous techniques. Now you are
 in a position to test the whole work you performed in this chapter.
 1.  Select Orders from the main navigation menu and then click the
 Enter New Order button.
 2.  Select New Customer.
 3.  Fill in the New Customer form using your own name,  address,
 and so on. Click Next to proceed.
 4.  On the Select Items page add some products to the Current Order
 pane.
 5.  Click the Place Order button to see the Order Summary page, as
 illustrated in figure 7-33.Figure 7-33 Order Summary Page
 NOTE: You might encounter a primary key violation message (ORA-00001:
 unique  constraint  (DEMO_ORDERS_PK)  violated)  while  creating  first
 product record. This is because the Sequence object for this table is created
 with an initial value of 1. Keep clicking the Place Order button unless the
 record is saved.
 6.  Click the Back To Orders button in the Order Summary page to
 return to the orders main page. The newly created order will appear
 in the orders list.
 7.  Click the number of the new order to modify it in Order  Details
 page (Page 29). Try to add or remove products on this page and
 save your modifications.8.  Also, try the delete operation by deleting this new order.
 
 ## 7.8 Sending Email from Oracle APEX Application
 You  can  use  the  APEX_MAIL  package  to  send  an  email  from  an  Oracle
 Application Express application. This package is built on top of the Oracle
 supplied UTL_SMTP package. Because of this dependence, the UTL_SMTP
 package must be installed and functioning to use APEX_MAIL. Since we are
 using the online APEX version, this package is already configured and we
 can  give  it  a  test  run.  In  this  section  we  are  going  to  send  an  order
 confirmation  email  to  customers,  whose  emails  exists  in  the
 DEMO_CUSTOMERS  table.  The  email  will  contain  a  link  to  access  the
 placed order.
 1.  Open  Page  12  (Order  Items)  and  create  a  new  process
 under the Place Order process. Set the attributes for this
 new process as shown on the next page. The PL/SQL code
 for this process is provided in BookCode\Chapter7\7.8.txt
 file.
 The PL/SQL code starts with the declaration of some variables. You can
 use  VARCHAR  type  for  Vbody  and  Vbody_html  variables.  Passing
 values to these variables yield a multi-part message that includes both
 plain  text  and  HTML  content.  The  settings  and  capabilities  of  the
 recipient's email client determine what displays. Although most modern
 email clients can read an HTML formatted email, remember that some
 users disable this functionality to address security issues. On line 7 we
 fetch  email  address  of  the  ordering  customer,  and  on  line  8  we  store
 customer name in a variable. The CSS code defined on line 10 formats
 different parts of the email. Line 11 creates the greeting line, while line
 12 forms a paragraph containing a link to the customer order. The order
 is displayed on Page 30 of the application. Remember, you must include
 a carriage return or line feed (CRLF) every 1000 characters because the
 SMTP/MIME  specification  dictates  that  no  single  line  shall  exceed
 1000 characters. We used utl_tcp.crlf for the same purpose. Finally, the
 APEX_MAIL.SEND procedure sends an outbound email message. The
 following table describes the parameters used in this SEND procedure.
 Parameter Descriptionp_to (required) Valid email address to which the email is sent. For multiple email
 addresses, use a comma-separated list.
 p_from
 (required)
 Email address from which the email is sent. This email address must
 be a valid address. Otherwise, the message is not sent.
 p_body
 (required)
 Body of the email in plain text. If a value is passed to p_body_html,
 then this is the only text the recipient sees. If a value is not passed to
 p_body_html, then this text only displays for email clients that do
 not support HTML or have HTML disabled. A carriage return or line
 feed (CRLF) must be included every 1000 characters.
 p_body_html Body of the email in HTML format.
 p_subj Subject of the email.
 Property     Value
 Name          Send Confirmation Email
 Type PL/SQL Code
 PL/SQL Code
 ```
 DECLARE
     Vbody CLOB;
     Vbody_html CLOB;
     Vcust_email varchar2(100);
     Vcust_name varchar2(100);
 BEGIN
     select cust_email into Vcust_email from DEMO_CUSTOMERS 
     where customer_id = :P11_CUSTOMER_ID;
     select CUST_FIRST_NAME into Vcust_name from DEMO_CUSTOMERS 
     where customer_id = :P11_CUSTOMER_ID;
     Vbody := 'To view the content of this message, please use an HTML enabled mail client.'||utl_tcp.crlf;
 
     Vbody_html := '<html>
         <head>
             <style type="text/css">
                 body{font-family: Arial, Helvetica, sans-serif; font-size:10pt;margin:30px;
                      background-color:#ffffff;}
                 span.sig{font-size: 20px; font-weight:bold; color:#811919;}
              </style>
          </head>
          <body>'||utl_tcp.crlf;
       
     Vbody_html := Vbody_html || 'Hi '|| Vcust_name ||','||utl_tcp.crlf||utl_tcp.crlf;
     Vbody_html := Vbody_html ||'<p> Your order has been confirmed which you can access by clicking <a href="'||APEX_UTIL.HOST_URL('SCRIPT')||'f?p='||:APP_ID|| ':30'||':0::::P30_ORDER_ID:'||:P14_ORDER_ID ||'"> here. </a></p>' ||utl_tcp.crlf;
         
     Vbody_html := Vbody_html ||'<p>  Regards,</p>'||utl_tcp.crlf;
     Vbody_html := Vbody_html ||'  <span class="sig">Sales Team</span><br />'||utl_tcp.crlf;
     apex_mail.send(
     p_to   => Vcust_email,   
     p_from => 'sales@abc.com', 
     p_body      => Vbody,
     p_body_html => Vbody_html,
     p_subj      => 'Order Confirmation');
 END;
 ```
 Success
 Message
 Order confirmation email sent to customer
 Error Message There was some problem in sending email
 When Button
 Pressed
 NEXT
 When a customer clicks the link in the email, he is routed to Page 30 (after
 providing his credentials on the sign in page) to see his order. This page will
 be  created  by  making  a  copy  of  Page  29.  There  are  a  couple  of  default
 security setting on this page that we need to change as well to allow access to
 the order.
 2.  Open  Page  29  in  Page  Designer.  From  the  Create  menu,  select
 Page as Copy – see section 7.5. Enter 30 for New Page Number
 and  Customer  Order  for  New  Page  Name.  On  the  Navigation
 Menu screen, select Identify an existing navigation menu entry
 for  this  page,  and  select  Orders  for  Existing  Navigation  Menu
 Entry.
 3.  Open Page 29 (Order Details) and click the root node. Scroll down
 to the Security section, and set Page Access Protection attribute to
 Unrestricted. This value is set for a page that is requested using a
 URL,  with  or  without  session  state  arguments,  and  having  nochecksum.
 4.  Delete all six buttons and their regions from Page 30.
 5.  Next, click the P30_ORDER_ID page item located under Wizard
 Body  |  Order  #&P30_ORDER_ID.  region.  Set  Session  State
 Protection under Security to Unrestricted. By setting this value the
 item's value can be set by passing the item in a URL or in a form
 and no checksum is required in the URL.
 All is set. Modify a customer record by entering your email account. Create a
 new  order  for  this  customer.  After  clicking  the  Place  Order  button  on  the
 second wizard screen, you will see the message “ Order  confirmation  email  sent  to
 customer. ”  Log  out  from  the  application.  After  a  while,  you  will  receive  an
 order confirmation email in your email account. Click the “ here ” link in the
 email  that  will  take  you  to  the  application  login  page.  Immediately  after
 providing  your  credentials,  the  copied  order  details  page  (Page  30)  will
 appear on your screen displaying the order you just entered.
 NOTE: If you get “Your session has expired. Please close this dialog and
 press your browser's reload button to obtain a new session.” message, then
 open Page 30, click its root node, and set Page Mode to Normal.
 
 ## 7.9 A More Simple Approach
 I  know  as  a  beginner  you  might  be  confused  with  the  stuff  described  in
 section  7.5  onward.  I  added  this  stuff  purposely  to  present  something  that
 would be helpful to you in your future endeavors. However, in this section
 I’ll demonstrate a simpler approach to add, modify, and delete orders using
 just one interface.
 1.  Execute  all  the  steps  mentioned  in  section  7.2  to  create  the  two
 master and details pages. In step 4, set number of the Master Page
 to 404, and number of the Details Page to 429.
 NOTE: Make the Interactive Grid visible on the Order Details page (Page
 429), as instructed at the end of section 7.2.
 2.  Open  Page  404  and  execute  the  instructions  provided  in  section
 7.3.1.  In  step  5  of    section  7.3.1,  set  Page  and  Clear  Cacheproperties to 429 to point to the correct page number and set the
 Name  property  to  P429_ORDER_ID.  Skip  the  optional  report
 sections  (spanning  from  7.3.2  to  7.3.4)  at  this  stage  to  preserve
 some time.
 3.  Set  the  following  attributes  for  the  CREATE  button.  Note  that
 previously  this  buttons  was  used  to  initiate  the  order  wizard  by
 calling Page 11. Here, we are calling Page 429 to directly enter a
 new order.
 Property Value
 Button Name CREATE
 Label Enter New Order
 Button Template Text with Icon
 Hot On
 Icon fa-chevron-right
 Action Redirect to Page in this Application
 Target
 Type = Page in this Application
 Page = 429
 Clear Cache = 429
 4.  Save Page 404.
 5.  In the Page Finder box, enter 429 and press the Enter key to call
 Page 429 in the Page Designer.
 6.  Click  the  root  node  (Page  429:  Order  Details)  and  set  the  Page
 Mode property to Modal Dialog. Set Width, Height, and Maximum
 Width  properties  to  900,  800,  and  1200,  respectively.  Also,  set
 Dialog  Template  (in  the  Appearance  section)  to  Wizard  Modal
 Dialog.
 7.  Edit  the  following  items  individually  and  set  the  corresponding
 properties  shown  under  each  item.  The  customer  ID  item,  which
 was displayed as  Display Only item in the previous method, will
 now  be  rendered  as  a  Select  List  carrying  the  names  of  all
 customers. The SQL query defined for the Select List automatically
 shows  the  correct  customer  name  when  you  navigate  from  oneorder to another.
 P429_CUSTOMER_ID
 Property Value
 Type Select List
 Label Customer
 Type  (List of Values) SQL Query
 SQL Query
 select cust_first_name ||' '|| cust_last_name d, customer_id r 
 from demo_customers
 P429_USER_NAME
 Property Value
 Type Select List
 Label Sales Rep
 Type  (List of Values) SQL Query
 SQL Query
 select distinct user_name d, user_name r
 from demo_orders
 union
 select upper(:APP_USER) d, upper(:APP_USER) r
 from dual
 order by 1
 Display Extra Values Off
 Display Null Value Off
 Help Text Use this list to change the Sales Rep associated with the order.
 8.  In the Region Buttons node, set Button  Position  property  to  Edit
 for GET_PREVIOUS_ORDER_ID and GET_NEXT_ORDER_ID
 buttons to place them on top of the region.
 9.  Click the Order Details interactive grid region. Set its Source Type
 to  SQL  Query,  and  replace  the  default  query  with  the  one  that
 follows:
 select oi.order_item_id, oi.order_id, oi.product_id,
 pi.product_name, oi.unit_price,
 oi.quantity, (oi.unit_price * oi.quantity) extended_price
 from DEMO_ORDER_ITEMS oi, DEMO_PRODUCT_INFO piwhere oi.ORDER_ID = :P429_ORDER_ID
 and oi.product_id = pi.product_id (+)
 10.  Under  the  Columns  node,  edit  the  following  columns  using  the
 specified properties and values.
 Column Property Value
 PRODUCT_ID
 Type
 Heading
 Alignment
 Type  (LOV)
 List of Values
 Display Null Value
 Select List
 Product
 left
 Shared Components
 Products With Price
 Off
 PRODUCT_NAME Type Hidden
 QUANTITY
 Width  (Appearance)
 Type  (Default)
 PL/SQL Expression
 5
 PL/SQL Expression
 1   (sets 1 as the default q
 EXTENDED_PRICE
 Type
 Heading
 Alignment
 Column Alignment
 Format Mask
 Query Only ( Source )
 Display Only
 Price
 right
 right
 $5,234.10
 On
 11.  Right-click the Wizard Buttons node and select Create Region. Set
 Title  of  the  new  region  to  Buttons  and  Template  to  Buttons
 Container. In Regions Buttons node, click the Cancel button and
 set its Region property (under Layout) to Buttons. Set this region
 for Delete, Save, and Create buttons, too. This action will place all
 the four buttons under the Buttons region.
 12.  Open Page 429 in the Page Designer. On the Processing tab make
 sure that the Process form Form on DEMO_ORDERS sits before
 the Order Details - Save Interactive Grid Data process.
 13.  Click the Save Interactive Grid Data process and switch its Type
 from  Interactive  Grid  -  Automatic  Row  Processing  (DML)  to
 PL/SQL Code. Enter the following code in the PL/SQL Code box.
 In this code, you specify SQL Insert, Update, and Delete statements
 to  manually  handle  the  three  operations  for  the  Interactive  Griddata.  The  :APEX$ROW_STATUS  is  a  built-in  substitution  string,
 which is used to refer to the row status in an Interactive Grid. This
 placeholder returns the status of C if created, U if updated, or D if
 deleted for the currently processed interactive grid row. Enter "The
 DML operation performed successfully" in the Success Message
 box. Similarly, enter "Could not perform the DML operation" in
 the Error Message box, and save your work.
 begin
 case :APEX$ROW_STATUS
 when 'C' then  
 insert into DEMO_ORDER_ITEMS
 (order_item_id, order_id, product_id, unit_price, quantity)
 values (null, :P429_ORDER_ID, :PRODUCT_ID, :UNIT_PRICE,
 :QUANTITY);
 when 'U' then
 update DEMO_ORDER_ITEMS
 set product_id  = :PRODUCT_ID,
 unit_price = :UNIT_PRICE,
 quantity = :QUANTITY
 where order_item_id = :ORDER_ITEM_ID and order_id =
 :ORDER_ID;
 when 'D' then
 delete DEMO_ORDER_ITEMS
 where order_item_id = :ORDER_ITEM_ID and order_id =
 :P429_ORDER_ID;
 end case;
 end;
 NOTE: All four input items in the Order Master section on Page 429 are
 rendered as floating elements (see Template property under Appearance
 section) in which the label is displayed inside of the input item, and it
 automatically shrinks once the input field has a value.
 Test Your Work
 Click the Enter New Order button (A) on Page 404. Select a customer (B)
 and pick an order date (C). Click the Edit button (D) in the Order Details
 region. With a product appearing in the first row (E) along with its default
 quantity (G), enter some value in the Unit Price column (F), and click the
 Create  button  (H).  The  order  will  be  saved  and  you  will  see  the  success
 message. On the Order Master page, click the order number you just saved,
 and  then  click  Add  Row  (I)  to  add    some  more  products.  Just  select  aproduct,  enter  some  value  in  the  Quantity  column,  and  click  Save.  The
 modified order will be saved as well. Try to remove a product from this order
 using the Delete  Rows  option  in  the  Row  Actions  menu.  Finally,  click  the
 Delete button on the Order Details page to test order deletion. You’re done!
 Figure 7-34 Order Master and Detail Pages
 
 ## 7.10 Looping Through Interactive Grid
 If you are an absolute beginner, I would recommend you to skip this section
 for the time being. Once you get a firm grip on APEX, revert to this section
 to learn some beyond stuff. In this section, you learn how to loop through
 each  record  in  an  interactive  grid  to  perform  some  kind  of  validation.  For
 example,  here  you  will  prevent  addition  of  duplicate  products  in  a  single
 order.  Of  course,  you  can  add  a  composite  unique  key  constraint  on  the
 corresponding  table  to  prevent  duplication.  But,  there  are  some  scenarios
 where  this  solution  doesn’t  fit.  For  example,  if  you  provide  some  free
 samples of a product in an invoice, you need to create two line item entries in
 your order screen for the same product – one with a price tag and another
 free.  Execute the following steps to prevent product duplication in an order.1.  Open  Page  429  in  page  designer.  Click  the  Form  on
 DEMO_ORDERS  static  content  region  (under  Wizard  Body)  and
 set it Title to Order Master.
 2.  Click the Order Details interactive grid region and enter ORDER
 for its Static ID attribute (under Advanced). The ORDER static id
 will  be  used  as  the  ID  for  the  interactive  grid  region,  which  is
 useful in developing custom JavaScript behavior for the region, as
 you will see later in this exercise.
 3.  Right-click the Items node under the Order  Master  static  content
 region (under Wizard Body) and select Create Page Item. Set the
 following attributes for this new item. It is a hidden item that will
 store 0 (as default) or 1 behind the scene. The value 1 in this item 
 means  that  there  are  some  duplicate  products  in  the  order.  This
 evaluation will be done by a validation – Check Duplicate Product.
 Property Value
 Name P429_PRODDUP
 Type Hidden
 Value Protected Off
 Type  (under Source) Null
 Type  (under Default) Static
 Static Value 0
 4.  Expand the Columns node (under the Order Details  region),  and
 set the following attributes for PRODUCT_NAME column:
 Property Value
 Type Text Field
 Heading Product Name
 5.  Switch  to  the  Dynamic  Actions  tab.  Right-click  the  main  Events
 node  and  select  Create  Dynamic  Action.  Set  the  following
 attributes for this dynamic action. The dynamic action will execute
 a JavaScript code that will be fired before submitting the page. The
 JavaScript code is defined as a custom function – chkDUP() in step7.
 Property Value
 Name Check Duplicate Product
 Event Before Page Submit
 Click the Show node (under True) to set the following attributes:
 Action Execute JavaScript Code
 Code chkDUP()
 6.  Create  another  dynamic  action.  This  time  right-click  the  Change
 node and select Create Dynamic Action from the context menu.
 Set the following attributes for this dynamic action, which is being
 created  to  fetch  product  name  when  a  user  selects  a  different
 product in the Order Details interactive grid.
 Property Value
 Name Fetch Product Name
 Event Change
 Selection Type Column(s)
 Region Order Details
 Column PRODUCT_ID
 Click the Show node (under True) to set the following attributes:
 Action Execute PL/SQL Code
 PL/SQL Code
 select product_name into :PRODUCT_NA
 from DEMO_PRODUCT_INFO
 where product_id = :PRODUCT_ID;
 Items to submit PRODUCT_ID
 Items to Return PRODUCT_NAME
 7.  On  the  Rendering  tab,  click  the  root  node  -  Page  429:  Order
 Details.  Scroll  down  to  the  Function  and  Global  Variable
 Declaration section and append the following JavaScript function
 after the existing code:
 function chkDUP() {
 var record;
 var prodDUP=0;//Identify the particular interactive grid
 var ig$ = apex.region("ORDER").widget();
 var grid = ig$.interactiveGrid("getViews","grid");
 //Fetch the model for the interactive grid
 var model = grid.model;
 //Select all rows
 ig$.interactiveGrid("getViews").grid.view$.grid("selectAll");
 //Fetch selected records
 var selectedRecords = grid.view$.grid("getSelectedRecords");
 for (idx1=0; idx1 < selectedRecords.length; idx1++) {
 record = model.getRecord(selectedRecords[idx1][0]);
 prodcode1 = model.getValue(record,"PRODUCT_NAME");
 for (idx2=0; idx2 < selectedRecords.length; idx2++) {
 record = model.getRecord(selectedRecords[idx2][0]);
 prodcode2 = model.getValue(record,"PRODUCT_NAME");
 if (prodcode1 == prodcode2 && idx1 != idx2) {
 prodDUP=1;
 break;
 }
 }
 if (prodDUP == 1) {
 break;
 }       
 }
 $s("P429_PRODDUP",prodDUP);       
 if (prodDUP == 1) {
 alert("Duplication of product occurred - "+prodcode2);  
 }  
 }
 The  function  is  called  from  the  Check  Duplicate  Product  dynamic
 action before the page is submitted. Initially the function identifies the
 Order Details interactive grid through its static ID. Then, after fetching
 the interactive grid's model, all rows in the interactive grid are selected.
 The  function  then  initiates  a  FOR  loop,  which  loops  through  every
 record  in  the  interactive  grid.  In  every  loop,  value  from  the  Product
 Name column is stored (in prodcode1 variable) and then compared with
 another  variable  in  an  inner  FOR  loop.  If  a  duplicate  is  found,  the
 duplicate switch is turned on – prodDUP=1. If the switch is turned on,
 you see the client-side message specified in the alert function.
 8.  The JavaScript function in the previous step alerts you of duplicateproducts.  After  the  alert,  the  page  is  submitted  and  the  order  is
 saved  with  duplication.  A  server-side  validation  must  also  be
 created to prevent this situation. On the Processing tab, right-click
 the  Validations  node  and  select  Create  Validation.  Set  the
 following  attributes  for  the  new  validation,  which  evaluates  the
 value of P429_PRODDUP hidden page item when either Save or
 Create  buttons  are  clicked.  If  the  value  of  this  item  is  zero,  the
 order is processed. If it is set as 1 by the chkDUP function, an error
 message is fired. Note that if a validation passes the equality test,
 or evaluates to TRUE, then the validation error message does not
 display. Validation error messages display when the validation fails
 the equality test, or evaluates to FALSE, or a non-empty text string
 is returned. Subsequent processes and branches are not executed if
 one or more validations fail evaluation.
 Property Value
 Name Check Duplicate Products
 Type  (under Validation) Item = Value
 Item P429_PRODDUP
 Value 0
 Error Message Duplicated product found – cannot proceed
 further
 Display Location Inline in Notification
 Server-side Condition section
 Type Request is contained in Value
 Value SAVE,CREATE
 Save  and  run  the  module.  Create  a  new  order.  Initially  the  Product
 column in the interactive grid defaults to Air Jordan 6. Select a different
 product  to  fire  the  dynamic  action  and  fetch  the  product  name  in  the
 Product Name column. Add another row and select the same product on
 the new row. Input unit price in both rows and click Create. First, you
 will get the client-side product duplication message from the JavaScript
 function followed by the error message defined in the validation.
 
 ## 7.11 Interactive Grid Native PDF Printing
 Interactive Grid Downloads includes native PDF Printing which allows youto  print  PDF  files  directly  from  Interactive  Grids.  This  feature  produces  a
 PDF  file  which  retains  Grid  formatting  such  as  highlighting,  column
 grouping,  and  column  breaks.  Let’s  go  through  a  simple  demonstration  to
 explore this feature.
 1.  Open  the  Orders  Interactive  Report  page  (Page  4)  in  Page
 Designer.
 2.  Right-click  the  Orders  interactive  report  region,  and  select
 Duplicate  from  the  context  menu.  A  copy  of  this  region  will  be
 created.
 Figure 7-35
 3.  Click the new Orders region, and change its Type property in the
 Identification section from Interactive Report to Interactive Grid.
 4.  Click  the  Attributes  node  under  the  new  Orders  region.  In  the
 properties pane, scroll down to Download section and ensure that
 PDF option (under Download | Formats) is checked. The checkeddownload  formats  can  be  utilized  by  users  to  download  the
 currently displayed columns in the interactive grid.
 5.  Save  and  run  the  page.  The  page  should  now  have  two  regions.
 Scroll  down  a  bit  to  see  the  interactive  grid  region.  From  the
 interactive grid’s Actions menu, select Format | Control Break.
 6.  On  the  Control  Break  dialog,  select  Order  Month  from  the
 Column list and click Save.
 Figure 7-36
 7.  Next,  select  Actions  |  Format  |  Highlight.  Set  the  following
 parameters  in  the  Highlight  dialog.  Once  you  hit  Save  in  the
 Highlight dialog, rows with 1000 or greater amount in the Order
 Total column will be highlighted.Figure 7-37
 8.  Click  the  Actions  menu  again  and  select  Download.  In  the
 Download dialog, select PDF and other options as illustrated in the
 following figure and click the Download button. The output of the
 interactive grid will be downloaded as a PDF to your device.Figure 7-38
 The following figure illustrates the downloaded PDF. As you can see both
 highlight and control break formattings are preserved in the PDF.Figure 7-39
 Summary
 Here are the highlights of this chapter:
 Master Detail – You learned how to implement Master Detail page
 feature to handle data in two relational tables and went through theauto-generated  page  components  added  by  the  wizard  to
 transparently manage the order processing module.
 Interactive Report – Created an interactive report and learned how
 to  alter  the  report  layout  by  applying  highlighting,  sorting,  and
 using  aggregate  functions.  You  also  applied  Control  Breaks  to
 group related data and added Chart and Group By Views.
 Primary, Public, and Alternative Interactive Report – You created
 three  variants  of  the  interactive  report  and  went  through  the
 concepts behind these variants.
 Wizard  Steps  –  Learned  how  to  create  wizard-like  interfaces  to
 perform related tasks in a sequence.
 Copy Page Utility – The chapter provided a shortcut to utilize an
 existing page with all functionalities using a different number and
 for a different scenario.
 Oracle APEX Collection – You learned how to use collections to
 store and retrieve rows and columns information in session state.
 Custom Processes and Dynamic Actions – In addition to the auto-
 generated components and processes, you learned how to manually
 add your own processes and other components.
 Using HTML in PL/SQL Code – You used PL/SQL to have more
 control over dynamically generated HTML within a region.
 Using CSS in Oracle APEX Pages – You applied styling rules to
 give the page a more professional look.
 Simple  Approach  –  Besides  the  advance  techniques,  you  also
 learned how to create this module using a simple approach.
 Looping  through  Interactive  Grid  –  In  the  final  section  of  this
 chapter you learned how to loop through interactive grid records.
 You  usually  execute  this  procedure  when  you  need  to  perform some sort of validation on the data in an interactive grid prior to
 storing it in your database.
 
 
 
 <br /><br /><br /><br /><br /><br /><a name="gra_mob"></a>
 # 08. Graphical Reports & Mobile Integration
 page 304/419
 
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....**Graph. & Mobile**.....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 
 
 
 
 <br /><br /><br /><br /><br /><br /> <a name="advrep"></a>
 # 09. Produce Advance Reports
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....**Adv. Rep**.....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
  
 
 
 
 
 <br /><br /><br /><br /><br /><br /> <a name="authoriz"></a>
 # 10. Authorization - Managing Users & App Access
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....**Authoriz**.....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 
 
 
 
 <br /><br /><br /><br /><br /><br /><a name="searchstylecal"></a>
 ## 11.1 Faceted Search
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz)....**Search**.....[Style Theme r.](#themeroll).....[Style buttons](#style_buttons).....[Calendar](#calendar).....[ Deploy](#deploy)
 
 
 
 <br /><br /><br /><a name="themeroll"></a>
 ## 11.2 Theme Roller – Style Your Application
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search, style, calendar](#searchstylecal).....**Style Theme r.**.....[Style buttons](#style_buttons).....[Calendar](#calendar).....[ Deploy](#deploy)
 
 
 
 
 <br /><br /><br /><a name="style_buttons"></a>
 ## 11.3 Styling Buttons
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz)....[Search, style, calendar](#searchstylecal).....[Style Theme r.](#themeroll).....**Style buttons**.....[Calendar](#calendar).....[ Deploy](#deploy)
 
 
 
 
 <br /><br /><br /><a name="calendar"></a>
 ## 11.4 Manage Events via Calendar component
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz)....[Search, style, calendar](#searchstylecal).....[Style Theme r.](#themeroll).....[Style buttons](#style_buttons).....**Calendar**.....[ Deploy](#deploy)
 
 
 
 
 
 <br /><br /><br /><br /><br /><br /> <a name="deploy"></a>
 # 12. Deploy
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....[Environm](#environm) .....[URL](#url).....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....**Deploy**  
 
 ## 12.1 About App Deployment dev to production environment
 Consists  of  two  steps :  Export desired  components  to  a  script file and  import script  file  into  your production  environment. Decide where and how app will run.
 
 1. **No  Deployment**:  dev environment  becomes prod environment and nothing is moved to another computer. In this option **users are provided with URL** to access app.
 2. **App**:  if target  computer  is  already running production Ora DB with all objects. You export  app and import it into target DB.
 3. **App and Table Structures**: you create two scripts, one for your app and another for DB tbl structures using **Generate DDL utility** in SQL Workshop.
 4. **App and DB obj. with Data**:  you  deploy your app along with all DB objects using **data pump utility**
 5. **Individual  Components**:  With dev  phase  going  on,  you can supplement your deployment plan by exporting only selected components.
 
 
 ## 12.2 Export App
 https://docs.oracle.com/en/database/oracle/application-express/20.1//htmdb/managing-application-backups.html
 
 For  simplicity,  we  will  **deploy  app  in the same workspace**. Same technique is applicable to new workspace or prod  env.
 1.  Sign in to APEX and edit (click) Sales Web Application.
 2.  Click Export/Import icon. On the ensuing page, click Export icon.
 4.  In "Choose  App"  section, set App to Sales  Web App,  and click Export button.
 5.  A file something like **f145615.sql** will be saved in Download folder under My Doc or in another folder specified in your browser.
 
 
 ## 12.3 Data pump utils DB 20.1c expdp/impdp (since 10g)
 Up to 40x faster than Exp/Imp Data.
 
 Very high-speed movement of data and metadata from one DB to another for a complete DB  or subsets of a DB.  In addition to basic import and export functionality data pump provides a PL/SQL API and support for external tables.  
 
 **See oracle_DB18c_devsuite10g_F6i_to_apex.txt**.
 
 
 ## 12.4 Import App
 
 Import exported app **f145615.sql into existing workspace you are connected to with a different WS ID**.
 1.  Go to App Builder interface and click Import icon.
 2.  On the Import screen, click the Choose File button and select exported  file (f145615.sql).  For File Type,  select **DB App, Page or Component** Export and click Next.
 3.  After  a  while  a  message  The  export  file  has  been  imported successfully will appear. The status bar at the bottom of your screen
 will show progress during the upload process. Click Next to move on.
 4.  On the **Install screen**, select default value for Parsing Schema. Set **Build Status** to Run and  Build App, Install  As Application  to  Auto  Assign  New  Application  ID,  and  click  the Install Application button. After a short while, the application will be installed with a new ID for you to give it a test-run.
 5.  On the Install page, click the Run Application  button.  You  will encounter  an  error  saying  “ You  are  not  authorized  to  view  this application,  either  because  you  have  not  been  granted  access,  or your  account  has  been  locked.  Please  contact  the  application administrator. ” Application users are not exported as part of your application.  When  you  deploy  your  application  you  will  need  to manually manage your user to role assignments. Roles are exported as  part  of  an  application  export  and  imported  with  application imports. Execute the following step to cope with this error.
 6.  On  the  Install  page,  click  the  Edit  Application  button.  Go  to Shared  Components,  and  click  Application  Access  Control  in the Security section. Using the Add User Role Assignment button (A) add the three users as shown in the following figure. In  Shared  Components,  click  Security  Attributes.  Click  the Authorization  tab,  and  set  Authorization  Scheme  to  No application authorization required (A). Apply the change. Now you will be able to access the application.
 
 ## 12.5 Prevent App Modification and Remove Developers Toolbar
 
 The  Developers  Toolbar  is  used  to  access  the  application  source.  In  this exercise,  we  are  going  to  prevent  users  from  modifying  the  application  by suppressing the toolbar.
 1.  Open  the  new  application  you  just  imported  in  the  designer interface.
 2.  Click Shared Components.
 3.  Click the Globalization Attributes link (under Globalization).
 4.  Click the Definition tab.
 5.  Click  the  Availability  tab,  set  Build  Status  to  Run  Application Only, and click Apply Changes.
 6.  Go to the App Builder interface and see that the new application doesnt have the Edit link. Click the Run button and provide yoursign  in  credentials.  Note  that  the  Developer  Toolbar  has disappeared as well.
 7.  To  make  the  application  editable  again,  select  App  Builder  | Workspace Utilities | All Workspace Utilities (A), as illustrated in  the  following  figure.  On  the  Workspace  Utilities  page,  select Build and App Status (B) from the right sidebar. On Build Status and  Application  Status  page,  click  the  application  ID  in  the  first report  column,  change  the  Build  Status  to  Run  and  Build Application, and apply the change.
 
 Thats  it.  You  have  successfully  deployed  your  application  in  the  same workspace. You can apply the same procedure to deploy the application to another environment.
 
 Conclusion
 
 Oracle APEX has come a long  way from its simple beginning. Sky is the limit, you are limited by your imagination.
 
 
 
 
 
 
 <br /><br /><br /><br /><a name="app_builder"></a>[Top](#top).....[Back](#goAPEXConcepts)
 ## 2.2 Applications, App. builder
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....**App. builder**.....[Page](#page).....[Environm](#environm).....[URL](#url)   .....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 1. 
    ## https://apex.oracle.com/pls/apex/
    (+ f?p=4550:1:117485610537637:::::)
 2. button "Sign in" opens same URL, page "App Builder" :
    
 Page "App Builder" : Create and manage my apps  and their pages :
 1. "**Create**" icon functionality :   
    1. New App based on **tables** you select or by providing a valid **SQL**
    2. New App from File :    
       **Load** Data Wizard appears to load definitions & data in : CSV, XLSX, XML, TXT or JSON  
       or Copy and Paste **column delimited** data.  
       After loading data into DB tbl, **wizard creates some app. pages based on new tbl**  
     3. **"App Gallery" -> "Productivity Apps"** eg  proj. mngmnt,  surveys,  shared  calendars, and tracking apps, can be installed, run, and removed.  
 2. "**Import**" icon
 3. "**Dashboard**" icon
 4. "**Workspace**" Utilities icon
  
 
 <br /><br /><br /><a name="page"></a>
 ## 2.3 Page eg App. builder -> click my "Sales Web app" icon
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....**Page**.....[Environm](#environm).....[URL](#url)   .....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 **Page creation wizards** - option to create a blank page and add components manually, **Page Designer** interface to add more controls after page creation.  
 
 When you run app requested with a URL, APEX engine relies on **two processes**: 
 1. **Show  Page**  is page  rendering  process, runs **when you request page** using a URL.  It  assembles  all  the  page attributes including regions (stacked canvases), items, and buttons into a viewable HTML page.  When you request a page using a URL, the engine is running Show Page.
 2. **Accept  Page**  performs  page  processing **when  you  submit page**.  It  performs computations, validations,  processes,  and branching. 
    1. APEX  engine  is  running  **Accept  Page**  then  performing  page **processing** during which it 
    2. saves submitted values in session cache 
    3. and then performs any computations, validations, or processes.
 
 You can create following **types of pages** for your app :
 1. **Blank Page** Creates a page without any built-in functionality
 2. Report Used to present a SQL query in a formatted style
     1. Interactive Report
     2. **Interactive Grid**
     3. Classic  Report
 3. Form
    1. Editable Interactive **Grid**
    2. **Report  with  Form**
 4. **Master Detail**
     1. Stacked
     2. Side by Side
     3. Drill Down
     4. Plug-ins
     5. Chart
     6. Tree
    7. Calendar
    8. Data Loading
  
 
 <br /><br /><br />
 ## 2.4 Region, Items, Buttons
 
 ### 1. Region (stacked canvas) serves as container  for  content
 **Region template** controls region look,  size, determines whether there is border or background color, and what type  of  fonts  to  display. Also  determines  standard placement for any buttons placed in region positions.
 
 You can use regions **to group page elements** (such as items or buttons).
 
 APEX supports many different **region types** eg **Static  Content,  Classic  Report,  Interactive Report, Interactive Grid, Chart**, and more.
 
 ### 2. Items
 Text  Field,  Textarea,  Password,  Select  List, Checkbox... Item properties : where a label displays, how large an item is, and **if item displays next to or below previous  item**.  Page  item name is eg  P7_CUSTOMER_ID = custID item on page 7 (preceded  P followed by number pageID).
 
 ### 3. Buttons to submit page or to take users to another page 
 Redirect :
 1. within the same site where  a  user  submits  a  page,  the Oracle  APEX  engine  executes  some  processes  associated  with  a  particular button and uploads the page's item values to the server - see Figure 1-3 in chapter  1
 2. or  to  a  different  site
 
 In  case  of  a  **redirect : nothing  is  uploaded  to  the  server**.  If  you change  some  items  values  on  a  page  and  press  a  **button created with a redirect action**, those changes will be lost.
 
 Button options are: **Icon, Text, and Text with Icon**. You can place buttons either in predefined region positions or with other items in a form - see Figures 1-1, 1-3, and 1-7 in chapter 1.
 
 Buttons **control flow of DB apps, are created by right-clicking region**  ->  select  "Create  Button"  from  context  menu.  By  placing buttons (such as Create, Delete, Cancel, Next, Previous , and more) on your web page, you can **post or process by customer provided information** or you can **direct user to another app pg or to another URL**.
 
 #### Buttons are used to:
 
 1. **Submit a page** eg to save user input in a DB tbl. When a button on a page is clicked, pg is submitted with REQUEST value that carries btnname. You can **reference value  of  REQUEST  from  within  PL/SQL  using bind variable " :REQUEST.". ** By  using  this  bind  variable,  you  can conditionally  process,  validate,  or  branch  based  on  which  button the  user  clicks.  You  can  create  processes  that  execute  when the  clicks a button. 
 And you can use a more complex condition as demonstrated in the following examples:
    ```
    If :REQUEST in ('EDIT','DELETE') then ...
    If :REQUEST != 'DELETE' then ...
    ```
      These  examples  assume existence  of  buttons  named  EDIT  and DELETE.  **You  can  also  use  this  syntax  in  PL/SQL  Expression conditions**.  If you name a button LOGIN, then request looking for Login fails - btnname is case sensitive.
 
  2. Take  user  to  another  page  within  the  same  app  with optional  additional  properties  for  **resetting  pagination**,  setting  request value, clearing cache, and setting item values on the target page.
 
 3. Redirect to another URL. 
 
 4. Do  nothing eg  if  buttons  behavior  is  defined  in  a Dynamic Action.
 
 5. Download  Printable  Report  Query.  This  creates  a  Submit  Page button  and  also  a  corresponding  branch.  When  the  button  is clicked, the output is downloaded from Report Query.
 
  
 
 <br /><br /><br /><a name="environm"></a>
 ## 2.5 APEX Web-based app Development Environment to build web apps
 
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page).....**Environment**.....[URL](#url)   [Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 You are not required to install any client software to develop, deploy, or run Oracle APEX applications.
 
 Primary APEX **tools**  :
 1. **App  Builder**  -  to  create  dynamic  database  driven  web appls. Here you create and modify your applications and pages. It comprises following :
    1. Create: new  apps.  See  section  2.3.2
    2. Import:  entire  Oracle  APEX apps developed somewhere else, along with related files.
    3. Dashboard: metrics about apps in  your  workspace  eg:  Developer  Activity,  Page Events,  Page  Count  by  App, Most  Active Pages...
    4. Workspace  Utilities: Most significant is  **Export** app  and  component metadata to **SQL script file format** that you can import on the  same  or  another  compatible  instance  of  APEX. 
 
 2. **SQL Workshop** -  to browse your DB objects, to run  ad-hoc  SQL  queries,  allow  App  Developers  to  maintain  DB  objects eg tables, packages, functions, views... It is beneficial  in  **hosted  environments  like  apex.oracle.com where direct access to underlying schemas is not provided**. It has five basic components:
    1. Object Browser: to review and maintain database objects (tables, views, functions, triggers...).
    2. SQL Commands: to run SQL queries.
    3. SQL Scripts: to **upload and execute** script files.
    4. Utilities:  eg  Query  Builder,  Data  Workshop, Generate DDL, Schema Comparison...
    5. RESTful  Services:  to  define  Web  Services  using  SQL and PL/SQL against DB
 
 3. **Team  Development**  -  allows development  teams  to  better  manage  their  Oracle  APEX projects by defining **milestones, features, to-dos, and bugs**. Features,  to-dos,  and  bugs  can  be  **associated  with  specific apps and pages** as necessary. Developers can readily configure  feedback  to  allow  their  end-users  to  provide **comments  on  app**.  The  feedback  also  **captures relevant session state details** and can be readily converted to a feature, to-do or bug.
 
 4. **App Gallery  -   Productivity apps** are a suite of business productivity  applications,  easily  installed  with  only  a  few clicks.  These  solutions  can  be  readily  used  as  production applications  to  improve  business  processes  and  are  fully supported by Oracle.
 
 
 
 Oracle APEX environment has two broad categories:
 1. **Development**  Environment:  Here  you  have  complete  control  to build and test your applications.
 2. **Runtime**  Environment:  After  completing  **development**  and **testing**  phase,  you  implement  your  apps  in  a  **production** environment  where  users  can  only  run  these  applications  and  do not have the right to modify them.
 
  
 <br /><br /><br />
 ## 2.6 Page Designer : App Builder ->  Sales app -> some page
 
 1. **page top, right**
    ### 2.6.1 Page Designer toolbar (A) 
    It comprises various tools to find a page, lock/unlock a page, undo/redo actions, Create menu, Utilities menu, shared components, save and run  page (see tooltips). 
 
    **Utilities menu** has an option that lets you delete the page being displayed in your browser. 
 
    **Lock icon (padlock - lokot)** indicates whether a page is currently locked.  Is also displayed  in  Page  Designer  as  well  as  on  App  home  page  -   Figure 2-5. This feature enables you **to prevent conflicts during app  development**.  By  locking  a  page  you  prevent  other  developers from editing it.
 
 2. **page top, left**
    ### 2.6.2 Tree Pane contains four icons (were tabs) and tree nodes
    Tree nodes : regions,  items,  buttons,  app  logic  (eg  computations,  processes, validations), dynamic actions, branches, shared components.  
    
    4 icons  :
 
    1. **Rendering icon**  (B)  -  contains  as  nodes  in  a  tree : regions,  page  items,  page  buttons,  and app logic.  **Components**  defined  in  this section appear when a page is rendered. These components can be viewed as  a  tree,  organized  either  by  **processing  order**  (the  default)  or  by **component type**. The first two buttons to the right of the Rendering label can be used to toggle between rendering trees. Rendering is divided in three  stages :
       1. pre-Rendering  stage  **pre**liminary  **computations**  are performed
       2. main  rendering  stage  comprises  **regions  and  its components**
       3.  **Post**-Rendering stage  also  carries  **computations** that occur after rendering a page. 
 
    2. **Dynamic Actions icon** (C) -  Displays dynamic actions defined on this page. By  creating  a  dynamic  action,  you  can  define  complex  client-side behavior declaratively without the need for JavaScript. Refer to Dynamic Actions  entry  in  the  book’s  index  to  see  its  utilization  in  the  project application.
 
    3. **Processing icon**  (D)  -  Use  this  icon  to  specify  app  logic  eg : 
       1. **Computations**  are APEX's  declarative  way  of  **setting  an  item's  values**  on  page. These  are  units  of  logic  used  to  **assign  session  state  to  items**  and  are executed ** at  the  time page  is  processed**.
       2. **Validation**  is **server-side** mechanism  designed  to  check  and  validate quality,  accuracy,  and consistency of page submitted data, prior to saving it into DB. If  a  validation  fails,  further  processing  is  aborted  by  the  server  and  existing page is redisplayed with all inline validation errors. 
       3. **Processing** are **logic controls  used  to  execute  DML** (Data  Manipulation  Language) **or PL/SQL**.  Processes  are  executed  **after page  is  submitted** - typically when user clicks button. 
       4. **Branches** enable you to create  logic controls  that  **determine  how user  navigates  through app**. 
 
    The  left  iconic  button  to  the  right  of  the  Processing  label displays  the  components  under  this  tab  according  to  the  servers processing  order.  The  middle  button  organizes  these  components according to their type, while the third one provides a menu to create a new component in the selected folder. 
 
    4. **Page Shared Components icon** (E) -  Displays shared components associated with this page. The list on this tab gets populated automatically when you use shared components on a page.
 
 3. 
    ### 2.6.3 Central Pane has two sections
    Upper section contains three tabs: Layout, Page Search, Help. Lower pane is called **Gallery** and it is **associated with Layout tab**.
    1. Layout (F) is a **visual representation of the regions, items, and buttons** that define a page. You can add new regions, items and buttons to a page by selecting them from Gallery at the bottom of the page, drag, drop.
    2. Page Search (G) -  to search all **page metadata** including regions, items, buttons, dynamic actions, columns, and so on.
    3. Help  (H) displays  **help  text  for  properties (purpose) in Property Editor (right pane)**. Click a property in the Property Editor and then click Help tab (in the Central pane). As you move from one property to next in property editor, Help tab displays it's help text.
 
 4. **right pane**
    ### 2.6.4 Property Editor (prop, value) for current component in either Tree View or Layout tab
    As you select component Property Editor updates to reflect current selection. Properties are organized into **functional groups** (Identification,  Source,  Layout,  Appearance,  and  more)  that  describe  their **purpose**. When you modify or add a value to a property, a **colored vertical bar** appears as a visual **modification indicator** before the property name.
 
  
 
 
 <br /><br /><br /><a name="url"></a>
 ## 2.7 APEX URL Syntax
 [Top](#top).....[Apexws_cloud](#Apexws_cloud).....[App. builder](#app_builder).....[Page](#page)   [Environm](#environm).....**URL**   .....[Sales](#sales).....[SHARED C.](#shared)......[Rep.List](#rep_list).....[Ord.WizList](#ord_wiz_list).....[Top. Navig](#top_navig).....[LOVs](#lov)....[IMGs](#img)
 .....[Home p.](#home).....[Buttons](#buttons).....[PgStyles](#pgstyles).....[Cust](#cust).....[Prod](#prod).....[Order](#order).....[Graph. & Mobile](#gra_mob).....[Adv. Rep](#advrep).....[Authoriz](#authoriz).....[Search Style Cal.](#searchstylecal).....[ Deploy](#deploy)
 
 ### f?p  URL  Syntax
 is  a  legacy syntax  that  creates  a  unique  URL  structure  that  identifies  address  of  APEX, app ID, page number, and session ID.
 
 **https://apex.oracle.com/pls/apex/f?p=4500:1000:706440515653484**
 
 **In code: https://apex.oracle.com/pls/apex/f?p=&APP_ID.:1000:&APP_SESSION.:::::**
 
 https://   URL of the server / **pls** is indicator to use the mod_plsql cartridge     
 
 / **apex** is (default)  DAD (database  access  descriptor)  name. DAD describes how HTTP server connects to DB server to fulfill HTTP request.        
 
 / **f?p=** is a prefix used by Oracle APEX to route the request to the correct engine process    
 
 **4500** is appID being called : 1000 is page within app to be displayed      
 
 : 440323506685863558 is **session number** to keep track of user’s session state     
 
 
 Developer  Toolbar among  other  tools  for  developers contains  a  **Session  option**,  which shows you the current session state. Clicking it opens a window (called **Session Page**, shown in Figure 2-6)  carrying  all  **items  and  their  current session  values**.  It  is  useful  for  developers  to  debug  pages.  When  you change some item value on a page and submit it, the value in the session window for that item changes to reflect the current state. Use Page, Find, and View parameters to view session state for the page. The drop-down View menu comprises Page Items, Application Items, Session State, Collections, and All options. Select an option from this list and click the Set button to **refresh the Session State report**.
 
  
 
 ### Friendly URL Syntax (APEX  release  >= 20)
 
 creates a URL structure that identifies the address of APEX,  app,  page,  and  uses  a  standard URL  hierarchy  and  passes  parameters  in  a  similar  fashion. You can change existing apps to use Friendly URLs by editing  Friendly  URLs  attribute  in  app  definition  :     
 
 Shared Components | Application Definition Attributes | Properties.
 
 **https://apex.oracle.com/pls/apex/POSSYS/r/4500/home?session=702685162362252**
 
 Friendly URL Syntax creates a URL with the following directory hierarchy and syntax:     
 
 https:// apex.oracle.com / pls /apex / myws/ r / 4500 / home?session=16167973992554      
 
 Where:     
 1. myws   is  the  path_prefix  which  is  URI  path  prefix  used  to  access RESTful  Services.  When  you  create  a  workspace,  this  value defaults  to  workspace  name.  You  can  customize  the  URI  path prefix  by  editing  the  Path  Prefix  attribute  in :  
    Administration  | Manage Service | Set Workspace Preferences | SQL Workshop
 
 2. r  is the router shortcut. This value is a constant and should never be changed
 
 3. 4500  is the application id
 
 4. home  is the alias of the page being displayed. **If no alias is defined, the page number is displayed instead**.
 
 5. ?session=16167973992554  identifies the session ID.
 
  
 
 <br /><br /><br />
 ## 2.8  Substitution Strings (&varname.) and Bind Variables (:item_name)
 &varname. means prefix ampersand to item name and append period at its end to  reference item.
 
 :item_name means precede item name with colon.
 
 **To make your app more portable**, APEX provides many features. On top of the list are the Substitution Strings that help you **avoid hard-coded  references**  in  your  app.  Every app  has  its  own  unique  ID  used  to identify  app  and  it's  metadata  within APEX repository.  When  you  move  app  from your dev. envir. to prod. envir, and if you've hard-coded  app  references,  eg you hard-coded the application ID (101) like this:  f?p=101:1:&APP_SESSION and prod. environ. already  has  an  app  ID=101, you will  be forced  to  use  a  different  ID,  which  will  **point  all  your  links  within  app to the wrong ID**.    
 
 To avoid such situations, you should always use substitution strings. You can avoid  hard-coding  appID  by  using   **APP_ID  substitution string**, which identifies ID of the currently executing app. With the substitution  string,  the  URL  looks  like: **f?p=&APP_ID.:1:&APP_SESSION.**. Supported syntax for referencing APP_ID :     
 
    | Reference Type                                                                                            | Syntax                   |  Help  |
    | :------------------------------------------------------------------------- | :---------------------: | :--------------------------- |
    |  Bind variable                                                                                                |   :APP_ID                   |   |
    |  Substitution string                                                                                    |    &APP_ID.               |                                |
 
 There  are  two  ways to get a page to access value of a session state variable:
 1. Use **bind variable** to  reference  the  variable  from **within SQL or PL/SQL** code, 
 2. Use **substitution string** from **within an HTML expression** so :       
    ## Using Substitution Strings
    1. Include  a  substitution  string  **within  a  template to  reference component values**     
       Special  substitution  strings  available  within  a  template  are  denoted  by  the number symbol (#). For example:  #PRODUCT_ID# - see Chapter 4 Section 4.3.2, 4.3.5, and 4.3.6.     
  
    2. **Reference page or app items** using &ITEM. syntax - all capital letters !       
       For example, you would **refer to a page item named P7_CUSTOMER_ID** in a region, a region title, an item label, or **in any of numerous other contexts in which static text is used**, like this: "&CUSTOMER_ID."  Notice required trailing period. When the page is rendered, APEX engine replaces the value of the substitution string **&CUSTOMER_ID. with the value of item P7_CUSTOMER_ID**
 
    3. Use one of many APEX **built-in** substitution strings to achieve specific types of functionality.  Eg APP_ID, APP_IMAGES,  APP_PAGE_ID,  APP_SESSION,  APP_USER, LOGIN_URL,  LOGOUT_URL.
 
 
 
 
 
 
 
 
 
 <br /><br /><br /><br /><a name="shared_about"></a>[Top](#top).....[Back](#shared)
 ## 3.1 Shared (common, appglobal) Components across all app pages eg menu options
 
 "Page Shared Components" tab **top left icon (pyramid of 3) in Page Designer (App Builder -> App)** displays a list of **APPLEVEL common elements** applied to that particular page. Shared  components are only  displayed in this section after you add them to a page.
 
 
 ## Shared comp. list 1. APP LOGIC SECTION : 
 
 ### 3.1.1 App Definition Attributes
 Link to  Edit  App  Definition page  where you can **modify your app attributes**, including its name, version, and availability options. You can turn on new Friendly URLs option.  
 
 ### 3.1.2 Application Processes
 Run  PL/SQL  logic  at  a  specific  point  from  multiple pages  (reports) of  an  app.  You  can  apply  conditions  to ** control  when** process executes. Currently there are **8 different types** of process that you can include in your app. 
 
    One significant is **On Demand App Process**. It is a special type of app process which executes when called from :
    1. page-level On Demand process
    2.  or from an Ajax call from the browser.  
    
    On Demand processes are useful eg  **assessing  customer's  outstanding balance  and  using  that  figure (value) on reports eg :**  customer  invoice,  age  analysis  report, customer balances report and so on. 
 
 
 
 ## Shared comp. list  2. SECURITY SECTION 
 
 ### 3.1.3 Authentication Schemes
 (access=prijava, functionalities=prava)    
 
 These  schemes  enable  us  to  declaratively  define  security  for  our apps quickly and easily.
 
 **Authentication** is the process of **establishing  identity  of  every your app  user **. Most  common  auth.  process : usrname and psw. These credentials are then evaluated either through  
 1. built-in  APEX  Auth.  scheme  
 2. or  using  a custom scheme with more control. 
 
 Authentication could involve use of **digital  certificates**  or  a  **secure  key**,  too.  If  credentials  pass,  user  is allowed to access app. Once a user has been identified, APEX engine keeps track of each user by setting the value of **built-in substitution string APP_USER**.
 
 As  you  create  your  app,  you  must  determine ** whether  to  include auth**. You can:
 
 1. Choose  to  **not  require  authentication**.  Oracle  APEX  does  not check  any  user  credentials.  All  pages  of  your  app  are accessible to all users eg **public informational app website**.
 
 2. Select a built-in authentication scheme. Create an auth. method based on available preconfigured authentication schemes. Each  scheme  follows  a  standard  behavior  for authentication and session management. 
 
 3. APEX Accounts. These are user accounts created within and managed in Oracle APEX user repository. When you use this method, your app is authenticated against these accounts.
 
 4. 
    ### DB Account Credentials authentication  scheme
    It  utilizes  DB  schema accounts.  This  authscheme  requires  that  DB  user (schema)  exist  in  local  DB.  When  using  this  method,   **username and password of the DB account is used to authenticate user**. Choose DB Account Credentials **if having one DB account  for  each  named  user  of  your  app**  is  feasible (viable, practicable, executable, workable)  and account maintenance using DB tools meets your needs.
 
    5. HTTP Header Variable. It supports the use of header variables to identify a user and to create an Application Express user session. Use this authentication scheme if your company employs a centralized web authentication  solution  like  Oracle  Access  Manager,  which  provides single sign-on across apps and technologies.
 
    6. LDAP  Directory  Verification.  You  can  configure  any authentication  scheme  that  uses  a  login  page  to  use  Lightweight Directory  Access  Protocol  (LDAP)  to  verify  the  username  and password submitted on the login page. App Builder includes wizards and  pages  that  explain  how  to  configure  this  option.  These  wizards assume that an LDAP directory accessible to your application for this purpose already exists and that it can respond to a SIMPLE_BIND_S call for credentials verification.
 
    7. Application Server Single Sign-On Server. This one delegates authentication to the Oracle AS Single Sign-On (SSO) Server. To use this  authentication  scheme,  your  site  must  have  been  registered  as  a partner application with the SSO server.
 
    8. Create  custom  authentication  scheme.
 
       Using  this  method  you can  have  complete  control  over  the  authentication  interface.  To implement this approach you must provide a PL/SQL function the Application Express engine executes before processing each page request.  The  Boolean  return  value  of  this  function  determines whether  the  Application  Express  engine  processes  the  page normally or displays a failure page. This is the best approach for apps when any of the following is true:
 
       1. Database authentication or other methods are not adequate
       2. You want to develop your **own login form** and associated methods
       3. You want to control security aspects of session management
       4. You want to record or audit activity at the user or session level
       5. You want to enforce session activity or expiry limits
       6. Your **app consists of multiple apps that operate seamlessly (eg, more than one app ID)**
 
 
 ### 3.1.4 Authorization Schemes  
 To  control  users  access  to  specific components  of  your  app. An auth.  scheme  can  be  specified  for  an  entire  app,  page,  or specific page components such as a region, button, or item. For instance, you can apply an auth. scheme to determine which menu options a user can  see,  or  whether  he  is  allowed  to  create  a  new  order  (using  Create button).
 
 
 
 ## Shared comp. list  3. OTHER COMPONENTS 
 
 ### 3.1.5 LOVs (Lists of Values) are defined by running LOV wizard - static  and dynamic
 Once  created,  LOVs  are  stored  in  LOVs  repository  and  are utilized  by  page  items Px\_...  
 1. static LOV displays and returns predefined values such as Yes and  No
 2. dynamic  list  is populated  using  SQL  query
 
 After creating LOV you associate it to page items such as **select list, radio group, checkbox...**.  LOVs  at app-level  can be added to  any page within app, and is  easy to locate and update (since all LOV definitions are stored in one location).
 
 ### 3.1.6 Plug-Ins framework - was introduced in Oracle APEX 4.0
 Allows developers to create their own plug-ins to add additional functionality in a supported and declarative way. Usually, a **tool like Ajax** is used to add custom functionality. The con of this approach  is  to  place  the  code  in  different  locations  such  as  within  the database, in external JavaScript files, and so on. On the other hand, turning that code into a plug-in is more convenient to use and manage because the code resides in one object. With the help of open source jQuery components you can create plug-ins without generating huge amount of code manually.
 
 Plug-ins  are  shared  component  objects  that  allow  you  to  extend  the functionality of item types, region types, dynamic actions, and process types. The plug-in architecture includes a declarative development environment that lets you create custom versions of these built-in objects. For example, you can create your **own star rating item** that allows your user to provide feedback using a one-to-five star graphic. This new item type can then be used across all your apps. The main part of a plug-in consists of PL/SQL code and can  be  supplemented  with  JavaScript  and  CSS  code.  A  plug-in  consists  of one  or  more  PL/SQL  functions.  These  functions  can  either  reside  in  the database (in a package or a set of functions) or be included within the plug-in. 
 
 NOTE: Plug-in  OTN  page (https://www.oracle.com/tools/technologies/apex-plug-ins.html)  has  several different plug-ins developed by APEX community.
 
 ### 3.1.7 Shortcuts to  avoid  repetitive  coding  of  HTML  or  PL/SQL functions  
 You can use a shortcut to define a page control such as a button, HTML text, or a PL/SQL procedure. Once defined, you can invoke a shortcut using  specific  syntax  unique  to  the  location  in  which  the  shortcut  is  used. Shortcuts can be referenced many times, thus reducing code redundancy. When you create a shortcut, you must specify the type of shortcut you want to create. Oracle APEX supports the following shortcut types:
 1. PL/SQL Function Body
 2. HTML Text
 3. HTML Text with Escaped Special Characters
 4. Image
 5. Text with JavaScript Escaped Single Quotes
 6. Message
 7. Message with JavaScript Escaped Special Quotes
 
 
 
 ## Shared comp. list  4. NAVIGATION
 
 ### 3.1.8 Lists - collections of links
    For each list entry, you specify display text, a target  URL,  and  other  attributes  to  control  when  and  how  the  list  entry displays. Once created, you can add a list to any number of pages within an app  by creating a region and specifying the region type as List. You control the display of the list and the appearance of all list entries by linking list to a template. Lists are of two types:  
 
    **Static Lists** -  When you create a static list you define a list entry label and a target (either a page or a URL). You can add list entries when you create the list (from scratch), by copying existing entries or  by  adding  the  list  entries.  You  can  control  when  list  entries display by defining display conditions.
 
    **Dynamic  Lists**  -  are  based  on  a  SQL  query  or  a PL/SQL function executed at runtime.
 
 ### 3.1.9 Navigation Menu
 You might have seen a horizontal bar at the top of a website. The options provided  on  this  bar  help  you  navigate  to  different  pages  within  that  site. app  Express  provides  you  with  a  similar  component  called Navigation Menu. It is an effective way to navigate users between pages of an app.  A navigation menu is basically a list with hierarchical entries.  
 
 When you create an app, the Create app Wizard automatically creates  a  navigation  menu  for  you  and  populates  it  with  one  or  more  list entries. Types of navigation menus include Side Me
 
 **Navig. Top Menu, or Mega Menu**  
 By default, the navigation menu is displayed as a left sidebar. Users can expand or collapse the Side Navigation Menu by clicking on the menu icon  from  the  header.  This  navigation  menu  renders  the  navigation  items using a tree component that enables users to expand or collapse sub items. A Top Navigation Menu displays at the top of the app. You can change how and where a navigation menu displays by editing the app User Interface  Details.  The  Top  Navigation  Mega  Menu  template  renders  your app navigation in a pop-up panel that can be opened or closed from the  header  menu  button.  Users  can  expand  or  collapse  a  Mega  Menu  by clicking on the menu icon from the header. Mega menus are especially useful when you want to display all navigation items at once to your user.
 
 ### 3.1.10 Breadcrumb
 A breadcrumb (A) is a hierarchical list of links rendered using a template. For example, you can display breadcrumbs as a list of links or as a breadcrumb path. A breadcrumb trail indicates where you are within the app from a hierarchical perspective. In addition, you can click a specific breadcrumb link to instantly view the page. For example, in the screen shot below you can access the app home page by clicking its breadcrumb entry (B). You use  breadcrumbs  as  a  second  level  of  navigation  at  the  top  of  each  page, complementing  other  navigation  options  such  as  Navigation  Menu  and Navigation Bar.
 
 ### 3.1.11 Navigation Bar List
 Just like menus, lists, and breadcrumb, a navigation bar is also created to link users  to  various  pages  within  an  app.  Typically,  a  navigation  bar carries links such as user id, logout, feedback, help, and so on. It appears on top-right of every app page. While creating a navigation bar, you can specify an image name, label, display sequence, and target location.
 
 
 
 ## Shared comp. list  5. USER INTERFACE
 
 ### 3.1.12 User Interface Attributes
    The  app  user  interface  determines  default  characteristics  of  app and optimizes the display for the target environment. This is place where you define your app logo.
 
 ### 3.1.13 Themes and Templates
 Instead of telling App Builder how to design and style your pages using HTML,  CSS,  and  JavaScript  code  that  you  may  not  be  familiar  with,  you  only apply theme and templates you want to use and the Oracle APEX engine does the rest of the job for you.  
 
 A  theme  is a named collection of templates that defines the look and feel of app user interface. Each theme contains templates for every type of app component and page control, including individual pages, regions,reports, lists, labels, menus, buttons, and list of values.  
 
 APEX engine constructs the appearance of each page in a app  using  Templates .  Templates  define  how  pages,  page  controls, and  page  components  display.  Templates  control  the  look  and  feel  of  the pages  in  your  app  using  snippets  of  HTML,  CSS,  JavaScript  and image icons. As you create your app, you specify templates for pages, regions,  reports,  lists,  labels,  menus,  buttons,  and  pop-up  lists  of  values.  
 
 Groups of templates are organized into named collections called themes.  
 
 App  Builder  also  allows  you  to  access  themes  and  template mechanism so you can create new ones according to your own requirements or amend (improve)  existing  ones.  Oracle  APEX  ships  with  an  extensive  theme repository.  Administrators  can  add  themes  to  the  theme  repository,  as follows:  
 1. Workspace administrators can create themes that are available to all  developers  within  the  workspace.  Such  themes  are  called workspace themes.
 2. Instance administrators can create public themes by adding them to the  Oracle  APEX  Administration  Services.  Once  added,  these public themes are available to all developers across all workspaces in an instance.
 3. Apps  you  create  with  the  Create  app  Wizard  use Universal Theme. Universal Theme - 42 features a responsive design, versatile UI components and enables developers to create web apps without extensive knowledge of HTML, CSS, or JavaScript. Responsive design enables you to design web pages so that the layout fits the available space regardless of the device on which  page  displays  (eg  desktop  computer,  laptop computer, tablet, or smartphone).
 
 
 
 ## Shared comp. list  6. FILES
 
 ### 3.1.14 Static App and Workspace resource Files (img, CSS, JS)
 Use these two links to upload, edit, and delete static files including images, custom  style  sheets,  JavaScript  files.
 
 Static App  file  can  be referenced from a specific app only, whereas **workspace file can be accessed by any app in workspace**. Here  we use Static app Files option to **upload your app logo**.
 
 
 
 ## Shared comp. list  7. DATA SOURCES
 
 
 
 ## Shared comp. list  8. REPORTS
 
 ### 3.1.15 Report Queries
    A  report  query  is  a  printable  document,  which  can  be  integrated  with  an app  using  buttons,  list  items,  branches,  or  any  other  navigational components that allow for using URLs as targets. A report query is based on a  standard  SQL  query.  It  can  be  downloaded  as  a  PDF  document,  a  Word document  (RTF  based),  an  Excel  Spreadsheet  (HTML  based),  or  as  an HTML  file.  The  layout  of  a  report  query  is  customizable  using  RTF templates.
 
 ### 3.1.16 Report Layouts
 Use  Report  Layouts  in  conjunction  with  a  report  region  or  report  query  to render  data  in  a  printer-friendly  format,  such  as  PDF,  Word,  or  Excel.  A report layout can be designed using the Template Builder Word plug-in and uploaded  as  a  file  of  type  RTF  or  XSL-FO.  Report  regions  use  a  generic XSL-FO layout, which is customizable.
 
 
 
 ## Shared comp. list  9. GLOBALIZATION
 
 ### 3.1.17 Globalization Attributes
 If  you  want  to  develop  apps  that  can  run  concurrently  in  different languages,  then  app  Express  is  the  right  platform  for  this.  In  the Globalization  interface,  you  can  specify  options  such  as  the  app Primary  Language,  Date/Time  format,  and  some  other  options  related  to app globalization.
 
 ### 3.1.18 Translate app
 A  single  Oracle  DB  and  APEX  instance  can  support  an app  in  multiple  languages.  Translating  an  app  involves multiple  steps.  To  translate  an  app  developed  in  App  Builder,  you must :  
 1. map  the  primary  and  target  language
 2. seed  and  export  text  to  a translation file
 3. translate the text
 4. apply the translation file
 5. publish the translated app.
  
 
 
 
 
 
 <br /><br /><br /><br /><a name="sampleIG"></a>[Top](#top).....[Back](#gosampleIG)
 
 ### App Gallery "Sample Database Application#
 Is finished this tutorial.
 
 Is an application that highlights common design concepts. It includes dedicated pages for customers, products, and orders as well as demonstrates the use of reports, charts, calendar, map, and tree.
 
 
 
 ## 5.6 IG : Learn IG - install "Sample Interactive Grids" app
 Interactive  Grid  is  a  page  component,  which  is  used  to  display  data  in row/column matrix. In appearance, it looks similar to an Interactive Report (used in the next chapter) and delivers **all features of Interactive Report**, but it also allows you to manipulate data by **clicking on a cell and editing its value (like Clipper Dbedit !)**, which is not available in Interactive Reports.  In many ways this  grid  looks  and  acts  like  an  Interactive  Report.  Here  are  some  new features and differences: 
 1. Rows are fixed height and columns have a specific width that can be adjusted by dragging the border between column headers (G) or with Ctrl+Left/Right keys when the column header has keyboard focus.
 2. Columns can be reordered with drag and drop (dragging the handle (E) at the start of a column heading) or with Shift+Left/Right keys when the column h