เริ่มอาทิตย์ที่ 2 ของการฝึกงาน จากวันศุกร์ที่ผ่านมาได้ทำความเข้าใจเกี่ยวกับหลักการทำงานของ UI ของ OFBIZ ไปแล้ว วันนี้จะได้ทำ UI ที่เป็นการค้นหา เพิ่มข้อมูลนักศึกษา กันครับ ในการสร้างนี้เราจะใช้แบบจาก app example ที่ติดมากับ


ภาพด้านบนเป็นภาพของ UI ของ app example และ path
ในที่ได้บทความที่แล้ว จะเห็นว่าแรกที่ถูกเรียกจะเป็นไฟล์ controller.xml และจะมาเรียกไฟล์ *screen.xml ดังนั้นเราจะมาแก้ไขไฟล์ screen ที่ชื่อว่า main ในไฟล์ *screen.xml นี้ก่อนเลย (****ตอนนี้เราอยู่ที่ app หรือ component ที่เราสร้างไว้นะครับ อย่างลืม) ซึ่งเราจะสร้างหน้าค้นหาก่อน ซึ่งหน้าตาจะคล้ายกับ app example ในการแก้ไขไฟล์ *screen.xml จะได้โค้ดดังด้านล่างนี้

การสร้างหน้าค้นหานี้ เราจะใช้ template ของ OFBIZ สังเกต tag <decorator>
<link target="CreateStudent" text="${uiLabelMap.HelloappCreateStu}" style="buttontext create"/>
ในโค้ดข้างนี้เป็นการสร้าง ling ไปในหน้าการเพิ่มข้อมูล attribute text เป็นการกำหนดค่า ตัวหนังสือของ ling ในที่นี้จะใช้ข้อความในตัวแปร uiLabelMap ซึ่งตัวแปรแบบ global การใช้ตัวแปรนี้ที่สร้างขึ้นในไฟล์ HelloappUiLabels.xml ในโฟล์เดอร์ config ซึ่งสามารถสร้างขึ้นเพื่อรองรับกับภาษาได้หลายภาษา และ attribute target="CreateStudent" เป็น request map ไปหาหน้าเพิ่มข้อมูลนักศึกษา ซึ่งเราจะต้องไปสร้าง request map และ view map ใน controller.xml ดังนี้
<request-map uri="CreateStudent"><security https="true" auth="true"/><response name="success" type="view" value="CreateStudent"/></request-map>
<view-map name="CreateStudent" type="screen" page="component://helloapp/widget/HelloappScreens.xml#CreateStudent"/>
อธิบาย ่tag request-map เป็นการสร้างคีย์เวิร์ดที่ เพื่อรอรับหรือกรองค่าที่ส่งมาทาง URL เพื่อให้ไปทำงานต่อไป แล้วจะทำการตรวจสอบสิทธิ์ (<security https="true" auth="true"/>) และเมื่อทำการตรวจสอบนั้นผ่านจะทำการเรียก view-map ที่ชื่อว่า CreateStudent มาทำงาน (<response name="success" type="view" value="CreateStudent"/>) ในไฟล์ Forms.xml
จากตัวอย่างที่เห็น เมื่อรับค่าจาก URL ที่ตรงกับ CreateStudent ซึ่ง screen นี้ มีโค้ดดังนี้

ใน screen นี้จะ include form เข้ามา 1 form คือ CreateStudent ในไฟล์ *From.xml
<form name="CreateStudent" type="single" target="createStudent" default-map-name="studentMap">
<alt-target use-when="studentId!=null" target="editStudent"/>
<auto-fields-entity entity-name="student"/><field name="studentId" title="${uiLabelMap.HelloappFieldStuId}"/>
<field name="studentFname" title="${uiLabelMap.HelloappFieldStuFname}"/>
<field name="studentLname" title="${uiLabelMap.HelloappFieldStuLname}"/>
<field name="studentGrade" title="${uiLabelMap.HelloappFieldStuGrade}"/>
<field name="searchButton" title="${uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button-type="button" image-location="/images/icons/magnifier.png"/>
</field>
</form>
ซึ่งใน form นี้เราจะทำ form เพิ่มข้อมูลกับแก้ไขข้อมูลไว้ที่เดียวกัน โดยการตรวจสอบว่ามีปารส่งค่า studentId มาด้วยหรือไม่ (<alt-target use-when="studentId!=null" target="editStudent"/>) ในกรณีที่มีจะเปลียน target เป็น editStudent ถ้าไม่มีค่า จะเปลี่ยน target เป็น createStudent เพื่อที่จะเรียก request map ที่มี even เรียก service ที่เราได้ทำในบทความที่ผ่านมา ซึ่งอยู่ในโฟลเดอร์ servicedef ดังโค้ดด้านล่างนี้
request map ของการ เพิ่มข้อมูล
<request-map uri="createStudent">
<security https="true" auth="true"/>
<event type="service" invoke="createStudentJAVA"></event>
<response name="success" type="request-redirect-noparam" value="main"/>
</request-map>
request map ของ การแก้ไข
<request-map uri="editStudent">
<security https="true" auth="true"/>
<event type="service" invoke="updateStudentJAVA"></event>
<response name="success" type="request-redirect-noparam" value="main"/>
</request-map>
หลักจากการแก้ไขโดย service เป็นผลสำเร็จแล้ว จะทำการเรียก veiw map main ขึ้นมาทำงานต่อ
ในส่วนของ tag view-map จะเป็นเส้นทางในการเรียก screen ขึ้นมาทำงาน ตาม attribute page ที่ได้กำหนดไว้ จะตามด้วยชื่อของ screen
ต่อมาดู tage include-form
<include-form name="FindStudent" location="component://helloapp/widget/HelloappForms.xml"/>
.
.
.
<include-form name="listStudent" location="component://helloapp/widget/HelloappForms.xml"/>
จะใช้ในการ include form ซึ่ง form จะเป็นหน้าแสดงผลสร้างเป็นส่วนๆ เช่นส่วน form ค้นหา ส่วนตารางแสดงผล ส่วนปฏิทิน เป็นต้น ใน OFBIZ จะแยกออกเป็นส่วนๆ แล้วจะเข้ามาแสดงใน screen อีกที ในที่นี้จะดึง form ที่ชื่อว่า FindStudent (ส่วนที่เป็น form ให้กรอกให้ค้นหาข้อมูลนักเรียน) และ listStudent (เป็นส่วนที่เป็นตารางแสดงลิสต์ข้อมูลนักเรียนที่ค้นหามาได้) การแสดงผลจะเป็นดังภาพด้านล่างนี้


เรามาดูไฟล์*Form.xml 

