讯光科技
EEPCloud
  • DataGrid
  • DataForm
  • Server
  • 其他問題

DataGrid

當前位置:首頁>常見問答>EEPCloud


如何使DataGrid的欄位可以排序?
進入EEPCloud畫面,左側點選RWD(Boostrap)打開表單,點選dgMaster,再點選 Columns ,
最後選擇您要排序的欄位,並將 Sortable 打勾即可。


查詢窗體中的Combobox如何額外設定Where的條件?
在DataGrid的QueryColumn中,找到Combobox元件,並在OnBeforeLoad事件裡點兩下,會自動產生以下的方法:

function dgMaster_CustomerID_onBeforeLoad(param)
{
param.whereStr = "Code like 'A%'"  //你的where條件
}

如何控制DataGrid上ToolItem隱藏或顯示? 如下在表單的 JS中,增加下列程式來隱藏"新增"的按鈕 (新增的onclick為"insert_row")

$('#dgMaster').prev('div.datagrid-toolitem').find('.btn').each(function () {
                var options = $.parseOptions(this);
                if (options.onclick == 'insert_row') { 
                    $(this).hide();
                }
            });

上面的 
dgMaster  -> datagrid 的ID
insert_row  ->toolitem onClick呼叫的function名稱
$(this).hide();  -> toolitem隱藏
$(this).show();  -> toolitem 顯示

如何在DataGrid的欄位中顯示多行(使用 Multiline的格式但顯示不會換行)?
請在datagrid的該欄位中設定Formatter事件,產生如下的js程式即可:

function dgMaster_地址_formatter(value, row, index)
{
    value=value.replace(/\n/g,'<br>');
    return value;
}

Image 在datagrid 如何控制照片大小(寬度)? 設定 DataGrid的相片 Format屬性即可,如下:


image,Images,200  (200代表相片寬度)
如何讓DataGrid TextArea的內容換行顯示如同在DataForm顯示的樣子?
請在DataGrid該欄位的Formatter設定一個Function名稱

然後請至 "原始碼" 寫下以下的function
function test(value, row, index)
{
    return value.replace(/\n/g,"<br />");
}
呼叫後端Server Method改變了資料後, 前端的DataGrid如何更新?
呼叫完後端Server Mehod完畢後,請添加以下的程式碼
$('#dgMaster').datagrid('load');

如何控制DataGrid瀏覽選擇時, 可以對應到另一個DataGrid顯示相對資料?
在DataGrid的Toolitem添加一個按鈕去執行ServerMethod

前端的JS
function serverMethod(){
    var row = $('#dgMaster').datagrid('getSelected'); //取得dgMaster上選中的一筆資料
        $.callMethod('sCustomers', 'testServerMethod', {CustomerID: row.CustomerID}, function(result){
                var rows = $.parseJSON(result); //將JSon轉回Object類型提供給Grid顯示
        $('#DataGrid1').datagrid('loadData', {rows:rows,total:rows.length});
        })
}

裡面的callMethod方法內參數依序是:ServerModule的名字、ServerMethod的名字、上傳的參數(如果沒有的話可以填null)、Server端返回時的回調方法

後端的js
exports. testServerMethod = function(param, callback){
    var clientInfo = this.clientInfo;
   var CustomerID =param.CustomerID;
    var sql = "select 名稱 from 客戶資料表 where 客戶編號 = '"+ CustomerID +"'"; //SQL條件句
   this.queryRaw(clientInfo, clientInfo.database, sql, {}, callback);
}

如何在DataGrid中, 只更新一筆數據?
$(target).datagrid('updateRow', {
index: index,
row: { fieldName: 'value'}//可以多欄位 用','隔開
});

target -> DataGrid的ID
fieldName -> 欄位名稱
'value' -> 給予的值

如何在DataGrid中, 只重新載入當頁數據?
var page = $('#dgMaster').datagrid('options').page;
$('#dgMaster').datagrid('load', { page: page});

如何控制 DataGrid的更改與刪除是否可以執行?
function dgMaster_onUpdate(row)
{
   var date = row.進貨日期.substr(0,4)+row.進貨日期.substr(5,2);
   var closeym = $.getVariableValue('closeYM');
   if (date <= closeym) {
      $.alert("進貨日期小於結帳日, 無法刪除與更改",'info');
      return false;
   }
   return true;
}

在DataGrid的印表到Word或Excel上, 可否動態更換Word或Excel的檔名格式嗎?
可以的, 透過 DataGrid.ToolItems中, 設定onclick事件, 重新定義Word或Excel的檔名即可, 如Excel為:
function exportExcel2()
{
$(this).datagrid('exportExcel', '銷貨統計表依業務');  // 更換成"銷貨統計表依業務.xls"
}
Word則為:
function exportWord2()
{
$(this).datagrid('exportWord', '出貨單2');  // 更換成"出貨單2.doc"
}

如何新增時複製DataGrid的某一筆資料?
請在DataGrid的ToolItem添加一個按鈕,
OnClick 呼叫 copy_row

如何讓DataGrid與DataForm同時顯示,並兩者互相同步?
只要把DataGrid的EditForm清空,並將DataForm的Mode設為Panel後,再設定 DataGrid的 onSelect事件就可以讓 DataGrid與DataForm同時與同步顯示: 如下:
function dgMaster_onSelect(index, row)
{
    $('#dfMaster').form('setWhere',  "F001=" + row.F001);
}
如果EditForm要能夠編輯,可以設定ToolItem內的Add/Update/Submit/Cancel等Button即可,並設定onApplied事件去同步DataGrid的內容,如下:
function dfMaster_onApplied(data)
{
    var page = $('#dgMaster').datagrid('options').page
    $('#dgMaster').datagrid('load', {page: page});
}

如果DataGrid上有兩個欄位分別DrillDown到不同表單時, 會兩個都同時打開追蹤, 請問如何避免? 在 DataGrid上的Format除了選擇"drilldown"格式外, 還要設定其對應的DrillDown組件, 
如設定為: "drilldown,#Drill進貨退回單" 代表要追蹤的對應組件。
如何以Tree組件自由控制DataGrid的Where條件?
透過 Tree組件的onNodeSelected事件來實現, 如下:
function Tree1_onNodeSelected(event, node)
{
    var sID = node.row.項目序號;
    var dataGrid = $('#dgDetail');
    dataGrid.datagrid('setWhere',"(項目序號='"+sID+"' or 上層項目='"+sID+"')");
}

DataGrid如何預設打開的顯示條件?
透過onBeoforeLoad事件來改變Where條件即可。如下: 
function dgMaster_onBeforeLoad(param)
{
    var user = $.getVariableValue('user'); 
    param.whereStr = "交辦人 = '" + user + "' or 待辦人='" + user + "'"; 
}

如何取得DataGrid欄位的值?
var rows = $('#dgMaster').datagrid('getRows'); 
var index=$('#dgMaster').datagrid('getSelectedIndex');
var row=rows[index];
alert(row.欄位名稱); //欄位名稱請自行替換

如何在DataGrid中選擇一筆資料, 然後呼叫後端的處理程序?
在DataGrid中加一個Button, 然後寫一個JS的方法來調用後端的程序, 如下:
function createPo() {
   var sIndex = $("#dgMaster").datagrid("getSelectedIndex");
   if (sIndex >= 0) {
       var pno = $("#dgMaster").datagrid("getRows")[sIndex].訂單號碼; //取出訂單號碼
       $.callMethod('客戶訂單','doCreatePo',{type:1,no:pno},function(result){
           $.alert(result,'info');
        });
     }
    else {
      $.alert('請選擇一筆訂單','info');
    }
}

如何在 DataGrid中以 Excel上傳來匯入資料,而不是一筆一筆輸入? 可以在DataGrid的ToolItems中, 新增一個"導入"的Button, 設定為 'importExcel' 即可
如何動態隱藏某一個DataGrid?
如下的程序:
$(‘#dgMaster’).closest('div').parent().hide();//隱藏datagrid

如何在Drilldown時自定參數傳給另一個頁面?
在Drilldown的onClick雙擊添加一個事件,如下:
function Drilldown1_onClick(row, whereItems)
{
    row.parameter1 = "abc";  //自定一個parameter1 參數
return true;
}

在目標頁面寫下
$(function(){
   var drillRow = $.getEncryptParameter('drillRow', 'drill'); //取出drillRow的對象
   var myPara1=drillRow.parameter1; // 取出parameter1參數
});

如何在DataGrid的編輯中, 讀取欄位的編輯內容, 及改變某欄位的內容?
可以透過Columns中的個別事件讀取與設定DataGrid欄位內容, 如在Refval或Combo可以透過onSelect事件, Textbox可以透過onBlur事件來處理, 如下範例:
function dgDetail_項目次序_onSelect(row)
{
    var type = $('#dgDetail').datagrid('getEditorValue', '類別'); //讀取欄位值
    var amt = 0;
    if (type=="代扣所得") {
        amt = -($('#dptab_薪資設定_所得扣繳金額').val());
    }
    else if (type=="代扣保險") {
        amt = -($('#dptab_勞保健保資料_本人勞健保費').val());
    }
    $('#dgDetail').datagrid('setEditorValue',{field: '金額', value: amt});  // 設定欄位值
}

Master/Detail中如何清除所有Detail的DataGrid資料?
function delAll() {
   //取消確認框的方法,但如果ConfirmDelete設為False就不用這段
$.confirm = function (text, callback) {
        callback(true);
};
var rows = $("#dgDetail").datagrid('getRows');
var cnt = rows.length;
for (var i = cnt - 1 ;i>= 0 ; i--) {
 $('#dgDetail').datagrid('delete_row', 0);
}
$('#dfMaster').form('submit'); //如果要自動存檔的話
}

為何DataGrid裡的ToolItems中的OnClick無法讓我鎖定成我更改過後的,每次iCoder產生時都會把我改的OnClick覆蓋? ToolItems的OnClick屬性為版本差異比對的主要key值, 所以無法鎖定,
每次Word輸出都會被覆蓋, 如果不想被覆蓋的話,請直接添加一個新的按鈕,這樣重新匯入Word時就不會覆蓋掉OnClick。
請問,如何用JS去更改DataGrid的欄位內容?
如下,透過DataGrid的getRows與updateRow的方法: 
function updTax()  //更新稅額
{
    var rows = $('#dgDetail').datagrid('getRows');
for(var i = 0; i<rows.length; i ++){
 var row = rows[i];
        if(row.類別=='代扣所得' ){
            var amt= -($('#dptab_薪資設定_所得扣繳金額').val());
     $('#dgDetail').datagrid('updateRow',{index: i,row: {'金額': amt}});
 }
        if(row.類別=='代扣保險' ){
            var amt= -($('#dptab_勞保健保資料_本人勞健保費').val());
     $('#dgDetail').datagrid('updateRow',{index: i,row: {'金額': amt}});
 }
     }
}

如何讓DataGrid某欄位的數值隨著條件變更顏色且依然使用原先的format?
舉例如下:
function dgMaster_總計含稅_formatter(value, row, index)
{
    if (value && value > 50000 ){ 
        return '<span style="color:red">' + $.getFormatValue.call(this, value, row, $(this)[0].format) + '</value>'; 
    } 
    else {  
        return $.getFormatValue.call(this, value, row, $(this)[0].format);
    }
}
DataGrid的欄位寬度通常是自動調整的,如何控制某些欄位讓他固定的寬度,以滿足使用者輸入的要求?
RWD的DataGrid是自適應寬度, 所以需透過CSS來改變欄位寬度, 可在EEPCloud中貼入Literal網頁組件, 並以CSS的方式在Html屬性中來改變欄寬, 如下:
<style>
  #dgMaster thead>tr>th:nth-child(3),
  #dgMaster thead>tr>th:nth-child(4){
   width: 150px!important;
  }
