jQuery 使用新的下拉菜单项创建对话框(任何类型)(包括 AJAX 请求)

jQuery dialog(any type) creation with new dropdown menu items (includes AJAX request)

我想创建一个 dialog box containing dropdown menu's。将弹出此对话框on a button click event in jQuery。我之前没有任何 HTML 内容,所以,这将是即时的。 All the dropdown items will be predefined/hard-coded。到目前为止,我已经写了这个:

$(document).ready(
    function() {
        var button = $('<div class="toolbar content-header-toolbar"><a href="javascript:void(0)">Start Job</a></div>');

        $("a", button).click(
            function()
            {
                $('<div></div>').dialog({
                            modal: true,
                             title: "Confirmation",
                            open: function() {
                            var markup = 'USER SELECTION';
                            $(this).html(markup);
                    },
                    buttons: {
                            Ok: function() {
                             $( this ).dialog( "close" );
                            }
                            }
                    }); 
               }
        );  
    }
);

这给了我一个带有标题 USER SELECTION 和按钮 OK to close the dialog box.

的对话框

我怎么create dropdown menus in such a dialog box? 再一次,我do not have any HTML之前的内容。我还想填写下拉列表,写在代码中,因为它们将被预定义。例如,一个下拉列表将是 user profile,其中包含 profile 1, profile 2 or profile 3 as their selection.

预期输出如下所示:

上面的预期输出图像显示了 3 个下拉菜单 SELECT A JOBTEST PROFILEEXPERIMENTS。然后,用户将为这些菜单设置 select 值,并在需要时点击 RUN 按钮。

用户点击 RUN 按钮后,如何发送 dropdown selected data via an AJAX request? (也许像下面这样的东西会起作用?):

$.ajax({        
            url: 'something.php',
            data: {...dropdown data...}
            type: 'post',             
            success: function(response) {}
});

不是jQuery、JS/AJAX的专家,一个好的例子会有帮助。

首先,我重新创建了您的原始示例:https://jsfiddle.net/Twisty/6150mygp/

$(document).ready(function() {
  var toolbar = $("<div>", {
    class: "toolbar content-header-toolbar",
  })
  var button = $("<a>", {
      href: "#"
    })
    .html("Start Job")
    .click(function() {
      var dlg = $("<div>", {
        id: "menuDialog"
      }).dialog({
        modal: true,
        title: "Confirmation",
        open: function() {
          var markup = 'USER SELECTION';
          $(this).html(markup);
        },
        buttons: {
          Ok: function() {
            $(this).dialog("close");
          }
        }
      });
    }).appendTo(toolbar);
  toolbar.appendTo("body");
});

这为我们提供了一个工作按钮,该按钮启动了正确的对话框。

接下来我们需要制作初始菜单 Header 链接。这些将取消隐藏菜单,以便用户可以进行选择。

我们现在可以看到菜单,还有一些工作要做:https://jsfiddle.net/Twisty/6150mygp/2/

$(document).ready(function() {
  var toolbar = $("<div>", {
    class: "toolbar content-header-toolbar",
  });
  var button = $("<a>", {
      href: "#"
    })
    .html("Start Job")
    .click(function() {
      var dlg = $("<div>", {
        id: "menuDialog"
      }).dialog({
        modal: true,
        title: "Confirmation",
        open: function() {
          var markup = '<span style="display: block; width: 100%; text-align: center" class="title">USER SELECTION</span>';
          var topMenu = $("<ul>", {
            id: "topMenu",
            style: "margin: 0;"
          });
          topMenu.append("<li data-menu='job'><a href='#'>SELECT A JOB</a></li><li data-menu='profile'><a href='#'>TEST PROFILE</a></li><li data-menu='exp'><a href='#'>EXPERIMENTS</a></li>");
          topMenu.find("li a").on("click", function() {
            var selection = $(this).data("menu");
            console.log("Clicked " + selection);
          });
          markup += '<style>#topMenu li { display: inline-block; width: 33%; list-style: none;} .ui-menu { width: 150px; } ul.subMenu { display: hidden; }</style>';
          markup += topMenu.prop('outerHTML');
          var jobMenu = $("<ul>", {
              class: "subMenu"
            }),
            proMenu = jobMenu.clone(),
            expMenu = jobMenu.clone();
          jobMenu.attr("id", "jobMenu")
            .css({
              width: "33%",
              display: "inline-block"
            })
            .append("<li>Android Phone</li><li>iOS Phone</li><li>iOS Tablet</li>")
            .menu();
          proMenu.attr("id", "proMenu")
            .css({
              width: "33%",
              display: "inline-block"
            })
            .append("<li>Profile 1</li><li>Profile 2</li><li>Profile 3</li>")
            .menu();
          expMenu.attr("id", "expMenu")
            .css({
              width: "33%",
              display: "inline-block"
            })
            .append("<li>Experiment 1</li><li>Experiment 2</li><li>Experiment 3</li>")
            .menu();
          $(this).html(markup).append(jobMenu, proMenu, expMenu);
        },
        buttons: {
          Ok: function() {
            $(this).dialog("close");
          }
        },
        width: "640"
      }).css("font-size", "85%");
      return false;
    })
    .appendTo(toolbar);
  toolbar.appendTo("body");
  $("body").find("#topMenu li").on("click", function() {
    var selection = $(this).data("menu");
    console.log("Clicked " + selection);
  });
});

你没有提到是否可以使用 CSS,所以我避免了这一点,也避免了任何初始 HTML。如您所见,在 jQuery 中构建元素、为它们分配 UI,然后附加它们更容易。由于我们在加载时没有 DOM,这允许我们分配所需的各种代码和结构。

