Hướng dẫn chi tiết hệ thống tên miền, email, DNS, chứng chỉ số miễn phí

Xin chào các bạn, trong bài viết lần này mình sẽ hướng dẫn các bạn đăng ký và sử dụng một loạt các hệ thống như tên miền, email, DNS và cả chứng chỉ số hoàn toàn miễn phí. Việc này giúp một số bạn có điều kiện tiếp xúc với các công nghệ thường được sử dụng nhưng không phải chi quá nhiều tiền để có được. Tất cả các bạn cần là dành một chút thời gian ra để đọc, tìm hiểu và đăng ký sử dụng cho riêng mình.

Đối với các công ty không có đủ kinh phí thì bài viết này cũng là một hướng dẫn đáng giá.

Các hệ thống miễn phí lần lượt sẽ được giới thiệu đầy đủ trong bài gồm:

  • Tên miền miễn phí (freenom.com)
  • Quản lý domain miễn phí (Dynu.com)
  • Hệ thống email miễn phí (Yandex – miễn phí 1000 địa chỉ email cho 1 tên miền)
  • Chứng chỉ số miễn phí (Wosign)

Có một lưu ý nho nhỏ lý do tại sao mình sử dụng Dynu.com để quản trị tên miền đó là vì Dynu.com hỗ trợ giải pháp Dynamic DNS miễn phí, phù hợp với rất nhiều người muốn sử dụng IP động của mình. Đối với các cá nhân hoặc doanh nghiệp đang sử dụng IP tĩnh thì có quá nhiều lựa chọn, có thể sử dụng luôn quản trị DNS của dịch vụ tên miền hoặc các dịch vụ khác chẳng hạn như cloudflare.com

1/ Đăng ký tên miền miễn phí:

Snap 2016-07-30 at 12.23.01

Để bắt đầu với tên miền, các bạn truy cập địa chỉ http://freenom.com và nhập tên miền muốn sử dụng.
Click Check Availability

Snap 2016-07-30 at 12.23.48

Freenom sẽ liệt kê ra các tên miền tương ứng đang có sẵn, các bạn chọn tên miền phù hợp nhất cho mình. Có 5 tên miền miễn phí đó là .tk, .ml, .ga, .cf, .gq
Click Get it now

Snap 2016-07-30 at 12.24.09

Click nút Checkout để tiến hành thanh toán (miễn phí)

Snap 2016-07-30 at 12.25.31

Chọn Use DNS, nhập IP tạm tương ứng với tên miền, chọn thời gian sử dụng tên miền (hết thời hạn sẽ có tùy ch��n renew để sử dụng tiếp)

Click Continue để tiếp tục

Snap 2016-07-30 at 12.26.30

Nhập email để xác nhận đăng ký tên miền

Snap 2016-07-30 at 12.27.05

Freenom thông báo đã gửi mail xác nhận về địa chỉ email đã nhập ở phần trước. Các bạn truy cập email để click vào đường link xác nhận

Snap 2016-07-30 at 12.29.10

Sau khi bạn click link xác nhận, các bạn nhập thông tin theo yêu cầu và click Complete Order để hoàn tất phần thanh toán

Snap 2016-07-30 at 12.30.01

Hoàn tất, click vào nút Click here to go to your Client Area

Snap 2016-07-30 at 12.31.37

Chọn mục My Domains để quản lý tên miền của mình

Snap 2016-07-30 at 12.32.13

Tại danh sách tên miền, click chọn Manage Domain để tiếp tục

Snap 2016-07-30 at 12.34.49

Ở đây thể hiện thông tin của tên miền như ngày đăng ký, ngày hết hạn sử dụng, trạng thái tên miền
Các bạn có thể click nút Manage Freenom DNS để quản lý các record DNS

Snap 2016-07-30 at 12.35.33

Giao diện quản lý DNS. Ở đây do mình trong phần tới sẽ sử dụng dịch vụ quản trị DNS của Dynu.com do đó sẽ không nói nhiều ở phần này

Snap 2016-07-30 at 12.37.39

Do đã chủ ý transfer phần quản trị domain sang Dynu.com do đó mình thiết lập DNS server trỏ về Dynu.com. Nếu bạn sử dụng dịch vụ Dynamic DNS khác thì làm theo hướng dẫn. Đối với IP tĩnh thì hiện tại có rất nhiều dịch vụ quản trị DNS, Cloudflare.com là một trong những dịch vụ rất tốt. Bạn có thể đăng ký để sử dụng.

