如何为模板编写.trigger()代码?

时间:2012-07-08 23:32:07

标签: javascript jquery

我下面有一个表格,其中包含一个文本框,在文本框旁边,它包含一个称为“打开网格”的超链接。如果用户点击此链接,它将打开一个网格,并在此网格上显示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,它只是将选项和控件功能从上面复制到模板中。 / p>

以下是模板:

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); 

}

更新:

我已为此应用here创建了一个网址。请按照步骤使用该应用程序,然后您可以看到发生了什么:

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

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

  • 第4步:点击“添加问题”按钮,它会在下方添加一行 包含选项和答案控件的详细信息。
  • 第5步:在刚刚添加的行中,您会看到绿色加号 左侧的按钮,单击此按钮并执行相同的操作 在搜索框中搜索“AAA”。
  • 第6步:这次选择最后一行,点击“添加” 按钮,此行的“选项类型”为“A-G”,因此应显示 “答案”按钮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>";

1 个答案:

答案 0 :(得分: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进行相关更改。