Xử lý Dialog với Jquery UI trên MVC asp.net

Giới thiệu về JQueryUI

JQueryUI là viết tắt của jQuery GUI. Nó là một bộ sưu tập các hiệu ứng hoạt hình hình ảnh, vật dụng GUI, và chủ đề thực hiện với jQuery, CSS, HTML và JavaScript. Các plug-ins mới thêm rất nhiều chức năng mới trong các thư viện lõi jQuery. Để tìm hiểu chi tiết mọi người truy cập vào link : https://jqueryui.com/

Hướng dẫn cài đặt

Bài Viblo tháng này mình xin giới thiệu 1 trong các cách sử dụng Jquery UI để tạo Message Dialog hoặc Popup trong mô hình MVC nhé.

Đầu tiên chúng ta sẽ tiến hành cài đặt JqueryUI vào project

  • Chúng ta sử dụng lệnh Package Manager Console: “Install-Package jQuery.UI.Combined” Sau khi chạy lệnh này thì Visual Studio sẽ tự động download và add file vào project cho chúng ta.

Tiếp theo để sử dụng Jquery chúng ta sửa lại file “BundleConfig.cs” bằng cách add them JqueryUI js và JqueryUI css vào câu lệnh render như sau:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js",
                        "~/Scripts/jquery-ui-{version}.js"));

bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css",
                        "~/Content/themes/base/jquery-ui.css"));

Như vậy là chúng ta đã add JqueryUI vào project, khi chúng ta start project thì bundle sẽ render JqueryUI và CSS cùng lúc với render Jquery.

Hướng dẫn sử dụng với ví dụ

Tiếp theo mình sẽ tạo 1 file JS có tên là “Dialog.js” để thực hiện custom lại JqueryUI

Cú pháp hoạt động của Jquery như sau: $(HtmlEmlement).dialog(DialogOption)

  • HtmlEmlement: đây chính là đối tượng mình sẽ custom để hiển thị theo ý của mình
  • DialogOption: đay chính là đối tượng mình sẽ custom để handle các sự kiện của dialog, nếu DialogOption ko đc custom thì JqueryUI sẽ tự động lấy defaultOption của dialog.

Chúng ta sẽ bắt tay vào thực hiện thôi

Đầu tiên mình sẽ bắt đầu với MessageBox, cho nên mình sẽ tạo 1 object có tên là “MessageBox” với Option và các sự kiện dành cho message Box vd như “confirm, alert,…”

var MessageBox = {
}

Tiếp theo mình sẽ tạo function để show dialog cho MessageBox

var MessageBox = {
    Show: function (message){
        var div = '<div id="divMessage"><p id="txtMessage"'
                    + 'style=" color: #58595B;float: left;text-align: left; width: 85%;">'
                    + message + '</p><div class="clear-both"></div></div>';

        $(div).dialog('open');
        }
}

Chúng ta sẽ test function bằng console của Chrome

MessageBox.Show(“Hello Word, I’m JqueryUI”)

Chúng ta đã tạo đc 1 Dialog với message là “Hello Word, I’m JqueryUI”

Default.jpg

Tiếp theo chúng ta sẽ xử lý tiếp về

  • Buttons
  • Function Call Back
  • Handle Close Dialog
  • Responsive jQuery UI Dialog

Chúng ta có thể add các button cho Dialog 1 cách rất đơn giản bằng Option “Buttons” của JqueryUI

  1. Handle Button and Function Call Back