2/ Dịch vụ Dynamic DNS và quản lý domain Dynu.com

Để sử dụng dịch vụ của Dynu.com, các bạn vào trang chủ đăng ký một account và làm theo các bước hướng dẫn dưới đây để quản trị domain từ freenom và cập nhật IP tự động.

Snap 2016-07-30 at 12.40.21

Chắc chắn rằng bạn trỏ DNS server ở Freenom về máy chủ DNS của Dynu.com

Snap 2016-07-30 at 12.41.04

Khi bạn đã đăng ký thành công tài khoản Dynu.com, các bạn đăng nhập tài khoản và chuyển đến trang quản trị Control Panel.

Ở đây các bạn chọn DDNS Services (dịch vụ Dynamic DNS)

Snap 2016-07-30 at 12.41.19

Click nút Add để thêm tiên miền quản lý, ở đây trong bài này mình sử dụng vmblogs.cf

Snap 2016-07-30 at 12.42.03

Nhập tên miền và click nút Add

Snap 2016-07-30 at 12.43.03

Ở phần quản lý của mỗi tên miền có rất nhiều tùy chọn, các bạn có thể theo dõi địa chỉ IPv4, IPv6, nhập địa điểm quản lý, bật thông báo qua email…

Click DNS Records để quản lý các bản ghi DNS

Snap 2016-07-30 at 12.45.57

Mình tạo sẵn một số record như A, CNAME và MX. Dynu cũng hỗ trợ rất nhiều loại record, sẽ rất tiện dụng về sau nếu ai đó có ý định dùng nhiều dịch vụ và hệ thống yêu cầu hỗ trợ.

Snap 2016-07-30 at 12.50.21

Sau khi đã thiết lập các bản ghi DNS, các bạn có thể kiểm tra trạng thái tại mục Current DNS Status
Mình cũng test ping thử để xác nhận

Snap 2016-07-30 at 12.51.48

Mục Manage Offline Settings giúp bạn thiết lập các thông báo khi hệ thống trục trặc hoặc offline. Rất tiện thay vì thông báo lỗi 404

Snap 2016-07-30 at 12.52.32

Phần Location giúp bạn quản lý các địa điểm sử dụng. Ví dụ Home, CN1, CN2, Truso…Location này giúp xác nhận IP theo từng địa điểm khi các bạn thiết lập thông tin trên tool Dynu IP Update Client của Dynu

Snap 2016-07-30 at 13.08.56

Cài đặt

Snap 2016-07-30 at 13.09.12

Hoàn tất và chạy Dynu IP Update Client

Snap 2016-07-30 at 13.11.10

Các bạn nhập chính xác tên truy cập, mật khẩu và địa điểm. Location mình có nói ở phần trước.

3/ Đăng ký hệ thống email miễn phí của Yandex.

Google Apps và Outlook của Microsoft đã từ lâu không cho đăng ký email miễn phí cho tên miền riêng, trên mạng hiện cũng có nhiều dịch vụ cho phép đăng ký tuy nhiên lượng tài khoản rất giới hạn. Tuy nhiên Yandex khá hào phóng khi cho phép bạn tạo email tên miền riêng lên đến 1000 tài khoản, một con số không nhỏ chút nào.

Ngoài email thì Yandex cũng có rất nhiều dịch vụ khác như Disk (lưu trữ 10GB cho mỗi tài khoản), Maps cho dịch vụ bản đồ, Translate…

Bây giờ mình sẽ hướng dẫn các bạn đăng ký

Để đăng ký các bạn truy cập vào địa chỉ https://domain.yandex.com

Snap 2016-07-31 at 21.15.01

Các bạn nhập tên miền và click nút Connect Domain

Snap 2016-07-31 at 21.17.49

Để tiếp tục Yandex yêu cầu bạn login, click Login ở góc phải màn hình

Snap 2016-07-31 at 21.18.23

Do chưa có tài khoản nên chúng ta click Registration để tạo một tài khoản

Snap 2016-07-31 at 21.20.22