</style>
註: dgMaster為DataGird的ID, child(3),(4)為DataGird的Columns次序(從3起算)

如何用JS程式取得DataGrid的查詢條件?
可以透過Runtime頁面的查詢元件以右鍵的'檢查'來得知查詢物件的ID, 再透過如下的JS來取得查詢內容:
var yymm = $('#dgMasterqueryObj_薪資年月').dateselect('getValue');  
var co = $('#dgMasterqueryObj_子公司').combobox('getValue');
var all = $('#dgMasterqueryObj_全部印出').selectoptions('getValue');
如何動態更改DataGrid的資料源(RemoteName), 來達到動態的統計效果?
例如, 原來資料為月份統計的明細, 可以透過一個 '年度彙總' 改為年度的統計內容, 如下: 
function reLoad()
{
    $('#dgMaster').datagrid('options').remoteName = '薪資發放作業.薪資發放統計';   
    $('#dgMaster').datagrid('load');
}
如何用js動態隱藏DataGrid?
舉例如下:
$('#dgMaster').closest('div').parent().hide();//隱藏DataGrid
//$('#dgMaster').closest('div').parent().show();//顯示DataGrid

DataGrid編輯時, 如果有些欄位為ReadOnly狀態, 可否使用原來顯示的格式, 而非ReadOnly的文字編輯框?
可以透過 DataGrid的 onShowEditor事件來處理, 如下: 
function dgDetail_onShowEditor(index, field, editor)
{
    if(field == '題目'){  //欄位為'題目'時, 改育 type: 'div'來顯示
        return {type: 'div'};  
    }
    else  {
        return editor;  // 使用原來的 Editor
    }
}

如何使用 Stored Procedure來查詢自訂的資料, 並傳回到DataGrid中?
* InfoCommand的CommandType如果為StoredProcedure時,前端的DataGrid查詢條件送回後端時會自動與StoredProcedure配合。如果在InfoCommand的Parameters中所設定的參數與前端DataGrid欄位名稱一致時,前端送過來的查詢條件會自動寫入Parameters的Value中,這樣就可以透過StoredProcedure的Input變數進行資料查詢與回傳結果。如下:
1.  設計一個SP,透過MSSQL或是EEPCloud來新增一個SP,並定義好input參數。
2.  原來前端的DataGrid需事先連上一個虛擬或實體的Table,結構與SP要傳會的資料一致。在Server端除了原來的InfoCommand對應到這個虛擬或實體的Table外,還要另外貼一個SP的InfoCommand(CommandType為StoredProcedure),CommandText輸入SP的名稱,並填好與SP對應的Parameters參數。
3.  前端的DataGrid.RemoteName改成這個SP的InfoCommand即可,這樣User輸入查詢條件就會送往SP這個InfoCommand,InfoCommand因為為SP的Type,所以會自動用欄位對應Parameters參數。


如何動態顯示或隱藏DataGrid的欄位?
舉例如下:
//隱藏
$("#dgMaster").datagrid('hideColumn', '姓名');
//顯示
$("#dgMaster").datagrid('showColumn', '姓名');

如何動態顯示或隱藏 DataGrid的查看/編輯/刪除的按鈕?
在DataGrid的OnBeforeLoad事件添加如下的js
function dgMaster_onBeforeLoad(param)
{
//隱藏
    $('#dgMaster').datagrid('options').viewCommandVisible = false;
    //如果要顯示將false改為true
    //$('#dgMaster').datagrid('options').editCommandVisible = false;
    //$('#dgMaster').datagrid('options').deleteCommandVisible = false;
}

如何動態修改DataGrid的欄位Caption?
舉例如下:
//RWD 一般畫面 改變欄位title
    $("#dgMaster").find('thead>tr>th').each(function () {
                if($.parseOptions(this).field == "英文姓名"){
                    this.innerText = "測試1";
                    //this.style.color = "red";
                    //this.style.fontSize = "22px";
                }
            });
    //RWD 手機/平板畫面 改變欄位title
    $("#dgMaster").find('tbody>tr>td').each(function () {
                if ($(this).attr('data-field') == "員工編號") {
                    $(this).find('.table-cell-label').html("測試2");
                    //$(this).find('.table-cell-label').css('color',"red");
                    //$(this).find('.table-cell-label')[0].style.fontSize = "22px";
                }
            });

請問 DataGrid 的顯示欄位上, 如何放入提示訊息(Title訊息)?
可以使用 Formatter屬性來控制, 如下為使用Title訊息顯示另一個欄位內容:
function dgMaster_請假日期時間_formatter(value, row, index)
{
    var data = $.getFormatValue.call(this, value, row, $(this)[0].format);  //以原來的Format來顯示
    var title = '結束日期時間:'+$.getFormatValue.call(this, row.結束日期時間 , row, $(this)[0].format);  // 取得另一個欄位
    return '<span title="'+ title +'">' +  data  + '</span>';
}

如何控制DataGrid Row的背景顏色?
透過DataGrid的RowStytler事件來處理, 如下:
 
js舉例如下:
function dgMaster_rowStyler(index, row)
{
    if(index%2 == 0)
        return 'background-color:#FFFFBB;color:black;';
    else 
        return 'background-color:#77FFCC;color:black;';
}

如何讓查詢的Refval欄位做到ColumnMatch的功能?
在QueryColumns的refval欄位屬性Editor裡設定OnSelect事件(雙擊可以直接產生一個function)
js舉例如下:
function dgMaster_客戶編號_onSelect(row)
{
$('#dgMasterqueryObj_名稱').val(row.名稱);
//#dgMasterqueryObj_名稱 為另一個查詢欄位的ID
//row.名稱 為 refval該筆資料的其他欄位值
}

如果不希望DataGrid的某欄位自動換行,該如何處理? 設定DataGrid->Columns->該欄位的屬性Nowrap設為false即可
如何讓DataGrid結束編輯?
舉例:
在明細DataGrid的Toolitem添加一個按鈕去執行下方的js
 
function end_Edit()
{
    $("#dgDetail").datagrid('endEdit');
}
DataGrid如何取得欄位加總值?
JQ取值方法:
    var footer =$('#dgMaster').datagrid('getFooterRows');
    alert(footer[0].欄位);
RWD取值方法:
    var totalRow = $('#dgMaster').datagrid('getTotal');
    alert(totalRow.欄位);

DataGrid的查詢, 我如何更換查詢條件?
可以透過 onQuery事件, 如下:
function dgMaster_onQuery(whereItems)
{
    for (i=0;i<whereItems.length;i++)
    {
        if (whereItems[i].field=='帳戶' && whereItems[i].value=='全部')  whereItems[i].value="";  // 如果是全部, 代表查詢為空
    }
    return true;
}
DataGrid查詢時, 我如何在欄位名稱上加上運算式來查詢?
前端的 onQuery是無法改動欄位名稱或加上運算式的, 所以必須改用後端 InfoCommand的onBeforeExecuteSQL事件來處理, 如下:
exports.股東開會通知書_onBeforeExecuteSQL = function(sql, whereStrs)
{
    for (var i = 0; i < whereStrs.length; i++) {
     whereStrs[i] = whereStrs[i].replace(/股東戶號/g, "CONVERT(INT,股東戶號)");  //將股東戶號改用INT的模式來查詢
    }
    return sql;
};
如果DataGrid屬性ShowCheckBox設為True,如何取到所有被勾選資料的某欄位值?
function GetCheck()
{
    var rows = $("#dgMaster").datagrid('getChecked');  //取出所有被勾選的資料
    for(var i = 0 ;i <rows.length;i++){
        alert(rows[i].出貨編號);
    }
}
DataGrid編輯時, 是否可以動態改變編輯器的屬性內容?
可以的, 如下使用 onShowEditor事件來處理, 利用editor來存取編輯器的屬性, 下面的例子是動態改變Combobox的欄位與條件:
function dgDetail2_onShowEditor(index, field, editor)
{
   if(field == '聯絡人') {
       editor.options.valueField = '次序';
       editor.options.textField = '姓名';
       editor.options.whereItems = [{ field: '客戶編號', operator: '=', value: "parent['客戶編號']"}];
   }
   return editor;    
}
如何在控制DataGrid動態隱藏或顯示每一筆row的(查看/編輯/刪除)按鈕?
可以透過OnLoad事件來處理,如下的方式:
$($('#dgMaster').find('.glyphicon-eye-open')[i]).hide();//查看按鈕
$($('#dgMaster').find('.glyphicon-pencil')[i]).hide();//編輯按鈕
$($('#dgMaster').find('.glyphicon-remove')[i]).hide();//刪除按鈕
// 以上i就是row的序號,從0開始,如要顯示的話將hide()改為show()
如何自行用程式進行DataGrid的新增/更改/刪除功能?
舉例如下:
var index = $('#dgMaster').datagrid('getSelectedIndex');
$('#dgMaster').datagrid('viewRow', index); // 查看 
$('#dgMaster').datagrid('delete_row', index); // 刪除
$('#dgMaster').datagrid('edit_row', index); //更改
$('#dgMaster').datagrid('insert_row'); //新增

