[K2 smartform] เพิ่ม Select All check box ให้กับ List View

สวัสดีครับเพื่อนๆ จากคราวที่แล้ว ที่คุณกายได้มาแชร์เรื่อง การทำ Check Box บน List View ก็มีคำถามเพิ่มเติมเข้ามาว่า แล้วอยากทำ Select All จะมีแนวทางอย่างไร คุณกายเลยเพิ่มเติมเข้ามาให้ครบ ลองมาดูกันครับผม

การเพิ่ม Select All

เพิ่ม Rule ไปที่ ChkAll

Advertisements

[k2 smartform] การทำ Check Box บน List View

สวัสดีครับเพื่อนๆ สำหรับ K2 Ranger วันนี้ เราได้รับเกียรติจาก “คุณกาย” K2 Champion ที่คอยช่วยตอบปัญหาด้านเทคนิค ให้กับพี่ๆ น้องๆ ในห้อง K2 Technical Rock อยู่สม่ำเสมอ ทาง K2 Ranger ทีมเลยขอส่งเทียบเชิญให้ช่วยเขียนบทความให้กับคอมมูนิตี้ของเราครับ

และตอนนี้ คุณกายได้ส่งมาให้เรียบร้อยแล้ว K2 Ranger ขอขอบคุณ “คุณกาย” มา ณ ที่นี้ด้วยครับ

Sky - K2 Technical Rock
คุณกายกับหนุ่มน้อย

Continue reading [k2 smartform] การทำ Check Box บน List View

[Authentication] – Using LDAP with K2

สวัสดีครับ ช่วงนี้ได้มีโอกาสทำอะไรใหม่ๆ อีกอย่างเลยเอามาเขียนเป็น blog ซะหน่อย นั่นคือ configure K2 ให้มองเห็น LDAP ที่ไม่ใช่ LDAP ของ AD แต่ถ้าเป็น LDAP ของ AD ก็น่าจะใช้ได้เหมือนกัน โดย step ที่ต้องทำมีตามด้านล่าง

  • Register Security label ของ LDAP
  • Configure Claim ใน SmartForms

 

เรามาเริ่มจาก Register Security label ของ LDAP ให้เปิด database K2 ที่ table HostServer.SecurityProvider

provider

ให้ copy GUID ของ ProviderClassName ที่เป็น SourceCode.Security.Providers.LdapProvider.Trusted.Ldap เอามาใส่ใน script ด้านล่าง ส่วนที่เป็นตัวแปร AuthSecurityProviderID

ส่วนอื่นที่ต้องเปลี่ยนจะมีหลายอันตาม highlight สีน้ำเงิน สามารถไปดูรายละเอียดได้จาก https://help.k2.com/onlinehelp/k2blackpearl/icg/4.7/default.htm#Configure/UM-LDAP-config.htm%3FTocPath%3DConfigure%7CUser%2520Managers%7C_____3 นะครับ

DECLARE @SecurityLabelName NVARCHAR(20) = ‘K2LDAP‘; –Update as needed
DECLARE @XmlConfig XML =
‘<AuthInit><LdapConnection LdapServer=”Server Name” LdapServerPort=”389” LdapSsl=”false” LdapAuthTypeConnect=”Basic” LdapAuthTypeAuthenticateUser=”Basic” LdapResolveAuthenticationUserToDistinguishedName=”true” LdapAutoBind=”false” LdapScope=”Subtree” LdapConnectIntegrated=”false” LdapConnectUserName=”uid=username,ou=People,dc=xxx,dc=xxx” LdapConnectUserPassword=”password” LdapTimeout=”0″ LdapProtocolVersion=”3″ LdapServerCertificatePath=”” /><LdapUserBaseObject>ou=People,dc=xxx,dc=xxx</LdapUserBaseObject><LdapUserSearchFormatString>(uid={0})</LdapUserSearchFormatString><LdapUserGroupSearchFormatString>(memberOf={0})</LdapUserGroupSearchFormatString><LdapUserAttributes><K2LdapMapping K2Name=”ID” LdapName=”uid” ObjectType=”System.String” /><K2LdapMapping K2Name=”Name” LdapName=”uid” ObjectType=”System.String” /><K2LdapMapping K2Name=”Email” LdapName=”mail” ObjectType=”System.String” /><K2LdapMapping K2Name=”CommonName” LdapName=”cn” ObjectType=”System.String” /><K2LdapMapping K2Name=”UserPrincipalName” LdapName=”uid” ObjectType=”System.String” /><K2LdapMapping K2Name=”DisplayName” LdapName=”cn” ObjectType=”System.String” /><K2LdapMapping K2Name=”Mobile” LdapName=”mobile” ObjectType=”System.String” /></LdapUserAttributes><LdapGroupBaseObject>ou=Group,dc=xxx,dc=xxx</LdapGroupBaseObject><LdapGroupSearchFormatString>(uid={0})</LdapGroupSearchFormatString><LdapGroupMemberSearchFormatString>(cn={0})</LdapGroupMemberSearchFormatString><LdapGroupAttributes><K2LdapMapping K2Name=”ID” LdapName=”cn” ObjectType=”System.String” /><K2LdapMapping K2Name=”Name” LdapName=”cn” ObjectType=”System.String” /><K2LdapMapping K2Name=”Email” LdapName=”mail” ObjectType=”System.String” /><K2LdapMapping K2Name=”Member” LdapName=”member” FullOnly=”true” SearchQuery=”(&amp;(objectCategory=Person)(objectCategory=User))” SearchResultProperty=”cn” ObjectType=”System.Collections.ArrayList” /></LdapGroupAttributes></AuthInit>’
DECLARE @SecurityLabelID UNIQUEIDENTIFIER = NEWID(); –Assigning new GUID
DECLARE @AuthSecurityProviderID UNIQUEIDENTIFIER = ‘EE554827-1C61-46EF-9146-293CE74E55C9‘;
DECLARE @AuthInit XML = @XmlConfig;
DECLARE @RoleSecurityProviderID UNIQUEIDENTIFIER = @AuthSecurityProviderID;
DECLARE @RoleInit XML = @XmlConfig;
DECLARE @DefaultLabel BIT = NULL; –1 = true, NULL and 0 = false

