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

场景:

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

1.父页面

效果

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

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

    {% extends '_base_list.html' %}
    {% load i18n static %}
    {% block custom_head_css_js %}
    <style>
    #domainSteps {
    padding-left: 7%;
    width: 35%;
    margin:10px auto;
    } .step-item {
    display: inline-block;
    line-height: 32px;
    position: relative;
    } .step-item-tail {
    width: 100%;
    padding: 0 10px;
    position: absolute;
    left: 15px;
    top: 15px;
    } .step-item-tail i {
    display: inline-block;
    width: 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;
    width: 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;"></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.

  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="width: 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

Bootstrap, 模态框实现值传递,自动勾选的更多相关文章

  1. Bootstrap 模态框(Modal)插件

    原文链接:http://www.runoob.com/bootstrap/bootstrap-modal-plugin.html Bootstrap 模态框(Modal)插件 模态框(Modal)是覆 ...

  2. BootStrap 模态框基本用法

    <!DOCTYPE html> <html> <head> <title>Bootstrap 实例 - 模态框(Modal)插件方法</title ...

  3. BootStrap——模态框

    模态框(Modal)是BootStrap中很棒的一个插件.可以去BootStrap菜鸟驿站里面看看. 模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开 ...

  4. 第二百四十三节,Bootstrap模态框插件

    Bootstrap模态框插件 学习要点: 1.基本使用 2.用法说明 本节课我们主要学习一下 Bootstrap 中的模态框插件,这是一款交互式网站非常常见的 弹窗功能插件. 一.基本使用 使用模态框 ...

  5. bootstrap模态框传值操作

    1.bootstrap模态框之html代码 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"& ...

  6. [bootstrap]模态框总结

    <!--data-backdrop禁止点击空白处关闭模态框,也可以js设置,其他参数可参考官网模态框文档--> <div class="modal fade" i ...

  7. js控制Bootstrap 模态框(Modal)插件

    js控制Bootstrap 模态框(Modal)插件 http://www.cnblogs.com/zzjeny/p/5564400.html

  8. Bootstrap模态框按钮

    1.触发模态框弹窗的代码 这里复制了一段Bootstrap模态框的代码 <h2>创建模态框(Modal)</h2> <!-- 按钮触发模态框 --> <but ...

  9. 解决bootstrap模态框内输入框无法获取焦点

    bootstrap 模态框中的input标签在某些情况下会无法获取焦点. 最终解决方法:去除模态框的 tabindex="-1" 属性即可

随机推荐

  1. HttpClient获取数据

    HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议 ...

  2. 分享一波目前写的最强的autohotkey 插件

    支持各种软件快速切换,补全括号,代码等!!!!!!!! ;这种全局定义要写在所有代码的前面才能让所有代码起作用. SetCapsLockState , AlwaysOff SetNumlockStat ...

  3. selenium怎样避免被服务器检测

    selenium是用来完成浏览器自动化相关的操作.可以通过代码的形式制定一些基于浏览器自动化的相关操作(行为动作),当代码执行后,浏览器就会自动触发相关的事件.但这并不能避免服务器的检测.当在浏览器中 ...

  4. php 中秒杀

    控制器层 2 //秒杀 首先要判断库存 其次高并发 然后入库 3 public function goods_do() 4 { 5 $gid=input("get.gid"); 6 ...

  5. Codeforces Round #595 (Div. 3) A,B,C,D

    A题:n个学生,分成任意组,要求每组中任意两名学生的技能值相差不等于1,问最小分组. #include<bits/stdc++.h> using namespace std; #defin ...

  6. 029_检测 MySQL 数据库连接数量

    #!/bin/bash#本脚本每 2 秒检测一次 MySQL 并发连接数,可以将本脚本设置为开机启动脚本,或在特定时间段执行#以满足对 MySQL 数据库的监控需求,查看 MySQL 连接是否正常#本 ...

  7. c++ 使用类生成随机数

    // generate algorithm example #include <iostream> // cout #include <algorithm> // genera ...

  8. shell 统计行数,单词个数,字符个数

    如果我们想知道1.txt中有多少行,多少个单词,多少个字符.我们可以使用wc命令.选项与参数-l:今列出行-w:今列出多少字(英文单词)-m:多少字符[zhang@localhost ~]$ cat ...

  9. windows环境rabbitmq安装步骤

    windows环境rabbitmq安装步骤: 1 提前安装erl; 2 rabbitmq安装后自动启动; 3 从开始菜单进入rabbit命令窗,启用插件;   下面是命令: 启用插件 rabbitmq ...

  10. Java中RuntimeException和Exception

    在java的异常类体系中,Error和RuntimeException是非检查型异常,其他的都是检查型异常. 所有方法都可以在不声明throws的情况下抛出RuntimeException及其子类 不 ...