Nhập các thông tin cá nhân và số điện thoại di động để nhận mã xác thực.
Click Send code để nhận mã. Tuy nhiên mình Send 4-5 lần không nhận được tin nhắn nào cả. Đành phải dùng tùy chọn “I don’t have a mobile phone number” và phải nhập Captcha để xác nhận

Sau khi xác nhận hoàn tất click Register để tiến hành đăng ký.

Snap 2016-07-31 at 21.38.23

Yandex sẽ tiến hành xác minh tên miền của bạn, ban đầu họ sẽ báo lỗi, tuy nhiên sẽ được xử lý nhanh
chóng.

Có 3 cách để Yandex xác minh tên miền, có thể upload 1 file html lên web hoặc tạo bản ghi CNAME trong phần quản trị DNS. Ở đây mình chọn cách đầu tiên là tạo 1 file html như hướng dẫn.

Sau khi đã thực hiện như hướng dẫn (1 trong 3 cách), click nút Verify Domain Ownership để xác minh tên miền

Snap 2016-07-31 at 21.47.11

File html mình tạo để Yandex xác minh tên miền

Snap 2016-07-31 at 21.48.26

Mình cũng tạo một bản ghi MX theo hướng dẫn của Yandex để tiến hành xác minh MX record

Snap 2016-07-31 at 21.49.18

MX record

Snap 2016-07-31 at 21.50.15

Sau khi tạo như hướng dẫn, click nút Verify MX Record

Snap 2016-07-31 at 21.51.28

Hoàn tất thủ tục
Nhập thông tin để tạo tài khoản email => click nút Add

Snap 2016-07-31 at 21.52.14

Giao diện khi hoàn tất

Snap 2016-07-31 at 21.58.37

Sau khi đăng nhập bằng tài khoản mới tạo, Yandex sẽ yêu cầu bổ sung thông tin cá nhân cho tài khoản. Bổ sung theo yêu cầu, nhập mã Captcha và click Complete registration

Snap 2016-07-31 at 21.59.01

Giao diện webmail của Yandex

Snap 2016-07-31 at 22.00.37

Yandex webmail

Snap 2016-07-31 at 22.02.30

Dịch vụ lưu trữ trực tuyến, mỗi tài khoản có được 10GB lưu trữ

Snap 2016-07-31 at 22.02.57

Dịch vụ bản đồ

Snap 2016-07-31 at 22.03.52

Dịch thuật, hỗ trợ đoạn văn, dịch website hoặc dịch từ hình ảnh.

4/ Đăng ký chứng chỉ số miễn phí Wosign

Wosign cung cấp chứng chỉ số miễn phí tương đối tốt, các trình duyệt hỗ trợ tốt trừ một số hệ điều hành di động cũ. Bên cạnh Wosign cũng có Let’s Encrypt tuy nhiên Let’s Encrypt chưa hỗ trợ tốt lắm cho Windows do đó trong bài này mình sử dụng IIS trên Windows Server là dùng chứng chỉ số của Wosign.

Snap 2016-07-31 at 22.13.50

Để đăng ký Wosign miễn phí, các bạn truy cập địa chỉ https://buy.wosign.com/free

Snap 2016-07-31 at 22.18.36

Nhập tên miền cần đăng ký chứng chỉ số, số năm, quốc gia, địa chỉ email
Khi bạn nhập địa chỉ email, click Send Email Verification để xác minh địa chỉ email, Wosign sẽ gửi mã xác nhận vào email do đó các bạn cần phải nhập chính xác.
Có mã xác nhận rồi các bạn nhập mật khẩu cho tài khoản Wosign, nhập mã Captcha và click Submit Request

Snap 2016-07-31 at 22.19.33

Sau khi hoàn tất các bạn click Domain Control Verification

Snap 2016-07-31 at 22.22.46

Có thể xác nhận domain thông qua email hoặc upload file lên trang web, do tài khoản admin@vmblogs.cf mình đã tạo trước đó nên mình dùng luôn địa chỉ email này để Wosign xác minh.
Click Send verification email và nhập mã xác nhận Verification code
Nhập mã Captcha và click Verify Now

Snap 2016-07-31 at 22.23.13

Sau khi hoàn tất xác minh tên miền, Wosign sẽ yêu cầu bạn dán nội dung yêu cầu cấp chứng chỉ số CSR

Snap 2016-07-31 at 22.25.17

