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

Posted

技术标签:

【中文标题】使用新的下拉菜单项创建 jQuery 对话框(任何类型)(包括 AJAX 请求)【英文标题】:jQuery dialog(any type) creation with new dropdown menu items (includes AJAX request) 【发布时间】:2016-10-04 23:11:00 【问题描述】:

我想创建一个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。然后,用户将为这些菜单选择值并在需要时点击RUN 按钮。

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

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

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

【问题讨论】:

【参考方案1】:

首先,我重新创建了您的原始示例: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");
);

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

接下来我们需要创建初始菜单标题链接。这些将取消隐藏菜单,以便用户进行选择。

这里的菜单是可见的,还有一些工作要做: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 对象中是否有 3 个键,如果有则启用“运行”按钮。

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

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

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

如果您有任何问题,请在 cmets 中告诉我。

【讨论】:

这绝对回答了我的问题,也是我学习的一个很好的例子。但是,看起来我想使用这个脚本的地方不支持某些东西,所以我无法获得某些下拉菜单。如果我们可以聊天,我可以分享我尝试使用此脚本的工具的凭据,并为您提供一个示例 - 这可能会对我们有所帮助。 @PratikJaiswal 很高兴。 Twisty 和我花了将近一天的时间来让这个脚本在我的外部工具上运行。很棒的学习,他让我解决了问题!

以上是关于使用新的下拉菜单项创建 jQuery 对话框(任何类型)(包括 AJAX 请求)的主要内容,如果未能解决你的问题,请参考以下文章

下拉菜单项中的 jquery 滑块导致太多事件

React Material UI 中的下拉菜单项

下拉菜单在第一页加载时出现延迟

使用 Angular 在按钮单击时添加新的下拉菜单

kivyMD:如何使用工具栏操作项创建下拉菜单?

每个选项下拉项显示不同的内容