瀏覽和編輯方法的第二個參數是rowindex,上面'getSelectdIndex是代表選中的row。 如果要指定某一筆row可以自行設定index值。
如何自行控制DataGrid的Query視窗所執行的"查詢/清除/取消"等按鈕功能?
在DataGrid的onBeforeLoad事件處理,舉例如下:
改寫DataGrid Query "查詢" 按鈕要做的事:
$('.form-query').unbind('click').bind('click', function () {
    //$('#dgMasterqueryObj').form('query'); //原來執行的功能
    alert('Query');
});
//改寫DataGrid Query "清除"按鈕要做的事情:
$('.form-clear').unbind('click').bind('click', function () {
    // $('#dgMasterqueryObj').form('clear'); //原來執行的功能    
alert('Clear');  
});  
//改寫DataGrid Query "取消"按鈕要做的事情:  
$('.form-close').unbind('click').bind('click', function () {  
    $('#dgMasterqueryObj').form('close'); //原來執行的功能  
    alert('Close');  
});
如何動態改變DataGrid 的標題Title?
舉例如下:
$('#dgMaster').prev().prev()[0].innerText = "你的標題";
如何取得DataGrid的資料總筆數?
可以在DataGrid_OnLoad的時機點取得資料總筆數,如下:
function dgMaster_onLoad(data)  
{  
        alert(data.total);  
}
如何隱藏或打開Query查詢的Panel?
$('#dgMasterqueryObj_panel').collapse('hide'); // 隱藏
$('#dgMasterqueryObj_panel').collapse('show'); // 打開
DataGrid打開的查詢頁面過小, 會造成部分查詢欄位折行, 可以加大彈出頁面的寬度嗎?
可以, 統一在"網頁"/"共用樣式表(CSS)"中, 設定以下的CSS內容即可:
@media (min-width: 768px){
    .bootstrap-form[id$="queryObj"] .modal-dialog{
        width: 700px; // 電腦桌面開啟寬度改為700點
    }
如何搭配ShowCheckBox的屬性控制當頁資料全部勾選或者全部取消勾選?
舉例:
function CheckAll()
{
    //全部勾選
    $(this).datagrid('checkAll');
}
function UnCheckAll()
{
    //全部取消勾選
    $(this).datagrid('uncheckAll');
}
如何讓user輸入密碼後才允許刪除?
舉例: 
請先將DataGrid的ConfirmDelete屬性設為False,再以onDelete的事件處理如下
var delFlag = false;
function dgMaster_onDelete(row)
{
    var delPassword='';
    if (!delFlag) {
        $.prompt( "請輸入管理者刪除密碼: ?","" , function(DelPassword) {
            if (DelPassword =='123'){  //為了保密, 這段最好寫在後端
                var index = $('#dgMaster').datagrid('getSelectedIndex');
                delFlag = true;
                $('#dgMaster').datagrid('delete_row', index);
            }
            else {  
                $.alert('密碼不正確, 取消刪除','info');
                delFlag = false;
            }
        });
    }
    return delFlag;
}
DataGrid的QueryColumns如何抓到指定日期的30天後?
舉例:
在QueryColumns欄位中的onSelect事件
function dgMaster_訂單日期_onSelect(date)
{
    var date = $('[name="dgMasterqueryObj_3"]').datebox('getValue');
    var addDate = addDays(date,30);
    $('[name="dgMasterqueryObj_4"]').datebox('setValue',addDate);

}
dgMasterqueryObj_3和dgMasterqueryObj_4為訂單日期起迄欄位的name

如果datagrid屬性autoApply設為false,那該如何針對Datagrid做存檔的動作?
在DataGrid的Toolitem添加一個按鈕去執行下方的js
function dg_submit()
{
    $('#dgMaster').datagrid('endEdit');//結束編輯
    $('#dgMaster').datagrid('submit');//存檔
}
DataGrid的QueryColumns使用時間欄位作為起迄時間查詢時,如何透過起始日期的值,自動給值至結束的日期欄位?
在QueryColumns的日期onSelect事件中,添加以下代碼
function dgMaster_日期_onSelect(date)
{
   var date = $(‘[name=”dgMasterqueryObj_3”]’).datebox(‘getValue’);
   var addDate =addDays(date,30); //將結束日期欄位設為抓取起始欄位後30天
   $(‘[name=”dgMasterqueryObj_4”]’).datebox(‘setValue’,addDate);
}
dgMasterqueryObj_3和dgMasterqueryObj_4為日期起迄欄位的name
DataGrid編輯中, 如何透過Refval選不同的ID, 來控制其他欄位是否可以編輯?
可以透過 Refval的 onSelect事件來控制, 如下:
function dgDetail_科目編號_onSelect(row)
{
   if (row.性質控制!='是') {  // 判斷條件
      $(this).closest('tr').find('td[data-field="性質別"]').find('.form-control').setReadonly(true); // 將性質別設為Readonly
   }
   else {
      $(this).closest('tr').find('td[data-field="性質別"]').find('.form-control').setReadonly(false); // 將性質別設為可編輯
   }
}
如何在 dataGrid中, 動態控制另一個Refval的資料來源與WhereItem內容?
假設有當某一個Refval更改時, 觸發了onSelect事件, 透過這個事件, 來控制另一個 Refval的RemoteName與WhereItem, 如下:
function dgDetail_科目編號_onSelect(row)
{
   var editor=$(this).closest('tr').find('td[data-field="子科目"]').find('.form-control'); //取得子科目的Refval對象
   if (row.對象別=='子科目') {  // 動態設定 refval的資料來源
      editor.refval('options').remoteName='會計科目.會計子科目';
      editor.refval('options').whereItems = [{field:'科目編號', operator: '=', value: "row['科目編號']"}]; // 動態設定WhereItem
   }
   else if (row.對象別=='客戶') { // 動態設定 refval的資料來源
      editor.refval('options').remoteName='客戶資料表.客戶子科目';
      editor.refval('options').whereItems = [];       
   }
   else if (row.對象別=='廠商') { // 動態設定 refval的資料來源
      editor.refval('options').remoteName='廠商資料表.廠商子科目';
      editor.refval('options').whereItems = [];
   }
}
請問Server Method會處理比較久, 如何頁面上告知'處理中'的訊息?
可以透過 $.loading() 來處理, 如下:
 $.loading($('#dgMaster').closest('div'), '處理中...');  // 顯示進度訊息
            $.callMethod('員工資料表','doCloseSalary',{yymm:row.年月,co:row.子公司,id:row.員工編號},function(result){ // 執行後端檢查方法
                $.loaded($('#dgMaster').closest('div')) //關閉訊息框
                $.alert('員工:'+row.員工編號+' 薪資結算成功!','info');
                $('#dgMaster').datagrid('load');
            });

如何在 DataGrid的QueryColumns中固定增加一個欄位?
有兩個方法, 一個寫在前端 DataGrid.onQuery() 事件, 如下:
   whereItems.push({field:'子科目',operator: '!=',value: ''});    
   return true;
}
另一個方法寫在後端的 Command.onBeforeExecuteSQL事件中, 如下:
exports.明細分類帳_onBeforeExecuteSQL = function(sql, whereStrs)
{
    whereStrs.push("子科目<>''");
    return sql;
};
如果我想在DataGrid的編輯要帶入初值, 而不是新增時帶入, 要如何處理?
可以使用DataGrid的onUpdate事件來處理, 以下為上一筆欄位的內容值, 帶入下一筆的方法:
function dgDetail_摘要_onBlur() 
{
    var rem = $('#dgDetail').datagrid('getEditorValue', '摘要');
    $.setVariableValue('remark',rem,true); // 設定全域變數 remark
}
 
function dgDetail_onUpdate(row)
{
    if (row.摘要.length==0)  row.摘要 = $.getVariableValue('remark');
    return true;
}
如何利用ToolItem對datagrid的資料進行過濾?
可以在ToolItem添加一個按鈕,onClick時呼叫一個function,參考如下:
function test(){ 
     $('#dgMaster').datagrid('setWhere',"您的Where條件'"); 
     // dgMaster為datagrid id
 }
為何我資料庫欄位前面故意有空格, 但到了DataGrid卻不見了?
因為空格在網頁中是無法顯示的, 要使用HTML的格式才會顯示, 可以加入 formatter 事件來處理:
function dgMaster_科目名稱_formatter(value, row, index)
{
 return (value || '').replace(/\s/g, '&nbsp;');    
}

如何默認選取Datagrid指定的第幾筆資料?
function select_first()
{
    var index = 0;
    $('#dgMaster').find("tbody>tr:eq("+index+")").addClass('selected').addClass('info');
    //$('#dgMaster').find("tbody").find("tr:eq("+index+")").addClass('selected').addClass('info');
}

Datagrid如何依照有勾選的資料進行欄位加總值的計算?
$(function (){
    //第一次進入畫面 先將total歸0
    setTimeout(function (){
        $("#dgMaster").find('tfoot>tr>td').each(function () {
            if ($(this).attr('data-field') == "小計") {
                $(this).find('.table-cell-text').html(0);
            }
        });
    },100);
    //添加onclick事件
    $('#dgMaster').click(function(){
        var Total = 0;
        var sumTotal = 0;
        var rows = $("#dgMaster").datagrid('getChecked');  //取出所有被勾選的資料
        if (rows.length > 0){
            for(var i = 0 ;i <rows.length;i++){
                Total=(parseInt(rows[i].小計));
                sumTotal += Total;
            }
        }
        $("#dgMaster").find('tfoot>tr>td').each(function () {
            if ($(this).attr('data-field') == "小計") {
                $(this).find('.table-cell-text').html(sumTotal);
            }
        });
    });
});

DataForm

當前位置:首頁>常見問答>EEPCloud


如何在user編輯時讓某一個欄位無法編輯?
首先,請至EEPCloud中點選左側RWD選到你要實作的那個表單, 
並點選要做設定的該欄位的dataform或datagrid,然後點選右側的Columns。


接下來請找到你要設定的欄位,並點選Editor進去做設定。



最後勾選"Readonly"即可,這樣即可以達到使該欄位無法被新增修改。


如何在DataForm中,新增一個連結或按鈕 打開另表單? 如下的JS範例,在"請假年度"的後方插入一個"請假狀況"的連結,並將申請人與請假年度傳送到"員工休假狀況表"的表當中。

$(function(){
    $('<a style="vertical-align:middle;display:table-cell;padding-left:10px;cursor:pointer">請假狀況</ a>').insertAfter($('#dfMaster__請假年度')).click(function(){
        if(window.top.addTab){
            var user = $('#dfMaster__申請人').refval('getValue');
            var year = $('#dfMaster__請假年度').dateselect('getValue');
            window.top.addTab('員工休假狀況表','員工休假狀況表', 'bootstrap/員工休假狀況表?year=' + year + '&user=' + user); //打開表單
        }
        else{
            alert('預覽無法打開此網頁')
        }
    });
})


另一個表單(如員工休假狀況表)的前端js

function dgMaster_onBeforeLoad(param)
{
    var year = $.getParameter('year');
    var user = $.getParameter('user');
    if(year && user){
    param.whereStr = "年度 = '" + year + "' AND 員工編號='" + user + "'"; 
// 設定 Datagrid的Where條件
    }
}

如何以程式控制DataForm的關閉或存檔?
$('#dfMaster').form('close'); //關閉dataform
$('#dfMaster').form('submit'); //存檔dataform

如何讓RWD DataForm的欄位隱藏?
//適用欄位類型:textbox/textarea/numberbox/datebox/dateselect/options/combobox/refval
//$('#dfMaster_欄位').parent().parent().hide();
//$('[for="dfMaster_欄位"]').hide();
    
//適用欄位類型:multiinput
//$('#dfMaster_欄位').parent().parent().parent().hide();
//$('[for="dfMaster_欄位"]').hide();
    
//適用欄位類型:switch
//$('#dfMaster_欄位').parent().parent().hide();
//$('#dfMaster_欄位').parent().parent().prev().children().hide();
    
//適用欄位類型:fileupload
//$('#dfMaster_欄位').parent().hide();
//$('[for="dfMaster_欄位"]').hide();

如何更改DataForm欄位的底色?
$(function(){   
    $('#dfMaster_CustomerID').css('background-color', '#fdd');
})
dfMaster_CustomerID -> 請自行替換DataFormID + 欄位ID
#fdd -> 請自行替換顏色

DataForm中如何控制在存檔前再次檢查條件, 並不讓user保存?
function dfMaster_onApply()
{

    var date = $('#dfMaster_進貨日期').datebox('getValue');
    date = date.substr(0,4)+date.substr(5,2);
    
    var closeym = $.getVariableValue('closeYM');
    if (date <= closeym) {
          $.alert("進貨日期小於結帳日, 無法保存",'info');
          return false;
    }
    return true;
}

如何取得DataForm的編輯狀態?
var status = $('#dfMaster').form('status');
status的值如果是 view 代表是編輯狀態為"查看",
inserted 代表是編輯狀態為"新增",
updated 代表是編輯狀態為"修改"。

只有DataForm(表單)的情況下,可否一打開表單就進入新增狀態,存擋後並顯示該筆新增的資料。
加入DataForm的onLoad事件:
var firstTime = true;
function dfMaster_onLoad(row)
{
    if(firstTime)  {
        firstTime = false;
        $(this).form('insert_row');  // 進入新增
    }
}
 
並在onApplied事件中, 顯示該新增的資料。
function dfMaster_onApplied(data)
{
    var key = data[0].inserted[0].F001;
    $(this).form('setWhere',"F001='"+key+"'");
    $.alert('新增成功!! 編號:'+key,'info');
}

如何讓 DataForm的 Pagination可以隱藏不顯示, 只顯示 ToolItems即可?
貼入Literal 組件, 然後設定 HTML內容如下即可:

<style>
  #dfMaster .pagination{
  display:none
  }
 </style>

DataForm中, 如何用JS存取TextBox的內容?
textbox取值的方法為:
var year = $('#dfMaster_請假年月').val();

textbox設值的方法為:
$('#dfMaster_請假年月').val(yymm);
如何在前端的DataForm編輯時顯示時鐘, 且此時鐘為Server端的時間?
可以透過以下的 JS 程式來完成:
var firstTime = true;  //僅Load網頁時第一次才執行.
var serverDate = '';  //設定Server端日期時間的共用變數
function dfMaster_onLoad(row)  // 讓DataForm自動進入新增狀態
{
    if(firstTime)  {
        firstTime = false;
        $(this).form('insert_row');  //新增一筆資料
        serverDate = $.getVariableValue('now');  //取得Server端日期間
        showtime();
    }
}
function showtime()
{
    var currtime = new Date(serverDate).Format('yyyy-MM-dd hh:mm:ss');  //取得Server端日期時間變數
    $('#dfMaster_日期時間').val(currtime);  // 設定打卡的時間日期
    if ($('#dfMaster').form('status')=='inserted') {   
        var systemTime = new Date(serverDate).getTime()+1000;  //將serverDate轉成數值+1000毫秒
        serverDate = new Date(systemTime);  //重新存回serverDate
        setTimeout('showtime()',1000);  //1秒以後重新執行showtime()
    }
}

在DataForm中, 如何取得 #O Options的選擇內容?
如下, 可以透過以 selectoptions()的方法來取得:
function dfMaster_onApply()
{
    var date1 = $('#dfMaster_申請日期').datebox('getValue');
    var date2 = $('#dfMaster_請假日期').datebox('getValue');
    var type = $('#dfMaster_請假類型').selectoptions('getValue');
    if (type=='特休假' && date1 < date2) {
          $.alert("特休假 至少需前1日申請之",'info');
          return false;
    }
    return true;
}

DataForm輸入時, 如何控制不同的欄位條件, 要自動控制那些欄位可以輸入(控制Readonly)?
如下例, 用戶選擇 Options條件後, 可以控制另一個欄位是否可以輸入, 設定其Readonly屬性:
function dfMaster_請假類型_onSelect(value)
{
    if (value=='特休假') {
        $('#dfMaster_特休假年度').setReadonly(false);
    }
    else {
        $('#dfMaster_特休假年度').setReadonly(true)
    }
}

DataForm有多個頁簽, 如何控制不同的人可以編輯不同的頁簽? (頁簽如何隱藏)
可以透過DataForm的onLoad事件來控制, 並判斷沒有權限的人, 將頁簽隱藏即可, 如下JS程式:
function dfMaster_onLoad(row)
{
    var groups = $.getVariableValue('groups');
     if (groups.indexOf("80")<0) { // 找不到"80"的群組角色
        var tabID = 'tabMaster';  // 設定要隱藏的 Tab
        var index = 1;  // 第幾頁要隱藏 (從0開始算)
        $('[href="#'+ tabID + '_'+ index +'"]').hide();
    }
}

如何針對#G Group群組裡的所有欄位進行ReadOnly處理?
var fs = $('#dpgroup_借用資訊_M_CU').closest('fieldset');//取得欄位群組
fs.find('.form-control').setReadonly(true);
//設所有欄位為readonly,反之設成false即可

如何取得DataForm欄位Refval的TextValue的值?
Refval的取值方式為:
$(target).closest('.row').find('.refval-text').val();

例如: 
$('#dfMaster_客戶編號').closest('.row').find('.refval-text').val();

DataForm中的各種欄位讀取值與設定值方法都不一樣,如下:

類型

取值

給值

TextBox

$(target).val();

$(target).val(value);

TextArea

$(target).val();

$(target).val(value);

Combobox

$(target).combobox('getValue');

$(target).combobox('setValue',value);

Refval

$(target).refval('getValue');

$(target).refval('setValue',value);

Optons

$(target).selectoptions('getValue');

$(target).selectoptions('setValue',value);

Numberbox

$(target).val();

$(target).val(value);

Datebox

$(target).datebox('getValue');

$(target).datebox('setValue',value);

Datetimebox

$(target).datebox('getValue');

$(target).datebox('setValue',value);

Timebox

$(target).timebox('getValue');

$(target).timebox('setValue',value);

Switch

$(target).switch('getValue');

$(target).switch('setValue',value);

Slider

$(target).slider('getValue');

$(target).slider('setValue',value);

DateSelect

$(target).dateselect('getValue');

$(target). dateselect ('setValue',value);

如何使DataForm所有欄位caption位置都靠左?
先於工具箱拉出一個Literal,並於HTML中寫下CSS:
<style>
@media (min-width: 768px) {
.form-horizontal .control-label {
    text-align: left;
    }
}
</style>

如何調整某一個DataForm欄位caption位置靠左?
舉例如下:
$('[for="dfMaster_員工編號"]').css('text-align', 'left');

DataForm如何動態更換標題及欄位顏色?
舉例如下:
DataForm標題顏色
$('[id="modalLabel"]').css('color', 'red');

欄位標題
$('[for="dfMaster_員工編號"]').css('color', 'blue');

欄位值
$("#dfMaster_員工編號").css('color', 'green');

DataForm中的DefaulValue通常是新增的時後帶入預設值, 如果想要更改的時後也帶入值, 要如何處理?
可以用 DataForm的onLoad事件來處理, 如下:
function dfMaster_onLoad(row)
{
   var memo = $('#dpMaster2_常規準備事項').val();
   if (memo.length == 0) {
       var def = $('#dfMaster').form('getDefaultValues').常規準備事項;
       $('#dpMaster2_常規準備事項').val(def);  
   }
}

DataForm輸入後, 如何取得自動編號或存檔之後的值?
可以使用 onApplied() 事件來處理, 如下:
function dfMaster_onApplied(data)
    if (data[0].inserted.length > 0)  // 新增才處理
    {
        var row=data[0].inserted[0]; // 取得剛剛insert的那一筆資料
        var repno = row.報修編號;   // 取得報修編號
        var date = row.報修日期;
        var man = row.報修人;  
        $.callMethod('報修服務紀錄','sendMail',{repno1:repno,date1:date,man1:man},function(err,result)
                     {
            if(err)
            {
                alert(err);
            }
            else $.alert('已報修並發送給管理中心','info');
            } 
        });
   }
   return true;
}

請問如何更換 DataForm 的Title標題?
可以利用 onLoad事件即可, 如下:
function dfMaster_onLoad(row)
{
    $('#dfMaster').find('.modal-title').html(row.F001);  // F001為欄位名稱
}

如何控制 DataForm的欄位標題與內容的寬度?
原來DatForm在sm模式下(電腦或平板頁面), 標題佔2/12, 欄位佔 4/12, 所以可以左右可以放2個欄位,如果想把標題加大到 3/12, 欄位縮小到 3/12(兩個一樣寬), 如下的程式:
* 更換DataForm的Title與欄位寬度
function dgMaster_onLoad(data)
{
   $('#dfMaster').find(".col-sm-4").removeClass("col-sm-4").addClass("col-sm-3");  //把所有的 col-sm-4 換成 col-sm-3
   $('#dfMaster').find(".col-sm-2").removeClass("col-sm-2").addClass("col-sm-3");  //把所有的 col-sm-2 換成 col-sm-3
}

DataForm使用到了ToolItems時會順便把導航條(操作上下筆)給顯示出來, 可否將導航條給隱藏?
可以, 請貼入一個 Literal組件, 在Html中設定以下的CSS即可:
<style>
  #dfMaster .pagination{
   display:none
  }
</style>

可以控制 DataForm存檔後不關閉嗎? 為了能及時存檔並取得最新的資料。
可以,如下的JS程式:
$(function(){
    $('#dfMaster').on('hide.bs.modal', function(e) {  // DataForm關閉時執行
       if($(this).data('isApply')){  // 判斷 isApply是否為True
         e.preventDefault();  //取消關閉DataForm的動作
            $(this).removeData('isApply');  // 再把isApply變數清除
        }
    });
})
function dfMaster_onApply()
{
    $(this).data('isApply', true);  //存檔前設定 isApply變數為True
    return true;
}

如何透過JS動態控制DataGrid的Where條件?
舉例如下:
function dfMaster_onLoad()
{
        $('#dgMaster ').datagrid('setWhere',"你的where條件");
}
如何透過JS動態控制Refval的Where條件?
舉例如下:
function dfMaster_onLoad()
{
        $('#dfMaster_欄位').refval('setWhere',"你的where條件");
}
如何透過JS動態控制Combobox的Where條件?
舉例如下:
function dfMaster_onLoad()
{
        //Combobox選項來源必須來自RemoteName而非Item
        $('#dfMaster_欄位').combobox('setWhere',"你的where條件");
}
DataForm新增資料後如何自動匯出Word?
透過DataForm的OnApplied事件來處理,程式碼如下:  
 
function dfMaster_onApplied(data)  
{  
    if (data.inserted.length>0) {  // 當Insert時才處理  
        $('#dgMaster').children("tbody").children("tr").removeAttr("class"); //離開選中哪一筆  
        $('#dgMaster').children("tbody").children("tr:last").attr("class", "selected info"); // 選中目前頁最後一筆  
        $('#dgMaster').datagrid('exportWord'); //調用輸出Word的功能  
    }  
}
如何控制使用者的游標進入DataForm的某個欄位?
舉例如下:
$('#dfMaster_英文姓名').focus(); // 進入英文姓名編輯
如何針對整個DataForm或指定頁籤底下的所有欄位ReadOnly?
如下的程式:
//如何Tab頁籤底下的所有欄位設為ReadOnly
$("#tabMaster_1").find('.form-control').setReadonly(true);
//如何將DataForm底下的所有欄位設為ReadOnly
$("#dfMaster").find('.form-control').setReadonly(true);
Signature簽名組件簽名時,可否自動設定簽名日期時間?
可以利用 Sinature的onChange事件來處理, 如下: 
function dfMaster_簽收_onChange()
{
 $('#dfMaster_簽收日期時間').val(new Date().Format('yyyy-MM-dd hh:mm:ss'));
}
如何透過js關閉DataForm?
舉例:
$('#dfMaster').modal('hide');
如何動態改變DataForm欄位caption名稱?
舉例:
function dfMaster_onLoad(row)
{
    $('[for="dfMaster_姓名"]')[0].innerText = '測試';
}

如何透過js觸發DataForm的Validate元件的檢查機制?
舉例:
$('#dfMaster').form('validate');

DataForm在Mode為Panel時, 顯示的狀態為唯讀的狀態, 如何讓他進入編輯狀態?
可以在需要編輯的時候, 執行下列 JS語法即可:
$('#dfMaster').form('status', 'updated'); 
或者:
$('#dfMaster').form('edit_row');
如何用js控制#G DataPanel的縮放?
$('id').closest('form').hide() // 找任一群組內的欄位ID
js舉例: 
$('#dpgroup_家庭資料_家庭背景描述').closest('form').hide();  //隱藏
$('#dpgroup_家庭資料_家庭背景描述').closest('form').show(); //顯示

Server

當前位置:首頁>常見問答>EEPCloud


Refval關聯元件可以使用WhereItem過濾資料,如果過濾條件較複雜無法以WhereItem設定時,應如何處理?
可以從server的該關聯的infocommand裡用SQL語法去過濾資料。
以出貨單為例,如果想要過濾 已審核 且 客戶編號為'1' 的"報價單號" : 

可以先在server端的infocommand寫入SQL語法過濾出已審核的報價單。


再從DataForm的column中的"報價單號"欄位設定WhereItem
如何在前端下SQL語法取得資料?
基於資訊安全的原因,eepcloud是不允許在前端直接執行SQL語法的,只能夠過後端的 Server Method來執行。

後端的ServerMethod寫法,如下:
exports.dosql = function(param, callback){
    var clientInfo = this.clientInfo;
   var id=param.id;
    var sql = "select 名稱 from 客戶資料表 where 客戶編號 = '"+id+"'"; //SQL條件句
   this.queryRaw(clientInfo, clientInfo.database, sql, {}, callback);
}

Client端的調用,如下的JS
function Test()
{
    var result =$.callSyncMethod('客戶資料表', 'dosql',{id:001}); //非同步調用
    var param = $.parseJSON(result); //傳回result為JSON格式
    if (param.length != 0){
        alert(param[0].名稱);  //假設只傳回1筆資料
   }
}