Để tạo CSR trong IIS các bạn chọn server và click Server Certificates

Snap 2016-07-31 at 22.25.46

Click Create Certificate Request

Snap 2016-07-31 at 22.26.27

Nhập đầy đủ các thông tin, quan trọng nhất là common name.
Common name có thể là tên miền, tên miền con…Vd vmblogs.cf, chat.vmblogs.cf, fileshare.vmblogs.cf…

Snap 2016-07-31 at 22.27.03

Chọn Microsoft RSA SCHANNEL và bitlength là 2048 => click Next

Snap 2016-07-31 at 22.27.34

Chọn nơi lưu certificate request CSR

Snap 2016-07-31 at 22.28.02

Copy nội dung file CSR và click check CSR

Snap 2016-07-31 at 22.28.36

Sau khi check xong click Submit để tiến hành

Snap 2016-07-31 at 22.29.40

Chứng chỉ số của bạn đã hoàn tất, click download để tải về

Snap 2016-07-31 at 22.32.28

Quay trở lại IIS và click Complete Certificate Request

Snap 2016-07-31 at 22.33.17

Mở đường dẫn đến tập tin mà Wosign gửi về, đặt tên gợi nhớ và click OK

Snap 2016-07-31 at 22.34.05

Click View để xem trước chứng chỉ số

Snap 2016-07-31 at 22.35.21

Cấu hình Binding để cho phép truy cập https và sử dụng chứng chỉ số từ Wosign

Snap 2016-07-31 at 22.36.55

Test thử trên máy client, thành công.

Như vậy mình đã hướng dẫn cho các bạn đầy đủ các cách thức đăng ký tên miền miễn phí, sử dụng tên miền này cho IP động thông qua dịch vụ Dynamic DNS Dynu.com, đăng ký hệ thống email và các tiện ích khác từ Yandex và hướng dẫn đăng ký chứng chỉ số miễn phí từ Wosign để sử dụng với IIS.

Chúc các bạn thành công.

Tính khoản cách giữa 2 điểm bằng sql server và C#

sql server 

 --[dbo].[sp_DuAnGetKhoangCach] 10.7756587, 106.70042379999995, 0.5

CREATE PROCEDURE [dbo].[sp_DuAnGetKhoangCach]

    @ZipLatitude float, 
    @ZipLongitude float,
    @Radius  float
AS  
SELECT * FROM DuAn

WHERE dbo.TinhKhoanCach2Diem(lat, lng, @ZipLatitude, @ZipLongitude) < @Radius



CREATE FUNCTION TinhKhoanCach2Diem(
    @Latitude1 float,
    @Longitude1 float,
    @Latitude2 float,
    @Longitude2 float
)
RETURNS float 
AS  
    BEGIN 
    -- CONSTANTS
    DECLARE @EarthRadiusInMiles float;
    SET @EarthRadiusInMiles = 6371 -- 3959 for miles, 6371 for KM

    DECLARE @PI  float;
    SET @PI = PI();
    -- RADIANS conversion
    DECLARE @lat1Radians float;
    DECLARE @long1Radians float;
    DECLARE @lat2Radians float;
    DECLARE @long2Radians float;
    SET @lat1Radians = @Latitude1 * @PI / 180;
    SET @long1Radians = @Longitude1 * @PI / 180;
    SET @lat2Radians = @Latitude2 * @PI / 180;
    SET @long2Radians = @Longitude2 * @PI / 180;
    RETURN Acos(
    Cos(@lat1Radians) * Cos(@long1Radians) * Cos(@lat2Radians) * Cos(@long2Radians) + 
    Cos(@lat1Radians) * Sin(@long1Radians) * Cos(@lat2Radians) * Sin(@long2Radians) + 
    Sin(@lat1Radians) * Sin(@lat2Radians)
    ) * @EarthRadiusInMiles;
END

C#

/// <summary>
/// Specifies a Latitude / Longitude point.
/// </summary>
public class LatLng
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }

    public LatLng(){
    }

    public LatLng(double lat, double lng)
    {
        this.Latitude = lat;
        this.Longitude = lng;
    }
}

