---
tags: 國興實習
---
# 前端 View(基本)
:::info
**⚠️排版時注意明細的div也要放上bootstrap,否則可能被空白div擋住輸入框**
**⚠️ng-model不可跟ng-checked同時使用,會有例外情形發生(官網證實)**
:::
### HTML
#### 欄位限制
```htmlmixed=
max-length=”10” //字串最大長度限制
only-p-integer //只能輸入正整數
only-integer //只能輸入正負整數
only-number //只能輸入數值至小數點後兩位
only-integer-str //只能輸入數字字串
only-date //只能輸入西元年月日
only-date-tw //只能輸入民國年月日
only-date-time //只能輸入日期時間
onclick="return false" //Checkbox禁止點擊
class="datepicker" //日期下拉
```
:::info
**⚠️datepicker跟著該input之id走,注意不要跟別的元件一起設到一樣的ID**
**EX:**
<input name="txtCHK_DAY" id="txtCHK_DAY" type="text" class="form-control" ng-model="editRow.CHK_DAY" ==maxlength="3"== ==only-p-integer==>
:::
#### ng模組
ksijs-angular
```htmlmixed=
ng-class="isRequiredClass('欄位名')" //必填欄位的Label
ng-class="{'class名稱': 條件式}"//條件式成立就使用對應的class
ng-class="{true: 'class名稱', false: 'class名稱'}[條件式]" //條件式成立與否決定樣式選用
ng-required="isRequired('欄位名')" //必填欄位
ng-show="條件" //預設隱藏欄位,條件成立才顯示
ng-disabled="條件" //預設開啟欄位,條件成立才唯讀
//只能新增不能修改條件設為 "isReadOnly('欄位名')"
//CONTROLLER getMaster()需要對應修改
ng-model="資料欄位" //input值放的地方
//模組上新增修改為 editRow.欄位名【對應資料庫欄位名稱】
//查詢為searchData.欄位名 【對應Controller searchClass變數名稱】
//欄位需要指定預設值時 ng-model=" || 預設值"
ng-confirm-click="內容" //
ng-change="函式名()" //當元件變換值時觸發SCRIPT函式
ng-click="函式名()" //當元件被點擊時觸發SCRIPT函式
ng-blur="函式名()" //當元件離開焦點時觸發SCRIPT函式
ng-focus="函式名()" //當元件進入焦點時觸發SCRIPT函式
```
:::info
⚠️**注意editRow一定要跟資料庫欄位名稱相同**
⚠️**注意div必須有form-group或input-group才吃的到css**
⚠️**ng-change觸發tab.click有時候會造成模組$apply衝突,使用ng-class可解決此問題**
Ex:ng-class="{'active': editRow.PASS_CODE == '2','': editRow.PASS_CODE == '0'}"
或ng-class="{true: 'active', false: ''}[editRow.PASS_CODE == '2']"
:::
#### bootstrap
```javascript=
sm - Small — 6吋以上的手機
md - Medium — iPad 直著看
lg - Large — iPad 橫著看 / iPad pro 直著看
xl - Extra large — 電腦螢幕
date-target //彈出窗ID
```
#### for/name
```htmlmixed=
<div class="form-group">
<label for="txtNAME" class="col-xs-1 control-label" ng-class="isRequireClass('NAME')">用戶名稱</label>
<div class="col-xs-2">
<input name="txtNAME" id="txtNAME" type="text" class="form-control" ng-model="editRow.NAME" ng-required="isRequired('NAME')" ng-change="changeData()" /> @*onblur="changeData()"*@
</div>
</div>
//for = label等文字標題說明使用
//name = for應該要對到的input
//使兩者可相互對應
```
#### 驚嘆號icon
```htmlmixed=
<i class="glyphicon glyphicon-warning-sign error-icon" ng-show="masterForm.txtNAME.$error.required" data-toggle="tooltip" data-placement="right" data-title="[用戶名稱]不可空白!"></i>
```
:::info
**複習前面:**
**利用ng-show來判斷此icon是否顯示(此處為判斷是否有輸入數值)**
:::
#### 折疊式視窗
```htmlmixed=
<div class="panel panel-default">
<div id="imgPanelH" class="panel-heading" data-toggle="collapse" data-target="#imgPanelB" aria-expanded="true">
圖檔管理
<i class="fa fa-angle-down fa-lg icon-open"></i>
<i class="fa fa-angle-up fa-lg icon-close"></i>
</div>
<div id="imgPanelB" class="panel-body collapse in" style="padding:15px;">
<div class="form-group fileupload-buttonbar">
<div class="col-xs-12 col-sm-6">
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>新增圖片</span>
<input type="file" name="files[]" multiple accept="image/*">
</span>
<button type="submit" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>全部上傳</span>
</button>
<button type="reset" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>全部取消</span>
</button>
<span class="fileupload-process"></span>
</div>
<!-- The global progress state -->
<div class="col-xs-offset-1 col-xs-10 col-sm-offset-0 col-sm-6 fileupload-progress fade">
<!-- The global progress bar -->
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-success" style="width:0%;"></div>
</div>
<!-- The extended global progress state -->
<div class="progress-extended"> </div>
</div>
</div>
<!-- The table listing the files available for upload/download -->
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
</div>
<div class="form-group">
<!-- The blueimp Gallery widget -->
<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls" data-filter=":even">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev">‹</a>
<a class="next">›</a>
<a class="close">×</a>
<a class="play-pause"></a>
<ol class="indicator"></ol>
</div>
</div>
</div>
```
:::info
* **此為預設開啟,若要預設關閉,更改`aria-expanded="false"`及`class="panel-body collapse in"`拿掉in** [【bootstrap摺疊效果】](https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/268288/)
:::
### javascript
#### Grid欄位顯示設定
```javascript
sortable: false, //關閉排序
visible: false, //欄位隱藏
```
ksijs.angular.js的內容
```javascript=
//--以下為panelMasterGrid init--------------------------------------------------------------------------
//定義明細Grid內容
$scope.panelMasterGrid = {
data: 'gridMasterData',
multiSelect: false,
enableColumnResize: true,
showSelectionCheckbox: false,
selectWithCheckboxOnly: false,
enablePinning: true,
pinSelectionCheckbox: true,
i18n: ksijsLocalized.public.language.toLowerCase(),
selectedItems: $scope.curRow,
enableCellSelection: true,
enableHighlighting: true,
sortInfo: $scope.sortInfo,
useExternalSorting: true,//server site sorting
//enableCellEdit:true,
columnDefs: []
};
```
可利用於各view,如需要顯示checkbox:
```javascript=
$scope.gridMaster.multiSelect = true;
$scope.gridMaster.showSelectionCheckbox = true;
$scope.gridMaster.columnDefs = [];
$scope.gridMaster.columnDefs.push({ field: "FORMNAME", displayName: '表單種類', width: '200px', pinnable: true, cellTemplate: getCellTemplate_mobile("表單種類") });
$scope.gridMaster.columnDefs.push({ field: 'ROUND_FORM_NO', displayName: '表單號碼', width: '100px', pinnable: true, cellTemplate: getCellTemplate_mobile("表單號碼") });
$scope.gridMaster.columnDefs.push({ field: 'SIGNUSERNO', displayName: '傳簽人員', width: '200px', pinnable: false, cellTemplate: getCellTemplate_mobile("傳簽人員") });
$scope.gridMaster.columnDefs.push({ field: "CAUSE_SUMMARY", displayName: '傳簽事由', pinnable: false, cellTemplate: getCellTemplate_mobile("傳簽事由") });
```
#### 顯示屬性
在ksijs-template中,以下列比較常用的:
```javascript=
cellTemplate: getCellTemplate_Date_lbl() //顯示日期
cellTemplate: getCellTemplate_DateTime_lbl() //顯示日期+時間
cellTemplate: getCellTemplate_Money_lbl(a_fractionSize) //金額格式
cellTemplate: getCellTemplate_href() //欄位連結
cellTemplate: getCellTemplate_DateTime_lbl_tw() //顯示民國/月/日
cellTemplate: getCellTemplate_GetRow() //下載按鈕(可自訂)
{{row.entity[col.field]}} = 該欄位的值;
{row.entity} = 對應的Row;
```
:::info
* **field的值與後端SQL相連結(getMaster查詢結果呈現)** ==**⚠️field必須為大寫**==
* **SearchData的值為後續l_Master_Searching()方法使用**
* **`‵@" Select M.* From FNAPRJNEO M Where 1=1 order by m.APRJNEO_ID_NEO "`為參數化SQL查詢指令**
* **notNullField與前端`ng-required="isRequired('ID')"`相關**;
* **noEditButInsertField與前端`ng-disabled="isReadOnly('ID')"`相關**
:::
#### Gird js事件【整理中,未完】
```javascript=
$scope.$on('cellChanged', function (e, a_arg) { //Grid Cell欄位值改變
var l_row = a_arg.oldRow; //取得row
//Grid Cell檢查資料
});
//--Grid Row判斷是否唯讀事件--------------------------------------
//--依Detail Row之資料內容,以鎖定某些欄位為唯讀
$scope.$on("isReadOnly_D", function (e, a_arg) {
//來自第1個GridDetail
if (a_arg.index == 0) {
}
})
```
#### 定義事件
```javascript=
//--初始後事件 inited----------------------------
$scope.$on('inited', function (e, a_arg) {
$scope.searchData.DEPT_NO = "";
$scope.searchData.CUST_NO = "";
$scope.searchData.ID = "";
//此為初始化時就為這些參數帶值
});
//--存檔前事件 posting----------------------------
$scope.$on('posting', function (e, a_arg) {
//if (isEmpty($scope.searchData.DPS_LEVEL)) { 確認是否為空
// swal("不可空白"); 相當於alert
// a_arg.cancel = true; 禁止前端存取 對應function的arg名稱
//}
if (a_arg.status == Enum.status.insert) {
// $window.alert('來自新增 ');
}
else if (a_arg.status == Enum.status.edit) {
// $window.alert('來自修改 ');
}
});
//--存檔後事件----------------------------------------
$scope.$on('posted', function (e, a_arg) {
if (a_arg.status == Enum.status.insert) {
// $window.alert('來自新增 ');
}
else if (a_arg.status == Enum.status.edit) {
// $window.alert('來自修改 ');
}
//doRefreshOpData用的地方
});
//--新增後事件 detailInserted-----------------------------------------
$scope.$on('inserted', function (e, a_arg) {
$scope.editRow.CUST_NO = "";
//新增時依需求給特定欄位預設值
});
//--編輯後事件 detailInserted-----------------------------------------
$scope.$on('edited', function (e, a_arg) { //以防新增連動更改下拉造成編輯時顯示不正常
var l_delta = newDeltaQuOther(); //自定義方法
l_delta.oldRow.CUST_NO = $scope.editRow.CUST_NO;
l_delta.name = "setCUST"
$scope.doQuOther(l_delta).then(function (a_result) {
$scope.opData.DL_ID = a_result.DL_ID; //下拉也要記得接回前端
})
});
```
:::info
* **依照需求狀況對應相關事件位置撰寫程式碼**
:::