【问题标题】:Switch toggle return to previous state when I click "No" in the alert prompt当我在警报提示中单击“否”时,切换开关返回到以前的状态
【发布时间】:2019-11-23 16:10:05
【问题描述】:

我创建了一个切换开关,允许系统管理员激活/停用帐户的登录访问权限。

在管理员点击开关切换(开关从状态 1 移动到 0)后,它会通过警报框提示确认(您要激活/停用此帐户吗?是 | 否),每当我单击“否” , 我希望它恢复到之前的状态(从 0 到 1)。

如果状态为“1”[帐户已激活],我成功地做到了这一点,但是当状态相反时,从状态 0 到 1,开关切换不会返回到之前的状态,并且卡在状态 1。

它仍然会发送正确的 POST 命令(例如,如果帐户已激活则停用该帐户,反之亦然),但视觉显示是错误的。

这是我的代码。

切换开关的Javascript


var chk;
    $(document).on('change', '.btn-change-status', function(e) {
      e.preventDefault();
      chk = $(this);
      var switch_status = $(this).attr('data-status');
      var account_status = (switch_status == 1) ? 0 : 1;
      var id  = $(this).attr('data-id');
      var confirm_alert = (switch_status == 1) ? confirm("Are you sure you want to deactivate this account?") : confirm("Are you sure you want to activate this account?");
        if (confirm_alert == true) {
         $.ajax({
              url: "/user/update-status",
              type: "POST",
              data: {
                _token: "{{csrf_token()}}",
                id: id,
                status: account_status
              },
              success: function(data) {
                if (data.success === true) {
                  alert("Account Successfully Updated!");
                  location.reload();
                }
              }

            });
        }
        else {
          if(chk.checked) {
            chk.prop("checked", false);
          }
          else {
            chk.prop("checked", true);
          }
        }
    });

编辑:添加了开关的 HTML 部分,尽管它仍然在 javascript 中,因为我将它附加到了一个数据表。

数据表的 HTML


 <div class="card mb-3">
            <div class="card-header">
              <i class="fas fa-table"></i>
              Accounts Management</div>
            <div class="card-body">

              <button type="button" id="btn-add-account" class="btn btn-primary">Add Account</button>
              <div class="table-responsive mt-3">
                <table class="table table-bordered dt-responsive" id="table-accounts" width="100%" cellspacing="0">
                  <thead>
                    <tr>
                      <th class="hidden">ID</th>
                      <th>Username</th>
                      <th>Email</th>
                      <th>Role</th>
                      <th>Date Created</th>
                      <th style="width: 15.5%">Actions</th>
                    </tr>
                  </thead>
                  <tfoot>
                    <tr>
                      <th class="hidden">ID</th>
                      <th>Username</th>
                      <th>Email</th>
                      <th>Role</th>
                      <th>Date Created</th>
                      <th style="width: 15.5%">Actions</th>
                    </tr>
                  </tfoot>
                  <tbody>
                  </tbody>
                </table>
              </div>
            </div>
          </div>

        </div>
        <!-- /.container-fluid -->
      </div>

数据表的Javascript