/// <summary>
/// Returns the distance in miles or kilometers of any two
/// latitude / longitude points.
/// </summary>
/// <param name="pos1">Location 1</param>
/// <param name="pos2">Location 2</param>
/// <param name="unit">Miles or Kilometers</param>
/// <returns>Distance in the requested unit</returns>
public double HaversineDistance(LatLng pos1, LatLng pos2, DistanceUnit unit)
{
    double R = (unit == DistanceUnit.Miles) ? 3960 : 6371;
    var lat = (pos2.Latitude - pos1.Latitude).ToRadians();
    var lng = (pos2.Longitude - pos1.Longitude).ToRadians();
    var h1 = Math.Sin(lat / 2) * Math.Sin(lat / 2) +
                  Math.Cos(pos1.Latitude.ToRadians()) * Math.Cos(pos2.Latitude.ToRadians()) *
                  Math.Sin(lng / 2) * Math.Sin(lng / 2);
    var h2 = 2 * Math.Asin(Math.Min(1, Math.Sqrt(h1)));
    return R * h2;
}

public enum DistanceUnit { Miles, Kilometers };

var Offices = GetMyOfficeList();
for(int i = 0; i< Offices.Count; i++)
{
    Offices[i].Distance = HaversineDistance(
                            coord,
                            new LatLng(Offices[i].Lat, Offices[i].Lng),
                            DistanceUnit.Miles);
}

var closestOffice = Offices.OrderBy(x => x.Distance).Take(1).Single();

 

 

Tổng hợp các Mã nguồn mở .Net

Danh sách các open source cho anh em tham khảo mọi người biết cái gì mới thì bổ sung nhá 

Form MVC https://github.com/YodasMyDad/mvcforum

BlogEngine.NET http://blogengine.codeplex.com/releases

nopCommerce https://github.com/nopSolutions/nopCommerce

Đóng góp của bạn Nguyễn Xuân Thanh

 - DotnetNuke - Portal khá nhiều các đơn vị và cơ quan sử dụng http://www.dnnsoftware.com/ 

- Umbraco - CMS gần giống với khóa học https://umbraco.com

- MRCMS -  khó sài -https://www.mrcms.com/

Đóng góp của bạn Kiet Tuan Le

Đây là trang web có rất nhiều mã nguồn

Mọi người tham khảo nhe : https://webgallery.microsoft.com/gallery

Chia sẽ anh em hàm validate mình viết

Chia sẽ anh em hàm validate mình viết cái này được cái  cái này gọn nhẹ sài được cho div không cần gắn vào form, có thể validate những nhóm đối tượng tách biệt nhau, theo class, id , attributes....

Để xử dụng cần gán thuộc tính required vào và các loại class int, date, datetim, dec , email..