如何在前端執行後端的SQL?
舉一個去後端更改一個Table某個欄位的日期格式例子,前端的JS:
function mymethod(){ 
    $.callMethod('庫存進出明細表','dosql',{},function(result){
        alert('執行成功!');
    });
}
庫存進出明細表 ->後端模組名稱
dosql -> callServerMethod 的名稱(請自行命名)

後端的JS:
exports.dosql = function(param, callback){
    var clientInfo = this.clientInfo;
    this.query(clientInfo, clientInfo.database, ['update [庫存進出明細表] set F010=LEFT(CONVERT(varchar(50),F003,112),6)'],{}, callback);
};

如何在後端資料存檔後,下達自己的SQL? 可以使用UpdateComp的onAfterUpdate事件寫一段後端JS來完成,如下:
sqls.push()為送出的自訂SQL語法,row._客戶編號 為該更改資料的欄位名稱。
如何Call Stored?
後端的js

exports.testMethod = function(param, callback){
    var clientInfo = this.clientInfo;
    var module = this;
    var sql =" exec test '"+param.userid+"' "; //SQL條件句
    module.query(clientInfo,clientInfo.database,[sql],{},function(err, result){
        if(err){
            callback(err)
        }
else{
            callback(null,result);
        }
    }); 
};


前端的js

function callservermethod(){
    var user = $.getVariableValue('user');
    $.callMethod('test', 'testMethod', {userid:user}, function(result){
     alert('成功執行');
    });
}
test -> 後端模組名稱
testMethod -> callServerMethod 的名稱(請自行命名)
userid:user -> 上傳的參數(如果沒有的話可以填null)

如何在Server端存檔前(新增或更改) 再決定某個欄位的內容並存入資料庫? 後端的js:

exports.uc盤點單明細_onBeforeInsert = function(row, sqls, callback)
{
    var dm = this.dataModule;
    var clientInfo = dm.clientInfo;
  
    var sql = "select max(年月) AS LASTYM from 庫存結帳表";
    dm.queryRaw(clientInfo, clientInfo.database, sql, {}, function(err, datas) {
        var last_period = datas[0].LASTYM;
        sql = "select 平均成本 from 庫存結帳表 Where 產品編號='"+row.產品編號+"' and 年月='"+last_period+"'";
        dm.queryRaw(clientInfo, clientInfo.database, sql,{}, function(err, datas) {
            if (datas.length>0) {
               row.單價 = datas[0].平均成本;
            }
            callback(null, true);
        });
    });
}

為何在server端的infocommand寫sql語法使用(不等於<>)會報錯?
因網頁安全問題『<>』要改用『 != 』

會報錯的語法 :
SELECT vUSERS.* FROM vUSERS 
where STATE <> '離職' 
ORDER BY USERID

須改為下列正確語法 :
SELECT vUSERS.* FROM vUSERS 
where STATE != '離職' 
ORDER BY USERID

如何在EEPCloud中開發Stored Procedure? 如何呼叫? 在EEPCloud的Table節點中, 可以右鍵"儲存過程"(預存程序), 打開頁面後可以用"+新增"來增加一個Stored Procedure, 如下, 填寫 Name為Stored Procedure Name, Parameters為Input/Output參數, Text代表Stored Procedure的程式內容,並按下確定即可。

如果在Server端要執行此SP, 只要使用 "Exec" 來執行即可, 如下的Server Method:
exports.doCreate = function(param,callback){
    var year = param.year; // 取出年度
    var clientInfo = this.clientInfo;
    var dm = this;
    dm.query(clientInfo, clientInfo.database, ['exec sp_vacation '+year],{}, callback); //執行sp
};

TRS交易時, 是否可以控制某些條件成立在過帳, 否則就不過帳?
可以的, 在EEPCloud的Transaction組件中, 每一個交易都有一個onBeforeTrans事件, 可以控制是否要持續交易或動態改變對方的交易欄位, 如下為控制是否交易的例子:
exports.trs請假單_年度特休假表_onBeforeTrans = function(row, oldRow, fields)
{
   if (row.請假類型!='特休假')  return false;  //不為特休假就不過帳
   return true;
};
上面的情況是針對'請假類型'不能更改的情況, 如果請假類型可以更改的話, 要改成這樣:
exports.trs請假單_年度特休假表_onBeforeTrans = function(row, oldRow, fields)
{
   if (row.請假類型!='特休假' && oldRow.請假類型!='特休假') {  //考慮更改時新舊值都不為特休假
       return false;
   }
   else if (oldRow.請假類型=='特休假') {  //如果是特休假改為其他假時
       row.請假天數=0;
   }
   return true;
};

Server端的JS程式非常不好Debug, 常常不知道錯誤在哪? 有沒有比較好的方法可以Debug?
Server端在主機, 服務大眾用戶, 確實很難Debug, 可以如下的方式來debug:
1. 可以在Server端中使用 dataModule.echo()方法, 回應到SQL Profiler的"Server"訊息中, 如使用 echo('pass 1'); 等等了解JS的程式邏輯與執行到哪個階段出錯, 或echo()你自己的變數, 看看是否變數的內容有錯。
2. 另一個方法, 就是當Server端程式比較複雜, 需要調用非同步的程式時, 如果非同步程式內出錯, 會回不來, 此時最好在非同步程式中, 使用 try/catch的方式來避免回不來, 如下:

後端Command中的SQL比較複雜, 用了很多Left Join與欄位AS別名後, 前端的Query送出後會發生Where錯誤, 因為前端並不知道後端的實際的欄名, 如何解決?
可以透過後端Command的onBeforeExecuteSQL事件來重新替換Where的欄位名稱, 如下的範例:
exports.GPT010RA_onBeforeExecuteSQL = function(sql, whereStrs)
{
     for (var i = 0; i < whereStrs.length; i++) {
      whereStrs[i] =  whereStrs[i].replace(/M_SVS/g, 'A.M_MA');  //將M_SVS別名欄位換成實際的A.M_MA欄位
     }
 return sql;  
};
執行後端的Server Method如果時間較長,如何告知使用者執行中,並於結束後關閉此訊息?
如下, 可以透過 $.loading()與$loaded() 這兩個方法來處理: 
function sendMail()
{
    $.confirm( "確認發送薪資eMail嗎?", function() {
        $.loading($('#dgMaster').closest('div'), '處理中...');
        $.callMethod('薪資明細表','doSendMails',{},function(result){ 
            $.alert(yymm+' 薪資eMail發送成功!','info');
            $.loaded($('#dgMaster').closest('div')) //關閉訊息框
         });
     });
}}

如何在後端利用資料表內容發送不同對象的eMail?
發送多封不同對象的EMail時, 因為EMail發送為非同步的機制, 所以這裡要採用一個 async非同步機制來執行, 可以透過Server端infoMail這個組件來發送eMail, 如下的範例, 其中, 可透過InfoMail.htmlrow()以網格形式來輸出欄位內容到Email內容中:
exports.doSendMails = function(param,callback){
this.echo('do send mail begin');
    var yymm = param.yymm;  // 取得薪資發放月份
    var co = param.co; //取得子公司
    var dm = this;
    var async = this.getModule('async'); // 改用新的方式來引用 async 非同步模組
this.getComponent('InfoMail1','infomail',function(err,mail){   
        var sql = "SELECT A.薪資年月,A.員工編號,A.部門,A.姓名,A.子公司,A.實發薪資,B.電子郵件 FROM 薪資發放作業 A,員工資料表 B";
sql = sql + " WHERE A.員工編號=B.員工編號 AND (B.電子郵件 IS NOT NULL AND B.電子郵件<>'') AND A.薪資年月='"+ yymm +"' AND A.子公司='"+ co +"'"; //取得當月員工薪資資料
dm.queryRaw(dm.clientInfo, dm.clientInfo.database, sql, {},function(err, rows) {
            if(err){
                callback(err);
            }
else{
async.eachSeries(rows,function(row,cb){
dm.echo(row.電子郵件);
                    var subject = yymm+"月份薪資發放通知";
                    var table1 = mail.HtmlRow(row, [{ field: '薪資年月', title: '薪資年月'},{ field: '員工編號', title: '員工編號'},{ field: '姓名', title: '姓名'},{ field: '子公司', title: '子公司'},{ field: '部門', title: '部門'},{ field: '實發薪資', title: '實發薪資'}]);
                    var param = {'subject':subject,'to':row.電子郵件,'body':table1};
mail.Send(param,cb);  // 發送郵件
},callback);   
            }            
        });
    });
};
為何我在 Server端的 InfoCommand中使用Group By命令, 沒Select到Key的欄位時, 會報錯 "Group By子句"的錯誤? 這是因為InfoCommand預設SelectPaging=True的屬性(資料快速分頁功能), 如果要特殊使用Group by時, 須配合SelectPaging=False即可。
執行Server Method時, 如何控制後端所發生的錯誤或訊息, 來告知前端?
通常後端的錯誤透過 callback(err) 傳送回前端, 如果想自定訊息內容, 可以透過 Error() 來定義, 如下:
exports.doCreate = function(param,callback)
{
    var clientInfo = this.clientInfo;
    var sql =" exec sp_create"; // call sp
    var dm=this;
    this.query(clientInfo,clientInfo.database,[sql],{},function(err, result){
        if(err) callback(new Error('後端的過帳程式出現錯誤, 請聯絡資訊人員!'));
        else callback(null);
    }); 
};

如何正確使用Server端infocommand的SecStyle和SecExcept屬性?
SecExcept要配合SecStyle, SecStyle=User那SecExcept要填Userid,
如果SecStyle=Group, SecExcept則填Groupid, 
如果SecExcept要填多個以”,”或”;”隔開

請問Server端的 JS 如何讓別人共用, 或互相調用?
可以使用 getServerModule來取得對象並直接調用, 如以下為被調用的 出貨單 ServerModule:
exports.readData = function(param,callback)
{
    var dm=param.dm; // 不能用 this.dataModule要從原來的方法中傳進來
    var clientInfo = dm.clientInfo;
    dm.queryRaw(clientInfo, clientInfo.database, "Select * from INVO WHERE F001='"+param.no+"'", {},callback)
}        
如下, 有一個 出貨單的Server Method要調用上面的readData()方法:
exports.writeData = function(param,callback)
{
    var clientInfo = this.clientInfo;
    var dm=this;
    var no=param.no;
    this.getServerModule('出貨單').readData({no:no,dm:dm}, function(err, result){  // call 出貨單.readData() export方法
        try {
            if (result.length != 0){
                dm.query(clientInfo, clientInfo.database, ["update INVO set F018='"+result[0].F016+"'"],{}, callback);
            }
        }
        catch(e)
        {
            callback(e);
        }
    });
}

自動編號中, 如何使用指定欄位作為前引碼來編號?
透過 AutoNumber組建的 onGetFixed事件即可, 如下:
exports.an出貨單_onGetFixed = function(fixedString, rows)
{
    fixedString = rows[0].客戶編號;  // 以客戶編號為前引碼
    return fixedString;
};

為何我CallServerMethod幾次以後, Server會掛掉不回應? 及Server Method如何傳回執行結果?
通常都是Server Method中,沒有執行Callback回不來的原因, 或是執行了兩次Callback,在Server端的Callback注意事項如下:
1. 一定要有callback,而且不能執行2次callback。
2. callback傳回參數的方法,通常會傳兩個參數,第一個參數:Err, 第二個參數: 自訂傳回值(如果有的話)。如下幾種:
  callback(err);  // 只傳回是否錯誤
  callback(err,datas);  // 傳回是否錯誤及datas資料內容
  callback(null);  // 回應正常無錯誤
  callback(new Error('程式發生錯誤, 請聯絡IT部門處理…'));  // 回應自訂的錯誤訊息
  callback;  // 預設傳遞兩個參數, 第1個err,第2個Data
  如以下兩種寫法是一樣的結果, 上面為省略的寫法:
   this.queryRaw(clientInfo, clientInfo.database, sql, {}, callback);  // 第一種寫法
   this.queryRaw(clientInfo, clientInfo.database, sql, {}, function(err,datas) {
    callback(err,datas);
}); // 第二種寫法

