简体   繁体   English

如何在其中切换输入的可见性 <td> 单行标签

[英]How to toggle visibility of inputs within <td> tags on a single row

I have a LINQ statement that passes multiple records back to the view. 我有一个LINQ语句,它将多个记录传递回视图。 For each record I'm generating, I need a clickable button that will toggle the visibility of datefields only for that row. 对于我生成的每个记录,我需要一个可单击的按钮,该按钮将仅切换该行的日期字段的可见性。 Please see screenshot. 请看截图。 First one works properly, but the remaining ones don't; 第一个可以正常工作,而其余的则不能。 What is better solution that will work for each row return whether its 1 row or 100 rows? 有什么更好的解决方案将对每行返回1行还是100行有效?

在此处输入图片说明

Razor/Html 剃刀/ 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: 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()
    }
});

@click2install answer is great. @ click2install答案很好。 You could also attach a data -property to your elements to pass data through your click events. 您还可以在元素上附加数据属性,以通过点击事件传递数据。 If you're repeating these fields via razor, you could assign some sort of ID to the elements that will/should be unique. 如果要通过剃刀重复这些字段,则可以为将/应该是唯一的元素分配某种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();

});

One of the problems you have is multiple same element ids on the page. 您遇到的问题之一是页面上有多个相同的元素ID。 Id's should be globally unique per page. 每页的ID应该是全局唯一的。 For DOM selection use class and filter the result collection to the one you want, or make the selector more specific. 对于DOM选择,请使用class并将结果集合过滤到所需的集合,或者使选择器更加具体。

If you are generating this in a Razor view, you can put a function on click that passes a reference of itself (the a element) to the function which finds the correct siblings. 如果要在Razor视图中生成此函数,则可以在单击时放置一个函数,该函数会将自身(a元素)的引用传递给找到正确同级的函数。 You are doing minimal DOM traversal then and not connecting many jQuery event triggers on load. 然后,您正在执行最小的DOM遍历,并且未在加载时连接许多jQuery事件触发器。

Something like this (but not making the function a global) should do it: 这样的事情(但不要使函数成为全局函数)应该做到这一点:

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

If you don't like the onclick idea, you can still connect your jQuery event handlers and perform similar logic based on the event.currentTarget (being the a element) in the jQuery click event handler. 如果您不喜欢onclick想法,您仍然可以连接jQuery事件处理程序,并基于jQuery click事件处理程序中的event.currentTarget (是a元素)执行类似的逻辑。 You would still need some small changes to your HTML to identify the a elements (+, -) by class and you could use the data-on/off to decide which one was clicked, and the jQuery JS would be very similar to the code above. 您仍然需要对HTML进行一些小的更改以按类识别a元素(+,-),并且可以使用data-on/off来决定单击哪个元素,并且jQuery JS与代码非常相似。以上。

EDIT 编辑
The code above is a little nasty IMO and prone to easy breakage. 上面的代码有点令人讨厌的IMO,容易损坏。 With some small changes to your HTML, the code could be much simpler and won't break if you start moving element around within their parent elements: 对HTML进行一些小的更改,如果您开始在其父元素内移动元素,则代码可能会更简单并且不会中断:

Changes to your 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>

try this code 试试这个代码

$(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();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM