0

我在下面有一个表格,其中包含一个文本框,并且在文本框旁边它包含一个称为“Open Grid”的超链接。如果用户单击此链接,则会打开一个网格,并在此网格上显示 3 到 26 的数字按钮。

<table id="optionAndAnswer" class="optionAndAnswer">
    <tr class="option">
    <td>1. Option Type:</td>
    <td>
    <div class="box">
        <input type="text" name="gridValues" class="gridTxt maxRow" id="mainGridTxt" readonly="readonly" />
        <span href="#" class="showGrid" id="showGridId">[Open Grid]</span>
    </div>


    <table class="optionTypeTbl">
    <tr>

        <tr><td><input type="button" value="3" id="btn3" name="btn3Name" class="gridBtns gridBtnsOff">

        <input type="button" value="4" id="btn4" name="btn4Name" class="gridBtns gridBtnsOff">
        <input type="button" value="5" id="btn5" name="btn5Name" class="gridBtns gridBtnsOff">
        <input type="button" value="6" id="btn6" name="btn6Name" class="gridBtns gridBtnsOff">

        //...goes all the way to btn26
            </tr>

            </table>

            </td>
    </tr>
</table>

现在,下面的代码能够触发其中一个网格按钮来声明单击了一个网格按钮。这段代码如下:

$('#btn'+gridValues).trigger('click');

现在上面的一切都很好。

问题:

我遇到的问题是用户可以添加一行,其中包含与顶部选项控件相同的模板。但在此选项和答案控件中,用户可以根据需要通过单击此模板中的一个网格按钮来更改选项类型。所以我的问题是我如何编写.trigger()正确指向此模板中的网格按钮?如果您查看上面的代码,它使用按钮的 id,但如果您查看下面的模板代码,它不包含 id,它只是将选项和控制功能从上面复制到模板中。

下面是模板:

function insertQuestion(form) {    

 var context = $('#optionAndAnswer');

    var $tbody = $('#qandatbl > tbody'); 
    var $tr = $("<tr class='optionAndAnswer' align='center'>");
    var $options = $("<div class='option'>Option Type:<br/></div>");
    var $questionType = '';

    $('.gridTxt', context).each( function() {

    var $this = $(this);
    var $optionsText = $("<input type='text' class='gridTxtRow maxRow' readonly='readonly' />")
    .attr('name',$this.attr('name')+"[]")
    .attr('value',$this.val())
    .appendTo( $options )
    .after("<span href='#' class='showGrid'>[Open Grid]</span>");

    $questionType = $this.val();

    });


    $td.append($options);
    $tbody.append($tr); 

}

更新:

我在这里为这个应用程序创建了一个 URL 。请按照步骤使用该应用程序,然后您可以看到发生了什么:

  • 步骤 1:当您打开应用程序时,您会在页面上看到一个绿色的加号按钮,单击它会显示一个模态窗口。
  • 第2步:在模态窗口有一个搜索栏,输入“AAA”并提交搜索,你会看到一堆行出现。
  • 第 3 步:在第一行中,您会在“选项类型”AD 下看到,单击该行中的“添加”按钮,模式窗口将关闭,您会在右侧的灰色文本框中看到“选项类型”文本框等于 4 并显示答案按钮 A、B、C 和 D,这是因为您记得该行的选项类型是“AD”。

现在这工作正常,但它只适用于顶部选项和答案控制,请按照以下步骤操作:

  • 第 4 步:单击“添加问题”按钮,它会在下方添加一行,其中包含选项的详细信息和顶部的答案控件。
  • 第5步:在您刚刚添加的行中,您会在左侧看到一个绿色的加号按钮,单击此按钮并在搜索框中执行相同的搜索“AAA”。
  • 第 6 步:这次通过单击“添加”按钮选择最后一行,该行的“选项类型”为“AG”,因此应显示“答案”按钮 A、B、C、D、E、F 和G,但它没有这样做,它仍然显示“A,B,C,D”。

那么如何在附加行之一中更改选项和答案控件中显示的答案按钮?

您在应用程序的视图源中看到的addwindow()功能是单击“添加”按钮后发生的功能。“添加”按钮位于包含的 PHP 脚本中,该按钮的代码如下所示,其中包含您在模式窗口中执行搜索后看到的所有列:

     echo "<table border='1' id='resulttbl'>
      <tr>
      <th class='questionth'>Question</th>
      <th class='optiontypeth'>Option Type</th>
      <th class='noofanswersth'>Number of <br/> Answers</th>
      <th class='answerth'>Answer</th>
      <th class='noofrepliesth'>Number of <br/> Replies</th>
      <th class='noofmarksth'>Number of <br/> Marks</th>
      </tr>";
      foreach ($searchResults as $key=>$question) {
        echo '<tr class="questiontd"><td>'.htmlspecialchars($question).'</td>';
        echo '<td class="optiontypetd">'.htmlspecialchars($searchOption[$key]).'</td>';
        echo '<td class="noofanswerstd">'.htmlspecialchars($searchNoofAnswers[$key]).'</td>';
        echo '<td class="answertd">'.htmlspecialchars($searchAnswer[$key]).'</td>';
        echo '<td class="noofrepliestd">'.htmlspecialchars($searchReply[$key]).'</td>';
        echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>';
        echo "<td class='addtd'><button type='button' class='add' onclick=\"parent.addwindow('$question','$searchMarks[$key]','$searchNoofAnswers[$key]','$searchOption[$key]','$searchReply[$key]','$searchAnswer[$key]');\">Add</button></td></tr>";
}
      echo "</table>";
4

1 回答 1

0

