javascript - 实现模态工厂?

标签 javascript jquery html css

一段时间以来,我一直在使用模式作为一种方式,通过几种不同的前端框架与我的应用程序中的用户进行交流。逻辑通常是相同的,定义模态的 html,然后通过一些点击事件呈现它。

随着我的应用程序的增长,我用于用户提示或确认的模态数量也在增加 - 这些模态可以包含从文本输入到表单再到下拉列表等任何内容。

我目前的方法是在一个 html 文件中写出每个单独的模态,然后简单地通过它们的 ID 调用它们,但我觉得这是低效的,因为有很多重复的样板代码,所以我想知道最好的方法是动态创建模态,同时保持代码尽可能轻巧干净?

我一直在考虑类似“模态工厂”的东西,您可以在其中传递模态的内容以及高度、宽度、样式等。这是一个好方法吗?

感谢任何输入!

最佳答案

我为从服务器加载的 Forms/HTML Content 做的是创建一个带有 ID 的 div - PartialViewDialog 在我的页面末尾 -(我加载对话框内的部分 View )

这个是基于Bootstrap 3.*的——(基于Frontend框架的HTML结构

所以 HTML 是这样的:

<body>

<!-- Other page content -->


<div class="modal fade" id="PartialViewDialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" data-modal="title"></h4>
            </div>
            <div class="modal-body" data-modal="content">

            </div>
            <div class="modal-footer" data-modal="footer">
            </div>
        </div>
    </div>
</div>

</body>

然后在 JS 中,我创建了一个对话框管理器:

   var MyApp = MyApp || {};

MyApp.UIHelper = MyApp.UIHelper || {};

MyApp.UIHelper.DialogManager = (function () {

    "use strict";


    var self = {};
    self.divId = null;
    self.dialog = null;
    self.dialogBody = null;
    self.dialogTitle = null;
    self.dialogFooter = null;
    self.actionUrl = "";
    self.modalObject = null;
    self.options = {};

    function Initilize(divId, options) {

        self.options = $.extend({ buttons: [] }, options);
        self.divId = divId;
        self.dialog = $(self.divId);
        self.dialogBody = self.dialog.find('*[data-modal="content"]');
        self.dialogTitle = self.dialog.find('*[data-modal="title"]');
        self.dialogFooter = self.dialog.find('*[data-modal="footer"]');
        self.BootgridObject = null;
    };

    function OpenPartialViewDialog(url, title, preprocessingFunction, postProcessingFunction) {

        // Create the buttons
        var options = self.GetPartialViewButtons(url, preprocessingFunction, postProcessingFunction);

        // Initialise the PartialViewDialog with Buttons
        Initilize('#PartialViewDialog', options);

        // Set the URL for Ajax content load and Form Post
        self.actionUrl = url;

        // Set Dialog Title
        self.dialogTitle.html(title);

        // Open the PartialViewDialog
        self.OpenModel();
    };


    // This Method creates the buttons for the Form dialog
    // e.g Save, Cancel, Ok buttons
    self.GetPartialViewButtons = function (url, preprocessingFunction, postProcessingFunction) {

        // I only need Save and Cancel buttons always so I create them here
        var buttons = {
            buttons: {
        // I create a save button which Posts back the Form in the Dialog
                Save: {
                    Text: "Save",
                    css: "btn btn-success",
                    click: function () {

                        // Call a function before sending the Ajax request to submit form
                        if (preprocessingFunction) { preprocessingFunction(); }

                        $.ajax({
                            type: "POST",
                            url: url,
                            // This Dialog has a Form - which is Post back to server
                            data: self.dialogBody.find("form").serialize(),
                            success: function (response) {
                                // TODO: Check if response is success - 
                                // Apply your own logic here
                                if (response.hasOwnProperty("IsSuccess")) {

                                    if (response.IsSuccess) {
                                        self.dialogBody.html("");
                                        self.dialog.modal("hide");
                                        // TODO: Show Success Message
                                        // You can call another function if you want
                                        if (postProcessingFunction) {
                                            postProcessingFunction();
                                        }
                                    } else {
                                        // If failure show Error Message    
                                    }
                                } 
                            },
                            error: function (response) {
                               // If failure show Error Message 
                            }
                        });
                    }
                },
                Cancel: {
                    Text: "Cancel",
                    css: "btn btn-danger",
                    click: function () {
                        self.dialogBody.html("");
                        self.dialogFooter.html("");
                        self.dialogTitle.html("");
                        self.dialog.modal("hide");
                    }
                }
            }
        };
        return buttons;
    };


    // dynamic creating the button objects
    self.CreateButtonsHtml = function () {
        var htmlButtons = [];
        $.each(self.options.buttons, function (name, props) {
            var tempBtn = $("<button/>", {
                text: props.Text,
                id: "btn_" + props.Text,
                "class": props.css + "",
                click: props.click
            }).attr({ "style": "margin-right: 5px;" });

            htmlButtons.push(tempBtn);

        });
        return htmlButtons;
    };


    // This method will load the content/form from server and assign the modal body - it will assign the buttons to the Modal Footer and Open the Dialog for user
    self.OpenModel = function () {
        $.ajax({
            url: self.actionUrl,
            type: "GET",
            success: function (response) {          
                // Handle response from server - 
                // I send JSON object if there is Error in loading the content - otherwise the result is HTML           
                if (response.hasOwnProperty("HasErrors")) { 
                    // Means some error has occured loading the content - you will have to apply your own logic
                } else {

                    //Server return HTML - assign to the modal body HTML        
                    self.dialogBody.html(response);
                    self.modalObject = self.dialog.modal();
                    // show modal
                    self.modalObject.show();
                }
            }
        });

        // Create the buttons in the Dialog footer
        var buttons = self.CreateButtonsHtml();
        self.dialogFooter.html('');
        for (var i = 0; i < buttons.length; i++) {
            self.dialogFooter.append(buttons[i]);
        }
    };
    return {
        OpenPartialViewDialog: OpenPartialViewDialog,
    };

})();

然后每当我需要从服务器打开一个对话框时,我可以这样调用它:

MyApp.UIHelper.DialogManager
          .OpenPartialViewDialog('/Content/Load', "My Title", 
                          function(){alert('pre-process')}, 
                          function(){alert('post-process')}
                  );

注意:单击“保存”按钮时将调用 PreProcess + PostProcess

这是一个工作/演示示例,它显示了上述 JS 的作用 - 希望它有所帮助 在演示中,我从 div id="dummycontent"

加载虚拟 HTML

fiddle :https://jsfiddle.net/1L0eLazf/

按钮 fiddle :https://jsfiddle.net/1L0eLazf/1/

关于javascript - 实现模态工厂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39689584/

相关文章:

javascript - JS - 如何从按钮单击事件中找到特定元素标签以将其删除?

javascript - 克隆项目时,是否可以像这样更改所有输入属性和 ID?

javascript - jQuery 代码适用于 php 循环生成按钮的最后一次迭代

javascript - 如何在 jQuery 函数中使用列表中选定的值?

javascript - 按标签名称向所有文档子级添加事件监听器

javascript - 我如何使用 jQuery 从搜索表单中删除空格?

javascript - DOM 更改后如何初始化 x-editable?

javascript - 如何从数组中提取子文档?

javascript - 屏蔽没有 type=password 的输入字符

javascript - MaterializeCSS 多选不工作