為何我在 TRS的onBeforeTrans中, 取不到 this.clientInfo的變數內容?
在UpdateComp或Transaction的事件對象中的 this 並非 dataModule本身, 而是更外層, 所以需使用 this.dataModule來取出 dataModule, 如下:
exports.trs你的表單_TRS_onBeforeTrans = function(row, oldRow, fields)
{
   var dm = this.dataModule;  //取出 dataModule
   var user = dm.clientInfo.user;  // 取得 user等
   .....
   return true;
}

TRS中如何使用後端來編明細表的自動序號?
自動序號通常在前端使用 AutoSeq組件來處理,如果要在TRS中使用自動序號的功能,需要在TRS中設定onBeforeTrans事件,如先在TRS設定好來源是"銷貨單明細.序號",目的是"庫存進出明細表.序號"(Replace模式),其實並要真正讀取來源的序號,而是利用這個機制,透過onBeforeTrans事件來動態替換來源數據來達到目的,如下:
exports.trs銷貨單明細_庫存進出明細表_onBeforeTrans = function(row, oldRow, fields,callback)
{
    var dm = this.dataModule;
    if (oldRow==null) {  // 新增的狀態才處理
        var clientInfo = dm.clientInfo;
        var sql = "SELECT MAX(序號) AS 序號 from 庫存進出明細表 Where 單據號碼='"+row.銷貨單號+"'"; // 取出對應的最大序號
        dm.queryRaw(clientInfo, clientInfo.database, sql, {}, function(err,datas) {
            if (err) callback(err);
            else if (datas.length==0 || (! datas[0].序號)) row.序號='001';  // 第一筆明細為 '001'
            else if (datas.length>0)  row.序號= ((parseInt(datas[0].序號)+1001).toString()).substring(1); // 序號+1
            callback(null, true); // callback要return true讓TRS繼續交易
        });
    }
    else {
        fields.splice(5,1); //刪除 '序號' 過帳欄位, 避免被覆蓋
        return true; // 沒有使用 callback請return true;
    }
};
如何在後端取得系統變數(如今天及時間等)?
舉例:
//後端servermethod的取值
this.getDateValue('today').Format("yyyy/MM/dd");  // 今天
this.getDateValue('firstday').Format("yyyy/MM/dd"); // 本月第一天
new Date().Format("yyyy/MM/dd hh:mm:ss"); //取得目前時間
 
//後端在UpdateComp的事件裡則用
this.dataModule.getDateValue('today').Format("yyyy/MM/dd"); 
this.dataModule.getDateValue('firstday').Format("yyyy/MM/dd");
 
系統變數如下:
變數名稱        內容
today         今天日期  
todayc8     今天日期(varchar8)    
firstday    本月首日  
lastday    本月末日  
firstdaylm  上月首日  
lastdaylm  上月末日  
firstdayty  本年首日  
lastdayty    本年末日  
firstdayly  去年首日  
lastdayly    去年末日
如果只是要到後端取關聯的名稱, 一定要寫Server Method嗎?  
如果只是單純的取某個資料表的每一個欄位值, 可以透過 getDisplayText() 系統方法來取值, 省去後端的Server Method,如下:  
var userMail = getDisplayText('購物車.User','USERID','EMAIL', $('#dfMaster_客戶編號').val() );  // 用客戶編號去取USERS的EMAIL欄位內容  
$('#dfMaster_電子郵件').val( userMail ); // 設值到電子郵件欄位  
以上需注意: "購物車.User"是一個RemoteName,需事先在"購物車"Server端模組中, 設定好"Select * From Users"這個Command  
後端如何傳送非資料表結構的訊息回到前端回?
如下的範例: 
後端的JS:
exports.test = function(param, callback)
{
   if (param.no=='1')  callback(null,'傳送你的訊息!'); // 傳回你的訊息
   else callback(new Error('錯誤!')); // 送出錯誤訊息
}
前端的JS:
function test()
{   
    $.callMethod('出貨單4','test',{no:'1'},function(result){ 
        $.alert(result,'info'); // 傳回正常的訊息
       });
}

其他問題

當前位置:首頁>常見問答>EEPCloud


如何取得登入者的userID?
前端的方法:
var userid = $.getVariableValue('user'); 

後端的方法:
var userid = this.dataModule.clientInfo.user;

server method內使用的方法:
var userid = this.clientInfo.user;

如何在執行JS之前讓USER可以輸入TEXTBOX?
如以下的JS,先透過 $.prompt讓user輸入年月後再往下執行:
function Test()
{
$.prompt( "確認結帳(格式:YYYYMM)?", new Date().Format("yyyyMM"), function(yymm) { 
doClose(yymm);
 });
}

執行後會先出現一個確認窗體,並讓user輸入內容後再往下執行後面的程式。
new Date().Format("yyyyMM") -> 預設日期為西元年+月份
如何取得主機的系統變數?
$.getVariableValue(SystemVar)

變數名稱 內容           
user         用戶編號   
userName 用戶名稱   
groups 用戶群組  
database 資料庫名稱   
solution 方案名稱   
computer IP地址  
locale 語言別   
today 今天日期
todayc8     今天日期(varchar8)  
now         今天日期時間
firstday 本月首日
lastday 本月末日
firstdaylm  上月首日
lastdaylm  上月末日
firstdayty   本年首日
lastdayty   本年末日
firstdayly 去年首日
lastdayly 去年末日

var userid = $.getVariableValue('user'); //取得目前userid
var today = $.getVariableValue('today'); //取得系統日期

前端執行程式前, 如何讓用戶確認再執行?
加上 $.confirm()的方法即可,如:

function sureexec(){
$.confirm( "確認執行?", function() { 
   alert('確認執行!');
  });
}

如何自訂全局變量, 在前後端都可以存取?
* ClientInfo提供自定義變數可讓用戶以全局來使用,可以用 $.setVariableValue('userPara1',value); 來設定內容

用  $.getVariableValue('userPara1'); 來取得內容。如:

// 前端設值的方法:
$.setVariableValue('myvar','andy test');

// 前端讀值的方法:
var myvar = $.getVariableValue('myvar');

//後端設值的方法:
this.dataModule.setClientInfo("myvar",'andy test');

//如果是後端的取值, 須改用:
var myvar = this.dataModule.clientInfo.myvar;

//後端servermethod的設值的方法:
this.setClientInfo("myvar",'andy test');

//如果是後端servermethod的取值,須改用:
var myvar = this.clientInfo.myvar;
如果日期的欄位Type並非為Date而是Varchar,如何設定預設值為今天?
請在Default元件中找到DefaultValue,然後將Type選擇為function,Function取名為test(請自行更改function名稱),並在原始碼處寫下以下function即可。

function test()
{
    return new Date().Format('yyyyMMdd');
}

如何動態控制 #O (Options) 停在哪一個選項?
如下:

function setType()
{
    var hour = new Date().getHours();
    if (hour<10) {
        $('#dfMaster_出勤類別').selectoptions('setValue','上班');
    }
    else if (hour>9 && hour<17) {
        $('#dfMaster_出勤類別').selectoptions('setValue','公出');
    }
    else if (hour>16 && hour<21) {
        $('#dfMaster_出勤類別').selectoptions('setValue','下班');
    }
}

如何在頁面上顯示動態的目前時間?
可以貼一個 Label, 如下:
$(function(){
   showtime();
})

function showtime()
{
    var currtime = new Date().Format('yyyy-MM-dd hh:mm:ss');
    $('#Label1').html(currtime);
    setTimeout('showtime()',1000);
}

如何讓RWD的頁面開放給不用登入的USER來使用?
只要在EEPCloud的設計模式中, 按下'右鍵', 打開 '免登入URL',
將其URL儲存到Server中, 並將本頁面對應InfoCommand.Nonlogin設為True即可,
這樣這個RWD頁面即可開放給沒有login的user來使用。

(注意: 如果你的RWD頁面有寫JS程式碼, 必須把程式碼用<script></script>包裝好, 
另外貼入到 Literal.Html 屬性中, 才能讓免登入URL可以調用)


Tree樹狀組件, 如何在別的組件中取得目前選中的節點, 並取出該節點的資訊?
取得Tree的節點方法如下: 

function getTree()
{
    var selnode=($('#tvMaster').tree('getSelected'));
    if (selnode != null) 
        return selnode.row.目錄編號;
    else
        return '';
}

如何動態控制Schedule(行事曆)的顯示條件?
可以使用Tree的onNodeSelected事件來控制, 如下:

function tvMaster_onNodeSelected(event, node)
{
    var gID = node.row.GROUPID;
    var schedule = $('#Schedule1');
    if (gID == '00') {
        schedule.schedule('setWhere',"1=1");
    }
    else  {
        schedule.schedule('setWhere',"部門='"+gID+"'");
    }
}

為何 ComBoBox 配合 Default的 Variable['user'] 預設使用者時, 有時後會無效? 因為User Login的user id是可以不分大小寫的, 但到了 ComBoBox ?件是有區分大小寫的, 
造成預設值匹配不到ComboBox內容而無效, 所以這種情?下請改用 Refval的選擇 User資料, 不要使用Combo。
如何控制打開工作流查詢模式時,指定顯示條件只顯示該申請者的資料?
可透過 datagrid的onBeforeLoad事件來控制,如下:
function dgMaster_onBeforeLoad(param)
{
    var flowParam = $.getEncryptParameters();  //取得流程的MENU參數
    if (flowParam && flowParam.NAVIGATOR_MODE==0) {
        var user = $.getVariableValue('user'); 
        param.whereStr = "申請人 = '" + user + "'";
    }
}

如何控制Workflow中, 針對某個活動才能更改某欄位內容值?
可以在 dataForm的onLoad事件中取得活動名稱(ActivityText), 再控制該欄位是否可以編輯, 如下:
function dfMaster_onLoad(row)
{
    var flowParam = $.getEncryptParameters();
    if (flowParam && flowParam.ActivityText=='財務審核') {   
      $('#dpgridDetail_核發金額').setDisabled(false); //財務審核時才能更改
    }
}

如何透過JS跳彈顯示一個包含QRCode的網址, 給使用者掃描或拷貝?
可透過 alert()的方法, 將一個 URL的網址以QRCode的方式顯示, 如下的JS程式:
function dfMaster_onApplied(data)
{
  key = data[0].inserted[0].報名序號;
  // 組出QRCode的url網址
  var url = "http://eepcloud.infolight.com:3000/cloud_andyeip_bootstrap/%E6%B4%BB%E5%8B%95%E5%A0%B1%E5%90%8D?checkin="+key;
  // 顯示報名成功
  var modal = $.alert('報名成功! 報名序號:'+key, 'info', { 
        small: true,
        content: '<div class="qr" style="width:200px;height:200px;background:red;margin:0 auto" />'
    });
  modal.find('.qr').qrcode({ width: 200,height:200,text: url }); //將URL傳入QRCode的Class
}

Drilldown設定的欄位條件通常都是"AND"的條件,如何透過onClick改成"OR"條件?
透過onClick來處理, 如下:
function Drilldown1_onClick(row, whereItems)
{
    whereItems.forEach(function(wi){
        wi.or = true;
    });
    return true;
}

