• Bootstrap, 模态框实现值传递,自动勾选


    Bootstrap,模态框自动勾选,值传递

    场景:

    ​ 有一个这样的需求, 在父页面有一个table, 在table中有每一行都有一个更新按钮, 用来更新此行数据关联的另一组完整数据, 在点击按钮时, 直接弹出新的table, 并且需要将默认已经关联的数据进行勾选处理. 如下所示.

    过程.gif

    1.父页面

    效果

    1. 图一为父页面 domain_list : 展示某列表信息,其中绑定主机 是涉及调用 子页面的 btn

    父页面.png

    1. 此页面代码如下, (后端主要使用了python, Django, 使用了模板语言. 这里不是重点)

      {% extends '_base_list.html' %}
      {% load i18n static %}
      {% block custom_head_css_js %}
      <style>
        #domainSteps {
          padding-left: 7%;
           35%;
          margin:10px auto;
        }
      
        .step-item {
          display: inline-block;
          line-height: 32px;
          position: relative;
        }
      
        .step-item-tail {
           100%;
          padding: 0 10px;
          position: absolute;
          left: 15px;
          top: 15px;
        }
      
        .step-item-tail i {
          display: inline-block;
           100%;
          height: 3px;
          vertical-align: top;
          background: #2061FF;
          position: relative;
        }
      
        .step-item-tail-done {
          background: #2061FF !important;
        }
      
        .step-item-head {
          position: relative;
          display: inline-block;
          height: 32px;
           32px;
          text-align: center;
          vertical-align: top;
          color: #2061FF;
          border: 1px solid #2061FF;
          border-radius: 50%;
        }
      
        .step-item-head.step-item-head-active {
          background: #2061FF;
          color: #ffffff;
        }
      
        .step-item-main {
          display: block;
          position: relative;
          left: -9px;
        }
      
        .step-item-main-title {
          font-weight: 500;
          color: #4B556A;
        }
      
        .step-item-main-desc {
          color: #aaaaaa;
        }
        /*搜索框样式*/
        #domain_list_table_filter input {
          border: 1px solid #D0D2D7;
        }
      
        #domain_list_table_filter input:focus {
          border: 1px solid rgb(32, 97, 255) !important;
        }
      </style>
      {% endblock %}
      {% block table_search %}{% endblock %}
      {% block help_message %}
      <div id="domainSteps"></div>
      
      {% endblock %}
      
      {% block table_container %}
      <div class="uc pull-left  m-r-5">
        <a href="/ops-audit{% url 'assets:domain-create' %}" class="btn btn-sm btn-primary">
          <i class="layui-icon" style="font-size: 12px;">&#xe654;</i>
          {% trans "Create domain" %}
        </a>
      </div>
      <table class="table table-hover" id="domain_list_table">
        <thead>
          <tr>
            <th class="text-center">
              <input type="checkbox" id="check_all" class="ipt_check_all">
            </th>
            <th class="text-center">{% trans 'Name' %}</th>
            <th class="text-center">{% trans 'Asset' %}</th>
            <th class="text-center">{% trans 'Gateway' %}</th>
            <th class="text-center">{% trans 'Comment' %}</th>
            <th class="text-center">{% trans 'Action' %}</th>
          </tr>
        </thead>
        <tbody>
        </tbody>
      </table>
      {% include 'assets/_asset_list_modal.html' %}
      {% endblock %}
      
      {% block content_bottom_left %}{% endblock %}
      {% block custom_foot_js %}
      <script>
      
      function initTable() {
          var options = {
              ele: $('#domain_list_table'),
              columnDefs: [
              {
                targets: 1, createdCell: function (td, cellData, rowData) {
                  var detail_btn = '<a href="/ops-audit{% url "assets:domain-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
                  $(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
                }
              },
              {
                targets: 3, createdCell: function (td, cellData, rowData) {
                  var gateway_list_btn = '<a href="/ops-audit{% url "assets:domain-gateway-list" pk=DEFAULT_PK %}">' + cellData + '</a>';
                  gateway_list_btn = gateway_list_btn.replace("{{ DEFAULT_PK }}", rowData.id);
                  $(td).html(gateway_list_btn);
                }
              },
              {
                targets: 5, createdCell: function (td, cellData, rowData) {
                  var bindHost = '<a  class="m-l-xs btn-bind"  data-aid="{{ DEFAULT_PK }}"  >{% trans "Bind assets" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
                  var update_btn = '<a href="/ops-audit{% url "assets:domain-update" pk=DEFAULT_PK %}" class="">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
                  var del_btn = '<a class="m-l-xs btn-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
                  $(td).html(bindHost+"<span style='color:#D9D9D9'> | </span>"+update_btn+"<span style='color:#D9D9D9'> | </span>"+del_btn)
                }
              }
              ],
              ajax_url: '/ops-audit{% url "api-assets:domain-list" %}',
              columns: [
                  { data: "id" }, { data: "name",orderable: false }, { data: "asset_count",orderable: false },
                  { data: "gateway_count",orderable: false }, { data: "comment",orderable: false }, { data: "id",orderable: false }
              ],
              op_html: $('#actions').html()
              };
          jumpserver.initServerSideDataTable(options);
      }
      $(document).ready(function () {
          initTable();
          layui.use('steps', function () {
              var steps = layui.steps;
      
              var dataDomain = [
                  { 'title': "创建网域"},
                  { 'title': "创建网关"},
                  { 'title': "绑定主机"}
      
              // { 'title': "第三步", "desc": "2018-07-01 10:44:42" }
              ];
      
              steps.make(dataDomain, '#domainSteps', 0);
              });
              //搜索框icon
              var html = '<span class="searchTubiao fa fa-search" id="searchTubiao"></span>';
              $("#domain_list_table_filter").append(html);
      })
      
      .on('click', '.btn-delete', function () {
          var $this = $(this);
          var $data_table = $('#domain_list_table').DataTable();
          var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
          var uid = $this.data('uid');
          var the_url = '/ops-audit{% url "api-assets:domain-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
          objectDelete($this, name, the_url);
          setTimeout(function () {
          $data_table.ajax.reload();
          }, 1500);
      })
      .on('click', '.btn-bind', function () {
          var $this = $(this);
          var aid = $this.data('aid');
          var $id_assets = $('#id_assets');
          $id_assets.attr("aid",aid);
          $('#asset_list_modal').modal('show');
      });
      </script>
      
      <script>
          // after bound assets,updated domain table.
          $(function() {
              var $data_table = $('#domain_list_table').DataTable();
              $('#asset_list_modal').on('hide.bs.modal',
                                        function() {
                  setTimeout(function () {
                      $data_table.ajax.reload();
                  }, 1000);
              })
          });
      </script>
      {% endblock %}
      

    代码分析

    1. body代码块中, {% include 'assets/_asset_list_modal.html' %} 是用来加载bootstrap的模态框,即子页面

    2. initTable() 用来初始化父页面的table. 重点在 targets: 5, createdCell: function (td, cellData, rowData) 第六列展示了三个button样式. 分别是 bindHost(绑定主机), update_btn(更新), del_btn(删除), 每一个button上面绑定一个``click 事件, 事件再绑定api`接口

    3. 删除btn事件如下,不多赘述

      <script>
         ...
      .on('click', '.btn-delete', function () {
          var $this = $(this);
          var $data_table = $('#domain_list_table').DataTable();
          var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
          var uid = $this.data('uid');
          var the_url = '/ops-audit{% url "api-assets:domain-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
          objectDelete($this, name, the_url);
          setTimeout(function () {
          $data_table.ajax.reload();
          }, 1500);
      })
      <script>
      
    4. 绑定主机btn click事件如下

      <script>
      .on('click', '.btn-bind', function () {
          var $this = $(this);
          var aid = $this.data('aid');
          var $id_assets = $('#id_assets');
          $id_assets.attr("aid",aid);
          $('#asset_list_modal').modal('show');
      });
      </script>
      

      说明

      • 此点击事件其实实现了两个api的调用①获取当前绑定资产的原有列表;②更新domain资产
      • aid为当前domain的pk值,用来传递给子页面, 然后调用相应的api
      • #id_assets为子页面中 <input>标签 id值, 用来接收父页面传递子页面的值
      • #asset_list_modal 为子页面 modal(模态框) id值

    2. 子页面(modal) 模态框

    效果

    1. 子页面assets_list用来展示所有的资产; 初始化时, 必须勾选已经绑定的资产; 提交按钮时用来 更新domain的assets.

    子页面.png

    1. 代码如下
    {% extends '_modal.html' %}
    {% load i18n %}
    {% load static %}
    
    {% block modal_class %}modal-lg{% endblock %}
    {% block modal_id %}asset_list_modal{% endblock %}
    {% block modal_title%}{% trans "Asset list" %}{% endblock %}
    
    
    {% block modal_body %}
    <link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
    <script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
    <script src="{% static 'js/jquery.form.min.js' %}"></script>
    <style>
    .inmodal .modal-header {
        padding: 10px 10px;
        text-align: center;
    }
    
    #assetTree2.ztree * {
        background-color: #f8fafb;
    }
    #assetTree2.ztree {
        background-color: #f8fafb;
    }
    </style>
    
    <input type="text"  name="id_assets" style="visibility: hidden" id="id_assets"  value="">
    
    <div class="wrapper wrapper-content">
       <div class="row">
           <div class="col-lg-3" id="split-left" style="padding-left: 3px">
               <div class="ibox float-e-margins">
                   <div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px">
                       <div class="file-manager ">
                           <div id="assetTree2" class="ztree">
                           </div>
                           <div class="clearfix"></div>
                       </div>
                   </div>
               </div>
           </div>
    
           <div class="col-lg-9 animated fadeInRight" id="split-right">
               <div class="mail-box-header">
                   <table class="table table-striped table-bordered table-hover " id="asset_list_modal_table" style=" 100%">
                       <thead>
                           <tr>
                               <th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
                               <th class="text-center">{% trans 'Hostname' %}</th>
                               <th class="text-center">{% trans 'IP' %}</th>
                           </tr>
                       </thead>
                       <tbody>
                       </tbody>
                   </table>
               </div>
           </div>
       </div>
    </div>
    
    <script>
    var zTree2, asset_table2 = 0;
    // 获取资产列表
    function initTable2() {
        if(asset_table2){
            return
        }
    
        var options = {
            ele: $('#asset_list_modal_table'),
            ajax_url: '/ops-audit{% url "api-assets:asset-list" %}?show_current_asset=1',
            columns: [
                {data: "id"}, {data: "hostname" }, {data: "ip" }
            ],
            pageLength: 10
        };
        asset_table2 = jumpserver.initServerSideDataTable(options);
        console.log();
        return asset_table2
    }
    
    // 初始化时选中 已经绑定的资产
    //function onNodeSelected2(event, treeNode) {
    //    var url = asset_table2.ajax.url();
    //    url = setUrlParam(url, "node_id", treeNode.meta.node.id);
    //    asset_table2.ajax.url(url);
    //    asset_table2.ajax.reload();
    // }
    
    // 获取节点
    function initTree2() {
        var url = '/ops-audit{% url "api-assets:node-children-tree" %}?assets=0';
        var setting = {
            view: {
                dblClickExpand: false,
                showLine: true
            },
            data: {
                simpleData: {
                    enable: true
                }
            },
            async: {
    			enable: true,
    			url: url,
    			autoParam: ["id=key", "name=n", "level=lv"],
                type: 'get'
    		},
            callback: {
                onSelected: onNodeSelected2
            }
        };
        zTree2 = $.fn.zTree.init($("#assetTree2"), setting);
    }
    
    function initSelectedAssets(){
            let init_bound_assets = [];
            let $id_assets = $('#id_assets');
            let aid = $id_assets.attr('aid');
            let api_url = '{% url "api-assets:domain-assets-update" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", aid);
            $.ajax({
                url: api_url,
                Type: 'GET',
                dataType: "json",
                sync: false,
                success :function (data) {
                   let res_assets = data.result.assets;
                   if  (res_assets.length !==0){
                        for (let i=0;i<res_assets.length;i++){
                            init_bound_assets.push(res_assets[i]);
                        }
                   }else{
                        init_bound_assets = [];
                   }
                   $id_assets.attr("value",init_bound_assets);
                   console.log("已绑定的资产:",init_bound_assets);
                   correctSelectedCheckbox(init_bound_assets);
                },
    
                error: function(XMLResponse) {
                   let error_msg = XMLResponse.responseText;
                   let error_res =  JSON.parse(error_msg);
                   console.error(error_res);
                }
            });
    }
    
    function correctSelectedCheckbox(init_bound_assets) {
        // var assets_table = document.getElementById('asset_list_modal_table');
        let selectedAssets = asset_table2.selected.concat();
        console.log("缓存资产1:",selectedAssets);
    	
        // 防止上一次操作勾选后存在缓存
        if (selectedAssets.length !== 0 && init_bound_assets.length === 0) {
            $.each(selectedAssets, function(index, assetId) {
                 $('#' + assetId).trigger('click'); // 取消勾选
            });
        }
        
        console.log("缓存资产2:",selectedAssets);
        if (selectedAssets.length !== 0 && init_bound_assets.length !== 0) {
            $.each(selectedAssets, function(index, AssetId) {
              if ($.inArray(AssetId, init_bound_assets) === -1) {
                  $('#' + AssetId).trigger('click'); // 将错误勾选资产取消勾选
              }
            });
    
            $.each(init_bound_assets,function(index,AssetId) {
              if ($.inArray(AssetId, selectedAssets) === -1){
                   $('#' + AssetId).trigger('click'); // 将未勾选的初始资产重新勾选
              }
            })
        }
    
        // 默认无勾选时,将已绑定的资产勾选上
        if (selectedAssets.length === 0 && init_bound_assets.length !== 0) {
            $.each(init_bound_assets,function(index,AssetId) {
                $('#' +  AssetId).trigger('click');
            });
        }
    }
    
    $(document).ready(function(){
    
    })
    
    .on('show.bs.modal', function () {
        initTable2();
        initTree2();
        initSelectedAssets();
    })
    
    // 提交按钮操作
    .on('click','#btn_asset_modal_confirm', function (){
        let $id_assets = $('#id_assets');
        let aid = $id_assets.attr("aid");
        let update_assets = asset_table2.selected;
        console.log(update_assets);
    
        let api_url = '{% url "api-assets:domain-assets-update" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", aid);
    
        $.ajax({
            url: api_url,
            type: 'PUT',
            dataType: "json",
            data: JSON.stringify({
                assets: update_assets
            }),
            contentType:'application/json',
            sync: false,
            success :function (data) {
                let assets = data.result.assets;
                console.log(111,assets);
    
                $id_assets.attr("value",assets);
                console.log("更新后绑定的资产id:",$id_assets.val());
            },
    
            error: function(XMLResponse) {
                let error_msg = XMLResponse.responseText;
                let error_res =  JSON.parse(error_msg);
                console.error("request error:"+error_res);
            }
        });
        $("#asset_list_modal").modal('hide');
    });
    
    </script>
    {% endblock %}
    
    {% block modal_button %}
        {{ block.super }}
    {% endblock %}
    
    {% block modal_confirm_id %}btn_asset_modal_confirm{% endblock %}
    

    代码分析

    1. {% extends '_modal.html' %} 说明此页面继承了_modal.html的父页面, 而父页面就是 模态框的一个模板

    2. 使用模块框继承时, 写法

      {% block modal_class %}modal-lg{% endblock %}   /
      {% block modal_id %}asset_list_modal{% endblock %} // 定义模板id,用于发页面的引用, 渲染页面时会自动将父页面中添加一个 <div>的标签,并将`asset_list_modal`做为id
      
    3. initTable2()用来初始化子页面 table

    4. initTree2() 用来获取节点

    5. correctSelectedCheckbox(init_bound_assets) , 将绑定的资产在table中进行勾选操作,

    6. initSelectedAssets() 获取已经绑定过的资产.

    7. 模态框显示时 event

      <script>
         ...
      .on('show.bs.modal', function () {
         initTable2();
         initTree2();
         initSelectedAssets();
      })
      </script>
      
    8. 提交btn事件如下

      <script>
      // 提交按钮操作
      .on('click','#btn_asset_modal_confirm', function (){
          let $id_assets = $('#id_assets');
          let aid = $id_assets.attr("aid");
          let update_assets = asset_table2.selected;
          let api_url = '{% url "api-assets:domain-assets-update" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", aid);
      
          $.ajax({
              url: api_url,
              type: 'PUT',
              dataType: "json",
              data: JSON.stringify({
                  assets: update_assets
              }),
              contentType:'application/json',
              sync: false,
              success :function (data) {
                  let assets = data.result.assets;
                  console.log(111,assets);
      
                  $id_assets.attr("value",assets);
                  console.log("更新后绑定的资产id:",$id_assets.val());
              },
      
              error: function(XMLResponse) {
                  let error_msg = XMLResponse.responseText;
                  let error_res =  JSON.parse(error_msg);
                  console.error("request error:"+error_res);
              }
          });
          $("#asset_list_modal").modal('hide');
      });
      </script>
      
    9. {% block modal_confirm_id %}btn_asset_modal_confirm{% endblock %} 定义提交按钮 id

  • 相关阅读:
    Generator函数执行器-co函数库源码解析
    前端解读Webview
    javascript设计模式详解之策略模式
    javascript设计模式详解之命令模式
    【VBA】标准Sub/Function定义,带ScreenUpdating、On Error GoTo
    【VBA】全局数组定义
    【VBA】全局常量定义
    调试Java代码(Eclipse)汇总
    为Eclipse添加反编译插件,更好的调试
    Eclipse图标含义
  • 原文地址:https://www.cnblogs.com/failymao/p/11995536.html
Copyright © 2020-2023  润新知