以下代码仍有一些问题需要您自行修复或调整。工作示例:https://jsfiddle.net/Twisty/6150mygp/4/

jQuery

function showMenu(m, o) {
  $(".subMenu").hide();
  console.log("Showing #" + m + "Menu");
  console.log("Setting #" + m + "Menu position to: { my: 'left top', at: 'right top', of: '#" + o + "' }");
  $("#" + m + "Menu").menu({
    position: {
      my: "left top",
      at: "right top",
      of: "#" + o
    }
  }).show();
}

function enableRun() {
  if (Object.keys(jobOptions).length === 3) {
    console.log("All options set. ", jobOptions);
    $("#run").prop("disabled", false).removeClass("ui-state-disabled");
  }
}
var jobOptions = {};
$(document).ready(function() {
  var toolbar = $("<div>", {
    class: "toolbar content-header-toolbar",
  });
  var button = $("<a>", {
      href: "#"
    })
    .html("Start Job")
    .click(function() {
      var dlg = $("<div>", {
        id: "menuDialog"
      }).dialog({
        modal: true,
        title: "Confirmation",
        open: function() {
          var markup = '<span style="display: block; width: 100%; text-align: center" class="title">USER SELECTION</span>';
          var topMenu = $("<ul>", {
            id: "topMenu",
          });
          var ml1 = $("<li>", {
              'data-menu': ''
            }),
            ml2 = ml1.clone(),
            ml3 = ml1.clone();
          ml1.html("SELECT A JOB").attr("data-menu", "job").appendTo(topMenu);
          ml2.html("TEST PROFILE").attr("data-menu", "pro").appendTo(topMenu);
          ml3.html("EXPERIMENTS").attr("data-menu", "exp").appendTo(topMenu);
          topMenu.menu({
            select: function(e, ui) {
              console.log("#topMenu Item Selected.");
              showMenu(ui.item.data("menu"));
            }
          });
          markup += '<style>#topMenu { width: 480px; margin: 10px auto; }\r\n#topMenu li { display: inline-block; width: 138px; list-style: none;}\r\n#jobMenu li, #proMenu li, #expMenu li { padding-left: 20px; }</style>';
          markup += topMenu.prop('outerHTML');
          var jobMenu = $("<ul>", {
              class: "subMenu"
            }),
            proMenu = jobMenu.clone(),
            expMenu = jobMenu.clone();
          jobMenu.attr("id", "jobMenu")
            .append("<li>Android Phone</li><li>iOS Phone</li><li>iOS Tablet</li>")
            .menu({
              select: function(e, ui) {
                ui.item.append("<span class='ui-icon ui-icon-check'></span>");
                jobOptions['job'] = ui.item.text();
                enableRun();
              }
            });
          proMenu.attr("id", "proMenu")
            .append("<li>Profile 1</li><li>Profile 2</li><li>Profile 3</li>")
            .menu({
              select: function(e, ui) {
                ui.item.append("<span class='ui-icon ui-icon-check'></span>");
                jobOptions['profile'] = ui.item.text();
                enableRun();
              }
            });
          expMenu.attr("id", "expMenu")
            .append("<li>Experiment 1</li><li>Experiment 2</li><li>Experiment 3</li>")
            .menu({
              select: function(e, ui) {
                ui.item.append("<span class='ui-icon ui-icon-check'></span>");
                jobOptions['experiment'] = ui.item.text();
                enableRun();
              }
            });
          jobMenu.hide();
          proMenu.hide();
          expMenu.hide();
          $(this).html(markup).append(jobMenu, proMenu, expMenu);
        },
        buttons: [{
          id: "run",
          text: "Run",
          class: "ui-state-disabled",
          disabled: true,
          click: function() {
            $.ajax({
              url: 'something.php',
              data: jobOptions,
              type: 'post',
              success: function(response) {
                alert("Job is running.");
              }
            });
          }
        }, {
          id: "cancel",
          text: "Cancel",
          click: function() {
            $(this).dialog("close");
          }
        }],
        width: "640"
      }).css("font-size", "85%");
      return false;
    })
    .appendTo(toolbar);
  toolbar.appendTo("body");
  $("body").on("click", "ul#topMenu li", function() {
    var selection = $(this).data("menu");
    console.log("Clicked " + selection);
    showMenu(selection, $(this).attr("id"));
  });
  $(":button:contains('Run')").prop("disabled", true).addClass("ui-state-disable");
});

我们现在在脚本中进行了很多操作。 showMenu() 显示我们从 #topMenu 中选择的菜单。它通过首先隐藏所有菜单然后只显示我们正在使用的菜单来实现这一点。

我将 运行 按钮设置为禁用,直到我们有足够的设置。 enableRun() 检查 jobOptions object 中是否有 3 个键,如果有则启用 运行 按钮。

当运行最终被点击并执行时,这可以使用收集到的数据object执行AJAX。您的 PHP 脚本将在 post 中收到它,您可以像这样访问它们:

$j = $_POST['job'];
$p = $_POST['profile'];
$e = $_POST['experiment'];

据我所知,这可以满足您的所有需求。使用手头已有的 HTML 布局会容易得多。在我看来,它使设置选项变得更加容易。此外,我怀疑如果您通过 jQuery 构建了所有元素并且没有通过 html()append() 对任何 HTML 进行硬编码,您将能够用更少的代码绘制它代码。我怀疑这也不是唯一的方法。

如有疑问,请在评论中告诉我。