feat: implement advanced bidirectional field referencing and cross-module path resolution
- Core Logic Enhancements:
- Implement bidirectional field referencing between <FIELDS>, <LAYOUT>, and <TITLES> tags in .frml files, enabling seamless navigation from definitions to usages and vice versa.
- Add robust support for AJAX-OPTION field mapping:
- SRC attribute: Links to field definitions within defs/ajax.xml datasets.
- TARGET attribute: Links to local field definitions within the same form.
- Implement global grid resolution: GRID-ID now searches across the current file and all recursively included files (<INCLUDE>).
- Enhance deep recursive search for fields/sections within nested tags like <SECTION>, <ROW>, and <FIELD-LIST>.
- Path Resolution & Helpers (DynFormPathUtils):
- Added support for module-relative paths starting with # (mapping to view/frm/).
- Added support for cross-module paths starting with / (mapping to WEB-INF/app/module/{module}/view/frm/).
- Implemented auto-correction for common keyboard typos (Thai 'ิ' instead of /).
- Added specialized helpers for locating ajax.xml and included files within the framework's structure.
- Smart Completion Enhancements:
- Added context-aware completion for TARGET and SRC fields in AJAX update-fields.
- Enabled global GRID-ID completion by scanning all included resources.
- Improved dataset completion to include both local and AJAX-defined datasets.
- Test Resources:
- Added a comprehensive set of real-world examples (bdgt04, bdgt05, bdgt06) in DevResources/full-examples/ to validate complex cross-module and master-detail scenarios.
This commit is contained in:
397
DevResources/dynform-exam.frml
Normal file
397
DevResources/dynform-exam.frml
Normal file
@@ -0,0 +1,397 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FORMS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/#dynf_form_def.xsd">
|
||||
<DATASETS>
|
||||
<DATASET ID="DS-BROWSER">
|
||||
<SCHEMA>APP</SCHEMA>
|
||||
<TABLENAME>V_ACTIVITY_TREE</TABLENAME>
|
||||
<KEYFIELDS>PROJ_ID,ACM_CODE</KEYFIELDS>
|
||||
<SQL>
|
||||
<SELECT>
|
||||
SELECT :PROJ_ID PROJ_ID
|
||||
, ACTT.ACM_CODE
|
||||
, ACTT.ACM_NAME
|
||||
, ACTT.ACM_SEQ
|
||||
, ACTT.NODE_LEVEL
|
||||
, ACTT.MAIN_NODE
|
||||
, ACTT.ACM_UNIT
|
||||
, ACTT.ACM_START_YEAR
|
||||
, ACTT.ACM_END_YEAR
|
||||
, ACTT.NODE_TYPE
|
||||
, PJBG.PBDG_TOTAL PBDG_TOTAL
|
||||
, PJBG.PBDG_COUNT PBDG_COUNT
|
||||
</SELECT>
|
||||
<FROM>
|
||||
FROM BGT.V_ACTIVITY_TREE ACTT
|
||||
INNER JOIN ( SELECT DISTINCT ACM.ACM_CODE
|
||||
FROM BUD.ACTIVITY_M ACM
|
||||
INNER JOIN BUD.ACTIVITY_CTRL_H ACH ON ACM.ACM_CODE = ACH.ACH_CODE
|
||||
START WITH ACM.ACM_CODE IN (SELECT ACM_CODE FROM PROJECT_BUDGETS PJBD WHERE PROJ_ID = :PROJ_ID)
|
||||
CONNECT BY PRIOR ACH.ACH_CTRL_CODE = ACH.ACH_CODE) FLTR ON FLTR.ACM_CODE = ACTT.ACM_CODE
|
||||
LEFT OUTER JOIN PROJECT_BUDGETS PJBG ON PJBG.PROJ_ID=:PROJ_ID AND PJBG.ACM_CODE = ACTT.ACM_CODE
|
||||
</FROM>
|
||||
<ORDER>ORDER BY ACTT.ACM_SEQ</ORDER>
|
||||
</SQL>
|
||||
</DATASET>
|
||||
|
||||
<DATASET ID="DS-MASTER">
|
||||
<SCHEMA>APP</SCHEMA>
|
||||
<TABLENAME>PROJECT_BUDGETS</TABLENAME>
|
||||
<KEYFIELDS>PROJ_ID,ACM_CODE</KEYFIELDS>
|
||||
<SQL>
|
||||
<SELECT>SELECT PROJ_ID
|
||||
, PBDG_ID
|
||||
, ACM_CODE
|
||||
, PBDG_TOTAL
|
||||
, PBDG_COUNT
|
||||
</SELECT>
|
||||
<FROM>FROM PROJECT_BUDGETS</FROM>
|
||||
<ORDER>ORDER BY PROJ_ID,PBDG_ID</ORDER>
|
||||
</SQL>
|
||||
<FIELDS>
|
||||
<FIELD NAME="PROJ_ID" TYPE="TEXT" LABEL="รหัสอ้างอิงโครงการ" WIDTH="32"/>
|
||||
<FIELD NAME="PBDG_ID" TYPE="TEXT" LABEL="รหัสงบประมาณโครงการ" WIDTH="32"/>
|
||||
<FIELD NAME="ACM_CODE" TYPE="TEXT" LABEL="รหัสกิจกรรม" WIDTH="20"/>
|
||||
<FIELD NAME="PBDG_TOTAL" TYPE="NUMBER" LABEL="ยอดรวม" WIDTH="15"/>
|
||||
<FIELD NAME="PBDG_COUNT" TYPE="NUMBER" LABEL="จำนวนกิจกรรม" WIDTH="15"/>
|
||||
</FIELDS>
|
||||
</DATASET>
|
||||
|
||||
<DATASET ID="DS-PROJECT-TARGETS">
|
||||
<SCHEMA>APP</SCHEMA>
|
||||
<TABLENAME>PROJECT_TARGETS</TABLENAME>
|
||||
<KEYFIELDS>PROJ_ID,ACM_CODE</KEYFIELDS>
|
||||
<SQL>
|
||||
<SELECT>SELECT PROJ_ID
|
||||
, ACM_CODE
|
||||
, PWMT_UNIT
|
||||
, PTGT_QT_0101
|
||||
, PTGT_QT_0102
|
||||
, PTGT_QT_0201
|
||||
, PTGT_QT_0202
|
||||
, PTGT_QT_0301
|
||||
, PTGT_QT_0302
|
||||
, PTGT_QT_0401
|
||||
, PTGT_QT_0402
|
||||
</SELECT>
|
||||
<FROM>FROM PROJECT_TARGETS</FROM>
|
||||
<ORDER>ORDER BY PROJ_ID,ACM_CODE</ORDER>
|
||||
</SQL>
|
||||
<FIELDS>
|
||||
<FIELD NAME="PROJ_ID" TYPE="TEXT" LABEL="รหัสอ้างอิงโครงการ" WIDTH="32"/>
|
||||
<FIELD NAME="ACM_CODE" TYPE="TEXT" LABEL="รหัสกิจกรรม" WIDTH="33"/>
|
||||
<FIELD NAME="PWMT_UNIT" TYPE="TEXT" LABEL="หน่วยนับ" WIDTH="32"/>
|
||||
<FIELD NAME="PTGT_QT_0101" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 1 (แผน)" WIDTH="15"/>
|
||||
<FIELD NAME="PTGT_QT_0102" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 1 (ผล)" WIDTH="15"/>
|
||||
<FIELD NAME="PTGT_QT_0201" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 2 (แผน)" WIDTH="15"/>
|
||||
<FIELD NAME="PTGT_QT_0202" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 2 (ผล)" WIDTH="15"/>
|
||||
<FIELD NAME="PTGT_QT_0301" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 3 (แผน)" WIDTH="15"/>
|
||||
<FIELD NAME="PTGT_QT_0302" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 3 (ผล)" WIDTH="15"/>
|
||||
<FIELD NAME="PTGT_QT_0401" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 4 (แผน)" WIDTH="15"/>
|
||||
<FIELD NAME="PTGT_QT_0402" TYPE="NUMBER" LABEL="เป้าหมายไตรมาส 4 (ผล)" WIDTH="15"/>
|
||||
<FIELD NAME="CREATE_BY" TYPE="TEXT" LABEL="ผู้สร้างรายการ" WIDTH="50"/>
|
||||
<FIELD NAME="CREATE_TIME" TYPE="DATE" LABEL="เวลาที่สร้างรายการ" WIDTH="0"/>
|
||||
<FIELD NAME="UPDATE_BY" TYPE="TEXT" LABEL="ผู้แก้ไขรายการล่าสุด" WIDTH="50"/>
|
||||
<FIELD NAME="UPDATE_TIME" TYPE="DATE" LABEL="เวลาที่แก้ไขรายการล่าสุด" WIDTH="0"/>
|
||||
</FIELDS>
|
||||
<MASTER-DATA DATASET-ID="DS-MASTER" MASTER-FIELDS="PROJ_ID,ACM_CODE" DETAIL-FIELDS="PROJ_ID,ACM_CODE"/>
|
||||
</DATASET>
|
||||
|
||||
<DATASET ID="DS-ATTACH_FILES">
|
||||
<SCHEMA>APP</SCHEMA>
|
||||
<TABLENAME>ATTACH_FILES</TABLENAME>
|
||||
<KEYFIELDS>PROJ_ID,ATFI_SEQ,ACM_CODE</KEYFIELDS>
|
||||
<SQL>
|
||||
<SELECT>SELECT ATFI_SEQ
|
||||
, PROJ_ID
|
||||
, ACM_CODE
|
||||
, ATFI_TYPE
|
||||
, ATFI_FILE
|
||||
, ATFI_MIME
|
||||
, ATFI_DESC
|
||||
, CREATE_BY
|
||||
, CREATE_TIME
|
||||
, UPDATE_BY
|
||||
, UPDATE_TIME
|
||||
</SELECT>
|
||||
<FROM>FROM ATTACH_FILES</FROM>
|
||||
<ORDER>ORDER BY PROJ_ID,ATFI_SEQ,ACM_CODE</ORDER>
|
||||
</SQL>
|
||||
<FIELDS>
|
||||
<FIELD NAME="ATFI_SEQ" TYPE="NUMBER" LABEL="ลำดับไฟล์แนบ" WIDTH="2147483646"/>
|
||||
<FIELD NAME="PROJ_ID" TYPE="TEXT" LABEL="รหัสโครงการ" WIDTH="50"/>
|
||||
<FIELD NAME="ACM_CODE" TYPE="TEXT" LABEL="รหัสกิจกรรม" WIDTH="25"/>
|
||||
<FIELD NAME="ATFI_TYPE" TYPE="TEXT" LABEL="ประเภทไฟล์แนบ" WIDTH="25"/>
|
||||
<FIELD NAME="ATFI_FILE" TYPE="TEXT" LABEL="ชื่อไฟล์แนบ" WIDTH="250"/>
|
||||
<FIELD NAME="ATFI_MIME" TYPE="TEXT" LABEL="ชนิดของไฟล์แนบ (MIME Type)" WIDTH="100"/>
|
||||
<FIELD NAME="ATFI_DESC" TYPE="TEXT" LABEL="คำอธิบาย/รายละเอียดไฟล์แนบ" WIDTH="250"/>
|
||||
</FIELDS>
|
||||
<MASTER-DATA DATASET-ID="DS-MASTER" MASTER-FIELDS="PROJ_ID,ACM_CODE" DETAIL-FIELDS="PROJ_ID,ACM_CODE"/>
|
||||
</DATASET>
|
||||
|
||||
|
||||
</DATASETS>
|
||||
|
||||
<FORM>
|
||||
<FORM_BROWSE DATAID="DS-BROWSER">
|
||||
<HEADER NAVI="Y" ADD="Y" EDIT="Y" DELETE="Y"/>
|
||||
<PAGESIZE>0</PAGESIZE>
|
||||
<FIELDS>
|
||||
<FIELD NAME="$itemno" LABEL="no" ALIGN="right" WIDTH="5em"/>
|
||||
<FIELD NAME="ACM_CODE" LABEL="project.acm_code" ALIGN="left" WIDTH="15em">
|
||||
<DATA-FORMATTER>
|
||||
<![CDATA[(value,row,idx)=>{return $(`<div class="col-24 row"><div class="col offset-${row.node_level}">${value}</div></div>`);}]]>
|
||||
</DATA-FORMATTER>
|
||||
</FIELD>
|
||||
<FIELD NAME="ACM_NAME" LABEL="project.acm_name" ALIGN="left">
|
||||
<DATA-FORMATTER>
|
||||
<![CDATA[(value,row,idx)=>{return $(`<div class="col-24 row"><div class="col offset-${row.node_level}">${value}</div></div>`);}]]>
|
||||
</DATA-FORMATTER>
|
||||
</FIELD>
|
||||
<FIELD NAME="PBDG_COUNT" LABEL="project.PBDG_COUNT" ALIGN="right" WIDTH="10em">
|
||||
<DATA-FORMATTER>
|
||||
<![CDATA[
|
||||
(value,row,idx)=>{ return (row["node_type"]==="C")?value:""}
|
||||
]]>
|
||||
</DATA-FORMATTER>
|
||||
</FIELD>
|
||||
<!-- <FIELD NAME="PBDG_TOTAL" LABEL="project.bgt_amount" ALIGN="right" WIDTH="10em"/>-->
|
||||
<COMMAND-BUTTONS>
|
||||
<BUTTONS-FILTER>
|
||||
<EDIT><![CDATA[(row)=>{return row["node_type"] !== "C"}]]></EDIT>
|
||||
<DELETE><![CDATA[(row)=>{return row["node_type"] !== "C"}]]></DELETE>
|
||||
<VIEW><![CDATA[(row)=>{return row["node_type"] !== "C"}]]></VIEW>
|
||||
</BUTTONS-FILTER>
|
||||
</COMMAND-BUTTONS>
|
||||
</FIELDS>
|
||||
<FILTERS AUTO-APPLY="Y" ALLOW-NO-FILTER="Y" >
|
||||
<FIELDS>
|
||||
<FIELD NAME="PROJ_YEAR" CAPTION="project.year" INPUTTYPE="COMBOBOX">
|
||||
<LIST-OPTION TABLE="VL_YEAR" TEXT="#DV_YEAR" VALUE="DV_YEAR" ORDER="DV_YEAR" FIRSTLIST="@{NONE}"/>
|
||||
</FIELD>
|
||||
<FIELD NAME="ACM_NAME" CAPTION="project.acm_name" INPUTTYPE="TEXT" SEARCH-ORIGIN="ACM_NAME='%${VALUE}%'"/>
|
||||
<FIELD NAME="PROJ_ID" INPUTTYPE="HIDDEN"></FIELD>
|
||||
</FIELDS>
|
||||
<LAYOUT>
|
||||
<ROW>
|
||||
<FIELD NAME="PROJ_YEAR" CAPT_WIDTH="10" VAL_WIDTH="14" LAYOUT_WIDTH="12"/>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<FIELD NAME="ACM_NAME" CAPT_WIDTH="6" VAL_WIDTH="14" LAYOUT_WIDTH="20"/>
|
||||
</ROW>
|
||||
</LAYOUT>
|
||||
</FILTERS>
|
||||
<FOOTER SHOW="Y"/>
|
||||
<SCRIPT>
|
||||
<INITIALIZE>
|
||||
<![CDATA[
|
||||
{
|
||||
console.log("init activity grid");
|
||||
|
||||
const fieldFormat = (value) => {
|
||||
return formatNumber(value, 0);
|
||||
}
|
||||
|
||||
const summary = (field, data) => {
|
||||
let total = 0;
|
||||
for (let id=0; id < data.length; id++) {
|
||||
let row = data[id];
|
||||
if (row["node_type"] === "D") {
|
||||
total += (+row[field]) || 0;
|
||||
}
|
||||
}
|
||||
if ($PageCtx.$dataGrid.load && !$PageCtx.$dataGrid.reload) {
|
||||
$PageCtx.$dataGrid.reload = true;
|
||||
for (let id=data.length-1; id>=0; id--) {
|
||||
let row = data[id];
|
||||
if (row["node_type"] === "C") {
|
||||
let grpTotal = 0;
|
||||
let mainNode = row["acm_code"];
|
||||
let nodes = [];
|
||||
nodes.push($$("main_node="+mainNode,data));
|
||||
for (let node of nodes.flat()) {
|
||||
grpTotal += +node[field];
|
||||
}
|
||||
data[id][field] = grpTotal;
|
||||
}
|
||||
}
|
||||
$PageCtx.$dataGrid.load(data);
|
||||
$PageCtx.$dataGrid.reload = false;
|
||||
}
|
||||
return formatNumber(total, 0);
|
||||
}
|
||||
|
||||
const $ctx = $PageCtx;
|
||||
const gridFields = [$$("field^pbdg_", $ctx.gridColumn.flat())].flat();
|
||||
for (let field of gridFields) {
|
||||
field.formatter = fieldFormat;
|
||||
field.footerFormatter = function (data) {
|
||||
return summary(this.field, data);
|
||||
}
|
||||
}
|
||||
|
||||
$ctx.rowStyle = function (row, index) {
|
||||
if (row["node_type"] === "C") {
|
||||
return {
|
||||
classes : `group-level-${row["node_level"]}`
|
||||
};
|
||||
}
|
||||
return {}; // Default style for other rows
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</INITIALIZE>
|
||||
</SCRIPT>
|
||||
</FORM_BROWSE>
|
||||
|
||||
<FORM_ENTRY DATAID="DS-MASTER" SAVE="Y" RETURN="Y">
|
||||
<FIELDS>
|
||||
<FIELD NAME="PROJ_ID" INPUTTYPE="HIDDEN"/>
|
||||
<FIELD NAME="PBDG_ID" INPUTTYPE="HIDDEN"/>
|
||||
<FIELD NAME="VACM_CODE" CAPTION="project.acm_code" INPUTTYPE="TEXT" REQUIRE="Y" READONLY="Y"/>
|
||||
<FIELD NAME="PROJ_YEAR" CAPTION="project.year" INPUTTYPE="TEXT" REQUIRE="Y" READONLY="Y"/>
|
||||
<FIELD NAME="PROJ_PRINCIPLES" CAPTION="project.remak" INPUTTYPE="TEXT" ROWS="3"/>
|
||||
<FIELD NAME="ACM_CODE" CAPTION="project.acm_name" INPUTTYPE="COMBOBOX" REQUIRE="Y" EDIT-READONLY="Y">
|
||||
<AJAX-OPTION URL="/api-data.jbx" DATASET="DS-ACTIVITY-01" VALUE-FIELD="ACM_CODE" TEXT-FIELD="ACM_NAME" PARAMETERS="DV_YEAR=PROJ_YEAR,STM_CODE=STM_CODE">
|
||||
<UPDATE-FIELDS>
|
||||
<FIELD SRC="ACM_CODE" TARGET="VACM_CODE"></FIELD>
|
||||
<FIELD SRC="ACM_UNIT" TARGET="TARGET_UNIT"></FIELD>
|
||||
<FIELD SRC="ACM_UNIT" TARGET="PWMT_UNIT"></FIELD>
|
||||
<FIELD SRC="PJM_CODE" TARGET="PJM_CODE"></FIELD>
|
||||
</UPDATE-FIELDS>
|
||||
</AJAX-OPTION>
|
||||
<LIST-OPTION>
|
||||
<FORMATTER><![CDATA[
|
||||
(data) => {
|
||||
console.log("call formater with ", data);
|
||||
let code = data.acm_code;
|
||||
let nodeLevel = +data.node_level;
|
||||
if (data.node_type === "C") {
|
||||
data.disabled = true;
|
||||
code = "#".repeat(nodeLevel+1);
|
||||
}
|
||||
return $(`<div class="d-flex flex-row"><div class="text-nowrap offset-${nodeLevel}">[${code}]</div> : <div>${data.acm_name}</div></div>`);
|
||||
}
|
||||
]]></FORMATTER>
|
||||
</LIST-OPTION>
|
||||
</FIELD>
|
||||
|
||||
<SECTION ID="SECT-PROJECT-TARGET">
|
||||
<FIELD NAME="PBDG_TOTAL" INPUTTYPE="HIDDEN"/>
|
||||
<FIELD NAME="PBDG_COUNT" INPUTTYPE="HIDDEN"/>
|
||||
<FIELD NAME="PWMT_UNIT" CAPTION="project.target" INPUTTYPE="TEXT" READONLY="Y"></FIELD>
|
||||
<FIELD NAME="QUOTER_1" INPUTTYPE="MULTI-FIELD" CAPTION="project.quoter 1" FIELD-SEPARATOR="/">
|
||||
<FIELD-LIST>
|
||||
<FIELD NAME="PTGT_QT_0101" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
<FIELD NAME="PTGT_QT_0102" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
</FIELD-LIST>
|
||||
</FIELD>
|
||||
<FIELD NAME="QUOTER_2" INPUTTYPE="MULTI-FIELD" CAPTION="project.quoter 2" FIELD-SEPARATOR="/">
|
||||
<FIELD-LIST>
|
||||
<FIELD NAME="PTGT_QT_0201" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
<FIELD NAME="PTGT_QT_0202" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
</FIELD-LIST>
|
||||
</FIELD>
|
||||
<FIELD NAME="QUOTER_3" INPUTTYPE="MULTI-FIELD" CAPTION="project.quoter 3" FIELD-SEPARATOR="/">
|
||||
<FIELD-LIST>
|
||||
<FIELD NAME="PTGT_QT_0301" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
<FIELD NAME="PTGT_QT_0302" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
</FIELD-LIST>
|
||||
</FIELD>
|
||||
<FIELD NAME="QUOTER_4" INPUTTYPE="MULTI-FIELD" CAPTION="project.quoter 4" FIELD-SEPARATOR="/">
|
||||
<FIELD-LIST>
|
||||
<FIELD NAME="PTGT_QT_0401" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
<FIELD NAME="PTGT_QT_0402" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
</FIELD-LIST>
|
||||
</FIELD>
|
||||
<FIELD NAME="TOTAL_QT" INPUTTYPE="MULTI-FIELD" CAPTION="project.total" FIELD-SEPARATOR="/" READONLY="Y">
|
||||
<FIELD-LIST>
|
||||
<FIELD NAME="QT_TOTAL_01" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
<FIELD NAME="QT_TOTAL_02" INPUTTYPE="TEXT" DATATYPE="NUMBER" DECIMAL="0"></FIELD>
|
||||
</FIELD-LIST>
|
||||
</FIELD>
|
||||
</SECTION>
|
||||
|
||||
<SECTION ID="SEC-ATTATCH-FILE">
|
||||
<FIELD NAME="FILE_LIST_BOX" CAPTION="file.upload" INPUTTYPE="FILE-LIST-BOX">
|
||||
<FILE-LIST-BOX DATASET="DS-ATTACH_FILES" FILE-TYPE="ATFI_TYPE" FILE-PATH="ATFI_FILE" FILE-DESC="ATFI_DESC"/>
|
||||
<FILE-BOX FILE-TYPE="budget" FILE-ACCEPTS="pdf,docx,xlsx,jpeg,jpg,png"
|
||||
UPLOAD-URL="/file-upload.jbx" FILE-URL="/get-file.jbx"
|
||||
DEFAULT-NAME="@{proj_id}/@{acm_code}/file-01"/>
|
||||
</FIELD>
|
||||
</SECTION>
|
||||
</FIELDS>
|
||||
|
||||
<LAYOUT CLASS="block-layout-form">
|
||||
<SECTION ID="SECT-MAIN">
|
||||
<ROW>
|
||||
<FIELD NAME="PROJ_YEAR" LAYOUT_WIDTH="6" OFFSET="6"/>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<FIELD NAME="VACM_CODE" LAYOUT_WIDTH="6"/>
|
||||
<FIELD NAME="ACM_CODE" LAYOUT_WIDTH="18"/>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<FIELD NAME="PROJ_PRINCIPLES" LAYOUT_WIDTH="18" OFFSET="6"/>
|
||||
</ROW>
|
||||
</SECTION>
|
||||
<SECTION ID="SECT-PROJECT-TARGET" TYPE="DATA-SECTION" DATASET="DS-PROJECT-TARGETS">
|
||||
<ROW>
|
||||
<FIELD NAME="PWMT_UNIT" LAYOUT_WIDTH="6"/>
|
||||
<FIELD NAME="QUOTER_1" LAYOUT_WIDTH="3"/>
|
||||
<FIELD NAME="QUOTER_2" LAYOUT_WIDTH="3"/>
|
||||
<FIELD NAME="QUOTER_3" LAYOUT_WIDTH="3"/>
|
||||
<FIELD NAME="QUOTER_4" LAYOUT_WIDTH="3"/>
|
||||
<FIELD NAME="TOTAL_QT" LAYOUT_WIDTH="4"/>
|
||||
</ROW>
|
||||
</SECTION>
|
||||
|
||||
<SECTION ID="SECT-FILE-UPLOAD" >
|
||||
<HEADER CLASS="col-24 pd-t-16">
|
||||
<![CDATA[<h4 class="ml-3 border-bottom-1 col-24">@M{project.constructor_attatchment}</h4>]]>
|
||||
</HEADER>
|
||||
<ROW>
|
||||
<FIELD NAME="FILE_LIST_BOX" LAYOUT_WIDTH="16" OFFSET="4"/>
|
||||
</ROW>
|
||||
</SECTION>
|
||||
</LAYOUT>
|
||||
|
||||
<SCRIPT>
|
||||
<EVENTS>
|
||||
<BEFORE-SAVE><![CDATA[
|
||||
({form, data}) => {
|
||||
console.log("before save data");
|
||||
if ($PageCtx.$action === "add") {
|
||||
let $data = $PageCtx.main.pageData;
|
||||
let budgetId = $$("VACM_CODE").val();
|
||||
$$("PBDG_ID").val(budgetId);
|
||||
}
|
||||
|
||||
let acmCount = $$("^QT_TOTAL_0").sum();
|
||||
$$("PBDG_COUNT").val(acmCount);
|
||||
let gridCtx = ($PageCtx.widgets["GRID-BUDGET"]||{})["$GridCtx"];
|
||||
if (gridCtx) {
|
||||
let bdgTotal = gridCtx.sum_of["pbgi_total"];
|
||||
$$("PBDG_TOTAL").val(bdgTotal);
|
||||
}
|
||||
Object.assign(data,form.mainForm.jsonData());
|
||||
}
|
||||
]]></BEFORE-SAVE>
|
||||
</EVENTS>
|
||||
<INITIALIZE>
|
||||
<![CDATA[
|
||||
const quoterSum = ()=>{
|
||||
for (let sect=1; sect <=2; sect++) {
|
||||
let summary = 0;
|
||||
for (let qt = 1; qt <= 4; qt++) {
|
||||
summary += $$(`PTGT_QT_0${qt}0${sect}`).number();
|
||||
}
|
||||
$$(`QT_TOTAL_0${sect}`).val(formatNumber(summary));
|
||||
}
|
||||
}
|
||||
$$("^PTGT_QT_").on("change",quoterSum);
|
||||
]]>
|
||||
</INITIALIZE>
|
||||
</SCRIPT>
|
||||
</FORM_ENTRY>
|
||||
</FORM>
|
||||
</FORMS>
|
||||
Reference in New Issue
Block a user