ClientMove的ColumnMatch中, 如何用JS自定SourceField內抓取內容?
可以改用SourceValue的方式, 設定Function為要調用的JS方法, 如下:
function getBeginDate(sourceRow)  //sourceRow會自動傳入
{
    var onBoardDate = sourceRow.到職日期;  //取到職日期
    var beginDate = addDays(new Date(onBoardDate),183);  //加上 半年
    return beginDate;
}

ClientMove整批新增時, 欄位的對應關係(ColumnMatch), 是否可以有條件控制目的欄位的內容?
可以的, 在ColumnMatch中, 可以設定SourceValue(原來的SourceField會優先, 所以要先清空), 設定SourrceValue的Type為Function, 然後設定Function對應到JS程式即可, 如下在ColumnMatch的"金額"欄位, 設定一個 getAmt()的JS:
function getAmt(row)
{
    var amt = row.金額;
    if (row.稅別=="未稅") {
        amt = row.金額*1.05;
    }
    return amt;
}

EEPCloud的用戶表USERS如何自行新增或與從別的Table中整合進來?
EEPCloud的帳號是放在USERS表中, 可以用一般的SQL來新增資料, 只有PWD這個欄位為一個加密的欄位, 所以必須使用EEPCloud的後端方法來加密, 達到新增帳號的效果, 如下的Server Method為自行新增User的方法:
exports.addUser = function(param,callback){
    var dm=this;
    var sql="INSERT INTO [USERS] (USERID,USERNAME,PWD,EMAIL,CREATEDATE) VALUES ";
    this.encryptPassword(param.userid, param.password, function(err, newPassword){  // 此為非同步調用
sql=sql+"('"+param.userid+"',N'"+param.username+"',N'"+newPassword+"',N'"+param.email+"',N'"+param.date+"')";
        dm.query(dm.clientInfo, dm.clientInfo.database,[sql],{}, function(err){
            callback(err);
        });
    });
}

如何動態改變行事曆TitleField的顏色(當MonthTitle=True時)?
舉例:將TitleField改成紅色的字,如下:
先從工具箱拉出一個Literal,並於html中寫下CSS:
<style>
.event-Red > a{
color: Red !important;
}
</style>

再來,在Schedule的OnRenderItem雙擊添加一個事件,
並寫入內容如下:

function Schedule1_onRenderItem(event)
{
  if(event.row.客戶編號 =='001')
event.class = 'event-info event-Red';
}

如何動態控制主畫面的選單項目中字的顏色?
可以在EEPCloud的”網頁”的”主頁程式碼(JS)”中來設定,例如,當選項的標題包含"流程"時,將文字改為紅色,如下:
var initMenu = true;
$(function() {
setInterval(function() {
  if (initMenu) {
   var menuItems = $('#menu').find('.list-group-item');
   if (menuItems.length) {
initMenu = false;
menuItems.each(function() {
     var text = $(this).html();
     if (text.indexOf('流程') > 0) { //判斷是否包含此文字流程
      $(this).css('color', 'red'); //設置顏色
     }
    });
   }
  }
 }, 100);
});

從Menu打開的表單,如何用JS程式來關閉?
可以用以下的程式關閉:
self.parent.closeCurrentTab();

為何使用EEPCloud的免登入網頁,用QRCode或網頁上打開是可以的? 但使用一般的網頁用href連結時會失效(導入登入頁面)?
這是因為href="https://your.com/..." 這個連結傳入EEPCloud會遺失原來 https://your.com 等這個網址內容, 所以必須改用window.open() 的方式來打開這個免入網頁, 如下的案例:

1. 將href="https://icoder.infolight.com/cloud_andyeip_bootstrap/活動報名?activity=A1910001" 改成
onclick="open_window('https://icoder.infolight.com/cloud_andyeip_bootstrap/活動報名?activity=A1910001')" 

2. 在你的網頁上增加一個js方法, 這樣即可做到免登入的打開網頁, 如下:
function open_window(full_link){
window.open('javascript:window.name;', '<script>location.replace("'+full_link+'")<\/script>');
 }
如果頁面呈現的比較複雜,導致在手機上執行時畫面呈現重疊錯亂的現象,該如何處理?
可以在原始碼最上方寫下以下的code,即可處理此問題。
$.fn.disableIOSWrapper = true;
如何讓頁面使用免登入的功能?
1.首先,切換到雲設計的畫面,確讓好畫面左上角的資料庫及方案是正確的(因為免登入設定時會自動記錄下當前的資料庫及方案)。
2.將Server端中會用到該登入頁面的InfoComand的NonLogon屬性設為True並存檔。
3.然後將要使用免登入的RWD頁面,在設計畫面的空白處點選右鍵->免登入URL->把網址複製下來使用並按下存檔即可。

為何發行免登入的RWD頁面後,打開畫面會出現”Timeout”的錯誤訊息? 這是因為該畫面server端主檔的infocommand的nonlogon屬性沒有設為true,設定後將Server端重新存檔一次即可。
如何針對某個頁籤添加onClick事件?
舉例如下:
可以透過Runtime頁面的查詢元件以右鍵的'檢查'來得知頁籤的href, 再透過如下的JS來添加該頁籤的onclick事件:
$('[href="#tabMaster_0"]').on('click', function () {
        alert('1');
    });

如何用js指定開啟某一個頁籤?
舉例如下:
可以透過Runtime頁面的查詢元件以右鍵的'檢查'來得知頁籤的href, 再透過如下的JS來開啟該頁籤:
$('[href="#tabMaster_1"]').tab('show');

如何使用別的網站程式對 EEPCloud或iCoder網站進行SSO一次性登入?
EEPCloud有提供Single-SignOn的機制,因為SSO都是兩個不同的獨立網站且前端JS的安全性有問題,所以SSO的機制都是必須寫在後端的,你可以用PHP、Node.JS、ASP.NET C#或其他語言來寫SSO的機制,以下為Node.JS的一個實例,請參考:
 
function iCoderSSO(url,callback)
{
    var http = require('http');  
    var post_data =''; //定義 EEPCloud的 SSO 變數 (JSON格式)
    post_data = JSON.stringify({
        "deisnger": "andyeip", //EEPCloud設計者ID
        "user":"001",   //用戶ID
        "database": "ERPS",   //資料庫
        "solution": "Solution1", //解決方案
        "password": "123",  //密碼
        "url": url    //EEPCloud的轉向位址, "main"是主頁, 如子頁面可以用 "bootstrap/客戶資料表"
    });
    // 以下定義 EEPCloud的 SSO 網站地址
    var post_options = {
        host: '60.248.34.75',
        port: 3000,
        path: '/sso',
        method: 'POST',
        headers: {
            'Content-Type': 'text/html;charset=utf-8',
            'Content-Length': post_data.length
        }
    };
    // 開始向 EEPCloud SSO 請求
    var post_req = http.request(post_options, function(post_res) {
        var _data = '';
        post_res.on('data', function(chunk) {
            _data += chunk;
        });
        post_res.on('end', function() {
           var key = _data;
          //取得 SSO 金鑰
           var sso_url = 'http://60.248.34.75:3000?p=' + encodeURIComponent(key);
          // 傳回前端可以打開 post_data.url 所指定的網頁
           callback(null,sso_url);             
        });
    });
    // 向 EEPCloud 傳送 post_data
    post_req.write(post_data);
    post_req.end();  // 傳送結束 開始讀取回應
}

如果想透過ToolItem的importexcel方法匯入資料,且該Table的Key欄位是Identity,該如何處理資料? Identity欄位及資料不用出現在excel的資料裡,只需要按格式整理其他欄位及資料即可。
請問統計圖組件如何動態給條件, 即時更新?
如果你是與DataGrid綁定的話, 可以設定 統計圖的 QueryObj屬性即可, QueryObj的名稱為 DataGrid名稱+"queryObj", 如: "dgMasterqueryObj";如果你是想自行以Where條件來控制統計圖, 如下為Line Chart的控制方法:
 $('#LineChart1').linechart('setWhere',"日期>='2020-01-01'")

點選統計圖中的資料, 是否可以打開視窗來顯示明細資料?
可以的, 透過 onClick()方式來處理, 如下為LineChart取出Click的統計值與X軸的KEY內容, 即可往下開啟表單或做Where條件控制:
function LineChart1_onClick(ev, si, pi, data)
{  // ev:對象, si:數組index(從0開始), pi:數據點index(從0開始), data:陣列(數值內容在[1])
    var Xtext = ev.target.textContent;  //取得X軸整個標題
    var myXdata = Xtext.split('Z');  //分隔X軸標題
    var value = data[1]; // 取出統計值
    $.alert(myXdata[pi],'info');  //取得X軸Key內容
}

如何透過CSS改變看板管理-選單列類型的選單顏色?
在網頁->共用樣式表編寫CSS
舉例如下:
.info-card .bootstrap-menulist li{
   background: #99BBFF;
}

如何call API?

舉例如下:
前端:
function void_invoice(){
    var sIndex = $("#dgMaster").datagrid("getSelectedIndex");
    if (sIndex >= 0) {
        var status =  $("#dgMaster").datagrid("getRows")[sIndex].狀態;
        var ivono = $("#dgMaster").datagrid("getRows")[sIndex].發票號碼;  
        var cdate = $("#dgMaster").datagrid("getRows")[sIndex].發票日期;
        cdate = cdate.replace(new RegExp("-", "g"), "").substring(0,8);

        if(status!="開立"){
            $.alert('無法呈送','danger');           
        }else{
            $.callMethod('發票資料','void_invoice',{type:1,ivono:ivono,InvoiceDate:cdate},function(result){
                $.alert(result,'info');
                var page = $('#dgMaster').datagrid('options').page;
$('#dgMaster').datagrid('load', { page: page});  
            }); 
        }
  ;   }else {
        $.alert('請選擇一筆發票','info');
    } 
}

後端:
//作廢發票
exports.void_invoice = function (param, callback) {
    var datamodule = this;
    var https = datamodule.getModule('https');
    var querystring = datamodule.getModule('querystring');
    var Buffer = datamodule.getModule('buffer').Buffer;
    var clientInfo = this.clientInfo;
    var ivono = param.ivono;
    //發票日期
    var InvoiceDate = param.InvoiceDate;
    var csv = '"InvoiceNumber","InvoiceDate"\n"' + ivono + '","' + InvoiceDate + '"\n"Finish"';
    datamodule.echo("csv:" + csv);
    var post_data = querystring.stringify({
        'id': 'XXXXXXXXX',
        'user': ' XXXXXXXXX',
       'passwd': ' XXXXXXXXX',
        'csv': Buffer.from(csv).toString('base64')
    });
    datamodule.echo("post_data:" + post_data);
    const options = {
        hostname: 'api-test.cxn.com.tw',
       port: 443,
        path: '/c0501.php',
        method: 'POST',
       headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length':Buffer.byteLength(post_data)
        }
   }
    const req = https.request(options, (res) => {
        console.log(`statusCode: ${res.statusCode}`)
       res.on('data', (d) => {
           var errmsg = "";
            var result = Buffer.from(d, 'base64').toString().split("&");
            if (result[0] == "rtcode=0000") {
               //成功取號後,寫入發票號碼
                var sql = "update 發票資料 set 狀態 ='作廢' where 流水編號 ='" + ivono + "'"; //SQL條件句
                this.query(clientInfo,clientInfo.database, [sql], {
                   check: true
               }, function (err, result) {
                    if (err.message == 'no row effect.') {
                       callback(new Error('請再執行一次')); //修改顯示的 錯誤訊息
                   } else if (err) {
                       callback(err);
                   } else {
                       callback(null, "**完成取號**");//這句不會執行
                   }
                });
               callback(null, "完成");
           } else {
                errmsg = Buffer.from(result[1].split("=")[1], 'base64').toString();
                callback(null,"錯誤訊息A: " + errmsg + "(" + result[0] + ")");
           }
        })
   })
    req.on('error', (error) => {
        callback(null, "錯誤訊息B: " + errmsg);
    })
    req.write(post_data)
    req.end()
};