var MessageBox = {
     Show: function (message, caption, messageBoxButton, messageBoxIcon, functionCallback) {
      var iconUrl = '';
        switch (messageBoxIcon) {
            case MessageBoxIcons.Warning:
                iconUrl = GetVirtualPath('/Content/images/icon-warning.png');
                break;

            case MessageBoxIcons.Confirm:
                iconUrl = GetVirtualPath('/Content/images/icon-confirm.png');
                break;

            case MessageBoxIcons.Error:
                iconUrl = GetVirtualPath('/Content/images/icon-error.png');
                break;

            case MessageBoxIcons.Information:
                iconUrl = GetVirtualPath('/Content/images/icon-infor.png');
                break;

            case MessageBoxIcons.Question:
                iconUrl = GetVirtualPath('/Content/images/icon-confirm.png');
                break;

            default:
                iconUrl = GetVirtualPath('/Content/images/icon-infor.png');
                break;
        }

        var div = '<div id="divMessage"><table><tr><td></td><td id="txtMessage"><div>' + message + '</div></td></tr></table></div>';

        var buttons;

        switch (messageBoxButton) {
            case MessageBoxButtons.Refresh:
                buttons = {
                    "Refresh": function () { MessageBox.Callback(DialogResults.Refresh, functionCallback); }
                }
                break;
            case MessageBoxButtons.OK:
                buttons = {
                    "OK": function () { MessageBox.Callback(DialogResults.OK, functionCallback); }
                }
                break;
            case MessageBoxButtons.OKCancel:
                buttons = {
                    "OK": function () { MessageBox.Callback(DialogResults.OK, functionCallback); },
                    "Cancel": function () { MessageBox.Callback(DialogResults.Cancel, functionCallback); }
                }
                break;
            case MessageBoxButtons.AbortRetryIgnore:
                buttons = {
                    "Abort": function () { MessageBox.Callback(DialogResults.Abort, functionCallback); },
                    "Retry": function () { MessageBox.Callback(DialogResults.Retry, functionCallback); },
                    "Ignore": function () { MessageBox.Callback(DialogResults.Ignore, functionCallback); }
                }
                break;
            case MessageBoxButtons.YesNoCancel:
                buttons = {
                    "Yes": function () { MessageBox.Callback(DialogResults.Yes, functionCallback); },
                    "No": function () { MessageBox.Callback(DialogResults.No, functionCallback); },
                    "Cancel": function () { MessageBox.Callback(DialogResults.Cancel, functionCallback); }
                }
                break;
            case MessageBoxButtons.YesNo:
                buttons = {
                    "Yes": function () { MessageBox.Callback(DialogResults.Yes, functionCallback); },
                    "No": function () { MessageBox.Callback(DialogResults.No, functionCallback); }
                }
                break;
            case MessageBoxButtons.RetryCancel:
                buttons = {
                    "Retry": function () { MessageBox.Callback(DialogResults.Retry, functionCallback); },
                    "Cancel": function () { MessageBox.Callback(DialogResults.Cancel, functionCallback); }
                }
                break;
            case MessageBoxButtons.YesNoStayOnPage:
                buttons = {
                    "Yes": function () { MessageBox.Callback(DialogResults.Yes, functionCallback); },
                    "No": function () { MessageBox.Callback(DialogResults.No, functionCallback); },
                    "Stay on this page": function () { MessageBox.Callback(DialogResults.StayOnPage, functionCallback); }
                }
                break;
            case MessageBoxButtons.BackContinue:
                buttons = {
                    "Back": function () { MessageBox.Callback(DialogResults.Back, functionCallback); },
                    "Continue": function () { MessageBox.Callback(DialogResults.Continue, functionCallback); }
                }
                break;
        }

        var result = $(div).dialog({
            title: caption,
            autoOpen: false,
            width: 'auto',
            height: 'auto',
            modal: true,
            fluid: true,
            resizable: false,
            draggable: false,
            buttons: buttons,
            });
        result.dialog('open');
    },
      Callback: function (dialogResult, functionCallback) {
        MessageBox.Close();
        if (functionCallback) {
            functionCallback(dialogResult);
        }
    },
    Close: function () {
        $('#divMessage').html('');
        $('#divMessage').remove();
        $('#divMessage').dialog('destroy').remove();
    }
}

var MessageBoxButtons = {
    OK: 0,
    OKCancel: 1,
    AbortRetryIgnore: 2,
    YesNoCancel: 3,
    YesNo: 4,
    RetryCancel: 5,
    YesNoStayOnPage: 6,
    BackContinue: 7
}

var DialogResults = {
    OK: "OK",
    Cancel: "Cancel",
    Abort: "Abort",
    Retry: "Retry",
    Ignore: "Ignore",
    Yes: "Yes",
    No: "No",
    StayOnPage: "StayOnPage",
    Back: "Back",
    Continue: "Continue",
    Refresh: "Refresh",
    NoThanks: "No, thanks"
}

function GetVirtualPath(patch) {
    var host = window.location.protocol + '//' + window.location.host;
    return host + patch
}
<script type="text/javascript">
    function showDiaglog() {
        MessageBox.Show("abc", "title", MessageBoxButtons.YesNoThanks, MessageBoxIcons.Question, function (event) {
            if (event == DialogResults.Yes) {
                alert("Click Yes")
            }
            else if (event == DialogResults.NoThanks) {
                alert("Click No")
            }
        });
    }
