Category Archive Joget

JoGet: Bean Shell Create Json

วิธีดีที่สุดในการให้ข้อมูลจำนวนมากให้ javascript คือรูปแบบ json ไม่เว้นแม้แต่ใน JoGet เพราะถึงแม้จะสามารถดึงข้อมูลจาก input หรือ grid ได้ แต่มันจะถูกบันทึกลง database ไปด้วยแถมดูรก

วิธีที่ดีอีกวิธีคือให้ beanshell ใน section ดึงข้อมูลจาก query แล้วแสดงออกมาใน input ตัวเดียว[code language=”java” title=”Bean Shell Create Json”]import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.joget.apps.app.service.AppUtil;
import org.joget.apps.form.model.Element;
import org.joget.apps.form.model.FormData;
import org.joget.apps.form.model.FormRow;
import org.joget.apps.form.model.FormRowSet;
import org.joget.apps.form.service.FormUtil;
import org.joget.commons.util.LogUtil;
import org.json.simple.JSONObject;

public FormRowSet load(Element element, String username, FormData formData) {

FormRowSet rows = new FormRowSet();

Connection con = null;
try {
DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean("setupDataSource");
con = ds.getConnection();

sql = "SELECT appId, appVersion, name FROM jwdb.app_app WHERE published = 1;";
//LogUtil.info("Bean Shell Create Json", "sql = " + sql);

if (!con.isClosed()) {
PreparedStatement stmt = con.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();

/* create json */
JSONObject json = new JSONObject();
while (rs.next()) {
JSONObject item = new JSONObject();

item.put("appVersion", rs.getObject("appVersion"));
item.put("name", rs.getObject("name"));

json.put(rs.getObject("appId"), item);
}

/* add json to input */
FormRow row = new FormRow();
rows.add(row);
row.put("json", json.toString());
}

} catch (Exception e) {
LogUtil.error(getClassName(), e, "Bean Shell Create Json");
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException e) {}
}

return rows;
}

return load(element, primaryKey, formData);[/code]

ตัวอย่างฟอร์ม[code language=”javascript” title=”Bean Shell Create Json”]{
"className": "org.joget.apps.form.model.Form",
"properties": {
"noPermissionMessage": "",
"loadBinder": {
"className": "org.joget.apps.form.lib.WorkflowFormBinder",
"properties": {}
},
"name": "Bean Shell Create Json",
"description": "",
"postProcessorRunOn": "both",
"permission": {
"className": "",
"properties": {}
},
"id": "BeanShellCreateJson",
"postProcessor": {
"className": "",
"properties": {}
},
"storeBinder": {
"className": "org.joget.apps.form.lib.WorkflowFormBinder",
"properties": {}
},
"tableName": "prototypes"
},
"elements": [
{
"elements": [
{
"elements": [
{
"className": "org.joget.apps.form.lib.TextArea",
"properties": {
"readonly": "",
"validator": {
"className": "",
"properties": {}
},
"workflowVariable": "",
"id": "json",
"label": "JSON",
"placeholder": "",
"rows": "10",
"value": "",
"cols": "100",
"readonlyLabel": ""
}
}
],
"className": "org.joget.apps.form.model.Column",
"properties": {
"width": "100%"
}
}
],
"className": "org.joget.apps.form.model.Section",
"properties": {
"readonly": "",
"loadBinder": {
"className": "org.joget.apps.form.lib.BeanShellFormBinder",
"properties": {
"useAjax": "",
"cacheIdlePause": "120",
"cacheInterval": "",
"script": "import java.sql.Connection;\nimport java.sql.PreparedStatement;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\nimport javax.sql.DataSource;\nimport org.joget.apps.app.service.AppUtil;\nimport org.joget.apps.form.model.Element;\nimport org.joget.apps.form.model.FormData;\nimport org.joget.apps.form.model.FormRow;\nimport org.joget.apps.form.model.FormRowSet;\nimport org.joget.apps.form.service.FormUtil;\nimport org.joget.commons.util.LogUtil;\nimport org.json.simple.JSONObject;\n\npublic FormRowSet load(Element element, String username, FormData formData) {\n\n FormRowSet rows = new FormRowSet();\n\n Connection con = null;\n try {\n DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean(\"setupDataSource\");\n con = ds.getConnection();\n\n sql = \"SELECT appId, appVersion, name FROM jwdb.app_app WHERE published = 1;\";\n //LogUtil.info(\"Bean Shell Create Json\", \"sql = \" + sql);\n\n if (!con.isClosed()) {\n PreparedStatement stmt = con.prepareStatement(sql);\n ResultSet rs = stmt.executeQuery();\n\n /* create json */\n JSONObject json = new JSONObject();\n while (rs.next()) {\n JSONObject item = new JSONObject();\n\n item.put(\"appVersion\", rs.getObject(\"appVersion\"));\n item.put(\"name\", rs.getObject(\"name\"));\n\n json.put(rs.getObject(\"appId\"), item);\n }\n\n /* add json to input */\n FormRow row = new FormRow();\n rows.add(row);\n row.put(\"json\", json.toString());\n }\n\n } catch (Exception e) {\n LogUtil.error(getClassName(), e, \"Bean Shell Create Json\");\n } finally {\n try {\n if (con != null) {\n con.close();\n }\n } catch (SQLException e) {}\n }\n\n return rows;\n}\n\nreturn load(element, primaryKey, formData);"
}
},
"permissionReadonly": "",
"permission": {
"className": "",
"properties": {}
},
"comment": "",
"id": "section1",
"label": "Bean Shell Create Json",
"storeBinder": {
"className": "",
"properties": {}
},
"readonlyLabel": ""
}
}
]
}[/code]