恐怕我一定是坏消息的传递者。您遇到的问题源于整体设计。您的 HTML 和 javascript 确实需要自下而上的大修,目的是让所有 javascript 进入单个 $(function(){...}) 结构,从而进入相同的范围。为此,您需要:

  • 在 javascript 中附加所有事件处理程序,以支持 HTML 属性方法(当前混合)。
  • 清除 iFrame 以通过 AJAX 获取以前的问题。

在此过程中,您还将清除一些重复的点击处理(加按钮 img 及其<a>...</a>包装)。

然后,您可以开始找到解决问题的方法:

  • 将与原始“选项和答案”块关联的所有事件处理委托给它和所有未来的“选项和答案”块通用的容器。公共容器可以是document但最好是更具体的东西。这似乎已经部分实现。
  • 确保原始“选项和答案”块中的所有内部引用都适用于类而不是 id。.closest()并且.find()在这里会很有用。
  • 单击“+”按钮时,存储对“选项和答案”块的引用(例如,表示其容器的 jQuery 对象,相对发现)。最简单的方法是将此引用存储在$(function(){...})范围内的变量中。(现在您正在从所有这些结构性变化中受益)。“添加”按钮的单击处理程序将使用此引用来影响正确的“选项和答案”块。
  • 在“添加问题”中,使用 jQuery.clone(true, true)制作原始块的副本(然后将克隆插入 DOM)。如果已应用其他修复,则所有功能(单击处理程序)将自动附加到克隆。

我工作得很快,但仍然需要 1-2 天。

以下是我将如何组织 javascript。

$(function() {
    // **********
    // Data area
    // **********
    var $$ = { // reusable static jQuery objects
        'optionTypeTbl': $('#optionTypeTbl'),
        'o_and_a_proto': $("#proto"),
        'o_and_a_extras': $("#extras"),
        'modal': $("#modal")
    },
    $o_and_a_section = null;

    // ******************
    // Utility functions
    // ******************
    function trim(str) {
        return str.replace(/(^\s*)|(\s*$)/gi, "") // removes leading and trailing spaces
            .replace(/[ ]{2,}/gi," ") // replaces multiple spaces with one space 
            .replace(/\n +/,"\n"); // Removes spaces after newlines
    }

    // ****************
    // Initial actions
    // ****************
    $$.modal.hide();
    $("input.gridBtns").removeClass("gridBtnsOn");
    $("input.answerBtns").removeClass("answerBtnsOn");
    $$.optionTypeTbl.hide();
    // code above makes sure all buttons start in the OFF state (so all button are white).

    // **********************************************
    // Handlers for elements inside the main window
    // **********************************************
    $(document).on('click', function() {
        $$.optionTypeTbl.fadeOut('slow');
    });
    $("input.gridBtns", $$.optionTypeTbl).on('click', function() {
        var $this = $(this);
        var $container = $this.closest('.optionAndAnswer');
        $container.find(".gridBtns").removeClass("gridBtnsOn");
        $this.addClass("gridBtnsOn");
        $container.find(".gridTxt").val($this.val());
        //$container.siblings('span[name=gridValues[]]').val($this.val()); // ???
        $container.find('.answerBtns').each(function(index) {
            if (index < Number($this.val())) {
                $(this).show();
            } else {
                $(this).hide();
            }
        });
    });
    $$.o_and_a_proto.find(".showGrid").on('click', function(e) {
        var $this = $(this);
        var $container = $this.closest(".optionAndAnswer");
        $("input.gridBtns").removeClass("gridBtnsOn");
        var value = $container.find(".gridTxt").val();
        //$("#btn" + value.replace(/\s/g, '')).addClass("gridBtnsOn"); //???
        $$.optionTypeTbl.appendTo($this.closest("div.box")).show().css({
            left: $this.position().left,
            top: $this.position().top + 20
        });
        e.stopPropagation();
    });
    $$.o_and_a_proto.find(".plusimage").on('click', function() {
        $o_and_a_section = $(this).closest(".optionAndAnswer");
        $$.modal.modal();
    });
    $$.o_and_a_proto.find(".answerBtns").on('click', function() {
        //btnclick(this); // ???
    });
    $("#addQuestionBtn").on('click', function insertQuestion() {
        $$.optionTypeTbl.hide().appendTo(document);//ensure this itinerant table is not cloned
        $$.o_and_a_extras.append($$.o_and_a_proto.clone(true,true).attr('id','')).find("span#plussignmsg").remove();
    });

    // **********************************************
    // Handlers for elements inside the modal window
    // **********************************************
    $$.modal.find("#close").on('click', function() {
        $.modal.close();
        return false;
    });
    $$.modal.find("form").on('submit', function() {
        var form = $(this).get(0);
        $.ajax({
            url: 'previousquestions.php',
            data: {
                'searchQuestion': 1,
                'questioncontent': trim(form.questioncontent.value)
            },
            type: "get",
            success: function(html) {
                $("#searchResults").html(html);
            },
            error: function() {
                alert("Something went wrong");
            }
        });
        return false;
    });

    $$.modal.find("#searchResults").on('click', 'button.add', function() {
        var $container = $(this).closest("tr");
        var g = $container.find("optiontypetd").data('g');
        var btn = $container.find("answertd").text();
        $o_and_a_section.find("input.gridTxt").val(g);
        if($o_and_a_section.closest("#detailsBlock").length) { //if is original Options and Answers section
            //do something ???
            //$('#btn'+g).trigger('click'); //???
        }
        $.modal.close();
    });
});

这在一定程度上可行,但请注意,它需要对 HTML 和 CSS 进行相关更改。

于 2012-07-09T12:12:21.373 回答