DELETE FROM [SecurityLabels] WHERE SecurityLabelName = @SecurityLabelName;
INSERT INTO [SecurityLabels] VALUES (@SecurityLabelID, @SecurityLabelName, @AuthSecurityProviderID, @AuthInit, @RoleSecurityProviderID, @RoleInit, @DefaultLabel)

จะมีบางอันที่อาจจะหาลำบากคือ ldapname กับ userbaseobject แนะนำให้ใช้พวก ldap browser เช่น http://www.ldapadministrator.com หรือ http://www.ldapadmin.org เพื่อหาข้อมูลที่ถูกต้องได้

ldap browser

เมื่อได้ script เรียบร้อย เราก็เอาไปรันใน database K2

LDAP Register

เสร็จแล้วให้ restart service K2 และเราก็พร้อมที่จะทำ step ถัดไป คือการ configure claim ให้เข้าไปที่ management site ของ K2 ไปที่ Authentication => Claims => Claims แล้วกด New

02

ใส่ข้อมูลตามด้านล่าง

03

กดปุ่ม OK แล้วไปทดสอบด้วยการ login ผ่าน form ได้เลย

Login

ถ้าใครไปลองแล้วติดอะไรก็สอบถามได้นะครับ ในส่วนของ blog นี้ ใช้ได้กับทั้ง K2 Five และ K2 blackpearl นะครับ ลองแล้วใช้งานได้ทั้ง 2 version ครับ ไว้เจอกันใหม่คราวหน้าครับ 🙂

10 เทคนิคที่ทำให้ List View ของคุณโหลดเร็ว!!