</script>
<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <p><a href="http://asp.net" class="btn btn-primary btn-large">Learn more »</a></p>
</div>

<div class="row" style="text-align:center">
    <input type="button" id="btnTest" onclick="showDiaglog();" value="Test Show Dialog" />
</div>

a. Mình định nghĩa các button mà mình cần sử dụng bằng việc thiết lập Object “MessageBoxButtons” là 1 enum

b. Update Function Show của MessageBox => Show: function (message, caption, messageBoxButton, messageBoxIcon, functionCallback)

c. Với mỗi parameter messageBoxButton truyền vào thì mình sẽ sử dụng switch case để config button cho Dialog

d. Với mỗi loại button thì khi click sẽ gọi FunctionCallBack với result truyền vào là value của button với mục đích khi mình xử lý function call back có thể nhận biết được đang xử lý cho button nào EX: Như ví dụ phía trên, mình sẽ bung message confirm với button “Yes/NoThank”, thì khi function callback đc gọi thì mình sẽ detect đc vừa click button nào và bung alert cho từng button.

e. Định nghĩa các option của JqueryUI: https://www.tutorialspoint.com/jqueryui/jqueryui_dialog.htm

YesNothankButton.jpg

Dialog with button YesNoThanks

ClickNo.jpg

Click Button No

ClickYes.jpg

Click Button Yes

  1. Handle Close Dialog
  • Bạn ko muốn dung button default của dialog và dialog bắt buộc phải click 1 button nào đó trước khi Close? Muốn như vậy thì chúng ta sẽ update lại function MessageBox.Show() 1 xí
var MessageBox = {
    Show: function (message, caption, messageBoxButton, messageBoxIcon, functionCallback, closeable) {
		    if (closeable == null) closeable = true;
			.
			.
			.

        var result = $(div).dialog({
            title: caption,
            autoOpen: false,
            width: 'auto',
            height: 'auto',
            modal: true,
            fluid: true,
            resizable: false,
            draggable: false,
            buttons: buttons,
            closeOnEscape: closeable,
            open: function (event, ui) {
                $('.ui-dialog-titlebar').addClass('custom-header-dialog');
                if (!closeable) {
                    $(".ui-dialog-titlebar-close").hide();
                };

            },
            close: function () {
                MessageBox.Close();
                functionCallback(null);
            }
        });
        result.dialog('open');
    },
}

Đơn giản là chúng ta chỉ cần hide default Close Button của Dialog là xong, còn việc Close Dialog đã có function CallBack sẽ Close giúp rồi 😄

Về việc handle các button và Function call back chỉ đơn giản như vậy, tiếp đến là chúng ta thực hiện Responsive cho dialog, nếu dừng ở đây thì chúng ta sẽ gặp vấn đề là ko thể Responsive cho dialog đc. Mình cũng research và được Bác Google chỉ cho đoạn code.

// run function on all dialog opens
$(document).on("dialogopen", ".ui-dialog", function (event, ui) {
    fluidDialog();
});

function fluidDialog() {
    var $visible = $(".ui-dialog:visible");
    // each open dialog
    $visible.each(function () {
        var $this = $(this);

        //jquery <= 1.9
        var dialog = $this.find(".ui-dialog-content").data("dialog");
        //jquery > 1.9
        if (dialog == undefined)
        {
            dialog = $this.find(".ui-dialog-content").data("uiDialog");
        }
        if (dialog != undefined) {
            // if fluid option == true
            if (dialog.options.maxWidth && dialog.options.width) {
                // fix maxWidth bug
                $this.css("max-width", dialog.options.maxWidth);
                //reposition dialog
                dialog.option("position", dialog.options.position);
            }

            if (dialog.options.fluid) {
                // namespace window resize
                $(window).on("resize.responsive", function () {
                    //reposition dialog
                    dialog.option("position", dialog.options.position);
                });
            }
        }
    });
}

Với đoạn code trên khi mình resize màn hình thì Dialog sẽ tự động điều chỉnh vị trí cho đúng giữa màn hình và resize lại cho đúng với màn hình hiện tại.

Note

Bài viết hôm nay mình xin dừng ở đây, bài sau sẽ là 1 bài lien quan đến xử lý 1 số vấn đề lien quan đến Popup như

  • using JqueryUI to load Popup
  • add/Edit grid row on Popup
  • bung dialog before close Popup