2016年10月5日 星期三

客製化checkbox樣式

原本的checkbox看起來很小一個,以下為客製化的checkbox:
  • 隱藏原本的checkbox
  • 將label調整成像一個checkbox的外觀
  • 用FontAwesome來顯示打勾

<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
        <style>
            #ckb1{
                display:none;
            }
                #ckb1 + label[for="ckb1"]{
                     border:1px solid gray;
                     width:26px;
                     height:26px;
                     border-radius:4px;
                     display:inline-block;
                 }
                 #ckb1:checked + label[for="ckb1"]:before{
                     color:green;
                     font-family:FontAwesome;
                     content:'\f00c';
                     position:ablolute;
                     font-size:26px;
                     line-height:28px;
                 }
        </style>
    </head>
    <body>
        <input type="checkbox" id="ckb1"/>
        <label for="ckb1"></label>
    </body>
</html>

2016年8月29日 星期一

用簡易的範例快速瞭解 c# delegate 的前世今生

深入研究asp.net core 需要了解 delegate, 所以做筆記複習一下:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp2
{
    // 定義一個委派型別
    public delegate bool Predicate(string s); 

    // 定義一個類別
    public class FruitList 
    {
        private List<string> fruits;

        public FruitList()
        {
            fruits = new List<string> { "Apple", "Banana", "Mango" };
        }
        public string Find(Predicate p)
        {
            for (int i = 0; i < fruits.Count(); i++)
            {
                var f = fruits[i];
                var isMatch = p(f); // 執行委派任務, 等同於  p.Invoke(f)
                if (isMatch)
                {
                    return f;
                }
            }
            return "";
        }
    }
    // demo c# 1.0
    public class Demo1
    {
        public void Run()
        {
            FruitList fruits = new FruitList();
            Predicate p = new Predicate(FindApple); // 建立委派物件. 可以加入多項工作, 例如 : p += new Predicate(FindBanana);
            string f = fruits.Find(p);
            Console.WriteLine(f);
        }

        private bool FindApple(string s)
        {
            return s == "Apple";
        }
    }
    // c# 2.0 : 匿名方法
    public class Demo2
    {
        public void Run()
        {
            FruitList fruits = new FruitList();
            Predicate p1 = FindBanana;  // 編譯器看到變數是委派型別, 便會自動加上 new 
            string f1 = fruits.Find(p1); 
            string f2 = fruits.Find(FindBanana); // 簡化 f1
            Console.WriteLine(f1);

            // 使用匿名方法
            Predicate p3 = delegate (string s) { return s == "Banana"; };
            string f3 = fruits.Find(p3);
            //
            Console.WriteLine(f3);
        }

        private bool FindBanana(string s)
        {
            return s == "Banana";
        }
    }
    // c# 3.0 : Lambda
    public class Demo3
    {
        public void Run()
        {
            FruitList fruits = new FruitList();
            Predicate p1 = (string s) => { return s == "Mango"; }; // Lambda 取代了匿名方法
            Predicate p2 = (string s) => s == "Mango"; // 簡化 p1 寫法
            Predicate p3 = s => s == "Mango"; // 簡化 p2 寫法
            string f1 = fruits.Find(p3);
            string f2 = fruits.Find(s => s == "Mango"); // 簡化 f1 
            Console.WriteLine(f2);
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var d = new Demo3();
            d.Run();
            Console.ReadKey();
        }
    }
}

2016年8月11日 星期四

drag and drop upload files with asp.net core





前端 HTML : 
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        body {
            font-family"Arial",sans-serif;
        }
 
        .dropzone {
            width300px;
            height300px;
            border2px dashed #ccc;
            color#ccc;
            line-height300px;
            text-aligncenter;
        }
 
            .dropzone.dragover {
                border-color#000;
                color#000;
            }
    </style>