List View เป็นการแสดงข้อมูลแบบหลาย records (ใครเขียน coding จะคล้ายๆ Grid view ใน C#) ในที่นี้จะขอรวมเทคนิคในการทำให้การเปิด List View ของคุณนั้นเร็วขึ้นมาอย่างแน่นอน

1. เรียกใช้ rule ในการ List แบบ Asynchronous

เปลี่ยนการเรียก execution block จาก then เป็น asynchronous ช่วยให้เรียก rule ได้อย่างรวดเร็วไม่ต้องรอจนทำงานเสร็จก่อนเรียก rule ถัดไป

execution block

ตอนแก้เสร็จก็ทดสอบก่อนนะ บางครั้งเราต้องรอข้อมูลก่อนหน้าให้โหลดเสร็จ แบบนี้ก็ต้องใช้ then ไปเนอะ

2. เปิด option ให้แสดงผลแบบ Paging

เปิด paging ใน list view แล้วจำกัดจำนวน item ที่จะเห็นในหน้าจอ จะช่วยลดปริมาณข้อมูลที่ต้องดึงมาแสดงผลที่หน้าจอได้

setting

ไม่ได้มีเลขเป๊ะ ๆ ว่าควรแสดงกี่รายการ แต่ส่วนใหญ่ที่ทำมักจะใช้ในช่วง 10 – 50 รายการต่อหน้าจอครับ

3. ลดการใช้งาน Association

ปกติจะใช้ร่วมกับ List Display ในกรณีที่เราเก็บ ID เป็น reference ไว้ แล้วต้องการไปดึงค่า Value ออกมาแสดงโดยอ้างอิงจาก ID

ถ้าเราอยากให้ performance ในการโหลด List View เร็วขึ้น สามารถทำได้โดยการทำการ join ในข้อมูลตั้งแต่ data source เองเช่น การเขียน Stored procedure หรือเขียน view ใน SQL ก็จะช่วยลดการทำงานในส่วนของ List Display และ association นี้ลงได้ (แต่ถ้าไม่ได้ช้ามาก ใช้ association ก็สะดวกดีครับ)

4. ลดจำนวน Column ที่แสดงใน List View

จำนวน column ที่แสดงน้อยลงจะทำให้ตอน bind เข้า List view สามารถแสดงผลได้รเ็วขึ้นไปอีก อ่อ..ต้องลบออกนะครับ ไม่ใช่แค่ซ่อนด้วย Visible = false

removeColumn

5. ลดจำนวน Properties ที่ส่งกลับมาจาก SmartObjects

โดยปกติถ้าเราสร้าง SmartObjects จากตารางบนฐานข้อมูล ใน SmartObjects จะมีจำนวน Properties เท่ากับจำนวนคอลัมน์ในตารางเลย ซึ่งเราสามารถไปลบ properties นี้ออก หรือเลือกให้ส่งกลับมาเฉพาะ properties ที่เราจะใช้ก็พอ

bind.png

หรือถ้ามีคนอื่นใช้ method นี้อยู่ด้วย ไปสร้าง method แยกไว้สำหรับหน้านี้โดยเฉพาะก็ยังได้ครับ

6. แสดงไฟล์ใน List View ด้วยลิงค์สำหรับดาวน์โหลด แทนที่จะแสดง file content

กรณีถ้าเราต้องโหลดไฟล์ขนาดใหญ่หรือไฟล์เล็ก ๆ จำนวนมากใน 1 หน้าจอก็ตาม การแสดงผลด้วย data type เป็น File จะโหลดไฟล์จริงขึ้นมาด้วย ถ้ายิ่งไฟล์มีขนาดใหญ่ ก็จะใช้ระยะเวลานานในการโหลดข้อมูล

fileListView.png

เราสามารถเปลี่ยนวิธีการเก็บไฟล์ไปอยู่บน shared network path หรือ Content Management System (CMS) เช่น SharePoint แทนได้ และแสดงผลเป็นลิ้งค์แทน เมื่อผู้ใช้งานต้องการเปิดไฟล์ ค่อยกดลิ้งค์ที่เราแสดงเพื่อไปโหลดไฟล์นั้นตรงจากที่ที่เราเก็บไฟล์ไว้ได้

7. ใช้ Input Properties ในการดึงข้อมูลแทนที่จะใช้ Filter

Filter นั้นมีความสามารถในการช่วยกรองข้อมูลที่จะแสดงใน List View ได้ด้วยเงื่อนไขต่าง ๆ แต่คุณรู้หรือไม่ว่าการใช้ Filter นั้นทำให้การแสดงผลใน List View ช้าลง เพราะข้อมูลจะถูกดึงมาทั้งหมดก่อนจึงจะมากรองออกด้วย Filter เพื่อแสดงผลในหน้าจอ

filter.png

การใช้ Input properties นั้นหลังบ้านมันคือการใส่ Where casue ว่า Input properties = ‘Value’ นั่นเอง ทำให้สำหรับหลายกรณี เจอว่า Input Properties นั้นไม่เพียงพอ เพราะต้องการค้นหาด้วยเงื่อนไขอื่นเช่น Contains, Greater than บ้าง

วิธีปรับคือพยายามควรป้อนข้อมูลใน Input properties ได้มากที่สุดก่อนเพื่อลดปริมาณข้อมูลที่ต้องโหลดขึ้นมา แล้วจึงเลือกใช้ Filter ต่ออีกทีเพื่อใส่เงื่อนไขแบบซับซ้อนลงไป หรือถ้าพบยังไม่เพียงพอ ผมก็จะใช้ View หรือ stored procedure มาช่วยรองรับเงื่อนไขแบบซับซ้อนครับ

8. ตรวจสอบว่าไม่โหลดข้อมูลซ้ำ 2 รอบ

ในการสร้าง List View ต่อกับ SmartObjects จะมี option ที่หน้า general ตรงด้านล่างว่าจะให้ Call this method when the form loads เลยหรือไม่

ถ้าไปติ๊กเลือก option นี้ระบบจะไปสร้าง rule Get List ไว้ใน View Initilize และถ้าลากไปใช้ใน Form Method Get List นี้ก็จะถูกเรียกใน Form Initilizing ด้วย (นอกจากนี้ด้วยค่า default ไม่ได้ใส่ input properties เลยทำให้มันจะดึงข้อมูลขึ้นมาทั้งหมด!!)

ListViewsGet.png

เคสที่เคยเจอคือมีไปเลือก option นี้ใน View ทำให้มีการโหลดข้อมูลแบบทั้งหมดขึ้นมา และเพิ่ม rule ใน Form initilzing ต่อ โดยโหลดข้อมูลแบบใส่ input properties ทำให้ตอนทดสอบแสดงผลที่หน้าจอถูกนะ แต่กว่าจะเปิดขึ้นมาทีช้ามาก วิธีแก้คือไปเอา rule นี้ออกซะ หรือเพิ่มเงื่อนไขให้เช็คก่อนใน View Initilize

9. ปิดการใช้ SmartForm ListView Row Count

จากที่เคยเขียน Blog ว่าด้วยเรื่องการแสดง Paging ใน Listview และ แก้ปัญหา SmartObjects สร้างข้อมูลซ้ำ หลังบ้านมีการทำงานโดยไปเรียก List method ขึ้นมา 2 ครั้งเพืื่อหาจำนวน page และเพื่อแสดงรายการ ทำให้เวลาในการโหลดข้อมูลนานขึ้น การไปตั้งค่า SmartObject.RuntimeListViewRowCount = false ก็จะช่วยให้ List method ต่าง ๆ ทำงานได้เร็วขึ้น

10. Tuning data source

ข้อนึงที่มักจะมองข้ามกัน คือการตรวจสอบที่ data soruce ตั้งต้นด้วยครับ ว่าเรียกใช้งานตรงๆ (ด้วยค่า input เดียวกับที่เราเรียกใน List view) ใช้ระยะเวลาเท่าไหร่ ถ้าระยะเวลาในการโหลดนานย่อมส่งผลต่อการเรียกผ่าน List View ไปด้วย

ส่วนวิธีแก้ให้ทำการปรับแต่งตั้งแต่ที่ data source ด้วยครับ เช่นการใส่ index ใน view หรือ table, การแก้ logic ที่ web service หรือ stored procedure ให้ทำงานเร็วตั้งต้นทาง

สำหรับเทคนิคที่ได้แนะนำไปมีทั้งทำง่าย ๆ ปรับตามได้เลย จนไปถึงยากมีต้องใช้ effort ในการทำที่มากน้อยต่างกันไป ขอให้ลองเลือกใช้ให้เหมาะสมนะครับ ว่าจะเลือกปรับตามข้อไหนและความเร็วที่ได้จากการ tuning นั้นคุ้มค่ากับที่เราลงแรงทำไปหรือเปล่า

แก้ปัญหา SmartObjects สร้างข้อมูลซ้ำ

มาจากคำถามจากทางบ้านอีกเช่นกันครับ สำหรับปัญหาที่ว่าสร้างข้อมูลจาก SmartObjects แล้วพบว่ามีข้อมูลเข้าไป 2 records

ถ้าใครเจอปัญหานี้เหมือนกันให้ลองตรวจสอบว่าเราได้ตั้งค่าหรือมีอาการตามนี้หรือไม่

  1. SmartObjects ต่อกับ Stored procedure ใน SQL
  2. Method ใน SmartObjects ที่ใช้สร้างข้อมูลเป็น type แบบ List
  3. ทดสอบเรียกผ่าน SmartObjects Services Tester แล้วพบว่าสร้าง 1 record แต่ถ้าเรียกผ่าน SmartForm แล้วเข้าไป 2 records

methodList.png

ถ้าใครเจอว่ามีอาการดังกล่าว แสดงว่าน่าจะมาจากสาเหตุเดียวกันแล้วครับ ให้ลองตรวจสอบเพิ่มอีกครับว่าเราได้ไปเปิดการแสดงผล paging ใน List View ด้วยหรือไม่

วิธีตรวจสอบง่าย ๆ คือไปเปิด List View ขึ้นมานะ ว่ามีแสดง paging หน้าสุดท้ายหรือไม่ (ถ้าไม่ได้เปิดจะไม่มีในวงเล็บ) แต่ถ้ามีก็ชัดเลยครับ ไปอ่านวิธีแก้กันต่อด้านล่างได้เลย (ส่วนวิธีการเปิดเคยเขียนไว้ใน blog นี้ -> ว่าด้วยเรื่องการแสดง Paging ใน Listview)

listview3.png

สาเหตุของอาการนี้มีสองอย่างด้วยกัน คือเพราะ method ใน SmartObject เป็นแบบ List และมีการเปิด SmartObject.RuntimeListViewRowCount ไว้ ทำให้ทุก method ที่เป็น List จะถูกเรียกสองครั้งเสมอ

วิธีแก้มีสองวิธีครับ

  1. แบบง่าย: ก็คือไปปิดการแสดง paging ของ List View ซะ (SmartObject.RuntimeListViewRowCount = false) แต่ถ้าเรายังอยากได้ทั้งการแสดงผลแบบนี้ และยังสร้าง record ให้ไม่ซ้ำด้วย ไปทำตามข้อสองครับ
  2. แบบยาก: ต้นเหตุคือตัว stored procedure ส่งประเภท method มาเป็น List อยู่ เราต้องไปแก้ stored procedure ให้ส่งมาเป็นประเภท Execute แทน โดยการเพิ่มบรรทัด SET FMTONLY ON ใน stored procedure แนะนำให้อ่านวิธีแก้เต็ม ๆ ใน KB นี้ครับ -> Determined SmartObject method ‘List’ or ‘Execute’ when SmartObject was created from SQL Store Procedure

ST136024.jpg

ย้อน version ของ K2 component ยังไงกันนะ?

Blog นี้เริ่มจากคำถามจากทางบ้านนะครับ ว่าในการพัฒนา K2 เห็นมีการเก็บ version ไว้ ทั้ง Workflow , SmartForm และ SmartObject

version.png

แต่ยังหาวิธีการย้อน version ไม่เจอว่าต้องทำยังไง ใน blog นี้เลยจะบอกวิิธีการของแต่ละส่วนครับ

1. Workflow

เริ่มด้วยการย้อน version ของ workflow ก่อนนะครับ เพราะเป็นส่วนที่ทำได้ง่ายที่สุดแล้ว เราสามารถเข้าไปดู version ของ workflow ได้ผ่านทาง K2 Workspace หรือ K2 Management (สำหรับ version 4.7 ขึ้นไป)

สำหรับ K2 Workspace ไปที่เมนู [Server name] -> Workflow Server -> Processes -> [Process Name] -> Versions

processVersion.png

สำหรับ K2 Management ไปที่ Workflow Server -> [Workflow name] แล้วกดที่ tab Versions

processVersion47

โดยในทั้งสองไซต์ เราสามารถเลือกย้อน version ในการทำงานของ workflow ได้โดยเลือกกดที่ Set as default (มีผลเฉพาะกับ workflow ที่ยังไม่ start มานะครับ) และสามารถเลือก Download workflow version นั้น มาแก้ไขได้อีกด้วย

2. SmartForm

การย้อน version ของ smartform สามารถทำได้โดยใช้ stored procedure ที่ชื่อ Form.mRevertToVersion โดยสามารถย้อนได้ทั้ง View และ Form

สามารถตามไปอ่านวิธีการ step by step ได้ที่ -> How to roll back to a deleted or previous version of a View or a Form

3. SmartObjects

SmartObject นั้นเก็บโครงสร้างอยู่ที่ database ของ K2 แยกตาม version ที่ deploy ไป ดังนั้นการย้อน version SmartObject นั้นต้องทำตรงที่ database เลย โดยไม่ได้มี stored procedure ช่วย เหมือนการย้อน SmartForm

วิธีการทำก็คือ ต้องใช้ SQL Command ในการ update โดยนำ XML ใน SmartObjectXML ของ version ที่ต้องการย้อนกลับไป นำมาอัพเดทให้ version ล่าสุดนั่นเอง

smoVersion.png

ย้อน version SmartForm กับ SmartObject เป็นการทำงานตรงกับ database ของ K2 ซึ่งอาจมีโอกาสเกิดความผิดพลาดกับ database แนะนำว่าไม่ควรทำบนเครื่อง Production และให้ backup database K2 ทั้งก้อน ก่อนจะเริ่มทำนะครับ

การสร้าง Custom Worklist แบบ Step by step (No coding)

การใช้งาน K2 กับ Worklist เป็นของคู่กันมานานนม ตั้งแต่สมัยใช้งานบน workspace จนมาถึงปัจจุบันก็มี worklist control ใน SmartForms ให้ใช้

โดยปกติ worklist control มี field ที่เกี่ยวกับการทำงานของ workflow เช่น Folio, Activity Name, Task Start Date และอื่น ๆ ให้เลือกแสดงได้อยู่แล้ว ซึ่งการใช้งานจริงเรามักอยากได้ worklist ที่มีข้อมูล ของระบบนั้นมาแสดงด้วย โดยทางออกที่เรามักจะทำกันคือการใส่ค่าแปะไว้ใน folio ของ workflow บางที Folio มันก็จะยาว ๆ หน่อยอ่ะนะ (- -“)

Leave00.png

แต่ในวันนี้มานำเสนออีกช่องทางครับ เป็นวิธีการทำ worklist ที่สามารถดึงข้อมูลระบบอื่นมาแสดงด้วย ในตัวอย่างจะเป็น worklist ของ ระบบ Leave request โดยจะมีข้อมูลประเภทการลา วันที่เริ่มลาจนถึงวันที่สิ้นสุด มาแสดงใน worklist ได้ด้วย ผลลัพท์ได้มีหน้าตาตามนี้ครับ

Leave11.png

สิ่งที่ใช้ในการทำ: Worklist Service Broker, Composite SmartObjects

Step by step

  1. ติดตั้ง Worklist Service Broker (ตามไป download ได้ตามลิ้งค์ด้านบนครับ)
    • WorklistService
  2. เพิ่ม field ProcessInstanceID ในตาราง leave request (ใน workflow เพิ่ม SmartObjects Event ให้ไป update ค่า ProcessInstanceID หลังจากส่งงานเข้า workflow ไปแล้วด้วย)
    •  Leave-table
  3. สร้าง composite SmartObject เชื่อมกันระหว่าง Leave Request  และ WorklistService
    • เปิด K2 Studio, สร้าง SmartObject ตั้งชื่อ LeaveRequestWorklist
    • Leave1.png
    • กด Add Method, เลือก Run the wizard in Advance Mode แล้ว กด Next
    • Leave6.png
    • ตั้งชื่อ method ว่า Get Leave Request Worklist แล้วกด Next
    • Leave3.png
    • ในหน้า Configure Method Parameter กด Next (ไม่ต้องสร้าง parameter)
    • ในหน้า Service Method Object กด Add
    • Leave13.png
    • ในหน้า Add Service Method กด Add เลือกไปที่ Service Object Server -> [SQL Service Instance Name] -> Table -> Leave Request -> List
    • Leave4.png
    • กด Create All เพื่อสร้าง properties แล้วกด OK
    • Leave3.png
    • โปรแกรมจะกลับมาที่หน้า Service Method Object กด Add อีกครั้ง
    • Leave12.png
    • ในหน้า Add Service Method กด Add เลือกไปที่ Service Object Server -> Worklist Server -> Basic Worklist Item -> Get Worklist Items
    • Leave7.png
    • กด Create All เพื่อสร้าง properties แล้วกด OK
    • กด Next
    • ในหน้า Setup Service Method Link กด Add
    • Leave9.png
    • ในหน้า Add Service Method Link เลือกปรับค่าดังนี้
      • Service Object Method: Leave Request.List
      • Link Type: Matching Value in both objects
      • Service Object Method: Worklist Service.GetWorklistItems
    • ในส่วนของ Property Name เลือกไปที่ ProcessInstanceID แล้วกด Assign เลือกไปที่ Process InstanceID ตามรูป
    • Leave10.png
    • กด OK
    • กด Next, กด Finish
    • Deploy SmartObjects
  4. ทดสอบและนำ SmartObjects ไปสร้าง ListView, form ต่อเพื่อใช้งาน
    • ตอนเรียกใช้งานก็เรียกผ่าน method ที่เราสร้างขึ้นครับ มันจะได้เฉพาะงานจาก worklist เท่านั้น แล้วจะไป join กับ field จากตาราง Leave Request
    • Field ที่ใช้ฝั่งของ worklist จะมีดังนี้ครับ
      • Link: เป็น URL ที่ส่งมาจาก workflow สำหรับเปิดหน้าฟอร์มเข้าไปอนุมัติ
      • Folio: ชื่อ folio ของ workflow นั้น ๆ
    • Leave11

 

สรุปข้อดีของการทำ custom worklist

  • เพิ่ม field จากฐานข้อมูลมาแสดงผลได้
  • สามารถใช้ฟังก์ชั่นของ list view ได้ เช่น การ sorting, filter, paging

แต่ก็มีข้อจำกัดของการทำ custom worklist นะ

  • ไม่สามารถใช้ function ที่ติดมากับ worklist control ได้ เช่น  Redirect, Delegate, Out of office (ทำได้แต่ต้องเขียนเพิ่มเอง)
  • ต้องสร้าง SmartObjects และ form แยกสำหรับแต่ละระบบ

 

การสร้าง custom worklist ขั้นตอนก็มีดังที่กล่าวไปข้างต้น รวมถึงมีทั้งข้อดีข้อเสีย ทั้งนี้ขอให้เลืิอกนำไปใช้ให้เหมาะสมกับงานของเราครับ 🙂

[K2 SmartForms] – Using Field Property

สวัสดีครับ หายไปนานกับ blog ของ K2 Ranger พอดีวันนี้มีคำถามเข้ามาทาง page K2 Thailand เกี่ยวกับการเลือก field ที่ผูกกับ data source เลยเอามาเขียนให้อ่านกัน

ในส่วนแรกให้เราสร้าง property field เพิ่มใน file .cs

public string Field

{

get

{

return base.GetOption<string>(“Field”, string.Empty);

}

set

{

base.SetOption<string>(“Field”, value, string.Empty);

}

}

จากนั้นก็ไปเพิ่ม property ใน file definition.xml ของ control

<Prop ID=”Field” mappable=”false” friendlyname=”Field” category=”Detail” refreshdisplay=”false” type=”complex” InitializeServerControl=”initializeFieldPropertyConfig” ClearServerControl=”clearFieldConfig” ServerControl=”SourceCode.Forms.Controls.Web.FieldConfiguration.FieldPropertyConfig,SourceCode.Forms.Controls.Web” />

เพิ่มแล้วเรียบร้อยให้ลอง build แล้ว deploy ใหม่ดู เราก็จะสามารถดึง field ที่อยู่ใน SmartObject ที่ผูกกับ view นี้ออกมาได้

Field

FieldSelection

จะมองเห็นเฉพาะ field type ที่ control นี้สามารถใช้งานได้ด้วย

   ส่วนวิธีเอาค่าจาก Field property ไปใช้ต่อ ก็ใช้วิธีเดียวกันกับการดึงค่าใน property อื่นๆ ไปใช้นะครับ สำหรับรอบนี้ขอลาไปเท่านี้ครับ 🙂

 

[K2 SmartForms] – Can’t click OK to finish rule in designer

สวัสดีครับ หลายๆ คนคงเคยเจอปัญหาอยู่บ้าง เวลาเราใส่ action เข้าไปใน SmartForms เยอะๆ จะไม่สามารถกดปุ่ม OK เพื่อ save action ที่เราใส่เข้าไปได้ หรือกดปุ่ม Finish ที่อยู่ใน form ก็ไม่ได้เช่นกัน ถ้าเคยเจอปัญหานี้ เรามีวิธีแก้ไขมาให้ 2 วิธี โดยทั้ง 2 วิธีเป็นการไปแก้ไข configure ใน web.config ของ SmartForms ที่ site designer (อยู่ใน {install dir}\K2 blackpearl\K2 smartforms Designer)

  • แก้ไขค่า MaxRequestLength จากค่า default เป็น “2097151” ซึ่งเป็นค่ามากที่สุดที่ใส่ได้

designer

  • ถ้าใช้วิธีแรกแล้วยังไม่หาย ให้เพิ่ม tag ตามด้านล่างลงไป ภายใต้ tag requestFiltering

<requestLimits maxAllowedContentLength=”300000000″ />

designer2

เมื่อแก้ไขแล้ว ให้ save web.config และ reset IIS จากนั้นลองใช้งานดู ก็น่าจะ save form ได้ตามปกติครับ  🙂

[K2 SmartForms] – Use SmartObject Property in Custom Control (Part III)

มาต่อจากคราวที่แล้ว ที่เราเลือกเป็น static ไป คราวนี้จะมาลองเลือก SmartObject มาใช้งานกันบ้าง เหมือนกับของ static คือ เราต้องสร้าง property ใน file .cs เพิ่มก่อน โดย property ที่ใช้งานจะมี AssociationSO, AssociationMethod, ValueProperty และ DisplayTemplate

public string AssociationSO

{

get

{

return this.GetOption<string>(“AssociationSO”, string.Empty);

}

set

{

this.SetOption<string>(“AssociationSO”, value, string.Empty);

}

}

public string AssociationMethod

{

get

{

return this.GetOption<string>(“AssociationMethod”, string.Empty);

}

set

{

this.SetOption<string>(“AssociationMethod”, value, string.Empty);

}

}

public string ValueProperty

{

get

{

return this.GetOption<string>(“ValueProperty”, string.Empty);

}

set

{

this.SetOption<string>(“ValueProperty”, value, string.Empty);

}

}

public string DisplayTemplate

{

get

{

return this.GetOption<string>(“DisplayTemplate”, string.Empty);

}

set

{

this.SetOption<string>(“DisplayTemplate”, value, string.Empty);

}

}

สิ่งที่ต้องทำถัดไปคือ สร้าง structure มาเพื่อรับค่าที่เราเก็บไว้ใน DisplayTemplate เพราะตอนที่เราเลือกว่า จะแสดงค่าอะไรออกมาที่ control เราสามารถเลือกได้หลาย field ตามตัวอย่างด้านล่าง

ccb5-01

structure ที่สร้างมาเพื่อรองรับค่า จะใช้ตามด้านล่าง โดยใน DisplayTemplate ที่ K2 เก็บไว้จะเก็บไว้ในรูปของ xml

internal struct DisplayTemplateObject
{

public string SourceType;

public string SourceID;

public string Value;

}

อีกส่วนที่ต้องทำไว้ก่อนคือ การเอา field จาก DisplayTemplate มาต่อกัน เพื่อนำไปใช้ใน control เลยสร้าง method ที่ชื่อ BuildValue ไว้ตามด้านล่าง

private string BuildValue(SmartObject smo, List<DisplayTemplateObject> ParsedTemplate)

{

StringBuilder builder = new StringBuilder();

foreach (DisplayTemplateObject templateObj in ParsedTemplate)

{

if (templateObj.SourceType == “Value”)

{

builder.Append(templateObj.Value);

}

else

{

builder.Append(smo.Properties[templateObj.SourceID].Value);

}

}

return builder.ToString();

}

ทีนี้ก็พร้อมแล้ว เรามาเพิ่ม code ใน CreateChildControls กัน โดยขั้นตอนการทำงานจะทำตาม step ด้านล่าง

  • ตรวจสอบว่า DataSourceType เป็น SmartObject หรือเปล่า?
  • เอาข้อมูล SmartObject, Method และ Value ออกมาจาก property
  • ดึงข้อมูลโดยใช้ class SmartObjectClientServer แบบที่เราเขียนโปรแกรมปกติ
  • ดึงข้อมูล DisplayTemplate มาใส่ใน list โดยแยก attribute มาจาก xml ที่ K2 เก็บไว้ให้
  • นำมาใส่ไว้ใน control ที่ต้องการ

if (this.DataSourceType.Equals(“smartobject”, StringComparison.InvariantCultureIgnoreCase))
{

string smo = this.AssociationSO;
string valueProp = this.ValueProperty;
string smoMethod = this.AssociationMethod;

SmartObjectClientServer smartObjectClient = ConnectionClass.GetSmartObjectClient();
Guid guid = new Guid(smo);
SmartObject smartObject = smartObjectClient.GetSmartObject(guid);
smartObject.MethodToExecute = smoMethod;
SmartObjectList list = new SmartObjectList();

list = smartObjectClient.ExecuteList(smartObject);

List<DisplayTemplateObject> parsedTemplate = new List<DisplayTemplateObject>();

foreach (XElement element in XDocument.Parse(this.DisplayTemplate).Root.Elements())
{

DisplayTemplateObject item = new DisplayTemplateObject

{

SourceType = element.Attribute(“SourceType”).Value

};

if (item.SourceType == “Value”)

{

item.Value = element.Element(“SourceValue”).Value;

}

else

{

item.SourceID = element.Attribute(“SourceID”).Value;

}

parsedTemplate.Add(item);

}

this.ddl = new DropDownList();

List<KeyValuePair<string, string>> showList = new List<KeyValuePair<string, string>>();

foreach(SmartObject item in list.SmartObjectsList)
{

ddl.Items.Add(new ListItem(this.BuildValue(item, parsedTemplate), item.Properties[valueProp].Value));

}

this.Controls.Add(this.ddl);

ในกรณีที่ใส่ code ไปแล้วติด reference บางตัวที่หาไม่เจอ ให้ลอง add dll SourceCode.SmartObjects.Client เพิ่มเข้ามาใน project แล้วก็ add using ตามด้านล่างเข้าไปใน coding ของ control เพิ่ม

using SourceCode.SmartObjects.Client;

using SourceCode.Forms.Controls.Web.SDK.Utilities;

using System.Xml.Linq;

จากนั้นก็ deploy แล้วก็ทดสอบ

ccb5-02

ccb5-03

สำหรับส่วนการ add property ก็จะจบเท่านี้นะครับ เอาไว้พบกันใหม่คราวหน้าครับ 🙂