@ -0,0 +1,49 @@
|
||||
# Operating System Files
|
||||
|
||||
*.DS_Store
|
||||
Thumbs.db
|
||||
*.sw?
|
||||
.#*
|
||||
*#
|
||||
*~
|
||||
*.sublime-*
|
||||
*.jar
|
||||
rebel.xml
|
||||
|
||||
# Build Artifacts
|
||||
|
||||
.gradle/
|
||||
build
|
||||
target/
|
||||
out/
|
||||
bin
|
||||
dependency-reduced-pom.xml
|
||||
logs/
|
||||
|
||||
# Eclipse Project Files
|
||||
|
||||
/target/
|
||||
.classpath
|
||||
.settings/
|
||||
*.iml
|
||||
*.project
|
||||
*.class
|
||||
*.metadata/
|
||||
/classes
|
||||
*.classpath
|
||||
*.factorypath
|
||||
# IntelliJ IDEA Files
|
||||
|
||||
MANIFEST.MF
|
||||
.idea/
|
||||
*.ipr
|
||||
*.iws
|
||||
*.idea
|
||||
|
||||
# studio Files
|
||||
|
||||
.studio/
|
||||
.mule/
|
||||
|
||||
README.html
|
||||
drsp-mission/src/upload/
|
||||
@ -0,0 +1,251 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>4.7.7</version>
|
||||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>4.7.7</ruoyi.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
||||
<shiro.version>1.10.1</shiro.version>
|
||||
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
|
||||
<druid.version>1.2.16</druid.version>
|
||||
<bitwalker.version>1.21</bitwalker.version>
|
||||
<kaptcha.version>2.3.3</kaptcha.version>
|
||||
<swagger.version>3.0.0</swagger.version>
|
||||
<pagehelper.boot.version>1.4.6</pagehelper.boot.version>
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
<oshi.version>6.4.3</oshi.version>
|
||||
<commons.io.version>2.11.0</commons.io.version>
|
||||
<poi.version>4.1.2</poi.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<hutool.version>5.6.5</hutool.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringBoot的依赖配置-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>2.5.15</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里数据库连接池 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 验证码 -->
|
||||
<dependency>
|
||||
<groupId>pro.fessional</groupId>
|
||||
<artifactId>kaptcha</artifactId>
|
||||
<version>${kaptcha.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Shiro核心框架 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Shiro使用Spring框架 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Shiro使用EhCache缓存框架 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-ehcache</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- thymeleaf模板引擎和shiro框架的整合 -->
|
||||
<dependency>
|
||||
<groupId>com.github.theborakompanioni</groupId>
|
||||
<artifactId>thymeleaf-extras-shiro</artifactId>
|
||||
<version>${thymeleaf.extras.shiro.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 解析客户端操作系统、浏览器等 -->
|
||||
<dependency>
|
||||
<groupId>eu.bitwalker</groupId>
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
<version>${bitwalker.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- pagehelper 分页插件 -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>${pagehelper.boot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 获取系统信息 -->
|
||||
<dependency>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
<version>${oshi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Swagger3依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
<version>${swagger.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- io常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- excel工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- velocity代码生成使用模板 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>${velocity.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 阿里JSON解析器 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 定时任务-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-quartz</artifactId>
|
||||
<version>${ruoyi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-generator</artifactId>
|
||||
<version>${ruoyi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 核心模块-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-framework</artifactId>
|
||||
<version>${ruoyi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 系统模块-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-system</artifactId>
|
||||
<version>${ruoyi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>${ruoyi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<modules>
|
||||
<module>ruoyi-admin</module>
|
||||
<module>ruoyi-framework</module>
|
||||
<module>ruoyi-system</module>
|
||||
<!-- <module>ruoyi-quartz</module>
|
||||
<module>ruoyi-generator</module>-->
|
||||
<module>ruoyi-common</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>https://maven.aliyun.com/repository/public</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>https://maven.aliyun.com/repository/public</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,19 @@
|
||||
package com.ruoyi;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||
public class RuoYiApplication
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(RuoYiApplication.class, args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.ruoyi;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
/**
|
||||
* web容器中进行部署
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RuoYiServletInitializer extends SpringBootServletInitializer
|
||||
{
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
|
||||
{
|
||||
return application.sources(RuoYiApplication.class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package com.ruoyi.web.controller.demo.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* 模态窗口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/demo/modal")
|
||||
public class DemoDialogController
|
||||
{
|
||||
private String prefix = "demo/modal";
|
||||
|
||||
/**
|
||||
* 模态窗口
|
||||
*/
|
||||
@GetMapping("/dialog")
|
||||
public String dialog()
|
||||
{
|
||||
return prefix + "/dialog";
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹层组件
|
||||
*/
|
||||
@GetMapping("/layer")
|
||||
public String layer()
|
||||
{
|
||||
return prefix + "/layer";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单
|
||||
*/
|
||||
@GetMapping("/form")
|
||||
public String form()
|
||||
{
|
||||
return prefix + "/form";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格
|
||||
*/
|
||||
@GetMapping("/table")
|
||||
public String table()
|
||||
{
|
||||
return prefix + "/table";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格check
|
||||
*/
|
||||
@GetMapping("/check")
|
||||
public String check()
|
||||
{
|
||||
return prefix + "/table/check";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格radio
|
||||
*/
|
||||
@GetMapping("/radio")
|
||||
public String radio()
|
||||
{
|
||||
return prefix + "/table/radio";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格回传父窗体
|
||||
*/
|
||||
@GetMapping("/parent")
|
||||
public String parent()
|
||||
{
|
||||
return prefix + "/table/parent";
|
||||
}
|
||||
|
||||
/**
|
||||
* 多层窗口frame1
|
||||
*/
|
||||
@GetMapping("/frame1")
|
||||
public String frame1()
|
||||
{
|
||||
return prefix + "/table/frame1";
|
||||
}
|
||||
|
||||
/**
|
||||
* 多层窗口frame2
|
||||
*/
|
||||
@GetMapping("/frame2")
|
||||
public String frame2()
|
||||
{
|
||||
return prefix + "/table/frame2";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.ruoyi.web.controller.demo.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* 图标相关
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/demo/icon")
|
||||
public class DemoIconController
|
||||
{
|
||||
private String prefix = "demo/icon";
|
||||
|
||||
/**
|
||||
* FontAwesome图标
|
||||
*/
|
||||
@GetMapping("/fontawesome")
|
||||
public String fontAwesome()
|
||||
{
|
||||
return prefix + "/fontawesome";
|
||||
}
|
||||
|
||||
/**
|
||||
* Glyphicons图标
|
||||
*/
|
||||
@GetMapping("/glyphicons")
|
||||
public String glyphicons()
|
||||
{
|
||||
return prefix + "/glyphicons";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package com.ruoyi.web.controller.demo.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* 报表
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/demo/report")
|
||||
public class DemoReportController
|
||||
{
|
||||
private String prefix = "demo/report";
|
||||
|
||||
/**
|
||||
* 百度ECharts
|
||||
*/
|
||||
@GetMapping("/echarts")
|
||||
public String echarts()
|
||||
{
|
||||
return prefix + "/echarts";
|
||||
}
|
||||
|
||||
/**
|
||||
* 图表插件
|
||||
*/
|
||||
@GetMapping("/peity")
|
||||
public String peity()
|
||||
{
|
||||
return prefix + "/peity";
|
||||
}
|
||||
|
||||
/**
|
||||
* 线状图插件
|
||||
*/
|
||||
@GetMapping("/sparkline")
|
||||
public String sparkline()
|
||||
{
|
||||
return prefix + "/sparkline";
|
||||
}
|
||||
|
||||
/**
|
||||
* 图表组合
|
||||
*/
|
||||
@GetMapping("/metrics")
|
||||
public String metrics()
|
||||
{
|
||||
return prefix + "/metrics";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
package com.ruoyi.web.controller.demo.domain;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* 客户测试信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CustomerModel
|
||||
{
|
||||
/**
|
||||
* 客户姓名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 客户手机
|
||||
*/
|
||||
private String phonenumber;
|
||||
|
||||
/**
|
||||
* 客户性别
|
||||
*/
|
||||
private String sex;
|
||||
|
||||
/**
|
||||
* 客户生日
|
||||
*/
|
||||
private String birthday;
|
||||
|
||||
/**
|
||||
* 客户描述
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 商品信息
|
||||
*/
|
||||
private List<GoodsModel> goods;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPhonenumber()
|
||||
{
|
||||
return phonenumber;
|
||||
}
|
||||
|
||||
public void setPhonenumber(String phonenumber)
|
||||
{
|
||||
this.phonenumber = phonenumber;
|
||||
}
|
||||
|
||||
|
||||
public String getSex()
|
||||
{
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(String sex)
|
||||
{
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public String getBirthday()
|
||||
{
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public void setBirthday(String birthday)
|
||||
{
|
||||
this.birthday = birthday;
|
||||
}
|
||||
|
||||
public String getRemark()
|
||||
{
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark)
|
||||
{
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public List<GoodsModel> getGoods()
|
||||
{
|
||||
return goods;
|
||||
}
|
||||
|
||||
public void setGoods(List<GoodsModel> goods)
|
||||
{
|
||||
this.goods = goods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("name", getName())
|
||||
.append("phonenumber", getPhonenumber())
|
||||
.append("sex", getSex())
|
||||
.append("birthday", getBirthday())
|
||||
.append("goods", getGoods())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
package com.ruoyi.web.controller.demo.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* 商品测试信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class GoodsModel
|
||||
{
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 商品重量
|
||||
*/
|
||||
private Integer weight;
|
||||
|
||||
/**
|
||||
* 商品价格
|
||||
*/
|
||||
private Double price;
|
||||
|
||||
/**
|
||||
* 商品日期
|
||||
*/
|
||||
private Date date;
|
||||
|
||||
/**
|
||||
* 商品种类
|
||||
*/
|
||||
private String type;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getWeight()
|
||||
{
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Integer weight)
|
||||
{
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public Double getPrice()
|
||||
{
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Double price)
|
||||
{
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public Date getDate()
|
||||
{
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date)
|
||||
{
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("name", getName())
|
||||
.append("weight", getWeight())
|
||||
.append("price", getPrice())
|
||||
.append("date", getDate())
|
||||
.append("type", getType())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,149 @@
|
||||
package com.ruoyi.web.controller.demo.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.annotation.Excel.Type;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
|
||||
public class UserOperateModel extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int userId;
|
||||
|
||||
@Excel(name = "用户编号")
|
||||
private String userCode;
|
||||
|
||||
@Excel(name = "用户姓名")
|
||||
private String userName;
|
||||
|
||||
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
|
||||
private String userSex;
|
||||
|
||||
@Excel(name = "用户手机")
|
||||
private String userPhone;
|
||||
|
||||
@Excel(name = "用户邮箱")
|
||||
private String userEmail;
|
||||
|
||||
@Excel(name = "用户余额")
|
||||
private double userBalance;
|
||||
|
||||
@Excel(name = "用户状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
|
||||
private Date createTime;
|
||||
|
||||
public UserOperateModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UserOperateModel(int userId, String userCode, String userName, String userSex, String userPhone,
|
||||
String userEmail, double userBalance, String status)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.userCode = userCode;
|
||||
this.userName = userName;
|
||||
this.userSex = userSex;
|
||||
this.userPhone = userPhone;
|
||||
this.userEmail = userEmail;
|
||||
this.userBalance = userBalance;
|
||||
this.status = status;
|
||||
this.createTime = DateUtils.getNowDate();
|
||||
}
|
||||
|
||||
public int getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(int userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserCode()
|
||||
{
|
||||
return userCode;
|
||||
}
|
||||
|
||||
public void setUserCode(String userCode)
|
||||
{
|
||||
this.userCode = userCode;
|
||||
}
|
||||
|
||||
public String getUserName()
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName)
|
||||
{
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getUserSex()
|
||||
{
|
||||
return userSex;
|
||||
}
|
||||
|
||||
public void setUserSex(String userSex)
|
||||
{
|
||||
this.userSex = userSex;
|
||||
}
|
||||
|
||||
public String getUserPhone()
|
||||
{
|
||||
return userPhone;
|
||||
}
|
||||
|
||||
public void setUserPhone(String userPhone)
|
||||
{
|
||||
this.userPhone = userPhone;
|
||||
}
|
||||
|
||||
public String getUserEmail()
|
||||
{
|
||||
return userEmail;
|
||||
}
|
||||
|
||||
public void setUserEmail(String userEmail)
|
||||
{
|
||||
this.userEmail = userEmail;
|
||||
}
|
||||
|
||||
public double getUserBalance()
|
||||
{
|
||||
return userBalance;
|
||||
}
|
||||
|
||||
public void setUserBalance(double userBalance)
|
||||
{
|
||||
this.userBalance = userBalance;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreateTime()
|
||||
{
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime)
|
||||
{
|
||||
this.createTime = createTime;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,131 @@
|
||||
package com.ruoyi.web.controller.home;
|
||||
|
||||
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.Ztree;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.domain.KCategory;
|
||||
import com.ruoyi.system.domain.KCategoryVO;
|
||||
import com.ruoyi.system.domain.KContent;
|
||||
import com.ruoyi.system.service.KCategoryService;
|
||||
import com.ruoyi.system.service.KContentService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* 首页
|
||||
* @author wangxy
|
||||
*/
|
||||
@Controller
|
||||
public class HomeController {
|
||||
|
||||
@Autowired
|
||||
private KContentService contentService;
|
||||
|
||||
@Autowired
|
||||
private KCategoryService categoryService;
|
||||
|
||||
|
||||
public static final String PAGE_SIZE = "15";
|
||||
|
||||
@Log(title = Constants.WEBSITE_ACCESS, businessType = BusinessType.OTHER)
|
||||
@ApiOperation("首页门户")
|
||||
@GetMapping("/home")
|
||||
public String home(ModelMap mmap,
|
||||
@RequestParam(required = false) Integer categoryid,
|
||||
@RequestParam(required = false) String kname,
|
||||
@RequestParam(required = false, defaultValue = "1", value = "p") Integer pageNum,
|
||||
@RequestParam(required = false ,defaultValue = PAGE_SIZE, value = "ps") Integer pageSize) {
|
||||
//最新通知
|
||||
PageMethod.startPage(pageNum,pageSize);
|
||||
List<KContent> list = contentService.lambdaQuery()
|
||||
.eq(Objects.nonNull(categoryid), KContent::getCategoryid, categoryid)
|
||||
.like(Objects.nonNull(kname), KContent::getKname, kname)
|
||||
.orderByDesc(KContent::getUpdatetime).list();
|
||||
list.forEach(kContent -> {
|
||||
KCategory category = categoryService.lambdaQuery()
|
||||
.eq(KCategory::getId, kContent.getCategoryid())
|
||||
.one();
|
||||
kContent.setCategoryname( Objects.nonNull(category) ? category.getCategoryname() : "" );
|
||||
});
|
||||
PageInfo<KContent> page = new PageInfo<>(list, pageSize);
|
||||
mmap.put("page", page);
|
||||
mmap.put("pageUrl", "/home");
|
||||
mmap.put("categoryid", categoryid);
|
||||
mmap.put("kname", kname);
|
||||
return "home/search _list";
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("详情")
|
||||
@GetMapping("/public_view.html")
|
||||
public String content(ModelMap mmap, @RequestParam String id) {
|
||||
KContent content = contentService.getById(id);
|
||||
mmap.put("content", content);
|
||||
return "home/public_view";
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("类别树")
|
||||
@GetMapping("/search")
|
||||
@ResponseBody
|
||||
public List<KCategory> search(
|
||||
@RequestParam(required = false) Integer categoryid) {
|
||||
return categoryService.lambdaQuery()
|
||||
.eq(KCategory::getHigherupid, Objects.nonNull(categoryid) ? categoryid : 0).list();
|
||||
}
|
||||
|
||||
@ApiOperation("类别树")
|
||||
@GetMapping("/getTree")
|
||||
@ResponseBody
|
||||
public List<KCategoryVO> getTree(@RequestParam(required = false,defaultValue = "0") Integer categoryid) {
|
||||
LambdaQueryWrapper<KCategory> tagWrapper = new LambdaQueryWrapper<>();
|
||||
tagWrapper.eq(KCategory::getHigherupid, categoryid);
|
||||
List<KCategory> datas = categoryService.list(tagWrapper);
|
||||
List<KCategoryVO> tagTreeVOList = new ArrayList<>(Convert.toList(KCategoryVO.class, datas));
|
||||
tagTreeVOList.forEach(this::buildChildren);
|
||||
return tagTreeVOList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建子节点
|
||||
*
|
||||
* @param pNode 父级
|
||||
*/
|
||||
private void buildChildren(KCategoryVO pNode) {
|
||||
// 获取子节点
|
||||
LambdaQueryWrapper<KCategory> tagWrapper = new LambdaQueryWrapper<>();
|
||||
tagWrapper.eq(KCategory::getHigherupid, pNode.getId());
|
||||
List<KCategory> dataTags = categoryService.list(tagWrapper);
|
||||
List<KCategoryVO> children = Convert.toList(KCategoryVO.class,dataTags);
|
||||
// 递归获取子节点
|
||||
children.forEach(this::buildChildren);
|
||||
pNode.setChildren(children);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package com.ruoyi.web.controller.monitor;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.framework.web.service.CacheService;
|
||||
|
||||
/**
|
||||
* 缓存监控
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/monitor/cache")
|
||||
public class CacheController extends BaseController
|
||||
{
|
||||
private String prefix = "monitor/cache";
|
||||
|
||||
@Autowired
|
||||
private CacheService cacheService;
|
||||
|
||||
@RequiresPermissions("monitor:cache:view")
|
||||
@GetMapping()
|
||||
public String cache(ModelMap mmap)
|
||||
{
|
||||
mmap.put("cacheNames", cacheService.getCacheNames());
|
||||
return prefix + "/cache";
|
||||
}
|
||||
|
||||
@RequiresPermissions("monitor:cache:view")
|
||||
@PostMapping("/getNames")
|
||||
public String getCacheNames(String fragment, ModelMap mmap)
|
||||
{
|
||||
mmap.put("cacheNames", cacheService.getCacheNames());
|
||||
return prefix + "/cache::" + fragment;
|
||||
}
|
||||
|
||||
@RequiresPermissions("monitor:cache:view")
|
||||
@PostMapping("/getKeys")
|
||||
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
|
||||
{
|
||||
mmap.put("cacheName", cacheName);
|
||||
mmap.put("cacheKeys", cacheService.getCacheKeys(cacheName));
|
||||
return prefix + "/cache::" + fragment;
|
||||
}
|
||||
|
||||
@RequiresPermissions("monitor:cache:view")
|
||||
@PostMapping("/getValue")
|
||||
public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap)
|
||||
{
|
||||
mmap.put("cacheName", cacheName);
|
||||
mmap.put("cacheKey", cacheKey);
|
||||
mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey));
|
||||
return prefix + "/cache::" + fragment;
|
||||
}
|
||||
|
||||
@RequiresPermissions("monitor:cache:view")
|
||||
@PostMapping("/clearCacheName")
|
||||
@ResponseBody
|
||||
public AjaxResult clearCacheName(String cacheName, ModelMap mmap)
|
||||
{
|
||||
cacheService.clearCacheName(cacheName);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@RequiresPermissions("monitor:cache:view")
|
||||
@PostMapping("/clearCacheKey")
|
||||
@ResponseBody
|
||||
public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap)
|
||||
{
|
||||
cacheService.clearCacheKey(cacheName, cacheKey);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@RequiresPermissions("monitor:cache:view")
|
||||
@GetMapping("/clearAll")
|
||||
@ResponseBody
|
||||
public AjaxResult clearAll(ModelMap mmap)
|
||||
{
|
||||
cacheService.clearAll();
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.ruoyi.web.controller.monitor;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
|
||||
/**
|
||||
* druid 监控
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/monitor/data")
|
||||
public class DruidController extends BaseController
|
||||
{
|
||||
private String prefix = "/druid";
|
||||
|
||||
@RequiresPermissions("monitor:data:view")
|
||||
@GetMapping()
|
||||
public String index()
|
||||
{
|
||||
return redirect(prefix + "/index.html");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.ruoyi.web.controller.monitor;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.framework.web.domain.Server;
|
||||
|
||||
/**
|
||||
* 服务器监控
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/monitor/server")
|
||||
public class ServerController extends BaseController
|
||||
{
|
||||
private String prefix = "monitor/server";
|
||||
|
||||
@RequiresPermissions("monitor:server:view")
|
||||
@GetMapping()
|
||||
public String server(ModelMap mmap) throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
server.copyTo();
|
||||
mmap.put("server", server);
|
||||
return prefix + "/server";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.ruoyi.web.controller.tool;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
|
||||
/**
|
||||
* build 表单构建
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/tool/build")
|
||||
public class BuildController extends BaseController
|
||||
{
|
||||
private String prefix = "tool/build";
|
||||
|
||||
@RequiresPermissions("tool:build:view")
|
||||
@GetMapping()
|
||||
public String build()
|
||||
{
|
||||
return prefix + "/build";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.ruoyi.web.controller.tool;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
|
||||
/**
|
||||
* swagger 接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/tool/swagger")
|
||||
public class SwaggerController extends BaseController
|
||||
{
|
||||
@RequiresPermissions("tool:swagger:view")
|
||||
@GetMapping()
|
||||
public String index()
|
||||
{
|
||||
return redirect("/swagger-ui/index.html");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,183 @@
|
||||
package com.ruoyi.web.controller.tool;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
/**
|
||||
* swagger 用户测试方法
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Api("用户信息管理")
|
||||
@RestController
|
||||
@RequestMapping("/test/user")
|
||||
public class TestController extends BaseController
|
||||
{
|
||||
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
|
||||
{
|
||||
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
|
||||
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户列表")
|
||||
@GetMapping("/list")
|
||||
public R<List<UserEntity>> userList()
|
||||
{
|
||||
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
|
||||
return R.ok(userList);
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户详细")
|
||||
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
|
||||
@GetMapping("/{userId}")
|
||||
public R<UserEntity> getUser(@PathVariable Integer userId)
|
||||
{
|
||||
if (!users.isEmpty() && users.containsKey(userId))
|
||||
{
|
||||
return R.ok(users.get(userId));
|
||||
}
|
||||
else
|
||||
{
|
||||
return R.fail("用户不存在");
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("新增用户")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
|
||||
@ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
|
||||
@ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
|
||||
@ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
|
||||
})
|
||||
@PostMapping("/save")
|
||||
public R<String> save(UserEntity user)
|
||||
{
|
||||
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
|
||||
{
|
||||
return R.fail("用户ID不能为空");
|
||||
}
|
||||
users.put(user.getUserId(), user);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ApiOperation("更新用户")
|
||||
@PutMapping("/update")
|
||||
public R<String> update(@RequestBody UserEntity user)
|
||||
{
|
||||
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
|
||||
{
|
||||
return R.fail("用户ID不能为空");
|
||||
}
|
||||
if (users.isEmpty() || !users.containsKey(user.getUserId()))
|
||||
{
|
||||
return R.fail("用户不存在");
|
||||
}
|
||||
users.remove(user.getUserId());
|
||||
users.put(user.getUserId(), user);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@ApiOperation("删除用户信息")
|
||||
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
|
||||
@DeleteMapping("/{userId}")
|
||||
public R<String> delete(@PathVariable Integer userId)
|
||||
{
|
||||
if (!users.isEmpty() && users.containsKey(userId))
|
||||
{
|
||||
users.remove(userId);
|
||||
return R.ok();
|
||||
}
|
||||
else
|
||||
{
|
||||
return R.fail("用户不存在");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiModel(value = "UserEntity", description = "用户实体")
|
||||
class UserEntity
|
||||
{
|
||||
@ApiModelProperty("用户ID")
|
||||
private Integer userId;
|
||||
|
||||
@ApiModelProperty("用户名称")
|
||||
private String username;
|
||||
|
||||
@ApiModelProperty("用户密码")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty("用户手机")
|
||||
private String mobile;
|
||||
|
||||
public UserEntity()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UserEntity(Integer userId, String username, String password, String mobile)
|
||||
{
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public Integer getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Integer userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username)
|
||||
{
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getMobile()
|
||||
{
|
||||
return mobile;
|
||||
}
|
||||
|
||||
public void setMobile(String mobile)
|
||||
{
|
||||
this.mobile = mobile;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
#url: jdbc:mysql://192.168.254.6:3306/work-portal?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
url: jdbc:mysql://127.0.0.1:3306/java_cti?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
#username: root
|
||||
#password: fq3gG@Ep
|
||||
username: ENC(qIDwFzwTd7W+6W3NTJsfsQ==)
|
||||
password: ENC(FZcHuy+40+UzU3k6M+FnT87FLCzZKG9S)
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置连接超时时间
|
||||
connectTimeout: 30000
|
||||
# 配置网络超时时间
|
||||
socketTimeout: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: ruoyi
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
@ -0,0 +1,66 @@
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
#url: jdbc:mysql://192.168.254.6:3306/work-portal?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
url: jdbc:mysql://127.0.0.1:3306/hyp-career?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
#username: sa
|
||||
#password: 123456
|
||||
#username: root
|
||||
#password: fq3gG@Ep
|
||||
username: ENC(qIDwFzwTd7W+6W3NTJsfsQ==)
|
||||
password: ENC(FZcHuy+40+UzU3k6M+FnT87FLCzZKG9S)
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置连接超时时间
|
||||
connectTimeout: 30000
|
||||
# 配置网络超时时间
|
||||
socketTimeout: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: ruoyi
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
@ -0,0 +1,2 @@
|
||||
Application Version: ${ruoyi.version}
|
||||
Spring Boot Version: ${spring-boot.version}
|
||||
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="/home/hyp/logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 用户访问日志输出 -->
|
||||
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-user.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 按天回滚 daily -->
|
||||
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.ruoyi" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
|
||||
<!--系统用户操作日志-->
|
||||
<logger name="sys-user" level="info">
|
||||
<appender-ref ref="sys-user"/>
|
||||
</logger>
|
||||
</configuration>
|
||||
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration
|
||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
<!-- 全局参数 -->
|
||||
<settings>
|
||||
<!-- 使全局的映射器启用或禁用缓存 -->
|
||||
<setting name="cacheEnabled" value="true" />
|
||||
<!-- 允许JDBC 支持自动生成主键 -->
|
||||
<setting name="useGeneratedKeys" value="true" />
|
||||
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
|
||||
<setting name="defaultExecutorType" value="SIMPLE" />
|
||||
<!-- 指定 MyBatis 所用日志的具体实现 -->
|
||||
<setting name="logImpl" value="SLF4J" />
|
||||
<!-- 使用驼峰命名法转换字段 -->
|
||||
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
|
||||
</settings>
|
||||
|
||||
</configuration>
|
||||
@ -0,0 +1,617 @@
|
||||
/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
|
||||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2007-2013 Einar Lielmanis and contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
Style HTML
|
||||
---------------
|
||||
|
||||
Written by Nochum Sossonko, (nsossonko@hotmail.com)
|
||||
|
||||
Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
|
||||
http://jsbeautifier.org/
|
||||
|
||||
Usage:
|
||||
style_html(html_source);
|
||||
|
||||
style_html(html_source, options);
|
||||
|
||||
The options are:
|
||||
indent_size (default 4) — indentation size,
|
||||
indent_char (default space) — character to indent with,
|
||||
max_char (default 250) - maximum amount of characters per line (0 = disable)
|
||||
brace_style (default "collapse") - "collapse" | "expand" | "end-expand"
|
||||
put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line.
|
||||
unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted
|
||||
indent_scripts (default normal) - "keep"|"separate"|"normal"
|
||||
|
||||
e.g.
|
||||
|
||||
style_html(html_source, {
|
||||
'indent_size': 2,
|
||||
'indent_char': ' ',
|
||||
'max_char': 78,
|
||||
'brace_style': 'expand',
|
||||
'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u']
|
||||
});
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
function style_html(html_source, options, js_beautify, css_beautify) {
|
||||
//Wrapper function to invoke all the necessary constructors and deal with the output.
|
||||
|
||||
var multi_parser,
|
||||
indent_size,
|
||||
indent_character,
|
||||
max_char,
|
||||
brace_style,
|
||||
unformatted;
|
||||
|
||||
options = options || {};
|
||||
indent_size = options.indent_size || 4;
|
||||
indent_character = options.indent_char || ' ';
|
||||
brace_style = options.brace_style || 'collapse';
|
||||
max_char = options.max_char === 0 ? Infinity : options.max_char || 250;
|
||||
unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
||||
|
||||
function Parser() {
|
||||
|
||||
this.pos = 0; //Parser position
|
||||
this.token = '';
|
||||
this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
|
||||
this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values
|
||||
parent: 'parent1',
|
||||
parentcount: 1,
|
||||
parent1: ''
|
||||
};
|
||||
this.tag_type = '';
|
||||
this.token_text = this.last_token = this.last_text = this.token_type = '';
|
||||
|
||||
this.Utils = { //Uilities made available to the various functions
|
||||
whitespace: "\n\r\t ".split(''),
|
||||
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
|
||||
extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them
|
||||
in_array: function (what, arr) {
|
||||
for (var i=0; i<arr.length; i++) {
|
||||
if (what === arr[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
this.get_content = function () { //function to capture regular content between tags
|
||||
|
||||
var input_char = '',
|
||||
content = [],
|
||||
space = false; //if a space is needed
|
||||
|
||||
while (this.input.charAt(this.pos) !== '<') {
|
||||
if (this.pos >= this.input.length) {
|
||||
return content.length?content.join(''):['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
input_char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
this.line_char_count++;
|
||||
|
||||
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
|
||||
if (content.length) {
|
||||
space = true;
|
||||
}
|
||||
this.line_char_count--;
|
||||
continue; //don't want to insert unnecessary space
|
||||
}
|
||||
else if (space) {
|
||||
if (this.line_char_count >= this.max_char) { //insert a line when the max_char is reached
|
||||
content.push('\n');
|
||||
for (var i=0; i<this.indent_level; i++) {
|
||||
content.push(this.indent_string);
|
||||
}
|
||||
this.line_char_count = 0;
|
||||
}
|
||||
else{
|
||||
content.push(' ');
|
||||
this.line_char_count++;
|
||||
}
|
||||
space = false;
|
||||
}
|
||||
content.push(input_char); //letter at-a-time (or string) inserted to an array
|
||||
}
|
||||
return content.length?content.join(''):'';
|
||||
};
|
||||
|
||||
this.get_contents_to = function (name) { //get the full content of a script or style to pass to js_beautify
|
||||
if (this.pos === this.input.length) {
|
||||
return ['', 'TK_EOF'];
|
||||
}
|
||||
var input_char = '';
|
||||
var content = '';
|
||||
var reg_match = new RegExp('</' + name + '\\s*>', 'igm');
|
||||
reg_match.lastIndex = this.pos;
|
||||
var reg_array = reg_match.exec(this.input);
|
||||
var end_script = reg_array?reg_array.index:this.input.length; //absolute end of script
|
||||
if(this.pos < end_script) { //get everything in between the script tags
|
||||
content = this.input.substring(this.pos, end_script);
|
||||
this.pos = end_script;
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
this.record_tag = function (tag){ //function to record a tag and its parent in this.tags Object
|
||||
if (this.tags[tag + 'count']) { //check for the existence of this tag type
|
||||
this.tags[tag + 'count']++;
|
||||
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
|
||||
}
|
||||
else { //otherwise initialize this tag type
|
||||
this.tags[tag + 'count'] = 1;
|
||||
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
|
||||
}
|
||||
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
|
||||
this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
|
||||
};
|
||||
|
||||
this.retrieve_tag = function (tag) { //function to retrieve the opening tag to the corresponding closer
|
||||
if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
|
||||
var temp_parent = this.tags.parent; //check to see if it's a closable tag.
|
||||
while (temp_parent) { //till we reach '' (the initial value);
|
||||
if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it
|
||||
break;
|
||||
}
|
||||
temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
|
||||
}
|
||||
if (temp_parent) { //if we caught something
|
||||
this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
|
||||
this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
|
||||
}
|
||||
delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
|
||||
delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
|
||||
if (this.tags[tag + 'count'] === 1) {
|
||||
delete this.tags[tag + 'count'];
|
||||
}
|
||||
else {
|
||||
this.tags[tag + 'count']--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.get_tag = function (peek) { //function to get a full tag and parse its type
|
||||
var input_char = '',
|
||||
content = [],
|
||||
comment = '',
|
||||
space = false,
|
||||
tag_start, tag_end,
|
||||
orig_pos = this.pos,
|
||||
orig_line_char_count = this.line_char_count;
|
||||
|
||||
peek = peek !== undefined ? peek : false;
|
||||
|
||||
do {
|
||||
if (this.pos >= this.input.length) {
|
||||
if (peek) {
|
||||
this.pos = orig_pos;
|
||||
this.line_char_count = orig_line_char_count;
|
||||
}
|
||||
return content.length?content.join(''):['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
input_char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
this.line_char_count++;
|
||||
|
||||
if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space
|
||||
space = true;
|
||||
this.line_char_count--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input_char === "'" || input_char === '"') {
|
||||
if (!content[1] || content[1] !== '!') { //if we're in a comment strings don't get treated specially
|
||||
input_char += this.get_unformatted(input_char);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (input_char === '=') { //no space before =
|
||||
space = false;
|
||||
}
|
||||
|
||||
if (content.length && content[content.length-1] !== '=' && input_char !== '>' && space) {
|
||||
//no space after = or before >
|
||||
if (this.line_char_count >= this.max_char) {
|
||||
this.print_newline(false, content);
|
||||
this.line_char_count = 0;
|
||||
}
|
||||
else {
|
||||
content.push(' ');
|
||||
this.line_char_count++;
|
||||
}
|
||||
space = false;
|
||||
}
|
||||
if (input_char === '<') {
|
||||
tag_start = this.pos - 1;
|
||||
}
|
||||
content.push(input_char); //inserts character at-a-time (or string)
|
||||
} while (input_char !== '>');
|
||||
|
||||
var tag_complete = content.join('');
|
||||
var tag_index;
|
||||
if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
|
||||
tag_index = tag_complete.indexOf(' ');
|
||||
}
|
||||
else { //otherwise go with the tag ending
|
||||
tag_index = tag_complete.indexOf('>');
|
||||
}
|
||||
var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
|
||||
if (tag_complete.charAt(tag_complete.length-2) === '/' ||
|
||||
this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /)
|
||||
if ( ! peek) {
|
||||
this.tag_type = 'SINGLE';
|
||||
}
|
||||
}
|
||||
else if (tag_check === 'script') { //for later script handling
|
||||
if ( ! peek) {
|
||||
this.record_tag(tag_check);
|
||||
this.tag_type = 'SCRIPT';
|
||||
}
|
||||
}
|
||||
else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content)
|
||||
if ( ! peek) {
|
||||
this.record_tag(tag_check);
|
||||
this.tag_type = 'STYLE';
|
||||
}
|
||||
}
|
||||
else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
|
||||
comment = this.get_unformatted('</'+tag_check+'>', tag_complete); //...delegate to get_unformatted function
|
||||
content.push(comment);
|
||||
// Preserve collapsed whitespace either before or after this tag.
|
||||
if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)){
|
||||
content.splice(0, 0, this.input.charAt(tag_start - 1));
|
||||
}
|
||||
tag_end = this.pos - 1;
|
||||
if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)){
|
||||
content.push(this.input.charAt(tag_end + 1));
|
||||
}
|
||||
this.tag_type = 'SINGLE';
|
||||
}
|
||||
else if (tag_check.charAt(0) === '!') { //peek for <!-- comment
|
||||
if (tag_check.indexOf('[if') !== -1) { //peek for <!--[if conditional comment
|
||||
if (tag_complete.indexOf('!IE') !== -1) { //this type needs a closing --> so...
|
||||
comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted
|
||||
content.push(comment);
|
||||
}
|
||||
if ( ! peek) {
|
||||
this.tag_type = 'START';
|
||||
}
|
||||
}
|
||||
else if (tag_check.indexOf('[endif') !== -1) {//peek for <!--[endif end conditional comment
|
||||
this.tag_type = 'END';
|
||||
this.unindent();
|
||||
}
|
||||
else if (tag_check.indexOf('[cdata[') !== -1) { //if it's a <[cdata[ comment...
|
||||
comment = this.get_unformatted(']]>', tag_complete); //...delegate to get_unformatted function
|
||||
content.push(comment);
|
||||
if ( ! peek) {
|
||||
this.tag_type = 'SINGLE'; //<![CDATA[ comments are treated like single tags
|
||||
}
|
||||
}
|
||||
else {
|
||||
comment = this.get_unformatted('-->', tag_complete);
|
||||
content.push(comment);
|
||||
this.tag_type = 'SINGLE';
|
||||
}
|
||||
}
|
||||
else if ( ! peek) {
|
||||
if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending
|
||||
this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
|
||||
this.tag_type = 'END';
|
||||
}
|
||||
else { //otherwise it's a start-tag
|
||||
this.record_tag(tag_check); //push it on the tag stack
|
||||
this.tag_type = 'START';
|
||||
}
|
||||
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line
|
||||
this.print_newline(true, this.output);
|
||||
}
|
||||
}
|
||||
|
||||
if (peek) {
|
||||
this.pos = orig_pos;
|
||||
this.line_char_count = orig_line_char_count;
|
||||
}
|
||||
|
||||
return content.join(''); //returns fully formatted tag
|
||||
};
|
||||
|
||||
this.get_unformatted = function (delimiter, orig_tag) { //function to return unformatted content in its entirety
|
||||
|
||||
if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
|
||||
return '';
|
||||
}
|
||||
var input_char = '';
|
||||
var content = '';
|
||||
var space = true;
|
||||
do {
|
||||
|
||||
if (this.pos >= this.input.length) {
|
||||
return content;
|
||||
}
|
||||
|
||||
input_char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
|
||||
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
|
||||
if (!space) {
|
||||
this.line_char_count--;
|
||||
continue;
|
||||
}
|
||||
if (input_char === '\n' || input_char === '\r') {
|
||||
content += '\n';
|
||||
/* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
|
||||
for (var i=0; i<this.indent_level; i++) {
|
||||
content += this.indent_string;
|
||||
}
|
||||
space = false; //...and make sure other indentation is erased
|
||||
*/
|
||||
this.line_char_count = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
content += input_char;
|
||||
this.line_char_count++;
|
||||
space = true;
|
||||
|
||||
|
||||
} while (content.toLowerCase().indexOf(delimiter) === -1);
|
||||
return content;
|
||||
};
|
||||
|
||||
this.get_token = function () { //initial handler for token-retrieval
|
||||
var token;
|
||||
|
||||
if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE') { //check if we need to format javascript
|
||||
var type = this.last_token.substr(7);
|
||||
token = this.get_contents_to(type);
|
||||
if (typeof token !== 'string') {
|
||||
return token;
|
||||
}
|
||||
return [token, 'TK_' + type];
|
||||
}
|
||||
if (this.current_mode === 'CONTENT') {
|
||||
token = this.get_content();
|
||||
if (typeof token !== 'string') {
|
||||
return token;
|
||||
}
|
||||
else {
|
||||
return [token, 'TK_CONTENT'];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.current_mode === 'TAG') {
|
||||
token = this.get_tag();
|
||||
if (typeof token !== 'string') {
|
||||
return token;
|
||||
}
|
||||
else {
|
||||
var tag_name_type = 'TK_TAG_' + this.tag_type;
|
||||
return [token, tag_name_type];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.get_full_indent = function (level) {
|
||||
level = this.indent_level + level || 0;
|
||||
if (level < 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return Array(level + 1).join(this.indent_string);
|
||||
};
|
||||
|
||||
this.is_unformatted = function(tag_check, unformatted) {
|
||||
//is this an HTML5 block-level link?
|
||||
if (!this.Utils.in_array(tag_check, unformatted)){
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tag_check.toLowerCase() !== 'a' || !this.Utils.in_array('a', unformatted)){
|
||||
return true;
|
||||
}
|
||||
|
||||
//at this point we have an tag; is its first child something we want to remain
|
||||
//unformatted?
|
||||
var next_tag = this.get_tag(true /* peek. */);
|
||||
|
||||
// tets next_tag to see if it is just html tag (no external content)
|
||||
var tag = (next_tag || "").match(/^\s*<\s*\/?([a-z]*)\s*[^>]*>\s*$/);
|
||||
|
||||
// if next_tag comes back but is not an isolated tag, then
|
||||
// let's treat the 'a' tag as having content
|
||||
// and respect the unformatted option
|
||||
if (!tag || this.Utils.in_array(tag, unformatted)){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
this.printer = function (js_source, indent_character, indent_size, max_char, brace_style) { //handles input/output and some other printing functions
|
||||
|
||||
this.input = js_source || ''; //gets the input for the Parser
|
||||
this.output = [];
|
||||
this.indent_character = indent_character;
|
||||
this.indent_string = '';
|
||||
this.indent_size = indent_size;
|
||||
this.brace_style = brace_style;
|
||||
this.indent_level = 0;
|
||||
this.max_char = max_char;
|
||||
this.line_char_count = 0; //count to see if max_char was exceeded
|
||||
|
||||
for (var i=0; i<this.indent_size; i++) {
|
||||
this.indent_string += this.indent_character;
|
||||
}
|
||||
|
||||
this.print_newline = function (ignore, arr) {
|
||||
this.line_char_count = 0;
|
||||
if (!arr || !arr.length) {
|
||||
return;
|
||||
}
|
||||
if (!ignore) { //we might want the extra line
|
||||
while (this.Utils.in_array(arr[arr.length-1], this.Utils.whitespace)) {
|
||||
arr.pop();
|
||||
}
|
||||
}
|
||||
arr.push('\n');
|
||||
for (var i=0; i<this.indent_level; i++) {
|
||||
arr.push(this.indent_string);
|
||||
}
|
||||
};
|
||||
|
||||
this.print_token = function (text) {
|
||||
this.output.push(text);
|
||||
};
|
||||
|
||||
this.indent = function () {
|
||||
this.indent_level++;
|
||||
};
|
||||
|
||||
this.unindent = function () {
|
||||
if (this.indent_level > 0) {
|
||||
this.indent_level--;
|
||||
}
|
||||
};
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
/*_____________________--------------------_____________________*/
|
||||
|
||||
multi_parser = new Parser(); //wrapping functions Parser
|
||||
multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
|
||||
|
||||
while (true) {
|
||||
var t = multi_parser.get_token();
|
||||
multi_parser.token_text = t[0];
|
||||
multi_parser.token_type = t[1];
|
||||
|
||||
if (multi_parser.token_type === 'TK_EOF') {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (multi_parser.token_type) {
|
||||
case 'TK_TAG_START':
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.indent();
|
||||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_TAG_STYLE':
|
||||
case 'TK_TAG_SCRIPT':
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_TAG_END':
|
||||
//Print new line only if the tag has no content and has child
|
||||
if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
|
||||
var tag_name = multi_parser.token_text.match(/\w+/)[0];
|
||||
var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length -1].match(/<\s*(\w+)/);
|
||||
if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) {
|
||||
multi_parser.print_newline(true, multi_parser.output);
|
||||
}
|
||||
}
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_TAG_SINGLE':
|
||||
// Don't add a newline before elements that should remain unformatted.
|
||||
var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
|
||||
if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)){
|
||||
multi_parser.print_newline(false, multi_parser.output);
|
||||
}
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
multi_parser.current_mode = 'CONTENT';
|
||||
break;
|
||||
case 'TK_CONTENT':
|
||||
if (multi_parser.token_text !== '') {
|
||||
multi_parser.print_token(multi_parser.token_text);
|
||||
}
|
||||
multi_parser.current_mode = 'TAG';
|
||||
break;
|
||||
case 'TK_STYLE':
|
||||
case 'TK_SCRIPT':
|
||||
if (multi_parser.token_text !== '') {
|
||||
multi_parser.output.push('\n');
|
||||
var text = multi_parser.token_text,
|
||||
_beautifier,
|
||||
script_indent_level = 1;
|
||||
if (multi_parser.token_type === 'TK_SCRIPT') {
|
||||
_beautifier = typeof js_beautify === 'function' && js_beautify;
|
||||
} else if (multi_parser.token_type === 'TK_STYLE') {
|
||||
_beautifier = typeof css_beautify === 'function' && css_beautify;
|
||||
}
|
||||
|
||||
if (options.indent_scripts === "keep") {
|
||||
script_indent_level = 0;
|
||||
} else if (options.indent_scripts === "separate") {
|
||||
script_indent_level = -multi_parser.indent_level;
|
||||
}
|
||||
|
||||
var indentation = multi_parser.get_full_indent(script_indent_level);
|
||||
if (_beautifier) {
|
||||
// call the Beautifier if avaliable
|
||||
text = _beautifier(text.replace(/^\s*/, indentation), options);
|
||||
} else {
|
||||
// simply indent the string otherwise
|
||||
var white = text.match(/^\s*/)[0];
|
||||
var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
|
||||
var reindent = multi_parser.get_full_indent(script_indent_level -_level);
|
||||
text = text.replace(/^\s*/, indentation)
|
||||
.replace(/\r\n|\r|\n/g, '\n' + reindent)
|
||||
.replace(/\s*$/, '');
|
||||
}
|
||||
if (text) {
|
||||
multi_parser.print_token(text);
|
||||
multi_parser.print_newline(true, multi_parser.output);
|
||||
}
|
||||
}
|
||||
multi_parser.current_mode = 'TAG';
|
||||
break;
|
||||
}
|
||||
multi_parser.last_token = multi_parser.token_type;
|
||||
multi_parser.last_text = multi_parser.token_text;
|
||||
}
|
||||
return multi_parser.output.join('');
|
||||
}
|
||||
|
||||
// If we're running a web page and don't have either of the above, add our one global
|
||||
window.html_beautify = function(html_source, options) {
|
||||
return style_html(html_source, options, window.js_beautify, window.css_beautify);
|
||||
};
|
||||
|
||||
}());
|
||||
@ -0,0 +1,688 @@
|
||||
/*!
|
||||
* bootstrap-fileinput v5.5.2
|
||||
* http://plugins.krajee.com/file-input
|
||||
*
|
||||
* Krajee default styling for bootstrap-fileinput.
|
||||
*
|
||||
* Author: Kartik Visweswaran
|
||||
* Copyright: 2014 - 2022, Kartik Visweswaran, Krajee.com
|
||||
*
|
||||
* Licensed under the BSD-3-Clause
|
||||
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
.file-loading input[type=file],
|
||||
input[type=file].file-loading {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.file-no-browse {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 20%;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
font-size: 0;
|
||||
opacity: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.kv-hidden,
|
||||
.file-caption-icon,
|
||||
.file-zoom-dialog .modal-header:before,
|
||||
.file-zoom-dialog .modal-header:after,
|
||||
.file-input-new .file-preview,
|
||||
.file-input-new .close,
|
||||
.file-input-new .glyphicon-file,
|
||||
.file-input-new .fileinput-remove-button,
|
||||
.file-input-new .fileinput-upload-button,
|
||||
.file-input-new .no-browse .input-group-btn,
|
||||
.file-input-ajax-new .fileinput-remove-button,
|
||||
.file-input-ajax-new .fileinput-upload-button,
|
||||
.file-input-ajax-new .no-browse .input-group-btn,
|
||||
.hide-content .kv-file-content,
|
||||
.is-locked .fileinput-upload-button,
|
||||
.is-locked .fileinput-remove-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-caption .input-group {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-file input[type=file],
|
||||
.file-caption-icon,
|
||||
.file-preview .fileinput-remove,
|
||||
.krajee-default .file-thumb-progress,
|
||||
.file-zoom-dialog .btn-navigate,
|
||||
.file-zoom-dialog .floating-buttons {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.file-caption-icon .kv-caption-icon {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.file-input,
|
||||
.file-loading:before,
|
||||
.btn-file,
|
||||
.file-caption,
|
||||
.file-preview,
|
||||
.krajee-default.file-preview-frame,
|
||||
.krajee-default .file-thumbnail-footer,
|
||||
.file-zoom-dialog .modal-dialog {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.file-error-message pre,
|
||||
.file-error-message ul,
|
||||
.krajee-default .file-actions,
|
||||
.krajee-default .file-other-error {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.file-error-message pre,
|
||||
.file-error-message ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.krajee-default .file-drag-handle,
|
||||
.krajee-default .file-upload-indicator {
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.file-thumb-progress .progress,
|
||||
.file-thumb-progress .progress-bar {
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.krajee-default .file-thumb-progress .progress,
|
||||
.kv-upload-progress .progress {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.krajee-default .file-caption-info,
|
||||
.krajee-default .file-size-info {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 160px;
|
||||
height: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.file-zoom-content > .file-object.type-video,
|
||||
.file-zoom-content > .file-object.type-flash,
|
||||
.file-zoom-content > .file-object.type-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.file-zoom-content > .file-object.type-video,
|
||||
.file-zoom-content > .file-object.type-flash {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.file-zoom-content > .file-object.type-pdf,
|
||||
.file-zoom-content > .file-object.type-html,
|
||||
.file-zoom-content > .file-object.type-text,
|
||||
.file-zoom-content > .file-object.type-default {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.file-loading:before {
|
||||
content: " Loading...";
|
||||
display: inline-block;
|
||||
padding-left: 20px;
|
||||
line-height: 16px;
|
||||
font-size: 13px;
|
||||
font-variant: small-caps;
|
||||
color: #999;
|
||||
background: transparent url(loading.gif) top left no-repeat;
|
||||
}
|
||||
|
||||
.file-object {
|
||||
margin: 0 0 -5px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.btn-file {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn-file input[type=file] {
|
||||
top: 0;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
text-align: right;
|
||||
opacity: 0;
|
||||
background: none repeat scroll 0 0 transparent;
|
||||
cursor: inherit;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.btn-file ::-ms-browse {
|
||||
font-size: 10000px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.file-caption.icon-visible .file-caption-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.file-caption.icon-visible .file-caption-name {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.file-caption.icon-visible > .input-group-lg .file-caption-name {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.file-caption.icon-visible > .input-group-sm .file-caption-name {
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.file-caption-name:not(.file-caption-disabled) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.file-caption-name.file-processing {
|
||||
font-style: italic;
|
||||
border-color: #bbb;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.file-caption-icon {
|
||||
padding: 7px 5px;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.input-group-lg .file-caption-icon {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.input-group-sm .file-caption-icon {
|
||||
font-size: 0.875rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.file-error-message {
|
||||
color: #a94442;
|
||||
background-color: #f2dede;
|
||||
margin: 5px;
|
||||
border: 1px solid #ebccd1;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.file-error-message pre {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.file-caption-disabled {
|
||||
background-color: #eee;
|
||||
cursor: not-allowed;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.file-preview {
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.file-preview .btn-xs {
|
||||
padding: 1px 5px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.file-preview .fileinput-remove {
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
line-height: 10px;
|
||||
}
|
||||
|
||||
.file-preview .clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-preview-image {
|
||||
font: 40px Impact, Charcoal, sans-serif;
|
||||
color: #008000;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.krajee-default.file-preview-frame {
|
||||
margin: 8px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
|
||||
padding: 6px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
.krajee-default.file-preview-frame .kv-file-content {
|
||||
width: 213px;
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.krajee-default.file-preview-frame[data-template="audio"] .kv-file-content {
|
||||
width: 240px;
|
||||
height: 55px;
|
||||
}
|
||||
|
||||
.krajee-default.file-preview-frame .file-thumbnail-footer {
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.krajee-default.file-preview-frame:not(.file-preview-error):hover {
|
||||
border: 1px solid rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.krajee-default .file-preview-text {
|
||||
color: #428bca;
|
||||
border: 1px solid #ddd;
|
||||
outline: none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.krajee-default .file-preview-html {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.krajee-default .file-other-icon {
|
||||
font-size: 6em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.krajee-default .file-footer-buttons {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.krajee-default .file-footer-caption {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding-top: 4px;
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.file-upload-stats {
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.kv-upload-progress .file-upload-stats {
|
||||
font-size: 12px;
|
||||
margin: -10px 0 5px;
|
||||
}
|
||||
|
||||
.krajee-default .file-preview-error {
|
||||
opacity: 0.65;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.krajee-default .file-thumb-progress {
|
||||
top: 37px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.krajee-default.kvsortable-ghost {
|
||||
background: #e1edf7;
|
||||
border: 2px solid #a1abff;
|
||||
}
|
||||
|
||||
.krajee-default .file-preview-other:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.kv-upload-progress .progress {
|
||||
height: 20px;
|
||||
margin: 10px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.kv-upload-progress .progress-bar {
|
||||
height: 20px;
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/*noinspection CssOverwrittenProperties*/
|
||||
|
||||
.file-zoom-dialog .file-other-icon {
|
||||
font-size: 22em;
|
||||
font-size: 50vmin;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .modal-dialog {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .btn-navigate {
|
||||
margin: 0 0.1rem;
|
||||
padding: 0;
|
||||
font-size: 1.2rem;
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
top: 50%;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-navigate * {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .floating-buttons {
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .btn-kv-prev {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .btn-kv-next {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .kv-zoom-header {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .kv-zoom-body {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .kv-zoom-description {
|
||||
position: absolute;
|
||||
opacity: 0.8;
|
||||
font-size: 0.8rem;
|
||||
background-color: #1a1a1a;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
border-radius: 0.5rem;
|
||||
color: #fff;
|
||||
left: 15%;
|
||||
right: 15%;
|
||||
bottom: 15%;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .kv-desc-hide {
|
||||
float: right;
|
||||
color: #fff;
|
||||
padding: 0 0.1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .kv-desc-hide:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .kv-desc-hide:focus {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.file-input-new .no-browse .form-control {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
.file-input-ajax-new .no-browse .form-control {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
.file-caption {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.file-thumb-loading {
|
||||
background: transparent url(loading.gif) no-repeat scroll center center content-box !important;
|
||||
}
|
||||
|
||||
.file-drop-zone {
|
||||
border: 1px dashed #aaa;
|
||||
min-height: 260px;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
margin: 12px 15px 12px 12px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.file-drop-zone.clickable:hover {
|
||||
border: 2px dashed #999;
|
||||
}
|
||||
|
||||
.file-drop-zone.clickable:focus {
|
||||
border: 2px solid #5acde2;
|
||||
}
|
||||
|
||||
.file-drop-zone .file-preview-thumbnails {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.file-drop-zone-title {
|
||||
color: #aaa;
|
||||
font-size: 1.6em;
|
||||
text-align: center;
|
||||
padding: 85px 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.file-highlighted {
|
||||
border: 2px dashed #999 !important;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.file-uploading {
|
||||
background: url(loading-sm.gif) no-repeat center bottom 10px;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.file-zoom-fullscreen .modal-dialog {
|
||||
min-width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.file-zoom-fullscreen .modal-content {
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.file-zoom-fullscreen .kv-zoom-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.floating-buttons {
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
.floating-buttons .btn-kv {
|
||||
margin-left: 3px;
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
.kv-zoom-actions {
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
.kv-zoom-actions .btn-kv {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.file-zoom-content {
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.file-zoom-content:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.file-zoom-content .file-preview-image {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.file-zoom-content .file-preview-video {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.file-zoom-content > .file-object.type-image {
|
||||
height: auto;
|
||||
min-height: inherit;
|
||||
}
|
||||
|
||||
.file-zoom-content > .file-object.type-audio {
|
||||
width: auto;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.file-zoom-dialog .modal-dialog {
|
||||
max-width: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.file-zoom-dialog .modal-lg {
|
||||
max-width: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.file-preview-thumbnails {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.file-zoom-dialog .modal-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 350px) {
|
||||
.krajee-default.file-preview-frame:not([data-template="audio"]) .kv-file-content {
|
||||
width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.file-loading[dir=rtl]:before {
|
||||
background: transparent url(loading.gif) top right no-repeat;
|
||||
padding-left: 0;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.clickable .file-drop-zone-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-sortable .file-drag-handle:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.file-sortable .file-drag-handle {
|
||||
cursor: grab;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.file-grabbing,
|
||||
.file-grabbing * {
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
.file-grabbing .file-preview-thumbnails * {
|
||||
cursor: grabbing !important;
|
||||
}
|
||||
|
||||
.file-preview-frame.sortable-chosen {
|
||||
background-color: #d9edf7;
|
||||
border-color: #17a2b8;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.file-preview .kv-zoom-cache {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.file-preview-other-frame, .file-preview-object, .kv-file-content, .kv-zoom-body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn-kv-rotate,
|
||||
.kv-file-rotate {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.rotatable:not(.hide-rotate) .btn-kv-rotate,
|
||||
.rotatable:not(.hide-rotate) .kv-file-rotate {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.rotatable .file-zoom-detail,
|
||||
.rotatable .kv-file-content,
|
||||
.rotatable .kv-file-content > :first-child {
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
.rotate-animate {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.kv-overflow-hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 847 B |
@ -0,0 +1,459 @@
|
||||
/*!
|
||||
* Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select)
|
||||
*
|
||||
* Copyright 2012-2020 SnapAppointments, LLC
|
||||
* Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
@-webkit-keyframes bs-notify-fadeOut {
|
||||
0% {
|
||||
opacity: 0.9;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-o-keyframes bs-notify-fadeOut {
|
||||
0% {
|
||||
opacity: 0.9;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes bs-notify-fadeOut {
|
||||
0% {
|
||||
opacity: 0.9;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
select.bs-select-hidden,
|
||||
.bootstrap-select > select.bs-select-hidden,
|
||||
select.selectpicker {
|
||||
display: none !important;
|
||||
}
|
||||
.bootstrap-select {
|
||||
width: 220px \0;
|
||||
/*IE9 and below*/
|
||||
vertical-align: middle;
|
||||
}
|
||||
.bootstrap-select > .dropdown-toggle {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.bootstrap-select > .dropdown-toggle:after {
|
||||
margin-top: -1px;
|
||||
}
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder:active {
|
||||
color: #999;
|
||||
}
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:hover,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:hover,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:hover,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:hover,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:hover,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:hover,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:focus,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:focus,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:focus,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:focus,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:focus,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:focus,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:active,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:active,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:active,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:active,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:active,
|
||||
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:active {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.bootstrap-select > select {
|
||||
position: absolute !important;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
display: block !important;
|
||||
width: 0.5px !important;
|
||||
height: 100% !important;
|
||||
padding: 0 !important;
|
||||
opacity: 0 !important;
|
||||
border: none;
|
||||
z-index: 0 !important;
|
||||
}
|
||||
.bootstrap-select > select.mobile-device {
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
z-index: 2 !important;
|
||||
}
|
||||
.has-error .bootstrap-select .dropdown-toggle,
|
||||
.error .bootstrap-select .dropdown-toggle,
|
||||
.bootstrap-select.is-invalid .dropdown-toggle,
|
||||
.was-validated .bootstrap-select select:invalid + .dropdown-toggle {
|
||||
border-color: #b94a48;
|
||||
}
|
||||
.bootstrap-select.is-valid .dropdown-toggle,
|
||||
.was-validated .bootstrap-select select:valid + .dropdown-toggle {
|
||||
border-color: #28a745;
|
||||
}
|
||||
.bootstrap-select.fit-width {
|
||||
width: auto !important;
|
||||
}
|
||||
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
|
||||
width: 220px;
|
||||
}
|
||||
.bootstrap-select > select.mobile-device:focus + .dropdown-toggle,
|
||||
.bootstrap-select .dropdown-toggle:focus {
|
||||
outline: thin dotted #333333 !important;
|
||||
outline: 5px auto -webkit-focus-ring-color !important;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.bootstrap-select.form-control {
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
height: auto;
|
||||
}
|
||||
:not(.input-group) > .bootstrap-select.form-control:not([class*="col-"]) {
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-select.form-control.input-group-btn {
|
||||
float: none;
|
||||
z-index: auto;
|
||||
}
|
||||
.form-inline .bootstrap-select,
|
||||
.form-inline .bootstrap-select.form-control:not([class*="col-"]) {
|
||||
width: auto;
|
||||
}
|
||||
.bootstrap-select:not(.input-group-btn),
|
||||
.bootstrap-select[class*="col-"] {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
margin-left: 0;
|
||||
}
|
||||
.bootstrap-select.dropdown-menu-right,
|
||||
.bootstrap-select[class*="col-"].dropdown-menu-right,
|
||||
.row .bootstrap-select[class*="col-"].dropdown-menu-right {
|
||||
float: right;
|
||||
}
|
||||
.form-inline .bootstrap-select,
|
||||
.form-horizontal .bootstrap-select,
|
||||
.form-group .bootstrap-select {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.form-group-lg .bootstrap-select.form-control,
|
||||
.form-group-sm .bootstrap-select.form-control {
|
||||
padding: 0;
|
||||
}
|
||||
.form-group-lg .bootstrap-select.form-control .dropdown-toggle,
|
||||
.form-group-sm .bootstrap-select.form-control .dropdown-toggle {
|
||||
height: 100%;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
border-radius: inherit;
|
||||
}
|
||||
.bootstrap-select.form-control-sm .dropdown-toggle,
|
||||
.bootstrap-select.form-control-lg .dropdown-toggle {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
border-radius: inherit;
|
||||
}
|
||||
.bootstrap-select.form-control-sm .dropdown-toggle {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.bootstrap-select.form-control-lg .dropdown-toggle {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
.form-inline .bootstrap-select .form-control {
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-select.disabled,
|
||||
.bootstrap-select > .disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-select.disabled:focus,
|
||||
.bootstrap-select > .disabled:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
.bootstrap-select.bs-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.bootstrap-select.bs-container .dropdown-menu {
|
||||
z-index: 1060;
|
||||
}
|
||||
.bootstrap-select .dropdown-toggle .filter-option {
|
||||
position: static;
|
||||
top: 0;
|
||||
left: 0;
|
||||
float: left;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
-webkit-box-flex: 0;
|
||||
-webkit-flex: 0 1 auto;
|
||||
-ms-flex: 0 1 auto;
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
.bs3.bootstrap-select .dropdown-toggle .filter-option {
|
||||
padding-right: inherit;
|
||||
}
|
||||
.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option {
|
||||
position: absolute;
|
||||
padding-top: inherit;
|
||||
padding-bottom: inherit;
|
||||
padding-left: inherit;
|
||||
float: none;
|
||||
}
|
||||
.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner {
|
||||
padding-right: inherit;
|
||||
}
|
||||
.bootstrap-select .dropdown-toggle .filter-option-inner-inner {
|
||||
overflow: hidden;
|
||||
}
|
||||
.bootstrap-select .dropdown-toggle .filter-expand {
|
||||
width: 0 !important;
|
||||
float: left;
|
||||
opacity: 0 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
.bootstrap-select .dropdown-toggle .caret {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 12px;
|
||||
margin-top: -2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.input-group .bootstrap-select.form-control .dropdown-toggle {
|
||||
border-radius: inherit;
|
||||
}
|
||||
.bootstrap-select[class*="col-"] .dropdown-toggle {
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu {
|
||||
min-width: 100%;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu > .inner:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu.inner {
|
||||
position: static;
|
||||
float: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li {
|
||||
position: relative;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li.active small {
|
||||
color: rgba(255, 255, 255, 0.5) !important;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li.disabled a {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li a {
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li a.opt {
|
||||
position: relative;
|
||||
padding-left: 2.25em;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li a span.check-mark {
|
||||
display: none;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li a span.text {
|
||||
display: inline-block;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu li small {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu .notify {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
width: 96%;
|
||||
margin: 0 2%;
|
||||
min-height: 26px;
|
||||
padding: 3px 5px;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #e3e3e3;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||
pointer-events: none;
|
||||
opacity: 0.9;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.bootstrap-select .dropdown-menu .notify.fadeOut {
|
||||
-webkit-animation: 300ms linear 750ms forwards bs-notify-fadeOut;
|
||||
-o-animation: 300ms linear 750ms forwards bs-notify-fadeOut;
|
||||
animation: 300ms linear 750ms forwards bs-notify-fadeOut;
|
||||
}
|
||||
.bootstrap-select .no-results {
|
||||
padding: 3px;
|
||||
background: #f5f5f5;
|
||||
margin: 0 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.bootstrap-select.fit-width .dropdown-toggle .filter-option {
|
||||
position: static;
|
||||
display: inline;
|
||||
padding: 0;
|
||||
}
|
||||
.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner,
|
||||
.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner {
|
||||
display: inline;
|
||||
}
|
||||
.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before {
|
||||
content: '\00a0';
|
||||
}
|
||||
.bootstrap-select.fit-width .dropdown-toggle .caret {
|
||||
position: static;
|
||||
top: auto;
|
||||
margin-top: -1px;
|
||||
}
|
||||
.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
right: 15px;
|
||||
top: 5px;
|
||||
}
|
||||
.bootstrap-select.show-tick .dropdown-menu li a span.text {
|
||||
margin-right: 34px;
|
||||
}
|
||||
.bootstrap-select .bs-ok-default:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0.5em;
|
||||
height: 1em;
|
||||
border-style: solid;
|
||||
border-width: 0 0.26em 0.26em 0;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
transform-style: preserve-3d;
|
||||
-webkit-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle,
|
||||
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle {
|
||||
z-index: 1061;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before {
|
||||
content: '';
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid rgba(204, 204, 204, 0.2);
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 9px;
|
||||
display: none;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after {
|
||||
content: '';
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid white;
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 10px;
|
||||
display: none;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before {
|
||||
bottom: auto;
|
||||
top: -4px;
|
||||
border-top: 7px solid rgba(204, 204, 204, 0.2);
|
||||
border-bottom: 0;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after {
|
||||
bottom: auto;
|
||||
top: -4px;
|
||||
border-top: 6px solid white;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before {
|
||||
right: 12px;
|
||||
left: auto;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after {
|
||||
right: 13px;
|
||||
left: auto;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:before,
|
||||
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:before,
|
||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:after,
|
||||
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:after {
|
||||
display: block;
|
||||
}
|
||||
.bs-searchbox,
|
||||
.bs-actionsbox,
|
||||
.bs-donebutton {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
.bs-actionsbox {
|
||||
width: 100%;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.bs-actionsbox .btn-group button {
|
||||
width: 50%;
|
||||
}
|
||||
.bs-donebutton {
|
||||
float: left;
|
||||
width: 100%;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.bs-donebutton .btn-group button {
|
||||
width: 100%;
|
||||
}
|
||||
.bs-searchbox + .bs-actionsbox {
|
||||
padding: 0 8px 4px;
|
||||
}
|
||||
.bs-searchbox .form-control {
|
||||
margin-bottom: 0;
|
||||
width: 100%;
|
||||
float: none;
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @author: Alec Fenichel
|
||||
* @webSite: https://fenichelar.com
|
||||
* @update: zhixin wen <wenzhixin2010@gmail.com>
|
||||
*/
|
||||
|
||||
var Utils = $.fn.bootstrapTable.utils
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
autoRefresh: false,
|
||||
showAutoRefresh: true,
|
||||
autoRefreshInterval: 60,
|
||||
autoRefreshSilent: true,
|
||||
autoRefreshStatus: true,
|
||||
autoRefreshFunction: null
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||
autoRefresh: {
|
||||
bootstrap3: 'glyphicon-time icon-time',
|
||||
bootstrap5: 'bi-clock',
|
||||
materialize: 'access_time',
|
||||
'bootstrap-table': 'icon-clock'
|
||||
}[$.fn.bootstrapTable.theme] || 'fa-clock'
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.locales, {
|
||||
formatAutoRefresh () {
|
||||
return 'Auto Refresh'
|
||||
}
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
init (...args) {
|
||||
super.init(...args)
|
||||
|
||||
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
|
||||
this.setupRefreshInterval()
|
||||
}
|
||||
}
|
||||
|
||||
initToolbar (...args) {
|
||||
if (this.options.autoRefresh) {
|
||||
this.buttons = Object.assign(this.buttons, {
|
||||
autoRefresh: {
|
||||
html: `
|
||||
<button class="auto-refresh ${this.constants.buttonsClass}
|
||||
${this.options.autoRefreshStatus ? ` ${this.constants.classes.buttonActive}` : ''}"
|
||||
type="button" name="autoRefresh" title="${this.options.formatAutoRefresh()}">
|
||||
${ this.options.showButtonIcons ? Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, this.options.icons.autoRefresh) : ''}
|
||||
${ this.options.showButtonText ? this.options.formatAutoRefresh() : ''}
|
||||
</button>
|
||||
`,
|
||||
event: this.toggleAutoRefresh
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
super.initToolbar(...args)
|
||||
}
|
||||
|
||||
toggleAutoRefresh () {
|
||||
if (this.options.autoRefresh) {
|
||||
if (this.options.autoRefreshStatus) {
|
||||
clearInterval(this.options.autoRefreshFunction)
|
||||
this.$toolbar.find('>.columns .auto-refresh')
|
||||
.removeClass(this.constants.classes.buttonActive)
|
||||
} else {
|
||||
this.setupRefreshInterval()
|
||||
this.$toolbar.find('>.columns .auto-refresh')
|
||||
.addClass(this.constants.classes.buttonActive)
|
||||
}
|
||||
this.options.autoRefreshStatus = !this.options.autoRefreshStatus
|
||||
}
|
||||
}
|
||||
|
||||
destroy () {
|
||||
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
|
||||
clearInterval(this.options.autoRefreshFunction)
|
||||
}
|
||||
|
||||
super.destroy()
|
||||
}
|
||||
|
||||
setupRefreshInterval () {
|
||||
this.options.autoRefreshFunction = setInterval(() => {
|
||||
if (!this.options.autoRefresh || !this.options.autoRefreshStatus) {
|
||||
return
|
||||
}
|
||||
this.refresh({ silent: this.options.autoRefreshSilent })
|
||||
}, this.options.autoRefreshInterval * 1000)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @author: Dustin Utecht
|
||||
* @github: https://github.com/UtechtDustin
|
||||
*/
|
||||
|
||||
var Utils = $.fn.bootstrapTable.utils
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
customView: false,
|
||||
showCustomView: false,
|
||||
showCustomViewButton: false
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||
customView: {
|
||||
bootstrap3: 'glyphicon glyphicon-eye-open',
|
||||
bootstrap5: 'bi-eye',
|
||||
bootstrap4: 'fa fa-eye',
|
||||
semantic: 'fa fa-eye',
|
||||
foundation: 'fa fa-eye',
|
||||
bulma: 'fa fa-eye',
|
||||
materialize: 'remove_red_eye'
|
||||
}[$.fn.bootstrapTable.theme] || 'fa-eye'
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
onCustomViewPostBody () {
|
||||
return false
|
||||
},
|
||||
onCustomViewPreBody () {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.locales, {
|
||||
formatToggleCustomView () {
|
||||
return 'Toggle custom view'
|
||||
}
|
||||
})
|
||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
||||
|
||||
$.fn.bootstrapTable.methods.push('toggleCustomView')
|
||||
|
||||
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||
'custom-view-post-body.bs.table': 'onCustomViewPostBody',
|
||||
'custom-view-pre-body.bs.table': 'onCustomViewPreBody'
|
||||
})
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
|
||||
init () {
|
||||
this.showCustomView = this.options.showCustomView
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
initToolbar (...args) {
|
||||
if (this.options.customView && this.options.showCustomViewButton) {
|
||||
this.buttons = Object.assign(this.buttons, {
|
||||
customView: {
|
||||
text: this.options.formatToggleCustomView(),
|
||||
icon: this.options.icons.customView,
|
||||
event: this.toggleCustomView,
|
||||
attributes: {
|
||||
'aria-label': this.options.formatToggleCustomView(),
|
||||
title: this.options.formatToggleCustomView()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
super.initToolbar(...args)
|
||||
}
|
||||
|
||||
initBody () {
|
||||
super.initBody()
|
||||
|
||||
if (!this.options.customView) {
|
||||
return
|
||||
}
|
||||
|
||||
const $table = this.$el
|
||||
const $customViewContainer = this.$container.find('.fixed-table-custom-view')
|
||||
|
||||
$table.hide()
|
||||
$customViewContainer.hide()
|
||||
if (!this.options.customView || !this.showCustomView) {
|
||||
$table.show()
|
||||
return
|
||||
}
|
||||
|
||||
const data = this.getData().slice(this.pageFrom - 1, this.pageTo)
|
||||
const value = Utils.calculateObjectValue(this, this.options.customView, [data], '')
|
||||
|
||||
this.trigger('custom-view-pre-body', data, value)
|
||||
if ($customViewContainer.length === 1) {
|
||||
$customViewContainer.show().html(value)
|
||||
} else {
|
||||
this.$tableBody.after(`<div class="fixed-table-custom-view">${value}</div>`)
|
||||
}
|
||||
|
||||
this.trigger('custom-view-post-body', data, value)
|
||||
}
|
||||
|
||||
toggleCustomView () {
|
||||
this.showCustomView = !this.showCustomView
|
||||
this.initBody()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,674 @@
|
||||
/*! X-editable - v1.5.3
|
||||
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
||||
* http://github.com/vitalets/x-editable
|
||||
* Copyright (c) 2019 Vitaliy Potapov; Licensed MIT */
|
||||
.editableform {
|
||||
margin-bottom: 0; /* overwrites bootstrap margin */
|
||||
}
|
||||
|
||||
.editableform .control-group {
|
||||
margin-bottom: 0; /* overwrites bootstrap margin */
|
||||
white-space: nowrap; /* prevent wrapping buttons on new line */
|
||||
line-height: 20px; /* overwriting bootstrap line-height. See #133 */
|
||||
}
|
||||
|
||||
/*
|
||||
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
|
||||
See: https://github.com/vitalets/x-editable/issues/682
|
||||
*/
|
||||
.form-horizontal .editable-popup .editableform .form-group {
|
||||
margin-left:0;
|
||||
margin-right:0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
BS3 width:1005 for inputs breaks editable form in popup
|
||||
See: https://github.com/vitalets/x-editable/issues/393
|
||||
*/
|
||||
.editableform .form-control {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.editable-buttons {
|
||||
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
|
||||
vertical-align: top;
|
||||
margin-left: 7px;
|
||||
/* inline-block emulation for IE7*/
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
}
|
||||
|
||||
.editable-buttons.editable-buttons-bottom {
|
||||
display: block;
|
||||
margin-top: 7px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.editable-input {
|
||||
vertical-align: top;
|
||||
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
|
||||
width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
|
||||
white-space: normal; /* reset white-space decalred in parent*/
|
||||
/* display-inline emulation for IE7*/
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
}
|
||||
|
||||
.editable-buttons .editable-cancel {
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
/*for jquery-ui buttons need set height to look more pretty*/
|
||||
.editable-buttons button.ui-button-icon-only {
|
||||
height: 24px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.editableform-loading {
|
||||
background: url('loading.gif') center center no-repeat;
|
||||
height: 25px;
|
||||
width: auto;
|
||||
min-width: 25px;
|
||||
}
|
||||
|
||||
.editable-inline .editableform-loading {
|
||||
background-position: left 5px;
|
||||
}
|
||||
|
||||
.editable-error-block {
|
||||
max-width: 300px;
|
||||
margin: 5px 0 0 0;
|
||||
width: auto;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/*add padding for jquery ui*/
|
||||
.editable-error-block.ui-state-error {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.editable-error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* ---- For specific types ---- */
|
||||
|
||||
.editableform .editable-date {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */
|
||||
.editable-inline .add-on .icon-th {
|
||||
margin-top: 3px;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
|
||||
/* checklist vertical alignment */
|
||||
.editable-checklist label input[type="checkbox"],
|
||||
.editable-checklist label span {
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.editable-checklist label {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* set exact width of textarea to fit buttons toolbar */
|
||||
.editable-wysihtml5 {
|
||||
width: 566px;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
/* clear button shown as link in date inputs */
|
||||
.editable-clear {
|
||||
clear: both;
|
||||
font-size: 0.9em;
|
||||
text-decoration: none;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* IOS-style clear button for text inputs */
|
||||
.editable-clear-x {
|
||||
background: url('clear.png') center center no-repeat;
|
||||
display: block;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
position: absolute;
|
||||
opacity: 0.6;
|
||||
z-index: 100;
|
||||
|
||||
top: 50%;
|
||||
right: 6px;
|
||||
margin-top: -6px;
|
||||
|
||||
}
|
||||
|
||||
.editable-clear-x:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editable-pre-wrapped {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.editable-container.editable-popup {
|
||||
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
|
||||
}
|
||||
|
||||
.editable-container.popover {
|
||||
width: auto; /* without this rule popover does not stretch */
|
||||
}
|
||||
|
||||
.editable-container.editable-inline {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: auto;
|
||||
/* inline-block emulation for IE7*/
|
||||
zoom: 1;
|
||||
*display: inline;
|
||||
}
|
||||
|
||||
.editable-container.ui-widget {
|
||||
font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
|
||||
z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */
|
||||
}
|
||||
.editable-click,
|
||||
a.editable-click,
|
||||
a.editable-click:hover {
|
||||
text-decoration: none;
|
||||
border-bottom: dashed 1px #0088cc;
|
||||
}
|
||||
|
||||
.editable-click.editable-disabled,
|
||||
a.editable-click.editable-disabled,
|
||||
a.editable-click.editable-disabled:hover {
|
||||
color: #585858;
|
||||
cursor: default;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.editable-empty, .editable-empty:hover, .editable-empty:focus{
|
||||
font-style: italic;
|
||||
color: #DD1144;
|
||||
/* border-bottom: none; */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.editable-unsaved {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.editable-unsaved:after {
|
||||
/* content: '*'*/
|
||||
}
|
||||
|
||||
.editable-bg-transition {
|
||||
-webkit-transition: background-color 1400ms ease-out;
|
||||
-moz-transition: background-color 1400ms ease-out;
|
||||
-o-transition: background-color 1400ms ease-out;
|
||||
-ms-transition: background-color 1400ms ease-out;
|
||||
transition: background-color 1400ms ease-out;
|
||||
}
|
||||
|
||||
/*see https://github.com/vitalets/x-editable/issues/139 */
|
||||
.form-horizontal .editable
|
||||
{
|
||||
padding-top: 5px;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Datepicker for Bootstrap
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Improvements by Andrew Rowls
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
.datepicker {
|
||||
padding: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
direction: ltr;
|
||||
/*.dow {
|
||||
border-top: 1px solid #ddd !important;
|
||||
}*/
|
||||
|
||||
}
|
||||
.datepicker-inline {
|
||||
width: 220px;
|
||||
}
|
||||
.datepicker.datepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.datepicker.datepicker-rtl table tr td span {
|
||||
float: right;
|
||||
}
|
||||
.datepicker-dropdown {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.datepicker-dropdown:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
.datepicker-dropdown:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #ffffff;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
.datepicker > div {
|
||||
display: none;
|
||||
}
|
||||
.datepicker.days div.datepicker-days {
|
||||
display: block;
|
||||
}
|
||||
.datepicker.months div.datepicker-months {
|
||||
display: block;
|
||||
}
|
||||
.datepicker.years div.datepicker-years {
|
||||
display: block;
|
||||
}
|
||||
.datepicker table {
|
||||
margin: 0;
|
||||
}
|
||||
.datepicker td,
|
||||
.datepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
.table-striped .datepicker table tr td,
|
||||
.table-striped .datepicker table tr th {
|
||||
background-color: transparent;
|
||||
}
|
||||
.datepicker table tr td.day:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker table tr td.old,
|
||||
.datepicker table tr td.new {
|
||||
color: #999999;
|
||||
}
|
||||
.datepicker table tr td.disabled,
|
||||
.datepicker table tr td.disabled:hover {
|
||||
background: none;
|
||||
color: #999999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td.today,
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today.disabled:hover {
|
||||
background-color: #fde19a;
|
||||
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||
border-color: #fdf59a #fdf59a #fbed50;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today:hover:hover,
|
||||
.datepicker table tr td.today.disabled:hover,
|
||||
.datepicker table tr td.today.disabled:hover:hover,
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today:hover.disabled,
|
||||
.datepicker table tr td.today.disabled.disabled,
|
||||
.datepicker table tr td.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.today[disabled],
|
||||
.datepicker table tr td.today:hover[disabled],
|
||||
.datepicker table tr td.today.disabled[disabled],
|
||||
.datepicker table tr td.today.disabled:hover[disabled] {
|
||||
background-color: #fdf59a;
|
||||
}
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active {
|
||||
background-color: #fbf069 \9;
|
||||
}
|
||||
.datepicker table tr td.today:hover:hover {
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today.active:hover {
|
||||
color: #fff;
|
||||
}
|
||||
.datepicker table tr td.range,
|
||||
.datepicker table tr td.range:hover,
|
||||
.datepicker table tr td.range.disabled,
|
||||
.datepicker table tr td.range.disabled:hover {
|
||||
background: #eeeeee;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today,
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover {
|
||||
background-color: #f3d17a;
|
||||
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
|
||||
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
|
||||
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
|
||||
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
|
||||
background-image: linear-gradient(top, #f3c17a, #f3e97a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
|
||||
border-color: #f3e97a #f3e97a #edde34;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today:hover:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover:hover,
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today:hover.disabled,
|
||||
.datepicker table tr td.range.today.disabled.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.range.today[disabled],
|
||||
.datepicker table tr td.range.today:hover[disabled],
|
||||
.datepicker table tr td.range.today.disabled[disabled],
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled] {
|
||||
background-color: #f3e97a;
|
||||
}
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active {
|
||||
background-color: #efe24b \9;
|
||||
}
|
||||
.datepicker table tr td.selected,
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover {
|
||||
background-color: #9e9e9e;
|
||||
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
|
||||
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
|
||||
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
|
||||
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
|
||||
background-image: linear-gradient(top, #b3b3b3, #808080);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
|
||||
border-color: #808080 #808080 #595959;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected:hover:hover,
|
||||
.datepicker table tr td.selected.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled:hover:hover,
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected:hover.disabled,
|
||||
.datepicker table tr td.selected.disabled.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled,
|
||||
.datepicker table tr td.selected[disabled],
|
||||
.datepicker table tr td.selected:hover[disabled],
|
||||
.datepicker table tr td.selected.disabled[disabled],
|
||||
.datepicker table tr td.selected.disabled:hover[disabled] {
|
||||
background-color: #808080;
|
||||
}
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active {
|
||||
background-color: #666666 \9;
|
||||
}
|
||||
.datepicker table tr td.active,
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active:hover:hover,
|
||||
.datepicker table tr td.active.disabled:hover,
|
||||
.datepicker table tr td.active.disabled:hover:hover,
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active:hover.disabled,
|
||||
.datepicker table tr td.active.disabled.disabled,
|
||||
.datepicker table tr td.active.disabled:hover.disabled,
|
||||
.datepicker table tr td.active[disabled],
|
||||
.datepicker table tr td.active:hover[disabled],
|
||||
.datepicker table tr td.active.disabled[disabled],
|
||||
.datepicker table tr td.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span {
|
||||
display: block;
|
||||
width: 23%;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 1%;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker table tr td span:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.datepicker table tr td span.disabled,
|
||||
.datepicker table tr td span.disabled:hover {
|
||||
background: none;
|
||||
color: #999999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td span.active,
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active:hover:hover,
|
||||
.datepicker table tr td span.active.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled:hover:hover,
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active:hover.disabled,
|
||||
.datepicker table tr td span.active.disabled.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled,
|
||||
.datepicker table tr td span.active[disabled],
|
||||
.datepicker table tr td span.active:hover[disabled],
|
||||
.datepicker table tr td span.active.disabled[disabled],
|
||||
.datepicker table tr td span.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span.old,
|
||||
.datepicker table tr td span.new {
|
||||
color: #999999;
|
||||
}
|
||||
.datepicker th.datepicker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.datepicker thead tr:first-child th,
|
||||
.datepicker tfoot tr th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker thead tr:first-child th:hover,
|
||||
.datepicker tfoot tr th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.datepicker .cw {
|
||||
font-size: 10px;
|
||||
width: 12px;
|
||||
padding: 0 2px 0 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.datepicker thead tr:first-child th.cw {
|
||||
cursor: default;
|
||||
background-color: transparent;
|
||||
}
|
||||
.input-append.date .add-on i,
|
||||
.input-prepend.date .add-on i {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.input-daterange input {
|
||||
text-align: center;
|
||||
}
|
||||
.input-daterange input:first-child {
|
||||
-webkit-border-radius: 3px 0 0 3px;
|
||||
-moz-border-radius: 3px 0 0 3px;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
.input-daterange input:last-child {
|
||||
-webkit-border-radius: 0 3px 3px 0;
|
||||
-moz-border-radius: 0 3px 3px 0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.input-daterange .add-on {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
min-width: 16px;
|
||||
height: 18px;
|
||||
padding: 4px 5px;
|
||||
font-weight: normal;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #ffffff;
|
||||
vertical-align: middle;
|
||||
background-color: #eeeeee;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
@ -0,0 +1,189 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/**
|
||||
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||
* extensions: https://github.com/vitalets/x-editable
|
||||
*/
|
||||
|
||||
var Utils = $.fn.bootstrapTable.utils
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
editable: true,
|
||||
onEditableInit () {
|
||||
return false
|
||||
},
|
||||
onEditableSave (field, row, rowIndex, oldValue, $el) {
|
||||
return false
|
||||
},
|
||||
onEditableShown (field, row, $el, editable) {
|
||||
return false
|
||||
},
|
||||
onEditableHidden (field, row, $el, reason) {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.columnDefaults, {
|
||||
alwaysUseFormatter: false
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.events, {
|
||||
'editable-init.bs.table': 'onEditableInit',
|
||||
'editable-save.bs.table': 'onEditableSave',
|
||||
'editable-shown.bs.table': 'onEditableShown',
|
||||
'editable-hidden.bs.table': 'onEditableHidden'
|
||||
})
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
initTable () {
|
||||
super.initTable()
|
||||
|
||||
if (!this.options.editable) {
|
||||
return
|
||||
}
|
||||
|
||||
this.editedCells = []
|
||||
$.each(this.columns, (i, column) => {
|
||||
if (!column.editable) {
|
||||
return
|
||||
}
|
||||
|
||||
const editableOptions = {}
|
||||
const editableDataMarkup = []
|
||||
const editableDataPrefix = 'editable-'
|
||||
const processDataOptions = (key, value) => {
|
||||
// Replace camel case with dashes.
|
||||
const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
|
||||
|
||||
if (dashKey.indexOf(editableDataPrefix) === 0) {
|
||||
editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
|
||||
}
|
||||
}
|
||||
|
||||
$.each(this.options, processDataOptions)
|
||||
|
||||
column.formatter = column.formatter || (value => value)
|
||||
column._formatter = column._formatter ? column._formatter : column.formatter
|
||||
column.formatter = (value, row, index, field) => {
|
||||
let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
|
||||
|
||||
result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
|
||||
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
|
||||
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
|
||||
|
||||
if ($.inArray(column.field + uniqueId, this.editedCells) !== -1) {
|
||||
result = value
|
||||
}
|
||||
}
|
||||
|
||||
$.each(column, processDataOptions)
|
||||
|
||||
$.each(editableOptions, (key, value) => {
|
||||
editableDataMarkup.push(` ${key}="${value}"`)
|
||||
})
|
||||
|
||||
let noEditFormatter = false
|
||||
const editableOpts = Utils.calculateObjectValue(column,
|
||||
column.editable, [index, row], {})
|
||||
|
||||
if (editableOpts.hasOwnProperty('noEditFormatter')) {
|
||||
noEditFormatter = editableOpts.noEditFormatter(value, row, index, field)
|
||||
}
|
||||
|
||||
if (noEditFormatter === false) {
|
||||
return `<a href="javascript:void(0)"
|
||||
data-name="${column.field}"
|
||||
data-pk="${row[this.options.idField]}"
|
||||
data-value="${result}"
|
||||
${editableDataMarkup.join('')}></a>`
|
||||
}
|
||||
return noEditFormatter
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
initBody (fixedScroll) {
|
||||
super.initBody(fixedScroll)
|
||||
|
||||
if (!this.options.editable) {
|
||||
return
|
||||
}
|
||||
|
||||
$.each(this.columns, (i, column) => {
|
||||
if (!column.editable) {
|
||||
return
|
||||
}
|
||||
|
||||
const data = this.getData({ escape: true })
|
||||
const $field = this.$body.find(`a[data-name="${column.field}"]`)
|
||||
|
||||
$field.each((i, element) => {
|
||||
const $element = $(element)
|
||||
const $tr = $element.closest('tr')
|
||||
const index = $tr.data('index')
|
||||
const row = data[index]
|
||||
|
||||
const editableOpts = Utils.calculateObjectValue(column,
|
||||
column.editable, [index, row, $element], {})
|
||||
|
||||
$element.editable(editableOpts)
|
||||
})
|
||||
|
||||
$field.off('save').on('save', ({ currentTarget }, { submitValue }) => {
|
||||
const $this = $(currentTarget)
|
||||
const data = this.getData()
|
||||
const rowIndex = $this.parents('tr[data-index]').data('index')
|
||||
const row = data[rowIndex]
|
||||
const oldValue = row[column.field]
|
||||
|
||||
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
|
||||
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
|
||||
|
||||
if ($.inArray(column.field + uniqueId, this.editedCells) === -1) {
|
||||
this.editedCells.push(column.field + uniqueId)
|
||||
}
|
||||
}
|
||||
|
||||
submitValue = Utils.escapeHTML(submitValue)
|
||||
$this.data('value', submitValue)
|
||||
row[column.field] = submitValue
|
||||
this.trigger('editable-save', column.field, row, rowIndex, oldValue, $this)
|
||||
this.initBody()
|
||||
})
|
||||
|
||||
$field.off('shown').on('shown', ({ currentTarget }, editable) => {
|
||||
const $this = $(currentTarget)
|
||||
const data = this.getData()
|
||||
const rowIndex = $this.parents('tr[data-index]').data('index')
|
||||
const row = data[rowIndex]
|
||||
|
||||
this.trigger('editable-shown', column.field, row, $this, editable)
|
||||
})
|
||||
|
||||
$field.off('hidden').on('hidden', ({ currentTarget }, reason) => {
|
||||
const $this = $(currentTarget)
|
||||
const data = this.getData()
|
||||
const rowIndex = $this.parents('tr[data-index]').data('index')
|
||||
const row = data[rowIndex]
|
||||
|
||||
this.trigger('editable-hidden', column.field, row, $this, reason)
|
||||
})
|
||||
})
|
||||
this.trigger('editable-init')
|
||||
}
|
||||
|
||||
getData (params) {
|
||||
const data = super.getData(params)
|
||||
|
||||
if (params && params.escape) {
|
||||
for (const row of data) {
|
||||
for (const [key, value] of Object.entries(row)) {
|
||||
if (typeof(value) !== "number") {
|
||||
row[key] = Utils.unescapeHTML(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 1.8 KiB |
@ -0,0 +1,337 @@
|
||||
/**
|
||||
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||
* extensions: https://github.com/hhurz/tableExport.jquery.plugin
|
||||
*/
|
||||
|
||||
var Utils = $.fn.bootstrapTable.utils
|
||||
|
||||
const TYPE_NAME = {
|
||||
json: 'JSON',
|
||||
xml: 'XML',
|
||||
png: 'PNG',
|
||||
csv: 'CSV',
|
||||
txt: 'TXT',
|
||||
sql: 'SQL',
|
||||
doc: 'MS-Word',
|
||||
excel: 'MS-Excel',
|
||||
xlsx: 'MS-Excel (OpenXML)',
|
||||
powerpoint: 'MS-Powerpoint',
|
||||
pdf: 'PDF'
|
||||
}
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
showExport: false,
|
||||
exportDataType: 'basic', // basic, all, selected
|
||||
exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
|
||||
exportOptions: {
|
||||
onCellHtmlData (cell, rowIndex, colIndex, htmlData) {
|
||||
if (cell.is('th')) {
|
||||
return cell.find('.th-inner').text()
|
||||
}
|
||||
|
||||
return htmlData
|
||||
}
|
||||
},
|
||||
exportFooter: false
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.columnDefaults, {
|
||||
forceExport: false,
|
||||
forceHide: false
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||
export: {
|
||||
bootstrap3: 'glyphicon-export icon-share',
|
||||
bootstrap5: 'bi-download',
|
||||
materialize: 'file_download',
|
||||
'bootstrap-table': 'icon-download'
|
||||
}[$.fn.bootstrapTable.theme] || 'fa-download'
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.locales, {
|
||||
formatExport () {
|
||||
return 'Export data'
|
||||
}
|
||||
})
|
||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
||||
|
||||
$.fn.bootstrapTable.methods.push('exportTable')
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onExportSaved (exportedRows) {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||
'export-saved.bs.table': 'onExportSaved'
|
||||
})
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
initToolbar (...args) {
|
||||
const o = this.options
|
||||
let exportTypes = o.exportTypes
|
||||
|
||||
this.showToolbar = this.showToolbar || o.showExport
|
||||
|
||||
if (this.options.showExport) {
|
||||
|
||||
if (typeof exportTypes === 'string') {
|
||||
const types = exportTypes.slice(1, -1).replace(/ /g, '').split(',')
|
||||
|
||||
exportTypes = types.map(t => t.slice(1, -1))
|
||||
}
|
||||
|
||||
this.$export = this.$toolbar.find('>.columns div.export')
|
||||
if (this.$export.length) {
|
||||
this.updateExportButton()
|
||||
return
|
||||
}
|
||||
|
||||
this.buttons = Object.assign(this.buttons, {
|
||||
export: {
|
||||
html:
|
||||
(() => {
|
||||
if (exportTypes.length === 1) {
|
||||
return `
|
||||
<div class="export ${this.constants.classes.buttonsDropdown}"
|
||||
data-type="${exportTypes[0]}">
|
||||
<button class="${this.constants.buttonsClass}"
|
||||
aria-label="Export"
|
||||
type="button"
|
||||
title="${o.formatExport()}">
|
||||
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||
${o.showButtonText ? o.formatExport() : ''}
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
const html = []
|
||||
|
||||
html.push(`
|
||||
<div class="export ${this.constants.classes.buttonsDropdown}">
|
||||
<button class="${this.constants.buttonsClass} dropdown-toggle"
|
||||
aria-label="Export"
|
||||
${this.constants.dataToggle}="dropdown"
|
||||
type="button"
|
||||
title="${o.formatExport()}">
|
||||
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||
${o.showButtonText ? o.formatExport() : ''}
|
||||
${this.constants.html.dropdownCaret}
|
||||
</button>
|
||||
${this.constants.html.toolbarDropdown[0]}
|
||||
`)
|
||||
|
||||
for (const type of exportTypes) {
|
||||
if (TYPE_NAME.hasOwnProperty(type)) {
|
||||
const $item = $(Utils.sprintf(this.constants.html.pageDropdownItem, '', TYPE_NAME[type]))
|
||||
|
||||
$item.attr('data-type', type)
|
||||
html.push($item.prop('outerHTML'))
|
||||
}
|
||||
}
|
||||
|
||||
html.push(this.constants.html.toolbarDropdown[1], '</div>')
|
||||
return html.join('')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
super.initToolbar(...args)
|
||||
this.$export = this.$toolbar.find('>.columns div.export')
|
||||
|
||||
if (!this.options.showExport) {
|
||||
return
|
||||
}
|
||||
|
||||
this.updateExportButton()
|
||||
let $exportButtons = this.$export.find('[data-type]')
|
||||
|
||||
if (exportTypes.length === 1) {
|
||||
$exportButtons = this.$export.find('button')
|
||||
}
|
||||
|
||||
$exportButtons.click(e => {
|
||||
e.preventDefault()
|
||||
|
||||
const type = $(e.currentTarget).data('type')
|
||||
const exportOptions = {
|
||||
type,
|
||||
escape: false
|
||||
}
|
||||
|
||||
this.exportTable(exportOptions)
|
||||
})
|
||||
this.handleToolbar()
|
||||
}
|
||||
|
||||
handleToolbar () {
|
||||
if (!this.$export) {
|
||||
return
|
||||
}
|
||||
|
||||
if (super.handleToolbar) {
|
||||
super.handleToolbar()
|
||||
}
|
||||
}
|
||||
|
||||
exportTable (options) {
|
||||
const o = this.options
|
||||
const stateField = this.header.stateField
|
||||
const isCardView = o.cardView
|
||||
|
||||
const doExport = callback => {
|
||||
if (stateField) {
|
||||
this.hideColumn(stateField)
|
||||
}
|
||||
if (isCardView) {
|
||||
this.toggleView()
|
||||
}
|
||||
|
||||
this.columns.forEach(row => {
|
||||
if (row.forceHide) {
|
||||
this.hideColumn(row.field)
|
||||
}
|
||||
})
|
||||
|
||||
const data = this.getData()
|
||||
|
||||
if (o.detailView && o.detailViewIcon) {
|
||||
const detailViewIndex = o.detailViewAlign === 'left' ? 0 : this.getVisibleFields().length + Utils.getDetailViewIndexOffset(this.options)
|
||||
|
||||
o.exportOptions.ignoreColumn = [detailViewIndex].concat(o.exportOptions.ignoreColumn || [])
|
||||
}
|
||||
|
||||
if (o.exportFooter) {
|
||||
const $footerRow = this.$tableFooter.find('tr').first()
|
||||
const footerData = {}
|
||||
const footerHtml = []
|
||||
|
||||
$.each($footerRow.children(), (index, footerCell) => {
|
||||
const footerCellHtml = $(footerCell).children('.th-inner').first().html()
|
||||
|
||||
footerData[this.columns[index].field] = footerCellHtml === ' ' ? null : footerCellHtml
|
||||
|
||||
// grab footer cell text into cell index-based array
|
||||
footerHtml.push(footerCellHtml)
|
||||
})
|
||||
|
||||
this.$body.append(this.$body.children().last()[0].outerHTML)
|
||||
const $lastTableRow = this.$body.children().last()
|
||||
|
||||
$.each($lastTableRow.children(), (index, lastTableRowCell) => {
|
||||
$(lastTableRowCell).html(footerHtml[index])
|
||||
})
|
||||
}
|
||||
|
||||
const hiddenColumns = this.getHiddenColumns()
|
||||
|
||||
hiddenColumns.forEach(row => {
|
||||
if (row.forceExport) {
|
||||
this.showColumn(row.field)
|
||||
}
|
||||
})
|
||||
|
||||
if (typeof o.exportOptions.fileName === 'function') {
|
||||
options.fileName = o.exportOptions.fileName()
|
||||
}
|
||||
|
||||
this.$el.tableExport($.extend({
|
||||
onAfterSaveToFile: () => {
|
||||
if (o.exportFooter) {
|
||||
this.load(data)
|
||||
}
|
||||
|
||||
if (stateField) {
|
||||
this.showColumn(stateField)
|
||||
}
|
||||
if (isCardView) {
|
||||
this.toggleView()
|
||||
}
|
||||
|
||||
hiddenColumns.forEach(row => {
|
||||
if (row.forceExport) {
|
||||
this.hideColumn(row.field)
|
||||
}
|
||||
})
|
||||
|
||||
this.columns.forEach(row => {
|
||||
if (row.forceHide) {
|
||||
this.showColumn(row.field)
|
||||
}
|
||||
})
|
||||
|
||||
if (callback) callback()
|
||||
}
|
||||
}, o.exportOptions, options))
|
||||
}
|
||||
|
||||
if (o.exportDataType === 'all' && o.pagination) {
|
||||
const eventName = o.sidePagination === 'server' ?
|
||||
'post-body.bs.table' : 'page-change.bs.table'
|
||||
const virtualScroll = this.options.virtualScroll
|
||||
|
||||
this.$el.one(eventName, () => {
|
||||
setTimeout(() => {
|
||||
doExport(() => {
|
||||
this.options.virtualScroll = virtualScroll
|
||||
this.togglePagination()
|
||||
})
|
||||
}, 0)
|
||||
})
|
||||
this.options.virtualScroll = false
|
||||
this.togglePagination()
|
||||
this.trigger('export-saved', this.getData())
|
||||
} else if (o.exportDataType === 'selected') {
|
||||
let data = this.getData()
|
||||
let selectedData = this.getSelections()
|
||||
const pagination = o.pagination
|
||||
|
||||
if (!selectedData.length) {
|
||||
return
|
||||
}
|
||||
|
||||
if (o.sidePagination === 'server') {
|
||||
data = {
|
||||
total: o.totalRows,
|
||||
[this.options.dataField]: data
|
||||
}
|
||||
selectedData = {
|
||||
total: selectedData.length,
|
||||
[this.options.dataField]: selectedData
|
||||
}
|
||||
}
|
||||
|
||||
this.load(selectedData)
|
||||
if (pagination) {
|
||||
this.togglePagination()
|
||||
}
|
||||
doExport(() => {
|
||||
if (pagination) {
|
||||
this.togglePagination()
|
||||
}
|
||||
this.load(data)
|
||||
})
|
||||
this.trigger('export-saved', selectedData)
|
||||
} else {
|
||||
doExport()
|
||||
this.trigger('export-saved', this.getData(true))
|
||||
}
|
||||
}
|
||||
|
||||
updateSelected () {
|
||||
super.updateSelected()
|
||||
this.updateExportButton()
|
||||
}
|
||||
|
||||
updateExportButton () {
|
||||
if (this.options.exportDataType === 'selected') {
|
||||
this.$export.find('> button')
|
||||
.prop('disabled', !this.getSelections().length)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
tableExport.jquery.plugin
|
||||
Version 1.10.24
|
||||
Copyright (c) 2015-2021 hhurz, https://github.com/hhurz/tableExport.jquery.plugin
|
||||
Based on https://github.com/kayalshri/tableExport.jquery.plugin
|
||||
Licensed under the MIT License
|
||||
*/
|
||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(d,k,y){d instanceof String&&(d=String(d));for(var C=d.length,v=0;v<C;v++){var R=d[v];if(k.call(y,R,v,d))return{i:v,v:R}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(d,k,y){d!=Array.prototype&&d!=Object.prototype&&(d[k]=y.value)};
|
||||
$jscomp.getGlobal=function(d){return"undefined"!=typeof window&&window===d?d:"undefined"!=typeof global&&null!=global?global:d};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(d,k,y,C){if(k){y=$jscomp.global;d=d.split(".");for(C=0;C<d.length-1;C++){var v=d[C];v in y||(y[v]={});y=y[v]}d=d[d.length-1];C=y[d];k=k(C);k!=C&&null!=k&&$jscomp.defineProperty(y,d,{configurable:!0,writable:!0,value:k})}};
|
||||
$jscomp.polyfill("Array.prototype.find",function(d){return d?d:function(d,y){return $jscomp.findInternal(this,d,y).v}},"es6","es3");
|
||||
(function(d){d.fn.tableExport=function(k){function y(b){var c=[];v(b,"thead").each(function(){c.push.apply(c,v(d(this),a.theadSelector).toArray())});return c}function C(b){var c=[];v(b,"tbody").each(function(){c.push.apply(c,v(d(this),a.tbodySelector).toArray())});a.tfootSelector.length&&v(b,"tfoot").each(function(){c.push.apply(c,v(d(this),a.tfootSelector).toArray())});return c}function v(b,a){var c=b[0].tagName,q=b.parents(c).length;return b.find(a).filter(function(){return q===d(this).closest(c).parents(c).length})}
|
||||
function R(b){var a=[],e=0,q=0,f=0;d(b).find("thead").first().find("th").each(function(b,c){b=void 0!==d(c).attr("data-field");"undefined"!==typeof c.parentNode.rowIndex&&q!==c.parentNode.rowIndex&&(q=c.parentNode.rowIndex,e=f=0);var h=J(c);for(e+=h?h:1;f<e;)a[f]=b?d(c).attr("data-field"):f.toString(),f++});return a}function I(b){var a="undefined"!==typeof b[0].rowIndex,e=!1===a&&"undefined"!==typeof b[0].cellIndex,q=e||a?Ja(b):b.is(":visible"),f=b.attr("data-tableexport-display");e&&"none"!==f&&
|
||||
"always"!==f&&(b=d(b[0].parentNode),a="undefined"!==typeof b[0].rowIndex,f=b.attr("data-tableexport-display"));a&&"none"!==f&&"always"!==f&&(f=b.closest("table").attr("data-tableexport-display"));return"none"!==f&&(!0===q||"always"===f)}function Ja(b){var a=[];V&&(a=K.filter(function(){var a=!1;this.nodeType===b[0].nodeType&&("undefined"!==typeof this.rowIndex&&this.rowIndex===b[0].rowIndex?a=!0:"undefined"!==typeof this.cellIndex&&this.cellIndex===b[0].cellIndex&&"undefined"!==typeof this.parentNode.rowIndex&&
|
||||
"undefined"!==typeof b[0].parentNode.rowIndex&&this.parentNode.rowIndex===b[0].parentNode.rowIndex&&(a=!0));return a}));return!1===V||0===a.length}function ta(b,c,e){var q=!1;I(b)?0<a.ignoreColumn.length&&(-1!==d.inArray(e,a.ignoreColumn)||-1!==d.inArray(e-c,a.ignoreColumn)||S.length>e&&"undefined"!==typeof S[e]&&-1!==d.inArray(S[e],a.ignoreColumn))&&(q=!0):q=!0;return q}function E(b,c,e,q,f){if("function"===typeof f){var h=!1;"function"===typeof a.onIgnoreRow&&(h=a.onIgnoreRow(d(b),e));if(!1===h&&
|
||||
(0===a.ignoreRow.length||-1===d.inArray(e,a.ignoreRow)&&-1===d.inArray(e-q,a.ignoreRow))&&I(d(b))){b=v(d(b),c);var n=b.length,l=0,u=0;b.each(function(){var b=d(this),a=J(this),c=T(this),h;d.each(G,function(){if(e>this.s.r&&e<=this.e.r&&l>=this.s.c&&l<=this.e.c)for(h=0;h<=this.e.c-this.s.c;++h)n++,u++,f(null,e,l++)});if(c||a)a=a||1,G.push({s:{r:e,c:l},e:{r:e+(c||1)-1,c:l+a-1}});!1===ta(b,n,u++)&&f(this,e,l++);if(1<a)for(h=0;h<a-1;++h)u++,f(null,e,l++)});d.each(G,function(){if(e>=this.s.r&&e<=this.e.r&&
|
||||
l>=this.s.c&&l<=this.e.c)for(ea=0;ea<=this.e.c-this.s.c;++ea)f(null,e,l++)})}}}function ua(b,a,e,d){if("undefined"!==typeof d.images&&(e=d.images[e],"undefined"!==typeof e)){a=a.getBoundingClientRect();var c=b.width/b.height,h=a.width/a.height,q=b.width,l=b.height,u=19.049976/25.4,g=0;h<=c?(l=Math.min(b.height,a.height),q=a.width*l/a.height):h>c&&(q=Math.min(b.width,a.width),l=a.height*q/a.width);q*=u;l*=u;l<b.height&&(g=(b.height-l)/2);try{d.doc.addImage(e.src,b.textPos.x,b.y+g,q,l)}catch(Pa){}b.textPos.x+=
|
||||
q}}function va(b,c){if("string"===a.outputMode)return b.output();if("base64"===a.outputMode)return L(b.output());if("window"===a.outputMode)window.URL=window.URL||window.webkitURL,window.open(window.URL.createObjectURL(b.output("blob")));else try{var e=b.output("blob");saveAs(e,a.fileName+".pdf")}catch(q){ka(a.fileName+".pdf","data:application/pdf"+(c?"":";base64")+",",c?b.output("blob"):b.output())}}function wa(b,a,e){var c=0;"undefined"!==typeof e&&(c=e.colspan);if(0<=c){for(var f=b.width,d=b.textPos.x,
|
||||
n=a.table.columns.indexOf(a.column),l=1;l<c;l++)f+=a.table.columns[n+l].width;1<c&&("right"===b.styles.halign?d=b.textPos.x+f-b.width:"center"===b.styles.halign&&(d=b.textPos.x+(f-b.width)/2));b.width=f;b.textPos.x=d;"undefined"!==typeof e&&1<e.rowspan&&(b.height*=e.rowspan);if("middle"===b.styles.valign||"bottom"===b.styles.valign)e=("string"===typeof b.text?b.text.split(/\r\n|\r|\n/g):b.text).length||1,2<e&&(b.textPos.y-=(2-1.15)/2*a.row.styles.fontSize*(e-2)/3);return!0}return!1}function xa(b,
|
||||
a,e){"undefined"!==typeof b&&null!==b&&(b.hasAttribute("data-tableexport-canvas")?(a=(new Date).getTime(),d(b).attr("data-tableexport-canvas",a),e.images[a]={url:'[data-tableexport-canvas="'+a+'"]',src:null}):"undefined"!==a&&null!=a&&a.each(function(){if(d(this).is("img")){var a=ya(this.src);e.images[a]={url:this.src,src:this.src}}xa(b,d(this).children(),e)}))}function Ka(b,a){function c(b){if(b.url)if(b.src){var c=new Image;q=++f;c.crossOrigin="Anonymous";c.onerror=c.onload=function(){if(c.complete&&
|
||||
(0===c.src.indexOf("data:image/")&&(c.width=b.width||c.width||0,c.height=b.height||c.height||0),c.width+c.height)){var e=document.createElement("canvas"),d=e.getContext("2d");e.width=c.width;e.height=c.height;d.drawImage(c,0,0);b.src=e.toDataURL("image/png")}--f||a(q)};c.src=b.url}else{var e=d(b.url);e.length&&(q=++f,html2canvas(e[0]).then(function(c){b.src=c.toDataURL("image/png");--f||a(q)}))}}var q=0,f=0;if("undefined"!==typeof b.images)for(var h in b.images)b.images.hasOwnProperty(h)&&c(b.images[h]);
|
||||
(b=f)||(a(q),b=void 0);return b}function za(b,c,e){c.each(function(){if(d(this).is("div")){var c=fa(M(this,"background-color"),[255,255,255]),f=fa(M(this,"border-top-color"),[0,0,0]),h=ha(this,"border-top-width",a.jspdf.unit),n=this.getBoundingClientRect(),l=this.offsetLeft*e.wScaleFactor,u=this.offsetTop*e.hScaleFactor,g=n.width*e.wScaleFactor;n=n.height*e.hScaleFactor;e.doc.setDrawColor.apply(void 0,f);e.doc.setFillColor.apply(void 0,c);e.doc.setLineWidth(h);e.doc.rect(b.x+l,b.y+u,g,n,h?"FD":"F")}else d(this).is("img")&&
|
||||
(c=ya(this.src),ua(b,this,c,e));za(b,d(this).children(),e)})}function Aa(b,c,e){if("function"===typeof e.onAutotableText)e.onAutotableText(e.doc,b,c);else{var q=b.textPos.x,f=b.textPos.y,h={halign:b.styles.halign,valign:b.styles.valign};if(c.length){for(c=c[0];c.previousSibling;)c=c.previousSibling;for(var n=!1,l=!1;c;){var u=c.innerText||c.textContent||"",g=u.length&&" "===u[0]?" ":"",k=1<u.length&&" "===u[u.length-1]?" ":"";!0!==a.preserve.leadingWS&&(u=g+la(u));!0!==a.preserve.trailingWS&&(u=ma(u)+
|
||||
k);d(c).is("br")&&(q=b.textPos.x,f+=e.doc.internal.getFontSize());d(c).is("b")?n=!0:d(c).is("i")&&(l=!0);(n||l)&&e.doc.setFontType(n&&l?"bolditalic":n?"bold":"italic");if(g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()){"linebreak"===b.styles.overflow&&q>b.textPos.x&&q+g>b.textPos.x+b.width&&(0<=".,!%*;:=-".indexOf(u.charAt(0))&&(k=u.charAt(0),g=e.doc.getStringUnitWidth(k)*e.doc.internal.getFontSize(),q+g<=b.textPos.x+b.width&&(e.doc.autoTableText(k,q,f,h),u=u.substring(1,u.length)),g=
|
||||
e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()),q=b.textPos.x,f+=e.doc.internal.getFontSize());if("visible"!==b.styles.overflow)for(;u.length&&q+g>b.textPos.x+b.width;)u=u.substring(0,u.length-1),g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize();e.doc.autoTableText(u,q,f,h);q+=g}if(n||l)d(c).is("b")?n=!1:d(c).is("i")&&(l=!1),e.doc.setFontType(n||l?n?"bold":"italic":"normal");c=c.nextSibling}b.textPos.x=q;b.textPos.y=f}else e.doc.autoTableText(b.text,b.textPos.x,b.textPos.y,h)}}
|
||||
function W(b,a,e){return null==b?"":b.toString().replace(new RegExp(null==a?"":a.toString().replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),e)}function la(b){return null==b?"":b.toString().replace(/^\s+/,"")}function ma(b){return null==b?"":b.toString().replace(/\s+$/,"")}function La(b){if(0===a.date.html.length)return!1;a.date.pattern.lastIndex=0;var c=a.date.pattern.exec(b);if(null==c)return!1;b=+c[a.date.match_y];if(0>b||8099<b)return!1;var e=1*c[a.date.match_m];c=1*c[a.date.match_d];if(!isFinite(c))return!1;
|
||||
var d=new Date(b,e-1,c,0,0,0);return d.getFullYear()===b&&d.getMonth()===e-1&&d.getDate()===c?new Date(Date.UTC(b,e-1,c,0,0,0)):!1}function na(b){b=b||"0";""!==a.numbers.html.thousandsSeparator&&(b=W(b,a.numbers.html.thousandsSeparator,""));"."!==a.numbers.html.decimalMark&&(b=W(b,a.numbers.html.decimalMark,"."));return"number"===typeof b||!1!==jQuery.isNumeric(b)?b:!1}function Ma(b){-1<b.indexOf("%")?(b=na(b.replace(/%/g,"")),!1!==b&&(b/=100)):b=!1;return b}function D(b,c,e,q){var f="",h="text";
|
||||
if(null!==b){var n=d(b);n.removeData("teUserDefText");if(n[0].hasAttribute("data-tableexport-canvas"))var l="";else if(n[0].hasAttribute("data-tableexport-value"))l=(l=n.attr("data-tableexport-value"))?l+"":"",n.data("teUserDefText",1);else if(l=n.html(),"function"===typeof a.onCellHtmlData)l=a.onCellHtmlData(n,c,e,l),n.data("teUserDefText",1);else if(""!==l){b=d.parseHTML(l);var g=0,k=0;l="";d.each(b,function(){if(d(this).is("input"))l+=n.find("input").eq(g++).val();else if(d(this).is("select"))l+=
|
||||
n.find("select option:selected").eq(k++).text();else if(d(this).is("br"))l+="<br>";else{if("undefined"===typeof d(this).html())l+=d(this).text();else if(void 0===jQuery().bootstrapTable||!1===d(this).hasClass("fht-cell")&&!1===d(this).hasClass("filterControl")&&0===n.parents(".detail-view").length)l+=d(this).html();if(d(this).is("a")){var b=n.find("a").attr("href")||"";f="function"===typeof a.onCellHtmlHyperlink?f+a.onCellHtmlHyperlink(n,c,e,b,l):"href"===a.htmlHyperlink?f+b:f+l;l=""}}})}if(l&&""!==
|
||||
l&&!0===a.htmlContent)f=d.trim(l);else if(l&&""!==l)if(""!==n.attr("data-tableexport-cellformat")){var m=l.replace(/\n/g,"\u2028").replace(/(<\s*br([^>]*)>)/gi,"\u2060"),p=d("<div/>").html(m).contents();b=!1;m="";d.each(p.text().split("\u2028"),function(b,c){0<b&&(m+=" ");!0!==a.preserve.leadingWS&&(c=la(c));m+=!0!==a.preserve.trailingWS?ma(c):c});d.each(m.split("\u2060"),function(b,c){0<b&&(f+="\n");!0!==a.preserve.leadingWS&&(c=la(c));!0!==a.preserve.trailingWS&&(c=ma(c));f+=c.replace(/\u00AD/g,
|
||||
"")});f=f.replace(/\u00A0/g," ");if("json"===a.type||"excel"===a.type&&"xmlss"===a.mso.fileFormat||!1===a.numbers.output)b=na(f),!1!==b&&(h="number",f=Number(b));else if(a.numbers.html.decimalMark!==a.numbers.output.decimalMark||a.numbers.html.thousandsSeparator!==a.numbers.output.thousandsSeparator)if(b=na(f),!1!==b){p=(""+b.substr(0>b?1:0)).split(".");1===p.length&&(p[1]="");var t=3<p[0].length?p[0].length%3:0;h="number";f=(0>b?"-":"")+(a.numbers.output.thousandsSeparator?(t?p[0].substr(0,t)+a.numbers.output.thousandsSeparator:
|
||||
"")+p[0].substr(t).replace(/(\d{3})(?=\d)/g,"$1"+a.numbers.output.thousandsSeparator):p[0])+(p[1].length?a.numbers.output.decimalMark+p[1]:"")}}else f=l;!0===a.escape&&(f=escape(f));"function"===typeof a.onCellData&&(f=a.onCellData(n,c,e,f,h),n.data("teUserDefText",1))}void 0!==q&&(q.type=h);return f}function Ba(b){return 0<b.length&&!0===a.preventInjection&&0<="=+-@".indexOf(b.charAt(0))?"'"+b:b}function Na(b,a,e){return a+"-"+e.toLowerCase()}function fa(b,a){(b=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(b))&&
|
||||
(a=[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]);return a}function Ca(b){var a=M(b,"text-align"),e=M(b,"font-weight"),d=M(b,"font-style"),f="";"start"===a&&(a="rtl"===M(b,"direction")?"right":"left");700<=e&&(f="bold");"italic"===d&&(f+=d);""===f&&(f="normal");a={style:{align:a,bcolor:fa(M(b,"background-color"),[255,255,255]),color:fa(M(b,"color"),[0,0,0]),fstyle:f},colspan:J(b),rowspan:T(b)};null!==b&&(b=b.getBoundingClientRect(),a.rect={width:b.width,height:b.height});return a}function J(b){var a=
|
||||
d(b).attr("data-tableexport-colspan");"undefined"===typeof a&&d(b).is("[colspan]")&&(a=d(b).attr("colspan"));return parseInt(a)||0}function T(b){var a=d(b).attr("data-tableexport-rowspan");"undefined"===typeof a&&d(b).is("[rowspan]")&&(a=d(b).attr("rowspan"));return parseInt(a)||0}function M(a,c){try{return window.getComputedStyle?(c=c.replace(/([a-z])([A-Z])/,Na),window.getComputedStyle(a,null).getPropertyValue(c)):a.currentStyle?a.currentStyle[c]:a.style[c]}catch(e){}return""}function ha(a,c,e){c=
|
||||
M(a,c).match(/\d+/);if(null!==c){c=c[0];a=a.parentElement;var b=document.createElement("div");b.style.overflow="hidden";b.style.visibility="hidden";a.appendChild(b);b.style.width=100+e;e=100/b.offsetWidth;a.removeChild(b);return c*e}return 0}function Oa(a){for(var b=new ArrayBuffer(a.length),e=new Uint8Array(b),d=0;d!==a.length;++d)e[d]=a.charCodeAt(d)&255;return b}function oa(a){var b=a.c,e="";for(++b;b;b=Math.floor((b-1)/26))e=String.fromCharCode((b-1)%26+65)+e;return e+(""+(a.r+1))}function pa(a,
|
||||
c){if("undefined"===typeof c||"number"===typeof c)return pa(a.s,a.e);"string"!==typeof a&&(a=oa(a));"string"!==typeof c&&(c=oa(c));return a===c?a:a+":"+c}function Da(a,c){var b=Number(a);if(isFinite(b))return b;var d=1;""!==c.thousandsSeparator&&(a=a.replace(new RegExp("([\\d])"+c.thousandsSeparator+"([\\d])","g"),"$1$2"));"."!==c.decimalMark&&(a=a.replace(new RegExp("([\\d])"+c.decimalMark+"([\\d])","g"),"$1.$2"));a=a.replace(/[$]/g,"").replace(/[%]/g,function(){d*=100;return""});if(isFinite(b=Number(a)))return b/
|
||||
d;a=a.replace(/[(](.*)[)]/,function(a,b){d=-d;return b});return isFinite(b=Number(a))?b/d:b}function ya(a){var b=0,d;if(0===a.length)return b;var q=0;for(d=a.length;q<d;q++){var f=a.charCodeAt(q);b=(b<<5)-b+f;b|=0}return b}function N(b,c,d,q,f,h){var e=!0;"function"===typeof a.onBeforeSaveToFile&&(e=a.onBeforeSaveToFile(b,c,d,q,f),"boolean"!==typeof e&&(e=!0));if(e)try{if(Ea=new Blob([b],{type:d+";charset="+q}),saveAs(Ea,c,!1===h),"function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(b,c)}catch(l){ka(c,
|
||||
"data:"+d+(q.length?";charset="+q:"")+(f.length?";"+f:"")+",",h?"\ufeff"+b:b)}}function ka(b,c,d){var e=window.navigator.userAgent;if(!1!==b&&window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(new Blob([d]),b);else if(!1!==b&&(0<e.indexOf("MSIE ")||e.match(/Trident.*rv\:11\./))){if(c=document.createElement("iframe")){document.body.appendChild(c);c.setAttribute("style","display:none");c.contentDocument.open("txt/plain","replace");c.contentDocument.write(d);c.contentDocument.close();
|
||||
c.contentWindow.focus();switch(b.substr(b.lastIndexOf(".")+1)){case "doc":case "json":case "png":case "pdf":case "xls":case "xlsx":b+=".txt"}c.contentDocument.execCommand("SaveAs",!0,b);document.body.removeChild(c)}}else{var f=document.createElement("a");if(f){var h=null;f.style.display="none";!1!==b?f.download=b:f.target="_blank";"object"===typeof d?(window.URL=window.URL||window.webkitURL,e=[],e.push(d),h=window.URL.createObjectURL(new Blob(e,{type:c})),f.href=h):0<=c.toLowerCase().indexOf("base64,")?
|
||||
f.href=c+L(d):f.href=c+encodeURIComponent(d);document.body.appendChild(f);if(document.createEvent)null===ia&&(ia=document.createEvent("MouseEvents")),ia.initEvent("click",!0,!1),f.dispatchEvent(ia);else if(document.createEventObject)f.fireEvent("onclick");else if("function"===typeof f.onclick)f.onclick();setTimeout(function(){h&&window.URL.revokeObjectURL(h);document.body.removeChild(f);if("function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(d,b)},100)}}}function L(a){var b,d="",q=0;if("string"===
|
||||
typeof a){a=a.replace(/\x0d\x0a/g,"\n");var f="";for(b=0;b<a.length;b++){var h=a.charCodeAt(b);128>h?f+=String.fromCharCode(h):(127<h&&2048>h?f+=String.fromCharCode(h>>6|192):(f+=String.fromCharCode(h>>12|224),f+=String.fromCharCode(h>>6&63|128)),f+=String.fromCharCode(h&63|128))}a=f}for(;q<a.length;){var n=a.charCodeAt(q++);f=a.charCodeAt(q++);b=a.charCodeAt(q++);h=n>>2;n=(n&3)<<4|f>>4;var l=(f&15)<<2|b>>6;var g=b&63;isNaN(f)?l=g=64:isNaN(b)&&(g=64);d=d+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h)+
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(n)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g)}return d}var a={csvEnclosure:'"',csvSeparator:",",csvUseBOM:!0,date:{html:"dd/mm/yyyy"},displayTableName:!1,escape:!1,exportHiddenCells:!1,fileName:"tableExport",htmlContent:!1,htmlHyperlink:"content",ignoreColumn:[],ignoreRow:[],jsonScope:"all",jspdf:{orientation:"p",
|
||||
unit:"pt",format:"a4",margins:{left:20,right:10,top:10,bottom:10},onDocCreated:null,autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:"normal",overflow:"ellipsize",halign:"inherit",valign:"middle"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:"bold",halign:"inherit",valign:"middle"},alternateRowStyles:{fillColor:245},tableExport:{doc:null,onAfterAutotable:null,onBeforeAutotable:null,onAutotableText:null,onTable:null,outputImages:!0}}},mso:{fileFormat:"xlshtml",
|
||||
onMsoNumberFormat:null,pageFormat:"a4",pageOrientation:"portrait",rtl:!1,styles:[],worksheetName:"",xslx:{formatId:{date:14,numbers:2}}},numbers:{html:{decimalMark:".",thousandsSeparator:","},output:{decimalMark:".",thousandsSeparator:","}},onAfterSaveToFile:null,onBeforeSaveToFile:null,onCellData:null,onCellHtmlData:null,onCellHtmlHyperlink:null,onIgnoreRow:null,onTableExportBegin:null,onTableExportEnd:null,outputMode:"file",pdfmake:{enabled:!1,docDefinition:{pageSize:"A4",pageOrientation:"portrait",
|
||||
styles:{header:{background:"#34495E",color:"#FFFFFF",bold:!0,alignment:"center",fillColor:"#34495E"},alternateRow:{fillColor:"#f5f5f5"}},defaultStyle:{color:"#000000",fontSize:8,font:"Roboto"}},fonts:{}},preserve:{leadingWS:!1,trailingWS:!1},preventInjection:!0,sql:{tableEnclosure:"`",columnEnclosure:"`"},tbodySelector:"tr",tfootSelector:"tr",theadSelector:"tr",tableName:"Table",type:"csv"},O={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,
|
||||
595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,
|
||||
161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]},B=this,ia=null,r=[],w=[],p=0,t="",S=[],G=[],Ea,K=[],V=!1;d.extend(!0,a,k);"xlsx"===a.type&&(a.mso.fileFormat=a.type,a.type="excel");"undefined"!==typeof a.excelFileFormat&&"undefined"===a.mso.fileFormat&&(a.mso.fileFormat=a.excelFileFormat);"undefined"!==typeof a.excelPageFormat&&"undefined"===a.mso.pageFormat&&
|
||||
(a.mso.pageFormat=a.excelPageFormat);"undefined"!==typeof a.excelPageOrientation&&"undefined"===a.mso.pageOrientation&&(a.mso.pageOrientation=a.excelPageOrientation);"undefined"!==typeof a.excelRTL&&"undefined"===a.mso.rtl&&(a.mso.rtl=a.excelRTL);"undefined"!==typeof a.excelstyles&&"undefined"===a.mso.styles&&(a.mso.styles=a.excelstyles);"undefined"!==typeof a.onMsoNumberFormat&&"undefined"===a.mso.onMsoNumberFormat&&(a.mso.onMsoNumberFormat=a.onMsoNumberFormat);"undefined"!==typeof a.worksheetName&&
|
||||
"undefined"===a.mso.worksheetName&&(a.mso.worksheetName=a.worksheetName);a.mso.pageOrientation="l"===a.mso.pageOrientation.substr(0,1)?"landscape":"portrait";a.date.html=a.date.html||"";if(a.date.html.length){k=[];k.dd="(3[01]|[12][0-9]|0?[1-9])";k.mm="(1[012]|0?[1-9])";k.yyyy="((?:1[6-9]|2[0-2])\\d{2})";k.yy="(\\d{2})";var z=a.date.html.match(/[^a-zA-Z0-9]/)[0];z=a.date.html.toLowerCase().split(z);a.date.regex="^\\s*";a.date.regex+=k[z[0]];a.date.regex+="(.)";a.date.regex+=k[z[1]];a.date.regex+=
|
||||
"\\2";a.date.regex+=k[z[2]];a.date.regex+="\\s*$";a.date.pattern=new RegExp(a.date.regex,"g");k=z.indexOf("dd")+1;a.date.match_d=k+(1<k?1:0);k=z.indexOf("mm")+1;a.date.match_m=k+(1<k?1:0);k=(0<=z.indexOf("yyyy")?z.indexOf("yyyy"):z.indexOf("yy"))+1;a.date.match_y=k+(1<k?1:0)}S=R(B);if("function"===typeof a.onTableExportBegin)a.onTableExportBegin();if("csv"===a.type||"tsv"===a.type||"txt"===a.type){var P="",Z=0;G=[];p=0;var qa=function(b,c,e){b.each(function(){t="";E(this,c,p,e+b.length,function(b,
|
||||
c,d){var e=t,f="";if(null!==b)if(b=D(b,c,d),c=null===b||""===b?"":b.toString(),"tsv"===a.type)b instanceof Date&&b.toLocaleString(),f=W(c,"\t"," ");else if(b instanceof Date)f=a.csvEnclosure+b.toLocaleString()+a.csvEnclosure;else if(f=Ba(c),f=W(f,a.csvEnclosure,a.csvEnclosure+a.csvEnclosure),0<=f.indexOf(a.csvSeparator)||/[\r\n ]/g.test(f))f=a.csvEnclosure+f+a.csvEnclosure;t=e+(f+("tsv"===a.type?"\t":a.csvSeparator))});t=d.trim(t).substring(0,t.length-1);0<t.length&&(0<P.length&&(P+="\n"),P+=t);p++});
|
||||
return b.length};Z+=qa(d(B).find("thead").first().find(a.theadSelector),"th,td",Z);v(d(B),"tbody").each(function(){Z+=qa(v(d(this),a.tbodySelector),"td,th",Z)});a.tfootSelector.length&&qa(d(B).find("tfoot").first().find(a.tfootSelector),"td,th",Z);P+="\n";if("string"===a.outputMode)return P;if("base64"===a.outputMode)return L(P);if("window"===a.outputMode){ka(!1,"data:text/"+("csv"===a.type?"csv":"plain")+";charset=utf-8,",P);return}N(P,a.fileName+"."+a.type,"text/"+("csv"===a.type?"csv":"plain"),
|
||||
"utf-8","","csv"===a.type&&a.csvUseBOM)}else if("sql"===a.type){p=0;G=[];var A="INSERT INTO "+a.sql.tableEnclosure+a.tableName+a.sql.tableEnclosure+" (";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(b,c,d){b=D(b,c,d)||"";-1<b.indexOf(a.sql.columnEnclosure)&&(b=W(b.toString(),a.sql.columnEnclosure,a.sql.columnEnclosure+a.sql.columnEnclosure));A+=a.sql.columnEnclosure+b+a.sql.columnEnclosure+","});p++;A=d.trim(A).substring(0,A.length-1)});A+=") VALUES ";w=C(d(B));d(w).each(function(){t=
|
||||
"";E(this,"td,th",p,r.length+w.length,function(a,c,d){a=D(a,c,d)||"";-1<a.indexOf("'")&&(a=W(a.toString(),"'","''"));t+="'"+a+"',"});3<t.length&&(A+="("+t,A=d.trim(A).substring(0,A.length-1),A+="),");p++});A=d.trim(A).substring(0,A.length-1);A+=";";if("string"===a.outputMode)return A;if("base64"===a.outputMode)return L(A);N(A,a.fileName+".sql","application/sql","utf-8","",!1)}else if("json"===a.type){var X=[];G=[];r=y(d(B));d(r).each(function(){var a=[];E(this,"th,td",p,r.length,function(b,d,g){a.push(D(b,
|
||||
d,g))});X.push(a)});var ra=[];w=C(d(B));d(w).each(function(){var a={},c=0;E(this,"td,th",p,r.length+w.length,function(b,d,f){X.length?a[X[X.length-1][c]]=D(b,d,f):a[c]=D(b,d,f);c++});!1===d.isEmptyObject(a)&&ra.push(a);p++});k="head"===a.jsonScope?JSON.stringify(X):"data"===a.jsonScope?JSON.stringify(ra):JSON.stringify({header:X,data:ra});if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".json","application/json","utf-8","base64",!1)}else if("xml"===a.type){p=
|
||||
0;G=[];var Q='<?xml version="1.0" encoding="utf-8"?>';Q+="<tabledata><fields>";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(a,d,e){Q+="<field>"+D(a,d,e)+"</field>"});p++});Q+="</fields><data>";var Fa=1;w=C(d(B));d(w).each(function(){var a=1;t="";E(this,"td,th",p,r.length+w.length,function(b,d,g){t+="<column-"+a+">"+D(b,d,g)+"</column-"+a+">";a++});0<t.length&&"<column-1></column-1>"!==t&&(Q+='<row id="'+Fa+'">'+t+"</row>",Fa++);p++});Q+="</data></tabledata>";if("string"===a.outputMode)return Q;
|
||||
if("base64"===a.outputMode)return L(Q);N(Q,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===a.type&&"xmlss"===a.mso.fileFormat){var sa=[],F=[];d(B).filter(function(){return I(d(this))}).each(function(){function b(a,b,c){var f=[];d(a).each(function(){var b=0,e=0;t="";E(this,"td,th",p,c+a.length,function(a,c,h){if(null!==a){var l="";c=D(a,c,h);h="String";if(!1!==jQuery.isNumeric(c))h="Number";else{var n=Ma(c);!1!==n&&(c=n,h="Number",l+=' ss:StyleID="pct1"')}"Number"!==h&&(c=
|
||||
c.replace(/\n/g,"<br>"));n=J(a);a=T(a);d.each(f,function(){if(p>=this.s.r&&p<=this.e.r&&e>=this.s.c&&e<=this.e.c)for(var a=0;a<=this.e.c-this.s.c;++a)e++,b++});if(a||n)a=a||1,n=n||1,f.push({s:{r:p,c:e},e:{r:p+a-1,c:e+n-1}});1<n&&(l+=' ss:MergeAcross="'+(n-1)+'"',e+=n-1);1<a&&(l+=' ss:MergeDown="'+(a-1)+'" ss:StyleID="rsp1"');0<b&&(l+=' ss:Index="'+(e+1)+'"',b=0);t+="<Cell"+l+'><Data ss:Type="'+h+'">'+d("<div />").text(c).html()+"</Data></Cell>\r";e++}});0<t.length&&(H+='<Row ss:AutoFitHeight="0">\r'+
|
||||
t+"</Row>\r");p++});return a.length}var c=d(this),e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(F.length+1):"undefined"!==typeof a.mso.worksheetName[F.length]&&(e=a.mso.worksheetName[F.length]);e.length||(e=c.find("caption").text()||"");e.length||(e="Table "+(F.length+1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));F.push(d("<div />").text(e).html());!1===a.exportHiddenCells&&(K=c.find("tr, th, td").filter(":hidden"),V=0<K.length);
|
||||
p=0;S=R(this);H="<Table>\r";e=b(y(c),"th,td",0);b(C(c),"td,th",e);H+="</Table>\r";sa.push(H)});k={};z={};for(var m,aa,Y=0,ea=F.length;Y<ea;Y++)m=F[Y],aa=k[m],aa=k[m]=null==aa?1:aa+1,2===aa&&(F[z[m]]=F[z[m]].substring(0,29)+"-1"),1<k[m]?F[Y]=F[Y].substring(0,29)+"-"+k[m]:z[m]=Y;k='<?xml version="1.0" encoding="UTF-8"?>\r<?mso-application progid="Excel.Sheet"?>\r<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:o="urn:schemas-microsoft-com:office:office"\r xmlns:x="urn:schemas-microsoft-com:office:excel"\r xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:html="http://www.w3.org/TR/REC-html40">\r<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">\r <Created>'+
|
||||
(new Date).toISOString()+'</Created>\r</DocumentProperties>\r<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">\r <AllowPNG/>\r</OfficeDocumentSettings>\r<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">\r <WindowHeight>9000</WindowHeight>\r <WindowWidth>13860</WindowWidth>\r <WindowTopX>0</WindowTopX>\r <WindowTopY>0</WindowTopY>\r <ProtectStructure>False</ProtectStructure>\r <ProtectWindows>False</ProtectWindows>\r</ExcelWorkbook>\r<Styles>\r <Style ss:ID="Default" ss:Name="Normal">\r <Alignment ss:Vertical="Bottom"/>\r <Borders/>\r <Font/>\r <Interior/>\r <NumberFormat/>\r <Protection/>\r </Style>\r <Style ss:ID="rsp1">\r <Alignment ss:Vertical="Center"/>\r </Style>\r <Style ss:ID="pct1">\r <NumberFormat ss:Format="Percent"/>\r </Style>\r</Styles>\r';
|
||||
for(z=0;z<sa.length;z++)k+='<Worksheet ss:Name="'+F[z]+'" ss:RightToLeft="'+(a.mso.rtl?"1":"0")+'">\r'+sa[z],k=a.mso.rtl?k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">\r<DisplayRightToLeft/>\r</WorksheetOptions>\r':k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"/>\r',k+="</Worksheet>\r";k+="</Workbook>\r";if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===
|
||||
a.type&&"xlsx"===a.mso.fileFormat){var ba=[],Ga=XLSX.utils.book_new();d(B).filter(function(){return I(d(this))}).each(function(){for(var b=d(this),c={},e=this.getElementsByTagName("tr"),g={s:{r:0,c:0},e:{r:0,c:0}},f=[],h,n=[],l=0,u=0,k,m,p,t,r,w=XLSX.SSF.get_table();l<e.length&&1E7>u;++l)if(k=e[l],m=!1,"function"===typeof a.onIgnoreRow&&(m=a.onIgnoreRow(d(k),l)),!0!==m&&(0===a.ignoreRow.length||-1===d.inArray(l,a.ignoreRow)&&-1===d.inArray(l-e.length,a.ignoreRow))&&!1!==I(d(k))){var y=k.children,
|
||||
B=0;for(k=0;k<y.length;++k)r=y[k],t=+J(r)||1,B+=t;var z=0;for(k=m=0;k<y.length;++k)if(r=y[k],t=+J(r)||1,h=k+z,!ta(d(r),B,h+(h<m?m-h:0))){z+=t-1;for(h=0;h<f.length;++h){var v=f[h];v.s.c==m&&v.s.r<=u&&u<=v.e.r&&(m=v.e.c+1,h=-1)}(0<(p=+T(r))||1<t)&&f.push({s:{r:u,c:m},e:{r:u+(p||1)-1,c:m+t-1}});var C={type:""};h=D(r,l,k+z,C);v={t:"s",v:h};var A="";if(""!==(d(r).attr("data-tableexport-cellformat")||"")){var x=parseInt(d(r).attr("data-tableexport-xlsxformatid")||0);0===x&&"function"===typeof a.mso.xslx.formatId.numbers&&
|
||||
(x=a.mso.xslx.formatId.numbers(d(r),l,k+z));0===x&&"function"===typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date(d(r),l,k+z));if(49===x||"@"===x)A="s";else if("number"===C.type||0<x&&14>x||36<x&&41>x||48===x)A="n";else if("date"===C.type||13<x&&37>x||44<x&&48>x||56===x)A="d"}else A="s";if(null!=h)if(0===h.length)v.t="z";else if(0!==h.trim().length)if("s"===A)d(r).find("a").length&&(h="href"!==a.htmlHyperlink?h:"",v={f:'=HYPERLINK("'+d(r).find("a").attr("href")+(h.length?'","'+h:"")+'")'});
|
||||
else if("function"===C.type)v={f:h};else if("TRUE"===h)v={t:"b",v:!0};else if("FALSE"===h)v={t:"b",v:!1};else if("n"===A||isFinite(Da(h,a.numbers.output))){if(r=Da(h,a.numbers.output),0===x&&"function"!==typeof a.mso.xslx.formatId.numbers&&(x=a.mso.xslx.formatId.numbers),isFinite(r)||isFinite(h))v={t:"n",v:isFinite(r)?r:h,z:"string"===typeof x?x:x in w?w[x]:"0.00"}}else if(!1!==(r=La(h))||"d"===A)0===x&&"function"!==typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date),v={t:"d",v:!1!==r?r:
|
||||
h,z:"string"===typeof x?x:x in w?w[x]:"m/d/yy"};c[oa({c:m,r:u})]=v;g.e.c<m&&(g.e.c=m);m+=t}++u}f.length&&(c["!merges"]=f);n.length&&(c["!rows"]=n);g.e.r=u-1;c["!ref"]=pa(g);1E7<=u&&(c["!fullref"]=pa((g.e.r=e.length-l+u-1,g)));e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(ba.length+1):"undefined"!==typeof a.mso.worksheetName[ba.length]&&(e=a.mso.worksheetName[ba.length]);e.length||(e=b.find("caption").text()||"");e.length||(e="Table "+(ba.length+
|
||||
1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));ba.push(e);XLSX.utils.book_append_sheet(Ga,c,e)});k=XLSX.write(Ga,{type:"binary",bookType:a.mso.fileFormat,bookSST:!1});N(Oa(k),a.fileName+"."+a.mso.fileFormat,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","UTF-8","",!1)}else if("excel"===a.type||"xls"===a.type||"word"===a.type||"doc"===a.type){k="excel"===a.type||"xls"===a.type?"excel":"word";z="excel"===k?"xls":"doc";m='xmlns:x="urn:schemas-microsoft-com:office:'+
|
||||
k+'"';var H="",ca="";d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this);""===ca&&(ca=a.mso.worksheetName||b.find("caption").text()||"Table",ca=d.trim(ca.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31)));!1===a.exportHiddenCells&&(K=b.find("tr, th, td").filter(":hidden"),V=0<K.length);p=0;G=[];S=R(this);H+="<table><thead>";r=y(b);d(r).each(function(){var b=d(this);t="";E(this,"th,td",p,r.length,function(d,c,f){if(null!==d){var e="";t+="<th";if(a.mso.styles.length){var n=document.defaultView.getComputedStyle(d,
|
||||
null),l=document.defaultView.getComputedStyle(b[0],null),g;for(g in a.mso.styles){var k=n[a.mso.styles[g]];""===k&&(k=l[a.mso.styles[g]]);""!==k&&"0px none rgb(0, 0, 0)"!==k&&"rgba(0, 0, 0, 0)"!==k&&(e+=""===e?'style="':";",e+=a.mso.styles[g]+":"+k)}}""!==e&&(t+=" "+e+'"');e=J(d);0<e&&(t+=' colspan="'+e+'"');e=T(d);0<e&&(t+=' rowspan="'+e+'"');t+=">"+D(d,c,f)+"</th>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});H+="</thead><tbody>";w=C(b);d(w).each(function(){var b=d(this);t="";E(this,"td,th",p,r.length+
|
||||
w.length,function(c,g,f){if(null!==c){var e=D(c,g,f),n="",l=d(c).attr("data-tableexport-msonumberformat");"undefined"===typeof l&&"function"===typeof a.mso.onMsoNumberFormat&&(l=a.mso.onMsoNumberFormat(c,g,f));"undefined"!==typeof l&&""!==l&&(n="style=\"mso-number-format:'"+l+"'");if(a.mso.styles.length){g=document.defaultView.getComputedStyle(c,null);f=document.defaultView.getComputedStyle(b[0],null);for(var k in a.mso.styles)l=g[a.mso.styles[k]],""===l&&(l=f[a.mso.styles[k]]),""!==l&&"0px none rgb(0, 0, 0)"!==
|
||||
l&&"rgba(0, 0, 0, 0)"!==l&&(n+=""===n?'style="':";",n+=a.mso.styles[k]+":"+l)}t+="<td";""!==n&&(t+=" "+n+'"');n=J(c);0<n&&(t+=' colspan="'+n+'"');c=T(c);0<c&&(t+=' rowspan="'+c+'"');"string"===typeof e&&""!==e&&(e=Ba(e),e=e.replace(/\n/g,"<br>"));t+=">"+e+"</td>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});a.displayTableName&&(H+="<tr><td></td></tr><tr><td></td></tr><tr><td>"+D(d("<p>"+a.tableName+"</p>"))+"</td></tr>");H+="</tbody></table>"});m='<html xmlns:o="urn:schemas-microsoft-com:office:office" '+
|
||||
m+' xmlns="http://www.w3.org/TR/REC-html40">'+('<meta http-equiv="content-type" content="application/vnd.ms-'+k+'; charset=UTF-8">')+"<head>";"excel"===k&&(m+="\x3c!--[if gte mso 9]>",m+="<xml>",m+="<x:ExcelWorkbook>",m+="<x:ExcelWorksheets>",m+="<x:ExcelWorksheet>",m+="<x:Name>",m+=ca,m+="</x:Name>",m+="<x:WorksheetOptions>",m+="<x:DisplayGridlines/>",a.mso.rtl&&(m+="<x:DisplayRightToLeft/>"),m+="</x:WorksheetOptions>",m+="</x:ExcelWorksheet>",m+="</x:ExcelWorksheets>",m+="</x:ExcelWorkbook>",m+=
|
||||
"</xml>",m+="<![endif]--\x3e");m+="<style>";m+="@page { size:"+a.mso.pageOrientation+"; mso-page-orientation:"+a.mso.pageOrientation+"; }";m+="@page Section1 {size:"+O[a.mso.pageFormat][0]+"pt "+O[a.mso.pageFormat][1]+"pt";m+="; margin:1.0in 1.25in 1.0in 1.25in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";m+="div.Section1 {page:Section1;}";m+="@page Section2 {size:"+O[a.mso.pageFormat][1]+"pt "+O[a.mso.pageFormat][0]+"pt";m+=";mso-page-orientation:"+a.mso.pageOrientation+";margin:1.25in 1.0in 1.25in 1.0in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";
|
||||
m+="div.Section2 {page:Section2;}";m+="br {mso-data-placement:same-cell;}";m+="</style>";m+="</head>";m+="<body>";m+='<div class="Section'+("landscape"===a.mso.pageOrientation?"2":"1")+'">';m+=H;m+="</div>";m+="</body>";m+="</html>";if("string"===a.outputMode)return m;if("base64"===a.outputMode)return L(m);N(m,a.fileName+"."+z,"application/vnd.ms-"+k,"","base64",!1)}else if("png"===a.type)html2canvas(d(B)[0]).then(function(b){b=b.toDataURL();for(var c=atob(b.substring(22)),d=new ArrayBuffer(c.length),
|
||||
g=new Uint8Array(d),f=0;f<c.length;f++)g[f]=c.charCodeAt(f);if("string"===a.outputMode)return c;if("base64"===a.outputMode)return L(b);"window"===a.outputMode?window.open(b):N(d,a.fileName+".png","image/png","","",!1)});else if("pdf"===a.type)if(!0===a.pdfmake.enabled){var U={content:[]};d.extend(!0,U,a.pdfmake.docDefinition);G=[];d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this),c=[],e=[];p=0;var g=function(a,b,c){var f=0;d(a).each(function(){var a=[];E(this,b,p,c,function(c,
|
||||
d,f){if("undefined"!==typeof c&&null!==c){var e=J(c),h=T(c);c={text:D(c,d,f)||" "};if(1<e||1<h)c.colSpan=e||1,c.rowSpan=h||1}else c={text:" "};0<=b.indexOf("th")&&(c.style="header");a.push(c)});for(var d=a.length;d<c;d++)a.push("");a.length&&e.push(a);f<a.length&&(f=a.length);p++});return f};r=y(b);for(var f=g(r,"th,td",r.length),h=c.length;h<f;h++)c.push("*");w=C(b);f=g(w,"td",r.length+w.length);for(h=c.length;h<f;h++)c.push("*");U.content.push({table:{headerRows:r.length?r.length:null,widths:c,
|
||||
body:e},layout:{layout:"noBorders",hLineStyle:function(a,b){return 0},vLineWidth:function(a,b){return 0},hLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},vLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},fillColor:function(b,c,d){return 0===b%2?a.pdfmake.docDefinition.styles.alternateRow.fillColor:
|
||||
null}},pageBreak:U.content.length?"before":void 0})});"undefined"!==typeof pdfMake&&"undefined"!==typeof pdfMake.createPdf&&(pdfMake.fonts={Roboto:{normal:"Roboto-Regular.ttf",bold:"Roboto-Medium.ttf",italics:"Roboto-Italic.ttf",bolditalics:"Roboto-MediumItalic.ttf"}},pdfMake.vfs.hasOwnProperty("Mirza-Regular.ttf")?(U.defaultStyle.font="Mirza",d.extend(!0,pdfMake.fonts,{Mirza:{normal:"Mirza-Regular.ttf",bold:"Mirza-Bold.ttf",italics:"Mirza-Medium.ttf",bolditalics:"Mirza-SemiBold.ttf"}})):pdfMake.vfs.hasOwnProperty("gbsn00lp.ttf")?
|
||||
(U.defaultStyle.font="gbsn00lp",d.extend(!0,pdfMake.fonts,{gbsn00lp:{normal:"gbsn00lp.ttf",bold:"gbsn00lp.ttf",italics:"gbsn00lp.ttf",bolditalics:"gbsn00lp.ttf"}})):pdfMake.vfs.hasOwnProperty("ZCOOLXiaoWei-Regular.ttf")&&(U.defaultStyle.font="ZCOOLXiaoWei",d.extend(!0,pdfMake.fonts,{ZCOOLXiaoWei:{normal:"ZCOOLXiaoWei-Regular.ttf",bold:"ZCOOLXiaoWei-Regular.ttf",italics:"ZCOOLXiaoWei-Regular.ttf",bolditalics:"ZCOOLXiaoWei-Regular.ttf"}})),d.extend(!0,pdfMake.fonts,a.pdfmake.fonts),pdfMake.createPdf(U).getBuffer(function(b){N(b,
|
||||
a.fileName+".pdf","application/pdf","","",!1)}))}else if(!1===a.jspdf.autotable){k={dim:{w:ha(d(B).first().get(0),"width","mm"),h:ha(d(B).first().get(0),"height","mm")},pagesplit:!1};var Ha=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format);Ha.addHTML(d(B).first(),a.jspdf.margins.left,a.jspdf.margins.top,k,function(){va(Ha,!1)})}else{var g=a.jspdf.autotable.tableExport;if("string"===typeof a.jspdf.format&&"bestfit"===a.jspdf.format.toLowerCase()){var ja="",da="",Ia=0;d(B).each(function(){if(I(d(this))){var a=
|
||||
ha(d(this).get(0),"width","pt");if(a>Ia){a>O.a0[0]&&(ja="a0",da="l");for(var c in O)O.hasOwnProperty(c)&&O[c][1]>a&&(ja=c,da="l",O[c][0]>a&&(da="p"));Ia=a}}});a.jspdf.format=""===ja?"a4":ja;a.jspdf.orientation=""===da?"w":da}if(null==g.doc&&(g.doc=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format),g.wScaleFactor=1,g.hScaleFactor=1,"function"===typeof a.jspdf.onDocCreated))a.jspdf.onDocCreated(g.doc);!0===g.outputImages&&(g.images={});"undefined"!==typeof g.images&&(d(B).filter(function(){return I(d(this))}).each(function(){var b=
|
||||
0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);r=y(d(this));w=C(d(this));d(w).each(function(){E(this,"td,th",r.length+b,r.length+w.length,function(a){xa(a,d(a).children(),g)});b++})}),r=[],w=[]);Ka(g,function(){d(B).filter(function(){return I(d(this))}).each(function(){var b;p=0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);S=R(this);g.columns=[];g.rows=[];g.teCells={};if("function"===typeof g.onTable&&
|
||||
!1===g.onTable(d(this),a))return!0;a.jspdf.autotable.tableExport=null;var c=d.extend(!0,{},a.jspdf.autotable);a.jspdf.autotable.tableExport=g;c.margin={};d.extend(!0,c.margin,a.jspdf.margins);c.tableExport=g;"function"!==typeof c.beforePageContent&&(c.beforePageContent=function(a){if(1===a.pageCount){var b=a.table.rows.concat(a.table.headerRow);d.each(b,function(){0<this.height&&(this.height+=(2-1.15)/2*this.styles.fontSize,a.table.height+=(2-1.15)/2*this.styles.fontSize)})}});"function"!==typeof c.createdHeaderCell&&
|
||||
(c.createdHeaderCell=function(a,b){a.styles=d.extend({},b.row.styles);if("undefined"!==typeof g.columns[b.column.dataKey]){var e=g.columns[b.column.dataKey];if("undefined"!==typeof e.rect){a.contentWidth=e.rect.width;if("undefined"===typeof g.heightRatio||0===g.heightRatio){var f=b.row.raw[b.column.dataKey].rowspan?b.row.raw[b.column.dataKey].rect.height/b.row.raw[b.column.dataKey].rowspan:b.row.raw[b.column.dataKey].rect.height;g.heightRatio=a.styles.rowHeight/f}f=b.row.raw[b.column.dataKey].rect.height*
|
||||
g.heightRatio;f>a.styles.rowHeight&&(a.styles.rowHeight=f)}a.styles.halign="inherit"===c.headerStyles.halign?"center":c.headerStyles.halign;a.styles.valign=c.headerStyles.valign;"undefined"!==typeof e.style&&!0!==e.style.hidden&&("inherit"===c.headerStyles.halign&&(a.styles.halign=e.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=e.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=e.style.color),"inherit"===c.styles.fontStyle&&(a.styles.fontStyle=e.style.fstyle))}});
|
||||
"function"!==typeof c.createdCell&&(c.createdCell=function(a,b){b=g.teCells[b.row.index+":"+b.column.dataKey];a.styles.halign="inherit"===c.styles.halign?"center":c.styles.halign;a.styles.valign=c.styles.valign;"undefined"!==typeof b&&"undefined"!==typeof b.style&&!0!==b.style.hidden&&("inherit"===c.styles.halign&&(a.styles.halign=b.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=b.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=b.style.color),"inherit"===c.styles.fontStyle&&
|
||||
(a.styles.fontStyle=b.style.fstyle))});"function"!==typeof c.drawHeaderCell&&(c.drawHeaderCell=function(a,b){var c=g.columns[b.column.dataKey];return(!0!==c.style.hasOwnProperty("hidden")||!0!==c.style.hidden)&&0<=c.rowIndex?wa(a,b,c):!1});"function"!==typeof c.drawCell&&(c.drawCell=function(a,b){var c=g.teCells[b.row.index+":"+b.column.dataKey];if(!0!==("undefined"!==typeof c&&c.isCanvas))wa(a,b,c)&&(g.doc.rect(a.x,a.y,a.width,a.height,a.styles.fillStyle),"undefined"===typeof c||"undefined"!==typeof c.hasUserDefText&&
|
||||
!0===c.hasUserDefText||"undefined"===typeof c.elements||!c.elements.length?Aa(a,{},g):(b=a.height/c.rect.height,b>g.hScaleFactor&&(g.hScaleFactor=b),g.wScaleFactor=a.width/c.rect.width,b=a.textPos.y,za(a,c.elements,g),a.textPos.y=b,Aa(a,c.elements,g)));else{c=c.elements[0];var e=d(c).attr("data-tableexport-canvas"),f=c.getBoundingClientRect();a.width=f.width*g.wScaleFactor;a.height=f.height*g.hScaleFactor;b.row.height=a.height;ua(a,c,e,g)}return!1});g.headerrows=[];r=y(d(this));d(r).each(function(){b=
|
||||
0;g.headerrows[p]=[];E(this,"th,td",p,r.length,function(a,c,d){var e=Ca(a);e.title=D(a,c,d);e.key=b++;e.rowIndex=p;g.headerrows[p].push(e)});p++});if(0<p)for(var e=p-1;0<=e;)d.each(g.headerrows[e],function(){var a=this;0<e&&null===this.rect&&(a=g.headerrows[e-1][this.key]);null!==a&&0<=a.rowIndex&&(!0!==a.style.hasOwnProperty("hidden")||!0!==a.style.hidden)&&g.columns.push(a)}),e=0<g.columns.length?-1:e-1;var k=0;w=[];w=C(d(this));d(w).each(function(){var a=[];b=0;E(this,"td,th",p,r.length+w.length,
|
||||
function(c,e,f){if("undefined"===typeof g.columns[b]){var h={title:"",key:b,style:{hidden:!0}};g.columns.push(h)}a.push(D(c,e,f));"undefined"!==typeof c&&null!==c?(h=Ca(c),h.isCanvas=c.hasAttribute("data-tableexport-canvas"),h.elements=h.isCanvas?d(c):d(c).children(),"undefined"!==typeof d(c).data("teUserDefText")&&(h.hasUserDefText=!0)):(h=d.extend(!0,{},g.teCells[k+":"+(b-1)]),h.colspan=-1);g.teCells[k+":"+b++]=h});a.length&&(g.rows.push(a),k++);p++});if("function"===typeof g.onBeforeAutotable)g.onBeforeAutotable(d(this),
|
||||
g.columns,g.rows,c);g.doc.autoTable(g.columns,g.rows,c);if("function"===typeof g.onAfterAutotable)g.onAfterAutotable(d(this),c);a.jspdf.autotable.startY=g.doc.autoTableEndPosY()+c.margin.top});va(g.doc,"undefined"!==typeof g.images&&!1===jQuery.isEmptyObject(g.images));"undefined"!==typeof g.headerrows&&(g.headerrows.length=0);"undefined"!==typeof g.columns&&(g.columns.length=0);"undefined"!==typeof g.rows&&(g.rows.length=0);delete g.doc;g.doc=null})}if("function"===typeof a.onTableExportEnd)a.onTableExportEnd();
|
||||
return this}})(jQuery);
|
||||
@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @author: Dennis Hernández
|
||||
* @webSite: http://djhvscf.github.io/Blog
|
||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
||||
*/
|
||||
|
||||
const debounce = (func, wait) => {
|
||||
let timeout = 0
|
||||
|
||||
return (...args) => {
|
||||
const later = () => {
|
||||
timeout = 0
|
||||
func(...args)
|
||||
}
|
||||
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(later, wait)
|
||||
}
|
||||
}
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
mobileResponsive: false,
|
||||
minWidth: 562,
|
||||
minHeight: undefined,
|
||||
heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar
|
||||
checkOnInit: true,
|
||||
columnsHidden: []
|
||||
})
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
init (...args) {
|
||||
super.init(...args)
|
||||
|
||||
if (!this.options.mobileResponsive || !this.options.minWidth) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.options.minWidth < 100 && this.options.resizable) {
|
||||
console.warn('The minWidth when the resizable extension is active should be greater or equal than 100')
|
||||
this.options.minWidth = 100
|
||||
}
|
||||
|
||||
let old = {
|
||||
width: $(window).width(),
|
||||
height: $(window).height()
|
||||
}
|
||||
|
||||
$(window).on('resize orientationchange', debounce(() => {
|
||||
// reset view if height has only changed by at least the threshold.
|
||||
const width = $(window).width()
|
||||
const height = $(window).height()
|
||||
const $activeElement = $(document.activeElement)
|
||||
|
||||
if ($activeElement.length && ['INPUT', 'SELECT', 'TEXTAREA'].includes($activeElement.prop('nodeName'))) {
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
Math.abs(old.height - height) > this.options.heightThreshold ||
|
||||
old.width !== width
|
||||
) {
|
||||
this.changeView(width, height)
|
||||
old = {
|
||||
width,
|
||||
height
|
||||
}
|
||||
}
|
||||
}, 200))
|
||||
|
||||
if (this.options.checkOnInit) {
|
||||
const width = $(window).width()
|
||||
const height = $(window).height()
|
||||
|
||||
this.changeView(width, height)
|
||||
old = {
|
||||
width,
|
||||
height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conditionCardView () {
|
||||
this.changeTableView(false)
|
||||
this.showHideColumns(false)
|
||||
}
|
||||
|
||||
conditionFullView () {
|
||||
this.changeTableView(true)
|
||||
this.showHideColumns(true)
|
||||
}
|
||||
|
||||
changeTableView (cardViewState) {
|
||||
this.options.cardView = cardViewState
|
||||
this.toggleView()
|
||||
}
|
||||
|
||||
showHideColumns (checked) {
|
||||
if (this.options.columnsHidden.length > 0) {
|
||||
this.columns.forEach(column => {
|
||||
if (this.options.columnsHidden.includes(column.field)) {
|
||||
if (column.visible !== checked) {
|
||||
this._toggleColumn(this.fieldsColumnsIndex[column.field], checked, true)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
changeView (width, height) {
|
||||
if (this.options.minHeight) {
|
||||
if ((width <= this.options.minWidth) && (height <= this.options.minHeight)) {
|
||||
this.conditionCardView()
|
||||
} else if ((width > this.options.minWidth) && (height > this.options.minHeight)) {
|
||||
this.conditionFullView()
|
||||
}
|
||||
} else if (width <= this.options.minWidth) {
|
||||
this.conditionCardView()
|
||||
} else if (width > this.options.minWidth) {
|
||||
this.conditionFullView()
|
||||
}
|
||||
|
||||
this.resetView()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,285 @@
|
||||
/**
|
||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
||||
*/
|
||||
|
||||
var Utils = $.fn.bootstrapTable.utils
|
||||
|
||||
function printPageBuilderDefault (table) {
|
||||
return `
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css" media="print">
|
||||
@page {
|
||||
size: auto;
|
||||
margin: 25px 0 25px 0;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css" media="all">
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
font-size: 12px;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid grey;
|
||||
}
|
||||
th, td {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
p {
|
||||
font-weight: bold;
|
||||
margin-left:20px;
|
||||
}
|
||||
table {
|
||||
width:94%;
|
||||
margin-left:3%;
|
||||
margin-right:3%;
|
||||
}
|
||||
div.bs-table-print {
|
||||
text-align:center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<title>Print Table</title>
|
||||
<body>
|
||||
<p>Printed on: ${new Date} </p>
|
||||
<div class="bs-table-print">${table}</div>
|
||||
</body>
|
||||
</html>`
|
||||
}
|
||||
|
||||
$.extend($.fn.bootstrapTable.locales, {
|
||||
formatPrint () {
|
||||
return 'Print'
|
||||
}
|
||||
})
|
||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
showPrint: false,
|
||||
printAsFilteredAndSortedOnUI: true,
|
||||
printSortColumn: undefined,
|
||||
printSortOrder: 'asc',
|
||||
printPageBuilder (table) {
|
||||
return printPageBuilderDefault(table)
|
||||
}
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
|
||||
printFilter: undefined,
|
||||
printIgnore: false,
|
||||
printFormatter: undefined
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||
print: {
|
||||
bootstrap3: 'glyphicon-print icon-share',
|
||||
'bootstrap-table': 'icon-printer'
|
||||
}[$.fn.bootstrapTable.theme] || 'fa-print'
|
||||
})
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
init (...args) {
|
||||
super.init(...args)
|
||||
|
||||
if (!this.options.showPrint) {
|
||||
return
|
||||
}
|
||||
|
||||
this.mergedCells = []
|
||||
}
|
||||
|
||||
initToolbar (...args) {
|
||||
this.showToolbar = this.showToolbar || this.options.showPrint
|
||||
|
||||
if (this.options.showPrint) {
|
||||
this.buttons = Object.assign(this.buttons, {
|
||||
print: {
|
||||
text: this.options.formatPrint(),
|
||||
icon: this.options.icons.print,
|
||||
event: () => {
|
||||
this.doPrint(this.options.printAsFilteredAndSortedOnUI ? this.getData() : this.options.data.slice(0))
|
||||
},
|
||||
attributes: {
|
||||
'aria-label': this.options.formatPrint(),
|
||||
title: this.options.formatPrint()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
super.initToolbar(...args)
|
||||
}
|
||||
|
||||
mergeCells (options) {
|
||||
super.mergeCells(options)
|
||||
|
||||
if (!this.options.showPrint) {
|
||||
return
|
||||
}
|
||||
|
||||
let col = this.getVisibleFields().indexOf(options.field)
|
||||
|
||||
if (Utils.hasDetailViewIcon(this.options)) {
|
||||
col += 1
|
||||
}
|
||||
|
||||
this.mergedCells.push({
|
||||
row: options.index,
|
||||
col,
|
||||
rowspan: options.rowspan || 1,
|
||||
colspan: options.colspan || 1
|
||||
})
|
||||
}
|
||||
|
||||
doPrint (data) {
|
||||
const formatValue = (row, i, column) => {
|
||||
const value = Utils.calculateObjectValue(column,
|
||||
column.printFormatter || column.formatter,
|
||||
[$.common.getItemField(row, column.field), row, i], $.common.getItemField(row, column.field))
|
||||
|
||||
return typeof value === 'undefined' || value === null ?
|
||||
this.options.undefinedText : value
|
||||
}
|
||||
|
||||
const buildTable = (data, columnsArray) => {
|
||||
const dir = this.$el.attr('dir') || 'ltr'
|
||||
const html = [`<table dir="${dir}"><thead>`]
|
||||
|
||||
for (const columns of columnsArray) {
|
||||
html.push('<tr>')
|
||||
for (let h = 0; h < columns.length; h++) {
|
||||
if (!columns[h].printIgnore) {
|
||||
html.push(
|
||||
`<th
|
||||
${Utils.sprintf(' rowspan="%s"', columns[h].rowspan)}
|
||||
${Utils.sprintf(' colspan="%s"', columns[h].colspan)}
|
||||
>${columns[h].title}</th>`)
|
||||
}
|
||||
}
|
||||
html.push('</tr>')
|
||||
}
|
||||
|
||||
html.push('</thead><tbody>')
|
||||
|
||||
const dontRender = []
|
||||
|
||||
if (this.mergedCells) {
|
||||
for (let mc = 0; mc < this.mergedCells.length; mc++) {
|
||||
const currentMergedCell = this.mergedCells[mc]
|
||||
|
||||
for (let rs = 0; rs < currentMergedCell.rowspan; rs++) {
|
||||
const row = currentMergedCell.row + rs
|
||||
|
||||
for (let cs = 0; cs < currentMergedCell.colspan; cs++) {
|
||||
const col = currentMergedCell.col + cs
|
||||
|
||||
dontRender.push(`${row },${ col}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
html.push('<tr>')
|
||||
|
||||
const columns = columnsArray.flat(1)
|
||||
|
||||
columns.sort((c1, c2) => {
|
||||
return c1.colspanIndex - c2.colspanIndex
|
||||
})
|
||||
|
||||
for (let j = 0; j < columns.length; j++) {
|
||||
if (columns[j].colspanGroup > 0) continue
|
||||
|
||||
let rowspan = 0
|
||||
let colspan = 0
|
||||
|
||||
if (this.mergedCells) {
|
||||
for (let mc = 0; mc < this.mergedCells.length; mc++) {
|
||||
const currentMergedCell = this.mergedCells[mc]
|
||||
|
||||
if (currentMergedCell.col === j && currentMergedCell.row === i) {
|
||||
rowspan = currentMergedCell.rowspan
|
||||
colspan = currentMergedCell.colspan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!columns[j].printIgnore && columns[j].field &&
|
||||
(
|
||||
!dontRender.includes(`${i },${ j}`) ||
|
||||
(rowspan > 0 && colspan > 0)
|
||||
)
|
||||
) {
|
||||
if (rowspan > 0 && colspan > 0) {
|
||||
html.push(`<td ${Utils.sprintf(' rowspan="%s"', rowspan)} ${Utils.sprintf(' colspan="%s"', colspan)}>`, formatValue(data[i], i, columns[j]), '</td>')
|
||||
} else {
|
||||
html.push('<td>', formatValue(data[i], i, columns[j]), '</td>')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
html.push('</tr>')
|
||||
}
|
||||
|
||||
html.push('</tbody>')
|
||||
if (this.options.showFooter) {
|
||||
html.push('<footer><tr>')
|
||||
|
||||
for (const columns of columnsArray) {
|
||||
for (let h = 0; h < columns.length; h++) {
|
||||
if (!columns[h].printIgnore) {
|
||||
const footerData = Utils.trToData(columns, this.$el.find('>tfoot>tr'))
|
||||
const footerValue = Utils.calculateObjectValue(columns[h], columns[h].footerFormatter, [data], footerData[0] && footerData[0][columns[h].field] || '')
|
||||
|
||||
html.push(`<th>${footerValue}</th>`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html.push('</tr></footer>')
|
||||
}
|
||||
html.push('</table>')
|
||||
return html.join('')
|
||||
}
|
||||
|
||||
const sortRows = (data, colName, sortOrder) => {
|
||||
if (!colName) {
|
||||
return data
|
||||
}
|
||||
let reverse = sortOrder !== 'asc'
|
||||
|
||||
reverse = -((+reverse) || -1)
|
||||
return data.sort((a, b) => reverse * (a[colName].localeCompare(b[colName])))
|
||||
}
|
||||
|
||||
const filterRow = (row, filters) => {
|
||||
for (let index = 0; index < filters.length; ++index) {
|
||||
if (row[filters[index].colName] !== filters[index].value) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const filterRows = (data, filters) => data.filter(row => filterRow(row, filters))
|
||||
const getColumnFilters = columns => !columns || !columns[0] ? [] : columns[0].filter(col => col.printFilter).map(col => ({
|
||||
colName: col.field,
|
||||
value: col.printFilter
|
||||
}))
|
||||
|
||||
data = filterRows(data, getColumnFilters(this.options.columns))
|
||||
data = sortRows(data, this.options.printSortColumn, this.options.printSortOrder)
|
||||
const table = buildTable(data, this.options.columns)
|
||||
const newWin = window.open('')
|
||||
|
||||
newWin.document.write(this.options.printPageBuilder.call(this, table))
|
||||
newWin.document.close()
|
||||
newWin.focus()
|
||||
newWin.print()
|
||||
newWin.close()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,213 @@
|
||||
/**
|
||||
* @author: Dennis Hernández
|
||||
* @webSite: http://djhvscf.github.io/Blog
|
||||
* @update: https://github.com/wenzhixin
|
||||
* @version: v1.2.0
|
||||
*/
|
||||
|
||||
$.akottr.dragtable.prototype._restoreState = function (persistObj) {
|
||||
let i = 0
|
||||
|
||||
for (const [field, value] of Object.entries(persistObj)) {
|
||||
const $th = this.originalTable.el.find(`th[data-field="${field}"]`)
|
||||
|
||||
if (!$th.length) {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
this.originalTable.startIndex = $th.prevAll().length + 1
|
||||
this.originalTable.endIndex = parseInt(value, 10) + 1 - i
|
||||
this._bubbleCols()
|
||||
}
|
||||
}
|
||||
|
||||
// From MDN site, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||
const filterFn = () => {
|
||||
if (!Array.prototype.filter) {
|
||||
Array.prototype.filter = function (fun/* , thisArg*/) {
|
||||
if (this === undefined || this === null) {
|
||||
throw new TypeError()
|
||||
}
|
||||
|
||||
const t = Object(this)
|
||||
const len = t.length >>> 0
|
||||
|
||||
if (typeof fun !== 'function') {
|
||||
throw new TypeError()
|
||||
}
|
||||
|
||||
const res = []
|
||||
const thisArg = arguments.length >= 2 ? arguments[1] : undefined
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
if (i in t) {
|
||||
const val = t[i]
|
||||
|
||||
// NOTE: Technically this should Object.defineProperty at
|
||||
// the next index, as push can be affected by
|
||||
// properties on Object.prototype and Array.prototype.
|
||||
// But this method's new, and collisions should be
|
||||
// rare, so use the more-compatible alternative.
|
||||
if (fun.call(thisArg, val, i, t)) {
|
||||
res.push(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
reorderableColumns: false,
|
||||
maxMovingRows: 10,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onReorderColumn (headerFields) {
|
||||
return false
|
||||
},
|
||||
dragaccept: null
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||
'reorder-column.bs.table': 'onReorderColumn'
|
||||
})
|
||||
|
||||
$.fn.bootstrapTable.methods.push('orderColumns')
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
initHeader (...args) {
|
||||
super.initHeader(...args)
|
||||
|
||||
if (!this.options.reorderableColumns) {
|
||||
return
|
||||
}
|
||||
|
||||
this.makeRowsReorderable()
|
||||
}
|
||||
|
||||
_toggleColumn (...args) {
|
||||
super._toggleColumn(...args)
|
||||
|
||||
if (!this.options.reorderableColumns) {
|
||||
return
|
||||
}
|
||||
|
||||
this.makeRowsReorderable()
|
||||
}
|
||||
|
||||
toggleView (...args) {
|
||||
super.toggleView(...args)
|
||||
|
||||
if (!this.options.reorderableColumns) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.options.cardView) {
|
||||
return
|
||||
}
|
||||
|
||||
this.makeRowsReorderable()
|
||||
}
|
||||
|
||||
resetView (...args) {
|
||||
super.resetView(...args)
|
||||
|
||||
if (!this.options.reorderableColumns) {
|
||||
return
|
||||
}
|
||||
|
||||
this.makeRowsReorderable()
|
||||
}
|
||||
|
||||
makeRowsReorderable (order = null) {
|
||||
try {
|
||||
$(this.$el).dragtable('destroy')
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
$(this.$el).dragtable({
|
||||
maxMovingRows: this.options.maxMovingRows,
|
||||
dragaccept: this.options.dragaccept,
|
||||
clickDelay: 200,
|
||||
dragHandle: '.th-inner',
|
||||
restoreState: order ? order : this.columnsSortOrder,
|
||||
beforeStop: table => {
|
||||
const sortOrder = {}
|
||||
|
||||
table.el.find('th').each((i, el) => {
|
||||
sortOrder[$(el).data('field')] = i
|
||||
})
|
||||
|
||||
this.columnsSortOrder = sortOrder
|
||||
if (this.options.cookie) {
|
||||
this.persistReorderColumnsState(this)
|
||||
}
|
||||
|
||||
const ths = []
|
||||
const formatters = []
|
||||
const columns = []
|
||||
let columnsHidden = []
|
||||
let columnIndex = -1
|
||||
const optionsColumns = []
|
||||
|
||||
this.$header.find('th:not(.detail)').each((i, el) => {
|
||||
ths.push($(el).data('field'))
|
||||
formatters.push($(el).data('formatter'))
|
||||
})
|
||||
|
||||
// Exist columns not shown
|
||||
if (ths.length < this.columns.length) {
|
||||
columnsHidden = this.columns.filter(column => !column.visible)
|
||||
for (let i = 0; i < columnsHidden.length; i++) {
|
||||
ths.push(columnsHidden[i].field)
|
||||
formatters.push(columnsHidden[i].formatter)
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < ths.length; i++) {
|
||||
columnIndex = this.fieldsColumnsIndex[ths[i]]
|
||||
if (columnIndex !== -1) {
|
||||
this.fieldsColumnsIndex[ths[i]] = i
|
||||
this.columns[columnIndex].fieldIndex = i
|
||||
columns.push(this.columns[columnIndex])
|
||||
}
|
||||
}
|
||||
|
||||
this.columns = columns
|
||||
|
||||
filterFn() // Support <IE9
|
||||
$.each(this.columns, (i, column) => {
|
||||
let found = false
|
||||
const field = column.field
|
||||
|
||||
this.options.columns[0].filter(item => {
|
||||
if (!found && item['field'] === field) {
|
||||
optionsColumns.push(item)
|
||||
found = true
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
})
|
||||
|
||||
this.options.columns[0] = optionsColumns
|
||||
|
||||
this.header.fields = ths
|
||||
this.header.formatters = formatters
|
||||
this.initHeader()
|
||||
this.initToolbar()
|
||||
this.initSearchText()
|
||||
this.initBody()
|
||||
this.resetView()
|
||||
this.trigger('reorder-column', ths)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
orderColumns (order) {
|
||||
this.columnsSortOrder = order
|
||||
this.makeRowsReorderable()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* @author: Dennis Hernández
|
||||
* @webSite: http://djhvscf.github.io/Blog
|
||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
||||
*/
|
||||
|
||||
const rowAttr = (row, index) => ({
|
||||
id: `customId_${index}`
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
reorderableRows: false,
|
||||
onDragStyle: null,
|
||||
onDropStyle: null,
|
||||
onDragClass: 'reorder_rows_onDragClass',
|
||||
dragHandle: '>tbody>tr>td:not(.bs-checkbox)',
|
||||
useRowAttrFunc: false,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onReorderRowsDrag (row) {
|
||||
return false
|
||||
},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onReorderRowsDrop (row) {
|
||||
return false
|
||||
},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onReorderRow (newData) {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||
'reorder-row.bs.table': 'onReorderRow'
|
||||
})
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
init (...args) {
|
||||
if (!this.options.reorderableRows) {
|
||||
super.init(...args)
|
||||
return
|
||||
}
|
||||
|
||||
if (this.options.useRowAttrFunc) {
|
||||
this.options.rowAttributes = rowAttr
|
||||
}
|
||||
|
||||
const onPostBody = this.options.onPostBody
|
||||
|
||||
this.options.onPostBody = () => {
|
||||
setTimeout(() => {
|
||||
this.makeRowsReorderable()
|
||||
onPostBody.call(this.options, this.options.data)
|
||||
}, 1)
|
||||
}
|
||||
|
||||
super.init(...args)
|
||||
}
|
||||
|
||||
makeRowsReorderable () {
|
||||
this.$el.tableDnD({
|
||||
onDragStyle: this.options.onDragStyle,
|
||||
onDropStyle: this.options.onDropStyle,
|
||||
onDragClass: this.options.onDragClass,
|
||||
onDragStart: (table, droppedRow) => this.onDropStart(table, droppedRow),
|
||||
onDrop: (table, droppedRow) => this.onDrop(table, droppedRow),
|
||||
dragHandle: this.options.dragHandle
|
||||
})
|
||||
}
|
||||
|
||||
onDropStart (table, draggingTd) {
|
||||
this.$draggingTd = $(draggingTd).css('cursor', 'move')
|
||||
this.draggingIndex = $(this.$draggingTd.parent()).data('index')
|
||||
// Call the user defined function
|
||||
this.options.onReorderRowsDrag(this.data[this.draggingIndex])
|
||||
}
|
||||
|
||||
onDrop (table) {
|
||||
this.$draggingTd.css('cursor', '')
|
||||
const newData = []
|
||||
|
||||
for (let i = 0; i < table.tBodies[0].rows.length; i++) {
|
||||
const $tr = $(table.tBodies[0].rows[i])
|
||||
|
||||
newData.push(this.data[$tr.data('index')])
|
||||
$tr.data('index', i)
|
||||
}
|
||||
|
||||
const draggingRow = this.data[this.draggingIndex]
|
||||
const droppedIndex = newData.indexOf(this.data[this.draggingIndex])
|
||||
const droppedRow = this.data[droppedIndex]
|
||||
const index = this.options.data.indexOf(this.data[droppedIndex])
|
||||
|
||||
this.options.data.splice(this.options.data.indexOf(draggingRow), 1)
|
||||
this.options.data.splice(index, 0, draggingRow)
|
||||
|
||||
this.initSearch()
|
||||
|
||||
// Call the user defined function
|
||||
this.options.onReorderRowsDrop(droppedRow)
|
||||
|
||||
// Call the event reorder-row
|
||||
this.trigger('reorder-row', newData, draggingRow, droppedRow)
|
||||
}
|
||||
|
||||
initSearch () {
|
||||
this.ignoreInitSort = true
|
||||
super.initSearch()
|
||||
}
|
||||
|
||||
initSort () {
|
||||
if (this.ignoreInitSort) {
|
||||
this.ignoreInitSort = false
|
||||
return
|
||||
}
|
||||
|
||||
super.initSort()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,603 @@
|
||||
/**
|
||||
* TableDnD plug-in for JQuery, allows you to drag and drop table rows
|
||||
* You can set up various options to control how the system will work
|
||||
* Copyright (c) Denis Howlett <denish@isocra.com>
|
||||
* License: MIT.
|
||||
* See https://github.com/isocra/TableDnD
|
||||
*/
|
||||
!function ($, window, document, undefined) {
|
||||
|
||||
var startEvent = 'touchstart mousedown',
|
||||
moveEvent = 'touchmove mousemove',
|
||||
endEvent = 'touchend mouseup';
|
||||
|
||||
$(document).ready(function () {
|
||||
function parseStyle(css) {
|
||||
var objMap = {},
|
||||
parts = css.match(/([^;:]+)/g) || [];
|
||||
while (parts.length)
|
||||
objMap[parts.shift()] = parts.shift().trim();
|
||||
|
||||
return objMap;
|
||||
}
|
||||
$('table').each(function () {
|
||||
if ($(this).data('table') === 'dnd') {
|
||||
|
||||
$(this).tableDnD({
|
||||
onDragStyle: $(this).data('ondragstyle') && parseStyle($(this).data('ondragstyle')) || null,
|
||||
onDropStyle: $(this).data('ondropstyle') && parseStyle($(this).data('ondropstyle')) || null,
|
||||
onDragClass: $(this).data('ondragclass') === undefined && "tDnD_whileDrag" || $(this).data('ondragclass'),
|
||||
onDrop: $(this).data('ondrop') && new Function('table', 'row', $(this).data('ondrop')), // 'return eval("'+$(this).data('ondrop')+'");') || null,
|
||||
onDragStart: $(this).data('ondragstart') && new Function('table', 'row' ,$(this).data('ondragstart')), // 'return eval("'+$(this).data('ondragstart')+'");') || null,
|
||||
onDragStop: $(this).data('ondragstop') && new Function('table', 'row' ,$(this).data('ondragstop')),
|
||||
scrollAmount: $(this).data('scrollamount') || 5,
|
||||
sensitivity: $(this).data('sensitivity') || 10,
|
||||
hierarchyLevel: $(this).data('hierarchylevel') || 0,
|
||||
indentArtifact: $(this).data('indentartifact') || '<div class="indent"> </div>',
|
||||
autoWidthAdjust: $(this).data('autowidthadjust') || true,
|
||||
autoCleanRelations: $(this).data('autocleanrelations') || true,
|
||||
jsonPretifySeparator: $(this).data('jsonpretifyseparator') || '\t',
|
||||
serializeRegexp: $(this).data('serializeregexp') && new RegExp($(this).data('serializeregexp')) || /[^\-]*$/,
|
||||
serializeParamName: $(this).data('serializeparamname') || false,
|
||||
dragHandle: $(this).data('draghandle') || null
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
jQuery.tableDnD = {
|
||||
/** Keep hold of the current table being dragged */
|
||||
currentTable: null,
|
||||
/** Keep hold of the current drag object if any */
|
||||
dragObject: null,
|
||||
/** The current mouse offset */
|
||||
mouseOffset: null,
|
||||
/** Remember the old value of X and Y so that we don't do too much processing */
|
||||
oldX: 0,
|
||||
oldY: 0,
|
||||
|
||||
/** Actually build the structure */
|
||||
build: function(options) {
|
||||
// Set up the defaults if any
|
||||
|
||||
this.each(function() {
|
||||
// This is bound to each matching table, set up the defaults and override with user options
|
||||
this.tableDnDConfig = $.extend({
|
||||
onDragStyle: null,
|
||||
onDropStyle: null,
|
||||
// Add in the default class for whileDragging
|
||||
onDragClass: "tDnD_whileDrag",
|
||||
onDrop: null,
|
||||
onDragStart: null,
|
||||
onDragStop: null,
|
||||
scrollAmount: 5,
|
||||
/** Sensitivity setting will throttle the trigger rate for movement detection */
|
||||
sensitivity: 10,
|
||||
/** Hierarchy level to support parent child. 0 switches this functionality off */
|
||||
hierarchyLevel: 0,
|
||||
/** The html artifact to prepend the first cell with as indentation */
|
||||
indentArtifact: '<div class="indent"> </div>',
|
||||
/** Automatically adjust width of first cell */
|
||||
autoWidthAdjust: true,
|
||||
/** Automatic clean-up to ensure relationship integrity */
|
||||
autoCleanRelations: true,
|
||||
/** Specify a number (4) as number of spaces or any indent string for JSON.stringify */
|
||||
jsonPretifySeparator: '\t',
|
||||
/** The regular expression to use to trim row IDs */
|
||||
serializeRegexp: /[^\-]*$/,
|
||||
/** If you want to specify another parameter name instead of the table ID */
|
||||
serializeParamName: false,
|
||||
/** If you give the name of a class here, then only Cells with this class will be draggable */
|
||||
dragHandle: null
|
||||
}, options || {});
|
||||
|
||||
// Now make the rows draggable
|
||||
$.tableDnD.makeDraggable(this);
|
||||
// Prepare hierarchy support
|
||||
this.tableDnDConfig.hierarchyLevel
|
||||
&& $.tableDnD.makeIndented(this);
|
||||
});
|
||||
|
||||
// Don't break the chain
|
||||
return this;
|
||||
},
|
||||
makeIndented: function (table) {
|
||||
var config = table.tableDnDConfig,
|
||||
rows = table.rows,
|
||||
firstCell = $(rows).first().find('td:first')[0],
|
||||
indentLevel = 0,
|
||||
cellWidth = 0,
|
||||
longestCell,
|
||||
tableStyle;
|
||||
|
||||
if ($(table).hasClass('indtd'))
|
||||
return null;
|
||||
|
||||
tableStyle = $(table).addClass('indtd').attr('style');
|
||||
$(table).css({whiteSpace: "nowrap"});
|
||||
|
||||
for (var w = 0; w < rows.length; w++) {
|
||||
if (cellWidth < $(rows[w]).find('td:first').text().length) {
|
||||
cellWidth = $(rows[w]).find('td:first').text().length;
|
||||
longestCell = w;
|
||||
}
|
||||
}
|
||||
$(firstCell).css({width: 'auto'});
|
||||
for (w = 0; w < config.hierarchyLevel; w++)
|
||||
$(rows[longestCell]).find('td:first').prepend(config.indentArtifact);
|
||||
firstCell && $(firstCell).css({width: firstCell.offsetWidth});
|
||||
tableStyle && $(table).css(tableStyle);
|
||||
|
||||
for (w = 0; w < config.hierarchyLevel; w++)
|
||||
$(rows[longestCell]).find('td:first').children(':first').remove();
|
||||
|
||||
config.hierarchyLevel
|
||||
&& $(rows).each(function () {
|
||||
indentLevel = $(this).data('level') || 0;
|
||||
indentLevel <= config.hierarchyLevel
|
||||
&& $(this).data('level', indentLevel)
|
||||
|| $(this).data('level', 0);
|
||||
for (var i = 0; i < $(this).data('level'); i++)
|
||||
$(this).find('td:first').prepend(config.indentArtifact);
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
/** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */
|
||||
makeDraggable: function(table) {
|
||||
var config = table.tableDnDConfig;
|
||||
|
||||
config.dragHandle
|
||||
// We only need to add the event to the specified cells
|
||||
&& $(config.dragHandle, table).each(function() {
|
||||
if (! $(this).hasClass("nodrag")) {
|
||||
// The cell is bound to "this"
|
||||
$(this).bind(startEvent, function(e) {
|
||||
if (e.target.tagName === "TD" && event.target.className !== "nodrag") {
|
||||
$.tableDnD.initialiseDrag($(this).parents('tr')[0], table, this, e, config);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
})
|
||||
// For backwards compatibility, we add the event to the whole row
|
||||
// get all the rows as a wrapped set
|
||||
|| $(table.rows).each(function() {
|
||||
// Iterate through each row, the row is bound to "this"
|
||||
if (! $(this).hasClass("nodrag")) {
|
||||
$(this).bind(startEvent, function(e) {
|
||||
if (e.target.tagName === "TD" && event.target.className !== "nodrag") {
|
||||
$.tableDnD.initialiseDrag(this, table, this, e, config);
|
||||
return false;
|
||||
}
|
||||
}).css("cursor", "move"); // Store the tableDnD object
|
||||
} else {
|
||||
$(this).css("cursor", ""); // Remove the cursor if we don't have the nodrag class
|
||||
}
|
||||
});
|
||||
},
|
||||
currentOrder: function() {
|
||||
var rows = this.currentTable.rows;
|
||||
return $.map(rows, function (val) {
|
||||
return ($(val).data('level') + val.id).replace(/\s/g, '');
|
||||
}).join('');
|
||||
},
|
||||
initialiseDrag: function(dragObject, table, target, e, config) {
|
||||
this.dragObject = dragObject;
|
||||
this.currentTable = table;
|
||||
this.mouseOffset = this.getMouseOffset(target, e);
|
||||
this.originalOrder = this.currentOrder();
|
||||
|
||||
// Now we need to capture the mouse up and mouse move event
|
||||
// We can use bind so that we don't interfere with other event handlers
|
||||
$(document)
|
||||
.bind(moveEvent, this.mousemove)
|
||||
.bind(endEvent, this.mouseup);
|
||||
|
||||
// Call the onDragStart method if there is one
|
||||
config.onDragStart
|
||||
&& config.onDragStart(table, target);
|
||||
},
|
||||
updateTables: function() {
|
||||
this.each(function() {
|
||||
// this is now bound to each matching table
|
||||
if (this.tableDnDConfig)
|
||||
$.tableDnD.makeDraggable(this);
|
||||
});
|
||||
},
|
||||
/** Get the mouse coordinates from the event (allowing for browser differences) */
|
||||
mouseCoords: function(e) {
|
||||
if (e.originalEvent.changedTouches)
|
||||
return {
|
||||
x: e.originalEvent.changedTouches[0].clientX,
|
||||
y: e.originalEvent.changedTouches[0].clientY
|
||||
};
|
||||
|
||||
if(e.pageX || e.pageY)
|
||||
return {
|
||||
x: e.pageX,
|
||||
y: e.pageY
|
||||
};
|
||||
|
||||
return {
|
||||
x: e.clientX + document.body.scrollLeft - document.body.clientLeft,
|
||||
y: e.clientY + document.body.scrollTop - document.body.clientTop
|
||||
};
|
||||
},
|
||||
/** Given a target element and a mouse eent, get the mouse offset from that element.
|
||||
To do this we need the element's position and the mouse position */
|
||||
getMouseOffset: function(target, e) {
|
||||
var mousePos,
|
||||
docPos;
|
||||
|
||||
e = e || window.event;
|
||||
|
||||
docPos = this.getPosition(target);
|
||||
mousePos = this.mouseCoords(e);
|
||||
|
||||
return {
|
||||
x: mousePos.x - docPos.x,
|
||||
y: mousePos.y - docPos.y
|
||||
};
|
||||
},
|
||||
/** Get the position of an element by going up the DOM tree and adding up all the offsets */
|
||||
getPosition: function(element) {
|
||||
var left = 0,
|
||||
top = 0;
|
||||
|
||||
// Safari fix -- thanks to Luis Chato for this!
|
||||
// Safari 2 doesn't correctly grab the offsetTop of a table row
|
||||
// this is detailed here:
|
||||
// http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
|
||||
// the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
|
||||
// note that firefox will return a text node as a first child, so designing a more thorough
|
||||
// solution may need to take that into account, for now this seems to work in firefox, safari, ie
|
||||
if (element.offsetHeight === 0)
|
||||
element = element.firstChild; // a table cell
|
||||
|
||||
while (element.offsetParent) {
|
||||
left += element.offsetLeft;
|
||||
top += element.offsetTop;
|
||||
element = element.offsetParent;
|
||||
}
|
||||
|
||||
left += element.offsetLeft;
|
||||
top += element.offsetTop;
|
||||
|
||||
return {
|
||||
x: left,
|
||||
y: top
|
||||
};
|
||||
},
|
||||
autoScroll: function (mousePos) {
|
||||
var config = this.currentTable.tableDnDConfig,
|
||||
yOffset = window.pageYOffset,
|
||||
windowHeight = window.innerHeight
|
||||
? window.innerHeight
|
||||
: document.documentElement.clientHeight
|
||||
? document.documentElement.clientHeight
|
||||
: document.body.clientHeight;
|
||||
|
||||
// Windows version
|
||||
// yOffset=document.body.scrollTop;
|
||||
if (document.all)
|
||||
if (typeof document.compatMode !== 'undefined'
|
||||
&& document.compatMode !== 'BackCompat')
|
||||
yOffset = document.documentElement.scrollTop;
|
||||
else if (typeof document.body !== 'undefined')
|
||||
yOffset = document.body.scrollTop;
|
||||
|
||||
mousePos.y - yOffset < config.scrollAmount
|
||||
&& window.scrollBy(0, - config.scrollAmount)
|
||||
|| windowHeight - (mousePos.y - yOffset) < config.scrollAmount
|
||||
&& window.scrollBy(0, config.scrollAmount);
|
||||
|
||||
},
|
||||
moveVerticle: function (moving, currentRow) {
|
||||
|
||||
if (0 !== moving.vertical
|
||||
// If we're over a row then move the dragged row to there so that the user sees the
|
||||
// effect dynamically
|
||||
&& currentRow
|
||||
&& this.dragObject !== currentRow
|
||||
&& this.dragObject.parentNode === currentRow.parentNode)
|
||||
0 > moving.vertical
|
||||
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow.nextSibling)
|
||||
|| 0 < moving.vertical
|
||||
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow);
|
||||
|
||||
},
|
||||
moveHorizontal: function (moving, currentRow) {
|
||||
var config = this.currentTable.tableDnDConfig,
|
||||
currentLevel;
|
||||
|
||||
if (!config.hierarchyLevel
|
||||
|| 0 === moving.horizontal
|
||||
// We only care if moving left or right on the current row
|
||||
|| !currentRow
|
||||
|| this.dragObject !== currentRow)
|
||||
return null;
|
||||
|
||||
currentLevel = $(currentRow).data('level');
|
||||
|
||||
0 < moving.horizontal
|
||||
&& currentLevel > 0
|
||||
&& $(currentRow).find('td:first').children(':first').remove()
|
||||
&& $(currentRow).data('level', --currentLevel);
|
||||
|
||||
0 > moving.horizontal
|
||||
&& currentLevel < config.hierarchyLevel
|
||||
&& $(currentRow).prev().data('level') >= currentLevel
|
||||
&& $(currentRow).children(':first').prepend(config.indentArtifact)
|
||||
&& $(currentRow).data('level', ++currentLevel);
|
||||
|
||||
},
|
||||
mousemove: function(e) {
|
||||
var dragObj = $($.tableDnD.dragObject),
|
||||
config = $.tableDnD.currentTable.tableDnDConfig,
|
||||
currentRow,
|
||||
mousePos,
|
||||
moving,
|
||||
x,
|
||||
y;
|
||||
|
||||
e && e.preventDefault();
|
||||
|
||||
if (!$.tableDnD.dragObject)
|
||||
return false;
|
||||
|
||||
// prevent touch device screen scrolling
|
||||
e.type === 'touchmove'
|
||||
&& event.preventDefault(); // TODO verify this is event and not really e
|
||||
|
||||
// update the style to show we're dragging
|
||||
config.onDragClass
|
||||
&& dragObj.addClass(config.onDragClass)
|
||||
|| dragObj.css(config.onDragStyle);
|
||||
|
||||
mousePos = $.tableDnD.mouseCoords(e);
|
||||
x = mousePos.x - $.tableDnD.mouseOffset.x;
|
||||
y = mousePos.y - $.tableDnD.mouseOffset.y;
|
||||
|
||||
// auto scroll the window
|
||||
$.tableDnD.autoScroll(mousePos);
|
||||
|
||||
currentRow = $.tableDnD.findDropTargetRow(dragObj, y);
|
||||
moving = $.tableDnD.findDragDirection(x, y);
|
||||
|
||||
$.tableDnD.moveVerticle(moving, currentRow);
|
||||
$.tableDnD.moveHorizontal(moving, currentRow);
|
||||
|
||||
return false;
|
||||
},
|
||||
findDragDirection: function (x,y) {
|
||||
var sensitivity = this.currentTable.tableDnDConfig.sensitivity,
|
||||
oldX = this.oldX,
|
||||
oldY = this.oldY,
|
||||
xMin = oldX - sensitivity,
|
||||
xMax = oldX + sensitivity,
|
||||
yMin = oldY - sensitivity,
|
||||
yMax = oldY + sensitivity,
|
||||
moving = {
|
||||
horizontal: x >= xMin && x <= xMax ? 0 : x > oldX ? -1 : 1,
|
||||
vertical : y >= yMin && y <= yMax ? 0 : y > oldY ? -1 : 1
|
||||
};
|
||||
|
||||
// update the old value
|
||||
if (moving.horizontal !== 0)
|
||||
this.oldX = x;
|
||||
if (moving.vertical !== 0)
|
||||
this.oldY = y;
|
||||
|
||||
return moving;
|
||||
},
|
||||
/** We're only worried about the y position really, because we can only move rows up and down */
|
||||
findDropTargetRow: function(draggedRow, y) {
|
||||
var rowHeight = 0,
|
||||
rows = this.currentTable.rows,
|
||||
config = this.currentTable.tableDnDConfig,
|
||||
rowY = 0,
|
||||
row = null;
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
row = rows[i];
|
||||
rowY = this.getPosition(row).y;
|
||||
rowHeight = parseInt(row.offsetHeight) / 2;
|
||||
if (row.offsetHeight === 0) {
|
||||
rowY = this.getPosition(row.firstChild).y;
|
||||
rowHeight = parseInt(row.firstChild.offsetHeight) / 2;
|
||||
}
|
||||
// Because we always have to insert before, we need to offset the height a bit
|
||||
if (y > (rowY - rowHeight) && y < (rowY + rowHeight))
|
||||
// that's the row we're over
|
||||
// If it's the same as the current row, ignore it
|
||||
if (draggedRow.is(row)
|
||||
|| (config.onAllowDrop
|
||||
&& !config.onAllowDrop(draggedRow, row))
|
||||
// If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic)
|
||||
|| $(row).hasClass("nodrop"))
|
||||
return null;
|
||||
else
|
||||
return row;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
processMouseup: function() {
|
||||
if (!this.currentTable || !this.dragObject)
|
||||
return null;
|
||||
|
||||
var config = this.currentTable.tableDnDConfig,
|
||||
droppedRow = this.dragObject,
|
||||
parentLevel = 0,
|
||||
myLevel = 0;
|
||||
|
||||
// Unbind the event handlers
|
||||
$(document)
|
||||
.unbind(moveEvent, this.mousemove)
|
||||
.unbind(endEvent, this.mouseup);
|
||||
|
||||
config.hierarchyLevel
|
||||
&& config.autoCleanRelations
|
||||
&& $(this.currentTable.rows).first().find('td:first').children().each(function () {
|
||||
myLevel = $(this).parents('tr:first').data('level');
|
||||
myLevel
|
||||
&& $(this).parents('tr:first').data('level', --myLevel)
|
||||
&& $(this).remove();
|
||||
})
|
||||
&& config.hierarchyLevel > 1
|
||||
&& $(this.currentTable.rows).each(function () {
|
||||
myLevel = $(this).data('level');
|
||||
if (myLevel > 1) {
|
||||
parentLevel = $(this).prev().data('level');
|
||||
while (myLevel > parentLevel + 1) {
|
||||
$(this).find('td:first').children(':first').remove();
|
||||
$(this).data('level', --myLevel);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// If we have a dragObject, then we need to release it,
|
||||
// The row will already have been moved to the right place so we just reset stuff
|
||||
config.onDragClass
|
||||
&& $(droppedRow).removeClass(config.onDragClass)
|
||||
|| $(droppedRow).css(config.onDropStyle);
|
||||
|
||||
this.dragObject = null;
|
||||
// Call the onDrop method if there is one
|
||||
config.onDrop
|
||||
&& this.originalOrder !== this.currentOrder()
|
||||
&& $(droppedRow).hide().fadeIn('fast')
|
||||
&& config.onDrop(this.currentTable, droppedRow);
|
||||
|
||||
// Call the onDragStop method if there is one
|
||||
config.onDragStop
|
||||
&& config.onDragStop(this.currentTable, droppedRow);
|
||||
|
||||
this.currentTable = null; // let go of the table too
|
||||
},
|
||||
mouseup: function(e) {
|
||||
e && e.preventDefault();
|
||||
$.tableDnD.processMouseup();
|
||||
return false;
|
||||
},
|
||||
jsonize: function(pretify) {
|
||||
var table = this.currentTable;
|
||||
if (pretify)
|
||||
return JSON.stringify(
|
||||
this.tableData(table),
|
||||
null,
|
||||
table.tableDnDConfig.jsonPretifySeparator
|
||||
);
|
||||
return JSON.stringify(this.tableData(table));
|
||||
},
|
||||
serialize: function() {
|
||||
return $.param(this.tableData(this.currentTable));
|
||||
},
|
||||
serializeTable: function(table) {
|
||||
var result = "";
|
||||
var paramName = table.tableDnDConfig.serializeParamName || table.id;
|
||||
var rows = table.rows;
|
||||
for (var i=0; i<rows.length; i++) {
|
||||
if (result.length > 0) result += "&";
|
||||
var rowId = rows[i].id;
|
||||
if (rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) {
|
||||
rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0];
|
||||
result += paramName + '[]=' + rowId;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
serializeTables: function() {
|
||||
var result = [];
|
||||
$('table').each(function() {
|
||||
this.id && result.push($.param($.tableDnD.tableData(this)));
|
||||
});
|
||||
return result.join('&');
|
||||
},
|
||||
tableData: function (table) {
|
||||
var config = table.tableDnDConfig,
|
||||
previousIDs = [],
|
||||
currentLevel = 0,
|
||||
indentLevel = 0,
|
||||
rowID = null,
|
||||
data = {},
|
||||
getSerializeRegexp,
|
||||
paramName,
|
||||
currentID,
|
||||
rows;
|
||||
|
||||
if (!table)
|
||||
table = this.currentTable;
|
||||
if (!table || !table.rows || !table.rows.length)
|
||||
return {error: { code: 500, message: "Not a valid table."}};
|
||||
if (!table.id && !config.serializeParamName)
|
||||
return {error: { code: 500, message: "No serializable unique id provided."}};
|
||||
|
||||
rows = config.autoCleanRelations
|
||||
&& table.rows
|
||||
|| $.makeArray(table.rows);
|
||||
paramName = config.serializeParamName || table.id;
|
||||
currentID = paramName;
|
||||
|
||||
getSerializeRegexp = function (rowId) {
|
||||
if (rowId && config && config.serializeRegexp)
|
||||
return rowId.match(config.serializeRegexp)[0];
|
||||
return rowId;
|
||||
};
|
||||
|
||||
data[currentID] = [];
|
||||
!config.autoCleanRelations
|
||||
&& $(rows[0]).data('level')
|
||||
&& rows.unshift({id: 'undefined'});
|
||||
|
||||
|
||||
|
||||
for (var i=0; i < rows.length; i++) {
|
||||
if (config.hierarchyLevel) {
|
||||
indentLevel = $(rows[i]).data('level') || 0;
|
||||
if (indentLevel === 0) {
|
||||
currentID = paramName;
|
||||
previousIDs = [];
|
||||
}
|
||||
else if (indentLevel > currentLevel) {
|
||||
previousIDs.push([currentID, currentLevel]);
|
||||
currentID = getSerializeRegexp(rows[i-1].id);
|
||||
}
|
||||
else if (indentLevel < currentLevel) {
|
||||
for (var h = 0; h < previousIDs.length; h++) {
|
||||
if (previousIDs[h][1] === indentLevel)
|
||||
currentID = previousIDs[h][0];
|
||||
if (previousIDs[h][1] >= currentLevel)
|
||||
previousIDs[h][1] = 0;
|
||||
}
|
||||
}
|
||||
currentLevel = indentLevel;
|
||||
|
||||
if (!$.isArray(data[currentID]))
|
||||
data[currentID] = [];
|
||||
rowID = getSerializeRegexp(rows[i].id);
|
||||
rowID && data[currentID].push(rowID);
|
||||
}
|
||||
else {
|
||||
rowID = getSerializeRegexp(rows[i].id);
|
||||
rowID && data[currentID].push(rowID);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
jQuery.fn.extend(
|
||||
{
|
||||
tableDnD : $.tableDnD.build,
|
||||
tableDnDUpdate : $.tableDnD.updateTables,
|
||||
tableDnDSerialize : $.proxy($.tableDnD.serialize, $.tableDnD),
|
||||
tableDnDSerializeAll : $.tableDnD.serializeTables,
|
||||
tableDnDData : $.proxy($.tableDnD.tableData, $.tableDnD)
|
||||
}
|
||||
);
|
||||
|
||||
}(jQuery, window, window.document);
|
||||
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @author: Dennis Hernández
|
||||
* @webSite: http://djhvscf.github.io/Blog
|
||||
* @version: v2.0.0
|
||||
*/
|
||||
|
||||
const isInit = that => that.$el.data('resizableColumns') !== undefined
|
||||
|
||||
const initResizable = that => {
|
||||
if (
|
||||
that.options.resizable &&
|
||||
!that.options.cardView &&
|
||||
!isInit(that) &&
|
||||
that.$el.is(':visible')
|
||||
) {
|
||||
that.$el.resizableColumns({
|
||||
store: window.store
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const destroy = that => {
|
||||
if (isInit(that)) {
|
||||
that.$el.data('resizableColumns').destroy()
|
||||
}
|
||||
}
|
||||
|
||||
const reInitResizable = that => {
|
||||
destroy(that)
|
||||
initResizable(that)
|
||||
}
|
||||
|
||||
$.extend($.fn.bootstrapTable.defaults, {
|
||||
resizable: false
|
||||
})
|
||||
|
||||
$.BootstrapTable = class extends $.BootstrapTable {
|
||||
|
||||
initBody (...args) {
|
||||
super.initBody(...args)
|
||||
|
||||
this.$el.off('column-switch.bs.table page-change.bs.table')
|
||||
.on('column-switch.bs.table page-change.bs.table', () => {
|
||||
reInitResizable(this)
|
||||
})
|
||||
|
||||
reInitResizable(this)
|
||||
}
|
||||
|
||||
toggleView (...args) {
|
||||
super.toggleView(...args)
|
||||
|
||||
if (this.options.resizable && this.options.cardView) {
|
||||
// Destroy the plugin
|
||||
destroy(this)
|
||||
}
|
||||
}
|
||||
|
||||
resetView (...args) {
|
||||
super.resetView(...args)
|
||||
|
||||
if (this.options.resizable) {
|
||||
// because in fitHeader function, we use setTimeout(func, 100);
|
||||
setTimeout(() => {
|
||||
initResizable(this)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Bootstrap Table Chinese translation
|
||||
* Author: Zhixin Wen<wenzhixin2010@gmail.com>
|
||||
*/
|
||||
$.fn.bootstrapTable.locales['zh-CN'] = {
|
||||
formatShowSearch: function formatShowSearch() {
|
||||
return '隐藏/显示搜索';
|
||||
},
|
||||
formatPageGo: function formatPageGo() {
|
||||
return '跳转';
|
||||
},
|
||||
formatCopyRows: function formatCopyRows() {
|
||||
return '复制行';
|
||||
},
|
||||
formatPrint: function formatPrint() {
|
||||
return '打印';
|
||||
},
|
||||
formatLoadingMessage: function formatLoadingMessage() {
|
||||
return '正在努力地加载数据中,请稍候';
|
||||
},
|
||||
formatRecordsPerPage: function formatRecordsPerPage(pageNumber) {
|
||||
return "每页显示 ".concat(pageNumber, " 条记录");
|
||||
},
|
||||
formatShowingRows: function formatShowingRows(pageFrom, pageTo, totalRows, totalNotFiltered) {
|
||||
if (totalNotFiltered !== undefined && totalNotFiltered > 0 && totalNotFiltered > totalRows) {
|
||||
return "显示第 ".concat(pageFrom, " 到第 ").concat(pageTo, " 条记录,总共 ").concat(totalRows, " 条记录(从 ").concat(totalNotFiltered, " 总记录中过滤)");
|
||||
}
|
||||
return "显示第 ".concat(pageFrom, " 到第 ").concat(pageTo, " 条记录,总共 ").concat(totalRows, " 条记录");
|
||||
},
|
||||
formatSRPaginationPreText: function formatSRPaginationPreText() {
|
||||
return '上一页';
|
||||
},
|
||||
formatSRPaginationPageText: function formatSRPaginationPageText(page) {
|
||||
return "第".concat(page, "页");
|
||||
},
|
||||
formatSRPaginationNextText: function formatSRPaginationNextText() {
|
||||
return '下一页';
|
||||
},
|
||||
formatDetailPagination: function formatDetailPagination(totalRows) {
|
||||
return "总共 ".concat(totalRows, " 条记录");
|
||||
},
|
||||
formatClearSearch: function formatClearSearch() {
|
||||
return '清空过滤';
|
||||
},
|
||||
formatSearch: function formatSearch() {
|
||||
return '搜索';
|
||||
},
|
||||
formatNoMatches: function formatNoMatches() {
|
||||
return '没有找到匹配的记录';
|
||||
},
|
||||
formatPaginationSwitch: function formatPaginationSwitch() {
|
||||
return '隐藏/显示分页';
|
||||
},
|
||||
formatPaginationSwitchDown: function formatPaginationSwitchDown() {
|
||||
return '显示分页';
|
||||
},
|
||||
formatPaginationSwitchUp: function formatPaginationSwitchUp() {
|
||||
return '隐藏分页';
|
||||
},
|
||||
formatRefresh: function formatRefresh() {
|
||||
return '刷新';
|
||||
},
|
||||
formatToggle: function formatToggle() {
|
||||
return '切换';
|
||||
},
|
||||
formatToggleOn: function formatToggleOn() {
|
||||
return '显示卡片视图';
|
||||
},
|
||||
formatToggleOff: function formatToggleOff() {
|
||||
return '隐藏卡片视图';
|
||||
},
|
||||
formatColumns: function formatColumns() {
|
||||
return '列';
|
||||
},
|
||||
formatColumnsToggleAll: function formatColumnsToggleAll() {
|
||||
return '切换所有';
|
||||
},
|
||||
formatFullscreen: function formatFullscreen() {
|
||||
return '全屏';
|
||||
},
|
||||
formatAllRows: function formatAllRows() {
|
||||
return '所有';
|
||||
},
|
||||
formatAutoRefresh: function formatAutoRefresh() {
|
||||
return '自动刷新';
|
||||
},
|
||||
formatExport: function formatExport() {
|
||||
return '导出数据';
|
||||
},
|
||||
formatJumpTo: function formatJumpTo() {
|
||||
return '跳转';
|
||||
},
|
||||
formatAdvancedSearch: function formatAdvancedSearch() {
|
||||
return '高级搜索';
|
||||
},
|
||||
formatAdvancedCloseButton: function formatAdvancedCloseButton() {
|
||||
return '关闭';
|
||||
},
|
||||
formatFilterControlSwitch: function formatFilterControlSwitch() {
|
||||
return '隐藏/显示过滤控制';
|
||||
},
|
||||
formatFilterControlSwitchHide: function formatFilterControlSwitchHide() {
|
||||
return '隐藏过滤控制';
|
||||
},
|
||||
formatFilterControlSwitchShow: function formatFilterControlSwitchShow() {
|
||||
return '显示过滤控制';
|
||||
}
|
||||
};
|
||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);
|
||||
@ -0,0 +1 @@
|
||||
$.fn.bootstrapTable.locales["zh-CN"]={formatShowSearch:function formatShowSearch(){return"隐藏/显示搜索"},formatPageGo:function formatPageGo(){return"跳转"},formatCopyRows:function formatCopyRows(){return"复制行"},formatPrint:function formatPrint(){return"打印"},formatLoadingMessage:function formatLoadingMessage(){return"正在努力地加载数据中,请稍候"},formatRecordsPerPage:function formatRecordsPerPage(pageNumber){return"每页显示 ".concat(pageNumber," 条记录")},formatShowingRows:function formatShowingRows(pageFrom,pageTo,totalRows,totalNotFiltered){if(totalNotFiltered!==undefined&&totalNotFiltered>0&&totalNotFiltered>totalRows){return"显示第 ".concat(pageFrom," 到第 ").concat(pageTo," 条记录,总共 ").concat(totalRows," 条记录(从 ").concat(totalNotFiltered," 总记录中过滤)")}return"显示第 ".concat(pageFrom," 到第 ").concat(pageTo," 条记录,总共 ").concat(totalRows," 条记录")},formatSRPaginationPreText:function formatSRPaginationPreText(){return"上一页"},formatSRPaginationPageText:function formatSRPaginationPageText(page){return"第".concat(page,"页")},formatSRPaginationNextText:function formatSRPaginationNextText(){return"下一页"},formatDetailPagination:function formatDetailPagination(totalRows){return"总共 ".concat(totalRows," 条记录")},formatClearSearch:function formatClearSearch(){return"清空过滤"},formatSearch:function formatSearch(){return"搜索"},formatNoMatches:function formatNoMatches(){return"没有找到匹配的记录"},formatPaginationSwitch:function formatPaginationSwitch(){return"隐藏/显示分页"},formatPaginationSwitchDown:function formatPaginationSwitchDown(){return"显示分页"},formatPaginationSwitchUp:function formatPaginationSwitchUp(){return"隐藏分页"},formatRefresh:function formatRefresh(){return"刷新"},formatToggle:function formatToggle(){return"切换"},formatToggleOn:function formatToggleOn(){return"显示卡片视图"},formatToggleOff:function formatToggleOff(){return"隐藏卡片视图"},formatColumns:function formatColumns(){return"列"},formatColumnsToggleAll:function formatColumnsToggleAll(){return"切换所有"},formatFullscreen:function formatFullscreen(){return"全屏"},formatAllRows:function formatAllRows(){return"所有"},formatAutoRefresh:function formatAutoRefresh(){return"自动刷新"},formatExport:function formatExport(){return"导出数据"},formatJumpTo:function formatJumpTo(){return"跳转"},formatAdvancedSearch:function formatAdvancedSearch(){return"高级搜索"},formatAdvancedCloseButton:function formatAdvancedCloseButton(){return"关闭"},formatFilterControlSwitch:function formatFilterControlSwitch(){return"隐藏/显示过滤控制"},formatFilterControlSwitchHide:function formatFilterControlSwitchHide(){return"隐藏过滤控制"},formatFilterControlSwitchShow:function formatFilterControlSwitchShow(){return"显示过滤控制"}};$.extend($.fn.bootstrapTable.defaults,$.fn.bootstrapTable.locales["zh-CN"]);
|
||||
@ -0,0 +1,304 @@
|
||||
/*!
|
||||
* Cropper.js v1.5.12
|
||||
* https://fengyuanchen.github.io/cropperjs
|
||||
*
|
||||
* Copyright 2015-present Chen Fengyuan
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: 2021-06-12T08:00:11.623Z
|
||||
*/
|
||||
|
||||
.cropper-container {
|
||||
direction: ltr;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.cropper-container img {
|
||||
display: block;
|
||||
height: 100%;
|
||||
image-orientation: 0deg;
|
||||
max-height: none !important;
|
||||
max-width: none !important;
|
||||
min-height: 0 !important;
|
||||
min-width: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cropper-wrap-box,
|
||||
.cropper-canvas,
|
||||
.cropper-drag-box,
|
||||
.cropper-crop-box,
|
||||
.cropper-modal {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.cropper-wrap-box,
|
||||
.cropper-canvas {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cropper-drag-box {
|
||||
background-color: #fff;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cropper-modal {
|
||||
background-color: #000;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.cropper-view-box {
|
||||
display: block;
|
||||
height: 100%;
|
||||
outline: 1px solid #39f;
|
||||
outline-color: rgba(51, 153, 255, 0.75);
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cropper-dashed {
|
||||
border: 0 dashed #eee;
|
||||
display: block;
|
||||
opacity: 0.5;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.cropper-dashed.dashed-h {
|
||||
border-bottom-width: 1px;
|
||||
border-top-width: 1px;
|
||||
height: calc(100% / 3);
|
||||
left: 0;
|
||||
top: calc(100% / 3);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cropper-dashed.dashed-v {
|
||||
border-left-width: 1px;
|
||||
border-right-width: 1px;
|
||||
height: 100%;
|
||||
left: calc(100% / 3);
|
||||
top: 0;
|
||||
width: calc(100% / 3);
|
||||
}
|
||||
|
||||
.cropper-center {
|
||||
display: block;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
opacity: 0.75;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.cropper-center::before,
|
||||
.cropper-center::after {
|
||||
background-color: #eee;
|
||||
content: ' ';
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.cropper-center::before {
|
||||
height: 1px;
|
||||
left: -3px;
|
||||
top: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.cropper-center::after {
|
||||
height: 7px;
|
||||
left: 0;
|
||||
top: -3px;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.cropper-face,
|
||||
.cropper-line,
|
||||
.cropper-point {
|
||||
display: block;
|
||||
height: 100%;
|
||||
opacity: 0.1;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
background-color: #fff;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.cropper-line {
|
||||
background-color: #39f;
|
||||
}
|
||||
|
||||
.cropper-line.line-e {
|
||||
cursor: ew-resize;
|
||||
right: -3px;
|
||||
top: 0;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.cropper-line.line-n {
|
||||
cursor: ns-resize;
|
||||
height: 5px;
|
||||
left: 0;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
.cropper-line.line-w {
|
||||
cursor: ew-resize;
|
||||
left: -3px;
|
||||
top: 0;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.cropper-line.line-s {
|
||||
bottom: -3px;
|
||||
cursor: ns-resize;
|
||||
height: 5px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.cropper-point {
|
||||
background-color: #39f;
|
||||
height: 5px;
|
||||
opacity: 0.75;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.cropper-point.point-e {
|
||||
cursor: ew-resize;
|
||||
margin-top: -3px;
|
||||
right: -3px;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.cropper-point.point-n {
|
||||
cursor: ns-resize;
|
||||
left: 50%;
|
||||
margin-left: -3px;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
.cropper-point.point-w {
|
||||
cursor: ew-resize;
|
||||
left: -3px;
|
||||
margin-top: -3px;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.cropper-point.point-s {
|
||||
bottom: -3px;
|
||||
cursor: s-resize;
|
||||
left: 50%;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.cropper-point.point-ne {
|
||||
cursor: nesw-resize;
|
||||
right: -3px;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
.cropper-point.point-nw {
|
||||
cursor: nwse-resize;
|
||||
left: -3px;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
.cropper-point.point-sw {
|
||||
bottom: -3px;
|
||||
cursor: nesw-resize;
|
||||
left: -3px;
|
||||
}
|
||||
|
||||
.cropper-point.point-se {
|
||||
bottom: -3px;
|
||||
cursor: nwse-resize;
|
||||
height: 20px;
|
||||
opacity: 1;
|
||||
right: -3px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.cropper-point.point-se {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.cropper-point.point-se {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.cropper-point.point-se {
|
||||
height: 5px;
|
||||
opacity: 0.75;
|
||||
width: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.cropper-point.point-se::before {
|
||||
background-color: #39f;
|
||||
bottom: -50%;
|
||||
content: ' ';
|
||||
display: block;
|
||||
height: 200%;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
right: -50%;
|
||||
width: 200%;
|
||||
}
|
||||
|
||||
.cropper-invisible {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cropper-bg {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
|
||||
}
|
||||
|
||||
.cropper-hide {
|
||||
display: block;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.cropper-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cropper-move {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.cropper-crop {
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.cropper-disabled .cropper-drag-box,
|
||||
.cropper-disabled .cropper-face,
|
||||
.cropper-disabled .cropper-line,
|
||||
.cropper-disabled .cropper-point {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Cropper.js v1.5.12
|
||||
* https://fengyuanchen.github.io/cropperjs
|
||||
*
|
||||
* Copyright 2015-present Chen Fengyuan
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: 2021-06-12T08:00:11.623Z
|
||||
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{image-orientation:0deg;display:block;height:100%;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}
|
||||
@ -0,0 +1,418 @@
|
||||
/*!
|
||||
* Datetimepicker for Bootstrap
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Improvements by Andrew Rowls
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
.datetimepicker {
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.datetimepicker-inline {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.datetimepicker.datetimepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.datetimepicker.datetimepicker-rtl table tr td span {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown, .datetimepicker-dropdown-left {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
[class*=" datetimepicker-dropdown"]:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #cccccc;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
[class*=" datetimepicker-dropdown"]:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #ffffff;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
[class*=" datetimepicker-dropdown-top"]:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-top: 7px solid #cccccc;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
[class*=" datetimepicker-dropdown-top"]:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid #ffffff;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-bottom-left:before {
|
||||
top: -7px;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-bottom-left:after {
|
||||
top: -6px;
|
||||
right: 7px;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-bottom-right:before {
|
||||
top: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-bottom-right:after {
|
||||
top: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-top-left:before {
|
||||
bottom: -7px;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-top-left:after {
|
||||
bottom: -6px;
|
||||
right: 7px;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-top-right:before {
|
||||
bottom: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
.datetimepicker-dropdown-top-right:after {
|
||||
bottom: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
.datetimepicker > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.datetimepicker.minutes div.datetimepicker-minutes {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.datetimepicker.hours div.datetimepicker-hours {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.datetimepicker.days div.datetimepicker-days {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.datetimepicker.months div.datetimepicker-months {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.datetimepicker.years div.datetimepicker-years {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.datetimepicker table {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.datetimepicker td,
|
||||
.datetimepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.table-striped .datetimepicker table tr td,
|
||||
.table-striped .datetimepicker table tr th {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.minute:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.hour:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.day:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.old,
|
||||
.datetimepicker table tr td.new {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.disabled,
|
||||
.datetimepicker table tr td.disabled:hover {
|
||||
background: none;
|
||||
color: #999999;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.today,
|
||||
.datetimepicker table tr td.today:hover,
|
||||
.datetimepicker table tr td.today.disabled,
|
||||
.datetimepicker table tr td.today.disabled:hover {
|
||||
background-color: #fde19a;
|
||||
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
|
||||
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||
border-color: #fdf59a #fdf59a #fbed50;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.today:hover,
|
||||
.datetimepicker table tr td.today:hover:hover,
|
||||
.datetimepicker table tr td.today.disabled:hover,
|
||||
.datetimepicker table tr td.today.disabled:hover:hover,
|
||||
.datetimepicker table tr td.today:active,
|
||||
.datetimepicker table tr td.today:hover:active,
|
||||
.datetimepicker table tr td.today.disabled:active,
|
||||
.datetimepicker table tr td.today.disabled:hover:active,
|
||||
.datetimepicker table tr td.today.active,
|
||||
.datetimepicker table tr td.today:hover.active,
|
||||
.datetimepicker table tr td.today.disabled.active,
|
||||
.datetimepicker table tr td.today.disabled:hover.active,
|
||||
.datetimepicker table tr td.today.disabled,
|
||||
.datetimepicker table tr td.today:hover.disabled,
|
||||
.datetimepicker table tr td.today.disabled.disabled,
|
||||
.datetimepicker table tr td.today.disabled:hover.disabled,
|
||||
.datetimepicker table tr td.today[disabled],
|
||||
.datetimepicker table tr td.today:hover[disabled],
|
||||
.datetimepicker table tr td.today.disabled[disabled],
|
||||
.datetimepicker table tr td.today.disabled:hover[disabled] {
|
||||
background-color: #fdf59a;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.today:active,
|
||||
.datetimepicker table tr td.today:hover:active,
|
||||
.datetimepicker table tr td.today.disabled:active,
|
||||
.datetimepicker table tr td.today.disabled:hover:active,
|
||||
.datetimepicker table tr td.today.active,
|
||||
.datetimepicker table tr td.today:hover.active,
|
||||
.datetimepicker table tr td.today.disabled.active,
|
||||
.datetimepicker table tr td.today.disabled:hover.active {
|
||||
background-color: #fbf069;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.active,
|
||||
.datetimepicker table tr td.active:hover,
|
||||
.datetimepicker table tr td.active.disabled,
|
||||
.datetimepicker table tr td.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #ffffff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.active:hover,
|
||||
.datetimepicker table tr td.active:hover:hover,
|
||||
.datetimepicker table tr td.active.disabled:hover,
|
||||
.datetimepicker table tr td.active.disabled:hover:hover,
|
||||
.datetimepicker table tr td.active:active,
|
||||
.datetimepicker table tr td.active:hover:active,
|
||||
.datetimepicker table tr td.active.disabled:active,
|
||||
.datetimepicker table tr td.active.disabled:hover:active,
|
||||
.datetimepicker table tr td.active.active,
|
||||
.datetimepicker table tr td.active:hover.active,
|
||||
.datetimepicker table tr td.active.disabled.active,
|
||||
.datetimepicker table tr td.active.disabled:hover.active,
|
||||
.datetimepicker table tr td.active.disabled,
|
||||
.datetimepicker table tr td.active:hover.disabled,
|
||||
.datetimepicker table tr td.active.disabled.disabled,
|
||||
.datetimepicker table tr td.active.disabled:hover.disabled,
|
||||
.datetimepicker table tr td.active[disabled],
|
||||
.datetimepicker table tr td.active:hover[disabled],
|
||||
.datetimepicker table tr td.active.disabled[disabled],
|
||||
.datetimepicker table tr td.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td.active:active,
|
||||
.datetimepicker table tr td.active:hover:active,
|
||||
.datetimepicker table tr td.active.disabled:active,
|
||||
.datetimepicker table tr td.active.disabled:hover:active,
|
||||
.datetimepicker table tr td.active.active,
|
||||
.datetimepicker table tr td.active:hover.active,
|
||||
.datetimepicker table tr td.active.disabled.active,
|
||||
.datetimepicker table tr td.active.disabled:hover.active {
|
||||
background-color: #003399;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td span {
|
||||
display: block;
|
||||
width: 23%;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 1%;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.datetimepicker .datetimepicker-hours span {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.datetimepicker .datetimepicker-hours table tr td span.hour_am,
|
||||
.datetimepicker .datetimepicker-hours table tr td span.hour_pm {
|
||||
width: 14.6%;
|
||||
}
|
||||
|
||||
.datetimepicker .datetimepicker-hours fieldset legend,
|
||||
.datetimepicker .datetimepicker-minutes fieldset legend {
|
||||
margin-bottom: inherit;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.datetimepicker .datetimepicker-minutes span {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td span:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td span.disabled,
|
||||
.datetimepicker table tr td span.disabled:hover {
|
||||
background: none;
|
||||
color: #999999;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td span.active,
|
||||
.datetimepicker table tr td span.active:hover,
|
||||
.datetimepicker table tr td span.active.disabled,
|
||||
.datetimepicker table tr td span.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #ffffff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.datetimepicker table tr td span.active:hover,
|
||||
.datetimepicker table tr td span.active:hover:hover,
|
||||
.datetimepicker table tr td span.active.disabled:hover,
|
||||
.datetimepicker table tr td span.active.disabled:hover:hover,
|
||||
.datetimepicker table tr td span.active:active,
|
||||
.datetimepicker table tr td span.active:hover:active,
|
||||
.datetimepicker table tr td span.active.disabled:active,
|
||||
.datetimepicker table tr td span.active.disabled:hover:active,
|
||||
.datetimepicker table tr td span.active.active,
|
||||
.datetimepicker table tr td span.active:hover.active,
|
||||
.datetimepicker table tr td span.active.disabled.active,
|
||||
.datetimepicker table tr td span.active.disabled:hover.active,
|
||||
.datetimepicker table tr td span.active.disabled,
|
||||
.datetimepicker table tr td span.active:hover.disabled,
|
||||
.datetimepicker table tr td span.active.disabled.disabled,
|
||||
.datetimepicker table tr td span.active.disabled:hover.disabled,
|
||||
.datetimepicker table tr td span.active[disabled],
|
||||
.datetimepicker table tr td span.active:hover[disabled],
|
||||
.datetimepicker table tr td span.active.disabled[disabled],
|
||||
.datetimepicker table tr td span.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td span.active:active,
|
||||
.datetimepicker table tr td span.active:hover:active,
|
||||
.datetimepicker table tr td span.active.disabled:active,
|
||||
.datetimepicker table tr td span.active.disabled:hover:active,
|
||||
.datetimepicker table tr td span.active.active,
|
||||
.datetimepicker table tr td span.active:hover.active,
|
||||
.datetimepicker table tr td span.active.disabled.active,
|
||||
.datetimepicker table tr td span.active.disabled:hover.active {
|
||||
background-color: #003399;
|
||||
}
|
||||
|
||||
.datetimepicker table tr td span.old {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.datetimepicker th.switch {
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
.datetimepicker th span.glyphicon {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.datetimepicker thead tr:first-child th,
|
||||
.datetimepicker tfoot th {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.datetimepicker thead tr:first-child th:hover,
|
||||
.datetimepicker tfoot th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
.input-append.date .add-on i,
|
||||
.input-prepend.date .add-on i,
|
||||
.input-group.date .input-group-addon span {
|
||||
cursor: pointer;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Bootstrap Duallistbox - v3.0.9
|
||||
* A responsive dual listbox widget optimized for Twitter Bootstrap. It works on all modern browsers and on touch devices.
|
||||
* https://www.virtuosoft.eu/code/bootstrap-duallistbox/
|
||||
*
|
||||
* Made by István Ujj-Mészáros
|
||||
* Under Apache License v2.0 License
|
||||
*/
|
||||
.bootstrap-duallistbox-container .buttons {
|
||||
width: 100%;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .info {
|
||||
display: inline-block;
|
||||
margin-bottom: 5px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .clear1,
|
||||
.bootstrap-duallistbox-container .clear2 {
|
||||
display: none;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .box1.filtered .clear1,
|
||||
.bootstrap-duallistbox-container .box2.filtered .clear2 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .move,
|
||||
.bootstrap-duallistbox-container .remove {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .btn-group .btn {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.bootstrap-duallistbox-container select {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .moveall,
|
||||
.bootstrap-duallistbox-container .removeall {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container.bs2compatible .btn-group > .btn + .btn {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container select {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .filter {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 31px;
|
||||
margin: 0 0 5px 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container .filter.placeholder {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container.moveonselect .move,
|
||||
.bootstrap-duallistbox-container.moveonselect .remove {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.bootstrap-duallistbox-container.moveonselect .moveall,
|
||||
.bootstrap-duallistbox-container.moveonselect .removeall {
|
||||
width: 100%;
|
||||
}
|
||||
@ -0,0 +1,844 @@
|
||||
/*
|
||||
* Bootstrap Duallistbox - v3.0.9
|
||||
* A responsive dual listbox widget optimized for Twitter Bootstrap. It works on all modern browsers and on touch devices.
|
||||
* https://www.virtuosoft.eu/code/bootstrap-duallistbox/
|
||||
*
|
||||
* Made by István Ujj-Mészáros
|
||||
* Under Apache License v2.0 License
|
||||
*/
|
||||
;(function ($, window, document, undefined) {
|
||||
// Create the defaults once
|
||||
var pluginName = 'bootstrapDualListbox',
|
||||
defaults = {
|
||||
bootstrap2Compatible: false,
|
||||
filterTextClear: 'show all',
|
||||
filterPlaceHolder: 'Filter',
|
||||
moveSelectedLabel: 'Move selected',
|
||||
moveAllLabel: 'Move all',
|
||||
removeSelectedLabel: 'Remove selected',
|
||||
removeAllLabel: 'Remove all',
|
||||
moveOnSelect: true, // true/false (forced true on androids, see the comment later)
|
||||
moveOnDoubleClick: true, // true/false (forced false on androids, cause moveOnSelect is forced to true)
|
||||
preserveSelectionOnMove: false, // 'all' / 'moved' / false
|
||||
selectedListLabel: false, // 'string', false
|
||||
nonSelectedListLabel: false, // 'string', false
|
||||
helperSelectNamePostfix: '_helper', // 'string_of_postfix' / false
|
||||
selectorMinimalHeight: 100,
|
||||
showFilterInputs: true, // whether to show filter inputs
|
||||
nonSelectedFilter: '', // string, filter the non selected options
|
||||
selectedFilter: '', // string, filter the selected options
|
||||
infoText: 'Showing all {0}', // text when all options are visible / false for no info text
|
||||
infoTextFiltered: '<span class="label label-warning">Filtered</span> {0} from {1}', // when not all of the options are visible due to the filter
|
||||
infoTextEmpty: 'Empty list', // when there are no options present in the list
|
||||
filterOnValues: false, // filter by selector's values, boolean
|
||||
sortByInputOrder: false,
|
||||
eventMoveOverride: false, // boolean, allows user to unbind default event behaviour and run their own instead
|
||||
eventMoveAllOverride: false, // boolean, allows user to unbind default event behaviour and run their own instead
|
||||
eventRemoveOverride: false, // boolean, allows user to unbind default event behaviour and run their own instead
|
||||
eventRemoveAllOverride: false // boolean, allows user to unbind default event behaviour and run their own instead
|
||||
},
|
||||
// Selections are invisible on android if the containing select is styled with CSS
|
||||
// http://code.google.com/p/android/issues/detail?id=16922
|
||||
isBuggyAndroid = /android/i.test(navigator.userAgent.toLowerCase());
|
||||
|
||||
// The actual plugin constructor
|
||||
function BootstrapDualListbox(element, options) {
|
||||
this.element = $(element);
|
||||
// jQuery has an extend method which merges the contents of two or
|
||||
// more objects, storing the result in the first object. The first object
|
||||
// is generally empty as we don't want to alter the default options for
|
||||
// future instances of the plugin
|
||||
this.settings = $.extend({}, defaults, options);
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.init();
|
||||
}
|
||||
|
||||
function triggerChangeEvent(dualListbox) {
|
||||
dualListbox.element.trigger('change');
|
||||
}
|
||||
|
||||
function updateSelectionStates(dualListbox) {
|
||||
dualListbox.element.find('option').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
if (typeof($item.data('original-index')) === 'undefined') {
|
||||
$item.data('original-index', dualListbox.elementCount++);
|
||||
}
|
||||
if (typeof($item.data('_selected')) === 'undefined') {
|
||||
$item.data('_selected', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function changeSelectionState(dualListbox, original_index, selected) {
|
||||
dualListbox.element.find('option').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
if ($item.data('original-index') === original_index) {
|
||||
$item.prop('selected', selected);
|
||||
if(selected){
|
||||
$item.attr('data-sortindex', dualListbox.sortIndex);
|
||||
dualListbox.sortIndex++;
|
||||
} else {
|
||||
$item.removeAttr('data-sortindex');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function formatString(s, args) {
|
||||
return s.replace(/\{(\d+)\}/g, function(match, number) {
|
||||
return typeof args[number] !== 'undefined' ? args[number] : match;
|
||||
});
|
||||
}
|
||||
|
||||
function refreshInfo(dualListbox) {
|
||||
if (!dualListbox.settings.infoText) {
|
||||
return;
|
||||
}
|
||||
|
||||
var visible1 = dualListbox.elements.select1.find('option').length,
|
||||
visible2 = dualListbox.elements.select2.find('option').length,
|
||||
all1 = dualListbox.element.find('option').length - dualListbox.selectedElements,
|
||||
all2 = dualListbox.selectedElements,
|
||||
content = '';
|
||||
|
||||
if (all1 === 0) {
|
||||
content = dualListbox.settings.infoTextEmpty;
|
||||
} else if (visible1 === all1) {
|
||||
content = formatString(dualListbox.settings.infoText, [visible1, all1]);
|
||||
} else {
|
||||
content = formatString(dualListbox.settings.infoTextFiltered, [visible1, all1]);
|
||||
}
|
||||
|
||||
dualListbox.elements.info1.html(content);
|
||||
dualListbox.elements.box1.toggleClass('filtered', !(visible1 === all1 || all1 === 0));
|
||||
|
||||
if (all2 === 0) {
|
||||
content = dualListbox.settings.infoTextEmpty;
|
||||
} else if (visible2 === all2) {
|
||||
content = formatString(dualListbox.settings.infoText, [visible2, all2]);
|
||||
} else {
|
||||
content = formatString(dualListbox.settings.infoTextFiltered, [visible2, all2]);
|
||||
}
|
||||
|
||||
dualListbox.elements.info2.html(content);
|
||||
dualListbox.elements.box2.toggleClass('filtered', !(visible2 === all2 || all2 === 0));
|
||||
}
|
||||
|
||||
function refreshSelects(dualListbox) {
|
||||
dualListbox.selectedElements = 0;
|
||||
|
||||
dualListbox.elements.select1.empty();
|
||||
dualListbox.elements.select2.empty();
|
||||
|
||||
dualListbox.element.find('option').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
if ($item.prop('selected')) {
|
||||
dualListbox.selectedElements++;
|
||||
dualListbox.elements.select2.append($item.clone(true).prop('selected', $item.data('_selected')));
|
||||
} else {
|
||||
dualListbox.elements.select1.append($item.clone(true).prop('selected', $item.data('_selected')));
|
||||
}
|
||||
});
|
||||
|
||||
if (dualListbox.settings.showFilterInputs) {
|
||||
filter(dualListbox, 1);
|
||||
filter(dualListbox, 2);
|
||||
}
|
||||
refreshInfo(dualListbox);
|
||||
}
|
||||
|
||||
function filter(dualListbox, selectIndex) {
|
||||
if (!dualListbox.settings.showFilterInputs) {
|
||||
return;
|
||||
}
|
||||
|
||||
saveSelections(dualListbox, selectIndex);
|
||||
|
||||
dualListbox.elements['select'+selectIndex].empty().scrollTop(0);
|
||||
var regex = new RegExp($.trim(dualListbox.elements['filterInput'+selectIndex].val()), 'gi'),
|
||||
allOptions = dualListbox.element.find('option'),
|
||||
options = dualListbox.element;
|
||||
|
||||
if (selectIndex === 1) {
|
||||
options = allOptions.not(':selected');
|
||||
} else {
|
||||
options = options.find('option:selected');
|
||||
}
|
||||
|
||||
options.each(function(index, item) {
|
||||
var $item = $(item),
|
||||
isFiltered = true;
|
||||
if (item.text.match(regex) || (dualListbox.settings.filterOnValues && $item.attr('value').match(regex) ) ) {
|
||||
isFiltered = false;
|
||||
dualListbox.elements['select'+selectIndex].append($item.clone(true).prop('selected', $item.data('_selected')));
|
||||
}
|
||||
allOptions.eq($item.data('original-index')).data('filtered'+selectIndex, isFiltered);
|
||||
});
|
||||
|
||||
refreshInfo(dualListbox);
|
||||
}
|
||||
|
||||
function saveSelections(dualListbox, selectIndex) {
|
||||
var options = dualListbox.element.find('option');
|
||||
dualListbox.elements['select'+selectIndex].find('option').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
options.eq($item.data('original-index')).data('_selected', $item.prop('selected'));
|
||||
});
|
||||
}
|
||||
|
||||
function sortOptionsByInputOrder(select){
|
||||
var selectopt = select.children('option');
|
||||
|
||||
selectopt.sort(function(a,b){
|
||||
var an = parseInt(a.getAttribute('data-sortindex')),
|
||||
bn = parseInt(b.getAttribute('data-sortindex'));
|
||||
|
||||
if(an > bn) {
|
||||
return 1;
|
||||
}
|
||||
if(an < bn) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
selectopt.detach().appendTo(select);
|
||||
}
|
||||
|
||||
function sortOptions(select, dualListbox) {
|
||||
select.find('option').sort(function(a, b) {
|
||||
return ($(a).data('original-index') > $(b).data('original-index')) ? 1 : -1;
|
||||
}).appendTo(select);
|
||||
|
||||
// workaround for chromium bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1072475
|
||||
refreshSelects(dualListbox);
|
||||
}
|
||||
|
||||
function clearSelections(dualListbox) {
|
||||
dualListbox.elements.select1.find('option').each(function() {
|
||||
dualListbox.element.find('option').data('_selected', false);
|
||||
});
|
||||
}
|
||||
|
||||
function move(dualListbox) {
|
||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 1);
|
||||
saveSelections(dualListbox, 2);
|
||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 1);
|
||||
}
|
||||
|
||||
dualListbox.elements.select1.find('option:selected').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
if (!$item.data('filtered1')) {
|
||||
changeSelectionState(dualListbox, $item.data('original-index'), true);
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelects(dualListbox);
|
||||
triggerChangeEvent(dualListbox);
|
||||
if(dualListbox.settings.sortByInputOrder){
|
||||
sortOptionsByInputOrder(dualListbox.elements.select2);
|
||||
} else {
|
||||
sortOptions(dualListbox.elements.select2, dualListbox);
|
||||
}
|
||||
}
|
||||
|
||||
function remove(dualListbox) {
|
||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 1);
|
||||
saveSelections(dualListbox, 2);
|
||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 2);
|
||||
}
|
||||
|
||||
dualListbox.elements.select2.find('option:selected').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
if (!$item.data('filtered2')) {
|
||||
changeSelectionState(dualListbox, $item.data('original-index'), false);
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelects(dualListbox);
|
||||
triggerChangeEvent(dualListbox);
|
||||
sortOptions(dualListbox.elements.select1, dualListbox);
|
||||
if(dualListbox.settings.sortByInputOrder){
|
||||
sortOptionsByInputOrder(dualListbox.elements.select2);
|
||||
}
|
||||
}
|
||||
|
||||
function moveAll(dualListbox) {
|
||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 1);
|
||||
saveSelections(dualListbox, 2);
|
||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 1);
|
||||
}
|
||||
|
||||
dualListbox.element.find('option').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
if (!$item.data('filtered1')) {
|
||||
$item.prop('selected', true);
|
||||
$item.attr('data-sortindex', dualListbox.sortIndex);
|
||||
dualListbox.sortIndex++;
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelects(dualListbox);
|
||||
triggerChangeEvent(dualListbox);
|
||||
}
|
||||
|
||||
function removeAll(dualListbox) {
|
||||
if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 1);
|
||||
saveSelections(dualListbox, 2);
|
||||
} else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
|
||||
saveSelections(dualListbox, 2);
|
||||
}
|
||||
|
||||
dualListbox.element.find('option').each(function(index, item) {
|
||||
var $item = $(item);
|
||||
if (!$item.data('filtered2')) {
|
||||
$item.prop('selected', false);
|
||||
$item.removeAttr('data-sortindex');
|
||||
}
|
||||
});
|
||||
|
||||
refreshSelects(dualListbox);
|
||||
triggerChangeEvent(dualListbox);
|
||||
}
|
||||
|
||||
function bindEvents(dualListbox) {
|
||||
dualListbox.elements.form.submit(function(e) {
|
||||
if (dualListbox.elements.filterInput1.is(':focus')) {
|
||||
e.preventDefault();
|
||||
dualListbox.elements.filterInput1.focusout();
|
||||
} else if (dualListbox.elements.filterInput2.is(':focus')) {
|
||||
e.preventDefault();
|
||||
dualListbox.elements.filterInput2.focusout();
|
||||
}
|
||||
});
|
||||
|
||||
dualListbox.element.on('bootstrapDualListbox.refresh', function(e, mustClearSelections){
|
||||
dualListbox.refresh(mustClearSelections);
|
||||
});
|
||||
|
||||
dualListbox.elements.filterClear1.on('click', function() {
|
||||
dualListbox.setNonSelectedFilter('', true);
|
||||
});
|
||||
|
||||
dualListbox.elements.filterClear2.on('click', function() {
|
||||
dualListbox.setSelectedFilter('', true);
|
||||
});
|
||||
|
||||
if (dualListbox.settings.eventMoveOverride === false) {
|
||||
dualListbox.elements.moveButton.on('click', function() {
|
||||
move(dualListbox);
|
||||
});
|
||||
}
|
||||
|
||||
if (dualListbox.settings.eventMoveAllOverride === false) {
|
||||
dualListbox.elements.moveAllButton.on('click', function() {
|
||||
moveAll(dualListbox);
|
||||
});
|
||||
}
|
||||
|
||||
if (dualListbox.settings.eventRemoveOverride === false) {
|
||||
dualListbox.elements.removeButton.on('click', function() {
|
||||
remove(dualListbox);
|
||||
});
|
||||
}
|
||||
|
||||
if (dualListbox.settings.eventRemoveAllOverride === false) {
|
||||
dualListbox.elements.removeAllButton.on('click', function() {
|
||||
removeAll(dualListbox);
|
||||
});
|
||||
}
|
||||
|
||||
dualListbox.elements.filterInput1.on('change keyup', function() {
|
||||
filter(dualListbox, 1);
|
||||
});
|
||||
|
||||
dualListbox.elements.filterInput2.on('change keyup', function() {
|
||||
filter(dualListbox, 2);
|
||||
});
|
||||
}
|
||||
|
||||
BootstrapDualListbox.prototype = {
|
||||
init: function () {
|
||||
// Add the custom HTML template
|
||||
this.container = $('' +
|
||||
'<div class="bootstrap-duallistbox-container">' +
|
||||
' <div class="box1">' +
|
||||
' <label></label>' +
|
||||
' <span class="info-container">' +
|
||||
' <span class="info"></span>' +
|
||||
' <button type="button" class="btn clear1 pull-right"></button>' +
|
||||
' </span>' +
|
||||
' <input class="filter" type="text">' +
|
||||
' <div class="btn-group buttons">' +
|
||||
' <button type="button" class="btn moveall">' +
|
||||
' <i></i>' +
|
||||
' <i></i>' +
|
||||
' </button>' +
|
||||
' <button type="button" class="btn move">' +
|
||||
' <i></i>' +
|
||||
' </button>' +
|
||||
' </div>' +
|
||||
' <select multiple="multiple"></select>' +
|
||||
' </div>' +
|
||||
' <div class="box2">' +
|
||||
' <label></label>' +
|
||||
' <span class="info-container">' +
|
||||
' <span class="info"></span>' +
|
||||
' <button type="button" class="btn clear2 pull-right"></button>' +
|
||||
' </span>' +
|
||||
' <input class="filter" type="text">' +
|
||||
' <div class="btn-group buttons">' +
|
||||
' <button type="button" class="btn remove">' +
|
||||
' <i></i>' +
|
||||
' </button>' +
|
||||
' <button type="button" class="btn removeall">' +
|
||||
' <i></i>' +
|
||||
' <i></i>' +
|
||||
' </button>' +
|
||||
' </div>' +
|
||||
' <select multiple="multiple"></select>' +
|
||||
' </div>' +
|
||||
'</div>')
|
||||
.insertBefore(this.element);
|
||||
|
||||
// Cache the inner elements
|
||||
this.elements = {
|
||||
originalSelect: this.element,
|
||||
box1: $('.box1', this.container),
|
||||
box2: $('.box2', this.container),
|
||||
filterInput1: $('.box1 .filter', this.container),
|
||||
filterInput2: $('.box2 .filter', this.container),
|
||||
filterClear1: $('.box1 .clear1', this.container),
|
||||
filterClear2: $('.box2 .clear2', this.container),
|
||||
label1: $('.box1 > label', this.container),
|
||||
label2: $('.box2 > label', this.container),
|
||||
info1: $('.box1 .info', this.container),
|
||||
info2: $('.box2 .info', this.container),
|
||||
select1: $('.box1 select', this.container),
|
||||
select2: $('.box2 select', this.container),
|
||||
moveButton: $('.box1 .move', this.container),
|
||||
removeButton: $('.box2 .remove', this.container),
|
||||
moveAllButton: $('.box1 .moveall', this.container),
|
||||
removeAllButton: $('.box2 .removeall', this.container),
|
||||
form: $($('.box1 .filter', this.container)[0].form)
|
||||
};
|
||||
|
||||
// Set select IDs
|
||||
this.originalSelectName = this.element.attr('name') || '';
|
||||
var select1Id = 'bootstrap-duallistbox-nonselected-list_' + this.originalSelectName,
|
||||
select2Id = 'bootstrap-duallistbox-selected-list_' + this.originalSelectName;
|
||||
this.elements.select1.attr('id', select1Id);
|
||||
this.elements.select2.attr('id', select2Id);
|
||||
this.elements.label1.attr('for', select1Id);
|
||||
this.elements.label2.attr('for', select2Id);
|
||||
|
||||
// Apply all settings
|
||||
this.selectedElements = 0;
|
||||
this.sortIndex = 0;
|
||||
this.elementCount = 0;
|
||||
this.setBootstrap2Compatible(this.settings.bootstrap2Compatible);
|
||||
this.setFilterTextClear(this.settings.filterTextClear);
|
||||
this.setFilterPlaceHolder(this.settings.filterPlaceHolder);
|
||||
this.setMoveSelectedLabel(this.settings.moveSelectedLabel);
|
||||
this.setMoveAllLabel(this.settings.moveAllLabel);
|
||||
this.setRemoveSelectedLabel(this.settings.removeSelectedLabel);
|
||||
this.setRemoveAllLabel(this.settings.removeAllLabel);
|
||||
this.setMoveOnSelect(this.settings.moveOnSelect);
|
||||
this.setMoveOnDoubleClick(this.settings.moveOnDoubleClick);
|
||||
this.setPreserveSelectionOnMove(this.settings.preserveSelectionOnMove);
|
||||
this.setSelectedListLabel(this.settings.selectedListLabel);
|
||||
this.setNonSelectedListLabel(this.settings.nonSelectedListLabel);
|
||||
this.setHelperSelectNamePostfix(this.settings.helperSelectNamePostfix);
|
||||
this.setSelectOrMinimalHeight(this.settings.selectorMinimalHeight);
|
||||
|
||||
updateSelectionStates(this);
|
||||
|
||||
this.setShowFilterInputs(this.settings.showFilterInputs);
|
||||
this.setNonSelectedFilter(this.settings.nonSelectedFilter);
|
||||
this.setSelectedFilter(this.settings.selectedFilter);
|
||||
this.setInfoText(this.settings.infoText);
|
||||
this.setInfoTextFiltered(this.settings.infoTextFiltered);
|
||||
this.setInfoTextEmpty(this.settings.infoTextEmpty);
|
||||
this.setFilterOnValues(this.settings.filterOnValues);
|
||||
this.setSortByInputOrder(this.settings.sortByInputOrder);
|
||||
this.setEventMoveOverride(this.settings.eventMoveOverride);
|
||||
this.setEventMoveAllOverride(this.settings.eventMoveAllOverride);
|
||||
this.setEventRemoveOverride(this.settings.eventRemoveOverride);
|
||||
this.setEventRemoveAllOverride(this.settings.eventRemoveAllOverride);
|
||||
|
||||
// Hide the original select
|
||||
this.element.hide();
|
||||
|
||||
bindEvents(this);
|
||||
refreshSelects(this);
|
||||
|
||||
return this.element;
|
||||
},
|
||||
setBootstrap2Compatible: function(value, refresh) {
|
||||
this.settings.bootstrap2Compatible = value;
|
||||
if (value) {
|
||||
this.container.removeClass('row').addClass('row-fluid bs2compatible');
|
||||
this.container.find('.box1, .box2').removeClass('col-md-6').addClass('span6');
|
||||
this.container.find('.clear1, .clear2').removeClass('btn-default btn-xs').addClass('btn-mini');
|
||||
this.container.find('input, select').removeClass('form-control');
|
||||
this.container.find('.btn').removeClass('btn-default');
|
||||
this.container.find('.moveall > i, .move > i').removeClass('glyphicon glyphicon-arrow-right').addClass('icon-arrow-right');
|
||||
this.container.find('.removeall > i, .remove > i').removeClass('glyphicon glyphicon-arrow-left').addClass('icon-arrow-left');
|
||||
} else {
|
||||
this.container.removeClass('row-fluid bs2compatible').addClass('row');
|
||||
this.container.find('.box1, .box2').removeClass('span6').addClass('col-md-6');
|
||||
this.container.find('.clear1, .clear2').removeClass('btn-mini').addClass('btn-default btn-xs');
|
||||
this.container.find('input, select').addClass('form-control');
|
||||
this.container.find('.btn').addClass('btn-default');
|
||||
this.container.find('.moveall > i, .move > i').removeClass('icon-arrow-right').addClass('glyphicon glyphicon-arrow-right');
|
||||
this.container.find('.removeall > i, .remove > i').removeClass('icon-arrow-left').addClass('glyphicon glyphicon-arrow-left');
|
||||
}
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setFilterTextClear: function(value, refresh) {
|
||||
this.settings.filterTextClear = value;
|
||||
this.elements.filterClear1.html(value);
|
||||
this.elements.filterClear2.html(value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setFilterPlaceHolder: function(value, refresh) {
|
||||
this.settings.filterPlaceHolder = value;
|
||||
this.elements.filterInput1.attr('placeholder', value);
|
||||
this.elements.filterInput2.attr('placeholder', value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setMoveSelectedLabel: function(value, refresh) {
|
||||
this.settings.moveSelectedLabel = value;
|
||||
this.elements.moveButton.attr('title', value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setMoveAllLabel: function(value, refresh) {
|
||||
this.settings.moveAllLabel = value;
|
||||
this.elements.moveAllButton.attr('title', value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setRemoveSelectedLabel: function(value, refresh) {
|
||||
this.settings.removeSelectedLabel = value;
|
||||
this.elements.removeButton.attr('title', value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setRemoveAllLabel: function(value, refresh) {
|
||||
this.settings.removeAllLabel = value;
|
||||
this.elements.removeAllButton.attr('title', value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setMoveOnSelect: function(value, refresh) {
|
||||
if (isBuggyAndroid) {
|
||||
value = true;
|
||||
}
|
||||
this.settings.moveOnSelect = value;
|
||||
if (this.settings.moveOnSelect) {
|
||||
this.container.addClass('moveonselect');
|
||||
var self = this;
|
||||
this.elements.select1.on('change', function() {
|
||||
move(self);
|
||||
});
|
||||
this.elements.select2.on('change', function() {
|
||||
remove(self);
|
||||
});
|
||||
} else {
|
||||
this.container.removeClass('moveonselect');
|
||||
this.elements.select1.off('change');
|
||||
this.elements.select2.off('change');
|
||||
}
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setMoveOnDoubleClick: function(value, refresh) {
|
||||
if (isBuggyAndroid) {
|
||||
value = false;
|
||||
}
|
||||
this.settings.moveOnDoubleClick = value;
|
||||
if (this.settings.moveOnDoubleClick) {
|
||||
this.container.addClass('moveondoubleclick');
|
||||
var self = this;
|
||||
this.elements.select1.on('dblclick', function() {
|
||||
move(self);
|
||||
});
|
||||
this.elements.select2.on('dblclick', function() {
|
||||
remove(self);
|
||||
});
|
||||
} else {
|
||||
this.container.removeClass('moveondoubleclick');
|
||||
this.elements.select1.off('dblclick');
|
||||
this.elements.select2.off('dblclick');
|
||||
}
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setPreserveSelectionOnMove: function(value, refresh) {
|
||||
// We are forcing to move on select and disabling preserveSelectionOnMove on Android
|
||||
if (isBuggyAndroid) {
|
||||
value = false;
|
||||
}
|
||||
this.settings.preserveSelectionOnMove = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setSelectedListLabel: function(value, refresh) {
|
||||
this.settings.selectedListLabel = value;
|
||||
if (value) {
|
||||
this.elements.label2.show().html(value);
|
||||
} else {
|
||||
this.elements.label2.hide().html(value);
|
||||
}
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setNonSelectedListLabel: function(value, refresh) {
|
||||
this.settings.nonSelectedListLabel = value;
|
||||
if (value) {
|
||||
this.elements.label1.show().html(value);
|
||||
} else {
|
||||
this.elements.label1.hide().html(value);
|
||||
}
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setHelperSelectNamePostfix: function(value, refresh) {
|
||||
this.settings.helperSelectNamePostfix = value;
|
||||
if (value) {
|
||||
this.elements.select1.attr('name', this.originalSelectName + value + '1');
|
||||
this.elements.select2.attr('name', this.originalSelectName + value + '2');
|
||||
} else {
|
||||
this.elements.select1.removeAttr('name');
|
||||
this.elements.select2.removeAttr('name');
|
||||
}
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setSelectOrMinimalHeight: function(value, refresh) {
|
||||
this.settings.selectorMinimalHeight = value;
|
||||
var height = this.element.height();
|
||||
if (this.element.height() < value) {
|
||||
height = value;
|
||||
}
|
||||
this.elements.select1.height(height);
|
||||
this.elements.select2.height(height);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setShowFilterInputs: function(value, refresh) {
|
||||
if (!value) {
|
||||
this.setNonSelectedFilter('');
|
||||
this.setSelectedFilter('');
|
||||
refreshSelects(this);
|
||||
this.elements.filterInput1.hide();
|
||||
this.elements.filterInput2.hide();
|
||||
} else {
|
||||
this.elements.filterInput1.show();
|
||||
this.elements.filterInput2.show();
|
||||
}
|
||||
this.settings.showFilterInputs = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setNonSelectedFilter: function(value, refresh) {
|
||||
if (this.settings.showFilterInputs) {
|
||||
this.settings.nonSelectedFilter = value;
|
||||
this.elements.filterInput1.val(value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
}
|
||||
},
|
||||
setSelectedFilter: function(value, refresh) {
|
||||
if (this.settings.showFilterInputs) {
|
||||
this.settings.selectedFilter = value;
|
||||
this.elements.filterInput2.val(value);
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
}
|
||||
},
|
||||
setInfoText: function(value, refresh) {
|
||||
this.settings.infoText = value;
|
||||
if (value) {
|
||||
this.elements.info1.show();
|
||||
this.elements.info2.show();
|
||||
} else {
|
||||
this.elements.info1.hide();
|
||||
this.elements.info2.hide();
|
||||
}
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setInfoTextFiltered: function(value, refresh) {
|
||||
this.settings.infoTextFiltered = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setInfoTextEmpty: function(value, refresh) {
|
||||
this.settings.infoTextEmpty = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setFilterOnValues: function(value, refresh) {
|
||||
this.settings.filterOnValues = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setSortByInputOrder: function(value, refresh){
|
||||
this.settings.sortByInputOrder = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setEventMoveOverride: function(value, refresh) {
|
||||
this.settings.eventMoveOverride = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setEventMoveAllOverride: function(value, refresh) {
|
||||
this.settings.eventMoveAllOverride = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setEventRemoveOverride: function(value, refresh) {
|
||||
this.settings.eventRemoveOverride = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
setEventRemoveAllOverride: function(value, refresh) {
|
||||
this.settings.eventRemoveAllOverride = value;
|
||||
if (refresh) {
|
||||
refreshSelects(this);
|
||||
}
|
||||
return this.element;
|
||||
},
|
||||
getContainer: function() {
|
||||
return this.container;
|
||||
},
|
||||
refresh: function(mustClearSelections) {
|
||||
updateSelectionStates(this);
|
||||
|
||||
if (!mustClearSelections) {
|
||||
saveSelections(this, 1);
|
||||
saveSelections(this, 2);
|
||||
} else {
|
||||
clearSelections(this);
|
||||
}
|
||||
|
||||
refreshSelects(this);
|
||||
},
|
||||
destroy: function() {
|
||||
this.container.remove();
|
||||
this.element.show();
|
||||
$.data(this, 'plugin_' + pluginName, null);
|
||||
return this.element;
|
||||
}
|
||||
};
|
||||
|
||||
// A really lightweight plugin wrapper around the constructor,
|
||||
// preventing against multiple instantiations
|
||||
$.fn[ pluginName ] = function (options) {
|
||||
var args = arguments;
|
||||
|
||||
// Is the first parameter an object (options), or was omitted, instantiate a new instance of the plugin.
|
||||
if (options === undefined || typeof options === 'object') {
|
||||
return this.each(function () {
|
||||
// If this is not a select
|
||||
if (!$(this).is('select')) {
|
||||
$(this).find('select').each(function(index, item) {
|
||||
// For each nested select, instantiate the Dual List Box
|
||||
$(item).bootstrapDualListbox(options);
|
||||
});
|
||||
} else if (!$.data(this, 'plugin_' + pluginName)) {
|
||||
// Only allow the plugin to be instantiated once so we check that the element has no plugin instantiation yet
|
||||
|
||||
// if it has no instance, create a new one, pass options to our plugin constructor,
|
||||
// and store the plugin instance in the elements jQuery data object.
|
||||
$.data(this, 'plugin_' + pluginName, new BootstrapDualListbox(this, options));
|
||||
}
|
||||
});
|
||||
// If the first parameter is a string and it doesn't start with an underscore or "contains" the `init`-function,
|
||||
// treat this as a call to a public method.
|
||||
} else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
|
||||
|
||||
// Cache the method call to make it possible to return a value
|
||||
var returns;
|
||||
|
||||
this.each(function () {
|
||||
var instance = $.data(this, 'plugin_' + pluginName);
|
||||
// Tests that there's already a plugin-instance and checks that the requested public method exists
|
||||
if (instance instanceof BootstrapDualListbox && typeof instance[options] === 'function') {
|
||||
// Call the method of our plugin instance, and pass it the supplied arguments.
|
||||
returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
|
||||
}
|
||||
});
|
||||
|
||||
// If the earlier cached method gives a value back return the value,
|
||||
// otherwise return this to preserve chainability.
|
||||
return returns !== undefined ? returns : this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
})(jQuery, window, document);
|
||||
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Bootstrap Duallistbox - v3.0.9
|
||||
* A responsive dual listbox widget optimized for Twitter Bootstrap. It works on all modern browsers and on touch devices.
|
||||
* https://www.virtuosoft.eu/code/bootstrap-duallistbox/
|
||||
*
|
||||
* Made by István Ujj-Mészáros
|
||||
* Under Apache License v2.0 License
|
||||
*/
|
||||
.bootstrap-duallistbox-container .buttons{width:100%;margin-bottom:-1px}.bootstrap-duallistbox-container label{display:block}.bootstrap-duallistbox-container .info{display:inline-block;margin-bottom:5px;font-size:11px}.bootstrap-duallistbox-container .clear1,.bootstrap-duallistbox-container .clear2{display:none;font-size:10px}.bootstrap-duallistbox-container .box1.filtered .clear1,.bootstrap-duallistbox-container .box2.filtered .clear2{display:inline-block}.bootstrap-duallistbox-container .move,.bootstrap-duallistbox-container .remove{width:60%}.bootstrap-duallistbox-container .btn-group .btn{border-bottom-left-radius:0;border-bottom-right-radius:0}.bootstrap-duallistbox-container select{border-top-left-radius:0;border-top-right-radius:0}.bootstrap-duallistbox-container .moveall,.bootstrap-duallistbox-container .removeall{width:40%}.bootstrap-duallistbox-container.bs2compatible .btn-group>.btn+.btn{margin-left:0}.bootstrap-duallistbox-container select{width:100%;height:300px;padding:0}.bootstrap-duallistbox-container .filter{display:inline-block;width:100%;height:31px;margin:0 0 5px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-duallistbox-container .filter.placeholder{color:#aaa}.bootstrap-duallistbox-container.moveonselect .move,.bootstrap-duallistbox-container.moveonselect .remove{display:none}.bootstrap-duallistbox-container.moveonselect .moveall,.bootstrap-duallistbox-container.moveonselect .removeall{width:100%}
|
||||
@ -0,0 +1,315 @@
|
||||
/* The MIT License
|
||||
|
||||
Copyright (c) 2011 by Michael Zinsmaier and nergal.dev
|
||||
Copyright (c) 2012 by Thomas Ritou
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
____________________________________________________
|
||||
|
||||
what it is:
|
||||
____________________________________________________
|
||||
|
||||
curvedLines is a plugin for flot, that tries to display lines in a smoother way.
|
||||
The plugin is based on nergal.dev's work https://code.google.com/p/flot/issues/detail?id=226
|
||||
and further extended with a mode that forces the min/max points of the curves to be on the
|
||||
points. Both modes are achieved through adding of more data points
|
||||
=> 1) with large data sets you may get trouble
|
||||
=> 2) if you want to display the points too, you have to plot them as 2nd data series over the lines
|
||||
|
||||
&& 3) consecutive x data points are not allowed to have the same value
|
||||
|
||||
This is version 0.5 of curvedLines so it will probably not work in every case. However
|
||||
the basic form of use descirbed next works (:
|
||||
|
||||
Feel free to further improve the code
|
||||
|
||||
____________________________________________________
|
||||
|
||||
how to use it:
|
||||
____________________________________________________
|
||||
|
||||
var d1 = [[5,5],[7,3],[9,12]];
|
||||
|
||||
var options = { series: { curvedLines: { active: true }}};
|
||||
|
||||
$.plot($("#placeholder"), [{data = d1, lines: { show: true}, curvedLines: {apply: true}}], options);
|
||||
|
||||
_____________________________________________________
|
||||
|
||||
options:
|
||||
_____________________________________________________
|
||||
|
||||
active: bool true => plugin can be used
|
||||
apply: bool true => series will be drawn as curved line
|
||||
fit: bool true => forces the max,mins of the curve to be on the datapoints
|
||||
curvePointFactor int defines how many "virtual" points are used per "real" data point to
|
||||
emulate the curvedLines (points total = real points * curvePointFactor)
|
||||
fitPointDist: int defines the x axis distance of the additional two points that are used
|
||||
to enforce the min max condition.
|
||||
|
||||
+ line options (since v0.5 curved lines use flots line implementation for drawing
|
||||
=> line options like fill, show ... are supported out of the box)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* v0.1 initial commit
|
||||
* v0.15 negative values should work now (outcommented a negative -> 0 hook hope it does no harm)
|
||||
* v0.2 added fill option (thanks to monemihir) and multi axis support (thanks to soewono effendi)
|
||||
* v0.3 improved saddle handling and added basic handling of Dates
|
||||
* v0.4 rewritten fill option (thomas ritou) mostly from original flot code (now fill between points rather than to graph bottom), corrected fill Opacity bug
|
||||
* v0.5 rewritten instead of implementing a own draw function CurvedLines is now based on the processDatapoints flot hook (credits go to thomas ritou).
|
||||
* This change breakes existing code however CurvedLines are now just many tiny straight lines to flot and therefore all flot lines options (like gradient fill,
|
||||
* shadow) are now supported out of the box
|
||||
* v0.6 flot 0.8 compatibility and some bug fixes
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
var options = {
|
||||
series : {
|
||||
curvedLines : {
|
||||
active : false,
|
||||
apply: false,
|
||||
fit : false,
|
||||
curvePointFactor : 20,
|
||||
fitPointDist : undefined
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function init(plot) {
|
||||
|
||||
plot.hooks.processOptions.push(processOptions);
|
||||
|
||||
//if the plugin is active register processDatapoints method
|
||||
function processOptions(plot, options) {
|
||||
if (options.series.curvedLines.active) {
|
||||
plot.hooks.processDatapoints.unshift(processDatapoints);
|
||||
}
|
||||
}
|
||||
|
||||
//only if the plugin is active
|
||||
function processDatapoints(plot, series, datapoints) {
|
||||
var nrPoints = datapoints.points.length / datapoints.pointsize;
|
||||
var EPSILON = 0.5; //pretty large epsilon but save
|
||||
|
||||
if (series.curvedLines.apply == true && series.originSeries === undefined && nrPoints > (1 + EPSILON)) {
|
||||
if (series.lines.fill) {
|
||||
|
||||
var pointsTop = calculateCurvePoints(datapoints, series.curvedLines, 1)
|
||||
,pointsBottom = calculateCurvePoints(datapoints, series.curvedLines, 2); //flot makes sure for us that we've got a second y point if fill is true !
|
||||
|
||||
//Merge top and bottom curve
|
||||
datapoints.pointsize = 3;
|
||||
datapoints.points = [];
|
||||
var j = 0;
|
||||
var k = 0;
|
||||
var i = 0;
|
||||
var ps = 2;
|
||||
while (i < pointsTop.length || j < pointsBottom.length) {
|
||||
if (pointsTop[i] == pointsBottom[j]) {
|
||||
datapoints.points[k] = pointsTop[i];
|
||||
datapoints.points[k + 1] = pointsTop[i + 1];
|
||||
datapoints.points[k + 2] = pointsBottom[j + 1];
|
||||
j += ps;
|
||||
i += ps;
|
||||
|
||||
} else if (pointsTop[i] < pointsBottom[j]) {
|
||||
datapoints.points[k] = pointsTop[i];
|
||||
datapoints.points[k + 1] = pointsTop[i + 1];
|
||||
datapoints.points[k + 2] = k > 0 ? datapoints.points[k-1] : null;
|
||||
i += ps;
|
||||
} else {
|
||||
datapoints.points[k] = pointsBottom[j];
|
||||
datapoints.points[k + 1] = k > 1 ? datapoints.points[k-2] : null;
|
||||
datapoints.points[k + 2] = pointsBottom[j + 1];
|
||||
j += ps;
|
||||
}
|
||||
k += 3;
|
||||
}
|
||||
} else if (series.lines.lineWidth > 0) {
|
||||
datapoints.points = calculateCurvePoints(datapoints, series.curvedLines, 1);
|
||||
datapoints.pointsize = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//no real idea whats going on here code mainly from https://code.google.com/p/flot/issues/detail?id=226
|
||||
//if fit option is selected additional datapoints get inserted before the curve calculations in nergal.dev s code.
|
||||
function calculateCurvePoints(datapoints, curvedLinesOptions, yPos) {
|
||||
|
||||
var points = datapoints.points, ps = datapoints.pointsize;
|
||||
var num = curvedLinesOptions.curvePointFactor * (points.length / ps);
|
||||
|
||||
var xdata = new Array;
|
||||
var ydata = new Array;
|
||||
|
||||
var curX = -1;
|
||||
var curY = -1;
|
||||
var j = 0;
|
||||
|
||||
if (curvedLinesOptions.fit) {
|
||||
//insert a point before and after the "real" data point to force the line
|
||||
//to have a max,min at the data point.
|
||||
|
||||
var fpDist;
|
||||
if(typeof curvedLinesOptions.fitPointDist == 'undefined') {
|
||||
//estimate it
|
||||
var minX = points[0];
|
||||
var maxX = points[points.length-ps];
|
||||
fpDist = (maxX - minX) / (500 * 100); //x range / (estimated pixel length of placeholder * factor)
|
||||
} else {
|
||||
//use user defined value
|
||||
fpDist = curvedLinesOptions.fitPointDist;
|
||||
}
|
||||
|
||||
for (var i = 0; i < points.length; i += ps) {
|
||||
|
||||
var frontX;
|
||||
var backX;
|
||||
curX = i;
|
||||
curY = i + yPos;
|
||||
|
||||
//add point X s
|
||||
frontX = points[curX] - fpDist;
|
||||
backX = points[curX] + fpDist;
|
||||
|
||||
var factor = 2;
|
||||
while (frontX == points[curX] || backX == points[curX]) {
|
||||
//inside the ulp
|
||||
frontX = points[curX] - (fpDist * factor);
|
||||
backX = points[curX] + (fpDist * factor);
|
||||
factor++;
|
||||
}
|
||||
|
||||
//add curve points
|
||||
xdata[j] = frontX;
|
||||
ydata[j] = points[curY];
|
||||
j++;
|
||||
|
||||
xdata[j] = points[curX];
|
||||
ydata[j] = points[curY];
|
||||
j++;
|
||||
|
||||
xdata[j] = backX;
|
||||
ydata[j] = points[curY];
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
//just use the datapoints
|
||||
for (var i = 0; i < points.length; i += ps) {
|
||||
curX = i;
|
||||
curY = i + yPos;
|
||||
|
||||
xdata[j] = points[curX];
|
||||
ydata[j] = points[curY];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
var n = xdata.length;
|
||||
|
||||
var y2 = new Array();
|
||||
var delta = new Array();
|
||||
y2[0] = 0;
|
||||
y2[n - 1] = 0;
|
||||
delta[0] = 0;
|
||||
|
||||
for (var i = 1; i < n - 1; ++i) {
|
||||
var d = (xdata[i + 1] - xdata[i - 1]);
|
||||
if (d == 0) {
|
||||
//point before current point and after current point need some space in between
|
||||
return [];
|
||||
}
|
||||
|
||||
var s = (xdata[i] - xdata[i - 1]) / d;
|
||||
var p = s * y2[i - 1] + 2;
|
||||
y2[i] = (s - 1) / p;
|
||||
delta[i] = (ydata[i + 1] - ydata[i]) / (xdata[i + 1] - xdata[i]) - (ydata[i] - ydata[i - 1]) / (xdata[i] - xdata[i - 1]);
|
||||
delta[i] = (6 * delta[i] / (xdata[i + 1] - xdata[i - 1]) - s * delta[i - 1]) / p;
|
||||
}
|
||||
|
||||
for (var j = n - 2; j >= 0; --j) {
|
||||
y2[j] = y2[j] * y2[j + 1] + delta[j];
|
||||
}
|
||||
|
||||
// xmax - xmin / #points
|
||||
var step = (xdata[n - 1] - xdata[0]) / (num - 1);
|
||||
|
||||
var xnew = new Array;
|
||||
var ynew = new Array;
|
||||
var result = new Array;
|
||||
|
||||
xnew[0] = xdata[0];
|
||||
ynew[0] = ydata[0];
|
||||
|
||||
result.push(xnew[0]);
|
||||
result.push(ynew[0]);
|
||||
|
||||
for ( j = 1; j < num; ++j) {
|
||||
//new x point (sampling point for the created curve)
|
||||
xnew[j] = xnew[0] + j * step;
|
||||
|
||||
var max = n - 1;
|
||||
var min = 0;
|
||||
|
||||
while (max - min > 1) {
|
||||
var k = Math.round((max + min) / 2);
|
||||
if (xdata[k] > xnew[j]) {
|
||||
max = k;
|
||||
} else {
|
||||
min = k;
|
||||
}
|
||||
}
|
||||
|
||||
//found point one to the left and one to the right of generated new point
|
||||
var h = (xdata[max] - xdata[min]);
|
||||
|
||||
if (h == 0) {
|
||||
//similar to above two points from original x data need some space between them
|
||||
return [];
|
||||
}
|
||||
|
||||
var a = (xdata[max] - xnew[j]) / h;
|
||||
var b = (xnew[j] - xdata[min]) / h;
|
||||
|
||||
ynew[j] = a * ydata[min] + b * ydata[max] + ((a * a * a - a) * y2[min] + (b * b * b - b) * y2[max]) * (h * h) / 6;
|
||||
|
||||
result.push(xnew[j]);
|
||||
result.push(ynew[j]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}//end init
|
||||
|
||||
$.plot.plugins.push({
|
||||
init : init,
|
||||
options : options,
|
||||
name : 'curvedLines',
|
||||
version : '0.5'
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@ -0,0 +1,750 @@
|
||||
/*
|
||||
Flot plugin for rendering pie charts. The plugin assumes the data is
|
||||
coming is as a single data value for each series, and each of those
|
||||
values is a positive value or zero (negative numbers don't make
|
||||
any sense and will cause strange effects). The data values do
|
||||
NOT need to be passed in as percentage values because it
|
||||
internally calculates the total and percentages.
|
||||
|
||||
* Created by Brian Medendorp, June 2009
|
||||
* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
|
||||
|
||||
* Changes:
|
||||
2009-10-22: lineJoin set to round
|
||||
2009-10-23: IE full circle fix, donut
|
||||
2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
|
||||
2009-11-17: Added IE hover capability submitted by Anthony Aragues
|
||||
2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
|
||||
|
||||
|
||||
Available options are:
|
||||
series: {
|
||||
pie: {
|
||||
show: true/false
|
||||
radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
|
||||
innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
|
||||
startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
|
||||
tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
|
||||
offset: {
|
||||
top: integer value to move the pie up or down
|
||||
left: integer value to move the pie left or right, or 'auto'
|
||||
},
|
||||
stroke: {
|
||||
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
|
||||
width: integer pixel width of the stroke
|
||||
},
|
||||
label: {
|
||||
show: true/false, or 'auto'
|
||||
formatter: a user-defined function that modifies the text/style of the label text
|
||||
radius: 0-1 for percentage of fullsize, or a specified pixel length
|
||||
background: {
|
||||
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
|
||||
opacity: 0-1
|
||||
},
|
||||
threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
|
||||
},
|
||||
combine: {
|
||||
threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
|
||||
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
|
||||
label: any text value of what the combined slice should be labeled
|
||||
}
|
||||
highlight: {
|
||||
opacity: 0-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
More detail and specific examples can be found in the included HTML file.
|
||||
|
||||
*/
|
||||
|
||||
(function ($)
|
||||
{
|
||||
function init(plot) // this is the "body" of the plugin
|
||||
{
|
||||
var canvas = null;
|
||||
var target = null;
|
||||
var maxRadius = null;
|
||||
var centerLeft = null;
|
||||
var centerTop = null;
|
||||
var total = 0;
|
||||
var redraw = true;
|
||||
var redrawAttempts = 10;
|
||||
var shrink = 0.95;
|
||||
var legendWidth = 0;
|
||||
var processed = false;
|
||||
var raw = false;
|
||||
|
||||
// interactive variables
|
||||
var highlights = [];
|
||||
|
||||
// add hook to determine if pie plugin in enabled, and then perform necessary operations
|
||||
plot.hooks.processOptions.push(checkPieEnabled);
|
||||
plot.hooks.bindEvents.push(bindEvents);
|
||||
|
||||
// check to see if the pie plugin is enabled
|
||||
function checkPieEnabled(plot, options)
|
||||
{
|
||||
if (options.series.pie.show)
|
||||
{
|
||||
//disable grid
|
||||
options.grid.show = false;
|
||||
|
||||
// set labels.show
|
||||
if (options.series.pie.label.show=='auto')
|
||||
if (options.legend.show)
|
||||
options.series.pie.label.show = false;
|
||||
else
|
||||
options.series.pie.label.show = true;
|
||||
|
||||
// set radius
|
||||
if (options.series.pie.radius=='auto')
|
||||
if (options.series.pie.label.show)
|
||||
options.series.pie.radius = 3/4;
|
||||
else
|
||||
options.series.pie.radius = 1;
|
||||
|
||||
// ensure sane tilt
|
||||
if (options.series.pie.tilt>1)
|
||||
options.series.pie.tilt=1;
|
||||
if (options.series.pie.tilt<0)
|
||||
options.series.pie.tilt=0;
|
||||
|
||||
// add processData hook to do transformations on the data
|
||||
plot.hooks.processDatapoints.push(processDatapoints);
|
||||
plot.hooks.drawOverlay.push(drawOverlay);
|
||||
|
||||
// add draw hook
|
||||
plot.hooks.draw.push(draw);
|
||||
}
|
||||
}
|
||||
|
||||
// bind hoverable events
|
||||
function bindEvents(plot, eventHolder)
|
||||
{
|
||||
var options = plot.getOptions();
|
||||
|
||||
if (options.series.pie.show && options.grid.hoverable)
|
||||
eventHolder.unbind('mousemove').mousemove(onMouseMove);
|
||||
|
||||
if (options.series.pie.show && options.grid.clickable)
|
||||
eventHolder.unbind('click').click(onClick);
|
||||
}
|
||||
|
||||
|
||||
// debugging function that prints out an object
|
||||
function alertObject(obj)
|
||||
{
|
||||
var msg = '';
|
||||
function traverse(obj, depth)
|
||||
{
|
||||
if (!depth)
|
||||
depth = 0;
|
||||
for (var i = 0; i < obj.length; ++i)
|
||||
{
|
||||
for (var j=0; j<depth; j++)
|
||||
msg += '\t';
|
||||
|
||||
if( typeof obj[i] == "object")
|
||||
{ // its an object
|
||||
msg += ''+i+':\n';
|
||||
traverse(obj[i], depth+1);
|
||||
}
|
||||
else
|
||||
{ // its a value
|
||||
msg += ''+i+': '+obj[i]+'\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
traverse(obj);
|
||||
alert(msg);
|
||||
}
|
||||
|
||||
function calcTotal(data)
|
||||
{
|
||||
for (var i = 0; i < data.length; ++i)
|
||||
{
|
||||
var item = parseFloat(data[i].data[0][1]);
|
||||
if (item)
|
||||
total += item;
|
||||
}
|
||||
}
|
||||
|
||||
function processDatapoints(plot, series, data, datapoints)
|
||||
{
|
||||
if (!processed)
|
||||
{
|
||||
processed = true;
|
||||
|
||||
canvas = plot.getCanvas();
|
||||
target = $(canvas).parent();
|
||||
options = plot.getOptions();
|
||||
|
||||
plot.setData(combine(plot.getData()));
|
||||
}
|
||||
}
|
||||
|
||||
function setupPie()
|
||||
{
|
||||
legendWidth = target.children().filter('.legend').children().width();
|
||||
|
||||
// calculate maximum radius and center point
|
||||
maxRadius = Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;
|
||||
centerTop = (canvas.height/2)+options.series.pie.offset.top;
|
||||
centerLeft = (canvas.width/2);
|
||||
|
||||
if (options.series.pie.offset.left=='auto')
|
||||
if (options.legend.position.match('w'))
|
||||
centerLeft += legendWidth/2;
|
||||
else
|
||||
centerLeft -= legendWidth/2;
|
||||
else
|
||||
centerLeft += options.series.pie.offset.left;
|
||||
|
||||
if (centerLeft<maxRadius)
|
||||
centerLeft = maxRadius;
|
||||
else if (centerLeft>canvas.width-maxRadius)
|
||||
centerLeft = canvas.width-maxRadius;
|
||||
}
|
||||
|
||||
function fixData(data)
|
||||
{
|
||||
for (var i = 0; i < data.length; ++i)
|
||||
{
|
||||
if (typeof(data[i].data)=='number')
|
||||
data[i].data = [[1,data[i].data]];
|
||||
else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')
|
||||
{
|
||||
if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')
|
||||
data[i].label = data[i].data.label; // fix weirdness coming from flot
|
||||
data[i].data = [[1,0]];
|
||||
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function combine(data)
|
||||
{
|
||||
data = fixData(data);
|
||||
calcTotal(data);
|
||||
var combined = 0;
|
||||
var numCombined = 0;
|
||||
var color = options.series.pie.combine.color;
|
||||
|
||||
var newdata = [];
|
||||
for (var i = 0; i < data.length; ++i)
|
||||
{
|
||||
// make sure its a number
|
||||
data[i].data[0][1] = parseFloat(data[i].data[0][1]);
|
||||
if (!data[i].data[0][1])
|
||||
data[i].data[0][1] = 0;
|
||||
|
||||
if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)
|
||||
{
|
||||
combined += data[i].data[0][1];
|
||||
numCombined++;
|
||||
if (!color)
|
||||
color = data[i].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
newdata.push({
|
||||
data: [[1,data[i].data[0][1]]],
|
||||
color: data[i].color,
|
||||
label: data[i].label,
|
||||
angle: (data[i].data[0][1]*(Math.PI*2))/total,
|
||||
percent: (data[i].data[0][1]/total*100)
|
||||
});
|
||||
}
|
||||
}
|
||||
if (numCombined>0)
|
||||
newdata.push({
|
||||
data: [[1,combined]],
|
||||
color: color,
|
||||
label: options.series.pie.combine.label,
|
||||
angle: (combined*(Math.PI*2))/total,
|
||||
percent: (combined/total*100)
|
||||
});
|
||||
return newdata;
|
||||
}
|
||||
|
||||
function draw(plot, newCtx)
|
||||
{
|
||||
if (!target) return; // if no series were passed
|
||||
ctx = newCtx;
|
||||
|
||||
setupPie();
|
||||
var slices = plot.getData();
|
||||
|
||||
var attempts = 0;
|
||||
while (redraw && attempts<redrawAttempts)
|
||||
{
|
||||
redraw = false;
|
||||
if (attempts>0)
|
||||
maxRadius *= shrink;
|
||||
attempts += 1;
|
||||
clear();
|
||||
if (options.series.pie.tilt<=0.8)
|
||||
drawShadow();
|
||||
drawPie();
|
||||
}
|
||||
if (attempts >= redrawAttempts) {
|
||||
clear();
|
||||
target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');
|
||||
}
|
||||
|
||||
if ( plot.setSeries && plot.insertLegend )
|
||||
{
|
||||
plot.setSeries(slices);
|
||||
plot.insertLegend();
|
||||
}
|
||||
|
||||
// we're actually done at this point, just defining internal functions at this point
|
||||
|
||||
function clear()
|
||||
{
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
target.children().filter('.pieLabel, .pieLabelBackground').remove();
|
||||
}
|
||||
|
||||
function drawShadow()
|
||||
{
|
||||
var shadowLeft = 5;
|
||||
var shadowTop = 15;
|
||||
var edge = 10;
|
||||
var alpha = 0.02;
|
||||
|
||||
// set radius
|
||||
if (options.series.pie.radius>1)
|
||||
var radius = options.series.pie.radius;
|
||||
else
|
||||
var radius = maxRadius * options.series.pie.radius;
|
||||
|
||||
if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)
|
||||
return; // shadow would be outside canvas, so don't draw it
|
||||
|
||||
ctx.save();
|
||||
ctx.translate(shadowLeft,shadowTop);
|
||||
ctx.globalAlpha = alpha;
|
||||
ctx.fillStyle = '#000';
|
||||
|
||||
// center and rotate to starting position
|
||||
ctx.translate(centerLeft,centerTop);
|
||||
ctx.scale(1, options.series.pie.tilt);
|
||||
|
||||
//radius -= edge;
|
||||
for (var i=1; i<=edge; i++)
|
||||
{
|
||||
ctx.beginPath();
|
||||
ctx.arc(0,0,radius,0,Math.PI*2,false);
|
||||
ctx.fill();
|
||||
radius -= i;
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function drawPie()
|
||||
{
|
||||
startAngle = Math.PI*options.series.pie.startAngle;
|
||||
|
||||
// set radius
|
||||
if (options.series.pie.radius>1)
|
||||
var radius = options.series.pie.radius;
|
||||
else
|
||||
var radius = maxRadius * options.series.pie.radius;
|
||||
|
||||
// center and rotate to starting position
|
||||
ctx.save();
|
||||
ctx.translate(centerLeft,centerTop);
|
||||
ctx.scale(1, options.series.pie.tilt);
|
||||
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
|
||||
|
||||
// draw slices
|
||||
ctx.save();
|
||||
var currentAngle = startAngle;
|
||||
for (var i = 0; i < slices.length; ++i)
|
||||
{
|
||||
slices[i].startAngle = currentAngle;
|
||||
drawSlice(slices[i].angle, slices[i].color, true);
|
||||
}
|
||||
ctx.restore();
|
||||
|
||||
// draw slice outlines
|
||||
ctx.save();
|
||||
ctx.lineWidth = options.series.pie.stroke.width;
|
||||
currentAngle = startAngle;
|
||||
for (var i = 0; i < slices.length; ++i)
|
||||
drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
|
||||
ctx.restore();
|
||||
|
||||
// draw donut hole
|
||||
drawDonutHole(ctx);
|
||||
|
||||
// draw labels
|
||||
if (options.series.pie.label.show)
|
||||
drawLabels();
|
||||
|
||||
// restore to original state
|
||||
ctx.restore();
|
||||
|
||||
function drawSlice(angle, color, fill)
|
||||
{
|
||||
if (angle<=0)
|
||||
return;
|
||||
|
||||
if (fill)
|
||||
ctx.fillStyle = color;
|
||||
else
|
||||
{
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineJoin = 'round';
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
if (Math.abs(angle - Math.PI*2) > 0.000000001)
|
||||
ctx.moveTo(0,0); // Center of the pie
|
||||
else if ($.browser.msie)
|
||||
angle -= 0.0001;
|
||||
//ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera
|
||||
ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);
|
||||
ctx.closePath();
|
||||
//ctx.rotate(angle); // This doesn't work properly in Opera
|
||||
currentAngle += angle;
|
||||
|
||||
if (fill)
|
||||
ctx.fill();
|
||||
else
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
function drawLabels()
|
||||
{
|
||||
var currentAngle = startAngle;
|
||||
|
||||
// set radius
|
||||
if (options.series.pie.label.radius>1)
|
||||
var radius = options.series.pie.label.radius;
|
||||
else
|
||||
var radius = maxRadius * options.series.pie.label.radius;
|
||||
|
||||
for (var i = 0; i < slices.length; ++i)
|
||||
{
|
||||
if (slices[i].percent >= options.series.pie.label.threshold*100)
|
||||
drawLabel(slices[i], currentAngle, i);
|
||||
currentAngle += slices[i].angle;
|
||||
}
|
||||
|
||||
function drawLabel(slice, startAngle, index)
|
||||
{
|
||||
if (slice.data[0][1]==0)
|
||||
return;
|
||||
|
||||
// format label text
|
||||
var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
|
||||
if (lf)
|
||||
text = lf(slice.label, slice);
|
||||
else
|
||||
text = slice.label;
|
||||
if (plf)
|
||||
text = plf(text, slice);
|
||||
|
||||
var halfAngle = ((startAngle+slice.angle) + startAngle)/2;
|
||||
var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
|
||||
var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
|
||||
|
||||
var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";
|
||||
target.append(html);
|
||||
var label = target.children('#pieLabel'+index);
|
||||
var labelTop = (y - label.height()/2);
|
||||
var labelLeft = (x - label.width()/2);
|
||||
label.css('top', labelTop);
|
||||
label.css('left', labelLeft);
|
||||
|
||||
// check to make sure that the label is not outside the canvas
|
||||
if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)
|
||||
redraw = true;
|
||||
|
||||
if (options.series.pie.label.background.opacity != 0) {
|
||||
// put in the transparent background separately to avoid blended labels and label boxes
|
||||
var c = options.series.pie.label.background.color;
|
||||
if (c == null) {
|
||||
c = slice.color;
|
||||
}
|
||||
var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';
|
||||
$('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);
|
||||
}
|
||||
} // end individual label function
|
||||
} // end drawLabels function
|
||||
} // end drawPie function
|
||||
} // end draw function
|
||||
|
||||
// Placed here because it needs to be accessed from multiple locations
|
||||
function drawDonutHole(layer)
|
||||
{
|
||||
// draw donut hole
|
||||
if(options.series.pie.innerRadius > 0)
|
||||
{
|
||||
// subtract the center
|
||||
layer.save();
|
||||
innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
|
||||
layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color
|
||||
layer.beginPath();
|
||||
layer.fillStyle = options.series.pie.stroke.color;
|
||||
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
|
||||
layer.fill();
|
||||
layer.closePath();
|
||||
layer.restore();
|
||||
|
||||
// add inner stroke
|
||||
layer.save();
|
||||
layer.beginPath();
|
||||
layer.strokeStyle = options.series.pie.stroke.color;
|
||||
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
|
||||
layer.stroke();
|
||||
layer.closePath();
|
||||
layer.restore();
|
||||
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
|
||||
}
|
||||
}
|
||||
|
||||
//-- Additional Interactive related functions --
|
||||
|
||||
function isPointInPoly(poly, pt)
|
||||
{
|
||||
for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
|
||||
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
|
||||
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
|
||||
&& (c = !c);
|
||||
return c;
|
||||
}
|
||||
|
||||
function findNearbySlice(mouseX, mouseY)
|
||||
{
|
||||
var slices = plot.getData(),
|
||||
options = plot.getOptions(),
|
||||
radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
|
||||
|
||||
for (var i = 0; i < slices.length; ++i)
|
||||
{
|
||||
var s = slices[i];
|
||||
|
||||
if(s.pie.show)
|
||||
{
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0,0); // Center of the pie
|
||||
//ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
|
||||
ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);
|
||||
ctx.closePath();
|
||||
x = mouseX-centerLeft;
|
||||
y = mouseY-centerTop;
|
||||
if(ctx.isPointInPath)
|
||||
{
|
||||
if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))
|
||||
{
|
||||
//alert('found slice!');
|
||||
ctx.restore();
|
||||
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
|
||||
p1X = (radius * Math.cos(s.startAngle));
|
||||
p1Y = (radius * Math.sin(s.startAngle));
|
||||
p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));
|
||||
p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));
|
||||
p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));
|
||||
p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));
|
||||
p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));
|
||||
p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));
|
||||
p5X = (radius * Math.cos(s.startAngle+s.angle));
|
||||
p5Y = (radius * Math.sin(s.startAngle+s.angle));
|
||||
arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];
|
||||
arrPoint = [x,y];
|
||||
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
|
||||
if(isPointInPoly(arrPoly, arrPoint))
|
||||
{
|
||||
ctx.restore();
|
||||
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
|
||||
}
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function onMouseMove(e)
|
||||
{
|
||||
triggerClickHoverEvent('plothover', e);
|
||||
}
|
||||
|
||||
function onClick(e)
|
||||
{
|
||||
triggerClickHoverEvent('plotclick', e);
|
||||
}
|
||||
|
||||
// trigger click or hover event (they send the same parameters so we share their code)
|
||||
function triggerClickHoverEvent(eventname, e)
|
||||
{
|
||||
var offset = plot.offset(),
|
||||
canvasX = parseInt(e.pageX - offset.left),
|
||||
canvasY = parseInt(e.pageY - offset.top),
|
||||
item = findNearbySlice(canvasX, canvasY);
|
||||
|
||||
if (options.grid.autoHighlight)
|
||||
{
|
||||
// clear auto-highlights
|
||||
for (var i = 0; i < highlights.length; ++i)
|
||||
{
|
||||
var h = highlights[i];
|
||||
if (h.auto == eventname && !(item && h.series == item.series))
|
||||
unhighlight(h.series);
|
||||
}
|
||||
}
|
||||
|
||||
// highlight the slice
|
||||
if (item)
|
||||
highlight(item.series, eventname);
|
||||
|
||||
// trigger any hover bind events
|
||||
var pos = { pageX: e.pageX, pageY: e.pageY };
|
||||
target.trigger(eventname, [ pos, item ]);
|
||||
}
|
||||
|
||||
function highlight(s, auto)
|
||||
{
|
||||
if (typeof s == "number")
|
||||
s = series[s];
|
||||
|
||||
var i = indexOfHighlight(s);
|
||||
if (i == -1)
|
||||
{
|
||||
highlights.push({ series: s, auto: auto });
|
||||
plot.triggerRedrawOverlay();
|
||||
}
|
||||
else if (!auto)
|
||||
highlights[i].auto = false;
|
||||
}
|
||||
|
||||
function unhighlight(s)
|
||||
{
|
||||
if (s == null)
|
||||
{
|
||||
highlights = [];
|
||||
plot.triggerRedrawOverlay();
|
||||
}
|
||||
|
||||
if (typeof s == "number")
|
||||
s = series[s];
|
||||
|
||||
var i = indexOfHighlight(s);
|
||||
if (i != -1)
|
||||
{
|
||||
highlights.splice(i, 1);
|
||||
plot.triggerRedrawOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
function indexOfHighlight(s)
|
||||
{
|
||||
for (var i = 0; i < highlights.length; ++i)
|
||||
{
|
||||
var h = highlights[i];
|
||||
if (h.series == s)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function drawOverlay(plot, octx)
|
||||
{
|
||||
//alert(options.series.pie.radius);
|
||||
var options = plot.getOptions();
|
||||
//alert(options.series.pie.radius);
|
||||
|
||||
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
|
||||
|
||||
octx.save();
|
||||
octx.translate(centerLeft, centerTop);
|
||||
octx.scale(1, options.series.pie.tilt);
|
||||
|
||||
for (i = 0; i < highlights.length; ++i)
|
||||
drawHighlight(highlights[i].series);
|
||||
|
||||
drawDonutHole(octx);
|
||||
|
||||
octx.restore();
|
||||
|
||||
function drawHighlight(series)
|
||||
{
|
||||
if (series.angle < 0) return;
|
||||
|
||||
//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
|
||||
octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor
|
||||
|
||||
octx.beginPath();
|
||||
if (Math.abs(series.angle - Math.PI*2) > 0.000000001)
|
||||
octx.moveTo(0,0); // Center of the pie
|
||||
octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);
|
||||
octx.closePath();
|
||||
octx.fill();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // end init (plugin body)
|
||||
|
||||
// define pie specific options and their default values
|
||||
var options = {
|
||||
series: {
|
||||
pie: {
|
||||
show: false,
|
||||
radius: 'auto', // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
|
||||
innerRadius:0, /* for donut */
|
||||
startAngle: 3/2,
|
||||
tilt: 1,
|
||||
offset: {
|
||||
top: 0,
|
||||
left: 'auto'
|
||||
},
|
||||
stroke: {
|
||||
color: '#FFF',
|
||||
width: 1
|
||||
},
|
||||
label: {
|
||||
show: 'auto',
|
||||
formatter: function(label, slice){
|
||||
return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';
|
||||
}, // formatter function
|
||||
radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
|
||||
background: {
|
||||
color: null,
|
||||
opacity: 0
|
||||
},
|
||||
threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
|
||||
},
|
||||
combine: {
|
||||
threshold: -1, // percentage at which to combine little slices into one larger slice
|
||||
color: null, // color to give the new slice (auto-generated if null)
|
||||
label: 'Other' // label to give the new slice
|
||||
},
|
||||
highlight: {
|
||||
//color: '#FFF', // will add this functionality once parseColor is available
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
options: options,
|
||||
name: "pie",
|
||||
version: "1.0"
|
||||
});
|
||||
})(jQuery);
|
||||
@ -0,0 +1,60 @@
|
||||
/* Flot plugin for automatically redrawing plots as the placeholder resizes.
|
||||
|
||||
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
It works by listening for changes on the placeholder div (through the jQuery
|
||||
resize event plugin) - if the size changes, it will redraw the plot.
|
||||
|
||||
There are no options. If you need to disable the plugin for some plots, you
|
||||
can just fix the size of their placeholders.
|
||||
|
||||
*/
|
||||
|
||||
/* Inline dependency:
|
||||
* jQuery resize event - v1.1 - 3/14/2010
|
||||
* http://benalman.com/projects/jquery-resize-plugin/
|
||||
*
|
||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://benalman.com/about/license/
|
||||
*/
|
||||
|
||||
(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
|
||||
|
||||
(function ($) {
|
||||
var options = { }; // no options
|
||||
|
||||
function init(plot) {
|
||||
function onResize() {
|
||||
var placeholder = plot.getPlaceholder();
|
||||
|
||||
// somebody might have hidden us and we can't plot
|
||||
// when we don't have the dimensions
|
||||
if (placeholder.width() == 0 || placeholder.height() == 0)
|
||||
return;
|
||||
|
||||
plot.resize();
|
||||
plot.setupGrid();
|
||||
plot.draw();
|
||||
}
|
||||
|
||||
function bindEvents(plot, eventHolder) {
|
||||
plot.getPlaceholder().resize(onResize);
|
||||
}
|
||||
|
||||
function shutdown(plot, eventHolder) {
|
||||
plot.getPlaceholder().unbind("resize", onResize);
|
||||
}
|
||||
|
||||
plot.hooks.bindEvents.push(bindEvents);
|
||||
plot.hooks.shutdown.push(shutdown);
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
options: options,
|
||||
name: 'resize',
|
||||
version: '1.0'
|
||||
});
|
||||
})(jQuery);
|
||||
@ -0,0 +1,212 @@
|
||||
/**
|
||||
* Flot plugin that provides spline interpolation for line graphs
|
||||
* author: Alex Bardas < alex.bardas@gmail.com >
|
||||
* modified by: Avi Kohn https://github.com/AMKohn
|
||||
* based on the spline interpolation described at:
|
||||
* http://scaledinnovation.com/analytics/splines/aboutSplines.html
|
||||
*
|
||||
* Example usage: (add in plot options series object)
|
||||
* for linespline:
|
||||
* series: {
|
||||
* ...
|
||||
* lines: {
|
||||
* show: false
|
||||
* },
|
||||
* splines: {
|
||||
* show: true,
|
||||
* tension: x, (float between 0 and 1, defaults to 0.5),
|
||||
* lineWidth: y (number, defaults to 2),
|
||||
* fill: z (float between 0 .. 1 or false, as in flot documentation)
|
||||
* },
|
||||
* ...
|
||||
* }
|
||||
* areaspline:
|
||||
* series: {
|
||||
* ...
|
||||
* lines: {
|
||||
* show: true,
|
||||
* lineWidth: 0, (line drawing will not execute)
|
||||
* fill: x, (float between 0 .. 1, as in flot documentation)
|
||||
* ...
|
||||
* },
|
||||
* splines: {
|
||||
* show: true,
|
||||
* tension: 0.5 (float between 0 and 1)
|
||||
* },
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @param {Number} x0, y0, x1, y1: coordinates of the end (knot) points of the segment
|
||||
* @param {Number} x2, y2: the next knot (not connected, but needed to calculate p2)
|
||||
* @param {Number} tension: control how far the control points spread
|
||||
* @return {Array}: p1 -> control point, from x1 back toward x0
|
||||
* p2 -> the next control point, returned to become the next segment's p1
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
function getControlPoints(x0, y0, x1, y1, x2, y2, tension) {
|
||||
|
||||
var pow = Math.pow,
|
||||
sqrt = Math.sqrt,
|
||||
d01, d12, fa, fb, p1x, p1y, p2x, p2y;
|
||||
|
||||
// Scaling factors: distances from this knot to the previous and following knots.
|
||||
d01 = sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2));
|
||||
d12 = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
|
||||
|
||||
fa = tension * d01 / (d01 + d12);
|
||||
fb = tension - fa;
|
||||
|
||||
p1x = x1 + fa * (x0 - x2);
|
||||
p1y = y1 + fa * (y0 - y2);
|
||||
|
||||
p2x = x1 - fb * (x0 - x2);
|
||||
p2y = y1 - fb * (y0 - y2);
|
||||
|
||||
return [p1x, p1y, p2x, p2y];
|
||||
}
|
||||
|
||||
var line = [];
|
||||
|
||||
function drawLine(points, ctx, height, fill, seriesColor) {
|
||||
var c = $.color.parse(seriesColor);
|
||||
|
||||
c.a = typeof fill == "number" ? fill : .3;
|
||||
c.normalize();
|
||||
c = c.toString();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(points[0][0], points[0][1]);
|
||||
|
||||
var plength = points.length;
|
||||
|
||||
for (var i = 0; i < plength; i++) {
|
||||
ctx[points[i][3]].apply(ctx, points[i][2]);
|
||||
}
|
||||
|
||||
ctx.stroke();
|
||||
|
||||
ctx.lineWidth = 0;
|
||||
ctx.lineTo(points[plength - 1][0], height);
|
||||
ctx.lineTo(points[0][0], height);
|
||||
|
||||
ctx.closePath();
|
||||
|
||||
if (fill !== false) {
|
||||
ctx.fillStyle = c;
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} ctx: canvas context
|
||||
* @param {String} type: accepted strings: 'bezier' or 'quadratic' (defaults to quadratic)
|
||||
* @param {Array} points: 2 points for which to draw the interpolation
|
||||
* @param {Array} cpoints: control points for those segment points
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
function queue(ctx, type, points, cpoints) {
|
||||
if (type === void 0 || (type !== 'bezier' && type !== 'quadratic')) {
|
||||
type = 'quadratic';
|
||||
}
|
||||
type = type + 'CurveTo';
|
||||
|
||||
if (line.length == 0) line.push([points[0], points[1], cpoints.concat(points.slice(2)), type]);
|
||||
else if (type == "quadraticCurveTo" && points.length == 2) {
|
||||
cpoints = cpoints.slice(0, 2).concat(points);
|
||||
|
||||
line.push([points[0], points[1], cpoints, type]);
|
||||
}
|
||||
else line.push([points[2], points[3], cpoints.concat(points.slice(2)), type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} plot
|
||||
* @param {Object} ctx: canvas context
|
||||
* @param {Object} series
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function drawSpline(plot, ctx, series) {
|
||||
// Not interested if spline is not requested
|
||||
if (series.splines.show !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cp = [],
|
||||
// array of control points
|
||||
tension = series.splines.tension || 0.5,
|
||||
idx, x, y, points = series.datapoints.points,
|
||||
ps = series.datapoints.pointsize,
|
||||
plotOffset = plot.getPlotOffset(),
|
||||
len = points.length,
|
||||
pts = [];
|
||||
|
||||
line = [];
|
||||
|
||||
// Cannot display a linespline/areaspline if there are less than 3 points
|
||||
if (len / ps < 4) {
|
||||
$.extend(series.lines, series.splines);
|
||||
return;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < len; idx += ps) {
|
||||
x = points[idx];
|
||||
y = points[idx + 1];
|
||||
if (x == null || x < series.xaxis.min || x > series.xaxis.max || y < series.yaxis.min || y > series.yaxis.max) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pts.push(series.xaxis.p2c(x) + plotOffset.left, series.yaxis.p2c(y) + plotOffset.top);
|
||||
}
|
||||
|
||||
len = pts.length;
|
||||
|
||||
// Draw an open curve, not connected at the ends
|
||||
for (idx = 0; idx < len - 2; idx += 2) {
|
||||
cp = cp.concat(getControlPoints.apply(this, pts.slice(idx, idx + 6).concat([tension])));
|
||||
}
|
||||
|
||||
ctx.save();
|
||||
ctx.strokeStyle = series.color;
|
||||
ctx.lineWidth = series.splines.lineWidth;
|
||||
|
||||
queue(ctx, 'quadratic', pts.slice(0, 4), cp.slice(0, 2));
|
||||
|
||||
for (idx = 2; idx < len - 3; idx += 2) {
|
||||
queue(ctx, 'bezier', pts.slice(idx, idx + 4), cp.slice(2 * idx - 2, 2 * idx + 2));
|
||||
}
|
||||
|
||||
queue(ctx, 'quadratic', pts.slice(len - 2, len), [cp[2 * len - 10], cp[2 * len - 9], pts[len - 4], pts[len - 3]]);
|
||||
|
||||
drawLine(line, ctx, plot.height() + 10, series.splines.fill, series.color);
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: function(plot) {
|
||||
plot.hooks.drawSeries.push(drawSpline);
|
||||
},
|
||||
options: {
|
||||
series: {
|
||||
splines: {
|
||||
show: false,
|
||||
lineWidth: 2,
|
||||
tension: 0.5,
|
||||
fill: false
|
||||
}
|
||||
}
|
||||
},
|
||||
name: 'spline',
|
||||
version: '0.8.2'
|
||||
});
|
||||
})(jQuery);
|
||||
@ -0,0 +1,71 @@
|
||||
/* Flot plugin that adds some extra symbols for plotting points.
|
||||
|
||||
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
The symbols are accessed as strings through the standard symbol options:
|
||||
|
||||
series: {
|
||||
points: {
|
||||
symbol: "square" // or "diamond", "triangle", "cross"
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
function processRawData(plot, series, datapoints) {
|
||||
// we normalize the area of each symbol so it is approximately the
|
||||
// same as a circle of the given radius
|
||||
|
||||
var handlers = {
|
||||
square: function (ctx, x, y, radius, shadow) {
|
||||
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
||||
var size = radius * Math.sqrt(Math.PI) / 2;
|
||||
ctx.rect(x - size, y - size, size + size, size + size);
|
||||
},
|
||||
diamond: function (ctx, x, y, radius, shadow) {
|
||||
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
|
||||
var size = radius * Math.sqrt(Math.PI / 2);
|
||||
ctx.moveTo(x - size, y);
|
||||
ctx.lineTo(x, y - size);
|
||||
ctx.lineTo(x + size, y);
|
||||
ctx.lineTo(x, y + size);
|
||||
ctx.lineTo(x - size, y);
|
||||
},
|
||||
triangle: function (ctx, x, y, radius, shadow) {
|
||||
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
|
||||
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
|
||||
var height = size * Math.sin(Math.PI / 3);
|
||||
ctx.moveTo(x - size/2, y + height/2);
|
||||
ctx.lineTo(x + size/2, y + height/2);
|
||||
if (!shadow) {
|
||||
ctx.lineTo(x, y - height/2);
|
||||
ctx.lineTo(x - size/2, y + height/2);
|
||||
}
|
||||
},
|
||||
cross: function (ctx, x, y, radius, shadow) {
|
||||
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
||||
var size = radius * Math.sqrt(Math.PI) / 2;
|
||||
ctx.moveTo(x - size, y - size);
|
||||
ctx.lineTo(x + size, y + size);
|
||||
ctx.moveTo(x - size, y + size);
|
||||
ctx.lineTo(x + size, y - size);
|
||||
}
|
||||
};
|
||||
|
||||
var s = series.points.symbol;
|
||||
if (handlers[s])
|
||||
series.points.symbol = handlers[s];
|
||||
}
|
||||
|
||||
function init(plot) {
|
||||
plot.hooks.processDatapoints.push(processRawData);
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
name: 'symbols',
|
||||
version: '1.0'
|
||||
});
|
||||
})(jQuery);
|
||||
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* jquery.flot.tooltip
|
||||
*
|
||||
* description: easy-to-use tooltips for Flot charts
|
||||
* version: 0.6.2
|
||||
* author: Krzysztof Urbas @krzysu [myviews.pl]
|
||||
* website: https://github.com/krzysu/flot.tooltip
|
||||
*
|
||||
* build on 2013-09-30
|
||||
* released under MIT License, 2012
|
||||
*/
|
||||
(function(t){var o={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},i=function(t){this.tipPosition={x:0,y:0},this.init(t)};i.prototype.init=function(o){function i(t){var o={};o.x=t.pageX,o.y=t.pageY,s.updateTooltipPosition(o)}function e(t,o,i){var e=s.getDomElement();if(i){var n;n=s.stringFormat(s.tooltipOptions.content,i),e.html(n),s.updateTooltipPosition({x:o.pageX,y:o.pageY}),e.css({left:s.tipPosition.x+s.tooltipOptions.shifts.x,top:s.tipPosition.y+s.tooltipOptions.shifts.y}).show(),"function"==typeof s.tooltipOptions.onHover&&s.tooltipOptions.onHover(i,e)}else e.hide().html("")}var s=this;o.hooks.bindEvents.push(function(o,n){s.plotOptions=o.getOptions(),s.plotOptions.tooltip!==!1&&void 0!==s.plotOptions.tooltip&&(s.tooltipOptions=s.plotOptions.tooltipOpts,s.getDomElement(),t(o.getPlaceholder()).bind("plothover",e),t(n).bind("mousemove",i))}),o.hooks.shutdown.push(function(o,s){t(o.getPlaceholder()).unbind("plothover",e),t(s).unbind("mousemove",i)})},i.prototype.getDomElement=function(){var o;return t("#flotTip").length>0?o=t("#flotTip"):(o=t("<div />").attr("id","flotTip"),o.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&o.css({background:"#fff","z-index":"100",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),o},i.prototype.updateTooltipPosition=function(o){var i=t("#flotTip").outerWidth()+this.tooltipOptions.shifts.x,e=t("#flotTip").outerHeight()+this.tooltipOptions.shifts.y;o.x-t(window).scrollLeft()>t(window).innerWidth()-i&&(o.x-=i),o.y-t(window).scrollTop()>t(window).innerHeight()-e&&(o.y-=e),this.tipPosition.x=o.x,this.tipPosition.y=o.y},i.prototype.stringFormat=function(t,o){var i=/%p\.{0,1}(\d{0,})/,e=/%s/,s=/%x\.{0,1}(?:\d{0,})/,n=/%y\.{0,1}(?:\d{0,})/;return"function"==typeof t&&(t=t(o.series.label,o.series.data[o.dataIndex][0],o.series.data[o.dataIndex][1],o)),o.series.percent!==void 0&&(t=this.adjustValPrecision(i,t,o.series.percent)),o.series.label!==void 0&&(t=t.replace(e,o.series.label)),this.isTimeMode("xaxis",o)&&this.isXDateFormat(o)&&(t=t.replace(s,this.timestampToDate(o.series.data[o.dataIndex][0],this.tooltipOptions.xDateFormat))),this.isTimeMode("yaxis",o)&&this.isYDateFormat(o)&&(t=t.replace(n,this.timestampToDate(o.series.data[o.dataIndex][1],this.tooltipOptions.yDateFormat))),"number"==typeof o.series.data[o.dataIndex][0]&&(t=this.adjustValPrecision(s,t,o.series.data[o.dataIndex][0])),"number"==typeof o.series.data[o.dataIndex][1]&&(t=this.adjustValPrecision(n,t,o.series.data[o.dataIndex][1])),o.series.xaxis.tickFormatter!==void 0&&(t=t.replace(s,o.series.xaxis.tickFormatter(o.series.data[o.dataIndex][0],o.series.xaxis))),o.series.yaxis.tickFormatter!==void 0&&(t=t.replace(n,o.series.yaxis.tickFormatter(o.series.data[o.dataIndex][1],o.series.yaxis))),t},i.prototype.isTimeMode=function(t,o){return o.series[t].options.mode!==void 0&&"time"===o.series[t].options.mode},i.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},i.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},i.prototype.timestampToDate=function(o,i){var e=new Date(o);return t.plot.formatDate(e,i)},i.prototype.adjustValPrecision=function(t,o,i){var e,s=o.match(t);return null!==s&&""!==RegExp.$1&&(e=RegExp.$1,i=i.toFixed(e),o=o.replace(t,i)),o};var e=function(t){new i(t)};t.plot.plugins.push({init:e,options:o,name:"tooltip",version:"0.6.1"})})(jQuery);
|
||||
@ -0,0 +1,182 @@
|
||||
/**
|
||||
* 基于jQuery FullScreen修改
|
||||
* 新增支持IE全屏显示
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
(function(jQuery) {
|
||||
|
||||
/**
|
||||
* Sets or gets the fullscreen state.
|
||||
*
|
||||
* @param {boolean=} state
|
||||
* True to enable fullscreen mode, false to disable it. If not
|
||||
* specified then the current fullscreen state is returned.
|
||||
* @return {boolean|Element|jQuery|null}
|
||||
* When querying the fullscreen state then the current fullscreen
|
||||
* element (or true if browser doesn't support it) is returned
|
||||
* when browser is currently in full screen mode. False is returned
|
||||
* if browser is not in full screen mode. Null is returned if
|
||||
* browser doesn't support fullscreen mode at all. When setting
|
||||
* the fullscreen state then the current jQuery selection is
|
||||
* returned for chaining.
|
||||
* @this {jQuery}
|
||||
*/
|
||||
function fullScreen(state)
|
||||
{
|
||||
var e, func, doc;
|
||||
|
||||
// Do nothing when nothing was selected
|
||||
if (!this.length) return this;
|
||||
|
||||
// We only use the first selected element because it doesn't make sense
|
||||
// to fullscreen multiple elements.
|
||||
e = (/** @type {Element} */ this[0]);
|
||||
|
||||
// Find the real element and the document (Depends on whether the
|
||||
// document itself or a HTML element was selected)
|
||||
if (e.ownerDocument)
|
||||
{
|
||||
doc = e.ownerDocument;
|
||||
}
|
||||
else
|
||||
{
|
||||
doc = e;
|
||||
e = doc.documentElement;
|
||||
}
|
||||
|
||||
// When no state was specified then return the current state.
|
||||
if (state == null)
|
||||
{
|
||||
// When fullscreen mode is not supported then return null
|
||||
if (!((/** @type {?Function} */ doc["exitFullscreen"])
|
||||
|| (/** @type {?Function} */ doc["webkitExitFullscreen"])
|
||||
|| (/** @type {?Function} */ doc["webkitCancelFullScreen"])
|
||||
|| (/** @type {?Function} */ doc["msExitFullscreen"])
|
||||
|| (/** @type {?Function} */ doc["mozCancelFullScreen"])))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check fullscreen state
|
||||
state = !!doc["fullscreenElement"]
|
||||
|| !!doc["msFullscreenElement"]
|
||||
|| !!doc["webkitIsFullScreen"]
|
||||
|| !!doc["mozFullScreen"];
|
||||
if (!state) return state;
|
||||
|
||||
// Return current fullscreen element or "true" if browser doesn't
|
||||
// support this
|
||||
return (/** @type {?Element} */ doc["fullscreenElement"])
|
||||
|| (/** @type {?Element} */ doc["webkitFullscreenElement"])
|
||||
|| (/** @type {?Element} */ doc["webkitCurrentFullScreenElement"])
|
||||
|| (/** @type {?Element} */ doc["msFullscreenElement"])
|
||||
|| (/** @type {?Element} */ doc["mozFullScreenElement"])
|
||||
|| state;
|
||||
}
|
||||
|
||||
// When state was specified then enter or exit fullscreen mode.
|
||||
if (state)
|
||||
{
|
||||
// Enter fullscreen
|
||||
func = (/** @type {?Function} */ e["requestFullscreen"])
|
||||
|| (/** @type {?Function} */ e["webkitRequestFullscreen"])
|
||||
|| (/** @type {?Function} */ e["webkitRequestFullScreen"])
|
||||
|| (/** @type {?Function} */ e["msRequestFullscreen"])
|
||||
|| (/** @type {?Function} */ e["mozRequestFullScreen"]);
|
||||
if (func)
|
||||
{
|
||||
func.call(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Exit fullscreen
|
||||
func = (/** @type {?Function} */ doc["exitFullscreen"])
|
||||
|| (/** @type {?Function} */ doc["webkitExitFullscreen"])
|
||||
|| (/** @type {?Function} */ doc["webkitCancelFullScreen"])
|
||||
|| (/** @type {?Function} */ doc["msExitFullscreen"])
|
||||
|| (/** @type {?Function} */ doc["mozCancelFullScreen"]);
|
||||
if (func) func.call(doc);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the fullscreen mode.
|
||||
*
|
||||
* @return {!jQuery}
|
||||
* The jQuery selection for chaining.
|
||||
* @this {jQuery}
|
||||
*/
|
||||
function toggleFullScreen()
|
||||
{
|
||||
return (/** @type {!jQuery} */ fullScreen.call(this,
|
||||
!fullScreen.call(this)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the browser-specific fullscreenchange event and triggers
|
||||
* a jquery event for it.
|
||||
*
|
||||
* @param {?Event} event
|
||||
* The fullscreenchange event.
|
||||
*/
|
||||
function fullScreenChangeHandler(event)
|
||||
{
|
||||
jQuery(document).trigger(new jQuery.Event("fullscreenchange"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the browser-specific fullscreenerror event and triggers
|
||||
* a jquery event for it.
|
||||
*
|
||||
* @param {?Event} event
|
||||
* The fullscreenerror event.
|
||||
*/
|
||||
function fullScreenErrorHandler(event)
|
||||
{
|
||||
jQuery(document).trigger(new jQuery.Event("fullscreenerror"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the fullscreenchange event handler.
|
||||
*/
|
||||
function installFullScreenHandlers()
|
||||
{
|
||||
var e, change, error;
|
||||
|
||||
// Determine event name
|
||||
e = document;
|
||||
if (e["webkitCancelFullScreen"])
|
||||
{
|
||||
change = "webkitfullscreenchange";
|
||||
error = "webkitfullscreenerror";
|
||||
}
|
||||
else if (e["msExitFullscreen"])
|
||||
{
|
||||
change = "MSFullscreenChange";
|
||||
error = "MSFullscreenError";
|
||||
}
|
||||
else if (e["mozCancelFullScreen"])
|
||||
{
|
||||
change = "mozfullscreenchange";
|
||||
error = "mozfullscreenerror";
|
||||
}
|
||||
else
|
||||
{
|
||||
change = "fullscreenchange";
|
||||
error = "fullscreenerror";
|
||||
}
|
||||
|
||||
// Install the event handlers
|
||||
jQuery(document).bind(change, fullScreenChangeHandler);
|
||||
jQuery(document).bind(error, fullScreenErrorHandler);
|
||||
}
|
||||
|
||||
jQuery.fn["fullScreen"] = fullScreen;
|
||||
jQuery.fn["toggleFullScreen"] = toggleFullScreen;
|
||||
installFullScreenHandlers();
|
||||
|
||||
})(jQuery);
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* GitHub Gist Theme
|
||||
* Author : Anthony Attard - https://github.com/AnthonyAttard
|
||||
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #d73a49;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hljs-number {
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.hljs-string {
|
||||
color: #032f62;
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/* iCheck plugin Square skin, green
|
||||
----------------------------------- */
|
||||
.icheckbox_square-green,
|
||||
.iradio_square-green {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background: url(green.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_square-green-login{
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background: url(green-login.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icheckbox_square-green,.icheckbox_square-green-login {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.icheckbox_square-green.hover,.icheckbox_square-green-login.hover {
|
||||
background-position: -24px 0;
|
||||
}
|
||||
.icheckbox_square-green.checked,.icheckbox_square-green-login.checked {
|
||||
background-position: -48px 0;
|
||||
}
|
||||
.icheckbox_square-green.disabled,.icheckbox_square-green.disabled-login {
|
||||
background-position: -72px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.icheckbox_square-green.checked.disabled,.icheckbox_square-green-login.checked.disabled {
|
||||
background-position: -96px 0;
|
||||
}
|
||||
|
||||
.iradio_square-green {
|
||||
background-position: -120px 0;
|
||||
}
|
||||
.iradio_square-green.hover {
|
||||
background-position: -144px 0;
|
||||
}
|
||||
.iradio_square-green.checked {
|
||||
background-position: -168px 0;
|
||||
}
|
||||
.iradio_square-green.disabled {
|
||||
background-position: -192px 0;
|
||||
cursor: default;
|
||||
}
|
||||
.iradio_square-green.checked.disabled {
|
||||
background-position: -216px 0;
|
||||
}
|
||||
|
||||
/* HiDPI support */
|
||||
@media (-o-min-device-pixel-ratio: 5/4), (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {
|
||||
.icheckbox_square-green,.icheckbox_square-green-login,
|
||||
.iradio_square-green {
|
||||
background-image: url(green%402x.png);
|
||||
-webkit-background-size: 240px 24px;
|
||||
background-size: 240px 24px;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
@ -0,0 +1,11 @@
|
||||
/*! iCheck v1.0.3 by Damir Sultanov, https://github.com/dargullin/icheck, MIT Licensed */
|
||||
(function(k){function E(a,b,e){var c=a[0],f=/er/.test(e)?"indeterminate":/bl/.test(e)?"disabled":"checked",d="update"==e?{checked:c.checked,disabled:c.disabled,indeterminate:"true"==a.attr("indeterminate")||"false"==a.attr("determinate")}:c[f];if(/^(ch|di|in)/.test(e)&&!d)B(a,f);else if(/^(un|en|de)/.test(e)&&d)v(a,f);else if("update"==e)for(var l in d)d[l]?B(a,l,!0):v(a,l,!0);else b&&"toggle"!=e||(b||a.trigger("ifClicked"),d?"radio"!==c.type&&v(a,f):B(a,f))}function B(a,b,e){var c=a[0],f=a.parent(),
|
||||
d="checked"==b,l="indeterminate"==b,t="disabled"==b,u=l?"determinate":d?"unchecked":"enabled",x=q(a,u+C(c.type)),y=q(a,b+C(c.type));if(!0!==c[b]){if(!e&&"checked"==b&&"radio"==c.type&&c.name){var z=a.closest("form"),r='input[name="'+c.name+'"]';r=z.length?z.find(r):k(r);r.each(function(){this!==c&&k(this).data("iCheck")&&v(k(this),b)})}l?(c[b]=!0,c.checked&&v(a,"checked","force")):(e||(c[b]=!0),d&&c.indeterminate&&v(a,"indeterminate",!1));I(a,d,b,e)}c.disabled&&q(a,"cursor",!0)&&f.find(".iCheck-helper").css("cursor",
|
||||
"default");f.addClass(y||q(a,b)||"");f.attr("role")&&!l&&f.attr("aria-"+(t?"disabled":"checked"),"true");f.removeClass(x||q(a,u)||"")}function v(a,b,e){var c=a[0],f=a.parent(),d="checked"==b,l="indeterminate"==b,t="disabled"==b,u=l?"determinate":d?"unchecked":"enabled",x=q(a,u+C(c.type)),y=q(a,b+C(c.type));if(!1!==c[b]){if(l||!e||"force"==e)c[b]=!1;I(a,d,u,e)}!c.disabled&&q(a,"cursor",!0)&&f.find(".iCheck-helper").css("cursor","pointer");f.removeClass(y||q(a,b)||"");f.attr("role")&&!l&&f.attr("aria-"+
|
||||
(t?"disabled":"checked"),"false");f.addClass(x||q(a,u)||"")}function J(a,b){a.data("iCheck")&&(a.parent().html(a.attr("style",a.data("iCheck").s||"")),b&&a.trigger(b),a.off(".i").unwrap(),k('label[for="'+a[0].id+'"]').add(a.closest("label")).off(".i"))}function q(a,b,e){if(a.data("iCheck"))return a.data("iCheck").o[b+(e?"":"Class")]}function C(a){return a.charAt(0).toUpperCase()+a.slice(1)}function I(a,b,e,c){c||(b&&a.trigger("ifToggled"),a.trigger("change").trigger("ifChanged").trigger("if"+C(e)))}
|
||||
var G=/ip(hone|od|ad)|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent)||"MacIntel"===navigator.platform&&1<navigator.maxTouchPoints;k.fn.iCheck=function(a,b){var e='input[type="checkbox"], input[type="radio"]',c=k(),f=function(g){g.each(function(){var m=k(this);c=m.is(e)?c.add(m):c.add(m.find(e))})};if(/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(a))return a=a.toLowerCase(),f(this),c.each(function(){var g=k(this);"destroy"==a?
|
||||
J(g,"ifDestroyed"):E(g,!0,a);k.isFunction(b)&&b()});if("object"!=typeof a&&a)return this;var d=k.extend({checkedClass:"checked",disabledClass:"disabled",indeterminateClass:"indeterminate",labelHover:!0},a),l=d.handle,t=d.hoverClass||"hover",u=d.focusClass||"focus",x=d.activeClass||"active",y=!!d.labelHover,z=d.labelHoverClass||"hover",r=(""+d.increaseArea).replace("%","")|0;if("checkbox"==l||"radio"==l)e='input[type="'+l+'"]';-50>r&&(r=-50);f(this);return c.each(function(){var g=k(this);J(g);var m=
|
||||
this,H=m.id,F=-r+"%",w=100+2*r+"%";w={position:"absolute",top:F,left:F,display:"block",width:w,height:w,margin:0,padding:0,background:"#fff",border:0,opacity:0};F=G?{position:"absolute",visibility:"hidden"}:r?w:{position:"absolute",opacity:0};var M="checkbox"==m.type?d.checkboxClass||"icheckbox":d.radioClass||"iradio",D=k('label[for="'+H+'"]').add(g.closest("label")),K=!!d.aria,L="iCheck-"+Math.random().toString(36).substr(2,6),h='<div class="'+M+'" '+(K?'role="'+m.type+'" ':"");K&&D.each(function(){h+=
|
||||
'aria-labelledby="';this.id?h+=this.id:(this.id=L,h+=L);h+='"'});h=g.wrap(h+"/>").trigger("ifCreated").parent().append(d.insert);w=k('<ins class="iCheck-helper"/>').css(w).appendTo(h);g.data("iCheck",{o:d,s:g.attr("style")}).css(F);d.inheritClass&&h.addClass(m.className||"");d.inheritID&&H&&h.attr("id","iCheck-"+H);"static"==h.css("position")&&h.css("position","relative");E(g,!0,"update");if(D.length)D.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i",function(p){var n=p.type,A=k(this);
|
||||
if(!m.disabled){if("click"==n){if(k(p.target).is("a"))return;E(g,!1,!0)}else y&&(/ut|nd/.test(n)?(h.removeClass(t),A.removeClass(z)):(h.addClass(t),A.addClass(z)));if(G)p.stopPropagation();else return!1}});g.on("click.i focus.i blur.i keyup.i keydown.i keypress.i",function(p){var n=p.type;p=p.keyCode;if("click"==n)return!1;if("keydown"==n&&32==p)return"radio"==m.type&&m.checked||(m.checked?v(g,"checked"):B(g,"checked")),!1;if("keyup"==n&&"radio"==m.type)!m.checked&&B(g,"checked");else if(/us|ur/.test(n))h["blur"==
|
||||
n?"removeClass":"addClass"](u)});w.on("click mousedown mouseup mouseover mouseout touchbegin.i touchend.i",function(p){var n=p.type,A=/wn|up/.test(n)?x:t;if(!m.disabled){if("click"==n)E(g,!1,!0);else if(/wn|er|in/.test(n)?h.addClass(A):h.removeClass(A+" "+x),D.length&&y&&A==t)D[/ut|nd/.test(n)?"removeClass":"addClass"](z);if(G)p.stopPropagation();else return!1}})})}})(window.jQuery||window.Zepto);
|
||||
@ -0,0 +1,620 @@
|
||||
/*!
|
||||
* Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap)
|
||||
* Copyright 2012-2014 Arnold Daniels
|
||||
* Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
.container-smooth {
|
||||
max-width: 1170px;
|
||||
}
|
||||
@media (min-width: 1px) {
|
||||
.container-smooth {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
.btn-labeled {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.btn-label {
|
||||
position: relative;
|
||||
left: -12px;
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
background: transparent;
|
||||
background: rgba(0, 0, 0, .15);
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
.btn-label.btn-label-right {
|
||||
right: -12px;
|
||||
left: auto;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.btn-lg .btn-label {
|
||||
left: -16px;
|
||||
padding: 10px 16px;
|
||||
border-radius: 5px 0 0 5px;
|
||||
}
|
||||
.btn-lg .btn-label.btn-label-right {
|
||||
right: -16px;
|
||||
left: auto;
|
||||
border-radius: 0 5px 5px 0;
|
||||
}
|
||||
.btn-sm .btn-label {
|
||||
left: -10px;
|
||||
padding: 5px 10px;
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
.btn-sm .btn-label.btn-label-right {
|
||||
right: -10px;
|
||||
left: auto;
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
.btn-xs .btn-label {
|
||||
left: -5px;
|
||||
padding: 1px 5px;
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
.btn-xs .btn-label.btn-label-right {
|
||||
right: -5px;
|
||||
left: auto;
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
.nav-tabs-bottom {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.nav-tabs-bottom > li {
|
||||
margin-top: -1px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.nav-tabs-bottom > li > a {
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
.nav-tabs-bottom > li > a:hover,
|
||||
.nav-tabs-bottom > li > a:focus,
|
||||
.nav-tabs-bottom > li.active > a,
|
||||
.nav-tabs-bottom > li.active > a:hover,
|
||||
.nav-tabs-bottom > li.active > a:focus {
|
||||
border: 1px solid #ddd;
|
||||
border-top-color: transparent;
|
||||
}
|
||||
.nav-tabs-left {
|
||||
border-right: 1px solid #ddd;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.nav-tabs-left > li {
|
||||
float: none;
|
||||
margin-right: -1px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.nav-tabs-left > li > a {
|
||||
margin-right: 0;
|
||||
margin-bottom: 2px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
.nav-tabs-left > li > a:hover,
|
||||
.nav-tabs-left > li > a:focus,
|
||||
.nav-tabs-left > li.active > a,
|
||||
.nav-tabs-left > li.active > a:hover,
|
||||
.nav-tabs-left > li.active > a:focus {
|
||||
border: 1px solid #ddd;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.row > .nav-tabs-left {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-right: 0;
|
||||
padding-left: 15px;
|
||||
margin-right: -1px;
|
||||
}
|
||||
.row > .nav-tabs-left + .tab-content {
|
||||
border-left: 1px solid #ddd;
|
||||
}
|
||||
.nav-tabs-right {
|
||||
border-bottom: 0;
|
||||
border-left: 1px solid #ddd;
|
||||
}
|
||||
.nav-tabs-right > li {
|
||||
float: none;
|
||||
margin-bottom: 0;
|
||||
margin-left: -1px;
|
||||
}
|
||||
.nav-tabs-right > li > a {
|
||||
margin-bottom: 2px;
|
||||
margin-left: 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.nav-tabs-right > li > a:hover,
|
||||
.nav-tabs-right > li > a:focus,
|
||||
.nav-tabs-right > li.active > a,
|
||||
.nav-tabs-right > li.active > a:hover,
|
||||
.nav-tabs-right > li.active > a:focus {
|
||||
border: 1px solid #ddd;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
.row > .nav-tabs-right {
|
||||
padding-right: 15px;
|
||||
padding-left: 0;
|
||||
}
|
||||
.navmenu,
|
||||
.navbar-offcanvas {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navmenu-fixed-left,
|
||||
.navmenu-fixed-right,
|
||||
.navbar-offcanvas {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 1030;
|
||||
overflow-y: auto;
|
||||
border-radius: 0;
|
||||
}
|
||||
.navmenu-fixed-left,
|
||||
.navbar-offcanvas.navmenu-fixed-left {
|
||||
right: auto;
|
||||
left: 0;
|
||||
border-width: 0 1px 0 0;
|
||||
}
|
||||
.navmenu-fixed-right,
|
||||
.navbar-offcanvas {
|
||||
right: 0;
|
||||
left: auto;
|
||||
border-width: 0 0 0 1px;
|
||||
}
|
||||
.navmenu-nav {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.navmenu-nav.dropdown-menu {
|
||||
position: static;
|
||||
float: none;
|
||||
padding-top: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.navbar-offcanvas .navbar-nav {
|
||||
margin: 0;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.navbar-offcanvas {
|
||||
width: auto;
|
||||
border-top: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
.navbar-offcanvas.offcanvas {
|
||||
position: static;
|
||||
display: block !important;
|
||||
height: auto !important;
|
||||
padding-bottom: 0;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.navbar-offcanvas .navbar-nav.navbar-left:first-child {
|
||||
margin-left: -15px;
|
||||
}
|
||||
.navbar-offcanvas .navbar-nav.navbar-right:last-child {
|
||||
margin-right: -15px;
|
||||
}
|
||||
.navbar-offcanvas .navmenu-brand {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.navmenu-brand {
|
||||
display: block;
|
||||
padding: 10px 15px;
|
||||
margin: 10px 0;
|
||||
font-size: 18px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.navmenu-brand:hover,
|
||||
.navmenu-brand:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
.navmenu-default,
|
||||
.navbar-default .navbar-offcanvas {
|
||||
background-color: #f8f8f8;
|
||||
border-color: #e7e7e7;
|
||||
}
|
||||
.navmenu-default .navmenu-brand,
|
||||
.navbar-default .navbar-offcanvas .navmenu-brand {
|
||||
color: #777;
|
||||
}
|
||||
.navmenu-default .navmenu-brand:hover,
|
||||
.navbar-default .navbar-offcanvas .navmenu-brand:hover,
|
||||
.navmenu-default .navmenu-brand:focus,
|
||||
.navbar-default .navbar-offcanvas .navmenu-brand:focus {
|
||||
color: #5e5e5e;
|
||||
background-color: transparent;
|
||||
}
|
||||
.navmenu-default .navmenu-text,
|
||||
.navbar-default .navbar-offcanvas .navmenu-text {
|
||||
color: #777;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > .dropdown > a:hover .caret,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a:hover .caret,
|
||||
.navmenu-default .navmenu-nav > .dropdown > a:focus .caret,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a:focus .caret {
|
||||
border-top-color: #333;
|
||||
border-bottom-color: #333;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > .open > a,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a,
|
||||
.navmenu-default .navmenu-nav > .open > a:hover,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:hover,
|
||||
.navmenu-default .navmenu-nav > .open > a:focus,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:focus {
|
||||
color: #555;
|
||||
background-color: #e7e7e7;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > .open > a .caret,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a .caret,
|
||||
.navmenu-default .navmenu-nav > .open > a:hover .caret,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:hover .caret,
|
||||
.navmenu-default .navmenu-nav > .open > a:focus .caret,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:focus .caret {
|
||||
border-top-color: #555;
|
||||
border-bottom-color: #555;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > .dropdown > a .caret,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a .caret {
|
||||
border-top-color: #777;
|
||||
border-bottom-color: #777;
|
||||
}
|
||||
.navmenu-default .navmenu-nav.dropdown-menu,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu {
|
||||
background-color: #e7e7e7;
|
||||
}
|
||||
.navmenu-default .navmenu-nav.dropdown-menu > .divider,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .divider {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.navmenu-default .navmenu-nav.dropdown-menu > .active > a,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a,
|
||||
.navmenu-default .navmenu-nav.dropdown-menu > .active > a:hover,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:hover,
|
||||
.navmenu-default .navmenu-nav.dropdown-menu > .active > a:focus,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:focus {
|
||||
background-color: #d7d7d7;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > li > a,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > li > a {
|
||||
color: #777;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > li > a:hover,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > li > a:hover,
|
||||
.navmenu-default .navmenu-nav > li > a:focus,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > li > a:focus {
|
||||
color: #333;
|
||||
background-color: transparent;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > .active > a,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .active > a,
|
||||
.navmenu-default .navmenu-nav > .active > a:hover,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .active > a:hover,
|
||||
.navmenu-default .navmenu-nav > .active > a:focus,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .active > a:focus {
|
||||
color: #555;
|
||||
background-color: #e7e7e7;
|
||||
}
|
||||
.navmenu-default .navmenu-nav > .disabled > a,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a,
|
||||
.navmenu-default .navmenu-nav > .disabled > a:hover,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a:hover,
|
||||
.navmenu-default .navmenu-nav > .disabled > a:focus,
|
||||
.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a:focus {
|
||||
color: #ccc;
|
||||
background-color: transparent;
|
||||
}
|
||||
.navmenu-inverse,
|
||||
.navbar-inverse .navbar-offcanvas {
|
||||
background-color: #222;
|
||||
border-color: #080808;
|
||||
}
|
||||
.navmenu-inverse .navmenu-brand,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-brand {
|
||||
color: #999;
|
||||
}
|
||||
.navmenu-inverse .navmenu-brand:hover,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-brand:hover,
|
||||
.navmenu-inverse .navmenu-brand:focus,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-brand:focus {
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
}
|
||||
.navmenu-inverse .navmenu-text,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-text {
|
||||
color: #999;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > .dropdown > a:hover .caret,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a:hover .caret,
|
||||
.navmenu-inverse .navmenu-nav > .dropdown > a:focus .caret,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a:focus .caret {
|
||||
border-top-color: #fff;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > .open > a,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a,
|
||||
.navmenu-inverse .navmenu-nav > .open > a:hover,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:hover,
|
||||
.navmenu-inverse .navmenu-nav > .open > a:focus,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:focus {
|
||||
color: #fff;
|
||||
background-color: #080808;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > .open > a .caret,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a .caret,
|
||||
.navmenu-inverse .navmenu-nav > .open > a:hover .caret,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:hover .caret,
|
||||
.navmenu-inverse .navmenu-nav > .open > a:focus .caret,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:focus .caret {
|
||||
border-top-color: #fff;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > .dropdown > a .caret,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a .caret {
|
||||
border-top-color: #999;
|
||||
border-bottom-color: #999;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav.dropdown-menu,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu {
|
||||
background-color: #080808;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav.dropdown-menu > .divider,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .divider {
|
||||
background-color: #222;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a,
|
||||
.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a:hover,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:hover,
|
||||
.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a:focus,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:focus {
|
||||
background-color: #000;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > li > a,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a {
|
||||
color: #999;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > li > a:hover,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a:hover,
|
||||
.navmenu-inverse .navmenu-nav > li > a:focus,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a:focus {
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > .active > a,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a,
|
||||
.navmenu-inverse .navmenu-nav > .active > a:hover,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a:hover,
|
||||
.navmenu-inverse .navmenu-nav > .active > a:focus,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a:focus {
|
||||
color: #fff;
|
||||
background-color: #080808;
|
||||
}
|
||||
.navmenu-inverse .navmenu-nav > .disabled > a,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a,
|
||||
.navmenu-inverse .navmenu-nav > .disabled > a:hover,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a:hover,
|
||||
.navmenu-inverse .navmenu-nav > .disabled > a:focus,
|
||||
.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a:focus {
|
||||
color: #444;
|
||||
background-color: transparent;
|
||||
}
|
||||
.alert-fixed-top,
|
||||
.alert-fixed-bottom {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
z-index: 1035;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.alert-fixed-top,
|
||||
.alert-fixed-bottom {
|
||||
left: 50%;
|
||||
width: 992px;
|
||||
margin-left: -496px;
|
||||
}
|
||||
}
|
||||
.alert-fixed-top {
|
||||
top: 0;
|
||||
border-width: 0 0 1px 0;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.alert-fixed-top {
|
||||
border-width: 0 1px 1px 1px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
}
|
||||
.alert-fixed-bottom {
|
||||
bottom: 0;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.alert-fixed-bottom {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
}
|
||||
.offcanvas {
|
||||
display: none;
|
||||
}
|
||||
.offcanvas.in {
|
||||
display: block;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.offcanvas-xs {
|
||||
display: none;
|
||||
}
|
||||
.offcanvas-xs.in {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.offcanvas-sm {
|
||||
display: none;
|
||||
}
|
||||
.offcanvas-sm.in {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@media (max-width: 1199px) {
|
||||
.offcanvas-md {
|
||||
display: none;
|
||||
}
|
||||
.offcanvas-md.in {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.offcanvas-lg {
|
||||
display: none;
|
||||
}
|
||||
.offcanvas-lg.in {
|
||||
display: block;
|
||||
}
|
||||
.canvas-sliding {
|
||||
-webkit-transition: top .35s, left .35s, bottom .35s, right .35s;
|
||||
transition: top .35s, left .35s, bottom .35s, right .35s;
|
||||
}
|
||||
.offcanvas-clone {
|
||||
position: absolute !important;
|
||||
top: auto !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
left: auto !important;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
overflow: hidden !important;
|
||||
border: none !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
.table.rowlink td:not(.rowlink-skip),
|
||||
.table .rowlink td:not(.rowlink-skip) {
|
||||
cursor: pointer;
|
||||
}
|
||||
.table.rowlink td:not(.rowlink-skip) a,
|
||||
.table .rowlink td:not(.rowlink-skip) a {
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
.table-hover.rowlink tr:hover td,
|
||||
.table-hover .rowlink tr:hover td {
|
||||
background-color: #cfcfcf;
|
||||
}
|
||||
.btn-file {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.btn-file > input {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-size: 23px;
|
||||
cursor: pointer;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
|
||||
direction: ltr;
|
||||
}
|
||||
.fileinput {
|
||||
display: inline-block;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
.fileinput .form-control {
|
||||
display: inline-block;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 5px;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle;
|
||||
cursor: text;
|
||||
}
|
||||
.fileinput .thumbnail {
|
||||
display: inline-block;
|
||||
margin-bottom: 5px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.fileinput .thumbnail > img {
|
||||
max-height: 100%;
|
||||
}
|
||||
.fileinput .btn {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.fileinput-exists .fileinput-new,
|
||||
.fileinput-new .fileinput-exists {
|
||||
display: none;
|
||||
}
|
||||
.fileinput-inline .fileinput-controls {
|
||||
display: inline;
|
||||
}
|
||||
.fileinput-filename {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.form-control .fileinput-filename {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.fileinput.input-group {
|
||||
display: table;
|
||||
}
|
||||
.fileinput.input-group > * {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.fileinput.input-group > .btn-file {
|
||||
z-index: 1;
|
||||
}
|
||||
.fileinput-new.input-group .btn-file,
|
||||
.fileinput-new .input-group .btn-file {
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.fileinput-new.input-group .btn-file.btn-xs,
|
||||
.fileinput-new .input-group .btn-file.btn-xs,
|
||||
.fileinput-new.input-group .btn-file.btn-sm,
|
||||
.fileinput-new .input-group .btn-file.btn-sm {
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.fileinput-new.input-group .btn-file.btn-lg,
|
||||
.fileinput-new .input-group .btn-file.btn-lg {
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
.form-group.has-warning .fileinput .fileinput-preview {
|
||||
color: #8a6d3b;
|
||||
}
|
||||
.form-group.has-warning .fileinput .thumbnail {
|
||||
border-color: #faebcc;
|
||||
}
|
||||
.form-group.has-error .fileinput .fileinput-preview {
|
||||
color: #a94442;
|
||||
}
|
||||
.form-group.has-error .fileinput .thumbnail {
|
||||
border-color: #ebccd1;
|
||||
}
|
||||
.form-group.has-success .fileinput .fileinput-preview {
|
||||
color: #3c763d;
|
||||
}
|
||||
.form-group.has-success .fileinput .thumbnail {
|
||||
border-color: #d6e9c6;
|
||||
}
|
||||
.input-group-addon:not(:first-child) {
|
||||
border-left: 0;
|
||||
}
|
||||
@ -0,0 +1,324 @@
|
||||
/*!
|
||||
* Jasny Bootstrap v4.0.0 (http://jasny.github.io/bootstrap)
|
||||
* Copyright 2012-2014 Arnold Daniels
|
||||
* Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
+function ($) { "use strict";
|
||||
|
||||
var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
|
||||
|
||||
// FILEUPLOAD PUBLIC CLASS DEFINITION
|
||||
// =================================
|
||||
|
||||
var Fileinput = function (element, options) {
|
||||
this.$element = $(element)
|
||||
|
||||
this.options = $.extend({}, Fileinput.DEFAULTS, options)
|
||||
this.$input = this.$element.find(':file')
|
||||
if (this.$input.length === 0) return
|
||||
|
||||
this.name = this.$input.attr('name') || options.name
|
||||
|
||||
this.$hidden = this.$element.find('input[type=hidden][name="' + this.name + '"]')
|
||||
if (this.$hidden.length === 0) {
|
||||
this.$hidden = $('<input type="hidden">').insertBefore(this.$input)
|
||||
}
|
||||
|
||||
this.$preview = this.$element.find('.fileinput-preview')
|
||||
var height = this.$preview.css('height')
|
||||
if (this.$preview.css('display') !== 'inline' && height !== '0px' && height !== 'none') {
|
||||
this.$preview.css('line-height', height)
|
||||
}
|
||||
|
||||
this.original = {
|
||||
exists: this.$element.hasClass('fileinput-exists'),
|
||||
preview: this.$preview.html(),
|
||||
hiddenVal: this.$hidden.val()
|
||||
}
|
||||
|
||||
this.listen()
|
||||
this.reset()
|
||||
}
|
||||
|
||||
Fileinput.DEFAULTS = {
|
||||
clearName: true
|
||||
}
|
||||
|
||||
Fileinput.prototype.listen = function() {
|
||||
this.$input.on('change.bs.fileinput', $.proxy(this.change, this))
|
||||
$(this.$input[0].form).on('reset.bs.fileinput', $.proxy(this.reset, this))
|
||||
|
||||
this.$element.find('[data-trigger="fileinput"]').on('click.bs.fileinput', $.proxy(this.trigger, this))
|
||||
this.$element.find('[data-dismiss="fileinput"]').on('click.bs.fileinput', $.proxy(this.clear, this))
|
||||
},
|
||||
|
||||
Fileinput.prototype.verifySizes = function(files) {
|
||||
if (typeof this.options.maxSize === 'undefined') return true
|
||||
|
||||
var max = parseFloat(this.options.maxSize)
|
||||
if (max !== this.options.maxSize) return true
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var size = typeof files[i].size !== 'undefined' ? files[i].size : null
|
||||
if (size === null) continue
|
||||
|
||||
size = size / 1000 / 1000 /* convert from bytes to MB */
|
||||
if (size > max) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
Fileinput.prototype.change = function(e) {
|
||||
var files = e.target.files === undefined ? (e.target && e.target.value ? [{ name: e.target.value.replace(/^.+\\/, '')}] : []) : e.target.files
|
||||
|
||||
e.stopPropagation()
|
||||
|
||||
if (files.length === 0) {
|
||||
this.clear()
|
||||
this.$element.trigger('clear.bs.fileinput')
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.verifySizes(files)) {
|
||||
this.$element.trigger('max_size.bs.fileinput')
|
||||
|
||||
this.clear()
|
||||
this.$element.trigger('clear.bs.fileinput')
|
||||
return
|
||||
}
|
||||
|
||||
this.$hidden.val('')
|
||||
this.$hidden.attr('name', '')
|
||||
this.$input.attr('name', this.name)
|
||||
|
||||
var file = files[0]
|
||||
|
||||
if (this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match(/^image\/(gif|png|jpeg|svg\+xml)$/) : file.name.match(/\.(gif|png|jpe?g|svg)$/i)) && typeof FileReader !== "undefined") {
|
||||
var Fileinput = this
|
||||
var reader = new FileReader()
|
||||
var preview = this.$preview
|
||||
var element = this.$element
|
||||
|
||||
reader.onload = function(re) {
|
||||
var $img = $('<img>')
|
||||
$img[0].src = re.target.result
|
||||
files[0].result = re.target.result
|
||||
|
||||
element.find('.fileinput-filename').text(file.name)
|
||||
|
||||
// if parent has max-height, using `(max-)height: 100%` on child doesn't take padding and border into account
|
||||
if (preview.css('max-height') != 'none') {
|
||||
var mh = parseInt(preview.css('max-height'), 10) || 0
|
||||
var pt = parseInt(preview.css('padding-top'), 10) || 0
|
||||
var pb = parseInt(preview.css('padding-bottom'), 10) || 0
|
||||
var bt = parseInt(preview.css('border-top'), 10) || 0
|
||||
var bb = parseInt(preview.css('border-bottom'), 10) || 0
|
||||
|
||||
$img.css('max-height', mh - pt - pb - bt - bb)
|
||||
}
|
||||
|
||||
preview.html($img)
|
||||
if (Fileinput.options.exif) {
|
||||
//Fix image tranformation if this is possible
|
||||
Fileinput.setImageTransform($img, file);
|
||||
}
|
||||
element.addClass('fileinput-exists').removeClass('fileinput-new')
|
||||
|
||||
element.trigger('change.bs.fileinput', files)
|
||||
}
|
||||
|
||||
reader.readAsDataURL(file)
|
||||
} else {
|
||||
var text = file.name
|
||||
var $nameView = this.$element.find('.fileinput-filename')
|
||||
|
||||
if (files.length > 1) {
|
||||
text = $.map(files, function(file) {
|
||||
return file.name;
|
||||
}).join(', ')
|
||||
}
|
||||
|
||||
$nameView.text(text)
|
||||
this.$preview.text(file.name)
|
||||
this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
|
||||
this.$element.trigger('change.bs.fileinput')
|
||||
}
|
||||
},
|
||||
|
||||
Fileinput.prototype.setImageTransform = function($img, file) {
|
||||
var Fileinput = this;
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(me) {
|
||||
var transform = false;
|
||||
var view = new DataView(reader.result);
|
||||
var exif = Fileinput.getImageExif(view);
|
||||
if (exif) {
|
||||
Fileinput.resetOrientation($img, exif);
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
|
||||
Fileinput.prototype.getImageExif = function(view) {
|
||||
if (view.getUint16(0, false) != 0xFFD8) {
|
||||
return -2;
|
||||
}
|
||||
var length = view.byteLength, offset = 2;
|
||||
while (offset < length) {
|
||||
var marker = view.getUint16(offset, false);
|
||||
offset += 2;
|
||||
if (marker == 0xFFE1) {
|
||||
if (view.getUint32(offset += 2, false) != 0x45786966) {
|
||||
return -1;
|
||||
}
|
||||
var little = view.getUint16(offset += 6, false) == 0x4949;
|
||||
offset += view.getUint32(offset + 4, little);
|
||||
var tags = view.getUint16(offset, little);
|
||||
offset += 2;
|
||||
for (var i = 0; i < tags; i++) {
|
||||
if (view.getUint16(offset + (i * 12), little) == 0x0112) {
|
||||
return view.getUint16(offset + (i * 12) + 8, little);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((marker & 0xFF00) != 0xFF00){
|
||||
break;
|
||||
} else {
|
||||
offset += view.getUint16(offset, false);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Fileinput.prototype.resetOrientation = function($img, transform) {
|
||||
var img = new Image();
|
||||
|
||||
img.onload = function() {
|
||||
var width = img.width,
|
||||
height = img.height,
|
||||
canvas = document.createElement('canvas'),
|
||||
ctx = canvas.getContext("2d");
|
||||
|
||||
// set proper canvas dimensions before transform & export
|
||||
if ([5,6,7,8].indexOf(transform) > -1) {
|
||||
canvas.width = height;
|
||||
canvas.height = width;
|
||||
} else {
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
}
|
||||
|
||||
// transform context before drawing image
|
||||
switch (transform) {
|
||||
case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
|
||||
case 3: ctx.transform(-1, 0, 0, -1, width, height ); break;
|
||||
case 4: ctx.transform(1, 0, 0, -1, 0, height ); break;
|
||||
case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
|
||||
case 6: ctx.transform(0, 1, -1, 0, height , 0); break;
|
||||
case 7: ctx.transform(0, -1, -1, 0, height , width); break;
|
||||
case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
|
||||
default: ctx.transform(1, 0, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
// draw image
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// export base64
|
||||
$img.attr('src', canvas.toDataURL());
|
||||
};
|
||||
|
||||
img.src = $img.attr('src');
|
||||
};
|
||||
|
||||
Fileinput.prototype.clear = function(e) {
|
||||
if (e) e.preventDefault()
|
||||
|
||||
this.$hidden.val('')
|
||||
this.$hidden.attr('name', this.name)
|
||||
if (this.options.clearName) this.$input.attr('name', '')
|
||||
|
||||
//ie8+ doesn't support changing the value of input with type=file so clone instead
|
||||
if (isIE) {
|
||||
var inputClone = this.$input.clone(true);
|
||||
this.$input.after(inputClone);
|
||||
this.$input.remove();
|
||||
this.$input = inputClone;
|
||||
} else {
|
||||
this.$input.val('')
|
||||
}
|
||||
|
||||
this.$preview.html('')
|
||||
this.$element.find('.fileinput-filename').text('')
|
||||
this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
|
||||
|
||||
if (e !== undefined) {
|
||||
this.$input.trigger('change')
|
||||
this.$element.trigger('clear.bs.fileinput')
|
||||
}
|
||||
},
|
||||
|
||||
Fileinput.prototype.reset = function() {
|
||||
this.clear()
|
||||
|
||||
this.$hidden.val(this.original.hiddenVal)
|
||||
this.$preview.html(this.original.preview)
|
||||
this.$element.find('.fileinput-filename').text('')
|
||||
|
||||
if (this.original.exists) this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
|
||||
else this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
|
||||
|
||||
this.$element.trigger('reseted.bs.fileinput')
|
||||
},
|
||||
|
||||
Fileinput.prototype.trigger = function(e) {
|
||||
this.$input.trigger('click')
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
|
||||
// FILEUPLOAD PLUGIN DEFINITION
|
||||
// ===========================
|
||||
|
||||
var old = $.fn.fileinput
|
||||
|
||||
$.fn.fileinput = function (options) {
|
||||
return this.each(function () {
|
||||
var $this = $(this),
|
||||
data = $this.data('bs.fileinput')
|
||||
if (!data) $this.data('bs.fileinput', (data = new Fileinput(this, options)))
|
||||
if (typeof options == 'string') data[options]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.fileinput.Constructor = Fileinput
|
||||
|
||||
|
||||
// FILEINPUT NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.fileinput.noConflict = function () {
|
||||
$.fn.fileinput = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// FILEUPLOAD DATA-API
|
||||
// ==================
|
||||
|
||||
$(document).on('click.fileinput.data-api', '[data-provides="fileinput"]', function (e) {
|
||||
var $this = $(this)
|
||||
if ($this.data('bs.fileinput')) return
|
||||
$this.fileinput($this.data())
|
||||
|
||||
var $target = $(e.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]');
|
||||
if ($target.length > 0) {
|
||||
e.preventDefault()
|
||||
$target.trigger('click.bs.fileinput')
|
||||
}
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
||||
@ -0,0 +1 @@
|
||||
.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-layout-pane{overflow:auto}.ui-layout-content{padding:10px;position:relative;overflow:auto;width:100%;border:0}.layout-child-container,.layout-content-container{padding:0;overflow:hidden}.layout-child-container{border:0}.layout-scroll{overflow:auto}.layout-hide{display:none}.ui-layout-resizer{background:#fafafa;border:1px solid #eee;border-width:0}.ui-layout-resizer-open-hover,.ui-layout-resizer-dragging{background:#fafafa}.ui-layout-resizer-dragging{border:1px solid #eee}.ui-layout-resizer-north-dragging,.ui-layout-resizer-south-dragging{border-width:1px 0}.ui-layout-resizer-west-dragging,.ui-layout-resizer-east-dragging{border-width:0 1px}.ui-layout-resizer-dragging-limit{background:#e1a4a4}.ui-layout-resizer-closed-hover{background:#ebd5aa}.ui-layout-resizer-north-sliding-hover{border-bottom-width:1px}.ui-layout-resizer-south-sliding-hover{border-top-width:1px}.ui-layout-resizer-west-sliding-hover{border-right-width:1px}.ui-layout-resizer-east-sliding-hover{border-left-width:1px}.ui-layout-toggler{border:1px solid #eee;background-color:#eee}.ui-layout-resizer-hover .ui-layout-toggler{opacity:1.00;filter:alpha(opacity=100)}.ui-layout-toggler-hover,.ui-layout-resizer-hover .ui-layout-toggler-hover{background-color:#FC6;opacity:1.00;filter:alpha(opacity=100)}.ui-layout-toggler-north,.ui-layout-toggler-south{border-width:0 1px}.ui-layout-toggler-west,.ui-layout-toggler-east{border-width:1px 0}.ui-layout-resizer-sliding .ui-layout-toggler{display:none}.ui-layout-toggler .ui-content{color:#666;font-size:12px;font-weight:bold;line-height:8px;width:100%;padding-bottom:.35ex}.ui-layout-toggler .ui-content .fa{line-height:8px}.ui-layout-toggler-north-closed .fa:before,.ui-layout-toggler-south-open .fa:before{content:"\f0d7"}.ui-layout-toggler-south-closed .fa:before,.ui-layout-toggler-north-open .fa:before{content:"\f0d8"}.ui-layout-toggler-west-closed .fa:before,.ui-layout-toggler-east-open .fa:before{content:"\f0da"}.ui-layout-toggler-east-closed .fa:before,.ui-layout-toggler-west-open .fa:before{content:"\f0d9"}.ui-layout-mask{border:none!important;padding:0!important;margin:0!important;overflow:hidden!important;position:absolute!important;opacity:0!important;filter:Alpha(Opacity="0")!important}.ui-layout-mask-inside-pane{top:0!important;left:0!important;width:100%!important;height:100%!important}@media print{html{height:auto!important;overflow:visible!important}body.ui-layout-container{position:static!important;top:auto!important;bottom:auto!important;left:auto!important;right:auto!important;_width:auto!important;_height:auto!important}.ui-layout-resizer,.ui-layout-toggler{display:none!important}.ui-layout-pane{border:none!important;background:transparent!important;position:relative!important;top:auto!important;bottom:auto!important;left:auto!important;right:auto!important;width:auto!important;height:auto!important;overflow:visible!important}}
|
||||