</head>
<body>
    <div id="uploads"></div>
    <div class="dropzone" id="dropzone">Drop files here to append file</div>
    <ul id="files-to-upload"></ul>
    <input type="text" name="tags" id="tags" value="blue,whatever" />
    <input type="text" name="name" id="name" value="name" />
    <button onclick="onUpload()">upload</button>
    <script>
        var dropzone = document.getElementById('dropzone'),
            filesToUpload = document.getElementById('files-to-upload'),
            fileArr = [];
 
        var appendFiles = function (files) {
            console.log(files);
            for (var i = 0; i < files.length; i++) {
                filesToUpload.insertAdjacentHTML('beforeend', '<li>' + files[i].name + '</li>');
                fileArr.push(files[i]);
            }
        };
 
        var onUpload = function () {
            var xhr = new XMLHttpRequest(), formData = new FormData();
            for (var i = 0; i < fileArr.length; i++) {
                formData.append('files', fileArr[i]);
            }
            // append metadata
            formData.append('tags', document.getElementById('tags').value);
            formData.append('name', document.getElementById('name').value);
            console.log(formData);
            //
            xhr.onload = function () { // success
                var data = this.responseText;
                while (filesToUpload.firstChild) { //  faster than "filesToUpload.innerHTML = '';"
                    filesToUpload.removeChild(filesToUpload.firstChild);
                }
                fileArr = []; // empty file list
                console.log(data);
            };
            xhr.open('post', '/Home/Upload');
            xhr.send(formData);
 
        }
 
        dropzone.ondrop = function (e) {
            e.preventDefault(); // 避免瀏覽器開啟圖片
            this.className = 'dropzone';
 
            appendFiles(e.dataTransfer.files);
        };
 
        dropzone.ondragover = function () {
            this.className = 'dropzone dragover';
            return false;
        };
 
        dropzone.ondragleave = function () {
            this.className = 'dropzone';
            return false;
        };
    </script>
</body>
</html>




=========================
後端 ASP.NET Core 

[HttpPost]
public async Task<IActionResult> Upload(ICollection<IFormFile> files, string tags, string name)
{
    foreach (var file in files)
    {
        if (file.Length > 0)
        {
            using (var fileStream = new FileStream(Path.Combine("wwwroot/images", file.FileName), FileMode.Create))
            {
                await file.CopyToAsync(fileStream);
            }
        }
    }
    return Content("A12345678");
}

2016年5月11日 星期三

ASP.NET 5 Self-hosting the application

在 Visual Studio 執行程式時選 web (預設是 IIS Express)

或是

在專案的資料夾([方案名稱]/src/[專案名稱])下開啟命令視窗(按Shift點右鍵會出現選項)

輸入 dnx web 後顯示  Listening on http:localhost:5000

如果要改用別的port, 修改 project.json

dependencies加入 Microsoft.AspNet.Server.WebListener
修改commandsweb(原本預設是:"Microsoft.AspNet.Server.Kestrel")


{
    "dependencies": {        
        "Microsoft.AspNet.Server.WebListener" : "1.0.0-rc-final",
    },
    "commands": {
      "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5001"  
    }
}


2016年4月18日 星期一

self-hosting console 的 signalr 使用靜態網頁

Startup 類別的 Configuration(IAppBuilder app) 裡添加程式碼:

           app.Map("/signalr", map =>
            {
                // To enable CORS requests, Install-Package Microsoft.Owin.Cors

                // Setup the cors middleware to run before SignalR.
                // By default this will allow all origins. You can
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);

                var hubConfiguration = new HubConfiguration
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                };

                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch is already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });
            // 這裡是新添加的部分
            var physicalFileSystem = new PhysicalFileSystem(@"./www");
            var options = new FileServerOptions
            {
                EnableDefaultFiles = true,
                FileSystem = physicalFileSystem
            };
            options.StaticFileOptions.FileSystem = physicalFileSystem;
            options.StaticFileOptions.ServeUnknownFileTypes = true;
            options.DefaultFilesOptions.DefaultFileNames = new[] { "index.html" };
            app.UseFileServer(options);
            //
            app.UseWelcomePage();


[專案名稱]\bin\Debug 裡新增資料夾 www