จากที่ได้ดึง form เข้าไปแสดงใน screen แล้ว จากภาพด้านบนเป็น form ที่ถูกดึงไปแสดง จะมีอยู่ 2 form FindStudent และ listStudent
form แรกเป็น form ที่จะสร้างส่วนที่ให้กรอกข้อมูลค้นหา จะมีจะกำหนด target = "FindStudent" ซึ่งใน form นี้จะมีการทำหนด ให้มีช่องกรอกหรือ text field ให้เท่ากับ attribute ของ entity student และ ในกรณีที่ไม่กรอกข้อมูลหรือทำการค้นหาเลย จะเป็นการค้นหาหรือแสดงข้อมูลนักเรียนทั้งหมดแทน
<auto-fields-entity entity-name="student"/>
<field name="noConditionFind"><hidden value="Y"/></field>
จาก target ที่ได้กำหนดไปเราจำเป็นต้องกำหนด request map เพิ่มขึ้นมา
<request-map uri="FindStudent">
<security https="true" auth="true"/>
<response name="success" type="view" value="main"/>
</request-map>
ในการกำหนด request map จะคล้ายกับที่ได้กำหนดไว้ข้างต้น แต่ให้ สังเกต ที่ <response ... value="main"> ซึ่งหมายถึงให้กลับมาหน้าเดิม ดังนั้นค่าที่เราได้กรอกข้อมูล (parameters) ไปจะถูกส่งมาในหน้าเดิมเหมือนกัน ซึ่งจะถูกใช้โดย form listStudent
form listStudent จะถูกกำหนด type เป็น list ซึ่งจะให้ผลลัพธ์เป็นตารางข้อมูล จะมี field ต่างๆ เหมือน attibute ของ entity student (default-entity-name="student") และมีการกำหนด style ไว้ด้วย
ใน tag <action> จะเป็น tag ที่เป็นการเตรียมข้อมูลไว้ ในการประมวลผลหรือไว้ในการดำเนินการใน form นั้นๆ
<service service-name="performFind" result-map="result" result-map-list="listIt">
<field-map field-name="inputFields" from-field="parameters"/>
<field-map field-name="entityName" value="student"/>
<field-map field-name="orderBy" from-field="parameters.sortField"/>
<field-map field-name="viewIndex" from-field="viewIndex"/>
<field-map field-name="viewSize" from-field="viewSize"/>
</service>
ในที่นี้ได้ทำการดึงข้อมูลจากข้อมูลที่ได้กรอกจาก form FindStudent แล้วส่งค่ามาใน form นี้ (parameters) แล้วเก็บไว้ ใน map จากนั้นทำการนำมาแสดง
ในการแสดงผลลัพธ์จะเห็นว่าจะมี field เพิ่มมา 2 field คือ field ที่เป็นข้อความ edit หรือ แก้ไข และ field ที่เป็นข้อความ delete หรือ ลบ ขึ้นอยู่กับภาษาที่ใช้ ชึ่งเกิดจากโค้ดด้านล่างนี้
<field name="editStudent">
<hyperlink description="${uiLabelMap.CommonEdit}" target="EditStudent">
<parameter param-name="studentId" from-field=" studentId"/></hyperlink></field><field name="deleteStudent">
<hyperlink description="${uiLabelMap.CommonDelete}" target="deleteStudent"><parameter param-name="studentId" from-field="studentId"/></hyperlink>
</field>
ใน <field name="editStudent"> จะเป็นสร้าง ling ไปหน้าแก้ไขข้อมูลนักเรียน โดยได้ส่งค่า parameter ที่ว่า studentId ซึ่งเป็น PK ของข้อมูลในตาราง ซึ่งจะบ่งบอกข้อมูลได้อย่างชัดเจน (ในกรณีที่เป็น composite key จะต้องส่งไปทั้งสองตัว) ไปด้วย การกำหนด target="EditStudent" จะไปเรียก request map
<request-map uri="EditStudent">
<security https="true" auth="true"/>
<response name="success" type="view" value="CreateStudent"/>
</request-map>
สังเกตว่า <response ... value="CreateStudent"> มันเป็น view map ที่ไปหาหน้า เพิ่มข้อมูลนักเรียน ซึ่งเราได้สร้างให้เป็นใช้เป็นเพิ่มและแก้ไขในตัวเดียวกัน
และใน <field name="deleteStudent"> จะทำลบข้อมูลนักเรียน ในการลบก็จะส่งค่า parameter studentId ไปเช่นเดียวกัน และมี target="deleteStudent" การกำหนด request map
<request-map uri="deleteStudent">
<security https="true" auth="true"/>
<event type="service" invoke="deleteStudent"></event>
<response name="success" type="request-redirect-noparam" value="main"/>
</request-map>
ซึ่งจะเรียกใช้ service ที่เราสร้างในบทความที่ผ่านมา (<event type="service" invoke="deleteStudent"></event>) เสร้จแล้วจะเรียกหน้าหลักขึ้นมาทำงาน (หน้าค้นหาข้อมูลนักศึกษา)
ในการเขียนโค้ดที่ดีและเพื่อแก้ไขโค้ดได้ง่ายให้ ค่อยๆ พิมพ์ และ ทำการทดสอบอย่างสม่ำเสมอ ตลอดการเขียนโค้ด เพื่อที่จะหาข้อผิดพลาดได้ง่าย
นี้เป็นการสร้าง UI เพิ่ม แก้ไข ลบ และแสดงข้อมูลในรูปแบบรายการ ในวันต่อไปเราจะมาทำ เกี่ยวกับ REPORT กัน
No comments:
Post a Comment