行事曆中, 如何控制不同類型不同顏色?
透過 onRenderItem事件來處理, 如下:
function scMaster_onRenderItem(event)
{
    var style='event-info';
    switch (event.row.行事曆類型) 
    {
        case '活動': style='event-important'; break;
        case '會議': style='event-special'; break;
        case '資源預約': style='event-warning'; break;
        case '公出': style='event-success'; break;
        case '其他': style='event-inverse';
    }    
    event.class = style;
}

Chart元件如何以StoreProcedure傳參數的方式產生圖表?
有兩個方法。
第一個方法:
前端透過CallServerMethod方式去後端Call SP,然後再回傳資料給前端,
前端再將後端傳回的結果轉成json,
最後透過loadData的方式將資料呈現在Chart上面,  
舉例如下:  
 
前端JS:  
function callSP()   
{     
    $.prompt( "輸入日期(格式:YYYY-MM-DD)?", new Date().Format("yyyy-MM-dd"), function(yymmdd) {   
        $.callMethod('出貨單','callSP',{date:yymmdd},function(result){   
            var param = $.parseJSON(result); //傳回result為JSON格式  
            if (param.length != 0){  
                $('#LineChart1').linechart('loadData', param);  
                //$('#PieChart1').piechart('loadData', param);  
                //$('#BarChart1').barchart('loadData', param);  
            }  
        });  
    });  
}  
 
後端JS:  
 
exports.callSP = function(param,callback)   
{  
    var date = param.date; // 取出編號  
    var clientInfo = this.clientInfo;  
    var sql = "exec 出貨單SP '"+date+"'";  
    var dm = this;  
    dm.queryRaw(clientInfo, clientInfo.database, sql, {}, callback);  
};  
第二個方法:  
 
先將DataGrid的RemoteName來源infocommand改為使用SP  
並且也讓Chart的RemoteName來源也設定為該infocommand  
 
DataGrid使用SP的方法參考如下:  
* InfoCommand的CommandType如果為StoredProcedure時,前端的DataGrid查詢條件送回後端時會自動與StoredProcedure配合。如果在InfoCommand的Parameters中所設定的參數與前端DataGrid欄位名稱一致時,前端送過來的查詢條件會自動寫入Parameters的Value中,這樣就可以透過StoredProcedure的Input變數進行資料查詢與回傳結果。如下:  
1.  設計一個SP,透過MSSQL或是EEPCloud來新增一個SP,並定義好input參數。  
2.  原來前端的DataGrid需事先連上一個虛擬或實體的Table,結構與SP要傳會的資料一致。在Server端除了原來的InfoCommand對應到這個虛擬或實體的Table外,還要另外貼一個SP的InfoCommand(CommandType為StoredProcedure),CommandText輸入SP的名稱,並填好與SP對應的Parameters參數。  
3.  前端的DataGrid.RemoteName改成這個SP的InfoCommand即可,這樣User輸入查詢條件就會送往SP這個InfoCommand,InfoCommand因為為SP的Type,所以會自動用欄位對應Parameters參數。
Word套表時,可否支援三階的印表?
如下的報表格式,有主表(A),與明細表(B),及第三階明細表(C):
 
Word表單設計時,可以將B設為##,將C設為##2,再以二次開發的方式控制##2(C表)為B的第三階明細;印表時可以另外再設計一個Word表格,##明細表的欄位可以完全由##2來取代(當然##2必須包含##所要印出的欄位),如下:
 
並在印表前先執行後端程序把C的第二筆之後重複的資料清空,如下JS:
function exportWord2()
{
   var sIndex = $("#dgMaster").datagrid("getSelectedIndex");
   if (sIndex >= 0) {
       var no = $("#dgMaster").datagrid("getRows")[sIndex].生產編號;
       $.callSyncMethod('生產實施方案','prepare',{no:no}); //清除重複的群組資料
       $(this).datagrid('exportWord','生產實施方案印表');  // 更換格式為"生產實施方案印表.doc"
   }
}

如何透過js打開別的表單?
舉例:
//在瀏覽器開啟一個新網頁(RWD表單)
window.open('員工資料表');//RWD表單名稱
 
//在瀏覽器開啟一個新的頁籤(RWD表單)
window.top.addTab('員工資料表','員工資料表', 'bootstrap/員工資料表');
// 參數分別代表RWD的: 表單ID,表單標題,表單位置。
用戶Login之後,  是否可以指定打開某個網頁?
可以透過 後台 '網頁'/'主頁原始碼(JS)'中, 來設定以下的JS即可:
$(function(){
    window.location.replace('bootstrap/你的表單');   //跳轉到你的RWD表單   
})
但如果要打開在主頁之下, 則改用以下的JS:
$(function(){
    window.top.addTab('你的表單ID','你的表單標題','bootstrap/你的表單');   //打開你的RWD表單
});
為何有時Default元件為何無效?
有可能是將Default元件放置到其他DataForm或DataPanel的元件裡面了,
移出到最外層即可。
如何透過servermethod自動產生流程起單?
舉例如下:
前端JS:
function callflow(){ 
    var rows = $('#dgMaster').datagrid('getRows'); 
    var index = $('#dgMaster').datagrid('getSelectedIndex');
    var row = rows[index];
    $.callMethod('出貨單','callflow',{no:row.出貨編號},function(result){
        alert('執行成功!');
    });

後端JS:
//* 後端提供了submitFlow方法來自動產生流程實例,如下:
//(如果工作流活動中有用到條件運算式的欄位時,該欄位內容必須放資料對象中)
//也就是說流程中會用到的欄位都要放置到資料對象裡面
exports.callflow = function(param, callback) {
    this.submitFlow({            //資料對象, 放KEY欄位即可
        出貨編號: param.no,
    }, {
        url: 'http://localhost:3000',      //email ?接
        FlowID: '出貨申請',               //流程名稱
        Remark: '自動起單',               //起單訊息
        WEBFORM_NAME: '出貨單',           //表單名稱
        FORM_KEYS: '出貨編號',            //表單主鍵
        FORM_PRESENTATION:"出貨編號='"+param.no+"'", //表單主鍵內容
        FORM_PRESENTATION_CT: '出貨編號:'+param.no, //表單欄位呈現
        PROVIDER_NAME: '出貨單.出貨單',   //RemoteName名稱
        tabTitle: '出貨單',                     //頁籤名稱
    }, callback);
};

如何改變私有雲或執行雲網址的port?
如果希望改變網址的port,可以改變run.bat 或 start.bat裡的內容,如下:
改變預設的3000port為3001port
 
內容:
@echo off
pushd "%~dp0"
start redis/3.2.100/redis-server.exe redis/3.2.100/redis.windows.conf
start cmd /k " set PORT=3001&&node bin/www_cluster"
start cmd /k node bin/schedule 
start http://localhost:3001/design
如果重新開機後,run.bat或start.bat開啟後私有雲或執行雲無法正常使用(重新啟動前是正常的),該如何處理?
因為當前windows登入者為非管理者,因此可以如下處理,
在run.bat 或 start.bat添加一行,如下:
pushd "%~dp0"
這句的目的是更改當前目錄為批處理本身的目錄
 
舉例:
@echo off
pushd "%~dp0"
start redis/3.2.100/redis-server.exe redis/3.2.100/redis.windows.conf
start cmd /k " set PUBLISH=true&&node bin/www_cluster"
start http://localhost:3000/?designer=test&database=ERPS&solution=SOLUTION1
在 Flow 預備模式中,為何已呈送的資料可以修改內容,內容改變後呈送卻會被系統擋住,告知流程已存在?
當資料尚未呈送或已結案,才可以進行修改或作廢並且重新起單。可以在datagrid的OnUpdate事件,添加程式碼判斷此流程目前的狀態
參考範例如下:
function dgMaster_onUpdate(row)
{
        var flowflag = row.FlowFlag.substring(0,1);
    if (!flowflag || flowflag == 'Z' || flowflag == ‘z’){ 
    //空白表示尚未起單,等於Z或z表示已結案
        return true;}
    else{
        alert('此流程已存在');
        return false;
    }
}
FLOWFLAG狀態代表意思如下:
'N':新流程建立.
'P':流程過程中.
'Z':流程結案.
'X':流程作廢. 
'B' 流程暫停 
用戶打開主畫面時, 如何讓Menu自動隱藏?
可以在EEPCloud的 "網頁"/"主頁程式碼JS"中設定以下程式即可:
$(function() {
    $('#menu').toggleClass('min');
    $('#tab').toggleClass('max');
    $('#favoricon').toggleClass('hide');
});

當日期欄位類型為varchar8,如何取得當日前七天日期?
function time(){
    var today = $.getVariableValue('today'); //取得系統今日日期
    var addDate = addDays(today,-20);        //取得前二十天
    var date = addDate.substr(0,10);         //取出年月日
    date = new Date(date).Format('yyyyMMdd');    //轉為varchar8
    return date;
}
使用後端Infocommand的RuntimeDatabase來設定保密的資料庫時, 前端頁面如何控制資料庫密碼的輸入?
密碼輸入可以使用 PromptDialog組件來設計, 設定一個欄位即可, Editor設定為password:
     這個表單加入以下JS:
$(function(){   // 打開表單就執行
   if (! $.getVariableValue('setPwd'))  // 沒設過Pwd的話
    {
        $('#PromptDialog1').promptdialog('show', function(row){     // 開啟輸入窗口
            $.setVariableValue('databasePwd',row.人資資料庫密碼);
            $.callMethod('員工資料表','checkPwd',{pwd:row.人資資料庫密碼},function(result){ // 執行後端檢查方法
                var param = $.parseJSON(result); //傳回result為JSON格式
                if (param.length != 0) 
                { $.alert('密碼正確','info');
                 $.setVariableValue('setPwd',"Yes",true);  // 避免重設  
                 $('#dgMaster').datagrid('options').remoteName = '員工資料表.員工資料表';  // 可以打開保密資料庫的資料表了
                 $('#dgMaster').datagrid('load'); 
                }
                else  $.alert('密碼正確','info');
            });
        });  
    }
})
function dgMaster_onBeforeLoad(param)
{
  if (! $.getVariableValue('setPwd')) //尚未輸入過密碼時
    {
        $('#dgMaster').datagrid('options').remoteName = '';  // 避免DataGrid下載資料
        $.loaded($(this).closest('div'));  // 關閉 "下載中…" 訊息
    }
}
Server端的保密資料庫的密碼檢查程式, 可以這樣寫:
exports.checkPwd = function(param,callback){
    var pwd = param.pwd;  // 取得密碼
    var clientInfo = this.clientInfo;
    clientInfo.database='HR'; // 要保密的資料庫
    var sql="select * from 員工資料表 "; // 保密資料庫任一個資料表皆可
    this.queryRaw(clientInfo, clientInfo.database, sql, {databasePwd:pwd}, callback);    
    // 如果密碼正確將傳回資料內容
};

流程呈送時可以設定傳遞的參數嗎? 可以在選單中的參數裡進行設定,參考如下:
當HTML頁面要超連結到免登入網址頁面,該如何處理?
不可以使用<a>標籤 因為免登入網址需要轉址 因此可以改用下列的方式:
 
onclick="open_new_window
  ("https://icoder.infolight.com/cloud_andyhome_bootstrap/WEBHOME";)"
 
onclick時另外呼叫open_new_window這個方法開啟網頁:
function open_new_window(full_link){ 
  window.open('javascript:window.name;', '<script>location.replace("'+full_link+'")<\/script>');
 }

其他問題

當前位置:首頁>常見問答>EEPCloud