javascript: string to JSON.parse()

หลังจากใช้ MySQL: return json format กันเป็นแล้วเรามาลองใช้กับ joget แทนที่จะต้องไปเขียน beanshell ให้ยุ่งยาก (พลาดง่ายๆ อีกตะหาก) ดูจริงๆ แล้วสามารถใช้กับหน้าเว็บทั้งหมดไม่ใช่แค่ joGet เพราะมันคือ javascript พื้นฐาน

เปิดฟอร์มที่ต้องการมา

  1. สร้าง section ขึ้นมา โดยกำหนด Load Binder เป็น JDBC Binder และ SQL SELECT Query ใส่ query ที่ต้องการ เช่น[code language=”sql” title=”Load Binder for optionsList”]SELECT
    CONCAT(‘[‘,
    GROUP_CONCAT(JSON_OBJECT(‘label’, name, ‘value’, appId)),
    ‘]’) AS optionsList
    FROM
    jwdb.app_app
    ORDER BY name ASC[/code]
  2. ลาก Hidden Field มาตั้ง id เป็น optionsList ใน section ที่สร้างไว้
  3. เขียน javascript ดึงค่ามาจาก string json ที่เก็บไว้ใน input ชื่อ optionsList โดยใช้ JSON.parse() เผื่อความปลอดภัย ควรใช้ JSON.parse() ใน try catch เพราะว่าถ้า json ที่ได้ผิดปกติจะสามารถควบคุมได้ ลาก Custom HTML มาแล้วใส่ code[code language=”html” title=”JSON.parse() example”]<table class="table table-striped" id="tableA">
    <thead>
    <tr>
    <th scope="col" style="width:20px;">#</th>
    <th scope="col">Name</th>
    <th scope="col">Value</th>
    </tr>
    </thead>
    <tbody>
    </tbody>
    </table>
    <script>
    $(document).ready(function () {

    let html = new Array();
    let no = 0;
    let optionsList = $(‘#optionsList’);
    try {
    let temp = JSON.parse(optionsList.val());

    if (temp.length > 0) {
    $.each(temp, function (index, value) {
    no++;
    html.push(‘<tr><th scope="row">’ + no + ‘</th><td>’ + value.label + ‘</td><td>’ + value.value + ‘</td><tr>’);
    });
    }
    if (html.length == 0) {
    html = ‘<tr><th scope="row">-</th><td>-</td><td>-</td><tr>’;
    } else {
    html = html.join("\n");
    }
    } catch (e) {
    console.log(e.message);
    html = ‘<h1>Error!!</h1>’;
    }
    $(‘#tableA > tbody’).html(html);

    });
    </script>[/code]

สามารถ copy form ตัวอย่างได้จาก json[code language=”javascript” title=”Form:JSON Parse”]{
"className": "org.joget.apps.form.model.Form",
"properties": {
"noPermissionMessage": "",
"loadBinder": {
"className": "org.joget.apps.form.lib.WorkflowFormBinder",
"properties": {}
},
"name": "JSON Parse",
"description": "",
"postProcessorRunOn": "both",
"permission": {
"className": "",
"properties": {}
},
"id": "JSONParse",
"postProcessor": {
"className": "",
"properties": {}
},
"storeBinder": {
"className": "org.joget.apps.form.lib.WorkflowFormBinder",
"properties": {}
},
"tableName": "prototypes"
},
"elements": [
{
"elements": [
{
"elements": [
{
"className": "org.joget.apps.form.lib.HiddenField",
"properties": {
"useDefaultWhenEmpty": "",
"workflowVariable": "",
"id": "optionsList",
"value": ""
}
}
],
"className": "org.joget.apps.form.model.Column",
"properties": {
"width": "100%"
}
}
],
"className": "org.joget.apps.form.model.Section",
"properties": {
"readonly": "",
"loadBinder": {
"className": "org.joget.plugin.enterprise.JdbcLoadBinder",
"properties": {
"jdbcDatasource": "default",
"sql": "SELECT \n CONCAT(‘[‘,\n GROUP_CONCAT(JSON_OBJECT(‘label’, name, ‘value’, appId)),\n ‘]’) AS optionsList\nFROM\n jwdb.app_app\nORDER BY name ASC"
}
},
"permissionReadonly": "",
"permission": {
"className": "",
"properties": {}
},
"comment": "",
"id": "section1",
"label": "",
"storeBinder": {
"className": "",
"properties": {}
},
"readonlyLabel": ""
}
},
{
"elements": [
{
"elements": [
{
"className": "org.joget.apps.form.lib.CustomHTML",
"properties": {
"autoPopulate": "",
"id": "field2",
"label": "",
"value": "<table class=\"table table-striped\" id=\"tableA\">\n <thead>\n <tr>\n <th scope=\"col\" style=\"width:20px;\">#</th>\n <th scope=\"col\">Name</th>\n <th scope=\"col\">Value</th>\n </tr>\n </thead>\n <tbody>\n </tbody>\n</table>\n<script>\n $(document).ready(function () {\n\n let html = new Array();\n let no = 0;\n let optionsList = $(‘#optionsList’);\n try {\n let temp = JSON.parse(optionsList.val());\n\n if (temp.length > 0) {\n $.each(temp, function (index, value) {\n no++;\n html.push(‘<tr><th scope=\"row\">’ + no + ‘</th><td>’ + value.label + ‘</td><td>’ + value.value + ‘</td><tr>’);\n });\n }\n if (html.length == 0) {\n html = ‘<tr><th scope=\"row\">-</th><td>-</td><td>-</td><tr>’;\n } else {\n html = html.join(\"\\n\");\n }\n } catch (e) {\n console.log(e.message);\n html = ‘<h1>Error!!</h1>’;\n }\n $(‘#tableA > tbody’).html(html);\n\n });\n</script>"
}
}
],
"className": "org.joget.apps.form.model.Column",
"properties": {
"width": "100%"
}
}
],
"className": "org.joget.apps.form.model.Section",
"properties": {
"readonly": "",
"loadBinder": {
"className": "",
"properties": {}
},
"permissionReadonly": "",
"permission": {
"className": "",
"properties": {}
},
"comment": "",
"id": "section2",
"label": "Options List",
"storeBinder": {
"className": "",
"properties": {}
},
"readonlyLabel": ""
}
}
]
}[/code]

MySQL: return json format

mysql ก็ support json เพราะว่าเดี๋ยวนี้อะไรๆ ก็แลกเปลี่ยนข้อมูลกันโดยใช้ json ถ้าสามารถ query จาก mysql ให้ result ออกมาเป็น json เลย ก็สะดวกที่จะไม่ต้องใช้ java หรือ beanshell ใน joget แปลงผลลัพธ์ให้ยุ่งยาก แค่มี input ซักตัวก็สามารถนำมันไปใช้ได้เลย

เริ่มจากการที่เขียน query ตามปกติเพื่อเลือกข้อมูลที่ต้องการ เช่น[code langage=”sql” title=”select provinces”]SELECT
*
FROM
snippets.province
ORDER BY PROVINCE_NAME ASC;[/code]จะเห็นว่ามี column PROVINCE_ID, PROVINCE_CODE, PROVINCE_NAME และ GEO_ID ทีนี้จะแปลง ให้เป็นรูปแบบ json array โดยใช้ JSON_OBJECT วิธีการใช้คือ[code language=”sql” title=”function JSON_OBJECT”]SELECT JSON_OBJECT(‘name1’, value1, ‘name2’, value2, ‘name3’, value3);[/code]คือ[code language=”sql” title=”function JSON_OBJECT example”]SELECT
JSON_OBJECT(‘PROVINCE_ID’,
PROVINCE_ID,
‘PROVINCE_CODE’,
PROVINCE_CODE,
‘PROVINCE_NAME’,
PROVINCE_NAME,
‘GEO_ID’,
GEO_ID) AS json
FROM
snippets.province
ORDER BY PROVINCE_NAME ASC;[/code]ค่าค่อยดูเป็น json ขึ้นมาหน่อย แต่มันยังอยู่คนละแถว ไม่เป็นไรมีตัวช่วย[code language=”sql” title=”mysql query to json”]SELECT
CONCAT(‘[‘,
GROUP_CONCAT(JSON_OBJECT(‘PROVINCE_ID’,
PROVINCE_ID,
‘PROVINCE_CODE’,
PROVINCE_CODE,
‘PROVINCE_NAME’,
PROVINCE_NAME,
‘GEO_ID’,
GEO_ID)),
‘]’) AS json
FROM
snippets.province
ORDER BY PROVINCE_NAME ASC;[/code]

แค่นี้ก็ได้ result เป็น json สมใจ อ่านตัวอย่างการใช้ได้ที่ javascript: string to JSON.parse()