$(document).ready(function() {
    getRoles();
    var accounts;
     $('#account-management').addClass('active');

    accounts = $("#table-accounts").DataTable({
        ajax: {
          url: "/users/get-all-users",
          dataSrc: ''
        },
        responsive:true,
        "order": [[ 7, "desc" ]],
        columns: [
        { data: 'id'},
        { data: 'username' },
        { data: 'email'},
        { data: 'role.id'},
        { data: 'created_at'},
        { data: null,
          render: function ( data, type, row ) {
            var html = "";
            if (data.status == 1) {
              html += '<span class="switch switch-sm"> <input type="checkbox" class="switch btn-change-status" id="'+data.id+'" data-id="'+data.id+'" data-status="'+data.status+'" checked> <label for="'+data.id+'"></label></span>';
            } else {
              html += '<span class="switch switch-sm"> <input type="checkbox" class="switch btn-change-status" id="'+data.id+'" data-id="'+data.id+'" data-status="'+data.status+'"> <label for="'+data.id+'"></label></span>';
            }
              html += "<button type='button' class='btn btn-primary btn-sm btn-edit-account mr-2' data-id='"+data.id+"' data-account='"+data.id+"'>Edit</button>";
              html += "<button type='button' class='btn btn-secondary btn-sm btn-reset-password' data-id='"+data.id+"' data-account='"+data.id+"'><i class='fas fa-key'></i></button>";

            // <button type='button' class='btn btn-primary btn-sm btn-edit' data-id='"+data.id+"' data-account='"+data.id+"'>Edit</button> 
            // html += "<button class='btn btn-danger btn-sm btn-delete' data-id='"+data.id+"' data-account='"+data.id+"'>Remove</button>";

            return html;
          } 
        },
        ],
        columnDefs: [
        { className: "hidden", "targets": [0]},
         { "orderable": false, "targets": 4 }
        ]
    });

谢谢!

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

    代表同一事物的值太多。您只需要两个值:

    1. id: [type: String] 复选框的id。
    2. status: [type: Boolean] 默认情况下,复选框值为true,如果选中,false,如果不选中。

    在这种情况下,您不需要任何data-* 属性,但如果您仍然认为需要,请改用.data() 方法:

    $('.status').data('id') // Returns the value of `data-id` on each `input.status`
    

    如果由于某种原因您发现需要为这样一项微不足道的任务使用更多值,您需要从根本上重新评估您的代码。详细信息在演示中进行了注释,它使用实时测试服务器来验证发送给它的内容。

    /* This function extracts the value of each output.member and then assigns a 
       modified version of the value as the id of the checkbox that follows (input.status)
       This is not required to answer the OP's question and is intended just to provide each
       checkbox with a unique id */
    $('.member').each(function(index) {
      let user = $(this).val().split('@')
      let id = user[0] + '-' + index;
      $(this).next('.status').attr('id', id);
    });
    
    // Any change event occuring on any input.staus (checkbox)...
    $('.status').on('change', function(e) {
    
      // A boolean that reflects the checkbox "check status"
      let checked = $(this).is(':checked');
      
      // A simple confirm...
      let changed = confirm("Are you sure you want to change this account?");
      
      //... if user cancels...
      if (!changed) {
      
        /* ...ternary: [?][if checkbox is checked] - [uncheck it] [:][otherwise] - [check it]
        [return][Terminate function - don't do anything else] */
        return checked ? $(this).prop('checked', false) : $(this).prop('checked', true);
      }
      
      /* function continues here if user confirmed by clicking "OK"
         The data will be posted to a live test server.
         A link will appear at the bottom, follow the directions to verify response */
      let ID = this.id;
      let active = checked ? 1 : 0;
      $.ajax({
        url: "http://ptsv2.com/t/status/post",
        type: "POST",
        data: {
          id: ID,
          status: active
        },
         success: function() {
           $('.response').show();
        }
      });
    });
    :root {
      font: 16px/1 Arial
    }
    
    label {
      display: block;
      margin: 8px 0 0 0;
    }
    
    .member {
      display: inline-block;
      width: 25ch;
      vertical-align: middle
    }
    
    .status {
      display: inline-block;
      vertical-align: middle
    }
    
    .response {
      display: none;
      cursor: pointer;
      width: 99vw
    }
    
    .response * {
      display: block;
      margin: 8px auto;
      width: 90%
    }
    <form id='admin-panel'>
      <fieldset class='member-status'>
        <legend>Member Status</legend>
        <label>
        <output class='member'>zer00ne@gmail.com</output>
        Status: <input class='status' type='checkbox' checked>
        </label>
        <label>
        <output class='member'>tech.artificer@gmail.com</output>
        Status: <input class='status' type='checkbox' checked>
        </label>
        <label>
        <output class='member'>joker666@4chan.org</output>
        Status: <input class='status' type='checkbox'>
        </label>
        <label>
        <output class='member'>byte.my@ss.com</output>
        Status: <input class='status' type='checkbox' checked>
        </label>
        <label>
        <output class='member'>bruce@wayne.com</output>
        Status: <input class='status' type='checkbox' checked>
        </label>
        <label>
        <output class='member'>clark.kent@dailyplanet.com</output>
        Status: <input class='status' type='checkbox' checked>
        </label>
      </fieldset>
      <hr>
      <output class='response'>
        <a href="https://ptsv2.com/t/status/d/latest" target='view'>Click then scroll down to <i style='display:inline'>Parameters</i> inside the iframe below</a>
        <iframe name='view'></iframe>
      </output>
    
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

    【讨论】:

    • 这帮助我解决了我的问题,谢谢!另外,我会注意你所说的关于值的使用,再次感谢你! :))
    • 太好了。编码愉快!
    【解决方案2】:

    能否用您的 HTML 更新您的帖子,因为我不确定问题中描述的情况。我知道为什么代码不起作用,但需要查看HTML 以进一步调查。 事后看来,我意识到我的解决方案可能无法解决问题。

    如果类btn-change-status 的元素是HTML 中的&lt;button&gt; 标签,那么jQuery 的.on("change", handler) 将不起作用(其中handler 是你的函数)。根据 jQuery 文档:

    change 事件在其值更改时发送到元素。此事件仅限于&lt;input&gt; 元素、&lt;textarea&gt; 框和&lt;select&gt; 元素。

    相反,我建议使用以下方法之一:

    • .on("click", handler)
    • .on("mouseup", handler)
    • .on("mousedown", handler)

    看看哪一个有效。

    【讨论】:

      【解决方案3】:

      因为您使用的是类选择器'.btn-change-status'

      chk = $(this);
      

      chk 现在是一个包含 1 个元素的集合。要检查它是否被检查使用

      chk.prop('checked')
      

      chk[0].checked
      

      【讨论】:

        【解决方案4】:

        您正在调用 ajax 并试图在错误的事件中切换您的输入。您必须在弹出窗口的 yes 按钮上处理这些事件,而不是在 change 事件中。

        代码应该清除它。

         $(document).on('change', '.btn-change-status', function(e) {
          e.preventDefault();
          var chk = $(this);
          var switch_status = $(this).attr('data-status');
          var account_status = (switch_status == 1) ? 0 : 1;
          var id  = $(this).attr('data-id');
          popUpConfirmation(id, status);
        });
        
        function popUpConfirmation(id,status) {
           //popup opens here is visible 
           $("#ok-button").data("id", id);
            $("#ok-button").data("status", status);
        }
        
        $("#ok-button").on('click', function() {
          var id  = $(this).attr('data-id');
          var status = $(this).attr('data-status');
        
          var checkbox = $("input[data-id='"+id+"']");
          if(checkbox.prop('checked')) {
             checkbox.prop('checked',false);
          } else {
             checkbox.prop('checked',true);
          }
        
           $.ajax({
                  url: "/user/update-status",
                  type: "POST",
                  data: {
                    _token: "{{csrf_token()}}",
                    id: id,
                    status: account_status
                  },
                  success: function(data) {
                    if (data.success === true) {
                      alert("Account Successfully Updated!");
                      location.reload();
                    }
                  }
        
                });
        
        });
        
        $("#cancel-button").on('click', function() {
          //close or hide the popup
        });
        

        为弹出窗口创建一个视图。这可以是任何 div 或按钮,或者您可以使用模态视图弹出窗口。主要的关键是触发按钮。

        <div class="popup">
          <input type="button" id="ok-button"></input>
           <input type="button" id="cancel-button"></input>
        </div>
        

        这应该可以解决您的视图问题,而无需过多更改您的代码。您可以使用三元运算符缩短代码。但我想保持简单,让其他人也能理解。

        如果您有任何疑问,请随时询问。

        我希望这会有所帮助...祝您编码愉快。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-12
          • 2017-08-19
          • 1970-01-01
          • 2021-12-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多