2016年3月29日 星期二

表單驗證使用jquery.validate

設定錯誤訊息出現位置及樣式
label.error {
        color: red;
        position: absolute;
        background-color: white;
        padding: 0.25em;
        border: 1px solid #adff2f;
}
$('#form1').validate({
errorPlacement: function (error, element) {
            $(element).parent().append(error);
            $(error).css({ top: $(element).position().top, left: $(element).position().left + $(element).width()+10 })
          },
});

自訂錯誤訊息
<input name="id" minlength="4" data-msg-minlength="長度必須大於4">

自訂驗證規則
$.validator.addMethod("fixlength", function (value, element,param) {
             return !value || value.length == param;
        }, jQuery.validator.format("長度必須為{0}"));
 $("#form").validate();
<input data-rule-fixlength='4' type="text">

依據條件驗證
$('#form1').validate({
            rules: {
                Mailbox: {
                    required: '#sendmail:checked',
                    email: '#sendmail:checked'
                },
            }
        });
 <input type="checkbox" id="sendmail"  />Email:<input type="text" name="Mailbox" id="Mailbox" />

ag-grid 設定欄寬依內容自動調整,且設定最小寬度避免欄位名稱無法完整顯示

{ field: '廠商編號', headerName: '廠商編號', minWidth:80 },
$scope.gridOptions.api.setRowData(list);              
$scope.gridOptions.columnApi.autoSizeColumns(Enumerable.From($scope.gridOptions.columnApi.getAllColumns()).Select('$.colId').ToArray());

* 使用 autoSizeColumns() 前必須讓 grid 為顯示狀態

2016年3月17日 星期四

ui bootstrap modal size 設定方式,包含內容區域填滿可用空間

javascript
====
.directive('modalbody', function ($timeout) { // 填滿可用空間
    return {
        link: function (scope, elem, attrs) {
            var positioner = function () {
                $(elem).closest('.modal-content').css('height', $(window).height() - 60);
                $(elem).closest('.modal-dialog').css('width', $(window).width() - 60);
                var h = $(elem).closest('.modal-content')[0].offsetHeight - $(elem).closest('.modal-content').find('.modal-header')[0].offsetHeight- $(elem).closest('.modal-content').find('.modal-footer')[0].offsetHeight; 
                if (attrs.modalbody) h += parseFloat(attrs.modalbody);
                $(elem).outerHeight(h);
                $(elem).find('.modal-body-inner').height($(elem).height());
            }
            $(window).resize(function () {
                positioner();
            });
            $timeout(function () {
                positioner();
            });
        }
    };
})

.directive('modalbodymax', function ($timeout) { // 超過最大可用空間才限制
        return {
            link: function (scope, elem, attrs) {
                var positioner = function () {
                    $(elem).closest('.modal-content').css('maxHeight', $(window).height() - 60);
                    $(elem).closest('.modal-content').css('maxWidth', $(window).width() - 60);
                    var maxh = $(window).height() - 60 * 2 - $(elem).closest('.modal-content').find('.modal-header').height() - $(elem).closest('.modal-content').find('.modal-footer').height();
                    $(elem).css('maxHeight', maxh);
                }
                $(window).resize(function () {
                    positioner();
                });
                $timeout(function () {
                    positioner();
                });
            }
        };
    })

html
====
<script type="text/ng-template" id="voucher.html"> 
<div class="modal-header "> <button class="close" ng-click="close()"><span class='glyphicon glyphicon-remove' style="font-size:40px"></span></button> <h3 class="modal-title">傳票明細</h3> </div> 
<div class="modal-body" modalbody> <div ag-grid="gridOptions" class="ag-green modal-body-inner">
</div>
 </div> 
</script>

css
====
.modal-body-inner {
    overflow-y: auto;
}

2016年3月15日 星期二

angularjs 與中文如何搭配

{{object.銷售}}  <= 中文不ok
{{object["銷售"]}}  <= 中文ok
ng-show="object['中文']==true" <= 中文不ok
ng-show='object["中文"]==true' <= 中文ok

2016年3月12日 星期六

於 angularjs 中顯示圖片

<img style="width:100%" data-ng-src="data:image/png;base64,{{object['照片']}}">

若要更換圖片且圖片來源是透過 <input id="fileinput" class="form-control" type="file" fileread="$parent['上傳照片']" /> 取得,則必須去除前面自動產生的 "data:image/png;base64," 這種字串
$scope.object['照片']=$scope.上傳照片.split(',')[1];

2016年3月9日 星期三

可輸入時間的 input

input type="datetime-local"

json 轉換

c#
====
將 json 字串轉為物件
var list = JsonConvert.DeserializeObject<IEnumerable<Newtonsoft.Json.Linq.JObject>>(jsonlist);
foreach (var obj in list)
foreach (var p in obj.Properties())
obj.Value<int>(p.Name); //轉換為特定型態
obj.Value<dynamic>(p.Name); //不轉換型態


javascript
====
將物件轉為 json 字串 : JSON.stringify(jsonlist)
將 json 字串轉為物件 : JSON.parse(jsonstring)


範例 : 把前端物件陣列匯出成excel

c#
====
public string JsonExcel(string jsonlist, string 檔名)
        {
            var list = JsonConvert.DeserializeObject(jsonlist);
            using (var ep = new OfficeOpenXml.ExcelPackage())
            {
                int row = 1, col = 1;
                var ws = ep.Workbook.Worksheets.Add("工作表1");
                if (list.Count()>0)
                foreach (var p in list.FirstOrDefault().Properties())
                    ws.Cells[row, col++].Value = p.Name;
                foreach (var obj in list)
                {
                    row++;
                    col = 1;
                    foreach (var p in obj.Properties())
                    {
                        ws.Cells[row, col++].Value = obj.Value(p.Name).Value;
                        if (obj.Value(p.Name).Value is DateTime)
                            ws.Cells[row, col-1].Style.Numberformat.Format = "yyyy/MM/dd";
                    }
                }
                var fi = new System.IO.FileInfo(Server.MapPath("~") + "\\download\\{0}.xlsx".FormatString(檔名));
                ep.SaveAs(fi);
                string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority + Request.ApplicationPath.TrimEnd('/') + "/";
                return baseUrl + "download/{0}.xlsx".FormatString(檔名);
            }
        }

javascript
====
 $http.post('@Url.Action("JsonExcel")', { jsonlist: JSON.stringify($scope.gridOptions.rowData), 檔名: "總分類帳明細" })
                 .then(function (result) {
                     window.location = result.data;
                 });

2016年3月8日 星期二

javascript 依照中文筆劃排序

array.sort(function(a,b){return a.localeCompare(b, "zh-Hant")})


切換排序方向並顯示箭頭
<div @click="排序('text');arrs=arrs.sort((a, b) => (a.text || '').localeCompare((b.text || ''), 'zh-Hant')*排序值)">
    {{ arr.text }}
    <div style="float:right" v-if="排序欄位=='text'"><span v-if="排序值==1">▲</span><span v-if="排序值==-1">▼</span></div>
</div>
const 排序 = (value) => {
    const 切換欄位 = 排序欄位.value != value;
    排序欄位.value = value;
    if (!切換欄位) 排序值.value = 排序值.value == -1 ? 1 : -1;
}


多欄位排序
arrs.sort((a, b) => (a.text.localeCompare(b.text, 'zh-Hant')*10+(a.text2 || '').localeCompare((b.text2 || ''), 'zh-Hant'))*排序值)

input 連結 datalist 用程式控制彈出選項

範例: nextTick(() => document.querySelector('input').showPicker());  ※僅支援現代瀏覽器