65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ThemeRollers 的 jQuery UI 警告对话框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (12投票s)

2011年12月5日

MIT

7分钟阅读

viewsIcon

73731

downloadIcon

1361

使用 jQuery UI 提示框替代 JavaScript 默认提示框 (alert, confirm, prompt)

引言

通过使用 jQuery 和 jQuery UI,我获得了各种性能和视觉上的改进。因此,当涉及到基于对话框的提示时,我知道我绝对不会使用老旧的 JavaScript 默认提示框。我已经看到了几种不同的选择,并且似乎每个人都有自己的风格。

我甚至还在 Code Project 上找到了这篇非常棒的文章 这里,讨论了一个可用于创建提示框的 jQuery 插件。

然而,我的需求非常具体,我真的很想完全按照自己的方式来做。因此,考虑到所有这些,我想要一些能够处理以下问题的东西:

  • 支持 jQuery UI 和 ThemeRoller;我想确保网站保持相同的外观和感觉。
  • 基本的对话框提示,可以替代 JavaScript 的 alert()
  • 提示框还需要扩展支持,以显示来自 $.ajax() 的错误异常。

第三个要求对我来说尤为重要,因为我想能够显示来自导致错误的 $.ajax() 请求的异常信息。

$.ajax({
    type: 'POST',
    url: 'url/someService.asmx',
    data: '',
    contentType: '',
    dataType: '',
    success: function(msg) { // do some stuff },
    error: function (request, status, error) {
        var info = $.parseJSON(request.responseText);

        // info should have all kinds of information in it, that I want to display
        // info.Message
        // info.ExceptionType
        // info.StackTrace
    }
});

背景

我之前写了一篇关于开发 自适应 960 网格系统的 jQuery 插件的文章,其中涵盖的一些概念将有助于理解创建对话框背后的代码。然而,在这篇文章中,解决方案将是 jQuery *工具函数*,它们不需要 HTML 元素即可运行。

基础知识

让我们来看看我们将要使用的函数容器的基本框架。

(function($) {
    if ($.ui) {
        // our code will go here
    }
})(jQuery);

与之前的插件一样,初始布局相当简单。第一行和最后一行将使我们的未来函数能够访问 jQuery。由于我们的*工具函数*依赖于 jQuery UI 的存在,所以 if ($.ui) 语句用于确保它已经被加载。

开发中的个人习惯

在我绝大多数(99%)的开发中,我使用 Visual Studio,并且我了解到智能感知会在让我想知道一切都已正确编码以加载方面起到一部分作用。

我还遵循一种习惯,将库等加载到文档的 head 中,然后将页面代码放在底部,紧靠 body 标签的闭合标签之前。对于那些会发生大量文档渲染的大型页面,我会通过代码控制 body 的可见性,以消除文档中的*闪烁*。

代码

引用我儿子最喜欢的电影中的不朽之言——“那么,我们开始吧!”。

警告、确认和提示

回到基础

让我们回顾一下我们的对话框函数将接收什么以及它们需要什么才能运行。

$.alert = function(message, options)

相当简单明了。

我们知道任何消息对话框的基本要求是向用户显示一条消息。好的,这就通过将接收到的第一个参数定义为将要显示的 message 来解决了。我们可以就此止步,但是如何更改对话框的标题,添加按钮以及它们的通知,多种消息类型,或者那些酷炫的消息类型图标呢?

我相信你明白我的意思,另外,如果你还记得我最初的要求之一是我想支持显示来自 $.ajax() 调用的异常信息。

选项,更多显示内容的控制

因此,我没有创建一个带有不同参数的函数,而是选择了提供一个对象来传递 options,每个函数都可以使用它。为了保持消息对话框有时只需显示一条消息的简单主题,我们将使 options 成为一个可选参数。

为了处理这个问题,我们需要创建一组 defaultOptions 供我们的函数使用。

var defaultOptions = {
    title: 'Alert', // Information displayed in the title bar
    icon: 'alert',  // message type icon, just use the jquery ui icons
    buttons: { "Ok": function() { $(this).dialog("close"); } }
};

好的,那么基本默认选项将是:

  • title:这是将显示在对话框标题栏中的 string
  • icon:消息类型图标;我选择使用 jQuery UI 图标,并将取 ui-icon- 后面的部分。
  • buttons:一个按钮名称数组以及每个按钮的相应函数。

对于 alert 和 prompt 对话框,我添加了以下默认选项:

  • exception:一个将要显示的 string,代表收到的异常。
  • stack:一个 string,代表伴随异常信息的堆栈跟踪。
  • defaultResult:一个 string,代表在提示输入信息时显示的默认值。

定义了所有默认选项后,我们将添加代码来处理开发人员更改或*覆盖*这些选项的事件。

if (options) {
    defaultOptions = $.extend(defaultOptions, options);
}

如果我们收到一组选项,我们将使用 jQuery 的 $.extend() 函数来更新 defaultOptions

构建对话框

所需的布局已经由 jQuery UI - Dialog 为我们定义了,所以我们只需要围绕这些要求编写代码。

var $dialog = $('#confirmDialog');
$dialog.remove();

$dialog = $("<div id='confirmDialog' style='display:hidden' title='" + 
		defaultOptions.title + "'></div>").appendTo('body');

$('#confirmMessage').remove();
$("<p id='confirmMessage'><span class='ui-icon ui-icon-" + 
defaultOptions.icon + "' style='float:left; margin:5px 10px 20px 0;'>
</span>" + message + "</p>").appendTo('#confirmDialog');

首先,为了方便多次使用,缩短 $('#confirmDialog')。然后,使用 jQuery 的 .remove() 函数,删除可能由先前调用存在的任何元素。

接下来,构建实际包含对话框的 div,将其显示设置为隐藏,并添加来自 defaultOptions.title 的标题信息,然后使用 .appendTo() 将其添加到 body

最后一步是构建将包含 defaultOptions.icon 消息类型图标以及将要显示给用户的 message 的段落 (p)。

您会注意到添加了 $('#confirmMessage').remove();,技术上来说,这些元素应该在为 $dialog 所做的 .remove() 调用中被删除。我添加这段代码只是为了让事情更易读。

显示对话框

所以,在所有东西都构建好之后,最后一步就是实际将其显示给用户。幸运的是,对于将 HTML 信息显示为对话框的大部分工作,jQuery UI Dialog 控件已经为我们处理好了。

$dialog.dialog({
    resizable: false,
    height: 'auto',
    width: 'auto',
    modal: true,
    buttons: defaultOptions.buttons
});
  • resizable - 像我见过的绝大多数消息对话框一样,用户不能也无需调整它们的大小。
  • heightwidth - 将其设置为 auto,以便对话框能够动态调整对话框的大小。
  • modal - 当我们的对话框显示时,我们不希望用户与页面上的其他部分进行交互。
  • buttons - 这是按钮和它们的回调函数的数组,这些函数最初是被提供的。

我们只有在处理带有异常信息,尤其是堆栈跟踪信息的 $.alert() 对话框时,才会偏离上述设置。由于一些堆栈跟踪可能很长并包含大量信息,我选择在这种情况下将 width 限制在最大 960px。

Using the Code

那么,让我们快速概览一下如何使用这一切。如果你还没有下载源代码,那么现在是时候了。它附带了一个示例页面,提供了所有消息对话框的完整演示以及如何使用它们。

警告框

简单警告

$.alert('Message to be displayed to user.');

更高级的警告

$.alert('Message to be displayed to user', {
    title: 'Alert Title',
    icon: 'alert',
    buttons: { 'Ok': function() {
        // make sure we always add this line in our handlers
        $(this).dialog("close");
    } }
});

这里的大部分内容我们都已经涵盖了,除了当按钮被按下时处理程序的内部内容。所有这些都需要代码来实际关闭对话框。无论你希望这段代码是第一个执行还是最后一个执行,完全取决于你如何使用对话框。但是,重要的是要注意,如果没有这一行代码,对话框将永远不会关闭。

确认框

简单确认

$.confirm('Confirmation message to be displayed to user.');

高级确认

$.confirm('Confirmation message to be displayed to user.', {
    title: 'Confirmation Title',
    icon: 'help',
    buttons: {
        "Yes": function() {
            // make sure we always add this line in our handlers
            $(this).dialog("close");
        },
        "No": function() {
            // make sure we always add this line in our handlers
            $(this).dialog("close");
        },
        Cancel: function() {
            // make sure we always add this line in our handlers
            $(this).dialog("close");
        }
    } }
});

提示框

简单提示

$.prompt('Question to be displayed to user.');

高级提示

$.prompt('Question to be displayed to user.', {
    title: 'Prompt Title',
    icon: 'help',
    defaultResult: 'Default response message',
    buttons: {
        "Ok": function() {
            // result value is stored in this.all.result.value

            // make sure we always add this line in our handlers
            $(this).dialog("close");
        },
        Cancel: function() {
            // make sure we always add this line in our handlers
            $(this).dialog("close");
        }
    }
});

好的,那么按钮处理程序和消息对话框很好,但是那些你期望有输入的呢?当然,在提示框的情况下,用户将输入某个值,这很重要。在返回处理程序中,你将访问 this 对象,并且其中包含各种有用的信息。

你将通过以下代码片段找到用户输入的输入结果。

this.all.result.value

关注点

查看 jQuery UI,了解它提供的其他功能。也花点时间看看 ThemeRoller

历史

  • 2011年12月4日:初始版本
  • 查看关于此主题的下一篇文章 这里。 
© . All rights reserved.