如何切换单行标记内输入的可见性

时间:2017-08-30 15:59:34

标签: javascript jquery html razor

我有一个LINQ语句,它将多条记录传递回视图。对于我生成的每条记录,我需要一个可点击的按钮,该按钮将仅为该行切换日期字段的可见性。请看截图。第一个工作正常,但其余的不适合;什么是适用于每一行的更好的解决方案,无论是1行还是100行?

enter image description here

剃刀/ HTML

<td>
  <a id="actionOnUserButton" class="toggle" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Show exclusion dates"><span id="userActionSpan" class="actionBtn GlyphSize glyphicon glyphicon-plus-sign"></span></a>
  <a id="actionOnUserButton2" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Hide exclusion dates"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-minus-sign"></span></a>
</td>
<td id="StartDateField">
  <div class="input-group">
    <span title="Select Start Date" class="input-group-addon" id="basic-addon1"><a class="glyphicon glyphicon-calendar"></a></span> @Html.EditorFor(modelItem => x.StartDate, "", new { htmlAttributes = new { @class = "form-control datepicker", @id = "UStartDateField",
    @style = "width:120px" } })
  </div>
</td>
<td id="EndDateField">
  <div class="input-group">
    <span title="Select End Date" class="input-group-addon" id="basic-addon1"><a class="glyphicon glyphicon-calendar"></a></span> @Html.EditorFor(modelItem => x.EndDate, "", new { htmlAttributes = new { @class = "form-control datepicker", @id = "UEndDateField",
    @style = "width:120px" } })
  </div>
</td>
<td>
  <a id="actionOnUserButtonSave" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Save changes" class="saveBtn"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-ok-sign green"></span></a>
  <a id="actionOnUserButtonCancel" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Cancel changes" class="canelBtn"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-remove-sign red"></span></a>
</td>
</tr>
<td>
  <a id="actionOnUserButton" class="toggle" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Show exclusion dates"><span id="userActionSpan" class="actionBtn GlyphSize glyphicon glyphicon-plus-sign"></span></a>
  <a id="actionOnUserButton2" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Hide exclusion dates"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-minus-sign"></span></a>
</td>
<td id="StartDateField">
  <div class="input-group">
    <span title="Select Start Date" class="input-group-addon" id="basic-addon1"><a class="glyphicon glyphicon-calendar"></a></span> @Html.EditorFor(modelItem => x.StartDate, "", new { htmlAttributes = new { @class = "form-control datepicker", @id = "UStartDateField",
    @style = "width:120px" } })
  </div>
</td>
<td id="EndDateField">
  <div class="input-group">
    <span title="Select End Date" class="input-group-addon" id="basic-addon1"><a class="glyphicon glyphicon-calendar"></a></span> @Html.EditorFor(modelItem => x.EndDate, "", new { htmlAttributes = new { @class = "form-control datepicker", @id = "UEndDateField",
    @style = "width:120px" } })
  </div>
</td>
<td>
  <a id="actionOnUserButtonSave" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Save changes" class="saveBtn"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-ok-sign green"></span></a>
  <a id="actionOnUserButtonCancel" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Cancel changes" class="canelBtn"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-remove-sign red"></span></a>
</td>
</tr>

Jquery的:

$(document).ready(
   function () {
       $("#StartDateHeader").hide()
       $("#EndDateHeader").hide()
       $("#StartDateField").hide()
       $("#EndDateField").hide()
       $('#actionOnUserButton2').hide()
       $("#actionOnUserButtonCancel").hide()
       $("#actionOnUserButtonSave").hide()
   });

  $("#actionOnUserButton").on('click', function () {


    if ($('#StartDateHeader').not(':visible')) {
        //Show the date headers
        $("#StartDateHeader").show()
        $("#EndDateHeader").show()
        $("#StartDateField").show()
        $("#EndDateField").show()
        $('#actionOnUserButton2').show()
        $('#actionOnUserButton').hide()
        $("#actionOnUserButtonCancel").show()
        $("#actionOnUserButtonSave").show()
    }
});

$("#actionOnUserButton2").on('click', function () {
    if ($('#StartDateHeader').is(':visible')) {

        $("#StartDateHeader").hide()
        $("#EndDateHeader").hide()
        $("#StartDateField").hide().val('')
        $("#EndDateField").hide()
        $('#actionOnUserButton2').hide()
        $("#actionOnUserButtonCancel").hide()
        $("#actionOnUserButtonSave").hide()
        $('#actionOnUserButton').show()
    }
});

2 个答案:

答案 0 :(得分:2)

@ click2install答案很棒。您还可以将数据属性附加到元素,以通过点击事件传递数据。如果您通过剃刀重复这些字段,则可以为将要/应该是唯一的元素分配某种ID。

 <td> <a class="btn btn-sm btn-success hidestuff" href="#" id="@Model.RandomId" data-randomid="@Model.RandomId"> </td>

$('.hidestuff').click(function () {

    var elemId = $(this).data('randomid');
//With this you have a reference to the actual element clicked, even though 
it's a razor generated value.
 $('#'+elemId).hide();

});

答案 1 :(得分:1)

您遇到的一个问题是页面上有多个相同的元素ID。 Id每页应该是全球唯一的。对于DOM选择,使用类并将结果集合过滤到您想要的那个,或者使选择器更具体。

如果要在Razor视图中生成它,可以在click上放置一个函数,将其自身的引用(a元素)传递给找到正确兄弟的函数。您正在进行最小的DOM遍历,而不是在加载时连接许多jQuery事件触发器。

这样的事情(但不能让这个函数成为全局函数)应该这样做:

<tr>
  ...
  <td>
    <a href="#" onclick="toggleRow(this, 'add');">text</a>
    <a href="#" onclick="toggleRow(this, 'delete');">text</a>
  </td>
    ...
  <td class="date-field">
    ...
  </td>
  <td class="date-field">
    ...
  </td>
  ... 
</tr>

function toggleRow(a, state)
{
  var a = $(a);
  var td = a.closest('td');
  // toggle the date selectors
  a.closest('td').siblings('.date-field').find('> div').toggle();

  var tr = a.closest('tr');
  // toggle the checkboxs on right of row
  tr.find('a.saveBtn').toggle();
  tr.find('a.canelBtn').toggle();

  // toggle the a elements that trigger this event
  var selector = (state == 'add') ? ':first' : ':last';
  td.find('a' + selector).toggle();      
}

如果你不喜欢onclick的想法,你仍然可以连接你的jQuery事件处理程序,并根据event.currentTarget(作为a元素)执行类似的逻辑。 jQuery单击事件处理程序。您仍然需要对HTML进行一些小的更改,以便按类识别a元素(+, - ),您可以使用data-on/off来决定点击哪一个,并且jQuery JS会非常类似于上面的代码。

修改
上面的代码是一个有点讨厌的IMO,容易破碎。通过对HTML进行一些小的更改,如果您开始在其父元素中移动元素,代码可能会更加简单并且不会中断:

对HTML的更改

<!-- add classes to the a tags -->
<a id="actionOnUserButton" class="toggle-show" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Show exclusion dates"><span id="userActionSpan" class="actionBtn GlyphSize glyphicon glyphicon-plus-sign"></span></a>
<a id="actionOnUserButton2" class="toggle-hide" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Hide exclusion dates"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-minus-sign"></span></a>

<!-- wrapped the a tags in the .input-group div -->
<td>
  <div class="input-group">
    <a id="actionOnUserButtonSave" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Save changes" class="saveBtn"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-ok-sign green"></span></a>
    <a id="actionOnUserButtonCancel" type="checkbox" data-toggle="toggle" data-on="Cancel" data-off="Set Exception" href="#" title="Cancel changes" class="canelBtn"><span id="userActionSpan" class="GlyphSize glyphicon glyphicon-remove-sign red"></span></a>
  </div>
</td>

试试这段代码

$(function()
{    
  function toggleControls(elem, toggler)
  {    
    // hide the button that fired the event
    var a = $(elem).hide();

    // hide or show the controls
    var func = (toggler == 'hide') ? 'hide' : 'show'; 
    // the line above is not essential but decouples the css class from the jQuery function name
    a.closest('tr').find('.input-group')[func]();

    // show the opposite button so it can be clicked to reverse the hide/show state
    var selector = (toggler == 'hide') ? 'show' : 'hide';
    a.closest('td').find('.toggle-' + selector).show();
  }

  $('a.toggle-hide').on('click', function()
  {
    toggleControls(this, 'hide');
  });

  $('a.toggle-show').on('click', function()
  {
    toggleControls(this, 'show');
  });

  // initially hide the controls, this would be better done with CSS on page load so the row doesn't show then hide on slow connections 
  $('a.toggle-hide').click();
});