---
tags: 國興實習
---
# 普通下拉 + 下拉連動 + 下拉刷新 + 多選下拉 + 相關應用
**前端html**
* 設定ng-options
```htmlmixed=
<select name="txtID_S" class="form-control" ng-model="searchData.ID" ng-options="m.DESC as m.DESC for m in opData.ID|filter:{GROUP:searchData.ID}"">
<option value=""></option>
</select>
```
**後端(放在Init()在初始頁面即執行)**
* addOpData(“前端下拉ng-options的opData對應到的參數”,“SQL語法”) ==**[KEY]主鍵、[DESC]排序、[GROUP]分組(連動時使用)**==
```C#
this.addOpData("ID", "select M.APRJNEO_ID_NEO as [KEY] , M.APRJNEO_ID_NEO as [DESC] from FNAPRJNEO M where 1=1 group by APRJNEO_ID_NEO");
```
## 下拉連動-GROUP
#### 後端
* 上group by,下[GROUP]
```C#=
void l_Master_Initialing(object sender, EventArgs e)
{
//加入來自DEMOMI ID的下拉,命名為MEB_ID
addOpData("MEB_ID", " select D.ID as [KEY] , D.ID as [DESC] from TEXT D where 1=1 group by ID");
//連動下拉式清單
addOpData("NAME_ID", " select D.NAME as [KEY] , D.NAME as [DESC], D.ID as [GROUP] from TEXT D where 1=1 order by D.ID ");
}
```
#### html
* 設定ng-options
* 連動的下拉ng-options要帶filter ==**|filter:{GROUP:searchData.要連動的參數}**==
```htmlmixed=
<div class="form-group">
<label for="txtID_S" class="col-xs-4 control-label">編號</label>
<div class="col-xs-4">
<select name="txtID_S" class="form-control" ng-model="searchData.ID" ng-options="m.DESC as m.DESC for m in opData.MEB_ID">
<option value=""></option>
</select>
</div>
</div>
<div class="form-group">
<label for="txtNAME_S" class="col-xs-4 control-label">名稱</label>
<div class="col-xs-4">
<select name="txtNAME_S" class="form-control" ng-model="searchData.NAME" ng-options="m.DESC as m.DESC for m in opData.NAME_ID|filter:{GROUP:searchData.ID}">
<option value=""></option>
</select>
</div>
</div>
```
:::info
* ==⚠️**注意GROUP**==
* **一般來說下拉會另外寫方法才在init()中呼叫(==l_Master_Initialing==)**
:::
較好看的下拉
```htmlmixed=
<ui-select name="stxtTYPE_DEPT" ng-model="searchData.TYPE_DEPT" theme="bootstrap" title="請選擇一項" ng-required="isRequired('TYPE_DEPT')">
<ui-select-match placeholder="--請選擇--" allow-clear="true">{{$select.selected.DESC}}</ui-select-match>
<ui-select-choices repeat="m.KEY as m in opData.QL_TYPE_DEPT | propsFilter: {KEY: $select.search, DESC: $select.search}">
<div ng-bind-html="m.DESC | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
```
```htmlmixed=
allow-clear="true" //是否可清空下拉所選值
```
:::info
**⚠️清空值為null,如果是被連動的下拉選單會出問題,記得設定`nvl(a_arg.oldRow['欄位名'], '');`將null情況轉為空字串**
**⚠️三個以上的下拉如果`allow-clear="true"`要記得倒數第二以前的下拉選單要把自己之後的下拉刷新**
:::
## 下拉連動-QuOther()
#### 後端
```C#=
[System.Web.Http.HttpPost]
public IHttpActionResult QuOther(DeltaQuOther a_delta)
{
string l_name = a_delta.name;
l_name = a_delta.name.ToUpper();
if (l_name == "SELECTDEPT") //ToUpper()
{
string DEPT_NO = a_delta.oldRow["CUST_DEPT"].ToString();
if( DEPT_NO == "")
{
this.addOpData("QL_CUST_NO", "select '' as [KEY], '--請選擇--' as [DESC] union select CUST_NO as [KEY], CUST_NO as [DESC] from QA_CUST");
}
else
{
this.addOpData("QL_CUST_NO", "select '' as [KEY], '--請選擇--' as [DESC] union select CUST_NO as [KEY], CUST_NO as [DESC] from QA_CUST where CUST_DEPT = '" + DEPT_NO + "'");
}
}
//回傳DataSet
return doQuOther();
}
```
#### js
```javascript=
$scope.selectDEPT = function () {
var l_delta = newDeltaQuOther(); //自定義方法
l_delta.oldRow.CUST_DEPT = $scope.searchData.CUST_DEPT;
l_delta.name = "selectDEPT"
$scope.doQuOther(l_delta).then(function (a_result) {
$scope.opData.QL_CUST_NO = a_result.QL_CUST_NO; //下拉也要記得接回前端
$scope.searchData.CUST_NO = "";
})
}
```
:::info
* **前端要接回後端之下拉**
* **⚠️若新增時連動更改下拉造成後續編輯時下拉顯示不正常,使用edited事件觸發QuOther()再刷新一次(自創)**
:::
## 下拉刷新-RefreshOpData()
#### 後端
```C#=
[System.Web.Http.HttpPost]
public IHttpActionResult RefreshOpData(string[] a_opNames)
{
foreach (var l_opName in a_opNames)
{
if (l_opName == "QL_CUST_NO")
{
this.addOpData("QL_CUST_NO", "select '' as [KEY], '--請選擇--' as [DESC] union select CUST_NO as [KEY], CUST_NO + '---' + RTRIM(ISNULL(CUST_NM,'未命名')) as [DESC] from QA_CUST");
}
if (l_opName == "QL_ID")
{
this.addOpData("QL_ID", "select '' as [KEY], '--請選擇--' as [DESC] union select ID as [KEY], ID + '---' + RTRIM(ISNULL(NAME,'未命名')) as [DESC] from QA_CUST_UNIT");
}
}
return this.doRefreshOpData();
}
```
## 下拉刷新-自訂方法
```javascript=
$scope.WahNoEditRefresh = function () {
$http({
method: 'POST',
url: '/api/apiQTEST/WahNoEditRefresh',
data: { SEX: $scope.searchData.SEX }
}).then(function (response) {
$scope.opData.CITY = response.data.CITY;
});
}
```
#### js
```javascript=
$scope.doRefreshOpData(["QL_CUST_NO"]); //通常放在存檔後
```
:::info
* **a_opNames為陣列型態,因此可一次刷新多個下拉選單**
:::
## 多選下拉
```htmlmixed=
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4">
<ui-select multiple name="stxtSEX" ng-model="editRow.SEX" theme="bootstrap" title="請選擇一項" ng-required="isRequired('SEX')">
<ui-select-match placeholder="選擇..." allow-clear="true">{{$item.DESC}}</ui-select-match>
<ui-select-choices repeat="m.KEY as m in opData.SEX | propsFilter: {KEY: $select.search, DESC: $select.search}">
<div ng-bind-html="m.DESC | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
```
#### 存檔時處理
```javascript=
var Errmsg = "";
//將資料整理成String,並用','隔開
if ($scope.editRow.SEX != null) {
$scope.Save_DEPT = $scope.editRow.SEX;//將資料先儲存至另一個變數
var DEPT = "";
for (var i = 0; i < $scope.editRow.SEX.length; i++) {
DEPT += $scope.editRow.SEX[i] + ',';
}
$scope.editRow.SEX = DEPT;
}
if (Errmsg != "") {
$scope.searchData.DEPT = ($scope.Save_DEPT == "") ? null : $scope.Save_DEPT;//將資料回復成陣列
a_arg.message = Errmsg;
a_arg.cancel = true;
}
```
:::info
* **差異在多選下拉會把{{$item.DESC}}的值放入select上顯示**
* **多選的值會變成陣列,要對資料進行處理**
:::
### 多選子視窗回傳值至多選下拉(一樣自己硬A)
```javascript=
//--QuModal查詢子視窗回傳資料事件 quModalCallbacked ----------------------------------------
$scope.$on("quModalCallbacked", function (e, a_arg) {
if ((a_arg.sender == "ESIGNP0140Q".toUpperCase()) && (a_arg.dst == "btnQ".toUpperCase())) { //找到回傳資料的子視窗
if ($scope.searchData.PASS_NO != null) { //代表原先的多選下拉有值
for (var i = 0; i < a_arg.rows.length; i++) {
var index = 0; //用來判斷資料是否重複之指標
for (var j = 0; j < $scope.searchData.PASS_NO.length; j++) {
if ($scope.searchData.PASS_NO[j] == a_arg.rows[i].PASS_NO) { //確認是否重複
index++;
break;
}
}
if (index == 0) { //=0代表此筆資料不為重複值,直接上傳資料
$scope.searchData.PASS_NO.push(a_arg.rows[i].PASS_NO);
}
}
}
else { //資料從0開始
$scope.searchData.PASS_NO = new Array(a_arg.rows.length); //宣告陣列以免丟資料時出錯
for (var i = 0; i < a_arg.rows.length; i++) {
$scope.searchData.PASS_NO[i] = a_arg.rows[i].PASS_NO; //依序放入資料
}
}
}
})
```
:::info
* **有特殊需要可以自己在最後加上排序法再將資料丟回searchData中**
:::