var ThuY = {};
ThuY.Form = function (formId) {
    this.hasError = false;
    this.$element = $(formId);

    this.focusError = function () {
        var $input = this.$element.find(".has-error:first :input");
        if ($input.length === 0) return;
        $("html, body").animate({ scrollTop: $input.offset().top - 100 }, 250);
        $input.focus();
    };
     function getValue($el) {
        return $el.is('[type="checkbox"]')
            ? $el.prop("checked")
            : $el.is('[type="radio"]') ? !!$('[name="' + $el.attr("name") + '"]:checked').length : $el.val();
    }
    this.getError = function () {
        var formError = {};

        this.$element.find('input[required],textarea[required],select[required]').each(function (i, requiredField) {
            var $el = $(requiredField);
            var $type = $el.attr('type');

            var $message = $el.attr('reqired-message');
            if (isNotSet($message)) {
                $message = "Giá trị này phải nhập";
            }

            var $maxLength = $el.attr('data-max');
            var $minLength = $el.attr('data-min');
            var $pattern = $el.attr('data-pattern');
            var $value = getValue($el);

            if ($el.hasClass('int')) {
                $value = $value.replace(/[^\d\.\-]/g, "");
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (typeof n == 'number' && /^-?\d+$/.test($value) === false) {
                    formError[$el.attr('name')] = "Vui lòng nhập vào chuỗi số";
                } else if (isSet($minLength)) {
                    if (parseInt($value) < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if (parseInt($value) > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải nhỏ hơn hơn " + $maxLength;
                    }
                }
            } else if ($el.hasClass('dec')) {
                $value = $value.replace(/[^\d\.\-]/g, "");
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^\d+.?\d*$/.test($value) === false) {
                    formError[$el.attr('name')] = "Vui lòng nhập vào chuỗi số";
                } else if (isSet($minLength)) {
                    if (parseFloat($value) < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if (parseFloat($value) > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải nhỏ hơn hơn " + $maxLength;
                    }
                }

            } else if ($el.hasClass('email') || $type === 'email') {
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/.test($value) === false) {
                    formError[$el.attr('name')] = "Email không đúng định dạng";
                }

            } else if ($el.hasClass('url') || $type === 'url') {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test($value) === false) {
                    formError[$el.attr('name')] = "Website không đúng định dạng";
                }
            } else if ($el.hasClass('date')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(\d{2})[\/](\d{2})[\/](\d{4})$/.test($value) === false) {
                    //Check date 99/99/9999
                    formError[$el.attr('name')] = "Ngày tháng không đúng định dạng";
                }
            } else if ($el.hasClass('time')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                    //Check time 99:99
                } else if (/([01]\d|2[0-3]):([0-5]\d)/.test($value) === false) {
                    formError[$el.attr('name')] = "Thời gian không đúng định dạng";
                }
            } else if ($el.hasClass('datetime')) {

                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (/^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2})$/.test($value) === false) {
                    //Check date time 99/99/9999 99:99
                    formError[$el.attr('name')] = "Thời gian không đúng định dạng";
                }
            } else if (isSet($pattern)) {

                if ($pattern.test($value) === false) {
                    formError[$el.attr('name')] = "Giá trị nhập vào không đúng định dạng";
                }
            } else {
                if ($value === '') {
                    formError[$el.attr('name')] = $message;
                } else if (isSet($minLength)) {
                    if ($el.val().length < $minLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải có số ký tự lớn hơn " + $minLength;
                    }
                } else if (isSet($maxLength)) {
                    if ($el.val().length > $maxLength) {
                        formError[$el.attr('name')] = "Giá trị nhập vào phải có số ký tự nhỏ hơn " + $maxLength;
                    }
                }
            }
            $el.bind('change', function () {
                formError[$(this).attr('name')] = null;
            });


        });

        if (!$.isEmptyObject(formError)) { this.hasError = true; }
        return formError;

    }
    this.isFloat = function (val) {
        var floatRegex = /^-?\d+(?:[.,]\d*?)?$/;
        if (!floatRegex.test(val)) return false;
        val = parseFloat(val);
        if (isNaN(val)) return false;
        return true;
    }

    this.isInt = function (val) {
        var intRegex = /^-?\d+$/;
        if (!intRegex.test(val))return false;
        var intVal = parseInt(val, 10);
        return parseFloat(val) === intVal && !isNaN(intVal);
    }
    this.resetForm = function () {
        this.$element.find("input, textarea, select").val("");
    }

    this.isEmpty = function (value, allowEmptyString) {
        function countProperty(obj) {
            var count = 0;
            for (var k in obj)
                obj.hasOwnProperty(k) && ++count;
            return count;
        }

        return value === false ||
            null === value ||
            isNaN(value) === false && 0 === parseInt(value, 10) ||
            "null" === value ||
            void 0 === value ||
            "undefined" === value ||
            (allowEmptyString ? false : "" === value) ||
            "object" == typeof value && 0 === countProperty(value) ||
            "object" == typeof value && 1 === countProperty(value) && "" === value[0] ||
            value instanceof jQuery && 0 === value.length;
    }
    this.loadItem = function () {
        var $item = {};
        this.$element.find('input,textarea,select')
            .each(function (i, item) {
                $item[$(item).attr('name')] = getValue($(item));
            });

        return $item;
    }
    this.item =  this.loadItem();
}

để xử dụng trong controller mình làm như sau

var form = new ThuY.Form("#formAddKhach");
$scope.formErrorAddKhach = form.getError();
if (form.hasError) {
    form.focusError();
    return;
}

html

<div class="col-md-3">
    <div class="form-group" data-ng-class="{'has-error' : formAddKhach.Ten.$invalid && formAddKhach.Ten.$dirty || formErrorAddKhach.Ten}">
        <label class="control-label" for="Ten">{{L('Ten')}} <span class="require">*</span></label>
        <div class="">
            <input class="form-control" id="Ten" name="Ten" ng-model="itemAddKhach.Ten" required reqired-message="Tên bắt buộc nhập." />
            <span class="help-block" ng-show="formAddKhach.Ten.$invalid  && formAddKhach.Ten.$dirty">Nhập {{L('Ten')}}</span>
            <span class="help-block" ng-if="formErrorAddKhach.Ten">{{formErrorAddKhach.Ten}}</span>
        </div>
    </div>
</div>

 

Một số phương thức của mảng trong Javascript

Để viết các ứng dụng với javascript thì việc vận dụng mảng là một điều hết sức cần thiết. Javascript cũng như các ngôn ngữ lập trình khác cũng có mảng và cách thức làm việc của mảng trong Javascript cũng tương tự, vấn đề cần quan tâm là các chức năng thao tác với mảng thì mỗi một ngôn ngữ lập trình đều viết sẵn một số hàm hoặc phương thức để thao tác, ý nghĩa của các hàm thì giống nhau chỉ khác ở cách khai báo và cách gọi tên hàm của từng ngôn ngữ.

Trong bài viết này chúng ta sẽ tìm hiểu một số phương thức thường được dùng để thao tác với các phần tử mảng trong Javascript.

Trong PHP bạn có thể khai báo mảng bằng rất nhiều cách ngắn gọn trong đó có một cách rất đơn giản là sử dụng dấu ngoặc vuông "[]" khi nào cần sử dụng mảng mà không cần phải khai báo trước, trong dấu ngoặc vuông có thể bỏ trống và PHP sẽ tự gán key cho mảng đó. Trong Javascript thì bạn không thể khai báo theo cách ngằn gọn giống PHP như trên mà cần phải khai báo mảng trước sau đó mới có thể sử dụng. Cú pháp khai báo mảng của Javascript là new array("phần tử","phần tử",..."").

Một điều nhấn mạnh rằng mảng trong Javascript là một đối tượng, sau đây sẽ là một số phương thức cần thiết để bạn thao tác với mảng:

  1. push("phần tử", "phần tử") -> Phương thức sẽ thêm phần tử vào cuối mảng
  2. unshift("phần tử", "phần tử") -> Phương thức sẽ thêm phần tử vào đầu mảng
  3. pop() ->Phương thức sẽ xóa phần tử cuối trong mảng
  4. shift() ->Phương thức sẽ xóa phần tử đầu trong mảng
  5. sort() ->Phương thức sẽ sắp các phần tử mảng theo giá trị tăng dần đồng thời gán lại key theo thứ tự tăng dần, chú ý phương thức chỉ có tác dụng với mảng có key liên tiếp bắt đầu từ 0
  6. concat() ->Phương thức kết hợp hai mảng thành một
  7. slice(ví trí bắt đầu, vị trí kết thúc) ->Phương thức tách ra một mảng con
  8. join() ->Phương thức tạo một chuỗi từ một mảng, đối số là chuỗi nối các giá trị của phần tử trong mảng
  9. reverse() ->Đảo ngược các vị trí phần từ trong mảng đồng thời xắp lại key

Ngoài ra chúng ta còn có một số các phương thức hữu dụng khác như every(), some(), filter(), forEach(), map() tuy nhiên chúng lại không được hổ trợ bởi các trình duyệt cũ như IE7.
Có một phương thức vô cùng mạnh mẽ khác trong javascript đó là phương thức splice(), nó có thể thay thế cho các phương thức như pop(), push(),shift(), unshift() ở trên:

  1. splice(vị trí bắt đầu, số lượng) ->Phương thức sẽ xóa một số phần tử tại vị trí bất kỳ trong mảng
  2. splice(vị trí bắt đầu, số lượng, "phẩn tử mới", "phần tử mới",""...) ->Khi thêm đối số vào phương thức nó sẽ thay thế các phần tử mới vào các phần tử đã xóa.

Chúng ta có thể thấy việc thao tác với các phần tử mảng trong Javascript cũng không có gì khó khăn điều quan trọng là chúng ta biết vận dụng các phương thức của chúng khi cần thiết. Bài viết này tôi chỉ mang hình thức giời thiệu, nếu bạn muốn thực sự làm việc với Javascript thì chí ít bạn cũng phải biết chút ít kiến thức về lập trình căn bản, bạn có thể tự làm ví dụ để hiểu rõ hơn nếu bạn chưa thực sự hiểu về nó.