Estado base antes de integración Cognito.
Incluye admin web Spring Boot, API JWT para escáner y app Flutter qrscanner con login y escaneo de pases.
This commit is contained in:
+17
@@ -0,0 +1,17 @@
|
||||
/data/
|
||||
/target/
|
||||
**/target/
|
||||
/.idea/
|
||||
/.vscode/
|
||||
*.iml
|
||||
*.log
|
||||
/.mvn/
|
||||
/.DS_Store
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
**/.classpath
|
||||
**/.project
|
||||
**/.settings/
|
||||
effective-pom.xml
|
||||
**/effective-pom.xml
|
||||
@@ -0,0 +1,221 @@
|
||||
# Base Admin Web
|
||||
|
||||
Proyecto base de Spring Boot con Metronic, autenticacion local y estructura modular lista para reutilizar en nuevos paneles administrativos.
|
||||
|
||||
## Stack
|
||||
|
||||
- Spring Boot 4.0.6
|
||||
- Java 25
|
||||
- Spring Security
|
||||
- Thymeleaf
|
||||
- JPA / Hibernate
|
||||
- H2 en archivo para desarrollo rapido
|
||||
- PostgreSQL listo por perfil
|
||||
- JWT para autenticacion API de escaneo
|
||||
- Assets Metronic reutilizados desde `base-web`
|
||||
|
||||
## Estructura
|
||||
|
||||
- `base-admin-web-domain`: entidades y repositorios
|
||||
- `base-admin-web-application`: servicios y carga inicial
|
||||
- `base-admin-web-configuration`: seguridad, JWT y perfiles
|
||||
- `base-admin-web-web`: controladores y vistas Thymeleaf
|
||||
- `base-admin-web-jar`: punto de entrada ejecutable
|
||||
|
||||
## Usuarios iniciales
|
||||
|
||||
### Administrador (panel web)
|
||||
|
||||
- Usuario: `admin`
|
||||
- Password: `Admin123*`
|
||||
- Rol: `ROLE_ADMIN`
|
||||
- Acceso: login web en `/login`, dashboard y modulo de codigos pase
|
||||
|
||||
Variables de entorno:
|
||||
|
||||
- `APP_ADMIN_USERNAME`
|
||||
- `APP_ADMIN_PASSWORD`
|
||||
- `APP_ADMIN_DISPLAY_NAME`
|
||||
|
||||
### Escaneador (API)
|
||||
|
||||
- Usuario: `scanner`
|
||||
- Password: `Scanner123*`
|
||||
- Rol: `ROLE_SCANNER`
|
||||
- Acceso: solo login por API y escaneo de codigos pase
|
||||
|
||||
Variables de entorno:
|
||||
|
||||
- `APP_SCANNER_USERNAME`
|
||||
- `APP_SCANNER_PASSWORD`
|
||||
- `APP_SCANNER_DISPLAY_NAME`
|
||||
|
||||
## Modulo de codigos pase
|
||||
|
||||
Panel administrativo para dar de alta y consultar codigos pase.
|
||||
|
||||
- URL: `http://localhost:8080/admin/pass-codes`
|
||||
- Tambien accesible desde el boton **Codigos pase** en el dashboard
|
||||
- Alta por nombre; el sistema genera un codigo aleatorio de 10 caracteres
|
||||
- Vista con tabla de estatus, escaneo y fecha de creacion
|
||||
- Modal Metronic para ver el QR de cada codigo
|
||||
- Al cerrar el modal, la lista se actualiza automaticamente por si el codigo fue utilizado
|
||||
|
||||
Campos del codigo pase:
|
||||
|
||||
- Nombre
|
||||
- Codigo aleatorio
|
||||
- Fecha de creacion
|
||||
- Estatus (`ACTIVO` / `UTILIZADO`)
|
||||
- Indicador de escaneado
|
||||
- Fecha de escaneo
|
||||
|
||||
## API
|
||||
|
||||
### Login escaner
|
||||
|
||||
```http
|
||||
POST /api/auth/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "scanner",
|
||||
"password": "Scanner123*"
|
||||
}
|
||||
```
|
||||
|
||||
Respuesta exitosa:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"accessToken": "eyJhbG...",
|
||||
"tokenType": "Bearer",
|
||||
"expiresIn": 28800,
|
||||
"username": "scanner",
|
||||
"roles": ["ROLE_SCANNER"]
|
||||
}
|
||||
```
|
||||
|
||||
Solo usuarios con rol `SCANNER` pueden iniciar sesion por API. El usuario `admin` no puede autenticarse por este endpoint.
|
||||
|
||||
### Escanear codigo pase
|
||||
|
||||
```http
|
||||
POST /api/pass-codes/scan
|
||||
Authorization: Bearer eyJhbG...
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"code": "K7P2M9XQ4R"
|
||||
}
|
||||
```
|
||||
|
||||
Marca el codigo como escaneado y cambia su estatus a `UTILIZADO`.
|
||||
|
||||
### Listado para el panel (requiere sesion admin)
|
||||
|
||||
```http
|
||||
GET /admin/pass-codes/list
|
||||
```
|
||||
|
||||
Devuelve JSON con los codigos registrados. Se usa internamente para refrescar la tabla del panel.
|
||||
|
||||
## Arranque local
|
||||
|
||||
Desde la raiz del proyecto:
|
||||
|
||||
```bash
|
||||
./run-local.sh
|
||||
```
|
||||
|
||||
El script:
|
||||
|
||||
- Detecta automaticamente Temurin/Java 25
|
||||
- Compila todos los modulos del proyecto
|
||||
- Arranca el modulo ejecutable `base-admin-web-jar`
|
||||
- Muestra el perfil activo y la base de datos en uso
|
||||
|
||||
Si `SPRING_PROFILES_ACTIVE` incluye `postgres`, el script intenta levantar automaticamente el contenedor definido en `docker-compose-postgres.local.yml` antes de iniciar la aplicacion.
|
||||
|
||||
Tambien puedes ejecutar:
|
||||
|
||||
```bash
|
||||
mvn test
|
||||
mvn -pl base-admin-web-jar -am -DskipTests install
|
||||
mvn -pl base-admin-web-jar spring-boot:run
|
||||
```
|
||||
|
||||
Aplicacion:
|
||||
|
||||
- Login: `http://localhost:8080/login`
|
||||
- Dashboard: `http://localhost:8080/dashboard`
|
||||
- Codigos pase: `http://localhost:8080/admin/pass-codes`
|
||||
- H2 Console: `http://localhost:8080/h2-console`
|
||||
|
||||
## Perfiles
|
||||
|
||||
- `dev`: H2 en archivo (`./data/h2/`), consola H2 habilitada, datos persistentes entre reinicios
|
||||
- `prod`: cache Thymeleaf y H2 console deshabilitada
|
||||
- `postgres`: datasource PostgreSQL, datos persistentes en el servidor o volumen Docker
|
||||
- `test`: H2 en memoria con `create-drop`, usado solo por `mvn test`
|
||||
|
||||
Con `postgres`, `run-local.sh` intenta arrancar Docker Compose automaticamente.
|
||||
|
||||
Ejemplo con PostgreSQL local:
|
||||
|
||||
```bash
|
||||
SPRING_PROFILES_ACTIVE=postgres ./run-local.sh
|
||||
```
|
||||
|
||||
Ejemplo con PostgreSQL remoto:
|
||||
|
||||
```bash
|
||||
SPRING_PROFILES_ACTIVE=postgres \
|
||||
SPRING_DATASOURCE_URL=jdbc:postgresql://TU_SERVIDOR:5432/base_admin_web \
|
||||
SPRING_DATASOURCE_USERNAME=tu_usuario \
|
||||
SPRING_DATASOURCE_PASSWORD=tu_password \
|
||||
./run-local.sh
|
||||
```
|
||||
|
||||
## Variables utiles
|
||||
|
||||
### Aplicacion
|
||||
|
||||
- `SERVER_PORT`
|
||||
- `SPRING_PROFILES_ACTIVE`
|
||||
- `APP_TITLE`
|
||||
|
||||
### Base de datos
|
||||
|
||||
- `SPRING_DATASOURCE_URL`
|
||||
- `SPRING_DATASOURCE_USERNAME`
|
||||
- `SPRING_DATASOURCE_PASSWORD`
|
||||
- `SPRING_JPA_HIBERNATE_DDL_AUTO`
|
||||
|
||||
### JWT API
|
||||
|
||||
- `APP_JWT_SECRET` (minimo 32 caracteres)
|
||||
- `APP_JWT_EXPIRATION_HOURS`
|
||||
|
||||
## Seguridad
|
||||
|
||||
- Panel web: autenticacion por formulario con usuarios en base de datos
|
||||
- API de escaneo: autenticacion stateless con JWT
|
||||
- `/admin/**` y `/dashboard`: requieren rol `ADMIN`
|
||||
- `/api/pass-codes/scan`: requiere rol `SCANNER` y token Bearer
|
||||
- `/api/auth/login`: publico, pero solo emite token a usuarios `SCANNER`
|
||||
|
||||
## Objetivo de esta base
|
||||
|
||||
Esta base deja resuelto lo minimo para arrancar nuevos proyectos internos:
|
||||
|
||||
- autenticacion local funcional para administradores
|
||||
- autenticacion API para escaneo movil o externo
|
||||
- layout inicial con Metronic
|
||||
- dashboard simple
|
||||
- modulo de codigos pase con QR y API de escaneo
|
||||
- estructura modular limpia
|
||||
- soporte rapido para H2 y PostgreSQL
|
||||
|
||||
El dashboard actual se mantiene deliberadamente sencillo para servir como punto de partida para futuras integraciones.
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>mx.gob.slp.baseadminweb</groupId>
|
||||
<artifactId>base-admin-web</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>base-admin-web-application</artifactId>
|
||||
<name>base-admin-web-application</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mx.gob.slp.baseadminweb</groupId>
|
||||
<artifactId>base-admin-web-domain</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package mx.gob.slp.baseadminweb.application.config;
|
||||
|
||||
import mx.gob.slp.baseadminweb.domain.model.AppUser;
|
||||
import mx.gob.slp.baseadminweb.domain.model.Role;
|
||||
import mx.gob.slp.baseadminweb.domain.repository.AppUserRepository;
|
||||
import mx.gob.slp.baseadminweb.domain.repository.RoleRepository;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class InitialDataLoader implements CommandLineRunner {
|
||||
|
||||
private static final String ADMIN_ROLE = "ROLE_ADMIN";
|
||||
private static final String SCANNER_ROLE = "ROLE_SCANNER";
|
||||
|
||||
private final RoleRepository roleRepository;
|
||||
private final AppUserRepository appUserRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final String adminUsername;
|
||||
private final String adminPassword;
|
||||
private final String adminDisplayName;
|
||||
private final String scannerUsername;
|
||||
private final String scannerPassword;
|
||||
private final String scannerDisplayName;
|
||||
|
||||
public InitialDataLoader(RoleRepository roleRepository,
|
||||
AppUserRepository appUserRepository,
|
||||
PasswordEncoder passwordEncoder,
|
||||
@Value("${app.admin.username:admin}") String adminUsername,
|
||||
@Value("${app.admin.password:Admin123*}") String adminPassword,
|
||||
@Value("${app.admin.display-name:Administrador Base}") String adminDisplayName,
|
||||
@Value("${app.scanner.username:scanner}") String scannerUsername,
|
||||
@Value("${app.scanner.password:Scanner123*}") String scannerPassword,
|
||||
@Value("${app.scanner.display-name:Escaneador}") String scannerDisplayName) {
|
||||
this.roleRepository = roleRepository;
|
||||
this.appUserRepository = appUserRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.adminUsername = adminUsername;
|
||||
this.adminPassword = adminPassword;
|
||||
this.adminDisplayName = adminDisplayName;
|
||||
this.scannerUsername = scannerUsername;
|
||||
this.scannerPassword = scannerPassword;
|
||||
this.scannerDisplayName = scannerDisplayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
Role adminRole = roleRepository.findByName(ADMIN_ROLE)
|
||||
.orElseGet(() -> roleRepository.save(new Role(ADMIN_ROLE, "Administrador del sistema")));
|
||||
|
||||
appUserRepository.findByUsername(adminUsername).orElseGet(() -> {
|
||||
AppUser admin = new AppUser(
|
||||
adminUsername,
|
||||
passwordEncoder.encode(adminPassword),
|
||||
adminDisplayName,
|
||||
true
|
||||
);
|
||||
admin.addRole(adminRole);
|
||||
return appUserRepository.save(admin);
|
||||
});
|
||||
|
||||
Role scannerRole = roleRepository.findByName(SCANNER_ROLE)
|
||||
.orElseGet(() -> roleRepository.save(new Role(SCANNER_ROLE, "Escaneo de codigos pase")));
|
||||
|
||||
appUserRepository.findByUsername(scannerUsername).orElseGet(() -> {
|
||||
AppUser scanner = new AppUser(
|
||||
scannerUsername,
|
||||
passwordEncoder.encode(scannerPassword),
|
||||
scannerDisplayName,
|
||||
true
|
||||
);
|
||||
scanner.addRole(scannerRole);
|
||||
return appUserRepository.save(scanner);
|
||||
});
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package mx.gob.slp.baseadminweb.application.service;
|
||||
|
||||
import mx.gob.slp.baseadminweb.domain.repository.AppUserRepository;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AppUserDetailsService implements UserDetailsService {
|
||||
|
||||
private final AppUserRepository appUserRepository;
|
||||
|
||||
public AppUserDetailsService(AppUserRepository appUserRepository) {
|
||||
this.appUserRepository = appUserRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
return appUserRepository.findByUsername(username)
|
||||
.orElseThrow(() -> new UsernameNotFoundException("Usuario no encontrado: " + username));
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package mx.gob.slp.baseadminweb.application.service;
|
||||
|
||||
import mx.gob.slp.baseadminweb.domain.model.PassCode;
|
||||
import mx.gob.slp.baseadminweb.domain.repository.PassCodeRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class PassCodeService {
|
||||
|
||||
private static final String CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||
private static final int CODE_LENGTH = 10;
|
||||
private static final int MAX_GENERATION_ATTEMPTS = 20;
|
||||
|
||||
private final PassCodeRepository passCodeRepository;
|
||||
private final SecureRandom secureRandom = new SecureRandom();
|
||||
|
||||
public PassCodeService(PassCodeRepository passCodeRepository) {
|
||||
this.passCodeRepository = passCodeRepository;
|
||||
}
|
||||
|
||||
public List<PassCode> findAll() {
|
||||
return passCodeRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public PassCode create(String name) {
|
||||
String trimmedName = name == null ? "" : name.trim();
|
||||
if (trimmedName.isEmpty()) {
|
||||
throw new IllegalArgumentException("El nombre del codigo pase es obligatorio.");
|
||||
}
|
||||
|
||||
PassCode passCode = new PassCode(trimmedName, generateUniqueCode(), Instant.now());
|
||||
return passCodeRepository.save(passCode);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public PassCode scan(String code) {
|
||||
String trimmedCode = code == null ? "" : code.trim().toUpperCase();
|
||||
if (trimmedCode.isEmpty()) {
|
||||
throw new IllegalArgumentException("El codigo es obligatorio.");
|
||||
}
|
||||
|
||||
PassCode passCode = passCodeRepository.findByCode(trimmedCode)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Codigo pase no encontrado."));
|
||||
|
||||
if (passCode.isScanned()) {
|
||||
throw new IllegalStateException("El codigo pase ya fue escaneado.");
|
||||
}
|
||||
|
||||
passCode.markAsUsed(Instant.now());
|
||||
return passCodeRepository.save(passCode);
|
||||
}
|
||||
|
||||
private String generateUniqueCode() {
|
||||
for (int attempt = 0; attempt < MAX_GENERATION_ATTEMPTS; attempt++) {
|
||||
String candidate = randomCode();
|
||||
if (!passCodeRepository.existsByCode(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No fue posible generar un codigo unico.");
|
||||
}
|
||||
|
||||
private String randomCode() {
|
||||
StringBuilder builder = new StringBuilder(CODE_LENGTH);
|
||||
for (int i = 0; i < CODE_LENGTH; i++) {
|
||||
int index = secureRandom.nextInt(CODE_ALPHABET.length());
|
||||
builder.append(CODE_ALPHABET.charAt(index));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>mx.gob.slp.baseadminweb</groupId>
|
||||
<artifactId>base-admin-web</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>base-admin-web-configuration</artifactId>
|
||||
<name>base-admin-web-configuration</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mx.gob.slp.baseadminweb</groupId>
|
||||
<artifactId>base-admin-web-application</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package mx.gob.slp.baseadminweb.configuration.security;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JwsHeader;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class ApiAuthService {
|
||||
|
||||
private static final String SCANNER_ROLE = "ROLE_SCANNER";
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final JwtEncoder jwtEncoder;
|
||||
private final JwtProperties jwtProperties;
|
||||
|
||||
public ApiAuthService(AuthenticationManager authenticationManager,
|
||||
JwtEncoder jwtEncoder,
|
||||
JwtProperties jwtProperties) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
this.jwtEncoder = jwtEncoder;
|
||||
this.jwtProperties = jwtProperties;
|
||||
}
|
||||
|
||||
public ApiLoginResponse login(String username, String password) {
|
||||
Authentication authentication = authenticationManager.authenticate(
|
||||
new UsernamePasswordAuthenticationToken(username, password));
|
||||
|
||||
List<String> roles = authentication.getAuthorities().stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.toList();
|
||||
|
||||
if (roles.stream().noneMatch(SCANNER_ROLE::equals)) {
|
||||
throw new BadCredentialsException("El usuario no tiene permisos para escanear codigos.");
|
||||
}
|
||||
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = issuedAt.plusSeconds(jwtProperties.getExpirationHours() * 3600L);
|
||||
|
||||
JwtClaimsSet claims = JwtClaimsSet.builder()
|
||||
.subject(authentication.getName())
|
||||
.issuedAt(issuedAt)
|
||||
.expiresAt(expiresAt)
|
||||
.claim("roles", roles)
|
||||
.build();
|
||||
|
||||
JwsHeader header = JwsHeader.with(MacAlgorithm.HS256).build();
|
||||
String accessToken = jwtEncoder.encode(JwtEncoderParameters.from(header, claims)).getTokenValue();
|
||||
|
||||
return new ApiLoginResponse(
|
||||
accessToken,
|
||||
"Bearer",
|
||||
jwtProperties.getExpirationHours() * 3600L,
|
||||
authentication.getName(),
|
||||
roles
|
||||
);
|
||||
}
|
||||
|
||||
public record ApiLoginResponse(
|
||||
String accessToken,
|
||||
String tokenType,
|
||||
long expiresIn,
|
||||
String username,
|
||||
List<String> roles
|
||||
) {
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package mx.gob.slp.baseadminweb.configuration.security;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
@Order(1)
|
||||
public class ApiSecurityConfig {
|
||||
|
||||
private final JwtAuthenticationConverter jwtAuthenticationConverter;
|
||||
|
||||
public ApiSecurityConfig(JwtAuthenticationConverter jwtAuthenticationConverter) {
|
||||
this.jwtAuthenticationConverter = jwtAuthenticationConverter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain apiSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.securityMatcher("/api/**")
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(authorize -> authorize
|
||||
.requestMatchers("/api/auth/login").permitAll()
|
||||
.requestMatchers("/api/pass-codes/scan").hasRole("SCANNER")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt
|
||||
.jwtAuthenticationConverter(jwtAuthenticationConverter)));
|
||||
|
||||
return http.build();
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package mx.gob.slp.baseadminweb.configuration.security;
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
|
||||
|
||||
import com.nimbusds.jose.JWSAlgorithm;
|
||||
import com.nimbusds.jose.jwk.JWKSet;
|
||||
import com.nimbusds.jose.jwk.OctetSequenceKey;
|
||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(JwtProperties.class)
|
||||
public class JwtConfig {
|
||||
|
||||
@Bean
|
||||
JwtEncoder jwtEncoder(JwtProperties jwtProperties) {
|
||||
OctetSequenceKey jwk = new OctetSequenceKey.Builder(jwtProperties.getSecret().getBytes(StandardCharsets.UTF_8))
|
||||
.algorithm(JWSAlgorithm.HS256)
|
||||
.build();
|
||||
return new NimbusJwtEncoder(new ImmutableJWKSet<>(new JWKSet(jwk)));
|
||||
}
|
||||
|
||||
@Bean
|
||||
JwtDecoder jwtDecoder(JwtProperties jwtProperties) {
|
||||
return NimbusJwtDecoder.withSecretKey(secretKey(jwtProperties))
|
||||
.macAlgorithm(MacAlgorithm.HS256)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
JwtAuthenticationConverter jwtAuthenticationConverter() {
|
||||
JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter();
|
||||
authoritiesConverter.setAuthoritiesClaimName("roles");
|
||||
authoritiesConverter.setAuthorityPrefix("");
|
||||
|
||||
JwtAuthenticationConverter authenticationConverter = new JwtAuthenticationConverter();
|
||||
authenticationConverter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
|
||||
return authenticationConverter;
|
||||
}
|
||||
|
||||
private SecretKey secretKey(JwtProperties jwtProperties) {
|
||||
return new SecretKeySpec(jwtProperties.getSecret().getBytes(), "HmacSHA256");
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package mx.gob.slp.baseadminweb.configuration.security;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "app.jwt")
|
||||
public class JwtProperties {
|
||||
|
||||
private String secret = "base-admin-web-dev-secret-change-me-32chars!!";
|
||||
private int expirationHours = 8;
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public int getExpirationHours() {
|
||||
return expirationHours;
|
||||
}
|
||||
|
||||
public void setExpirationHours(int expirationHours) {
|
||||
this.expirationHours = expirationHours;
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package mx.gob.slp.baseadminweb.configuration.security;
|
||||
|
||||
import mx.gob.slp.baseadminweb.application.service.AppUserDetailsService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity
|
||||
@Order(2)
|
||||
public class SecurityConfig {
|
||||
|
||||
private final AppUserDetailsService appUserDetailsService;
|
||||
|
||||
public SecurityConfig(AppUserDetailsService appUserDetailsService) {
|
||||
this.appUserDetailsService = appUserDetailsService;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.securityMatcher(request -> !request.getRequestURI().startsWith("/api/"))
|
||||
.authorizeHttpRequests(authorize -> authorize
|
||||
.requestMatchers("/assets/**", "/login", "/error").permitAll()
|
||||
.requestMatchers("/h2-console/**").permitAll()
|
||||
.requestMatchers("/admin/**", "/dashboard").hasRole("ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.formLogin(form -> form
|
||||
.loginPage("/login")
|
||||
.defaultSuccessUrl("/dashboard", true)
|
||||
.failureUrl("/login?error")
|
||||
.permitAll()
|
||||
)
|
||||
.logout(logout -> logout
|
||||
.logoutUrl("/logout")
|
||||
.logoutSuccessUrl("/login?logout")
|
||||
.invalidateHttpSession(true)
|
||||
.deleteCookies("JSESSIONID")
|
||||
)
|
||||
.headers(headers -> headers.frameOptions(frame -> frame.sameOrigin()))
|
||||
.userDetailsService(appUserDetailsService)
|
||||
.rememberMe(Customizer.withDefaults());
|
||||
|
||||
http.csrf(csrf -> csrf.ignoringRequestMatchers("/h2-console/**"));
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
|
||||
return authenticationConfiguration.getAuthenticationManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package mx.gob.slp.baseadminweb.configuration.security;
|
||||
|
||||
import org.apache.catalina.session.StandardManager;
|
||||
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class TomcatConfig {
|
||||
|
||||
@Bean
|
||||
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
|
||||
return factory -> factory.addContextCustomizers(context -> {
|
||||
StandardManager manager = new StandardManager();
|
||||
manager.setPathname(null);
|
||||
context.setManager(manager);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
.load {
|
||||
width:100%;
|
||||
height:100%;
|
||||
/* background: #313131 url('assets/images/gif/load.gif') no-repeat center; */
|
||||
background: #313131;
|
||||
opacity:.50;
|
||||
top:0;
|
||||
left:0;
|
||||
position:fixed;
|
||||
overflow:auto;
|
||||
z-index: 999999999999 !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.load .effect-1,
|
||||
.load .effect-2 {
|
||||
display: unset;
|
||||
z-index: 999999999999 !important;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 3px solid transparent;
|
||||
border-left: 3px solid rgb(41, 4, 110);
|
||||
border-radius: 50%;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.load .effect-1 {
|
||||
animation: rotate 1s ease infinite;
|
||||
}
|
||||
|
||||
.load .effect-2 {
|
||||
animation: rotateOpacity 1s ease infinite 0.1s;
|
||||
}
|
||||
|
||||
.load .effect-3 {
|
||||
position: absolute;
|
||||
z-index: 999999999999 !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 3px solid transparent;
|
||||
border-left: 3px solid rgb(41, 4, 110);
|
||||
-webkit-animation: rotateOpacity 1s ease infinite 0.2s;
|
||||
animation: rotateOpacity 1s ease infinite 0.2s;
|
||||
border-radius: 50%;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.load .effects {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.load-logo {
|
||||
position: absolute;
|
||||
z-index: 999999999999 !important;
|
||||
left: calc(50% - 45px);
|
||||
top: 40%;
|
||||
}
|
||||
|
||||
.loader {
|
||||
position: absolute;
|
||||
z-index: 999999999999 !important;
|
||||
left: calc(50% - 35px);
|
||||
margin: inherit !important;
|
||||
top: 50%;
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
border-radius: 50%;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
border: 3px solid transparent;
|
||||
}
|
||||
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(1turn);
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotateOpacity {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(1turn);
|
||||
transform: rotate(1turn);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Base.Autocomplete 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Autocomplete : {
|
||||
|
||||
//Los Datos debende vernir en un Json {id: '', label : ''}
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.autocomplete);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
method: 'POST',
|
||||
wrapperClass: "bc-wrapper",
|
||||
menuClass: "bc-menu",
|
||||
idField: true, //idFieldName set value to (idFieldName options) if idField=false
|
||||
minLength: 3,
|
||||
dataParams: {},
|
||||
formParams: {},
|
||||
clearIdFieldOnKeyUp: true
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return $(selector).bootcomplete(finallyOptions);
|
||||
},
|
||||
|
||||
_qxAutocomplete : function (autocomplete) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Autocomplete 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxAutocomplete = function () {
|
||||
|
||||
var autocomplete = this;
|
||||
|
||||
return Base.Modal._qxAutocomplete(autocomplete);
|
||||
}
|
||||
});
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
AwsUpload: {
|
||||
|
||||
config: function(){
|
||||
AWS.config.update({
|
||||
accessKeyId : app.aws.accessKey,
|
||||
secretAccessKey : app.aws.secretKey,
|
||||
correctClockSkew: true,
|
||||
});
|
||||
AWS.config.region = app.aws.region;
|
||||
},
|
||||
|
||||
/* options:{
|
||||
directory:String,
|
||||
file:File,
|
||||
callBack: function(data){}
|
||||
}*/
|
||||
upload: function (options) {
|
||||
|
||||
Base.AwsUpload.config();
|
||||
|
||||
var upFile=options.file;
|
||||
var bucket = new AWS.S3({params: {Bucket: app.aws.buket}});
|
||||
|
||||
var ext = "";
|
||||
if ((upFile.name).split('.').length > 1) {
|
||||
ext = "." + (upFile.name).split('.')[(upFile.name).split('.').length - 1];
|
||||
}
|
||||
|
||||
var directory = options.directory ? options.directory : "private";
|
||||
|
||||
var fileName= directory+"/" + crypto.randomUUID() + ext;
|
||||
|
||||
var uploadParams = {Key:fileName, ContentType: upFile.type, Body: upFile};
|
||||
|
||||
|
||||
bucket.upload(uploadParams, function(err, data) {
|
||||
if(err) {
|
||||
alert('Error subiendo Ficheros a amazon');
|
||||
console.log("error subiendo ficheros a amazon", err);
|
||||
Base.Loading.hide();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(options.callBack != undefined && options.callBack != null && $.isFunction(options.callBack)) {
|
||||
|
||||
var url = data.Location;
|
||||
var fileName = url.split('com')[url.split('com').length - 1];
|
||||
|
||||
return options.callBack(fileName);
|
||||
}
|
||||
|
||||
console.log('Successfully Uploaded!');
|
||||
|
||||
}).on('httpUploadProgress', function(progress) {
|
||||
var uploaded = parseInt((progress.loaded * 100) / progress.total);
|
||||
$("progress").attr('value', uploaded);
|
||||
});
|
||||
},
|
||||
|
||||
_qxAwsUpload: function (box) {
|
||||
|
||||
return {
|
||||
|
||||
ver: function () {
|
||||
|
||||
console.log("Base.AwsUpload 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxAwsUpload = function () {
|
||||
|
||||
var awsUpload = this;
|
||||
|
||||
return Base.Box._qxAwsUpload(awsUpload);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Loading: {
|
||||
|
||||
showTimeout: function(options){
|
||||
if (document.getElementById('loaddiv')) {
|
||||
document.getElementById('loaddiv').className = 'load';
|
||||
setTimeout(options.calback, 50);
|
||||
}
|
||||
},
|
||||
|
||||
show: function (message=null) {
|
||||
if (document.getElementById('loaddiv')) {
|
||||
document.getElementById('loaddiv').className = 'load';
|
||||
}
|
||||
},
|
||||
showInBlock: function (target, options) {
|
||||
if (document.getElementById('loaddiv')) {
|
||||
document.getElementById('loaddiv').className = 'load';
|
||||
}
|
||||
},
|
||||
hide: function(){
|
||||
if (document.getElementById('loaddiv')) {
|
||||
document.getElementById('loaddiv').className = '';
|
||||
}
|
||||
},
|
||||
|
||||
_qxLoading: function (box) {
|
||||
|
||||
return {
|
||||
|
||||
ver: function () {
|
||||
|
||||
console.log("Base.Loading 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxLoading = function () {
|
||||
|
||||
var loading = this;
|
||||
|
||||
return Base.Box._qxLoading(loading);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* BaseJS 1.0
|
||||
*/
|
||||
$(function () {
|
||||
Base = {
|
||||
|
||||
locale: {
|
||||
language: 'es',
|
||||
},
|
||||
|
||||
i18n: {
|
||||
datatable: {},
|
||||
buttons: {},
|
||||
modal: {},
|
||||
date: {},
|
||||
box: {},
|
||||
print: {},
|
||||
kanban: {},
|
||||
typedjs: {},
|
||||
touchspin: {},
|
||||
loading: {}
|
||||
},
|
||||
|
||||
month: {
|
||||
fullNames: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio",
|
||||
"Agosto", "Septiembre", "Octubre", "Noviembre", "Deciembre"],
|
||||
acronyms: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dec"]
|
||||
},
|
||||
|
||||
daysOfWeek: {
|
||||
fullNames: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],
|
||||
acronyms: ["Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sa"]
|
||||
},
|
||||
|
||||
TempCode: {},
|
||||
|
||||
initComponents: function () {
|
||||
|
||||
//https://momentjs.com/docs/#/i18n/
|
||||
moment.locale(Base.locale.language);
|
||||
moment.updateLocale('es', {
|
||||
months: Base.month.fullNames,
|
||||
monthsShort: Base.month.acronyms,
|
||||
weekdays: Base.daysOfWeek.fullNames,
|
||||
weekdaysShort: Base.daysOfWeek.acronyms,
|
||||
weekdaysMin: Base.daysOfWeek.acronyms
|
||||
});
|
||||
|
||||
Base.Select.create('.base-select-mth8', {});
|
||||
Base.Date.create('.base-date-mth8', {});
|
||||
|
||||
$(document).on('select2:open', () => {
|
||||
let allFound = document.querySelectorAll('.select2-container--open .select2-search__field');
|
||||
allFound[allFound.length - 1].focus();
|
||||
});
|
||||
|
||||
//Gedux.markMenuActive();
|
||||
Base._deleteConfirmSimple();
|
||||
// Gedux.hiddenToolMenu();
|
||||
//Base._makeButtons();
|
||||
},
|
||||
|
||||
showFlashMessageFromServer: function (geduxFlashMessages) {
|
||||
|
||||
if (undefined != geduxFlashMessages && null != geduxFlashMessages) {
|
||||
|
||||
geduxFlashMessages.forEach(function (object, idx) {
|
||||
|
||||
let typeMessage = object.showType;
|
||||
let classMessage = object.classMessage;
|
||||
let message = object.message;
|
||||
|
||||
if (typeMessage == 'SIMPLE') {
|
||||
Base.Message.flash(message, classMessage);
|
||||
} else {
|
||||
alert("Mensaje Flash " + typeMessage + " NO Soportado");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_loadingGlobal: null,
|
||||
|
||||
isSecurityAccessFor: function (chkRoles) {
|
||||
|
||||
if (chkRoles == 'ALL') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (app.user.roles.indexOf('ROLE_ROOT') >= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (null == chkRoles || chkRoles == undefined) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Array.isArray(chkRoles)) {
|
||||
|
||||
for (var i = 0; i < chkRoles.length; i++) {
|
||||
|
||||
if (app.user.roles.indexOf(chkRoles[i]) > 0) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return (app.user.roles.indexOf(chkRoles) >= 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
guid: function () {
|
||||
return Base._s4() + Base._s4() + '-' + Base._s4() + '-' + Base._s4() + '-' +
|
||||
Base._s4() + '-' + Base._s4() + Base._s4() + Base._s4();
|
||||
},
|
||||
|
||||
localeConfig: function (options) {
|
||||
|
||||
Base.locale = $.extend(true, Base.locale, options);
|
||||
},
|
||||
|
||||
loadLanguage: function (baseUrlScript, reload) {
|
||||
|
||||
$.cookie.json = true;
|
||||
|
||||
if (reload || $.cookie('base_language') == undefined) {
|
||||
Base._readLanguage(baseUrlScript);
|
||||
} else {
|
||||
Base.i18n = $.cookie('base_language');
|
||||
}
|
||||
},
|
||||
downloadFile: function (url, fileName) {
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
cache: false,
|
||||
xhr: function () {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 2) {
|
||||
if (xhr.status == 200) {
|
||||
xhr.responseType = "blob";
|
||||
} else {
|
||||
xhr.responseType = "text";
|
||||
}
|
||||
}
|
||||
};
|
||||
return xhr;
|
||||
},
|
||||
success: function (data) {
|
||||
//Convert the Byte Data to BLOB object.
|
||||
var blob = new Blob([data], {type: "application/octetstream"});
|
||||
|
||||
//Check the Browser type and download the File.
|
||||
var isIE = false || !!document.documentMode;
|
||||
if (isIE) {
|
||||
window.navigator.msSaveBlob(blob, fileName);
|
||||
} else {
|
||||
console.log("entrooo a descargar")
|
||||
console.log("url", url)
|
||||
console.log("fileName", fileName)
|
||||
var url = window.URL || window.webkitURL;
|
||||
link = url.createObjectURL(blob);
|
||||
var a = $("<a />");
|
||||
a.attr("download", fileName);
|
||||
a.attr("href", link);
|
||||
$("body").append(a);
|
||||
a[0].click();
|
||||
$("body").remove(a);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
TempCode: {},
|
||||
ajax: function (url, data, callback, config) {
|
||||
|
||||
if (typeof callback != 'function') {
|
||||
|
||||
config = callback;
|
||||
} else if (typeof config == 'undefined') {
|
||||
config = {};
|
||||
}
|
||||
|
||||
var default_config = {
|
||||
url: url,
|
||||
async: false,
|
||||
type: 'POST',
|
||||
contentType: 'application/json; charset=UTF-8',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify(data),
|
||||
error: function (response, statusText) {
|
||||
return false;
|
||||
},
|
||||
dataFilter: function (data, type) {
|
||||
|
||||
return data;
|
||||
},
|
||||
success: callback
|
||||
};
|
||||
|
||||
$().extend(true, default_config, config);
|
||||
|
||||
$.ajax(default_config);
|
||||
},
|
||||
|
||||
_readLanguage: function (baseUrlScript) {
|
||||
|
||||
$.ajax({
|
||||
url: baseUrlScript + "/i18n/" + Base.locale.language + ".json",
|
||||
dataType: "json",
|
||||
cache: true,
|
||||
|
||||
}).done(function (data) {
|
||||
|
||||
Base.i18n = $.extend(true, Base.i18n, data);
|
||||
$.cookie("base_language", Base.i18n, {expires: 7, path: '/'});
|
||||
|
||||
}).fail(function (jqXHR, textStatus, errorThrown) {
|
||||
|
||||
console.log(errorThrown);
|
||||
});
|
||||
},
|
||||
|
||||
_s4: function () {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
},
|
||||
|
||||
_deleteConfirmSimple: function () {
|
||||
|
||||
$.each($('.btn_simple_delete_confirm'), function (i, obj) {
|
||||
|
||||
var url = $(obj).attr('uriAction');
|
||||
var messageDel = $(obj).attr('messageDel');
|
||||
if (messageDel == undefined || messageDel == "") {
|
||||
messageDel = "¿Desea realmente eliminar el elemento?";
|
||||
}
|
||||
|
||||
$(obj).click(function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Base.Alert.custom({
|
||||
title: "Confirmado eliminación",
|
||||
text: messageDel,
|
||||
type: "question",
|
||||
confirmButtonText: "Acepto",
|
||||
showCancelButton: true,
|
||||
cancelButtonText: "Cancelar",
|
||||
callBackThen: function (result) {
|
||||
|
||||
if (result.isConfirmed) {
|
||||
window.location = url;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_makeButtons: function () {
|
||||
|
||||
$('[data-toggle=confirmation-submit]').confirmation({
|
||||
rootSelector: '[data-toggle=confirmation-submit]',
|
||||
// other options
|
||||
});
|
||||
|
||||
$('[data-toggle=confirmation-delete]').confirmation({
|
||||
rootSelector: '[data-toggle=confirmation-delete]',
|
||||
// other options
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
/** TO ADD COMPONENT IN OTHER FILE.JS
|
||||
* Base.Component [ver] (Example: 1.0)
|
||||
*
|
||||
* Requiere
|
||||
* Base [ver] (Example: 1.0)
|
||||
* ...
|
||||
*/
|
||||
// $(function() {
|
||||
// $.extend(Base, {
|
||||
// Component = {
|
||||
// create: function (selector, options) {},
|
||||
//
|
||||
// _qxComponent : function (object) {
|
||||
//
|
||||
// return {
|
||||
//
|
||||
// ver : function () {
|
||||
//
|
||||
// console.log("Base.Component 1.0");
|
||||
// console.log("Requiere: Base 1.0; Base.OtherComponent 1.0");
|
||||
// },
|
||||
//
|
||||
// otherfunction: function (param1, param2) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// });
|
||||
//
|
||||
// //Para hacer llamadas a funciones extendidas: $(selector).Component().function()
|
||||
// $.fn.QxComponent = function () {
|
||||
//
|
||||
// var object = this;
|
||||
//
|
||||
// return Base.Component.qxComponent(object);
|
||||
// }
|
||||
// });
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
PopupNearby: {
|
||||
|
||||
//options
|
||||
// {
|
||||
// idElementToDisplayPopup: "idElement",
|
||||
// title: "titulo",
|
||||
// message: "mesage",
|
||||
// buttons = {
|
||||
// accept: {
|
||||
// label: "Aceptar",
|
||||
// callback: function(){
|
||||
// }
|
||||
// },
|
||||
// cancel: {
|
||||
// label: "Cancelar",
|
||||
// callback: function(){
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
Start: function (options) {
|
||||
|
||||
//elementToDisplayPopup (elemento sobre el cual se motrara el pupu)
|
||||
//ejemplo de como capturarlo:
|
||||
//var elementToDisplayPopup = document.getElementById('element');
|
||||
|
||||
var containerPopupNearby = document.getElementById('container-popup-nearby');
|
||||
var elementToDisplayPopup = document.getElementById(options.idElementToDisplayPopup);
|
||||
|
||||
let html = "";
|
||||
html += " <div class='overlay-n' id='overlay-n'> " +
|
||||
" <div class='popup-n' id='popup-n'> " +
|
||||
" <h3>"+ options.title +"</h3> " +
|
||||
" <h4>"+ options.message +"</h4> " +
|
||||
" <button type='button' class='btn-primary' id='btn-primary-n'>"+options.buttons.accept.label+"</button> "+
|
||||
" <button type='button' class='btn-secondary' id='btn-secondary-n'>"+options.buttons.cancel.label+"</button> "+
|
||||
" </div> " +
|
||||
" </div> ";
|
||||
|
||||
console.log(html);
|
||||
|
||||
while(containerPopupNearby.hasChildNodes()){
|
||||
containerPopupNearby.removeChild(containerPopupNearby.firstChild)
|
||||
}
|
||||
|
||||
containerPopupNearby.insertAdjacentHTML('beforeend',html);
|
||||
|
||||
var overlay = document.getElementById('overlay-n'),
|
||||
popup = document.getElementById('popup-n'),
|
||||
btnAceptarPopup = document.getElementById('btn-primary-n');
|
||||
btnCancelarPopup = document.getElementById('btn-secondary-n');
|
||||
|
||||
//Mostrar popup
|
||||
overlay.classList.add('active');
|
||||
popup.style.position = "fixed";
|
||||
// Asignando las coordenadas, no olvides "px"!
|
||||
let coordsPopup = popup.getBoundingClientRect();
|
||||
console.log(coordsPopup);
|
||||
let coords = elementToDisplayPopup.getBoundingClientRect();
|
||||
|
||||
|
||||
popup.style.left = coords.left + "px";
|
||||
popup.style.top = coords.top - coords.height/2 - coordsPopup.height + "px";
|
||||
|
||||
|
||||
//popup.innerHTML = html;
|
||||
popup.classList.add('active');
|
||||
|
||||
|
||||
|
||||
btnAceptarPopup.addEventListener('click', function(e){
|
||||
|
||||
if(options.buttons.accept.callback != undefined && options.buttons.accept.callback != null && $.isFunction(options.buttons.accept.callback)) {
|
||||
e.preventDefault();
|
||||
overlay.classList.remove('active');
|
||||
popup.classList.remove('active');
|
||||
|
||||
console.log("entro en accion de aceptar")
|
||||
console.log(options.buttons.accept.callback)
|
||||
options.buttons.accept.callback();
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
btnCancelarPopup.addEventListener('click', function(e){
|
||||
|
||||
if(options.buttons.cancel.callback != undefined && options.buttons.cancel.callback != null && $.isFunction(options.buttons.cancel.callback)) {
|
||||
|
||||
e.preventDefault();
|
||||
overlay.classList.remove('active');
|
||||
popup.classList.remove('active');
|
||||
|
||||
console.log("entro en accion de cancelar")
|
||||
console.log(options.buttons.cancel.callback)
|
||||
options.buttons.cancel.callback();
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
_qxLoading: function (box) {
|
||||
|
||||
return {
|
||||
|
||||
ver: function () {
|
||||
|
||||
console.log("Base.Loading 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxLoading = function () {
|
||||
|
||||
var loading = this;
|
||||
|
||||
return Base.Box._qxLoading(loading);
|
||||
}
|
||||
|
||||
});
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Redirect: {
|
||||
|
||||
go: function (url) {
|
||||
window.setTimeout(function () {
|
||||
Base.Loading.hide();
|
||||
location.href = url;
|
||||
}, 350);
|
||||
},
|
||||
|
||||
|
||||
_qxRedirect: function (box) {
|
||||
|
||||
return {
|
||||
|
||||
ver: function () {
|
||||
|
||||
console.log("Base.Redirect 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxLoading = function () {
|
||||
|
||||
var loading = this;
|
||||
|
||||
return Base.Box._qxLoading(loading);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,463 @@
|
||||
/**
|
||||
* Base.Box 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
* Base.Box 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Box : {
|
||||
|
||||
formAjax: function (formId, url, data, options) {
|
||||
|
||||
Base.Message.clear();
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.box);
|
||||
|
||||
if (options != undefined && options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var showLoading = (null != options.showLoading && options.showLoading != undefined) ? options.showLoading : true;
|
||||
var loadingMessage = (null != options.loadingMessage && options.loadingMessage != undefined) ? options.loadingMessage : "Cargando...";
|
||||
|
||||
var buttons = {
|
||||
submit: {
|
||||
label: "Aceptar",
|
||||
className: 'btn btn-primary',
|
||||
callback: function(e){
|
||||
|
||||
submitButton = e.currentTarget;
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
submitButton.disabled = true;
|
||||
|
||||
Base.Message.clear();
|
||||
|
||||
var formSelector = '#' + formId;
|
||||
var formValidator = $(formSelector).QxForm().validatorInstance;
|
||||
|
||||
if(formValidator){
|
||||
formValidator.validate().then(function (status){
|
||||
|
||||
if (status == 'Valid'){
|
||||
|
||||
submitButton.disabled = true;
|
||||
// if(showLoading) {
|
||||
//Base.Loading.show({message: loadingMessage})
|
||||
// }
|
||||
|
||||
var _defaultAjaxOptions = {
|
||||
|
||||
success: function (data, textStatus, jqXHR, form) {
|
||||
// Base.Loading.hide();
|
||||
|
||||
if(data.type == 'Success' || data.type == 'Warning' || data.type == 'Info') {
|
||||
|
||||
if(data.message != null & data.message != "") {
|
||||
Base.Message.flash(data.message, data.cssClass);
|
||||
}
|
||||
|
||||
Base.Box.clearAll();
|
||||
|
||||
if(options.mySuccessCallBack != undefined && options.mySuccessCallBack != null && $.isFunction(options.mySuccessCallBack)) {
|
||||
|
||||
return options.mySuccessCallBack(data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(data.type == 'Error' || data.type == 'Exception'){
|
||||
|
||||
Base.Message.flash(data.message, data.cssClass);
|
||||
|
||||
// Show error message.
|
||||
submitButton.disabled = false;
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
if(options.myErrorCallBack != undefined && options.myErrorCallBack != null && $.isFunction(options.myErrorCallBack)) {
|
||||
|
||||
return options.myErrorCallBack(data);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
if(options.mySuccessCallBack != undefined && options.mySuccessCallBack != null && $.isFunction(options.mySuccessCallBack)) {
|
||||
|
||||
return options.mySuccessCallBack(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var _ajaxOption = $.extend(true, _defaultAjaxOptions, options.ajaxFormOption);
|
||||
|
||||
$(formSelector).ajaxSubmit(_ajaxOption);
|
||||
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
|
||||
// Show error message.
|
||||
submitButton.disabled = false;
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Base.Alert.custom({
|
||||
text: "Errores detectados al validar el formulario, por favor intente nuevamente.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Volver al formulario!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
},
|
||||
callBackThen: function(result){
|
||||
KTUtil.scrollTop();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
label: "Cancelar",
|
||||
className: 'btn btn-light',
|
||||
callback: function(){
|
||||
Base.Loading.hide();
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
//Delete
|
||||
if(options.actionDelete != undefined && options.actionDelete != null && $.isFunction(options.actionDelete)){
|
||||
buttons = $.extend(true,
|
||||
{
|
||||
submit: {},
|
||||
delete : {
|
||||
label: "Eliminar",
|
||||
className: 'btn btn-warning',
|
||||
callback: function(){
|
||||
options.actionDelete(data)
|
||||
}
|
||||
},
|
||||
cancel : {},
|
||||
},
|
||||
buttons);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
|
||||
title: 'Mensaje',
|
||||
message: " ",
|
||||
size: 'large',
|
||||
scrollable: false,
|
||||
mySuccessCallBack: null,
|
||||
myErrorCallBack: null,
|
||||
swapButtonOrder: false,
|
||||
ajaxFormOption : {},
|
||||
buttons: buttons
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
Base.ajax(
|
||||
url,
|
||||
data,
|
||||
function (text) {
|
||||
|
||||
Base.Loading.hide();
|
||||
// Base.Message.clear();
|
||||
|
||||
newOptions = $.extend(true, finallyOptions,
|
||||
{message : text});
|
||||
|
||||
bootbox.dialog(finallyOptions);
|
||||
$('#base-bootbox-id select').each(function(idx, element){
|
||||
$(element).attr("data-dropdown-parent", "#base-bootbox-id");
|
||||
});
|
||||
},
|
||||
{
|
||||
type: 'POST',
|
||||
dataType: "html"
|
||||
});
|
||||
},
|
||||
|
||||
viewAjax: function (url, data, options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.box);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
|
||||
buttons = {};
|
||||
|
||||
//Botones por Defecto
|
||||
if (options.showCloseButton == undefined ||
|
||||
options.showCloseButton == null || options.showCloseButton){
|
||||
|
||||
buttons = {
|
||||
accept: {
|
||||
label: "Aceptar",
|
||||
className: 'btn btn-primary',
|
||||
callback: function(){
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
label: "Cancelar",
|
||||
className: 'btn btn-light',
|
||||
callback: function(){
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
else if(!options.showCloseButton){
|
||||
|
||||
buttons = {
|
||||
accept: {
|
||||
label: "Aceptar",
|
||||
className: 'btn btn-primary',
|
||||
callback: function(){
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
|
||||
title: 'Mensaje',
|
||||
message: " ",
|
||||
size: 'medium',
|
||||
scrollable: false,
|
||||
buttons: buttons
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
|
||||
Base.ajax(
|
||||
url,
|
||||
data,
|
||||
function (text) {
|
||||
|
||||
newOptions = $.extend(true, finallyOptions,
|
||||
{message : text});
|
||||
|
||||
bootbox.dialog(finallyOptions);
|
||||
$('#base-bootbox-id select').each(function(idx, element){
|
||||
$(element).attr("data-dropdown-parent", "#base-bootbox-id");
|
||||
});
|
||||
},
|
||||
{
|
||||
type: 'POST',
|
||||
dataType: "html"
|
||||
});
|
||||
},
|
||||
|
||||
dialog: function (options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.box);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
|
||||
title: 'Mensaje',
|
||||
message: " ",
|
||||
size: 'medium',
|
||||
scrollable: false,
|
||||
swapButtonOrder: true,
|
||||
buttons: {
|
||||
accept: {
|
||||
label: "Aceptar",
|
||||
className: 'btn btn-primary',
|
||||
callback: function(){
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
label: "Cancelar",
|
||||
className: 'btn btn-light',
|
||||
callback: function(){
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
Base.Loading.hide();
|
||||
|
||||
var dialog = bootbox.dialog(finallyOptions);
|
||||
|
||||
return dialog;
|
||||
},
|
||||
|
||||
confirm: function(options){
|
||||
|
||||
alert("Deprecado para este Tema. Use Base.Alert()");
|
||||
console.log("Deprecado para este Tema. Use Base.Alert()");
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.box);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
title: 'Confirmación',
|
||||
message: "¿ Seguro desea realizar la acción ?",
|
||||
size: 'small',
|
||||
inputType: 'text',
|
||||
swapButtonOrder: true,
|
||||
centerVertical: true,
|
||||
buttons: {
|
||||
cancel: {
|
||||
label: "Cancelar",
|
||||
className: 'btn btn-light'
|
||||
},
|
||||
confirm: {
|
||||
label: "Aceptar",
|
||||
className: 'btn btn-primary'
|
||||
}
|
||||
},
|
||||
callback: function(result){
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
//Base.Loading.hide();
|
||||
|
||||
var dialog = bootbox.confirm(finallyOptions);
|
||||
|
||||
return dialog;
|
||||
},
|
||||
|
||||
prompt: function (options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.box);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
title: 'Confirmación',
|
||||
message: " ",
|
||||
size: 'small',
|
||||
inputType: 'text',
|
||||
centerVertical: true,
|
||||
swapButtonOrder: true,
|
||||
buttons: {
|
||||
cancel: {
|
||||
label: "Cancelar",
|
||||
className: 'btn btn-light'
|
||||
},
|
||||
confirm: {
|
||||
label: "Aceptar",
|
||||
className: 'btn btn-primary'
|
||||
}
|
||||
},
|
||||
callback: function(value){
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
//Base.Loading.hide();
|
||||
|
||||
var dialog = bootbox.prompt(finallyOptions);
|
||||
|
||||
return dialog;
|
||||
},
|
||||
|
||||
alert: function (options) {
|
||||
|
||||
alert("Deprecado para este Tema. Use Base.Alert()");
|
||||
console.log("Deprecado para este Tema. Use Base.Alert()");
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.box);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
title: "Mensaje",
|
||||
backdrop: true,
|
||||
message: " ",
|
||||
size: 'small',
|
||||
buttons: {
|
||||
ok: {
|
||||
label: "Aceptar",
|
||||
className: 'btn btn-primary',
|
||||
callback: function(){
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
Base.Loading.hide();
|
||||
|
||||
return bootbox.alert(finallyOptions);
|
||||
},
|
||||
|
||||
clearAll: function(){
|
||||
|
||||
bootbox.hideAll();
|
||||
},
|
||||
|
||||
_qxBox : function (box) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Box 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxBox = function () {
|
||||
|
||||
var box = this;
|
||||
|
||||
return Base.Box._qxBox(box);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
* Base.Buttons 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base > 1.0
|
||||
* ...
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
|
||||
Button : {
|
||||
|
||||
Icon : {
|
||||
|
||||
Style: {
|
||||
|
||||
Edit: 'fas fa-edit' ,
|
||||
View: 'fas fa-search',
|
||||
Check: 'fas fa-check',
|
||||
Evaluation: 'fas fa-clipboard',
|
||||
PEProfiles: 'fas fa-graduation-cap',
|
||||
ToggleON: 'fas fa-toggle-on',
|
||||
ToggleOFF: 'fas fa-toggle-off',
|
||||
GrantAccess: 'fas fa-key',
|
||||
Cancel: 'fas fa-close',
|
||||
PreEnrollment: 'fas fa-address-card-o',
|
||||
Enrollment: 'fas fa-address-card',
|
||||
Group: 'fas fa-users',
|
||||
Announcment: 'fas fa-book',
|
||||
Students: 'fas fa-users',
|
||||
Delete: 'fas fa-trash',
|
||||
Download: 'fas fa-file-download'
|
||||
},
|
||||
|
||||
Edit: function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
chkRoles: null,
|
||||
id : Base.guid(),
|
||||
url: '#',
|
||||
title: 'Editar',
|
||||
class: Base.Button.Icon.Style.Edit,
|
||||
containerClass : 'list-table-action-button'
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
|
||||
return this._icon(finallyOptions);
|
||||
},
|
||||
|
||||
View: function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
chkRoles: null,
|
||||
id : Base.guid(),
|
||||
url: '#',
|
||||
title: 'Ver Detalles',
|
||||
class: Base.Button.Icon.Style.View,
|
||||
containerClass : 'list-table-action-button'
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return this._icon(finallyOptions);
|
||||
},
|
||||
|
||||
Action: function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
chkRoles: null,
|
||||
id : Base.guid(),
|
||||
url: '#',
|
||||
title: 'Acction',
|
||||
class: ((options.class != undefined) ? options.class : Base.Button.Icon.Style.Check),
|
||||
containerClass : 'list-table-action-button'
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return this._icon(finallyOptions);
|
||||
},
|
||||
|
||||
ActionConfirm: function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
confirm : {
|
||||
title: 'Confirmación',
|
||||
message: "¿ Seguro desea realizar la acción ?",
|
||||
},
|
||||
chkRoles: null,
|
||||
id : Base.guid(),
|
||||
url: '#',
|
||||
txt: '',
|
||||
title: 'Acction',
|
||||
class: Base.Button.Icon.Style.Check,
|
||||
containerClass : 'list-table-action-button'
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return this._iconConfirm(finallyOptions);
|
||||
},
|
||||
|
||||
CallFunction: function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
chkRoles: null,
|
||||
id : Base.guid(),
|
||||
title: 'Acction',
|
||||
class: Base.Button.Icon.Style.Check,
|
||||
containerClass : 'list-table-action-button',
|
||||
functionCall: null,
|
||||
params: null
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return this._iconFunction(finallyOptions);
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated Usar CallFunction con Base.Box.prompt
|
||||
*/
|
||||
CallConfirmFunction: function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
confirm : {
|
||||
title: 'Confirmación',
|
||||
message: "¿ Seguro desea realizar la acción ?",
|
||||
},
|
||||
chkRoles: null,
|
||||
id : Base.guid(),
|
||||
title: 'Acction',
|
||||
class: Base.Button.Icon.Style.Check,
|
||||
containerClass : 'list-table-action-button',
|
||||
functionCall: null,
|
||||
params: null
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return this._iconConfirmCallFunction(finallyOptions);
|
||||
},
|
||||
|
||||
_icon: function (options) {
|
||||
|
||||
if(options.chkRoles != null && options.chkRoles != undefined && options.chkRoles != ''){
|
||||
|
||||
if (!Base.isSecurityAccessFor(options.chkRoles))
|
||||
return "";
|
||||
}
|
||||
|
||||
var icon = '<a title="' + options.title + '" id="' + options.id + '" href="' + options.url + '" class="' + options.containerClass + '"><i class="' + options.class + '"></i></a>';
|
||||
|
||||
|
||||
return icon;
|
||||
},
|
||||
|
||||
_iconConfirm: function (options) {
|
||||
|
||||
if(options.chkRoles != null && options.chkRoles != undefined && options.chkRoles != ''){
|
||||
|
||||
if (!Base.isSecurityAccessFor(options.chkRoles))
|
||||
return "";
|
||||
}
|
||||
|
||||
var onClick = "Base.Box.confirm({" +
|
||||
" title: '" + options.confirm.title + "'," +
|
||||
" message: '" + options.confirm.message + "'," +
|
||||
" callback: function(result){" +
|
||||
" if(result){" +
|
||||
" Base.Loading.show({}); " +
|
||||
" window.location = '" + options.url + "' ;" +
|
||||
" }" +
|
||||
" }" +
|
||||
" });";
|
||||
|
||||
|
||||
var icon = '<a title="' + options.title + '" ' +
|
||||
' id="' + options.id + '" ' +
|
||||
' href="#" ' +
|
||||
' class="' + options.containerClass + '" ' +
|
||||
' onclick="' + onClick + '" >' +
|
||||
' <i class="' + options.class + '"></i></a>';
|
||||
return icon;
|
||||
},
|
||||
|
||||
_iconFunction: function (options) {
|
||||
|
||||
if(options.chkRoles != null && options.chkRoles != undefined && options.chkRoles != ''){
|
||||
|
||||
if (!Base.isSecurityAccessFor(options.chkRoles))
|
||||
return "";
|
||||
}
|
||||
|
||||
var params = JSON.stringify( options.params );
|
||||
|
||||
var regex = new RegExp("\"", "g");
|
||||
params = params.replace(regex, "'");
|
||||
|
||||
var icon = '<span title="' + options.title + '" id="' + options.id + '" class="' + options.containerClass + '">'
|
||||
+'<i class="' + options.class + '" onclick="' + options.functionCall + '(this,' + params + ')"></i></span>';
|
||||
|
||||
return icon;
|
||||
},
|
||||
|
||||
_iconConfirmCallFunction: function (options) {
|
||||
|
||||
if(options.chkRoles != null && options.chkRoles != undefined && options.chkRoles != ''){
|
||||
|
||||
if (!Base.isSecurityAccessFor(options.chkRoles))
|
||||
return "";
|
||||
}
|
||||
|
||||
var params = JSON.stringify( options.params );
|
||||
|
||||
var regex = new RegExp("\"", "g");
|
||||
params = params.replace(regex, "'");
|
||||
|
||||
|
||||
|
||||
var onClick = "Base.Box.confirm({" +
|
||||
" title: '" + options.confirm.title + "'," +
|
||||
" message: '" + options.confirm.message + "'," +
|
||||
" callback: function(result){" +
|
||||
" if(result){" +
|
||||
" " + options.functionCall + '(this,' + params + ') ' +
|
||||
" }" +
|
||||
" }" +
|
||||
" });";
|
||||
|
||||
|
||||
var icon = '<a title="' + options.title + '" ' +
|
||||
' id="' + options.id + '" ' +
|
||||
' href="#" ' +
|
||||
' class="' + options.containerClass + '" ' +
|
||||
' onclick="' + onClick + '" >' +
|
||||
' <i class="' + options.class + '"> ' +
|
||||
' </i></a>';
|
||||
|
||||
|
||||
return icon;
|
||||
}
|
||||
},
|
||||
|
||||
Button: function () {
|
||||
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* Base.Chart 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
* Base.Filter 1.0
|
||||
*
|
||||
* morris.js
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Chart: {
|
||||
|
||||
create: function (type, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.chart);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
element: 'graph',
|
||||
data: [],
|
||||
xkey: 'X',
|
||||
ykey: ['Y'],
|
||||
labels: ['Y'],
|
||||
reload_url: null,
|
||||
postdata: {},
|
||||
show_legend: true,
|
||||
colors : null
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
|
||||
var realoadUrl = function (chart, options) {
|
||||
|
||||
Base.ajax(
|
||||
options.reload_url,
|
||||
options.postdata,
|
||||
function (data) {
|
||||
|
||||
chart.setData(data);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
var chart = null;
|
||||
switch (type) {
|
||||
|
||||
case 'line':
|
||||
finallyOptions = $.extend(true,
|
||||
{
|
||||
parseTime: false,
|
||||
hideHover: true,
|
||||
barOpacity: 1.0,
|
||||
barRadius: [0, 0, 0, 0],
|
||||
xLabelAngle: 20,
|
||||
barRatio: 0.4,
|
||||
resize: true
|
||||
},
|
||||
finallyOptions);
|
||||
|
||||
if(null != options.colors){
|
||||
finallyOptions = $.extend(true, {lineColors: options.colors, }, finallyOptions);
|
||||
}
|
||||
|
||||
chart = new Morris.Line(finallyOptions);
|
||||
break;
|
||||
|
||||
case 'bar':
|
||||
finallyOptions = $.extend(true,
|
||||
{
|
||||
parseTime: false,
|
||||
hideHover: true,
|
||||
barOpacity: 1.0,
|
||||
barRadius: [0, 0, 0, 0],
|
||||
xLabelAngle: 20,
|
||||
barRatio: 0.4,
|
||||
resize: true,
|
||||
stacked: false
|
||||
},
|
||||
finallyOptions);
|
||||
|
||||
if(null != options.colors){
|
||||
finallyOptions = $.extend(true, {barColors: options.colors, }, finallyOptions);
|
||||
}
|
||||
|
||||
chart = new Morris.Bar(finallyOptions);
|
||||
break;
|
||||
|
||||
case 'stacked':
|
||||
finallyOptions = $.extend(true,
|
||||
{
|
||||
parseTime: false,
|
||||
hideHover: true,
|
||||
barOpacity: 1.0,
|
||||
barRadius: [0, 0, 0, 0],
|
||||
xLabelAngle: 20,
|
||||
barRatio: 0.4,
|
||||
resize: true,
|
||||
stacked: true
|
||||
},
|
||||
finallyOptions);
|
||||
chart = new Morris.Bar(finallyOptions);
|
||||
|
||||
if(null != options.colors){
|
||||
finallyOptions = $.extend(true, {barColors: options.colors, }, finallyOptions);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'area':
|
||||
finallyOptions = $.extend(true,
|
||||
{
|
||||
parseTime: false,
|
||||
hideHover: true,
|
||||
barOpacity: 1.0,
|
||||
barRadius: [0, 0, 0, 0],
|
||||
xLabelAngle: 20,
|
||||
barRatio: 0.4,
|
||||
resize: true
|
||||
},
|
||||
finallyOptions);
|
||||
|
||||
if(null != options.colors){
|
||||
finallyOptions = $.extend(true, {barColors: options.colors, }, finallyOptions);
|
||||
}
|
||||
|
||||
chart = new Morris.Area(finallyOptions);
|
||||
break;
|
||||
|
||||
case 'ring':
|
||||
finallyOptions = $.extend(true,
|
||||
{
|
||||
parseTime: false,
|
||||
hideHover: true,
|
||||
barOpacity: 1.0,
|
||||
barRadius: [0, 0, 0, 0],
|
||||
xLabelAngle: 20,
|
||||
barRatio: 0.4,
|
||||
resize: true
|
||||
},
|
||||
finallyOptions);
|
||||
|
||||
if(null != options.colors){
|
||||
finallyOptions = $.extend(true, {colors: options.colors, }, finallyOptions);
|
||||
}
|
||||
|
||||
chart = new Morris.Donut(finallyOptions);
|
||||
break;
|
||||
}
|
||||
|
||||
//Load Data Ajax
|
||||
if (finallyOptions.reload_url != null) {
|
||||
|
||||
realoadUrl(chart, finallyOptions);
|
||||
}
|
||||
|
||||
if(finallyOptions.show_legend){
|
||||
|
||||
chart.options.labels.forEach(function(label, i){
|
||||
|
||||
var legendItem = $("<div class='graph_legend_item'></div>");
|
||||
|
||||
var legendLabel= $('<span class="graph_legend_item_label">'+label+'</span>');
|
||||
|
||||
var legendBox = "";
|
||||
|
||||
if(type == 'line') {
|
||||
legendBox = $('<div class="graph_legend_box"></div>').css('background-color', chart.options.lineColors[i]);
|
||||
}
|
||||
|
||||
if(type == 'bar' || type == 'stacked' || type == 'area') {
|
||||
legendBox = $('<div class="graph_legend_box"></div>').css('background-color', chart.options.barColors[i]);
|
||||
}
|
||||
|
||||
if(type == 'ring') {
|
||||
legendBox = $('<div class="graph_legend_box"></div>').css('background-color', chart.options.colors[i]);
|
||||
}
|
||||
|
||||
$(legendItem).append(legendBox);
|
||||
$(legendItem).append(legendLabel);
|
||||
|
||||
|
||||
$('#legend_' + options.element).append(legendItem);
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
return chart;
|
||||
},
|
||||
|
||||
_qxChart : function (table) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Chart 1.0");
|
||||
console.log("Requiere: Chart 1.0; Chart.Filter 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$.fn.QxChart = function () {
|
||||
|
||||
var chart = this;
|
||||
|
||||
return Base.Chart._qxChart(chart);
|
||||
}
|
||||
});
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Base.DashboardFilter 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
|
||||
DashboardFilter : {
|
||||
|
||||
create: function(selector, options){
|
||||
|
||||
selector = selector.replace("#", "");
|
||||
dashboardFilterSelector = "#dashboard_filter_container_" + selector;
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.date);
|
||||
|
||||
if(options._i18n !== undefined && options._i18n != null){
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
callOnChange: null
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
$(dashboardFilterSelector).on('onChange', function(event, selector, dashboardFilter){
|
||||
|
||||
if(finallyOptions.callOnChange != undefined && finallyOptions.callOnChange != null && $.isFunction(finallyOptions.callOnChange)) {
|
||||
|
||||
return finallyOptions.callOnChange(selector, dashboardFilter);
|
||||
}
|
||||
});
|
||||
|
||||
return $(dashboardFilterSelector);
|
||||
},
|
||||
|
||||
|
||||
buildFiltersRequest : function (selector) {
|
||||
|
||||
selector = selector.replace("#", "");
|
||||
var searchSelector = "#fsearchtext_" + selector;
|
||||
var filterSelector = "[filter-selector='" + "filters_" + selector + "']";
|
||||
|
||||
var _buildSearch = function (_selector) {
|
||||
|
||||
return $(_selector).val();
|
||||
}
|
||||
|
||||
var _builFilters = function (_selector) {
|
||||
|
||||
var filters = [];
|
||||
|
||||
var idx = 0;
|
||||
$.each($(_selector), function (i, obj) {
|
||||
|
||||
if (typeof ($(obj).attr('name')) !== 'undefined') {
|
||||
|
||||
var fname = $(obj).attr('name');
|
||||
var fvalue = '';
|
||||
|
||||
//Checkbox and Radio
|
||||
if (($(obj).attr('type')) === 'checkbox' || ($(obj).attr('type')) === 'radio') {
|
||||
//Add values
|
||||
fvalue = Array();
|
||||
|
||||
$('input[name="' + fname + '"]:checked').each(function () {
|
||||
var val = this.value;
|
||||
|
||||
if (val !== 'undefined' && val !== '' && val !== null && val !== 'null') {
|
||||
fvalue.push(val);
|
||||
}
|
||||
});
|
||||
}
|
||||
//Others
|
||||
else {
|
||||
var val = $(obj).val();
|
||||
|
||||
if (val !== 'undefined' && val !== '' && val !== null && val !== 'null') {
|
||||
|
||||
//Add values
|
||||
fvalue = val;
|
||||
}
|
||||
}
|
||||
|
||||
//Add Filter
|
||||
if (fvalue !== 'undefined'
|
||||
&& fvalue !== ''
|
||||
&& fvalue !== null
|
||||
&& fvalue !== 'null'
|
||||
&& fvalue.length > 0
|
||||
)
|
||||
{
|
||||
|
||||
var filter = {
|
||||
name: fname,
|
||||
value: fvalue
|
||||
};
|
||||
|
||||
filters[idx++] = filter;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
dashboarFilter = {
|
||||
search: _buildSearch(searchSelector),
|
||||
filters: _builFilters(filterSelector)
|
||||
};
|
||||
|
||||
return dashboarFilter;
|
||||
},
|
||||
|
||||
isFilterReady : function (selector) {
|
||||
|
||||
selector = selector.replace("#", "");
|
||||
var filterSelector = "[filter-selector='" + "filters_" + selector + "']";
|
||||
|
||||
if ($('#fsearchtext_' + selector).attr('filter-obligatory') == 'true'){
|
||||
|
||||
if($('#fsearchtext_' + selector).val().trim() == ""){
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var _obligatoryFiltersReady = function (_selector) {
|
||||
|
||||
var ofr = true;
|
||||
|
||||
$.each($(_selector), function (i, obj) {
|
||||
|
||||
if (typeof ($(obj).attr('name')) !== 'undefined') {
|
||||
|
||||
var fname = $(obj).attr('name');
|
||||
|
||||
//Check must has value if is obligatory
|
||||
if ($(obj).attr('filter-obligatory') == 'true') {
|
||||
|
||||
//Checkbox and Radio
|
||||
if (($(obj).attr('type')) === 'checkbox' || ($(obj).attr('type')) === 'radio') {
|
||||
|
||||
if ($('input[name="' + fname + '"]:checked').length == 0) {
|
||||
|
||||
ofr = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Others
|
||||
else {
|
||||
|
||||
var val = $(obj).val();
|
||||
|
||||
if (val == 'undefined' || val == '' || val == null || val == 'null') {
|
||||
|
||||
ofr = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return ofr;
|
||||
};
|
||||
|
||||
return _obligatoryFiltersReady(filterSelector);
|
||||
},
|
||||
|
||||
_qxDashboardFilter : function (dashboarFilter) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.DashboardFilter 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
},
|
||||
|
||||
triggerChange: function () {
|
||||
|
||||
var data = $(dashboarFilter).data("dashboardFilterData");
|
||||
$(dashboarFilter).trigger('onChange', [data.tableSelector, Base.DashboardFilter.buildFiltersRequest(data.tableSelector)]);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxDashboardFilter = function () {
|
||||
|
||||
var dashboarFilter = this;
|
||||
|
||||
return Base.DashboardFilter._qxDashboardFilter(dashboarFilter);
|
||||
}
|
||||
});
|
||||
+430
@@ -0,0 +1,430 @@
|
||||
/**
|
||||
* Base.DataTable 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
* Base.Filter 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
DataTable : {
|
||||
|
||||
_language: {
|
||||
"sProcessing": '<div class="blockui-message"><span class="spinner-border spinner-border-sm align-middle ms-2 text-primary"></span> Cargando...</div>',
|
||||
"sLengthMenu": "_MENU_",
|
||||
"sZeroRecords": "Sin resultados",
|
||||
"sEmptyTable": "Sin datos",
|
||||
"sInfo": "Resultado _START_ - _END_ de _TOTAL_",
|
||||
"sInfoEmpty": "No hay registros",
|
||||
"sInfoFiltered": "(filtrado de un total de _MAX_ registros)",
|
||||
"sInfoPostFix": "",
|
||||
"sSearch": "Buscar:",
|
||||
"sUrl": "",
|
||||
"sInfoThousands": ",",
|
||||
"sLoadingRecords": "Cargando...",
|
||||
"oAria": {
|
||||
"sSortAscending": ": Activar para ordenar la columna de manera ascendente",
|
||||
"sSortDescending": ": Activar para ordenar la columna de manera descendente"
|
||||
}
|
||||
},
|
||||
|
||||
createSimpleAjax: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
actionColunmLabel: 'Actions',
|
||||
language: {
|
||||
"lengthMenu": "Show _MENU_ entries"
|
||||
}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.datatable);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
deferLoading: (Base.DashboardFilter.isFilterReady(selector)) ? null : 0,
|
||||
responsive: true,
|
||||
serverSide: true,
|
||||
processing: true,
|
||||
paging: false,
|
||||
pageLength: 10,
|
||||
lengthMenu: [10, 25, 50, 75, 100],
|
||||
language: this._language,
|
||||
columnDefs: [],
|
||||
onRowClick: null,
|
||||
rowClickMode: 'FULL',
|
||||
autoWidth: true,
|
||||
sort: false,
|
||||
searching: false,
|
||||
myDrawCallback: null,
|
||||
customData: {},
|
||||
drawCallback: function (oSettings) {
|
||||
if(options.myDrawCallback != undefined && options.myDrawCallback != null && $.isFunction(options.myDrawCallback)) {
|
||||
|
||||
return options.myDrawCallback(oSettings);
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
url: options.url,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
async: false,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataSrc: function (data) {
|
||||
|
||||
return data.content;
|
||||
},
|
||||
data: function (data, table) {
|
||||
|
||||
var sort = {};
|
||||
|
||||
var customData = {};
|
||||
|
||||
if (options.customData != undefined && options.customData != null && $.isFunction(options.customData)) {
|
||||
|
||||
customData = options.customData();
|
||||
}
|
||||
else if(options.customData != undefined && options.customData != null ){
|
||||
|
||||
customData = options.customData;
|
||||
}
|
||||
|
||||
var myData = {
|
||||
draw: data.draw,
|
||||
page: 0,
|
||||
size: 1,
|
||||
search: null,
|
||||
sort: sort,
|
||||
dashboardFilter: Base.DashboardFilter.buildFiltersRequest(selector),
|
||||
data: customData
|
||||
};
|
||||
|
||||
return JSON.stringify(myData);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var _columnActions = function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
column: {
|
||||
data: "id",
|
||||
title: _i18n.actionColunmLabel,
|
||||
className: "list-table-columns-actions",
|
||||
width: "15%"
|
||||
},
|
||||
columnDef: {
|
||||
targets: -1,
|
||||
orderable: false,
|
||||
render: function (data, type, row, meta) {
|
||||
|
||||
if (options.buttons != undefined && options.buttons != null && $.isFunction(options.buttons)) {
|
||||
return options.buttons(data, type, row, meta);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return $.extend(true, defaultOptions, options);
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
if (options.columnActions !== undefined && options.columnActions != null) {
|
||||
|
||||
var columnActions = _columnActions(options.columnActions);
|
||||
|
||||
finallyOptions.columns.push(columnActions.column);
|
||||
finallyOptions.columnDefs.push(columnActions.columnDef);
|
||||
}
|
||||
Base.DataTable._globalActionRow(selector, finallyOptions);
|
||||
|
||||
return $(selector).DataTable(finallyOptions);
|
||||
},
|
||||
|
||||
createStaticTable: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
actionColunmLabel: 'Actions',
|
||||
language: {
|
||||
"lengthMenu": "Show _MENU_ entries"
|
||||
}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.datatable);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
responsive: true,
|
||||
pagingType: 'none',
|
||||
serverSide: false,
|
||||
processing: false,
|
||||
paging: false,
|
||||
info: false,
|
||||
language: this._language,
|
||||
columnDefs: [],
|
||||
onRowClick: null,
|
||||
rowClickMode: 'FULL',
|
||||
autoWidth: true,
|
||||
sort: false,
|
||||
searching: false,
|
||||
myDrawCallback: null,
|
||||
drawCallback: function (oSettings) {
|
||||
if(options.myDrawCallback != undefined && options.myDrawCallback != null && $.isFunction(options.myDrawCallback)) {
|
||||
|
||||
return options.myDrawCallback(oSettings);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var _columnActions = function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
column: {
|
||||
title: _i18n.actionColunmLabel,
|
||||
className: "list-table-columns-actions",
|
||||
width: "15%"
|
||||
},
|
||||
columnDef: {
|
||||
targets: -1,
|
||||
orderable: false,
|
||||
render: function (data, type, row, meta) {
|
||||
|
||||
if (options.buttons != undefined && options.buttons != null && $.isFunction(options.buttons)) {
|
||||
return options.buttons(data, type, row, meta);
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return $.extend(true, defaultOptions, options);
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
if (options.columnActions !== undefined && options.columnActions != null) {
|
||||
|
||||
var columnActions = _columnActions(options.columnActions);
|
||||
|
||||
finallyOptions.columns.push(columnActions.column);
|
||||
finallyOptions.columnDefs.push(columnActions.columnDef);
|
||||
}
|
||||
Base.DataTable._globalActionRow(selector, finallyOptions);
|
||||
|
||||
return $(selector).DataTable(finallyOptions);
|
||||
},
|
||||
|
||||
create: function (selector, options) {
|
||||
var _i18n = {
|
||||
actionColunmLabel: 'Actions',
|
||||
language: {
|
||||
"lengthMenu": "Show _MENU_ entries"
|
||||
}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.datatable);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
deferLoading: (Base.DashboardFilter.isFilterReady(selector)) ? null : 0,
|
||||
responsive: true,
|
||||
serverSide: true,
|
||||
processing: true,
|
||||
paging: true,
|
||||
pageLength: 10,
|
||||
lengthMenu: [10, 25, 50, 75, 100],
|
||||
language: this._language,
|
||||
columnDefs: [],
|
||||
onRowClick: null,
|
||||
rowClickMode: null,
|
||||
autoWidth: true,
|
||||
sort: false,
|
||||
searching: false,
|
||||
myDrawCallback: null,
|
||||
customData: null,
|
||||
drawCallback: function (oSettings) {
|
||||
|
||||
if(options.myDrawCallback != undefined && options.myDrawCallback != null && $.isFunction(options.myDrawCallback)) {
|
||||
|
||||
return options.myDrawCallback(oSettings);
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
url: options.url,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
async: false,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataSrc: function (data) {
|
||||
|
||||
return data.content;
|
||||
},
|
||||
data: function (data, table) {
|
||||
|
||||
var sort = {};
|
||||
|
||||
if (defaultOptions.sort) {
|
||||
|
||||
var order = [];
|
||||
for (var i = 0; i < data.order.length; i++) {
|
||||
|
||||
var columnSort = (typeof data.columns[data.order[i].column].data == 'string')
|
||||
? data.columns[data.order[i].column].data
|
||||
: data.columns[data.order[i].column].data.sort;
|
||||
order.push({
|
||||
column: columnSort,
|
||||
direction: data.order[i].dir
|
||||
})
|
||||
}
|
||||
|
||||
sort = {
|
||||
orderList: order
|
||||
}
|
||||
}
|
||||
|
||||
var customData = {};
|
||||
|
||||
if (options.customData != undefined && options.customData != null && $.isFunction(options.customData)) {
|
||||
|
||||
customData = options.customData();
|
||||
}
|
||||
else if(options.customData != undefined && options.customData != null ){
|
||||
|
||||
customData = options.customData;
|
||||
}
|
||||
|
||||
var myData = {
|
||||
draw: data.draw,
|
||||
page: $(selector).DataTable().page.info().page,
|
||||
size: data.length,
|
||||
search: data.search.value,
|
||||
sort: sort,
|
||||
dashboardFilter: Base.DashboardFilter.buildFiltersRequest(selector),
|
||||
data: customData
|
||||
};
|
||||
|
||||
return JSON.stringify(myData);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var _columnActions = function (options) {
|
||||
|
||||
var defaultOptions = {
|
||||
column: {
|
||||
data: "id",
|
||||
title: _i18n.actionColunmLabel,
|
||||
className: "list-table-columns-actions",
|
||||
width: "15%"
|
||||
},
|
||||
columnDef: {
|
||||
targets: -1,
|
||||
orderable: false,
|
||||
render: function (data, type, row, meta) {
|
||||
|
||||
if (options.buttons != undefined && options.buttons != null && $.isFunction(options.buttons)) {
|
||||
return options.buttons(data, type, row, meta);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return $.extend(true, defaultOptions, options);
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
if (options.columnActions !== undefined && options.columnActions != null) {
|
||||
|
||||
var columnActions = _columnActions(options.columnActions);
|
||||
|
||||
finallyOptions.columns.push(columnActions.column);
|
||||
finallyOptions.columnDefs.push(columnActions.columnDef);
|
||||
}
|
||||
Base.DataTable._globalActionRow(selector, finallyOptions);
|
||||
|
||||
return $(selector).DataTable(finallyOptions);
|
||||
},
|
||||
|
||||
_globalActionRow: function(selector, options){
|
||||
|
||||
if ((options.onRowClick == undefined || options.onRowClick == null)
|
||||
&& !$.isFunction(options.onRowClick)) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var trSelector = '';
|
||||
var trSelector1 = '';
|
||||
var trSelector2 = '';
|
||||
|
||||
//No click en la primera columna
|
||||
if(options.rowClickMode == 'SKIP-FIRST'){
|
||||
trSelector1 += 'tbody tr td:first-child';
|
||||
}
|
||||
//No click en la ultima columna (o esta activado las options)
|
||||
if(options.rowClickMode == 'SKIP-LAST'
|
||||
|| (options.columnActions !== undefined && options.columnActions != null)){
|
||||
trSelector2 = 'tbody tr td:last-child';
|
||||
}
|
||||
if(trSelector1 != ""){
|
||||
trSelector1 += ", ";
|
||||
}
|
||||
trSelector = 'td:not(' + trSelector1 + trSelector2 + ')';
|
||||
|
||||
$(selector).on('click', trSelector, function () {
|
||||
|
||||
var data = $(selector).DataTable().row( this ).data();
|
||||
|
||||
return options.onRowClick(data);
|
||||
} );
|
||||
},
|
||||
|
||||
_qxDataTable : function (table) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.DataTable 1.0");
|
||||
console.log("Requiere: Base 1.0; Base.Filter 1.0");
|
||||
},
|
||||
|
||||
reload: function () {
|
||||
|
||||
$(table).DataTable().ajax.reload();
|
||||
},
|
||||
|
||||
deleteRow: function (idx, callback, redraw) {
|
||||
|
||||
$(table).dataTable().fnDeleteRow(idx, callback, redraw);
|
||||
$(table).DataTable().rows().invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxDataTable = function () {
|
||||
|
||||
var table = this;
|
||||
|
||||
return Base.DataTable._qxDataTable(table);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Base.Date 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Date : {
|
||||
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.date);
|
||||
if(options != undefined && options._i18n !== undefined && options._i18n != null){
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
//Option Convert/Compatibility
|
||||
var convertOptions = {};
|
||||
if(options != undefined){
|
||||
if(options.startDate != undefined){
|
||||
convertOptions.minDate = options.startDate;
|
||||
}
|
||||
if(options.startDate != undefined){
|
||||
convertOptions.maxDate = options.endDate;
|
||||
}
|
||||
if(options.datesDisabled != undefined){
|
||||
convertOptions.disable = options.datesDisabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var defaultOptions = {
|
||||
allowInput: true,
|
||||
enableTime: false,
|
||||
time_24hr: false,
|
||||
disable: [],
|
||||
disableMobile: false,
|
||||
dateFormat: 'd/m/Y',
|
||||
language: 'es',
|
||||
mode: 'single', //"single", "multiple", or "range"
|
||||
minDate : new Date('1900-01-01'),
|
||||
maxDate : new Date('2050-12-31')
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options, convertOptions);
|
||||
|
||||
return $(selector).flatpickr(finallyOptions);
|
||||
},
|
||||
|
||||
_qxDate : function (date) {
|
||||
console.log("date ", date)
|
||||
return {
|
||||
|
||||
instance : (date[0]._flatpickr),
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Date 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
},
|
||||
|
||||
destroy: function(value){
|
||||
this.instance.destroy();
|
||||
|
||||
if(value != undefined){
|
||||
$(date).val(value);
|
||||
}
|
||||
},
|
||||
|
||||
setOption: function(option, value){
|
||||
|
||||
this.instance.set(option, value);
|
||||
},
|
||||
|
||||
clear: function(){
|
||||
this.instance.clear();
|
||||
},
|
||||
|
||||
getDay: function (format) {
|
||||
|
||||
if(this.instance.selectedDates[0] == undefined){
|
||||
return "";
|
||||
}
|
||||
|
||||
if(format == undefined) {
|
||||
return moment(this.instance.selectedDates[0], "L").format('dddd');
|
||||
}
|
||||
|
||||
return moment(this.instance.selectedDates[0], "L").format(format);
|
||||
},
|
||||
|
||||
getMonth: function (format) {
|
||||
|
||||
if(this.instance.selectedDates[0] == undefined){
|
||||
return "";
|
||||
}
|
||||
|
||||
if(format == undefined) {
|
||||
return moment(this.instance.selectedDates[0], "L").format('MMMM');
|
||||
}
|
||||
|
||||
return moment(this.instance.selectedDates[0], "L").format(format);
|
||||
},
|
||||
|
||||
getYear: function (format) {
|
||||
|
||||
if(this.instance.selectedDates[0] == undefined){
|
||||
return "";
|
||||
}
|
||||
|
||||
if(format == undefined) {
|
||||
return moment(this.instance.selectedDates[0], "L").format('yyyy');
|
||||
}
|
||||
|
||||
return moment(this.instance.selectedDates[0], "L").format(format);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$.fn.QxDate = function () {
|
||||
|
||||
var date = this;
|
||||
|
||||
return Base.Date._qxDate(date);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Base.Date 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Date : {
|
||||
|
||||
formatStrDate: function (date, format) {
|
||||
|
||||
if (typeof date === 'string' || date instanceof String){
|
||||
|
||||
date = date + " 00:00";
|
||||
}
|
||||
|
||||
var newDate = new Date(date);
|
||||
var inputDate = '<input value="">';
|
||||
|
||||
var options = {};
|
||||
if(null != format || format != undefined){
|
||||
options = {format: format};
|
||||
}
|
||||
|
||||
console.log(format);
|
||||
console.log(options);
|
||||
|
||||
var dtPick = Base.Date.create(inputDate, options);
|
||||
|
||||
return dtPick.datepicker('setDate', newDate).val();
|
||||
},
|
||||
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.date);
|
||||
|
||||
if(options != undefined && options._i18n !== undefined && options._i18n != null){
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
autoApply: false,
|
||||
singleDatePicker: true,
|
||||
todayHighlight: true,
|
||||
language: 'es',
|
||||
showDropdowns: true,
|
||||
minYear: 1901,
|
||||
maxYear: 2050,
|
||||
minDate: '01/01/1901',
|
||||
maxDate: '31/12/2049',
|
||||
timePicker: false,
|
||||
locale: {
|
||||
format: 'DD/MM/YYYY',
|
||||
separator: '-' ,
|
||||
applyLabel: 'Aceptar',
|
||||
cancelLabel: 'Cancelar',
|
||||
fromLabel: 'Desde',
|
||||
toLabel: 'a',
|
||||
customRangeLabel: "Custom",
|
||||
weekLabel: 'Sem',
|
||||
daysOfWeek: Base.daysOfWeek.acronyms,
|
||||
monthNames: Base.month.fullNames,
|
||||
firstDay: 1
|
||||
}
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return $(selector).daterangepicker(finallyOptions);
|
||||
},
|
||||
|
||||
_qxDate : function (date) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Date 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
},
|
||||
|
||||
getMonth: function (format) {
|
||||
|
||||
if(format == undefined) {
|
||||
return moment($(date).val(), "L").format('MMMM');
|
||||
}
|
||||
|
||||
return moment($(date).val(), "DD/MM/YYYY").format(format);
|
||||
},
|
||||
|
||||
getYear: function (format) {
|
||||
|
||||
if(format == undefined) {
|
||||
return moment($(date).val(), "DD/MM/YYYY").format('yyyy');
|
||||
}
|
||||
|
||||
return moment($(date).val(), "dd/mm/yyyy").format(format);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$.fn.QxDate = function () {
|
||||
|
||||
var date = this;
|
||||
|
||||
return Base.Date._qxDate(date);
|
||||
}
|
||||
});
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
// Made by DNMjustME
|
||||
|
||||
// Validar los inputs
|
||||
function validarInputNumerico(idInput) {
|
||||
var input = $('#' + idInput);
|
||||
var mensajeError = $('<div/>', {
|
||||
'text': 'Por favor ingrese solo caracteres numéricos',
|
||||
'class': 'text-danger',
|
||||
'id': 'error_numerico'
|
||||
});
|
||||
|
||||
// Expresión regular para permitir solo caracteres numéricos
|
||||
var regex = /^[0-9]*$/;
|
||||
|
||||
if (!regex.test(input.val().trim())) {
|
||||
if (!input.parent().find('#error_numerico').length) {
|
||||
// El input contiene caracteres no numéricos, mostramos el mensaje de error
|
||||
input.parent().append(mensajeError);
|
||||
}
|
||||
// Actualizar el estado del campo a inválido (false)
|
||||
return false;
|
||||
} else {
|
||||
// El input contiene solo caracteres numéricos, ocultamos cualquier mensaje de error previo
|
||||
input.parent().find('#error_numerico').remove();
|
||||
// Actualizar el estado del campo a válido (true)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function validarInputEmail(idInput) {
|
||||
var input = $('#' + idInput);
|
||||
var mensajeError = $('<div/>', {
|
||||
'text': 'Por favor ingrese un correo electrónico válido',
|
||||
'class': 'text-danger',
|
||||
'id': 'error_email'
|
||||
});
|
||||
|
||||
// Expresión regular para validar correos electrónicos
|
||||
var regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
|
||||
if (!regex.test(input.val().trim())) {
|
||||
if (!input.parent().find('#error_email').length) {
|
||||
// El input no contiene un correo electrónico válido, mostramos el mensaje de error
|
||||
input.parent().append(mensajeError);
|
||||
}
|
||||
// Actualizar el estado del campo a inválido (false)
|
||||
return false;
|
||||
} else {
|
||||
// El input contiene un correo electrónico válido, ocultamos cualquier mensaje de error previo
|
||||
input.parent().find('#error_email').remove();
|
||||
// Actualizar el estado del campo a válido (true)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function validarInputNotEmpty(idInput) {
|
||||
var input = $('#' + idInput);
|
||||
var mensajeError = $('<div/>', {
|
||||
'text': 'Este campo es obligatorio',
|
||||
'class': 'text-danger',
|
||||
'id': 'error_notempty'
|
||||
});
|
||||
|
||||
var parent;
|
||||
if (idInput.includes('fecha')) {
|
||||
parent = input.parent();
|
||||
} else {
|
||||
parent = input;
|
||||
}
|
||||
|
||||
if (input.val().trim() === '') {
|
||||
if (!parent.parent().find('#error_notempty').length) {
|
||||
// El input está vacío, mostramos el mensaje de error
|
||||
parent.parent().append(mensajeError);
|
||||
}
|
||||
// Actualizar el estado del campo a vacío (false)
|
||||
return false;
|
||||
} else {
|
||||
// El input no está vacío, ocultamos cualquier mensaje de error previo
|
||||
parent.parent().find('#error_notempty').remove();
|
||||
// Actualizar el estado del campo a no vacío (true)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function validarInputMinMaxCaracteres(idInput, min, max) {
|
||||
var input = $('#' + idInput);
|
||||
var mensajeError = $('<div/>', {
|
||||
'class': 'text-danger',
|
||||
'id': 'error_minmaxcaracteres'
|
||||
});
|
||||
|
||||
if (input.val().length < min) {
|
||||
mensajeError.text('El mínimo de caracteres permitido es ' + min);
|
||||
if (!input.parent().find('#error_minmaxcaracteres').length) {
|
||||
// El input tiene menos caracteres que el mínimo permitido, mostramos el mensaje de error
|
||||
input.parent().append(mensajeError);
|
||||
}
|
||||
// Actualizar el estado del campo a no válido (false)
|
||||
return false;
|
||||
} else if (input.val().length > max) {
|
||||
mensajeError.text('El máximo de caracteres permitido es ' + max);
|
||||
if (!input.parent().find('#error_minmaxcaracteres').length) {
|
||||
// El input tiene más caracteres que el máximo permitido, mostramos el mensaje de error
|
||||
input.parent().append(mensajeError);
|
||||
}
|
||||
// Actualizar el estado del campo a no válido (false)
|
||||
return false;
|
||||
} else {
|
||||
// El número de caracteres es válido, eliminamos cualquier mensaje de error previo
|
||||
input.parent().find('#error_minmaxcaracteres').remove();
|
||||
// Actualizar el estado del campo a válido (true)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function validarInputMinMaxExactosCaracteres(idInput, min, max) {
|
||||
var input = $('#' + idInput);
|
||||
var mensajeError = $('<div/>', {
|
||||
'class': 'text-danger',
|
||||
'id': 'error_minmaxexactoscaracteres'
|
||||
});
|
||||
|
||||
if (input.val().length === min || input.val().length === max) {
|
||||
// El número de caracteres es válido, eliminamos cualquier mensaje de error previo
|
||||
input.parent().find('#error_minmaxexactoscaracteres').remove();
|
||||
// Actualizar el estado del campo a válido (true)
|
||||
return true;
|
||||
} else {
|
||||
mensajeError.text('El campo debe tener exactamente ' + min + ' o ' + max + ' caracteres');
|
||||
if (!input.parent().find('#error_minmaxexactoscaracteres').length) {
|
||||
// El input tiene menos o más caracteres que los permitidos exactos, mostramos el mensaje de error
|
||||
input.parent().append(mensajeError);
|
||||
}
|
||||
// Actualizar el estado del campo a no válido (false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function validarInputDatalist(idInput) {
|
||||
var input = $('#' + idInput);
|
||||
var inputValue = input.val();
|
||||
|
||||
var mensajeError = $('<div/>', {
|
||||
'class': 'text-danger',
|
||||
'id': 'error_datalist',
|
||||
'text': 'Seleccione una opción válida.' // Mensaje de error por defecto
|
||||
});
|
||||
|
||||
if (inputValue === null || inputValue === undefined || inputValue.trim() === '') {
|
||||
mostrarOcultarError(input.parent(), mensajeError, true);
|
||||
return false;
|
||||
} else {
|
||||
mostrarOcultarError(input.parent(), mensajeError, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function mostrarOcultarError(contenedor, mensajeError, mostrar) {
|
||||
if (mostrar) {
|
||||
if (!contenedor.find('#error_datalist').length) {
|
||||
contenedor.append(mensajeError);
|
||||
}
|
||||
} else {
|
||||
contenedor.find('#error_datalist').remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Evento para ll
|
||||
|
||||
|
||||
//Funcion que valida el input por cada una de sus validaciones
|
||||
function validarCampo(idInput, validaciones) {
|
||||
var estadoCampos = JSON.parse(localStorage.getItem("estadoCampos")) || {};
|
||||
var campoValido = true; // Suponemos que el campo es válido hasta que se demuestre lo contrario
|
||||
|
||||
// Iterar sobre todas las validaciones
|
||||
validaciones.forEach(function (validacion) {
|
||||
var tipo = validacion.tipo;
|
||||
var parametros = validacion.parametros || {};
|
||||
|
||||
switch (tipo) {
|
||||
case "notEmpty":
|
||||
if (!validarInputNotEmpty(idInput)) {
|
||||
campoValido = false;
|
||||
}
|
||||
break;
|
||||
case "minMaxCaracteres":
|
||||
var min = parametros.min;
|
||||
var max = parametros.max;
|
||||
if (!validarInputMinMaxCaracteres(idInput, min, max)) {
|
||||
campoValido = false;
|
||||
}
|
||||
break;
|
||||
case "minMaxExactosCaracteres":
|
||||
var min = parametros.min;
|
||||
var max = parametros.max;
|
||||
if (!validarInputMinMaxExactosCaracteres(idInput, min, max)) {
|
||||
campoValido = false;
|
||||
}
|
||||
break;
|
||||
case "numerico":
|
||||
if (!validarInputNumerico(idInput)) {
|
||||
campoValido = false;
|
||||
}
|
||||
break;
|
||||
case "datalist":
|
||||
if (!validarInputDatalist(idInput)) {
|
||||
campoValido = false;
|
||||
}
|
||||
break;
|
||||
case "email":
|
||||
if (!validarInputEmail(idInput)) {
|
||||
campoValido = false;
|
||||
}
|
||||
break;
|
||||
// Agregar más casos según las validaciones que necesites
|
||||
default:
|
||||
console.error('Validación no reconocida: ' + tipo);
|
||||
}
|
||||
});
|
||||
|
||||
// Actualizar el estado del campo en el objeto estadoCampos
|
||||
estadoCampos[idInput] = campoValido;
|
||||
localStorage.setItem("estadoCampos", JSON.stringify(estadoCampos));
|
||||
|
||||
// Devolver true si el campo es válido, false si no lo es
|
||||
return campoValido;
|
||||
}
|
||||
|
||||
|
||||
// Función para adjuntar eventos de validación a un campo
|
||||
function eventAttacher(idInput, validaciones) {
|
||||
var input = $('#' + idInput);
|
||||
|
||||
// Asignar la función validarCampo a los eventos de input, blur y change
|
||||
input.on('input blur change', function () {
|
||||
validarCampo(idInput, validaciones);
|
||||
});
|
||||
}
|
||||
|
||||
// Función para manejar la visualización del asterisco rojo para campos requeridos
|
||||
function manejarAsteriscoRojo(input, validaciones) {
|
||||
var label;
|
||||
var redSpan;
|
||||
|
||||
// Buscar el label adecuado dependiendo del tipo de input
|
||||
if (input.attr('id').includes('fecha')) {
|
||||
label = input.closest('.fv-row').find('label');
|
||||
} else {
|
||||
label = input.closest('.fv-row').find('label');
|
||||
}
|
||||
|
||||
// Encontrar el span de error (si existe)
|
||||
redSpan = label.find('span.error-span');
|
||||
|
||||
// Verificar si hay validaciones de tipo notEmpty
|
||||
var contieneNotEmpty = validaciones.some(function (validation) {
|
||||
return validation.tipo === "notEmpty" || validation.tipo === "datalist";
|
||||
});
|
||||
|
||||
// Manejo de la lógica para agregar o quitar el asterisco rojo
|
||||
if (!contieneNotEmpty && validaciones.length > 0) {
|
||||
// No hay validaciones notEmpty, remover el asterisco si existe
|
||||
if (redSpan.length) {
|
||||
redSpan.remove();
|
||||
}
|
||||
} else if (contieneNotEmpty && validaciones.length > 0) {
|
||||
// Hay validaciones notEmpty, agregar el asterisco si no existe
|
||||
if (!redSpan.length) {
|
||||
label.append('<span class="error-span" style="color: red;">*</span>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
localStorage.setItem("estadoCampos", JSON.stringify({}));
|
||||
|
||||
// Inicializar el formulario
|
||||
function inicializarFormulario(campos) {
|
||||
// Objeto para almacenar el estado de cada campo
|
||||
var estadoCampos = JSON.parse(localStorage.getItem("estadoCampos")) || {};
|
||||
|
||||
localStorage.setItem("campos", JSON.stringify(campos));
|
||||
|
||||
// Recorrer los campos
|
||||
campos.forEach(function (campo) {
|
||||
// Obtener el input por su id
|
||||
var input = $('#' + campo.campo);
|
||||
var validaciones = campo.validaciones;
|
||||
|
||||
// Verificar si el campo ya existe en estadoCampos
|
||||
if (!(campo.campo in estadoCampos)) {
|
||||
// Si no existe, inicializar el estado del campo como false
|
||||
estadoCampos[campo.campo] = false;
|
||||
}
|
||||
|
||||
// Verificar si hay validaciones
|
||||
if (validaciones && validaciones.length > 0) {
|
||||
// Aplicar cada validación al input
|
||||
eventAttacher(campo.campo, validaciones);
|
||||
}
|
||||
|
||||
// Manejar la visualización del asterisco rojo para campos requeridos
|
||||
if (validaciones.some(function (validation) { return validation.tipo === "notEmpty" || validation.tipo === "datalist" })) {
|
||||
manejarAsteriscoRojo(input, validaciones)
|
||||
}
|
||||
});
|
||||
|
||||
// Eliminar campos en estadoCampos que no están presentes en la lista de campos proporcionada
|
||||
for (var campo in estadoCampos) {
|
||||
if (estadoCampos.hasOwnProperty(campo) && !campos.some(function (c) { return c.campo === campo; })) {
|
||||
delete estadoCampos[campo];
|
||||
}
|
||||
}
|
||||
|
||||
// Guardar el objeto actualizado en localStorage
|
||||
localStorage.setItem("estadoCampos", JSON.stringify(estadoCampos));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Base.DropZone 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
* Ver: https://www.cssscript.com/pure-js-dual-list-box-component/
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
DropZone : {
|
||||
|
||||
create: function (selector) {
|
||||
|
||||
$(selector).dropzone({
|
||||
success : function(file, response) {
|
||||
alert('Fichero cargado en dropZone');
|
||||
console.log("Fichero cargado en dropZone", file);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxDropZone = function () {
|
||||
|
||||
var dropZone = this;
|
||||
|
||||
return Base.DropZone._qxDropZone(dropZone);
|
||||
}
|
||||
});
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Base.Duallistbox 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
* Ver: https://www.cssscript.com/pure-js-dual-list-box-component/
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Duallistbox : {
|
||||
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.dualListbox);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
addEvent: function(value) {},
|
||||
removeEvent: function(value) {},
|
||||
availableTitle: 'Origen',
|
||||
selectedTitle: 'Destino',
|
||||
addButtonText: '<i class="bi bi-chevron-right"></i>',
|
||||
removeButtonText: '<i class="bi bi-chevron-left"></i>',
|
||||
addAllButtonText: '<i class="bi bi-chevron-double-right"></i>',
|
||||
removeAllButtonText: '<i class="bi bi-chevron-double-left"></i>',
|
||||
searchPlaceholder: 'Buscar',
|
||||
options: []
|
||||
};
|
||||
|
||||
let finallyOptions = $.extend(true, defaultOptions, options);
|
||||
let dualListbox = new DualListbox(selector, finallyOptions);
|
||||
|
||||
//Gurdar instancia
|
||||
$(selector).data('dualListboxInstance', dualListbox);
|
||||
|
||||
//Estilos a pp
|
||||
$(".dual-listbox__container > div:not('.dual-listbox__buttons')").addClass('col-5');
|
||||
$(".dual-listbox__buttons").addClass('col-2');
|
||||
$(".dual-listbox__buttons").prop('style', 'margin: 0px; padding: 5%;');
|
||||
$(".dual-listbox__available").prop('style', 'width: 100%;');
|
||||
$(".dual-listbox__selected").prop('style', 'width: 100%;');
|
||||
|
||||
return dualListbox;
|
||||
},
|
||||
|
||||
_qxDuallistbox : function (duallistbox) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Duallistbox 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
},
|
||||
reload: function (url, postData, callBackFunction) {
|
||||
|
||||
//recuperando instancia
|
||||
let dualListboxInstance = $(duallistbox).data('dualListboxInstance');
|
||||
|
||||
Base.ajax(
|
||||
url,
|
||||
postData,
|
||||
function (data)
|
||||
{
|
||||
|
||||
$("#subjectInstance").empty();
|
||||
dualListboxInstance.available = [];
|
||||
dualListboxInstance.selected = [];
|
||||
dualListboxInstance.options = [];
|
||||
|
||||
$.each(data, function (i, item) {
|
||||
|
||||
const option = '<option value="' + item.val + '" >' + item.txt + '</option>';
|
||||
duallistbox.append(option);
|
||||
|
||||
dualListboxInstance._addOption( {
|
||||
'text': item.txt,
|
||||
'value': item.val
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
dualListboxInstance.redraw();
|
||||
|
||||
if(callBackFunction != undefined && callBackFunction != null && $.isFunction(callBackFunction)) {
|
||||
|
||||
return callBackFunction(data);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxDuallistbox = function () {
|
||||
|
||||
var duallistbox = this;
|
||||
|
||||
return Base.Duallistbox._qxDuallistbox(duallistbox);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,532 @@
|
||||
/**
|
||||
* Base.Form 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Form : {
|
||||
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
if(options == undefined){
|
||||
options = {}
|
||||
}
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.form);
|
||||
|
||||
if (options != undefined && options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {};
|
||||
|
||||
return $(selector);
|
||||
},
|
||||
|
||||
_qxForm : function (form) {
|
||||
|
||||
return {
|
||||
|
||||
//Example $('selector').QxForm().ver()
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Form 1.0");
|
||||
console.log("Requiere: Base 1.0;");
|
||||
},
|
||||
|
||||
validate: function(options){
|
||||
|
||||
//Catch Submit Handler
|
||||
var submitHandler = options.submitHandler;
|
||||
delete options['submitHandler'];
|
||||
|
||||
var submitButton = options.submitButton;
|
||||
if(null == submitButton || undefined == submitButton){
|
||||
submitButton = $(form).find('button[actiontype="submit"]')[0];
|
||||
}
|
||||
delete options['submitButton'];
|
||||
|
||||
//Options
|
||||
var _defaultOptions = {
|
||||
setLabelErrorClass: true,
|
||||
labelErrorClass: 'required',
|
||||
fields: {},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
options = $.extend(true, _defaultOptions, options);
|
||||
|
||||
//Set Required class to Fields
|
||||
var newvaldiate = false;
|
||||
if(options.setLabelErrorClass) {
|
||||
$.each(options.fields, function (element, field) {
|
||||
|
||||
$.each(field.validators, function (key, value) {
|
||||
if (key == 'notEmpty') {
|
||||
|
||||
$(form).find("span[for=" + element + "]").addClass(options.labelErrorClass);
|
||||
|
||||
newvaldiate = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
//Validator
|
||||
var validator = FormValidation.formValidation(
|
||||
form[0],
|
||||
options
|
||||
);
|
||||
//Add Validator to Form
|
||||
$(form).data("QxValidator", validator);
|
||||
|
||||
if(submitButton == undefined){
|
||||
return validator;
|
||||
}
|
||||
|
||||
|
||||
//Default Validate-Submit Function
|
||||
var _submitForm = function(){
|
||||
|
||||
var formValidator = $(form).QxForm().validatorInstance;
|
||||
if (formValidator) {
|
||||
formValidator.validate().then(function (status) {
|
||||
|
||||
submitButton.disabled = true;
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable button to avoid multiple click
|
||||
submitButton.disabled = true;
|
||||
form.submit();
|
||||
} else {
|
||||
// Show error message.
|
||||
submitButton.disabled = false;
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Base.Alert.custom({
|
||||
text: "Errores detectados al validar el formulario, por favor intente nuevamente.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Volver al formulario!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
},
|
||||
callBackThen: function(result){
|
||||
KTUtil.scrollTop();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var formValidator = $(form).QxForm().validatorInstance;
|
||||
|
||||
//Custom Submit Handler
|
||||
if(submitHandler != undefined && submitHandler != null && $.isFunction(submitHandler)) {
|
||||
|
||||
return submitHandler(form[0], formValidator, submitButton);
|
||||
}
|
||||
//Default Submit Handler
|
||||
else{
|
||||
_submitForm();
|
||||
}
|
||||
});
|
||||
|
||||
return $(form).QxForm().validatorInstance;
|
||||
},
|
||||
|
||||
ajaxSubmit: function (options) {
|
||||
|
||||
// Base.Message.clear();
|
||||
//
|
||||
// var showLoading = (null != options.showLoading && options.showLoading != undefined) ? options.showLoading : true;
|
||||
// var loadingMessage = (null != options.loadingMessage && options.loadingMessage != undefined) ? options.loadingMessage : "Cargando...";
|
||||
//
|
||||
//
|
||||
// var _defaultAjaxOptions = {
|
||||
//
|
||||
// success: function (data, textStatus, jqXHR, form) {
|
||||
//
|
||||
// if(data.type == 'Success' || data.type == 'Warning' || data.type == 'Info') {
|
||||
//
|
||||
// if(data.message != null & data.message != "") {
|
||||
// Base.Message.flash(data.message, data.cssClass);
|
||||
// }
|
||||
//
|
||||
// bootbox.hideAll();
|
||||
// Base.Loading.hide();
|
||||
//
|
||||
// if(options.mySuccessCallBack != undefined && options.mySuccessCallBack != null && $.isFunction(options.mySuccessCallBack)) {
|
||||
//
|
||||
// return options.mySuccessCallBack(data);
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
// else if(data.type == 'Error' || data.type == 'Exception'){
|
||||
//
|
||||
// Base.Message.flash(data.message, data.cssClass, options.errorContainer);
|
||||
//
|
||||
// Base.Loading.hide();
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// var _ajaxOption = $.extend(true, _defaultAjaxOptions, options.ajaxFormOption);
|
||||
//
|
||||
// if(showLoading) {
|
||||
// Base.Loading.show({message: loadingMessage})
|
||||
// }
|
||||
//
|
||||
// $(form).ajaxSubmit(_ajaxOption);
|
||||
},
|
||||
|
||||
validatorInstance: $(form).data("QxValidator"),
|
||||
|
||||
validator : {
|
||||
callback: function(options){
|
||||
let defaultOptions = {
|
||||
message: "Campos con error",
|
||||
callback: function(n){return false;}
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
return options;
|
||||
},
|
||||
notEmpty: function(options){
|
||||
let defaultOptions = {
|
||||
message: 'Campo requerido' //gedux.i18n.gral.messages.required
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
return options
|
||||
},
|
||||
digits: function(options){
|
||||
let defaultOptions = {
|
||||
message: 'Por favor entre solo dígitos' //gedux.i18n.gral.messages.digits
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
return options
|
||||
},
|
||||
emailAddress: function(options){
|
||||
let defaultOptions = {
|
||||
message: 'Por favor entre una dirección válida' //gedux.i18n.gral.messages.email
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
return options
|
||||
},
|
||||
lessThan: function(options){
|
||||
if(options.max === undefined || options.max === null)
|
||||
{
|
||||
throw new Error('El atributo max es obligatorio')
|
||||
}
|
||||
|
||||
let defaultOptions = {
|
||||
max: 100000000000000000000, //infinitive by default
|
||||
message: 'Por favor entre un valor menor o igual que {0}' //gedux.i18n.gral.messages.max
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
|
||||
if(options.max !== undefined && options.max !== null)
|
||||
{
|
||||
if($.isFunction(options.max))
|
||||
{
|
||||
options.max = options.max()
|
||||
}
|
||||
options.message ='Por favor entre un valor menor o igual que ' // gedux.i18n.gral.messages.max.replace("{0}", options.max)
|
||||
}
|
||||
|
||||
return options
|
||||
},
|
||||
greaterThan: function(options){
|
||||
if(options.min === undefined || options.min === null)
|
||||
{
|
||||
throw new Error('El atributo min es obligatorio')
|
||||
}
|
||||
let defaultOptions = {
|
||||
min: -100000000000000000000, //infinitive by default
|
||||
message: 'Por favor entre un valor mayor o igual que {0}' //gedux.i18n.gral.messages.min
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
if(options.min !== undefined && options.min !== null)
|
||||
{
|
||||
if($.isFunction(options.min))
|
||||
{
|
||||
options.min = options.min()
|
||||
}
|
||||
options.message = 'Por favor entre un valor mayor o igual que' //gedux.i18n.gral.messages.min.replace("{0}", options.min)
|
||||
}
|
||||
|
||||
return options
|
||||
},
|
||||
stringLength: function(options){
|
||||
|
||||
let defaultOptions = {
|
||||
max: 250, //infinitive by default
|
||||
min: 0,
|
||||
message: 'Por favor entre un valor menor o igual que {0}' //gedux.i18n.gral.messages.max + " | " + gedux.i18n.gral.messages.min
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
let setMsgForMin = false
|
||||
if(options != undefined && options.min !== undefined && options.min !== null)
|
||||
{
|
||||
if($.isFunction(options.min))
|
||||
{
|
||||
options.min = options.min()
|
||||
}
|
||||
setMsgForMin = true
|
||||
options.message ='Por favor entre {0} o más characters' // gedux.i18n.gral.messages.minlength.replace("{0}", options.min)
|
||||
}
|
||||
if(options != undefined && options.max !== undefined && options.max !== null)
|
||||
{
|
||||
if($.isFunction(options.max))
|
||||
{
|
||||
options.max = options.max()
|
||||
}
|
||||
|
||||
if(!setMsgForMin){
|
||||
options.message ='Por favor no entre más de {0} characters' // gedux.i18n.gral.messages.maxlength.replace("{0}", options.max)
|
||||
}else{
|
||||
options.message = `Por favor, solo se admite entre ${options.min} y ${options.max} caracteres` //gedux.i18n.gral.messages.betweenlength.replace("{0}", options.min).replace("{1}", options.max)
|
||||
}
|
||||
}
|
||||
|
||||
return options
|
||||
},
|
||||
integer: function(options){
|
||||
let defaultOptions = {
|
||||
message: 'Por favor entre un valor entero' //gedux.i18n.gral.messages.integer
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
return options
|
||||
},
|
||||
identical: function(options){
|
||||
if(options.compare === undefined || options.compare === null)
|
||||
{
|
||||
throw new Error('El atributo compare es obligatorio')
|
||||
}
|
||||
let defaultOptions = {
|
||||
message:'Las constraseñas no coinciden' // gedux.i18n.gral.messages.equalTo
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
return options
|
||||
},
|
||||
email: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var value = $(input.element).val()
|
||||
|
||||
return value == '' || /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
|
||||
},
|
||||
message: 'Por favor entre una dirección válida' //gedux.i18n.gral.messages.email
|
||||
}
|
||||
},
|
||||
emailWithComa: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var value = $(input.element).val()
|
||||
|
||||
return value == '' || /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*(,[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)*$/.test(value);
|
||||
},
|
||||
message: 'Por favor entre una dirección válida' //gedux.i18n.gral.messages.email
|
||||
}
|
||||
},
|
||||
validMoney: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var value = $(input.element).val()
|
||||
|
||||
var exp = new RegExp("^(\\d{1,3})+(\\.\\d{2})?$","i");
|
||||
|
||||
return exp.test(value);
|
||||
},
|
||||
message: 'Por favor entre un monto correcto' //gedux.i18n.gral.messages.validMoney
|
||||
}
|
||||
},
|
||||
numberwithcomma: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var value = $(input.element).val()
|
||||
|
||||
var exp = new RegExp("^(?:\\d+,)*\\d+$","i");
|
||||
|
||||
return exp.test(value);
|
||||
},
|
||||
message: 'Por favor entre un valor numérico' //gedux.i18n.gral.messages.number
|
||||
}
|
||||
},
|
||||
strongpassword: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var value = $(input.element).val()
|
||||
|
||||
return (
|
||||
/.*([a-z]+)+.*/.test(value) &&
|
||||
/.*([A-Z]+)+.*/.test(value) &&
|
||||
/.*(\d+)+.*/.test(value) &&
|
||||
/.*([$@$!%*?&+_/-]+)+.*/.test(value)
|
||||
);
|
||||
},
|
||||
message: 'La contraseña debe tener al menos 8 o más caracteres con una combinación de letras, números y simbolos'
|
||||
}
|
||||
},
|
||||
number: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var value = $(input.element).val()
|
||||
|
||||
return $.isNumeric(value)
|
||||
},
|
||||
message: 'Por favor entre un valor numérico' //gedux.i18n.gral.messages.number
|
||||
}
|
||||
},
|
||||
curp: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var curp = $(input.element).val()
|
||||
|
||||
//Validar que coincida el dígito verificador
|
||||
function digitoVerificador(curp17) {
|
||||
//Fuente https://consultas.curp.gob.mx/CurpSP/
|
||||
var diccionario = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ",
|
||||
lngSuma = 0.0,
|
||||
lngDigito = 0.0;
|
||||
for(var i=0; i<17; i++)
|
||||
lngSuma = lngSuma + diccionario.indexOf(curp17.charAt(i)) * (18 - i);
|
||||
lngDigito = 10 - lngSuma % 10;
|
||||
if (lngDigito == 10) return 0;
|
||||
return lngDigito;
|
||||
}
|
||||
|
||||
var re = /^([A-Z][AEIOUX][A-Z]{2}\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])[HM](?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)[B-DF-HJ-NP-TV-Z]{3}[A-Z\d])(\d)$/,
|
||||
validado = curp.match(re);
|
||||
|
||||
if (!validado) //Coincide con el formato general?
|
||||
return false;
|
||||
|
||||
|
||||
if (validado[2] != digitoVerificador(validado[1]))
|
||||
return false;
|
||||
|
||||
return true; //Validado
|
||||
},
|
||||
message: "La CURP no tiene un formato valido"
|
||||
}
|
||||
},
|
||||
rfc: function(){
|
||||
return {
|
||||
callback: function(input){
|
||||
var rfc = $(input.element).val()
|
||||
|
||||
var rfc_pattern = /^(([A-ZÑ&]{3}|[A-ZÑ&]{4})([0-9]{2})(0[13578]|1[02])((0[1-9]|[12][0-9])|3[01])([A-Z0-9]{3}))|(([A-ZÑ&]{3}|[A-ZÑ&]{4})([0-9]{2})(0[13456789]|1[012])((0[1-9]|[12][0-9])|30)([A-Z0-9]{3}))|(([A-ZÑ&]{3}|[A-ZÑ&]{4})([02468][048]|[13579][26])0229([A-Z0-9]{3}))|(([A-ZÑ&]{3}|[A-ZÑ&]{4})([0-9]{2})0229([A-Z0-9]{3}))$/i;
|
||||
|
||||
var validado = rfc.match(rfc_pattern)
|
||||
if (validado == null){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
message: "La RFC no tiene un formato valido"
|
||||
}
|
||||
},
|
||||
numeric: function(options){
|
||||
let defaultOptions = {
|
||||
message: 'Por favor entre un valor numérico' //gedux.i18n.gral.messages.number
|
||||
}
|
||||
|
||||
options = $.extend(true, defaultOptions, options);
|
||||
|
||||
return options
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxForm = function () {
|
||||
|
||||
var form = this;
|
||||
|
||||
return Base.Form._qxForm(form);
|
||||
}
|
||||
|
||||
|
||||
// $.validator.addMethod( "email", function( value, element, params ) {
|
||||
//
|
||||
// return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
|
||||
//
|
||||
// }, "Please enter a valid email address.");
|
||||
//
|
||||
// $.validator.addMethod("validMoney",function(value,element,param){
|
||||
//
|
||||
// var exp= new RegExp("^(\\d{1,3})+(\\.\\d{2})?$","i");
|
||||
//
|
||||
// return this.optional(element) || exp.test(value);
|
||||
//
|
||||
// },"Por favor entre valor correcto");
|
||||
//
|
||||
// $.validator.addMethod("numberwithcomma",function(value,element,param){
|
||||
//
|
||||
// if(param==true){
|
||||
// var exp= new RegExp("^(?:\\d+,)*\\d+$","i");
|
||||
//
|
||||
// return this.optional(element) || exp.test(value);
|
||||
// }
|
||||
//
|
||||
// return this.optional(element);
|
||||
//
|
||||
// },"Por favor entre solo dígitos ó dígitos separados por comas");
|
||||
//
|
||||
// $.validator.addMethod("exactlydecimallength",function(value,element,param){
|
||||
//
|
||||
// var exp= new RegExp("^\\d+\.\\d{"+param+"}?$","i");
|
||||
//
|
||||
// return this.optional(element) || exp.test(value);
|
||||
//
|
||||
// },$.validator.format("Por favor entre exactamente {0} dígitos flotantes"));
|
||||
//
|
||||
// $.validator.addMethod("strongpassword", function(value, element) {
|
||||
//
|
||||
// return this.optional( element ) || (/.*([a-z]+)+.*/.test(value) && /.*([A-Z]+)+.*/.test(value));
|
||||
//
|
||||
// }, 'La contraseña debe tener al menos una Mayúscula y una Minúscula');
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Base.Hint 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Hint : {
|
||||
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.autocomplete);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
title: 'Mensaje',
|
||||
trigger: 'manual',
|
||||
delay: 3000,
|
||||
placement: 'auto', //auto | top | bottom | left | right
|
||||
container: 'body'
|
||||
};
|
||||
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
$(selector).attr('data-original-title', finallyOptions.title);
|
||||
$(selector).attr('data-placement', finallyOptions.placement);
|
||||
|
||||
$(selector).tooltip(finallyOptions);
|
||||
$(selector).tooltip('show');
|
||||
|
||||
setTimeout(function() {
|
||||
$(selector).tooltip('hide');
|
||||
},
|
||||
finallyOptions.delay);
|
||||
},
|
||||
|
||||
_qxHint : function (hint) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Hint 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxHint = function () {
|
||||
|
||||
var hint = this;
|
||||
|
||||
return Base.Modal._qxHint(hint);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"datatable" : {
|
||||
"actionColunmLabel" : "Acciones",
|
||||
"language": {
|
||||
"sProcessing": "Procesando...",
|
||||
"sLengthMenu": "_MENU_",
|
||||
"sZeroRecords": "No se encontraron resultados",
|
||||
"sEmptyTable": "Ningún dato disponible en esta tabla",
|
||||
"sInfo": "Mostrando _START_ al _END_ de un total de _TOTAL_",
|
||||
"sInfoEmpty": "No hay registros",
|
||||
"sInfoFiltered": "(filtrado de un total de _MAX_ registros)",
|
||||
"sInfoPostFix": "",
|
||||
"sSearch": "Buscar:",
|
||||
"sUrl": "",
|
||||
"sInfoThousands": ",",
|
||||
"sLoadingRecords": "Cargando...",
|
||||
"oPaginate": {
|
||||
"sFirst": "Primero",
|
||||
"sLast": "Último",
|
||||
"sNext": "Siguiente",
|
||||
"sPrevious": "Anterior"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": Activar para ordenar la columna de manera ascendente",
|
||||
"sSortDescending": ": Activar para ordenar la columna de manera descendente"
|
||||
}
|
||||
}
|
||||
},
|
||||
"buttons" : {
|
||||
"Icon": {
|
||||
"editTitle" : "Editar",
|
||||
"viewTitle" : "Ver"
|
||||
}
|
||||
},
|
||||
"modal":{
|
||||
|
||||
},
|
||||
"select":{
|
||||
|
||||
},
|
||||
"autocomplete":{
|
||||
|
||||
},
|
||||
"date":{
|
||||
|
||||
},
|
||||
"colorpick": {
|
||||
|
||||
},
|
||||
"dualListbox": {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"datatable" : {
|
||||
"actionColunmLabel" : "Acciones",
|
||||
"language": {
|
||||
"sProcessing": "Procesando...",
|
||||
"sLengthMenu": "_MENU_",
|
||||
"sZeroRecords": "No se encontraron resultados",
|
||||
"sEmptyTable": "Ningún dato disponible en esta tabla",
|
||||
"sInfo": "Mostrando _START_ al _END_ de un total de _TOTAL_",
|
||||
"sInfoEmpty": "No hay registros",
|
||||
"sInfoFiltered": "(filtrado de un total de _MAX_ registros)",
|
||||
"sInfoPostFix": "",
|
||||
"sSearch": "Buscar:",
|
||||
"sUrl": "",
|
||||
"sInfoThousands": ",",
|
||||
"sLoadingRecords": "Cargando...",
|
||||
"oPaginate": {
|
||||
"sFirst": "Primero",
|
||||
"sLast": "Último",
|
||||
"sNext": "Siguiente",
|
||||
"sPrevious": "Anterior"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": Activar para ordenar la columna de manera ascendente",
|
||||
"sSortDescending": ": Activar para ordenar la columna de manera descendente"
|
||||
}
|
||||
}
|
||||
},
|
||||
"buttons" : {
|
||||
"Icon": {
|
||||
"editTitle" : "Editar",
|
||||
"viewTitle" : "Ver"
|
||||
}
|
||||
},
|
||||
"modal":{
|
||||
|
||||
},
|
||||
"select":{
|
||||
|
||||
},
|
||||
"autocomplete":{
|
||||
|
||||
},
|
||||
"date":{
|
||||
|
||||
},
|
||||
"colorpick": {
|
||||
|
||||
},
|
||||
"dualListbox": {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Base.Kanban 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Kanban : {
|
||||
|
||||
create: function (idKanban, options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
if(options == undefined){
|
||||
options = {}
|
||||
}
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.kanban);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
element: '#' + idKanban, // selector of the kanban container
|
||||
gutter : '15px', // gutter of the board
|
||||
widthBoard : '250px', // width of the board
|
||||
responsivePercentage: false, // if it is true I use percentage in the width of the boards and it is not necessary gutter and widthBoard
|
||||
dragItems : true, // if false, all items are not draggable
|
||||
boards : [], // json of boards
|
||||
dragBoards : true, // the boards are draggable, if false only item can be dragged
|
||||
itemAddOptions: {
|
||||
enabled: false, // add a button to board for easy item creation
|
||||
content: '+', // text or html content of the board button
|
||||
class: 'kanban-title-button btn btn-default btn-xs', // default class of the button
|
||||
footer: false // position the button on footer
|
||||
}, // text or html content of the board button
|
||||
itemHandleOptions: {
|
||||
enabled : false, // if board item handle is enabled or not
|
||||
handleClass : "item_handle", // css class for your custom item handle
|
||||
customCssHandler : "drag_handler", // when customHandler is undefined, jKanban will use this property to set main handler class
|
||||
customCssIconHandler: "drag_handler_icon", // when customHandler is undefined, jKanban will use this property to set main icon handler class. If you want, you can use font icon libraries here
|
||||
customHandler : "<span class='item_handle'>+</span> %s"// your entirely customized handler. Use %s to position item title
|
||||
},
|
||||
click : function (el) {}, // callback when any board's item are clicked
|
||||
dragEl : function (el, source) {}, // callback when any board's item are dragged
|
||||
dragendEl : function (el) {}, // callback when any board's item stop drag
|
||||
dropEl : function (el, target, source, sibling) {}, // callback when any board's item drop in a board
|
||||
dragBoard : function (el, source) {}, // callback when any board stop drag
|
||||
dragendBoard : function (el) {}, // callback when any board stop drag
|
||||
buttonClick : function(el, boardId) {}, // callback when the board's button is clicked
|
||||
propagationHandlers: [], // the specified callback does not cancel the browser event. possible values: "click", "context"
|
||||
};
|
||||
|
||||
//Now take a look to the boards object
|
||||
// [
|
||||
// {
|
||||
// "id" : "board-id-1", // id of the board
|
||||
// "title" : "Board Title", // title of the board
|
||||
// "class" : "class1,class2,...", // css classes to add at the title
|
||||
// "dragTo": ['another-board-id',...], // array of ids of boards where items can be dropped (default: [])
|
||||
// "item" : [ // item of this board
|
||||
// {
|
||||
// "id" : "item-id-1", // id of the item
|
||||
// "title" : "Item 1" // title of the item
|
||||
// "class" : ["myClass",...] // array of additional classes
|
||||
// },
|
||||
// {
|
||||
// "id" : "item-id-2",
|
||||
// "title" : "Item 2"
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// "id" : "board-id-2",
|
||||
// "title" : "Board Title 2"
|
||||
// }
|
||||
// ]
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
var kanban = new jKanban(finallyOptions);
|
||||
|
||||
return kanban;
|
||||
},
|
||||
|
||||
_qxKanban : function (kanban) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Kanban 1.0");
|
||||
console.log("Requiere: Base 1.0;");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.qxKanban = function () {
|
||||
|
||||
var kanban = this;
|
||||
|
||||
return Base.Kanban._qxKanban(kanban);
|
||||
}
|
||||
});
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* Base.Box 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Loading: {
|
||||
|
||||
_buildMessage: function(options){
|
||||
|
||||
message = options.message;
|
||||
|
||||
if(options.spinner){
|
||||
message = '<span class="spinner-border ' + options.spinnerClass + '"></span>' + message;
|
||||
}
|
||||
|
||||
if(options.blockMessage){
|
||||
message = '<div class="blockui-message">' + message + '</div>';
|
||||
}
|
||||
|
||||
return message;
|
||||
},
|
||||
|
||||
show: function (options) {
|
||||
|
||||
var _i18n = {};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.loading);
|
||||
|
||||
if(undefined == options)
|
||||
options = {};
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
zIndex: false,
|
||||
message: '<div class="blockui-message"><span class="spinner-border text-primary"></span> Cargando...</div>',
|
||||
overlayClass: null,
|
||||
overflow: 'hidden',
|
||||
spinner: true,
|
||||
spinnerClass: 'text-primary',
|
||||
blockMessage: true
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
finallyOptions.message = this._buildMessage(finallyOptions);
|
||||
var targetContent = document.querySelector("#kt_content");
|
||||
var targetPopup = document.querySelector(".bootbox-dialog .modal-content");
|
||||
|
||||
var target = targetPopup ? targetPopup : targetContent;
|
||||
|
||||
var blockUI = KTBlockUI.getInstance(target);
|
||||
|
||||
if(!blockUI)
|
||||
blockUI = new KTBlockUI(target, finallyOptions);
|
||||
|
||||
if (!blockUI.isBlocked())
|
||||
blockUI.block();
|
||||
|
||||
return blockUI;
|
||||
},
|
||||
|
||||
showInBlock: function (target, options) {
|
||||
|
||||
var _i18n = {};
|
||||
|
||||
if(undefined == options)
|
||||
options = {};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.loading);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
zIndex: false,
|
||||
message: '<div class="blockui-message"><span class="spinner-border text-primary"></span> Cargando...</div>',
|
||||
overlayClass: null,
|
||||
overflow: 'hidden'
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
finallyOptions.message = this._buildMessage(finallyOptions);
|
||||
var targetElement = document.querySelector(target);
|
||||
var blockUI = KTBlockUI.getInstance(targetElement);
|
||||
|
||||
if(!blockUI)
|
||||
blockUI = new KTBlockUI(targetElement, finallyOptions);
|
||||
|
||||
if (!blockUI.isBlocked())
|
||||
blockUI.block();
|
||||
|
||||
return blockUI;
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
|
||||
var targetContent = document.querySelector("#kt_content");
|
||||
var targetPopup = document.querySelector(".bootbox-dialog .modal-content");
|
||||
var target = targetPopup ? targetPopup : targetContent;
|
||||
|
||||
var blockUI = KTBlockUI.getInstance(target);
|
||||
|
||||
if(blockUI){
|
||||
blockUI.release();
|
||||
blockUI.destroy();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
hideInBlock: function(target){
|
||||
|
||||
var targetElement = document.querySelector(target);
|
||||
var blockUI = KTBlockUI.getInstance(targetElement);
|
||||
|
||||
if(blockUI){
|
||||
blockUI.release();
|
||||
blockUI.destroy();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
progress: function(target, options){
|
||||
var _i18n = {};
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.loading);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
opacity: 0.05,
|
||||
state: 'dark',
|
||||
centerX: true,
|
||||
centerY: true,
|
||||
shadow: true,
|
||||
width: 'auto',
|
||||
overlayColor: '#000000',
|
||||
type: 'v2',
|
||||
state: 'success',
|
||||
message: '',
|
||||
size: 'lg',
|
||||
closeButton: false
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
KTApp.progress(target, finallyOptions);
|
||||
},
|
||||
|
||||
unprogress: function(target){
|
||||
|
||||
KTApp.unprogress(target);
|
||||
},
|
||||
|
||||
_qxLoading: function (box) {
|
||||
|
||||
return {
|
||||
|
||||
ver: function () {
|
||||
|
||||
console.log("Base.Loading 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxLoading = function () {
|
||||
|
||||
var loading = this;
|
||||
|
||||
return Base.Box._qxLoading(loading);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Base.Message 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Message : {
|
||||
|
||||
Type: {
|
||||
Success : 'success',
|
||||
Error: 'error', //alert-danger
|
||||
Info: 'info',
|
||||
Warning: 'warning',
|
||||
Exception: 'alert-danger' //alert-danger
|
||||
},
|
||||
|
||||
flash: function (message, type) {
|
||||
|
||||
Base.Message.custom(message, type, {});
|
||||
},
|
||||
|
||||
custom: function(message, type, options){
|
||||
|
||||
console.log(message);
|
||||
console.log(type);
|
||||
|
||||
//Option Convert/Compatibility
|
||||
var convertOptions = {};
|
||||
if(options != undefined){
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
closeButton: true,
|
||||
debug: false,
|
||||
newestOnTop: true,
|
||||
progressBar: false,
|
||||
positionClass: "toastr-top-right",
|
||||
preventDuplicates: true,
|
||||
showDuration: 300,
|
||||
hideDuration: 1000,
|
||||
timeOut: 5000,
|
||||
extendedTimeOut: 5000,
|
||||
showEasing: "swing",
|
||||
hideEasing: "linear",
|
||||
showMethod: "fadeIn",
|
||||
hideMethod: "fadeOut",
|
||||
onclick: null,
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options, convertOptions);
|
||||
|
||||
toastr.options = finallyOptions;
|
||||
|
||||
toastr[type](message);
|
||||
},
|
||||
|
||||
clear: function(container){
|
||||
|
||||
toastr.clear();
|
||||
},
|
||||
|
||||
_qxMessage : function (message) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Message 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxMessage = function () {
|
||||
|
||||
var message = this;
|
||||
|
||||
return Base.Modal._qxMessage(message);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Base.Print 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Print : {
|
||||
|
||||
//Los Datos debende vernir en un Json {id: '', label : ''}
|
||||
print: function (printable, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
|
||||
if(null == options || options == undefined){
|
||||
options = {};
|
||||
}
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.print);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
|
||||
var defaultOptions = {
|
||||
printable: printable,
|
||||
type: 'pdf',
|
||||
showModal: true,
|
||||
modalMessage: 'Cargando archivo ...',
|
||||
properties: {mumCopies: 1}
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
printJS(finallyOptions);
|
||||
},
|
||||
|
||||
_qxPrint : function (print) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Print 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxPrint = function () {
|
||||
|
||||
var print = this;
|
||||
|
||||
return Base.Modal._qxPrint(print);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* Base.Select 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function () {
|
||||
|
||||
$.extend(Base, {
|
||||
Select: {
|
||||
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
language: {}
|
||||
};
|
||||
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.select);
|
||||
|
||||
if (options != undefined && options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
allowClear: true,
|
||||
closeOnSelect: true
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return $(selector).select2(finallyOptions);
|
||||
},
|
||||
|
||||
_qxSelect: function (select) {
|
||||
|
||||
return {
|
||||
|
||||
ver: function () {
|
||||
|
||||
console.log("Base.Select 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
},
|
||||
|
||||
reset: function (defaultOption) {
|
||||
|
||||
defaultOption = (defaultOption == undefined) ? null : defaultOption;
|
||||
|
||||
$(select).val(defaultOption);
|
||||
$(select).trigger("change");
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
|
||||
$(select).empty();
|
||||
$(select).trigger("change");
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
|
||||
$(select).select2("destroy");
|
||||
},
|
||||
|
||||
|
||||
reload: function (url, postData, callBackFunction) {
|
||||
Base.ajax(
|
||||
url,
|
||||
postData,
|
||||
function (data) {
|
||||
$(select).empty();
|
||||
|
||||
if (!$(select).prop('multiple'))
|
||||
select.append("<option></option>");
|
||||
|
||||
$.each(data, function (i, item) {
|
||||
|
||||
var addSelected = "";
|
||||
if (item.selected) {
|
||||
addSelected = ' selected="selected" '
|
||||
}
|
||||
|
||||
var option = '<option '
|
||||
+ 'value="' + item.val + '" '
|
||||
|
||||
+ addSelected
|
||||
|
||||
+ 'data-one="' + item.dataOne + '" '
|
||||
+ 'data-tow="' + item.dataTow + '" '
|
||||
+ 'data-three="' + item.dataThree + '"'
|
||||
+ 'data-four="' + item.dataFour + '"'
|
||||
+ 'data-five="' + item.dataFive + '"'
|
||||
+ '>'
|
||||
+ item.txt
|
||||
+ '</option>';
|
||||
|
||||
select.append(option);
|
||||
});
|
||||
|
||||
$(select).trigger("change");
|
||||
|
||||
if (callBackFunction != undefined && callBackFunction != null && $.isFunction(callBackFunction)) {
|
||||
|
||||
return callBackFunction(data);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
advange: function (url, defaultValue, postData) {
|
||||
$(select).select2({
|
||||
minimumInputLength: 0,
|
||||
triggerChange: true,
|
||||
data: [
|
||||
{ // Each of these gets processed by fnRenderResults.
|
||||
id: defaultValue.id,
|
||||
text: defaultValue.text,
|
||||
selected: true // Causes the selection to actually get selected.
|
||||
}
|
||||
],
|
||||
ajax: {
|
||||
url: url,
|
||||
delay: 0,
|
||||
data: function (params) {
|
||||
return {
|
||||
q: params.term, // search term
|
||||
page: params.page,
|
||||
value_1: postData.value_1,
|
||||
value_2: postData.value_2
|
||||
};
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
// parse the results into the format expected by Select2
|
||||
// since we are using custom formatting functions we do not need to
|
||||
// alter the remote JSON data, except to indicate that infinite
|
||||
// scrolling can be used
|
||||
params.page = params.page || 1;
|
||||
return {
|
||||
results: data,
|
||||
pagination: {
|
||||
more: (params.page * 10) < data.total_count
|
||||
}
|
||||
};
|
||||
},
|
||||
cache: true
|
||||
}
|
||||
});
|
||||
$(select).val(defaultValue.id).trigger("change.select2");
|
||||
},
|
||||
|
||||
advange_with_button: function (url, defaultValue, postData, addUrl) {
|
||||
$(select).select2({
|
||||
minimumInputLength: 0,
|
||||
triggerChange: true,
|
||||
data: [
|
||||
{ // Each of these gets processed by fnRenderResults.
|
||||
id: defaultValue.id,
|
||||
text: defaultValue.text,
|
||||
selected: true // Causes the selection to actually get selected.
|
||||
}
|
||||
],
|
||||
ajax: {
|
||||
url: url,
|
||||
delay: 0,
|
||||
data: function (params) {
|
||||
return {
|
||||
q: params.term, // search term
|
||||
page: params.page,
|
||||
value_1: postData.value_1,
|
||||
value_2: postData.value_2
|
||||
};
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
// parse the results into the format expected by Select2
|
||||
// since we are using custom formatting functions we do not need to
|
||||
// alter the remote JSON data, except to indicate that infinite
|
||||
// scrolling can be used
|
||||
params.page = params.page || 1;
|
||||
return {
|
||||
results: data,
|
||||
pagination: {
|
||||
more: (params.page * 10) < data.total_count
|
||||
}
|
||||
};
|
||||
},
|
||||
cache: true
|
||||
},
|
||||
language: {
|
||||
noResults: function () {
|
||||
return $('<div>No se encontraron resultados. <a href="' + addUrl + '">Adicionar nuevo</a></div>');
|
||||
}
|
||||
},
|
||||
});
|
||||
$(select).val(defaultValue.id).trigger("change.select2");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxSelect = function () {
|
||||
|
||||
var select = this;
|
||||
|
||||
return Base.Select._qxSelect(select);
|
||||
}
|
||||
});
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Base.Autocomplete 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
* https://sweetalert2.github.io/#configuration
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
$.extend(Base, {
|
||||
Alert : {
|
||||
|
||||
simple: function(message, text, type){
|
||||
|
||||
//Type: warning error success info question
|
||||
Swal.fire(message, text, type);
|
||||
},
|
||||
|
||||
custom: function (options) {
|
||||
|
||||
//Option Convert/Compatibility
|
||||
var convertOptions = {};
|
||||
if(options != undefined){
|
||||
if(options.type != undefined){
|
||||
convertOptions.icon = options.type;
|
||||
delete options['type'];
|
||||
}
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
title: "",
|
||||
text: "",
|
||||
icon: "success", //warning error success info question
|
||||
|
||||
buttonsStyling: true,
|
||||
showCloseButton: false,
|
||||
reverseButtons: false,
|
||||
customClass: {
|
||||
},
|
||||
|
||||
backdrop: false,
|
||||
toast: false,
|
||||
allowEscapeKey: false,
|
||||
allowEnterKey: false,
|
||||
|
||||
showConfirmButton: true,
|
||||
confirmButtonText: "Aceptar",
|
||||
focusConfirm: false,
|
||||
|
||||
showDenyButton: false,
|
||||
denyButtonText: "Denegar",
|
||||
focusDeny: false,
|
||||
|
||||
showCancelButton: false,
|
||||
cancelButtonText: "Cancelar",
|
||||
focusCancel: false,
|
||||
|
||||
callBackThen: null
|
||||
};
|
||||
switch (defaultOptions.type) {
|
||||
case "warning": {
|
||||
defaultOptions.title = gedux.i18n.gral.title.warning
|
||||
}break;
|
||||
case "error": {
|
||||
defaultOptions.title = gedux.i18n.gral.title.error
|
||||
}break;
|
||||
case "success": {
|
||||
defaultOptions.title = gedux.i18n.gral.title.success
|
||||
}break;
|
||||
case "info": {
|
||||
defaultOptions.title = gedux.i18n.gral.title.info
|
||||
}break;
|
||||
case "question": {
|
||||
defaultOptions.title = gedux.i18n.gral.title.question
|
||||
}break;
|
||||
}
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options, convertOptions);
|
||||
|
||||
|
||||
Swal.fire(finallyOptions)
|
||||
.then(function(result){
|
||||
|
||||
if(finallyOptions.callBackThen != undefined && finallyOptions.callBackThen != null && $.isFunction(finallyOptions.callBackThen)) {
|
||||
|
||||
return finallyOptions.callBackThen(result);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_qxAlert : function (swalert) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Alert 1.0");
|
||||
console.log("Requiere: Base 1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxAlert = function () {
|
||||
|
||||
var swalert = this;
|
||||
|
||||
return Base.Alert._qxAlert(swalert);
|
||||
}
|
||||
});
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Base.Touchspin 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Touchspin : {
|
||||
|
||||
create: function (selector, options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
if(options == undefined){
|
||||
options = {}
|
||||
}
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.touchspin);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 1,
|
||||
decimals: 0
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
return $(selector).TouchSpin(finallyOptions);
|
||||
},
|
||||
|
||||
_qxTouchspin : function (touchspin) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Touchspin 1.0");
|
||||
console.log("Requiere: Base 1.0;");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.qxTouchspin = function () {
|
||||
|
||||
var touchspin = this;
|
||||
|
||||
return Base.Touchspin._qxTouchspin(touchspin);
|
||||
}
|
||||
});
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Base.Typedjs 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Typedjs : {
|
||||
|
||||
create: function (idSelector, options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
if(options == undefined){
|
||||
options = {}
|
||||
}
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.typedjs);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
var defaultOptions = {
|
||||
strings: [],
|
||||
typeSpeed: 30 // the specified callback does not cancel the browser event. possible values: "click", "context"
|
||||
};
|
||||
|
||||
//All options
|
||||
// {
|
||||
// /**
|
||||
// * @property {array} strings strings to be typed
|
||||
// * @property {string} stringsElement ID of element containing string children
|
||||
// */
|
||||
// strings: [
|
||||
// 'These are the default values...',
|
||||
// 'You know what you should do?',
|
||||
// 'Use your own!',
|
||||
// 'Have a great day!'
|
||||
// ],
|
||||
// stringsElement: null,
|
||||
//
|
||||
// /**
|
||||
// * @property {number} typeSpeed type speed in milliseconds
|
||||
// */
|
||||
// typeSpeed: 0,
|
||||
//
|
||||
// /**
|
||||
// * @property {number} startDelay time before typing starts in milliseconds
|
||||
// */
|
||||
// startDelay: 0,
|
||||
//
|
||||
// /**
|
||||
// * @property {number} backSpeed backspacing speed in milliseconds
|
||||
// */
|
||||
// backSpeed: 0,
|
||||
//
|
||||
// /**
|
||||
// * @property {boolean} smartBackspace only backspace what doesn't match the previous string
|
||||
// */
|
||||
// smartBackspace: true,
|
||||
//
|
||||
// /**
|
||||
// * @property {boolean} shuffle shuffle the strings
|
||||
// */
|
||||
// shuffle: false,
|
||||
//
|
||||
// /**
|
||||
// * @property {number} backDelay time before backspacing in milliseconds
|
||||
// */
|
||||
// backDelay: 700,
|
||||
//
|
||||
// /**
|
||||
// * @property {boolean} fadeOut Fade out instead of backspace
|
||||
// * @property {string} fadeOutClass css class for fade animation
|
||||
// * @property {boolean} fadeOutDelay Fade out delay in milliseconds
|
||||
// */
|
||||
// fadeOut: false,
|
||||
// fadeOutClass: 'typed-fade-out',
|
||||
// fadeOutDelay: 500,
|
||||
//
|
||||
// /**
|
||||
// * @property {boolean} loop loop strings
|
||||
// * @property {number} loopCount amount of loops
|
||||
// */
|
||||
// loop: false,
|
||||
// loopCount: Infinity,
|
||||
//
|
||||
// /**
|
||||
// * @property {boolean} showCursor show cursor
|
||||
// * @property {string} cursorChar character for cursor
|
||||
// * @property {boolean} autoInsertCss insert CSS for cursor and fadeOut into HTML <head>
|
||||
// */
|
||||
// showCursor: true,
|
||||
// cursorChar: '|',
|
||||
// autoInsertCss: true,
|
||||
//
|
||||
// /**
|
||||
// * @property {string} attr attribute for typing
|
||||
// * Ex: input placeholder, value, or just HTML text
|
||||
// */
|
||||
// attr: null,
|
||||
//
|
||||
// /**
|
||||
// * @property {boolean} bindInputFocusEvents bind to focus and blur if el is text input
|
||||
// */
|
||||
// bindInputFocusEvents: false,
|
||||
//
|
||||
// /**
|
||||
// * @property {string} contentType 'html' or 'null' for plaintext
|
||||
// */
|
||||
// contentType: 'html',
|
||||
//
|
||||
// /**
|
||||
// * Before it begins typing
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onBegin: (self) => {},
|
||||
//
|
||||
// /**
|
||||
// * All typing is complete
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onComplete: (self) => {},
|
||||
//
|
||||
// /**
|
||||
// * Before each string is typed
|
||||
// * @param {number} arrayPos
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// preStringTyped: (arrayPos, self) => {},
|
||||
//
|
||||
// /**
|
||||
// * After each string is typed
|
||||
// * @param {number} arrayPos
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onStringTyped: (arrayPos, self) => {},
|
||||
//
|
||||
// /**
|
||||
// * During looping, after last string is typed
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onLastStringBackspaced: (self) => {},
|
||||
//
|
||||
// /**
|
||||
// * Typing has been stopped
|
||||
// * @param {number} arrayPos
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onTypingPaused: (arrayPos, self) => {},
|
||||
//
|
||||
// /**
|
||||
// * Typing has been started after being stopped
|
||||
// * @param {number} arrayPos
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onTypingResumed: (arrayPos, self) => {},
|
||||
//
|
||||
// /**
|
||||
// * After reset
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onReset: (self) => {},
|
||||
//
|
||||
// /**
|
||||
// * After stop
|
||||
// * @param {number} arrayPos
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onStop: (arrayPos, self) => {},
|
||||
//
|
||||
// /**
|
||||
// * After start
|
||||
// * @param {number} arrayPos
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onStart: (arrayPos, self) => {},
|
||||
//
|
||||
// /**
|
||||
// * After destroy
|
||||
// * @param {Typed} self
|
||||
// */
|
||||
// onDestroy: (self) => {}
|
||||
// }
|
||||
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
var typed = new Typed(idSelector, finallyOptions);
|
||||
|
||||
return typed;
|
||||
},
|
||||
|
||||
_qxTypedjs : function (kanban) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Typedjs 1.0");
|
||||
console.log("Requiere: Base 1.0;");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.qxTypedjs = function () {
|
||||
|
||||
var typedjs = this;
|
||||
|
||||
return Base.Kanban._qxTypedjs(typedjs);
|
||||
}
|
||||
});
|
||||
+1290
File diff suppressed because it is too large
Load Diff
+159
@@ -0,0 +1,159 @@
|
||||
(function ( $ ) {
|
||||
|
||||
$.fn.bootcomplete = function(options) {
|
||||
|
||||
var defaults = {
|
||||
url : "",
|
||||
method : 'POST',
|
||||
wrapperClass : "bc-wrapper",
|
||||
menuClass : "bc-menu",
|
||||
idField : true,
|
||||
idFieldName : $(this).attr('name')+"_id",
|
||||
minLength : 3,
|
||||
dataParams : {},
|
||||
formParams : {},
|
||||
functionParams : null,
|
||||
clearIdFieldOnKeyUp: true
|
||||
}
|
||||
|
||||
var settings = $.extend( {}, defaults, options );
|
||||
|
||||
$(this).attr('autocomplete','off')
|
||||
$(this).wrap('<div class="'+settings.wrapperClass+'"></div>')
|
||||
|
||||
if (settings.idField) {
|
||||
if ($(this).parent().parent().find('input[name="' + settings.idFieldName + '"]').length !== 0) {
|
||||
//use existing id field
|
||||
} else {
|
||||
//there is no existing id field so create one
|
||||
$('<input type="hidden" name="' + settings.idFieldName + '" value="">').insertBefore($(this))
|
||||
}
|
||||
}
|
||||
|
||||
$('<div class="'+settings.menuClass+' list-group"></div>').insertAfter($(this))
|
||||
|
||||
$(this).on("keyup", searchQuery);
|
||||
$(this).on("focusout", hideThat)
|
||||
|
||||
var xhr;
|
||||
var that = $(this)
|
||||
|
||||
function hideThat() {
|
||||
if ($('.list-group-item' + ':hover').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var containerResult = $(that).next('.'+settings.menuClass);
|
||||
|
||||
if(containerResult.length == 0){
|
||||
containerResult = $(that).next().next('.'+settings.menuClass);
|
||||
}
|
||||
|
||||
containerResult.hide();
|
||||
}
|
||||
|
||||
function searchQuery(){
|
||||
if (settings.idField && settings.clearIdFieldOnKeyUp) {
|
||||
if ($(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').length !== 0) {
|
||||
//use existed id field
|
||||
$(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').val("");
|
||||
|
||||
// by froilan
|
||||
$(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').trigger('change');
|
||||
}
|
||||
else {
|
||||
//use created id field
|
||||
$(that).prev('input[name="' + settings.idFieldName + '"]').val("");
|
||||
|
||||
//by froilan
|
||||
$(that).prev('input[name="' + settings.idFieldName + '"]').trigger('change');
|
||||
}
|
||||
}
|
||||
|
||||
var arr = [];
|
||||
$.each(settings.formParams,function(k,v){
|
||||
arr[k]=$(v).val();
|
||||
})
|
||||
var dyFormParams = $.extend({}, arr );
|
||||
|
||||
var dyDynamicParams = {};
|
||||
if(settings.functionParams != undefined && settings.functionParams != null && $.isFunction(settings.functionParams)) {
|
||||
|
||||
dyDynamicParams = settings.functionParams();
|
||||
}
|
||||
|
||||
//Build Data
|
||||
var Data = $.extend({search: $(this).val()}, settings.dataParams, dyFormParams, dyDynamicParams);
|
||||
|
||||
if(!Data.search){
|
||||
$(this).next('.'+settings.menuClass).html('')
|
||||
$(this).next('.'+settings.menuClass).hide()
|
||||
}
|
||||
|
||||
Data.search = Data.search.trim();
|
||||
if(Data.search.length >= settings.minLength){
|
||||
|
||||
if(xhr && xhr.readyState != 4){
|
||||
xhr.abort();
|
||||
}
|
||||
|
||||
xhr = $.ajax({
|
||||
type: settings.method,
|
||||
url: settings.url,
|
||||
data: JSON.stringify(Data),
|
||||
dataType: "json",
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
success: function( json ) {
|
||||
var results = ''
|
||||
$.each( json, function(i, j) {
|
||||
results += '<a href="#" class="list-group-item" data-id="'+j.id+'" data-label="'+j.label+'">'+j.label+'</a>'
|
||||
});
|
||||
|
||||
|
||||
var containerResult = $(that).next('.'+settings.menuClass);
|
||||
|
||||
if(containerResult.length == 0){
|
||||
containerResult = $(that).next().next('.'+settings.menuClass);
|
||||
}
|
||||
|
||||
|
||||
$(containerResult).html(results);
|
||||
$(containerResult).children().on("click", selectResult);
|
||||
$(containerResult).show();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function selectResult(){
|
||||
$(that).val($(this).data('label'));
|
||||
if (settings.idField) {
|
||||
if ($(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').length !== 0) {
|
||||
//use existed id field
|
||||
$(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').val($(this).data('id'));
|
||||
//ensure we trigger the onchange so we can do stuff
|
||||
$(that).parent().parent().find('input[name="' + settings.idFieldName + '"]').trigger('change');
|
||||
}
|
||||
else {
|
||||
//use created id field
|
||||
$(that).prev('input[name="' + settings.idFieldName + '"]').val($(this).data('id'));
|
||||
//ensure we trigger the onchange so we can do stuff
|
||||
$(that).prev('input[name="' + settings.idFieldName + '"]').trigger('change');
|
||||
}
|
||||
}
|
||||
|
||||
var containerResult = $(that).next('.'+settings.menuClass);
|
||||
|
||||
if(containerResult.length == 0){
|
||||
containerResult = $(that).next().next('.'+settings.menuClass);
|
||||
}
|
||||
|
||||
containerResult.hide();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
}( jQuery ));
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Base.Wizard 1.0
|
||||
*
|
||||
* Requiere
|
||||
* Base 1.0
|
||||
*/
|
||||
$(function() {
|
||||
$.extend(Base, {
|
||||
Wizard : {
|
||||
|
||||
create: function (idWizard, form, options) {
|
||||
|
||||
var _i18n = {
|
||||
};
|
||||
|
||||
if(options == undefined){
|
||||
options = {}
|
||||
}
|
||||
|
||||
_i18n = $.extend(true, _i18n, Base.i18n.wizard);
|
||||
|
||||
if (options._i18n !== undefined && options._i18n != null) {
|
||||
_i18n = $.extend(true, _i18n, options._i18n);
|
||||
}
|
||||
|
||||
//Extract Validator Options
|
||||
var validatorOpt = options.validator;
|
||||
delete options['validator'];
|
||||
|
||||
var defaultOptions = {
|
||||
startIndex: 0,
|
||||
animation: false,
|
||||
animationSpeed: '0.3s',
|
||||
customPrevious: null,
|
||||
customNext : null,
|
||||
customSubmit : null
|
||||
};
|
||||
|
||||
var finallyOptions = $.extend(true, defaultOptions, options);
|
||||
|
||||
//Prepare Wizard KtStepper
|
||||
var stepper = document.querySelector(idWizard);
|
||||
|
||||
var cantSteps = KTUtil.findAll(stepper, '[data-kt-stepper-element="nav"]').length;
|
||||
stepper.setAttribute("cantSteps", cantSteps);
|
||||
|
||||
var formSubmitButton = stepper.querySelector('[data-kt-stepper-action="submit"]');
|
||||
var formContinueButton = stepper.querySelector('[data-kt-stepper-action="next"]');
|
||||
var formPreviousButton = stepper.querySelector('[data-kt-stepper-action="previous"]');
|
||||
|
||||
//Create Wizard KtStepper
|
||||
var wizard = new KTStepper(stepper, finallyOptions);
|
||||
|
||||
//Create Validator Form
|
||||
//Validator with Submit Handler
|
||||
var validatorDefaultOption = {
|
||||
submitHandler: function(form, validator, submitButton){
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
|
||||
submitButton.disabled = true;
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable button to avoid multiple click
|
||||
submitButton.disabled = true;
|
||||
|
||||
//Custom Submit
|
||||
if(finallyOptions.customSubmit != undefined && finallyOptions.customSubmit != null && $.isFunction(finallyOptions.customSubmit)) {
|
||||
finallyOptions.customSubmit(wizardPlugin, form, validator, submitButton);
|
||||
}
|
||||
else{
|
||||
form.submit();
|
||||
}
|
||||
} else {
|
||||
// Show error message.
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
submitButton.disabled = false;
|
||||
|
||||
Base.Alert.custom({
|
||||
text: "Errores detectados, por favor corríjalos para finalizar.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Aceptar",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
submitButton: formSubmitButton
|
||||
}
|
||||
var validatorOpt = $.extend(true, validatorDefaultOption, validatorOpt);
|
||||
var validator = form.QxForm().validate(validatorOpt);
|
||||
|
||||
//Validator Add Wizard Plugin if not Register
|
||||
validator.registerPlugin("wizard",
|
||||
new FormValidation.plugins.Wizard({
|
||||
stepSelector: '.base-wizard-step',
|
||||
nextButton: idWizard + '-fvw-next',
|
||||
prevButton: idWizard + '-fvw-previous',
|
||||
onStepValid: function(e){
|
||||
},
|
||||
onStepInvalid: function(e) {
|
||||
Base.Alert.custom({
|
||||
text: "Errores detectados, por favor corríjalos para continuar.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Aceptar",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
},
|
||||
callBackThen: function(result){
|
||||
KTUtil.scrollTop();
|
||||
}
|
||||
});
|
||||
},
|
||||
onStepActive: function(e) {
|
||||
wizard.goTo(e.step+1);
|
||||
KTUtil.scrollTop();
|
||||
}
|
||||
})
|
||||
);
|
||||
var wizardPlugin = validator.getPlugin('wizard');
|
||||
|
||||
|
||||
//Events for Wizard KtStepper
|
||||
// Stepper change event
|
||||
wizard.on('kt.stepper.changed', function (stepper) {
|
||||
|
||||
if (wizard.getCurrentStepIndex() === cantSteps) {
|
||||
formSubmitButton.classList.remove('d-none');
|
||||
formSubmitButton.classList.add('d-inline-block');
|
||||
formContinueButton.classList.add('d-none');
|
||||
} else {
|
||||
formSubmitButton.classList.remove('d-inline-block');
|
||||
formSubmitButton.classList.remove('d-none');
|
||||
formContinueButton.classList.remove('d-none');
|
||||
}
|
||||
});
|
||||
|
||||
//Next Event. WizardPlugin: .goToPrevStep(), .goToNextStep()
|
||||
wizard.on('kt.stepper.next', function (stepperElement) {
|
||||
var stepIndex = $(idWizard).QxWizard().currentStep();
|
||||
console.log("Wizard Next: " + stepIndex);
|
||||
|
||||
if(finallyOptions.customNext != undefined && finallyOptions.customNext != null && $.isFunction(finallyOptions.customNext)) {
|
||||
finallyOptions.customNext(wizardPlugin, stepIndex, form, validator);
|
||||
}
|
||||
else{
|
||||
wizardPlugin.goToNextStep();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Prev Event
|
||||
wizard.on('kt.stepper.previous', function (stepperElement) {
|
||||
var stepIndex = $(idWizard).QxWizard().currentStep();
|
||||
console.log("Wizard Previous: " + stepIndex);
|
||||
|
||||
if(finallyOptions.customPrevious != undefined && finallyOptions.customPrevious != null && $.isFunction(finallyOptions.customPrevious)) {
|
||||
finallyOptions.customPrevious(wizardPlugin, stepIndex, form, validator);
|
||||
}
|
||||
else{
|
||||
wizardPlugin.goToPrevStep();
|
||||
}
|
||||
});
|
||||
|
||||
return wizard;
|
||||
},
|
||||
|
||||
_qxWizard : function (wizard) {
|
||||
|
||||
return {
|
||||
|
||||
ver : function () {
|
||||
|
||||
console.log("Base.Wizard 1.0");
|
||||
console.log("Requiere: Base 1.0;");
|
||||
},
|
||||
|
||||
instance : KTStepper.getInstance(wizard[0]),
|
||||
|
||||
cantSteps: function(){
|
||||
|
||||
return parseInt(wizard[0].getAttribute('cantSteps'));
|
||||
},
|
||||
|
||||
currentStep: function(){
|
||||
|
||||
return this.instance.getCurrentStepIndex();
|
||||
},
|
||||
|
||||
getStepDirection : function() {
|
||||
|
||||
let index = this.instance.getPassedStepIndex();
|
||||
let current = this.instance.getCurrentStepIndex();
|
||||
|
||||
if ( index < current ) {
|
||||
return 'next';
|
||||
} else {
|
||||
return 'previous';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.QxWizard = function () {
|
||||
|
||||
var wizard = this;
|
||||
|
||||
return Base.Wizard._qxWizard(wizard);
|
||||
}
|
||||
});
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountAPIKeys = function () {
|
||||
// Private functions
|
||||
var initLicenceCopy = function() {
|
||||
KTUtil.each(document.querySelectorAll('#kt_api_keys_table [data-action="copy"]'), function(button) {
|
||||
var tr = button.closest('tr');
|
||||
var license = KTUtil.find(tr, '[data-bs-target="license"]');
|
||||
|
||||
var clipboard = new ClipboardJS(button, {
|
||||
target: license,
|
||||
text: function() {
|
||||
return license.innerHTML;
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('success', function(e) {
|
||||
// Icons
|
||||
var copyIcon = button.querySelector('.ki-copy');
|
||||
var checkIcon = button.querySelector('.ki-check');
|
||||
|
||||
// exit if check icon is already shown
|
||||
if (checkIcon) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create check icon
|
||||
checkIcon = document.createElement('i');
|
||||
checkIcon.classList.add('ki-solid');
|
||||
checkIcon.classList.add('ki-check');
|
||||
checkIcon.classList.add('fs-2');
|
||||
|
||||
// Append check icon
|
||||
button.appendChild(checkIcon);
|
||||
|
||||
// Highlight target
|
||||
license.classList.add('text-success');
|
||||
|
||||
// Hide copy icon
|
||||
copyIcon.classList.add('d-none');
|
||||
|
||||
// Set 3 seconds timeout to hide the check icon and show copy icon back
|
||||
setTimeout(function() {
|
||||
// Remove check icon
|
||||
copyIcon.classList.remove('d-none');
|
||||
// Show check icon back
|
||||
button.removeChild(checkIcon);
|
||||
|
||||
// Remove highlight
|
||||
license.classList.remove('text-success');
|
||||
}, 3000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initLicenceCopy();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountAPIKeys.init();
|
||||
});
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountBillingGeneral = function () {
|
||||
// Private variables
|
||||
var cancelSubscriptionButton;
|
||||
|
||||
// Private functions
|
||||
var handlePlan = function () {
|
||||
cancelSubscriptionButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
swal.fire({
|
||||
text: "Are you sure you would like to cancel your subscription ?",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: "Yes",
|
||||
denyButtonText: 'No',
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
denyButton: "btn btn-light-danger"
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
Swal.fire({
|
||||
text: 'Your subscription has been canceled.',
|
||||
icon: 'success',
|
||||
confirmButtonText: "Ok",
|
||||
buttonsStyling: false,
|
||||
customClass: {
|
||||
confirmButton: "btn btn-light-primary"
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var handleCardDelete = function() {
|
||||
KTUtil.on(document.body, '[data-kt-billing-action="card-delete"]', 'click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var el = this;
|
||||
|
||||
swal.fire({
|
||||
text: "Are you sure you would like to delete selected card ?",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: "Yes",
|
||||
denyButtonText: 'No',
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
denyButton: "btn btn-light-danger"
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
el.setAttribute('data-kt-indicator', 'on');
|
||||
el.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
Swal.fire({
|
||||
text: 'Your selected card has been successfully deleted',
|
||||
icon: 'success',
|
||||
confirmButtonText: "Ok",
|
||||
buttonsStyling: false,
|
||||
customClass: {
|
||||
confirmButton: "btn btn-light-primary"
|
||||
}
|
||||
}).then((result) => {
|
||||
el.closest('[data-kt-billing-element="card"]').remove();
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var handleAddressDelete = function() {
|
||||
KTUtil.on(document.body, '[data-kt-billing-action="address-delete"]', 'click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var el = this;
|
||||
|
||||
swal.fire({
|
||||
text: "Are you sure you would like to delete selected address ?",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: "Yes",
|
||||
denyButtonText: 'No',
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
denyButton: "btn btn-light-danger"
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
el.setAttribute('data-kt-indicator', 'on');
|
||||
el.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
Swal.fire({
|
||||
text: 'Your selected address has been successfully deleted',
|
||||
icon: 'success',
|
||||
confirmButtonText: "Ok",
|
||||
buttonsStyling: false,
|
||||
customClass: {
|
||||
confirmButton: "btn btn-light-primary"
|
||||
}
|
||||
}).then((result) => {
|
||||
el.closest('[data-kt-billing-element="address"]').remove();
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
cancelSubscriptionButton = document.querySelector('#kt_account_billing_cancel_subscription_btn');
|
||||
|
||||
if ( cancelSubscriptionButton ) {
|
||||
handlePlan();
|
||||
}
|
||||
|
||||
handleCardDelete();
|
||||
handleAddressDelete();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountBillingGeneral.init();
|
||||
});
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTDatatablesClassic = function () {
|
||||
// Private functions
|
||||
|
||||
var initClassic = function () {
|
||||
|
||||
// Set date data order
|
||||
const table = document.getElementById('kt_orders_classic');
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[1].innerHTML, "MMM D, YYYY").format('x');
|
||||
dateRow[1].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
const datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': []
|
||||
});
|
||||
|
||||
// Filter dropdown elements
|
||||
const filterOrders = document.getElementById('kt_filter_orders');
|
||||
const filterYear = document.getElementById('kt_filter_year');
|
||||
|
||||
// Filter by order status --- official docs reference: https://datatables.net/reference/api/search()
|
||||
filterOrders.addEventListener('change', function (e) {
|
||||
datatable.column(3).search(e.target.value).draw();
|
||||
});
|
||||
|
||||
// Filter by date --- official docs reference: https://momentjs.com/docs/
|
||||
var minDate;
|
||||
var maxDate;
|
||||
filterYear.addEventListener('change', function (e) {
|
||||
const value = e.target.value;
|
||||
switch (value) {
|
||||
case 'thisyear': {
|
||||
minDate = moment().startOf('year').format('x');
|
||||
maxDate = moment().endOf('year').format('x');
|
||||
datatable.draw();
|
||||
break;
|
||||
}
|
||||
case 'thismonth': {
|
||||
minDate = moment().startOf('month').format('x');
|
||||
maxDate = moment().endOf('month').format('x');
|
||||
datatable.draw();
|
||||
break;
|
||||
}
|
||||
case 'lastmonth': {
|
||||
minDate = moment().subtract(1, 'months').startOf('month').format('x');
|
||||
maxDate = moment().subtract(1, 'months').endOf('month').format('x');
|
||||
datatable.draw();
|
||||
break;
|
||||
}
|
||||
case 'last90days': {
|
||||
minDate = moment().subtract(30, 'days').format('x');
|
||||
maxDate = moment().format('x');
|
||||
datatable.draw();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
minDate = moment().subtract(100, 'years').startOf('month').format('x');
|
||||
maxDate = moment().add(1, 'months').endOf('month').format('x');
|
||||
datatable.draw();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Date range filter --- offical docs reference: https://datatables.net/examples/plug-ins/range_filtering.html
|
||||
$.fn.dataTable.ext.search.push(
|
||||
function (settings, data, dataIndex) {
|
||||
var min = minDate;
|
||||
var max = maxDate;
|
||||
var date = parseFloat(moment(data[1]).format('x')) || 0; // use data for the age column
|
||||
|
||||
if ((isNaN(min) && isNaN(max)) ||
|
||||
(isNaN(min) && date <= max) ||
|
||||
(min <= date && isNaN(max)) ||
|
||||
(min <= date && date <= max)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
// Search --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var filterSearch = document.getElementById('kt_filter_search');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initClassic();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTDatatablesClassic.init();
|
||||
});
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountReferralsReferralProgram = function () {
|
||||
// Private functions
|
||||
|
||||
var initReferralProgrammClipboard = function() {
|
||||
var button = document.querySelector('#kt_referral_program_link_copy_btn');
|
||||
var input = document.querySelector('#kt_referral_link_input');
|
||||
var clipboard = new ClipboardJS(button);
|
||||
|
||||
clipboard.on('success', function(e) {
|
||||
var buttonCaption = button.innerHTML;
|
||||
//Add bgcolor
|
||||
input.classList.add('bg-success');
|
||||
input.classList.add('text-inverse-success');
|
||||
|
||||
button.innerHTML = 'Copied!';
|
||||
|
||||
setTimeout(function() {
|
||||
button.innerHTML = buttonCaption;
|
||||
|
||||
// Remove bgcolor
|
||||
input.classList.remove('bg-success');
|
||||
input.classList.remove('text-inverse-success');
|
||||
}, 3000); // 3seconds
|
||||
|
||||
e.clearSelection();
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initReferralProgrammClipboard();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountReferralsReferralProgram.init();
|
||||
});
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountSecurityLicenseUsage = function () {
|
||||
// Private functions
|
||||
var initLicenceCopy = function() {
|
||||
KTUtil.each(document.querySelectorAll('#kt_security_license_usage_table [data-action="copy"]'), function(button) {
|
||||
var tr = button.closest('tr');
|
||||
var license = KTUtil.find(tr, '[data-bs-target="license"]');
|
||||
|
||||
var clipboard = new ClipboardJS(button, {
|
||||
target: license,
|
||||
text: function() {
|
||||
return license.innerHTML;
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('success', function(e) {
|
||||
// Icons
|
||||
var copyIcon = button.querySelector('.ki-copy');
|
||||
var checkIcon = button.querySelector('.ki-check');
|
||||
|
||||
// exit if check icon is already shown
|
||||
if (checkIcon) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create check icon
|
||||
checkIcon = document.createElement('i');
|
||||
checkIcon.classList.add('ki-solid');
|
||||
checkIcon.classList.add('ki-check');
|
||||
checkIcon.classList.add('fs-2');
|
||||
|
||||
// Append check icon
|
||||
button.appendChild(checkIcon);
|
||||
|
||||
// Highlight target
|
||||
license.classList.add('text-success');
|
||||
|
||||
// Hide copy icon
|
||||
copyIcon.classList.add('d-none');
|
||||
|
||||
// Set 3 seconds timeout to hide the check icon and show copy icon back
|
||||
setTimeout(function() {
|
||||
// Remove check icon
|
||||
copyIcon.classList.remove('d-none');
|
||||
// Show check icon back
|
||||
button.removeChild(checkIcon);
|
||||
|
||||
// Remove highlight
|
||||
license.classList.remove('text-success');
|
||||
}, 3000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initLicenceCopy();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountSecurityLicenseUsage.init();
|
||||
});
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountSecuritySummary = function () {
|
||||
// Private functions
|
||||
var initChart = function(tabSelector, chartSelector, data1, data2, initByDefault) {
|
||||
var element = document.querySelector(chartSelector);
|
||||
var height = parseInt(KTUtil.css(element, 'height'));
|
||||
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'Net Profit',
|
||||
data: data1
|
||||
}, {
|
||||
name: 'Revenue',
|
||||
data: data2
|
||||
}],
|
||||
chart: {
|
||||
fontFamily: 'inherit',
|
||||
type: 'bar',
|
||||
height: height,
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: ['35%'],
|
||||
borderRadius: 6
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
stroke: {
|
||||
show: true,
|
||||
width: 2,
|
||||
colors: ['transparent']
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: KTUtil.getCssVariableValue('--bs-gray-400'),
|
||||
fontSize: '12px'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
style: {
|
||||
colors: KTUtil.getCssVariableValue('--bs-gray-400'),
|
||||
fontSize: '12px'
|
||||
}
|
||||
}
|
||||
},
|
||||
fill: {
|
||||
opacity: 1
|
||||
},
|
||||
states: {
|
||||
normal: {
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
active: {
|
||||
allowMultipleDataPointsSelection: false,
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
style: {
|
||||
fontSize: '12px'
|
||||
},
|
||||
y: {
|
||||
formatter: function (val) {
|
||||
return "$" + val + " thousands"
|
||||
}
|
||||
}
|
||||
},
|
||||
colors: [KTUtil.getCssVariableValue('--bs-primary'), KTUtil.getCssVariableValue('--bs-gray-200')],
|
||||
grid: {
|
||||
borderColor: KTUtil.getCssVariableValue('--bs-gray-200'),
|
||||
strokeDashArray: 4,
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(element, options);
|
||||
|
||||
var init = false;
|
||||
var tab = document.querySelector(tabSelector);
|
||||
|
||||
if (initByDefault === true) {
|
||||
setTimeout(function() {
|
||||
chart.render();
|
||||
init = true;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
tab.addEventListener('shown.bs.tab', function (event) {
|
||||
if (init == false) {
|
||||
chart.render();
|
||||
init = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initChart('#kt_security_summary_tab_hours_agents', '#kt_security_summary_chart_hours_agents', [50, 70, 90, 117, 80, 65, 80, 90, 115, 95, 70, 84], [50, 70, 90, 117, 80, 65, 70, 90, 115, 95, 70, 84], true);
|
||||
initChart('#kt_security_summary_tab_hours_clients', '#kt_security_summary_chart_hours_clients', [50, 70, 90, 117, 80, 65, 80, 90, 115, 95, 70, 84], [50, 70, 90, 117, 80, 65, 80, 90, 115, 95, 70, 84], false);
|
||||
|
||||
initChart('#kt_security_summary_tab_day', '#kt_security_summary_chart_day_agents', [50, 70, 80, 100, 90, 65, 80, 90, 115, 95, 70, 84], [50, 70, 90, 117, 60, 65, 80, 90, 100, 95, 70, 84], false);
|
||||
initChart('#kt_security_summary_tab_day_clients', '#kt_security_summary_chart_day_clients', [50, 70, 100, 90, 80, 65, 80, 90, 115, 95, 70, 84], [50, 70, 90, 115, 80, 65, 80, 90, 115, 95, 70, 84], false);
|
||||
|
||||
initChart('#kt_security_summary_tab_week', '#kt_security_summary_chart_week_agents', [50, 70, 75, 117, 80, 65, 80, 90, 115, 95, 50, 84], [50, 60, 90, 117, 80, 65, 80, 90, 115, 95, 70, 84], false);
|
||||
initChart('#kt_security_summary_tab_week_clients', '#kt_security_summary_chart_week_clients', [50, 70, 90, 117, 80, 65, 80, 90, 100, 80, 70, 84], [50, 70, 90, 117, 80, 65, 80, 90, 100, 95, 70, 84], false);
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountSecuritySummary.init();
|
||||
});
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountSettingsDeactivateAccount = function () {
|
||||
// Private variables
|
||||
var form;
|
||||
var validation;
|
||||
var submitButton;
|
||||
|
||||
// Private functions
|
||||
var initValidation = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validation = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
deactivate: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please check the box to deactivate your account'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
submitButton: new FormValidation.plugins.SubmitButton(),
|
||||
//defaultSubmit: new FormValidation.plugins.DefaultSubmit(), // Uncomment this line to enable normal button submit after form validation
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var handleForm = function () {
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
validation.validate().then(function (status) {
|
||||
if (status == 'Valid') {
|
||||
|
||||
swal.fire({
|
||||
text: "Are you sure you would like to deactivate your account?",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: "Yes",
|
||||
denyButtonText: 'No',
|
||||
customClass: {
|
||||
confirmButton: "btn btn-light-primary",
|
||||
denyButton: "btn btn-danger"
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
Swal.fire({
|
||||
text: 'Your account has been deactivated.',
|
||||
icon: 'success',
|
||||
confirmButtonText: "Ok",
|
||||
buttonsStyling: false,
|
||||
customClass: {
|
||||
confirmButton: "btn btn-light-primary"
|
||||
}
|
||||
})
|
||||
} else if (result.isDenied) {
|
||||
Swal.fire({
|
||||
text: 'Account not deactivated.',
|
||||
icon: 'info',
|
||||
confirmButtonText: "Ok",
|
||||
buttonsStyling: false,
|
||||
customClass: {
|
||||
confirmButton: "btn btn-light-primary"
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-light-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
form = document.querySelector('#kt_account_deactivate_form');
|
||||
|
||||
if (!form) {
|
||||
return;
|
||||
}
|
||||
|
||||
submitButton = document.querySelector('#kt_account_deactivate_account_submit');
|
||||
|
||||
initValidation();
|
||||
handleForm();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountSettingsDeactivateAccount.init();
|
||||
});
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountSettingsOverview = function () {
|
||||
// Private functions
|
||||
var initSettings = function() {
|
||||
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initSettings();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountSettingsOverview.init();
|
||||
});
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountSettingsProfileDetails = function () {
|
||||
// Private variables
|
||||
var form;
|
||||
var submitButton;
|
||||
var validation;
|
||||
|
||||
// Private functions
|
||||
var initValidation = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validation = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
fname: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'First name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
lname: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Last name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
company: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Company name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
phone: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Contact phone number is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
country: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please select a country'
|
||||
}
|
||||
}
|
||||
},
|
||||
timezone: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please select a timezone'
|
||||
}
|
||||
}
|
||||
},
|
||||
'communication[]': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please select at least one communication method'
|
||||
}
|
||||
}
|
||||
},
|
||||
language: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please select a language'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
submitButton: new FormValidation.plugins.SubmitButton(),
|
||||
//defaultSubmit: new FormValidation.plugins.DefaultSubmit(), // Uncomment this line to enable normal button submit after form validation
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Select2 validation integration
|
||||
$(form.querySelector('[name="country"]')).on('change', function() {
|
||||
// Revalidate the color field when an option is chosen
|
||||
validation.revalidateField('country');
|
||||
});
|
||||
|
||||
$(form.querySelector('[name="language"]')).on('change', function() {
|
||||
// Revalidate the color field when an option is chosen
|
||||
validation.revalidateField('language');
|
||||
});
|
||||
|
||||
$(form.querySelector('[name="timezone"]')).on('change', function() {
|
||||
// Revalidate the color field when an option is chosen
|
||||
validation.revalidateField('timezone');
|
||||
});
|
||||
}
|
||||
|
||||
var handleForm = function () {
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
validation.validate().then(function (status) {
|
||||
if (status == 'Valid') {
|
||||
|
||||
swal.fire({
|
||||
text: "Thank you! You've updated your basic info",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-light-primary"
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-light-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
form = document.getElementById('kt_account_profile_details_form');
|
||||
|
||||
if (!form) {
|
||||
return;
|
||||
}
|
||||
|
||||
submitButton = form.querySelector('#kt_account_profile_details_submit');
|
||||
|
||||
initValidation();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountSettingsProfileDetails.init();
|
||||
});
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAccountSettingsSigninMethods = function () {
|
||||
var signInForm;
|
||||
var signInMainEl;
|
||||
var signInEditEl;
|
||||
var passwordMainEl;
|
||||
var passwordEditEl;
|
||||
var signInChangeEmail;
|
||||
var signInCancelEmail;
|
||||
var passwordChange;
|
||||
var passwordCancel;
|
||||
|
||||
var toggleChangeEmail = function () {
|
||||
signInMainEl.classList.toggle('d-none');
|
||||
signInChangeEmail.classList.toggle('d-none');
|
||||
signInEditEl.classList.toggle('d-none');
|
||||
}
|
||||
|
||||
var toggleChangePassword = function () {
|
||||
passwordMainEl.classList.toggle('d-none');
|
||||
passwordChange.classList.toggle('d-none');
|
||||
passwordEditEl.classList.toggle('d-none');
|
||||
}
|
||||
|
||||
// Private functions
|
||||
var initSettings = function () {
|
||||
if (!signInMainEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// toggle UI
|
||||
signInChangeEmail.querySelector('button').addEventListener('click', function () {
|
||||
toggleChangeEmail();
|
||||
});
|
||||
|
||||
signInCancelEmail.addEventListener('click', function () {
|
||||
toggleChangeEmail();
|
||||
});
|
||||
|
||||
passwordChange.querySelector('button').addEventListener('click', function () {
|
||||
toggleChangePassword();
|
||||
});
|
||||
|
||||
passwordCancel.addEventListener('click', function () {
|
||||
toggleChangePassword();
|
||||
});
|
||||
}
|
||||
|
||||
var handleChangeEmail = function (e) {
|
||||
var validation;
|
||||
|
||||
if (!signInForm) {
|
||||
return;
|
||||
}
|
||||
|
||||
validation = FormValidation.formValidation(
|
||||
signInForm,
|
||||
{
|
||||
fields: {
|
||||
emailaddress: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Email is required'
|
||||
},
|
||||
emailAddress: {
|
||||
message: 'The value is not a valid email address'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
confirmemailpassword: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Password is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
plugins: { //Learn more: https://formvalidation.io/guide/plugins
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row'
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
signInForm.querySelector('#kt_signin_submit').addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
console.log('click');
|
||||
|
||||
validation.validate().then(function (status) {
|
||||
if (status == 'Valid') {
|
||||
swal.fire({
|
||||
text: "Sent password reset. Please check your email",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn font-weight-bold btn-light-primary"
|
||||
}
|
||||
}).then(function(){
|
||||
signInForm.reset();
|
||||
validation.resetForm(); // Reset formvalidation --- more info: https://formvalidation.io/guide/api/reset-form/
|
||||
toggleChangeEmail();
|
||||
});
|
||||
} else {
|
||||
swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn font-weight-bold btn-light-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var handleChangePassword = function (e) {
|
||||
var validation;
|
||||
|
||||
// form elements
|
||||
var passwordForm = document.getElementById('kt_signin_change_password');
|
||||
|
||||
if (!passwordForm) {
|
||||
return;
|
||||
}
|
||||
|
||||
validation = FormValidation.formValidation(
|
||||
passwordForm,
|
||||
{
|
||||
fields: {
|
||||
currentpassword: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Current Password is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
newpassword: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'New Password is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
confirmpassword: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Confirm Password is required'
|
||||
},
|
||||
identical: {
|
||||
compare: function() {
|
||||
return passwordForm.querySelector('[name="newpassword"]').value;
|
||||
},
|
||||
message: 'The password and its confirm are not the same'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
plugins: { //Learn more: https://formvalidation.io/guide/plugins
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row'
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
passwordForm.querySelector('#kt_password_submit').addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
console.log('click');
|
||||
|
||||
validation.validate().then(function (status) {
|
||||
if (status == 'Valid') {
|
||||
swal.fire({
|
||||
text: "Sent password reset. Please check your email",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn font-weight-bold btn-light-primary"
|
||||
}
|
||||
}).then(function(){
|
||||
passwordForm.reset();
|
||||
validation.resetForm(); // Reset formvalidation --- more info: https://formvalidation.io/guide/api/reset-form/
|
||||
toggleChangePassword();
|
||||
});
|
||||
} else {
|
||||
swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn font-weight-bold btn-light-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
signInForm = document.getElementById('kt_signin_change_email');
|
||||
signInMainEl = document.getElementById('kt_signin_email');
|
||||
signInEditEl = document.getElementById('kt_signin_email_edit');
|
||||
passwordMainEl = document.getElementById('kt_signin_password');
|
||||
passwordEditEl = document.getElementById('kt_signin_password_edit');
|
||||
signInChangeEmail = document.getElementById('kt_signin_email_button');
|
||||
signInCancelEmail = document.getElementById('kt_signin_cancel');
|
||||
passwordChange = document.getElementById('kt_signin_password_button');
|
||||
passwordCancel = document.getElementById('kt_password_cancel');
|
||||
|
||||
initSettings();
|
||||
handleChangeEmail();
|
||||
handleChangePassword();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function() {
|
||||
KTAccountSettingsSigninMethods.init();
|
||||
});
|
||||
+830
@@ -0,0 +1,830 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppCalendar = function () {
|
||||
// Shared variables
|
||||
// Calendar variables
|
||||
var calendar;
|
||||
var data = {
|
||||
id: '',
|
||||
eventName: '',
|
||||
eventDescription: '',
|
||||
eventLocation: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
allDay: false
|
||||
};
|
||||
|
||||
// Add event variables
|
||||
var eventName;
|
||||
var eventDescription;
|
||||
var eventLocation;
|
||||
var startDatepicker;
|
||||
var startFlatpickr;
|
||||
var endDatepicker;
|
||||
var endFlatpickr;
|
||||
var startTimepicker;
|
||||
var startTimeFlatpickr;
|
||||
var endTimepicker
|
||||
var endTimeFlatpickr;
|
||||
var modal;
|
||||
var modalTitle;
|
||||
var form;
|
||||
var validator;
|
||||
var addButton;
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
|
||||
// View event variables
|
||||
var viewEventName;
|
||||
var viewAllDay;
|
||||
var viewEventDescription;
|
||||
var viewEventLocation;
|
||||
var viewStartDate;
|
||||
var viewEndDate;
|
||||
var viewModal;
|
||||
var viewEditButton;
|
||||
var viewDeleteButton;
|
||||
|
||||
|
||||
// Private functions
|
||||
var initCalendarApp = function () {
|
||||
// Define variables
|
||||
var calendarEl = document.getElementById('kt_calendar_app');
|
||||
var todayDate = moment().startOf('day');
|
||||
var YM = todayDate.format('YYYY-MM');
|
||||
var YESTERDAY = todayDate.clone().subtract(1, 'day').format('YYYY-MM-DD');
|
||||
var TODAY = todayDate.format('YYYY-MM-DD');
|
||||
var TOMORROW = todayDate.clone().add(1, 'day').format('YYYY-MM-DD');
|
||||
|
||||
// Init calendar --- more info: https://fullcalendar.io/docs/initialize-globals
|
||||
calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
//locale: 'es', // Set local --- more info: https://fullcalendar.io/docs/locale
|
||||
headerToolbar: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: 'dayGridMonth,timeGridWeek,timeGridDay'
|
||||
},
|
||||
initialDate: TODAY,
|
||||
navLinks: true, // can click day/week names to navigate views
|
||||
selectable: true,
|
||||
selectMirror: true,
|
||||
|
||||
// Select dates action --- more info: https://fullcalendar.io/docs/select-callback
|
||||
select: function (arg) {
|
||||
formatArgs(arg);
|
||||
handleNewEvent();
|
||||
},
|
||||
|
||||
// Click event --- more info: https://fullcalendar.io/docs/eventClick
|
||||
eventClick: function (arg) {
|
||||
formatArgs({
|
||||
id: arg.event.id,
|
||||
title: arg.event.title,
|
||||
description: arg.event.extendedProps.description,
|
||||
location: arg.event.extendedProps.location,
|
||||
startStr: arg.event.startStr,
|
||||
endStr: arg.event.endStr,
|
||||
allDay: arg.event.allDay
|
||||
});
|
||||
|
||||
handleViewEvent();
|
||||
},
|
||||
|
||||
editable: true,
|
||||
dayMaxEvents: true, // allow "more" link when too many events
|
||||
events: [
|
||||
{
|
||||
id: uid(),
|
||||
title: 'All Day Event',
|
||||
start: YM + '-01',
|
||||
end: YM + '-02',
|
||||
description: 'Toto lorem ipsum dolor sit incid idunt ut',
|
||||
className: "border-success bg-success text-inverse-success",
|
||||
location: 'Federation Square'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Reporting',
|
||||
start: YM + '-14T13:30:00',
|
||||
description: 'Lorem ipsum dolor incid idunt ut labore',
|
||||
end: YM + '-14T14:30:00',
|
||||
className: "border-warning bg-warning text-inverse-success",
|
||||
location: 'Meeting Room 7.03'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Company Trip',
|
||||
start: YM + '-02',
|
||||
description: 'Lorem ipsum dolor sit tempor incid',
|
||||
end: YM + '-03',
|
||||
className: "border-info bg-info text-info-success",
|
||||
location: 'Seoul, Korea'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'ICT Expo 2021 - Product Release',
|
||||
start: YM + '-03',
|
||||
description: 'Lorem ipsum dolor sit tempor inci',
|
||||
end: YM + '-05',
|
||||
className: "fc-event-light fc-event-solid-primary",
|
||||
location: 'Melbourne Exhibition Hall'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Dinner',
|
||||
start: YM + '-12',
|
||||
description: 'Lorem ipsum dolor sit amet, conse ctetur',
|
||||
end: YM + '-13',
|
||||
location: 'Squire\'s Loft'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Repeating Event',
|
||||
start: YM + '-09T16:00:00',
|
||||
end: YM + '-09T17:00:00',
|
||||
description: 'Lorem ipsum dolor sit ncididunt ut labore',
|
||||
className: "fc-event-danger",
|
||||
location: 'General Area'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Repeating Event',
|
||||
description: 'Lorem ipsum dolor sit amet, labore',
|
||||
start: YM + '-16T16:00:00',
|
||||
end: YM + '-16T17:00:00',
|
||||
location: 'General Area'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Conference',
|
||||
start: YESTERDAY,
|
||||
end: TOMORROW,
|
||||
description: 'Lorem ipsum dolor eius mod tempor labore',
|
||||
className: "fc-event-primary",
|
||||
location: 'Conference Hall A'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Meeting',
|
||||
start: TODAY + 'T10:30:00',
|
||||
end: TODAY + 'T12:30:00',
|
||||
description: 'Lorem ipsum dolor eiu idunt ut labore',
|
||||
location: 'Meeting Room 11.06'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Lunch',
|
||||
start: TODAY + 'T12:00:00',
|
||||
end: TODAY + 'T14:00:00',
|
||||
className: "fc-event-info",
|
||||
description: 'Lorem ipsum dolor sit amet, ut labore',
|
||||
location: 'Cafeteria'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Meeting',
|
||||
start: TODAY + 'T14:30:00',
|
||||
end: TODAY + 'T15:30:00',
|
||||
className: "fc-event-warning",
|
||||
description: 'Lorem ipsum conse ctetur adipi scing',
|
||||
location: 'Meeting Room 11.10'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Happy Hour',
|
||||
start: TODAY + 'T17:30:00',
|
||||
end: TODAY + 'T21:30:00',
|
||||
className: "fc-event-info",
|
||||
description: 'Lorem ipsum dolor sit amet, conse ctetur',
|
||||
location: 'The English Pub'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Dinner',
|
||||
start: TOMORROW + 'T18:00:00',
|
||||
end: TOMORROW + 'T21:00:00',
|
||||
className: "fc-event-solid-danger fc-event-light",
|
||||
description: 'Lorem ipsum dolor sit ctetur adipi scing',
|
||||
location: 'New York Steakhouse'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Birthday Party',
|
||||
start: TOMORROW + 'T12:00:00',
|
||||
end: TOMORROW + 'T14:00:00',
|
||||
className: "fc-event-primary",
|
||||
description: 'Lorem ipsum dolor sit amet, scing',
|
||||
location: 'The English Pub'
|
||||
},
|
||||
{
|
||||
id: uid(),
|
||||
title: 'Site visit',
|
||||
start: YM + '-28',
|
||||
end: YM + '-29',
|
||||
className: "fc-event-solid-info fc-event-light",
|
||||
description: 'Lorem ipsum dolor sit amet, labore',
|
||||
location: '271, Spring Street'
|
||||
}
|
||||
],
|
||||
|
||||
// Handle changing calendar views --- more info: https://fullcalendar.io/docs/datesSet
|
||||
datesSet: function(){
|
||||
// do some stuff
|
||||
}
|
||||
});
|
||||
|
||||
calendar.render();
|
||||
}
|
||||
|
||||
// Init validator
|
||||
const initValidator = () => {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'calendar_event_name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Event name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'calendar_event_start_date': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Start date is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'calendar_event_end_date': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'End date is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Initialize datepickers --- more info: https://flatpickr.js.org/
|
||||
const initDatepickers = () => {
|
||||
startFlatpickr = flatpickr(startDatepicker, {
|
||||
enableTime: false,
|
||||
dateFormat: "Y-m-d",
|
||||
});
|
||||
|
||||
endFlatpickr = flatpickr(endDatepicker, {
|
||||
enableTime: false,
|
||||
dateFormat: "Y-m-d",
|
||||
});
|
||||
|
||||
startTimeFlatpickr = flatpickr(startTimepicker, {
|
||||
enableTime: true,
|
||||
noCalendar: true,
|
||||
dateFormat: "H:i",
|
||||
});
|
||||
|
||||
endTimeFlatpickr = flatpickr(endTimepicker, {
|
||||
enableTime: true,
|
||||
noCalendar: true,
|
||||
dateFormat: "H:i",
|
||||
});
|
||||
}
|
||||
|
||||
// Handle add button
|
||||
const handleAddButton = () => {
|
||||
addButton.addEventListener('click', e => {
|
||||
// Reset form data
|
||||
data = {
|
||||
id: '',
|
||||
eventName: '',
|
||||
eventDescription: '',
|
||||
startDate: new Date(),
|
||||
endDate: new Date(),
|
||||
allDay: false
|
||||
};
|
||||
handleNewEvent();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle add new event
|
||||
const handleNewEvent = () => {
|
||||
// Update modal title
|
||||
modalTitle.innerText = "Add a New Event";
|
||||
|
||||
modal.show();
|
||||
|
||||
// Select datepicker wrapper elements
|
||||
const datepickerWrappers = form.querySelectorAll('[data-kt-calendar="datepicker"]');
|
||||
|
||||
// Handle all day toggle
|
||||
const allDayToggle = form.querySelector('#kt_calendar_datepicker_allday');
|
||||
allDayToggle.addEventListener('click', e => {
|
||||
if (e.target.checked) {
|
||||
datepickerWrappers.forEach(dw => {
|
||||
dw.classList.add('d-none');
|
||||
});
|
||||
} else {
|
||||
endFlatpickr.setDate(data.startDate, true, 'Y-m-d');
|
||||
datepickerWrappers.forEach(dw => {
|
||||
dw.classList.remove('d-none');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
populateForm(data);
|
||||
|
||||
// Handle submit form
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission
|
||||
setTimeout(function () {
|
||||
// Simulate form submission
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "New event added to calendar!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Detect if is all day event
|
||||
let allDayEvent = false;
|
||||
if (allDayToggle.checked) { allDayEvent = true; }
|
||||
if (startTimeFlatpickr.selectedDates.length === 0) { allDayEvent = true; }
|
||||
|
||||
// Merge date & time
|
||||
var startDateTime = moment(startFlatpickr.selectedDates[0]).format();
|
||||
var endDateTime = moment(endFlatpickr.selectedDates[endFlatpickr.selectedDates.length - 1]).format();
|
||||
if (!allDayEvent) {
|
||||
const startDate = moment(startFlatpickr.selectedDates[0]).format('YYYY-MM-DD');
|
||||
const endDate = startDate;
|
||||
const startTime = moment(startTimeFlatpickr.selectedDates[0]).format('HH:mm:ss');
|
||||
const endTime = moment(endTimeFlatpickr.selectedDates[0]).format('HH:mm:ss');
|
||||
|
||||
startDateTime = startDate + 'T' + startTime;
|
||||
endDateTime = endDate + 'T' + endTime;
|
||||
}
|
||||
|
||||
// Add new event to calendar
|
||||
calendar.addEvent({
|
||||
id: uid(),
|
||||
title: eventName.value,
|
||||
description: eventDescription.value,
|
||||
location: eventLocation.value,
|
||||
start: startDateTime,
|
||||
end: endDateTime,
|
||||
allDay: allDayEvent
|
||||
});
|
||||
calendar.render();
|
||||
|
||||
// Reset form for demo purposes only
|
||||
form.reset();
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show popup warning
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle edit event
|
||||
const handleEditEvent = () => {
|
||||
// Update modal title
|
||||
modalTitle.innerText = "Edit an Event";
|
||||
|
||||
modal.show();
|
||||
|
||||
// Select datepicker wrapper elements
|
||||
const datepickerWrappers = form.querySelectorAll('[data-kt-calendar="datepicker"]');
|
||||
|
||||
// Handle all day toggle
|
||||
const allDayToggle = form.querySelector('#kt_calendar_datepicker_allday');
|
||||
allDayToggle.addEventListener('click', e => {
|
||||
if (e.target.checked) {
|
||||
datepickerWrappers.forEach(dw => {
|
||||
dw.classList.add('d-none');
|
||||
});
|
||||
} else {
|
||||
endFlatpickr.setDate(data.startDate, true, 'Y-m-d');
|
||||
datepickerWrappers.forEach(dw => {
|
||||
dw.classList.remove('d-none');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
populateForm(data);
|
||||
|
||||
// Handle submit form
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission
|
||||
setTimeout(function () {
|
||||
// Simulate form submission
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "New event added to calendar!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Remove old event
|
||||
calendar.getEventById(data.id).remove();
|
||||
|
||||
// Detect if is all day event
|
||||
let allDayEvent = false;
|
||||
if (allDayToggle.checked) { allDayEvent = true; }
|
||||
if (startTimeFlatpickr.selectedDates.length === 0) { allDayEvent = true; }
|
||||
|
||||
// Merge date & time
|
||||
var startDateTime = moment(startFlatpickr.selectedDates[0]).format();
|
||||
var endDateTime = moment(endFlatpickr.selectedDates[endFlatpickr.selectedDates.length - 1]).format();
|
||||
if (!allDayEvent) {
|
||||
const startDate = moment(startFlatpickr.selectedDates[0]).format('YYYY-MM-DD');
|
||||
const endDate = startDate;
|
||||
const startTime = moment(startTimeFlatpickr.selectedDates[0]).format('HH:mm:ss');
|
||||
const endTime = moment(endTimeFlatpickr.selectedDates[0]).format('HH:mm:ss');
|
||||
|
||||
startDateTime = startDate + 'T' + startTime;
|
||||
endDateTime = endDate + 'T' + endTime;
|
||||
}
|
||||
|
||||
// Add new event to calendar
|
||||
calendar.addEvent({
|
||||
id: uid(),
|
||||
title: eventName.value,
|
||||
description: eventDescription.value,
|
||||
location: eventLocation.value,
|
||||
start: startDateTime,
|
||||
end: endDateTime,
|
||||
allDay: allDayEvent
|
||||
});
|
||||
calendar.render();
|
||||
|
||||
// Reset form for demo purposes only
|
||||
form.reset();
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show popup warning
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle view event
|
||||
const handleViewEvent = () => {
|
||||
viewModal.show();
|
||||
|
||||
// Detect all day event
|
||||
var eventNameMod;
|
||||
var startDateMod;
|
||||
var endDateMod;
|
||||
|
||||
// Generate labels
|
||||
if (data.allDay) {
|
||||
eventNameMod = 'All Day';
|
||||
startDateMod = moment(data.startDate).format('Do MMM, YYYY');
|
||||
endDateMod = moment(data.endDate).format('Do MMM, YYYY');
|
||||
} else {
|
||||
eventNameMod = '';
|
||||
startDateMod = moment(data.startDate).format('Do MMM, YYYY - h:mm a');
|
||||
endDateMod = moment(data.endDate).format('Do MMM, YYYY - h:mm a');
|
||||
}
|
||||
|
||||
// Populate view data
|
||||
viewEventName.innerText = data.eventName;
|
||||
viewAllDay.innerText = eventNameMod;
|
||||
viewEventDescription.innerText = data.eventDescription ? data.eventDescription : '--';
|
||||
viewEventLocation.innerText = data.eventLocation ? data.eventLocation : '--';
|
||||
viewStartDate.innerText = startDateMod;
|
||||
viewEndDate.innerText = endDateMod;
|
||||
}
|
||||
|
||||
// Handle delete event
|
||||
const handleDeleteEvent = () => {
|
||||
viewDeleteButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to delete this event?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
calendar.getEventById(data.id).remove();
|
||||
|
||||
viewModal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your event was not deleted!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle edit button
|
||||
const handleEditButton = () => {
|
||||
viewEditButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
viewModal.hide();
|
||||
handleEditEvent();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle cancel button
|
||||
const handleCancelButton = () => {
|
||||
// Edit event modal cancel button
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle close button
|
||||
const handleCloseButton = () => {
|
||||
// Edit event modal close button
|
||||
closeButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle view button
|
||||
const handleViewButton = () => {
|
||||
const viewButton = document.querySelector('#kt_calendar_event_view_button');
|
||||
viewButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
hidePopovers();
|
||||
handleViewEvent();
|
||||
});
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
// Reset form validator on modal close
|
||||
const resetFormValidator = (element) => {
|
||||
// Target modal hidden event --- For more info: https://getbootstrap.com/docs/5.0/components/modal/#events
|
||||
element.addEventListener('hidden.bs.modal', e => {
|
||||
if (validator) {
|
||||
// Reset form validator. For more info: https://formvalidation.io/guide/api/reset-form
|
||||
validator.resetForm(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Populate form
|
||||
const populateForm = () => {
|
||||
eventName.value = data.eventName ? data.eventName : '';
|
||||
eventDescription.value = data.eventDescription ? data.eventDescription : '';
|
||||
eventLocation.value = data.eventLocation ? data.eventLocation : '';
|
||||
startFlatpickr.setDate(data.startDate, true, 'Y-m-d');
|
||||
|
||||
// Handle null end dates
|
||||
const endDate = data.endDate ? data.endDate : moment(data.startDate).format();
|
||||
endFlatpickr.setDate(endDate, true, 'Y-m-d');
|
||||
|
||||
const allDayToggle = form.querySelector('#kt_calendar_datepicker_allday');
|
||||
const datepickerWrappers = form.querySelectorAll('[data-kt-calendar="datepicker"]');
|
||||
if (data.allDay) {
|
||||
allDayToggle.checked = true;
|
||||
datepickerWrappers.forEach(dw => {
|
||||
dw.classList.add('d-none');
|
||||
});
|
||||
} else {
|
||||
startTimeFlatpickr.setDate(data.startDate, true, 'Y-m-d H:i');
|
||||
endTimeFlatpickr.setDate(data.endDate, true, 'Y-m-d H:i');
|
||||
endFlatpickr.setDate(data.startDate, true, 'Y-m-d');
|
||||
allDayToggle.checked = false;
|
||||
datepickerWrappers.forEach(dw => {
|
||||
dw.classList.remove('d-none');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Format FullCalendar reponses
|
||||
const formatArgs = (res) => {
|
||||
data.id = res.id;
|
||||
data.eventName = res.title;
|
||||
data.eventDescription = res.description;
|
||||
data.eventLocation = res.location;
|
||||
data.startDate = res.startStr;
|
||||
data.endDate = res.endStr;
|
||||
data.allDay = res.allDay;
|
||||
}
|
||||
|
||||
// Generate unique IDs for events
|
||||
const uid = () => {
|
||||
return Date.now().toString() + Math.floor(Math.random() * 1000).toString();
|
||||
}
|
||||
|
||||
return {
|
||||
// Public Functions
|
||||
init: function () {
|
||||
// Define variables
|
||||
// Add event modal
|
||||
const element = document.getElementById('kt_modal_add_event');
|
||||
form = element.querySelector('#kt_modal_add_event_form');
|
||||
eventName = form.querySelector('[name="calendar_event_name"]');
|
||||
eventDescription = form.querySelector('[name="calendar_event_description"]');
|
||||
eventLocation = form.querySelector('[name="calendar_event_location"]');
|
||||
startDatepicker = form.querySelector('#kt_calendar_datepicker_start_date');
|
||||
endDatepicker = form.querySelector('#kt_calendar_datepicker_end_date');
|
||||
startTimepicker = form.querySelector('#kt_calendar_datepicker_start_time');
|
||||
endTimepicker = form.querySelector('#kt_calendar_datepicker_end_time');
|
||||
addButton = document.querySelector('[data-kt-calendar="add"]');
|
||||
submitButton = form.querySelector('#kt_modal_add_event_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_add_event_cancel');
|
||||
closeButton = element.querySelector('#kt_modal_add_event_close');
|
||||
modalTitle = form.querySelector('[data-kt-calendar="title"]');
|
||||
modal = new bootstrap.Modal(element);
|
||||
|
||||
// View event modal
|
||||
const viewElement = document.getElementById('kt_modal_view_event');
|
||||
viewModal = new bootstrap.Modal(viewElement);
|
||||
viewEventName = viewElement.querySelector('[data-kt-calendar="event_name"]');
|
||||
viewAllDay = viewElement.querySelector('[data-kt-calendar="all_day"]');
|
||||
viewEventDescription = viewElement.querySelector('[data-kt-calendar="event_description"]');
|
||||
viewEventLocation = viewElement.querySelector('[data-kt-calendar="event_location"]');
|
||||
viewStartDate = viewElement.querySelector('[data-kt-calendar="event_start_date"]');
|
||||
viewEndDate = viewElement.querySelector('[data-kt-calendar="event_end_date"]');
|
||||
viewEditButton = viewElement.querySelector('#kt_modal_view_event_edit');
|
||||
viewDeleteButton = viewElement.querySelector('#kt_modal_view_event_delete');
|
||||
|
||||
initCalendarApp();
|
||||
initValidator();
|
||||
initDatepickers();
|
||||
handleEditButton();
|
||||
handleAddButton();
|
||||
handleDeleteEvent();
|
||||
handleCancelButton();
|
||||
handleCloseButton();
|
||||
resetFormValidator(element);
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppCalendar.init();
|
||||
});
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppChat = function () {
|
||||
// Private functions
|
||||
var handeSend = function (element) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle send
|
||||
KTUtil.on(element, '[data-kt-element="input"]', 'keydown', function(e) {
|
||||
if (e.keyCode == 13) {
|
||||
handeMessaging(element);
|
||||
e.preventDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
KTUtil.on(element, '[data-kt-element="send"]', 'click', function(e) {
|
||||
handeMessaging(element);
|
||||
});
|
||||
}
|
||||
|
||||
var handeMessaging = function(element) {
|
||||
var messages = element.querySelector('[data-kt-element="messages"]');
|
||||
var input = element.querySelector('[data-kt-element="input"]');
|
||||
|
||||
if (input.value.length === 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var messageOutTemplate = messages.querySelector('[data-kt-element="template-out"]');
|
||||
var messageInTemplate = messages.querySelector('[data-kt-element="template-in"]');
|
||||
var message;
|
||||
|
||||
// Show example outgoing message
|
||||
message = messageOutTemplate.cloneNode(true);
|
||||
message.classList.remove('d-none');
|
||||
message.querySelector('[data-kt-element="message-text"]').innerText = input.value;
|
||||
input.value = '';
|
||||
messages.appendChild(message);
|
||||
messages.scrollTop = messages.scrollHeight;
|
||||
|
||||
|
||||
setTimeout(function() {
|
||||
// Show example incoming message
|
||||
message = messageInTemplate.cloneNode(true);
|
||||
message.classList.remove('d-none');
|
||||
message.querySelector('[data-kt-element="message-text"]').innerText = 'Thank you for your awesome support!';
|
||||
messages.appendChild(message);
|
||||
messages.scrollTop = messages.scrollHeight;
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function(element) {
|
||||
handeSend(element);
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
// Init inline chat messenger
|
||||
KTAppChat.init(document.querySelector('#kt_chat_messenger'));
|
||||
|
||||
// Init drawer chat messenger
|
||||
KTAppChat.init(document.querySelector('#kt_drawer_chat_messenger'));
|
||||
});
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppContactEdit = function () {
|
||||
// Shared variables
|
||||
|
||||
|
||||
// Private functions
|
||||
const initForm = () => {
|
||||
// Select form
|
||||
const form = document.getElementById('kt_ecommerce_settings_general_form');
|
||||
|
||||
if (!form) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dynamically create validation non-empty rule
|
||||
const requiredFields = form.querySelectorAll('.required');
|
||||
var detectedField;
|
||||
var validationFields = {
|
||||
fields: {},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Detect required fields
|
||||
requiredFields.forEach(el => {
|
||||
const input = el.closest('.fv-row').querySelector('input');
|
||||
if (input) {
|
||||
detectedField = input;
|
||||
}
|
||||
|
||||
const select = el.closest('.fv-row').querySelector('select');
|
||||
if (select) {
|
||||
detectedField = select;
|
||||
}
|
||||
|
||||
// Add validation rule
|
||||
const name = detectedField.getAttribute('name');
|
||||
validationFields.fields[name] = {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: el.innerText + ' is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
var validator = FormValidation.formValidation(
|
||||
form,
|
||||
validationFields
|
||||
);
|
||||
|
||||
// Submit button handler
|
||||
const submitButton = form.querySelector('[data-kt-contacts-type="submit"]');
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable button to avoid multiple click
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission. For more info check the plugin's official documentation: https://sweetalert2.github.io/
|
||||
setTimeout(function () {
|
||||
// Remove loading indication
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Enable button
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show popup error
|
||||
Swal.fire({
|
||||
text: "Oops! There are some error(s) detected.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Init Select2 with flags
|
||||
const initSelect2Flags = () => {
|
||||
// Format options
|
||||
var optionFormat = function(item) {
|
||||
if ( !item.id ) {
|
||||
return item.text;
|
||||
}
|
||||
|
||||
var span = document.createElement('span');
|
||||
var template = '';
|
||||
|
||||
template += '<img src="' + item.element.getAttribute('data-kt-select2-country') + '" class="rounded-circle me-2" style="height:19px;" alt="image"/>';
|
||||
template += item.text;
|
||||
|
||||
span.innerHTML = template;
|
||||
|
||||
return $(span);
|
||||
}
|
||||
|
||||
// Init Select2 --- more info: https://select2.org/
|
||||
$('[data-kt-ecommerce-settings-type="select2_flags"]').select2({
|
||||
placeholder: "Select a country",
|
||||
minimumResultsForSearch: Infinity,
|
||||
templateSelection: optionFormat,
|
||||
templateResult: optionFormat
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
|
||||
initForm();
|
||||
initSelect2Flags();
|
||||
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppContactEdit.init();
|
||||
});
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppContactView = function () {
|
||||
// Private functions
|
||||
const handleDeleteButton = () => {
|
||||
// Select form
|
||||
const deleteButton = document.getElementById('kt_contact_delete');
|
||||
|
||||
if (!deleteButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
deleteButton.addEventListener('click', e => {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Delete contact confirmation",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Yes, delete it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-danger",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "Contact has been deleted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
// Redirect to customers list page
|
||||
window.location = deleteButton.getAttribute("data-kt-redirect");
|
||||
}
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Contact has not been deleted!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
|
||||
handleDeleteButton();
|
||||
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppContactView.init();
|
||||
});
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTModalCustomersAdd = function () {
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var validator;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var handleForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Customer name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'email': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Customer email is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'first-name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'First name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'last-name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Last name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'country': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Country is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'address1': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Address 1 is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'city': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'City is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'state': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'State is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'postcode': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Postcode is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Revalidate country field. For more info, plase visit the official plugin site: https://select2.org/
|
||||
$(form.querySelector('[name="country"]')).on('change', function() {
|
||||
// Revalidate the field when an option is chosen
|
||||
validator.revalidateField('country');
|
||||
});
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Hide modal
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Redirect to customers list page
|
||||
window.location = form.getAttribute("data-kt-redirect");
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
modal = new bootstrap.Modal(document.querySelector('#kt_modal_add_customer'));
|
||||
|
||||
form = document.querySelector('#kt_modal_add_customer_form');
|
||||
submitButton = form.querySelector('#kt_modal_add_customer_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_add_customer_cancel');
|
||||
closeButton = form.querySelector('#kt_modal_add_customer_close');
|
||||
|
||||
handleForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTModalCustomersAdd.init();
|
||||
});
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomersExport = function () {
|
||||
var element;
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var validator;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var handleForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'date': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Date range is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Customer list has been successfully exported!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var initForm = function () {
|
||||
const datepicker = form.querySelector("[name=date]");
|
||||
|
||||
// Handle datepicker range -- For more info on flatpickr plugin, please visit: https://flatpickr.js.org/
|
||||
$(datepicker).flatpickr({
|
||||
altInput: true,
|
||||
altFormat: "F j, Y",
|
||||
dateFormat: "Y-m-d",
|
||||
mode: "range"
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
element = document.querySelector('#kt_customers_export_modal');
|
||||
modal = new bootstrap.Modal(element);
|
||||
|
||||
form = document.querySelector('#kt_customers_export_form');
|
||||
submitButton = form.querySelector('#kt_customers_export_submit');
|
||||
cancelButton = form.querySelector('#kt_customers_export_cancel');
|
||||
closeButton = element.querySelector('#kt_customers_export_close');
|
||||
|
||||
handleForm();
|
||||
initForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomersExport.init();
|
||||
});
|
||||
+283
@@ -0,0 +1,283 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomersList = function () {
|
||||
// Define shared variables
|
||||
var datatable;
|
||||
var filterMonth;
|
||||
var filterPayment;
|
||||
var table
|
||||
|
||||
// Private functions
|
||||
var initCustomerList = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[5].innerHTML, "DD MMM YYYY, LT").format(); // select date from 5th column in table
|
||||
dateRow[5].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 0 }, // Disable ordering on column 0 (checkbox)
|
||||
{ orderable: false, targets: 6 }, // Disable ordering on column 6 (actions)
|
||||
]
|
||||
});
|
||||
|
||||
// Re-init functions on every table re-draw -- more info: https://datatables.net/reference/event/draw
|
||||
datatable.on('draw', function () {
|
||||
initToggleToolbar();
|
||||
handleDeleteRows();
|
||||
toggleToolbars();
|
||||
KTMenu.init(); // reinit KTMenu instances
|
||||
});
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-customer-table-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Filter Datatable
|
||||
var handleFilterDatatable = () => {
|
||||
// Select filter options
|
||||
filterMonth = $('[data-kt-customer-table-filter="month"]');
|
||||
filterPayment = document.querySelectorAll('[data-kt-customer-table-filter="payment_type"] [name="payment_type"]');
|
||||
const filterButton = document.querySelector('[data-kt-customer-table-filter="filter"]');
|
||||
|
||||
// Filter datatable on submit
|
||||
filterButton.addEventListener('click', function () {
|
||||
// Get filter values
|
||||
const monthValue = filterMonth.val();
|
||||
let paymentValue = '';
|
||||
|
||||
// Get payment value
|
||||
filterPayment.forEach(r => {
|
||||
if (r.checked) {
|
||||
paymentValue = r.value;
|
||||
}
|
||||
|
||||
// Reset payment value if "All" is selected
|
||||
if (paymentValue === 'all') {
|
||||
paymentValue = '';
|
||||
}
|
||||
});
|
||||
|
||||
// Build filter string from filter options
|
||||
const filterString = monthValue + ' ' + paymentValue;
|
||||
|
||||
// Filter datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
datatable.search(filterString).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Delete customer
|
||||
var handleDeleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-customer-table-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get customer name
|
||||
const customerName = parent.querySelectorAll('td')[1].innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete " + customerName + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + customerName + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: customerName + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Reset Filter
|
||||
var handleResetForm = () => {
|
||||
// Select reset button
|
||||
const resetButton = document.querySelector('[data-kt-customer-table-filter="reset"]');
|
||||
|
||||
// Reset datatable
|
||||
resetButton.addEventListener('click', function () {
|
||||
// Reset month
|
||||
filterMonth.val(null).trigger('change');
|
||||
|
||||
// Reset payment type
|
||||
filterPayment[0].checked = true;
|
||||
|
||||
// Reset datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
datatable.search('').draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Init toggle toolbar
|
||||
var initToggleToolbar = () => {
|
||||
// Toggle selected action toolbar
|
||||
// Select all checkboxes
|
||||
const checkboxes = table.querySelectorAll('[type="checkbox"]');
|
||||
|
||||
// Select elements
|
||||
const deleteSelected = document.querySelector('[data-kt-customer-table-select="delete_selected"]');
|
||||
|
||||
// Toggle delete selected toolbar
|
||||
checkboxes.forEach(c => {
|
||||
// Checkbox on click event
|
||||
c.addEventListener('click', function () {
|
||||
setTimeout(function () {
|
||||
toggleToolbars();
|
||||
}, 50);
|
||||
});
|
||||
});
|
||||
|
||||
// Deleted selected rows
|
||||
deleteSelected.addEventListener('click', function () {
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete selected customers?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted all selected customers!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove all selected customers
|
||||
checkboxes.forEach(c => {
|
||||
if (c.checked) {
|
||||
datatable.row($(c.closest('tbody tr'))).remove().draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Remove header checked box
|
||||
const headerCheckbox = table.querySelectorAll('[type="checkbox"]')[0];
|
||||
headerCheckbox.checked = false;
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Selected customers was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle toolbars
|
||||
const toggleToolbars = () => {
|
||||
// Define variables
|
||||
const toolbarBase = document.querySelector('[data-kt-customer-table-toolbar="base"]');
|
||||
const toolbarSelected = document.querySelector('[data-kt-customer-table-toolbar="selected"]');
|
||||
const selectedCount = document.querySelector('[data-kt-customer-table-select="selected_count"]');
|
||||
|
||||
// Select refreshed checkbox DOM elements
|
||||
const allCheckboxes = table.querySelectorAll('tbody [type="checkbox"]');
|
||||
|
||||
// Detect checkboxes state & count
|
||||
let checkedState = false;
|
||||
let count = 0;
|
||||
|
||||
// Count checked boxes
|
||||
allCheckboxes.forEach(c => {
|
||||
if (c.checked) {
|
||||
checkedState = true;
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle toolbars
|
||||
if (checkedState) {
|
||||
selectedCount.innerHTML = count;
|
||||
toolbarBase.classList.add('d-none');
|
||||
toolbarSelected.classList.remove('d-none');
|
||||
} else {
|
||||
toolbarBase.classList.remove('d-none');
|
||||
toolbarSelected.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_customers_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initCustomerList();
|
||||
initToggleToolbar();
|
||||
handleSearchDatatable();
|
||||
handleFilterDatatable();
|
||||
handleDeleteRows();
|
||||
handleResetForm();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomersList.init();
|
||||
});
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTModalUpdateCustomer = function () {
|
||||
var element;
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var initForm = function () {
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Simulate form submission
|
||||
setTimeout(function () {
|
||||
// Simulate form submission
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
element = document.querySelector('#kt_modal_update_customer');
|
||||
modal = new bootstrap.Modal(element);
|
||||
|
||||
form = element.querySelector('#kt_modal_update_customer_form');
|
||||
submitButton = form.querySelector('#kt_modal_update_customer_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_update_customer_cancel');
|
||||
closeButton = element.querySelector('#kt_modal_update_customer_close');
|
||||
|
||||
initForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTModalUpdateCustomer.init();
|
||||
});
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTModalAddPayment = function () {
|
||||
var element;
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var validator;
|
||||
var newBalance;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var initForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'invoice': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Invoice number is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'status': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Invoice status is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'amount': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Invoice amount is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Revalidate country field. For more info, plase visit the official plugin site: https://select2.org/
|
||||
$(form.querySelector('[name="status"]')).on('change', function () {
|
||||
// Revalidate the field when an option is chosen
|
||||
validator.revalidateField('status');
|
||||
});
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission
|
||||
setTimeout(function () {
|
||||
// Simulate form submission
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Reset form for demo purposes only
|
||||
form.reset();
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show popup warning
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
element = document.querySelector('#kt_modal_add_payment');
|
||||
modal = new bootstrap.Modal(element);
|
||||
|
||||
form = element.querySelector('#kt_modal_add_payment_form');
|
||||
submitButton = form.querySelector('#kt_modal_add_payment_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_add_payment_cancel');
|
||||
closeButton = element.querySelector('#kt_modal_add_payment_close');
|
||||
|
||||
initForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTModalAddPayment.init();
|
||||
});
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTModalAdjustBalance = function () {
|
||||
var element;
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var validator;
|
||||
var maskInput;
|
||||
var newBalance;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var initForm = function () {
|
||||
// Init inputmask plugin --- For more info please refer to the official documentation here: https://github.com/RobinHerbots/Inputmask
|
||||
Inputmask("US$ 9,999,999.99", {
|
||||
"numericInput": true
|
||||
}).mask("#kt_modal_inputmask");
|
||||
}
|
||||
|
||||
var handleBalanceCalculator = function () {
|
||||
// Select elements
|
||||
const currentBalance = element.querySelector('[kt-modal-adjust-balance="current_balance"]');
|
||||
newBalance = element.querySelector('[kt-modal-adjust-balance="new_balance"]');
|
||||
maskInput = document.getElementById('kt_modal_inputmask');
|
||||
|
||||
// Get current balance value
|
||||
const isNegative = currentBalance.innerHTML.includes('-');
|
||||
let currentValue = parseFloat(currentBalance.innerHTML.replace(/[^0-9.]/g, '').replace(',', ''));
|
||||
currentValue = isNegative ? currentValue * -1 : currentValue;
|
||||
|
||||
// On change event for inputmask
|
||||
let maskValue;
|
||||
maskInput.addEventListener('focusout', function (e) {
|
||||
// Get inputmask value on change
|
||||
maskValue = parseFloat(e.target.value.replace(/[^0-9.]/g, '').replace(',', ''));
|
||||
|
||||
// Set mask value as 0 when NaN detected
|
||||
if(isNaN(maskValue)){
|
||||
maskValue = 0;
|
||||
}
|
||||
|
||||
// Calculate & set new balance value
|
||||
newBalance.innerHTML = 'US$ ' + (maskValue + currentValue).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
|
||||
});
|
||||
}
|
||||
|
||||
// Handle form validation and submittion
|
||||
var handleForm = function () {
|
||||
// Stepper custom navigation
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'adjustment': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Adjustment type is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'amount': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Amount is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Revalidate country field. For more info, plase visit the official plugin site: https://select2.org/
|
||||
$(form.querySelector('[name="adjustment"]')).on('change', function () {
|
||||
// Revalidate the field when an option is chosen
|
||||
validator.revalidateField('adjustment');
|
||||
});
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission
|
||||
setTimeout(function () {
|
||||
// Simulate form submission
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Reset form for demo purposes only
|
||||
form.reset();
|
||||
newBalance.innerHTML = "--";
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show popup warning
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
element = document.querySelector('#kt_modal_adjust_balance');
|
||||
modal = new bootstrap.Modal(element);
|
||||
|
||||
form = element.querySelector('#kt_modal_adjust_balance_form');
|
||||
submitButton = form.querySelector('#kt_modal_adjust_balance_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_adjust_balance_cancel');
|
||||
closeButton = element.querySelector('#kt_modal_adjust_balance_close');
|
||||
|
||||
initForm();
|
||||
handleBalanceCalculator();
|
||||
handleForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTModalAdjustBalance.init();
|
||||
});
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomerViewInvoices = function () {
|
||||
|
||||
// Private functions
|
||||
// Init current year datatable
|
||||
var initInvoiceYearCurrent = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_details_invoices_table_1';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 5,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Init year 2020 datatable
|
||||
var initInvoiceYear2020 = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_details_invoices_table_2';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 5,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Init year 2019 datatable
|
||||
var initInvoiceYear2019 = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_details_invoices_table_3';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 5,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Init year 2018 datatable
|
||||
var initInvoiceYear2018 = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_details_invoices_table_4';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 5,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initInvoiceYearCurrent();
|
||||
initInvoiceYear2020();
|
||||
initInvoiceYear2019();
|
||||
initInvoiceYear2018();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomerViewInvoices.init();
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomerViewPaymentMethod = function () {
|
||||
|
||||
// Private functions
|
||||
var initPaymentMethod = function () {
|
||||
// Define variables
|
||||
const table = document.getElementById('kt_customer_view_payment_method');
|
||||
const tableRows = table.querySelectorAll('[ data-kt-customer-payment-method="row"]');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
// Select delete button
|
||||
const deleteButton = row.querySelector('[data-kt-customer-payment-method="delete"]');
|
||||
|
||||
// Delete button action
|
||||
deleteButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Popup confirmation
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to delete this card?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
row.remove();
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your card was not deleted!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle set as primary button
|
||||
const handlePrimaryButton = () => {
|
||||
// Define variable
|
||||
const button = document.querySelector('[data-kt-payment-mehtod-action="set_as_primary"]');
|
||||
|
||||
button.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Popup confirmation
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to set this card as primary?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, set it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "Your card was set to primary!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your card was not set to primary!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initPaymentMethod();
|
||||
handlePrimaryButton();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomerViewPaymentMethod.init();
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomerViewPaymentTable = function () {
|
||||
|
||||
// Define shared variables
|
||||
var datatable;
|
||||
var table = document.querySelector('#kt_table_customers_payment');
|
||||
|
||||
// Private functions
|
||||
var initCustomerView = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[3].innerHTML, "DD MMM YYYY, LT").format(); // select date from 4th column in table
|
||||
dateRow[3].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 5,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 5 (actions)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Delete customer
|
||||
var deleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-customer-table-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get customer name
|
||||
const invoiceNumber = parent.querySelectorAll('td')[0].innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete " + invoiceNumber + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + invoiceNumber + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
}).then(function () {
|
||||
// Detect checked checkboxes
|
||||
toggleToolbars();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: customerName + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initCustomerView();
|
||||
deleteRows();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomerViewPaymentTable.init();
|
||||
});
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomerViewStatements = function () {
|
||||
|
||||
// Private functions
|
||||
// Init current year datatable
|
||||
var initStatementYearCurrent = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_view_statement_table_1';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 10,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Init year 2020 datatable
|
||||
var initStatementYear2020 = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_view_statement_table_2';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 10,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Init year 2019 datatable
|
||||
var initStatementYear2019 = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_view_statement_table_3';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 10,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Init year 2018 datatable
|
||||
var initStatementYear2018 = function () {
|
||||
// Define table element
|
||||
const id = '#kt_customer_view_statement_table_4';
|
||||
var table = document.querySelector(id);
|
||||
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "DD MMM YYYY, LT").format(); // select date from 1st column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
var datatable = $(id).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 10,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 0 (download)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initStatementYearCurrent();
|
||||
initStatementYear2020();
|
||||
initStatementYear2019();
|
||||
initStatementYear2018();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomerViewStatements.init();
|
||||
});
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceCategories = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 0 }, // Disable ordering on column 0 (checkbox)
|
||||
{ orderable: false, targets: 3 }, // Disable ordering on column 3 (actions)
|
||||
]
|
||||
});
|
||||
|
||||
// Re-init functions on datatable re-draws
|
||||
datatable.on('draw', function () {
|
||||
handleDeleteRows();
|
||||
});
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-category-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Delete cateogry
|
||||
var handleDeleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-ecommerce-category-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get category name
|
||||
const categoryName = parent.querySelector('[data-kt-ecommerce-category-filter="category_name"]').innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete " + categoryName + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + categoryName + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: categoryName + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_category_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
handleSearchDatatable();
|
||||
handleDeleteRows();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceCategories.init();
|
||||
});
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceProducts = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
'columnDefs': [
|
||||
{ render: DataTable.render.number(',', '.', 2), targets: 4},
|
||||
{ orderable: false, targets: 0 }, // Disable ordering on column 0 (checkbox)
|
||||
{ orderable: false, targets: 7 }, // Disable ordering on column 7 (actions)
|
||||
]
|
||||
});
|
||||
|
||||
// Re-init functions on datatable re-draws
|
||||
datatable.on('draw', function () {
|
||||
handleDeleteRows();
|
||||
});
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-product-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle status filter dropdown
|
||||
var handleStatusFilter = () => {
|
||||
const filterStatus = document.querySelector('[data-kt-ecommerce-product-filter="status"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if(value === 'all'){
|
||||
value = '';
|
||||
}
|
||||
datatable.column(6).search(value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Delete cateogry
|
||||
var handleDeleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-ecommerce-product-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get category name
|
||||
const productName = parent.querySelector('[data-kt-ecommerce-product-filter="product_name"]').innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete " + productName + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + productName + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: productName + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_products_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
handleSearchDatatable();
|
||||
handleStatusFilter();
|
||||
handleDeleteRows();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceProducts.init();
|
||||
});
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceSaveCategory = function () {
|
||||
|
||||
// Private functions
|
||||
|
||||
// Init quill editor
|
||||
const initQuill = () => {
|
||||
// Define all elements for quill editor
|
||||
const elements = [
|
||||
'#kt_ecommerce_add_category_description',
|
||||
'#kt_ecommerce_add_category_meta_description'
|
||||
];
|
||||
|
||||
// Loop all elements
|
||||
elements.forEach(element => {
|
||||
// Get quill element
|
||||
let quill = document.querySelector(element);
|
||||
|
||||
// Break if element not found
|
||||
if (!quill) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Init quill --- more info: https://quilljs.com/docs/quickstart/
|
||||
quill = new Quill(element, {
|
||||
modules: {
|
||||
toolbar: [
|
||||
[{
|
||||
header: [1, 2, false]
|
||||
}],
|
||||
['bold', 'italic', 'underline'],
|
||||
['image', 'code-block']
|
||||
]
|
||||
},
|
||||
placeholder: 'Type your text here...',
|
||||
theme: 'snow' // or 'bubble'
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Init tagify
|
||||
const initTagify = () => {
|
||||
// Define all elements for tagify
|
||||
const elements = [
|
||||
'#kt_ecommerce_add_category_meta_keywords'
|
||||
];
|
||||
|
||||
// Loop all elements
|
||||
elements.forEach(element => {
|
||||
// Get tagify element
|
||||
const tagify = document.querySelector(element);
|
||||
|
||||
// Break if element not found
|
||||
if (!tagify) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Init tagify --- more info: https://yaireo.github.io/tagify/
|
||||
new Tagify(tagify);
|
||||
});
|
||||
}
|
||||
|
||||
// Init form repeater --- more info: https://github.com/DubFriend/jquery.repeater
|
||||
const initFormRepeater = () => {
|
||||
$('#kt_ecommerce_add_category_conditions').repeater({
|
||||
initEmpty: false,
|
||||
|
||||
defaultValues: {
|
||||
'text-input': 'foo'
|
||||
},
|
||||
|
||||
show: function () {
|
||||
$(this).slideDown();
|
||||
|
||||
// Init select2 on new repeated items
|
||||
initConditionsSelect2();
|
||||
},
|
||||
|
||||
hide: function (deleteElement) {
|
||||
$(this).slideUp(deleteElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Init condition select2
|
||||
const initConditionsSelect2 = () => {
|
||||
// Tnit new repeating condition types
|
||||
const allConditionTypes = document.querySelectorAll('[data-kt-ecommerce-catalog-add-category="condition_type"]');
|
||||
allConditionTypes.forEach(type => {
|
||||
if ($(type).hasClass("select2-hidden-accessible")) {
|
||||
return;
|
||||
} else {
|
||||
$(type).select2({
|
||||
minimumResultsForSearch: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Tnit new repeating condition equals
|
||||
const allConditionEquals = document.querySelectorAll('[data-kt-ecommerce-catalog-add-category="condition_equals"]');
|
||||
allConditionEquals.forEach(equal => {
|
||||
if ($(equal).hasClass("select2-hidden-accessible")) {
|
||||
return;
|
||||
} else {
|
||||
$(equal).select2({
|
||||
minimumResultsForSearch: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Category status handler
|
||||
const handleStatus = () => {
|
||||
const target = document.getElementById('kt_ecommerce_add_category_status');
|
||||
const select = document.getElementById('kt_ecommerce_add_category_status_select');
|
||||
const statusClasses = ['bg-success', 'bg-warning', 'bg-danger'];
|
||||
|
||||
$(select).on('change', function (e) {
|
||||
const value = e.target.value;
|
||||
|
||||
switch (value) {
|
||||
case "published": {
|
||||
target.classList.remove(...statusClasses);
|
||||
target.classList.add('bg-success');
|
||||
hideDatepicker();
|
||||
break;
|
||||
}
|
||||
case "scheduled": {
|
||||
target.classList.remove(...statusClasses);
|
||||
target.classList.add('bg-warning');
|
||||
showDatepicker();
|
||||
break;
|
||||
}
|
||||
case "unpublished": {
|
||||
target.classList.remove(...statusClasses);
|
||||
target.classList.add('bg-danger');
|
||||
hideDatepicker();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Handle datepicker
|
||||
const datepicker = document.getElementById('kt_ecommerce_add_category_status_datepicker');
|
||||
|
||||
// Init flatpickr --- more info: https://flatpickr.js.org/
|
||||
$('#kt_ecommerce_add_category_status_datepicker').flatpickr({
|
||||
enableTime: true,
|
||||
dateFormat: "Y-m-d H:i",
|
||||
});
|
||||
|
||||
const showDatepicker = () => {
|
||||
datepicker.parentNode.classList.remove('d-none');
|
||||
}
|
||||
|
||||
const hideDatepicker = () => {
|
||||
datepicker.parentNode.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
// Condition type handler
|
||||
const handleConditions = () => {
|
||||
const allConditions = document.querySelectorAll('[name="method"][type="radio"]');
|
||||
const conditionMatch = document.querySelector('[data-kt-ecommerce-catalog-add-category="auto-options"]');
|
||||
allConditions.forEach(radio => {
|
||||
radio.addEventListener('change', e => {
|
||||
if (e.target.value === '1') {
|
||||
conditionMatch.classList.remove('d-none');
|
||||
} else {
|
||||
conditionMatch.classList.add('d-none');
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Submit form handler
|
||||
const handleSubmit = () => {
|
||||
// Define variables
|
||||
let validator;
|
||||
|
||||
// Get elements
|
||||
const form = document.getElementById('kt_ecommerce_add_category_form');
|
||||
const submitButton = document.getElementById('kt_ecommerce_add_category_submit');
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'category_name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Category name is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Handle submit button
|
||||
submitButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function () {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Redirect to customers list page
|
||||
window.location = form.getAttribute("data-kt-redirect");
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
// Init forms
|
||||
initQuill();
|
||||
initTagify();
|
||||
initFormRepeater();
|
||||
initConditionsSelect2();
|
||||
|
||||
// Handle forms
|
||||
handleStatus();
|
||||
handleConditions();
|
||||
handleSubmit();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceSaveCategory.init();
|
||||
});
|
||||
+416
@@ -0,0 +1,416 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceSaveProduct = function () {
|
||||
|
||||
// Private functions
|
||||
|
||||
// Init quill editor
|
||||
const initQuill = () => {
|
||||
// Define all elements for quill editor
|
||||
const elements = [
|
||||
'#kt_ecommerce_add_product_description',
|
||||
'#kt_ecommerce_add_product_meta_description'
|
||||
];
|
||||
|
||||
// Loop all elements
|
||||
elements.forEach(element => {
|
||||
// Get quill element
|
||||
let quill = document.querySelector(element);
|
||||
|
||||
// Break if element not found
|
||||
if (!quill) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Init quill --- more info: https://quilljs.com/docs/quickstart/
|
||||
quill = new Quill(element, {
|
||||
modules: {
|
||||
toolbar: [
|
||||
[{
|
||||
header: [1, 2, false]
|
||||
}],
|
||||
['bold', 'italic', 'underline'],
|
||||
['image', 'code-block']
|
||||
]
|
||||
},
|
||||
placeholder: 'Type your text here...',
|
||||
theme: 'snow' // or 'bubble'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Init tagify
|
||||
const initTagify = () => {
|
||||
// Define all elements for tagify
|
||||
const elements = [
|
||||
'#kt_ecommerce_add_product_category',
|
||||
'#kt_ecommerce_add_product_tags'
|
||||
];
|
||||
|
||||
// Loop all elements
|
||||
elements.forEach(element => {
|
||||
// Get tagify element
|
||||
const tagify = document.querySelector(element);
|
||||
|
||||
// Break if element not found
|
||||
if (!tagify) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Init tagify --- more info: https://yaireo.github.io/tagify/
|
||||
new Tagify(tagify, {
|
||||
whitelist: ["new", "trending", "sale", "discounted", "selling fast", "last 10"],
|
||||
dropdown: {
|
||||
maxItems: 20, // <- mixumum allowed rendered suggestions
|
||||
classname: "tagify__inline__suggestions", // <- custom classname for this dropdown, so it could be targeted
|
||||
enabled: 0, // <- show suggestions on focus
|
||||
closeOnSelect: false // <- do not hide the suggestions dropdown once an item has been selected
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Init form repeater --- more info: https://github.com/DubFriend/jquery.repeater
|
||||
const initFormRepeater = () => {
|
||||
$('#kt_ecommerce_add_product_options').repeater({
|
||||
initEmpty: false,
|
||||
|
||||
defaultValues: {
|
||||
'text-input': 'foo'
|
||||
},
|
||||
|
||||
show: function () {
|
||||
$(this).slideDown();
|
||||
|
||||
// Init select2 on new repeated items
|
||||
initConditionsSelect2();
|
||||
},
|
||||
|
||||
hide: function (deleteElement) {
|
||||
$(this).slideUp(deleteElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Init condition select2
|
||||
const initConditionsSelect2 = () => {
|
||||
// Tnit new repeating condition types
|
||||
const allConditionTypes = document.querySelectorAll('[data-kt-ecommerce-catalog-add-product="product_option"]');
|
||||
allConditionTypes.forEach(type => {
|
||||
if ($(type).hasClass("select2-hidden-accessible")) {
|
||||
return;
|
||||
} else {
|
||||
$(type).select2({
|
||||
minimumResultsForSearch: -1
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Init noUIslider
|
||||
const initSlider = () => {
|
||||
var slider = document.querySelector("#kt_ecommerce_add_product_discount_slider");
|
||||
var value = document.querySelector("#kt_ecommerce_add_product_discount_label");
|
||||
|
||||
noUiSlider.create(slider, {
|
||||
start: [10],
|
||||
connect: true,
|
||||
range: {
|
||||
"min": 1,
|
||||
"max": 100
|
||||
}
|
||||
});
|
||||
|
||||
slider.noUiSlider.on("update", function (values, handle) {
|
||||
value.innerHTML = Math.round(values[handle]);
|
||||
if (handle) {
|
||||
value.innerHTML = Math.round(values[handle]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Init DropzoneJS --- more info:
|
||||
const initDropzone = () => {
|
||||
var myDropzone = new Dropzone("#kt_ecommerce_add_product_media", {
|
||||
url: "https://keenthemes.com/scripts/void.php", // Set the url for your upload script location
|
||||
paramName: "file", // The name that will be used to transfer the file
|
||||
maxFiles: 10,
|
||||
maxFilesize: 10, // MB
|
||||
addRemoveLinks: true,
|
||||
accept: function (file, done) {
|
||||
if (file.name == "wow.jpg") {
|
||||
done("Naha, you don't.");
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle discount options
|
||||
const handleDiscount = () => {
|
||||
const discountOptions = document.querySelectorAll('input[name="discount_option"]');
|
||||
const percentageEl = document.getElementById('kt_ecommerce_add_product_discount_percentage');
|
||||
const fixedEl = document.getElementById('kt_ecommerce_add_product_discount_fixed');
|
||||
|
||||
discountOptions.forEach(option => {
|
||||
option.addEventListener('change', e => {
|
||||
const value = e.target.value;
|
||||
|
||||
switch (value) {
|
||||
case '2': {
|
||||
percentageEl.classList.remove('d-none');
|
||||
fixedEl.classList.add('d-none');
|
||||
break;
|
||||
}
|
||||
case '3': {
|
||||
percentageEl.classList.add('d-none');
|
||||
fixedEl.classList.remove('d-none');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
percentageEl.classList.add('d-none');
|
||||
fixedEl.classList.add('d-none');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Shipping option handler
|
||||
const handleShipping = () => {
|
||||
const shippingOption = document.getElementById('kt_ecommerce_add_product_shipping_checkbox');
|
||||
const shippingForm = document.getElementById('kt_ecommerce_add_product_shipping');
|
||||
|
||||
shippingOption.addEventListener('change', e => {
|
||||
const value = e.target.checked;
|
||||
|
||||
if (value) {
|
||||
shippingForm.classList.remove('d-none');
|
||||
} else {
|
||||
shippingForm.classList.add('d-none');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Category status handler
|
||||
const handleStatus = () => {
|
||||
const target = document.getElementById('kt_ecommerce_add_product_status');
|
||||
const select = document.getElementById('kt_ecommerce_add_product_status_select');
|
||||
const statusClasses = ['bg-success', 'bg-warning', 'bg-danger'];
|
||||
|
||||
$(select).on('change', function (e) {
|
||||
const value = e.target.value;
|
||||
|
||||
switch (value) {
|
||||
case "published": {
|
||||
target.classList.remove(...statusClasses);
|
||||
target.classList.add('bg-success');
|
||||
hideDatepicker();
|
||||
break;
|
||||
}
|
||||
case "scheduled": {
|
||||
target.classList.remove(...statusClasses);
|
||||
target.classList.add('bg-warning');
|
||||
showDatepicker();
|
||||
break;
|
||||
}
|
||||
case "inactive": {
|
||||
target.classList.remove(...statusClasses);
|
||||
target.classList.add('bg-danger');
|
||||
hideDatepicker();
|
||||
break;
|
||||
}
|
||||
case "draft": {
|
||||
target.classList.remove(...statusClasses);
|
||||
target.classList.add('bg-primary');
|
||||
hideDatepicker();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Handle datepicker
|
||||
const datepicker = document.getElementById('kt_ecommerce_add_product_status_datepicker');
|
||||
|
||||
// Init flatpickr --- more info: https://flatpickr.js.org/
|
||||
$('#kt_ecommerce_add_product_status_datepicker').flatpickr({
|
||||
enableTime: true,
|
||||
dateFormat: "Y-m-d H:i",
|
||||
});
|
||||
|
||||
const showDatepicker = () => {
|
||||
datepicker.parentNode.classList.remove('d-none');
|
||||
}
|
||||
|
||||
const hideDatepicker = () => {
|
||||
datepicker.parentNode.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
// Condition type handler
|
||||
const handleConditions = () => {
|
||||
const allConditions = document.querySelectorAll('[name="method"][type="radio"]');
|
||||
const conditionMatch = document.querySelector('[data-kt-ecommerce-catalog-add-category="auto-options"]');
|
||||
allConditions.forEach(radio => {
|
||||
radio.addEventListener('change', e => {
|
||||
if (e.target.value === '1') {
|
||||
conditionMatch.classList.remove('d-none');
|
||||
} else {
|
||||
conditionMatch.classList.add('d-none');
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Submit form handler
|
||||
const handleSubmit = () => {
|
||||
// Define variables
|
||||
let validator;
|
||||
|
||||
// Get elements
|
||||
const form = document.getElementById('kt_ecommerce_add_product_form');
|
||||
const submitButton = document.getElementById('kt_ecommerce_add_product_submit');
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'product_name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Product name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'sku': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'SKU is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'barcode': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Product barcode is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'shelf': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Shelf quantity is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'price': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Product base price is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'tax': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Product tax class is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Handle submit button
|
||||
submitButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function () {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Redirect to customers list page
|
||||
window.location = form.getAttribute("data-kt-redirect");
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
html: "Sorry, looks like there are some errors detected, please try again. <br/><br/>Please note that there may be errors in the <strong>General</strong> or <strong>Advanced</strong> tabs",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
// Init forms
|
||||
initQuill();
|
||||
initTagify();
|
||||
initSlider();
|
||||
initFormRepeater();
|
||||
initDropzone();
|
||||
initConditionsSelect2();
|
||||
|
||||
// Handle forms
|
||||
handleStatus();
|
||||
handleConditions();
|
||||
handleDiscount();
|
||||
handleShipping();
|
||||
handleSubmit();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceSaveProduct.init();
|
||||
});
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTModalAddAddress = function () {
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var validator;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var handleForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Address name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'country': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Country is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'address1': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Address 1 is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'city': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'City is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'state': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'State is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'postcode': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Postcode is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Revalidate country field. For more info, plase visit the official plugin site: https://select2.org/
|
||||
$(form.querySelector('[name="country"]')).on('change', function() {
|
||||
// Revalidate the field when an option is chosen
|
||||
validator.revalidateField('country');
|
||||
});
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Hide modal
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
modal = new bootstrap.Modal(document.querySelector('#kt_modal_add_address'));
|
||||
|
||||
form = document.querySelector('#kt_modal_add_address_form');
|
||||
submitButton = form.querySelector('#kt_modal_add_address_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_add_address_cancel');
|
||||
closeButton = form.querySelector('#kt_modal_add_address_close');
|
||||
|
||||
handleForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTModalAddAddress.init();
|
||||
});
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTUsersAddAuthApp = function () {
|
||||
// Shared variables
|
||||
const element = document.getElementById('kt_modal_add_auth_app');
|
||||
const modal = new bootstrap.Modal(element);
|
||||
|
||||
// Init add schedule modal
|
||||
var initAddAuthApp = () => {
|
||||
|
||||
// Close button handler
|
||||
const closeButton = element.querySelector('[data-kt-users-modal-action="close"]');
|
||||
closeButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to close?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, close it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
modal.hide(); // Hide modal
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// QR code to text code swapper
|
||||
var initCodeSwap = () => {
|
||||
const qrCode = element.querySelector('[ data-kt-add-auth-action="qr-code"]');
|
||||
const textCode = element.querySelector('[ data-kt-add-auth-action="text-code"]');
|
||||
const qrCodeButton = element.querySelector('[ data-kt-add-auth-action="qr-code-button"]');
|
||||
const textCodeButton = element.querySelector('[ data-kt-add-auth-action="text-code-button"]');
|
||||
const qrCodeLabel = element.querySelector('[ data-kt-add-auth-action="qr-code-label"]');
|
||||
const textCodeLabel = element.querySelector('[ data-kt-add-auth-action="text-code-label"]');
|
||||
|
||||
const toggleClass = () =>{
|
||||
qrCode.classList.toggle('d-none');
|
||||
qrCodeButton.classList.toggle('d-none');
|
||||
qrCodeLabel.classList.toggle('d-none');
|
||||
textCode.classList.toggle('d-none');
|
||||
textCodeButton.classList.toggle('d-none');
|
||||
textCodeLabel.classList.toggle('d-none');
|
||||
}
|
||||
|
||||
// Swap to text code handler
|
||||
textCodeButton.addEventListener('click', e =>{
|
||||
e.preventDefault();
|
||||
|
||||
toggleClass();
|
||||
});
|
||||
|
||||
qrCodeButton.addEventListener('click', e =>{
|
||||
e.preventDefault();
|
||||
|
||||
toggleClass();
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
initAddAuthApp();
|
||||
initCodeSwap();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTUsersAddAuthApp.init();
|
||||
});
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTUsersAddOneTimePassword = function () {
|
||||
// Shared variables
|
||||
const element = document.getElementById('kt_modal_add_one_time_password');
|
||||
const form = element.querySelector('#kt_modal_add_one_time_password_form');
|
||||
const modal = new bootstrap.Modal(element);
|
||||
|
||||
// Init one time password modal
|
||||
var initAddOneTimePassword = () => {
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
var validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'otp_mobile_number': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Valid mobile number is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'otp_confirm_password': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Password confirmation is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Close button handler
|
||||
const closeButton = element.querySelector('[data-kt-users-modal-action="close"]');
|
||||
closeButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to close?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, close it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
modal.hide(); // Hide modal
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Cancel button handler
|
||||
const cancelButton = element.querySelector('[data-kt-users-modal-action="cancel"]');
|
||||
cancelButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Submit button handler
|
||||
const submitButton = element.querySelector('[data-kt-users-modal-action="submit"]');
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable button to avoid multiple click
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission. For more info check the plugin's official documentation: https://sweetalert2.github.io/
|
||||
setTimeout(function () {
|
||||
// Remove loading indication
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Enable button
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show popup warning. For more info check the plugin's official documentation: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
initAddOneTimePassword();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTUsersAddOneTimePassword.init();
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomerViewPaymentMethod = function () {
|
||||
|
||||
// Private functions
|
||||
var initPaymentMethod = function () {
|
||||
// Define variables
|
||||
const table = document.getElementById('kt_customer_view_payment_method');
|
||||
const tableRows = table.querySelectorAll('[ data-kt-customer-payment-method="row"]');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
// Select delete button
|
||||
const deleteButton = row.querySelector('[data-kt-customer-payment-method="delete"]');
|
||||
|
||||
// Delete button action
|
||||
deleteButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Popup confirmation
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to delete this card?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
row.remove();
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your card was not deleted!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle set as primary button
|
||||
const handlePrimaryButton = () => {
|
||||
// Define variable
|
||||
const button = document.querySelector('[data-kt-payment-mehtod-action="set_as_primary"]');
|
||||
|
||||
button.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Popup confirmation
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to set this card as primary?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, set it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "Your card was set to primary!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your card was not set to primary!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initPaymentMethod();
|
||||
handlePrimaryButton();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomerViewPaymentMethod.init();
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomerViewPaymentTable = function () {
|
||||
|
||||
// Define shared variables
|
||||
var datatable;
|
||||
var table = document.querySelector('#kt_table_customers_payment');
|
||||
|
||||
// Private functions
|
||||
var initCustomerView = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[3].innerHTML, "DD MMM YYYY, LT").format(); // select date from 4th column in table
|
||||
dateRow[3].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
"pageLength": 5,
|
||||
"lengthChange": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 4 }, // Disable ordering on column 5 (actions)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Delete customer
|
||||
var deleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-customer-table-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get customer name
|
||||
const invoiceNumber = parent.querySelectorAll('td')[0].innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete " + invoiceNumber + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + invoiceNumber + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
}).then(function () {
|
||||
// Detect checked checkboxes
|
||||
toggleToolbars();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: customerName + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initCustomerView();
|
||||
deleteRows();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomerViewPaymentTable.init();
|
||||
});
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTModalUpdateAddress = function () {
|
||||
var element;
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var form;
|
||||
var modal;
|
||||
var validator;
|
||||
|
||||
// Init form inputs
|
||||
var initForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Address name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'country': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Country is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'address1': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Address 1 is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'city': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'City is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'state': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'State is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'postcode': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Postcode is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Revalidate country field. For more info, plase visit the official plugin site: https://select2.org/
|
||||
$(form.querySelector('[name="country"]')).on('change', function () {
|
||||
// Revalidate the field when an option is chosen
|
||||
validator.revalidateField('country');
|
||||
});
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Hide modal
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
element = document.querySelector('#kt_modal_update_address');
|
||||
modal = new bootstrap.Modal(element);
|
||||
|
||||
form = element.querySelector('#kt_modal_update_address_form');
|
||||
submitButton = form.querySelector('#kt_modal_update_address_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_update_address_cancel');
|
||||
closeButton = element.querySelector('#kt_modal_update_address_close');
|
||||
|
||||
initForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTModalUpdateAddress.init();
|
||||
});
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTUsersUpdatePassword = function () {
|
||||
// Shared variables
|
||||
const element = document.getElementById('kt_modal_update_password');
|
||||
const form = element.querySelector('#kt_modal_update_password_form');
|
||||
const modal = new bootstrap.Modal(element);
|
||||
|
||||
// Init add schedule modal
|
||||
var initUpdatePassword = () => {
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
var validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'current_password': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Current password is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'new_password': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'The password is required'
|
||||
},
|
||||
callback: {
|
||||
message: 'Please enter valid password',
|
||||
callback: function (input) {
|
||||
if (input.value.length > 0) {
|
||||
return validatePassword();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'confirm_password': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'The password confirmation is required'
|
||||
},
|
||||
identical: {
|
||||
compare: function () {
|
||||
return form.querySelector('[name="new_password"]').value;
|
||||
},
|
||||
message: 'The password and its confirm are not the same'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Close button handler
|
||||
const closeButton = element.querySelector('[data-kt-users-modal-action="close"]');
|
||||
closeButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Cancel button handler
|
||||
const cancelButton = element.querySelector('[data-kt-users-modal-action="cancel"]');
|
||||
cancelButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Submit button handler
|
||||
const submitButton = element.querySelector('[data-kt-users-modal-action="submit"]');
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable button to avoid multiple click
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission. For more info check the plugin's official documentation: https://sweetalert2.github.io/
|
||||
setTimeout(function () {
|
||||
// Remove loading indication
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Enable button
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
initUpdatePassword();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTUsersUpdatePassword.init();
|
||||
});
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTUsersUpdateEmail = function () {
|
||||
// Shared variables
|
||||
const element = document.getElementById('kt_modal_update_phone');
|
||||
const form = element.querySelector('#kt_modal_update_phone_form');
|
||||
const modal = new bootstrap.Modal(element);
|
||||
|
||||
// Init add schedule modal
|
||||
var initUpdateEmail = () => {
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
var validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'profile_phone': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Phone number is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Close button handler
|
||||
const closeButton = element.querySelector('[data-kt-users-modal-action="close"]');
|
||||
closeButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Cancel button handler
|
||||
const cancelButton = element.querySelector('[data-kt-users-modal-action="cancel"]');
|
||||
cancelButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Submit button handler
|
||||
const submitButton = element.querySelector('[data-kt-users-modal-action="submit"]');
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable button to avoid multiple click
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission. For more info check the plugin's official documentation: https://sweetalert2.github.io/
|
||||
setTimeout(function () {
|
||||
// Remove loading indication
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Enable button
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
initUpdateEmail();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTUsersUpdateEmail.init();
|
||||
});
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTEcommerceUpdateProfile = function () {
|
||||
var submitButton;
|
||||
var validator;
|
||||
var form;
|
||||
|
||||
// Init form inputs
|
||||
var handleForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'gen_email': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'General Email is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Your profile has been saved!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
form = document.querySelector('#kt_ecommerce_customer_profile');
|
||||
submitButton = form.querySelector('#kt_ecommerce_customer_profile_submit');
|
||||
|
||||
handleForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTEcommerceUpdateProfile.init();
|
||||
});
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTModalCustomersAdd = function () {
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var validator;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var handleForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Customer name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'email': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Customer email is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'first-name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'First name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'last-name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Last name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'country': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Country is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'address1': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Address 1 is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'city': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'City is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'state': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'State is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'postcode': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Postcode is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Revalidate country field. For more info, plase visit the official plugin site: https://select2.org/
|
||||
$(form.querySelector('[name="country"]')).on('change', function() {
|
||||
// Revalidate the field when an option is chosen
|
||||
validator.revalidateField('country');
|
||||
});
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Hide modal
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Redirect to customers list page
|
||||
window.location = form.getAttribute("data-kt-redirect");
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
modal = new bootstrap.Modal(document.querySelector('#kt_modal_add_customer'));
|
||||
|
||||
form = document.querySelector('#kt_modal_add_customer_form');
|
||||
submitButton = form.querySelector('#kt_modal_add_customer_submit');
|
||||
cancelButton = form.querySelector('#kt_modal_add_customer_cancel');
|
||||
closeButton = form.querySelector('#kt_modal_add_customer_close');
|
||||
|
||||
handleForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTModalCustomersAdd.init();
|
||||
});
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomersExport = function () {
|
||||
var element;
|
||||
var submitButton;
|
||||
var cancelButton;
|
||||
var closeButton;
|
||||
var validator;
|
||||
var form;
|
||||
var modal;
|
||||
|
||||
// Init form inputs
|
||||
var handleForm = function () {
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'date': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Date range is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Action buttons
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function() {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Customer list has been successfully exported!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
modal.hide();
|
||||
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
closeButton.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to cancel?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, cancel it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
form.reset(); // Reset form
|
||||
modal.hide(); // Hide modal
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your form has not been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var initForm = function () {
|
||||
const datepicker = form.querySelector("[name=date]");
|
||||
|
||||
// Handle datepicker range -- For more info on flatpickr plugin, please visit: https://flatpickr.js.org/
|
||||
$(datepicker).flatpickr({
|
||||
altInput: true,
|
||||
altFormat: "F j, Y",
|
||||
dateFormat: "Y-m-d",
|
||||
mode: "range"
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
// Public functions
|
||||
init: function () {
|
||||
// Elements
|
||||
element = document.querySelector('#kt_customers_export_modal');
|
||||
modal = new bootstrap.Modal(element);
|
||||
|
||||
form = document.querySelector('#kt_customers_export_form');
|
||||
submitButton = form.querySelector('#kt_customers_export_submit');
|
||||
cancelButton = form.querySelector('#kt_customers_export_cancel');
|
||||
closeButton = element.querySelector('#kt_customers_export_close');
|
||||
|
||||
handleForm();
|
||||
initForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomersExport.init();
|
||||
});
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTCustomersList = function () {
|
||||
// Define shared variables
|
||||
var datatable;
|
||||
var filterMonth;
|
||||
var filterPayment;
|
||||
var table
|
||||
|
||||
// Private functions
|
||||
var initCustomerList = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[5].innerHTML, "DD MMM YYYY, LT").format(); // select date from 5th column in table
|
||||
dateRow[5].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 0 }, // Disable ordering on column 0 (checkbox)
|
||||
{ orderable: false, targets: 6 }, // Disable ordering on column 6 (actions)
|
||||
]
|
||||
});
|
||||
|
||||
// Re-init functions on every table re-draw -- more info: https://datatables.net/reference/event/draw
|
||||
datatable.on('draw', function () {
|
||||
initToggleToolbar();
|
||||
handleDeleteRows();
|
||||
toggleToolbars();
|
||||
});
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-customer-table-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Delete customer
|
||||
var handleDeleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-customer-table-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get customer name
|
||||
const customerName = parent.querySelectorAll('td')[1].innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete " + customerName + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + customerName + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: customerName + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Handle status filter dropdown
|
||||
var handleStatusFilter = () => {
|
||||
const filterStatus = document.querySelector('[data-kt-ecommerce-order-filter="status"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if (value === 'all') {
|
||||
value = '';
|
||||
}
|
||||
datatable.column(3).search(value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Init toggle toolbar
|
||||
var initToggleToolbar = () => {
|
||||
// Toggle selected action toolbar
|
||||
// Select all checkboxes
|
||||
const checkboxes = table.querySelectorAll('[type="checkbox"]');
|
||||
|
||||
// Select elements
|
||||
const deleteSelected = document.querySelector('[data-kt-customer-table-select="delete_selected"]');
|
||||
|
||||
// Toggle delete selected toolbar
|
||||
checkboxes.forEach(c => {
|
||||
// Checkbox on click event
|
||||
c.addEventListener('click', function () {
|
||||
setTimeout(function () {
|
||||
toggleToolbars();
|
||||
}, 50);
|
||||
});
|
||||
});
|
||||
|
||||
// Deleted selected rows
|
||||
deleteSelected.addEventListener('click', function () {
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete selected customers?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted all selected customers!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove all selected customers
|
||||
checkboxes.forEach(c => {
|
||||
if (c.checked) {
|
||||
datatable.row($(c.closest('tbody tr'))).remove().draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Remove header checked box
|
||||
const headerCheckbox = table.querySelectorAll('[type="checkbox"]')[0];
|
||||
headerCheckbox.checked = false;
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Selected customers was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle toolbars
|
||||
const toggleToolbars = () => {
|
||||
// Define variables
|
||||
const toolbarBase = document.querySelector('[data-kt-customer-table-toolbar="base"]');
|
||||
const toolbarSelected = document.querySelector('[data-kt-customer-table-toolbar="selected"]');
|
||||
const selectedCount = document.querySelector('[data-kt-customer-table-select="selected_count"]');
|
||||
|
||||
// Select refreshed checkbox DOM elements
|
||||
const allCheckboxes = table.querySelectorAll('tbody [type="checkbox"]');
|
||||
|
||||
// Detect checkboxes state & count
|
||||
let checkedState = false;
|
||||
let count = 0;
|
||||
|
||||
// Count checked boxes
|
||||
allCheckboxes.forEach(c => {
|
||||
if (c.checked) {
|
||||
checkedState = true;
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle toolbars
|
||||
if (checkedState) {
|
||||
selectedCount.innerHTML = count;
|
||||
toolbarBase.classList.add('d-none');
|
||||
toolbarSelected.classList.remove('d-none');
|
||||
} else {
|
||||
toolbarBase.classList.remove('d-none');
|
||||
toolbarSelected.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_customers_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initCustomerList();
|
||||
initToggleToolbar();
|
||||
handleSearchDatatable();
|
||||
handleDeleteRows();
|
||||
handleStatusFilter();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTCustomersList.init();
|
||||
});
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceReportCustomerOrders = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[3].innerHTML, "DD MMM YYYY, LT").format(); // select date from 4th column in table
|
||||
dateRow[3].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
});
|
||||
}
|
||||
|
||||
// Init daterangepicker
|
||||
var initDaterangepicker = () => {
|
||||
var start = moment().subtract(29, "days");
|
||||
var end = moment();
|
||||
var input = $("#kt_ecommerce_report_customer_orders_daterangepicker");
|
||||
|
||||
function cb(start, end) {
|
||||
input.html(start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY"));
|
||||
}
|
||||
|
||||
input.daterangepicker({
|
||||
startDate: start,
|
||||
endDate: end,
|
||||
ranges: {
|
||||
"Today": [moment(), moment()],
|
||||
"Yesterday": [moment().subtract(1, "days"), moment().subtract(1, "days")],
|
||||
"Last 7 Days": [moment().subtract(6, "days"), moment()],
|
||||
"Last 30 Days": [moment().subtract(29, "days"), moment()],
|
||||
"This Month": [moment().startOf("month"), moment().endOf("month")],
|
||||
"Last Month": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
|
||||
}
|
||||
}, cb);
|
||||
|
||||
cb(start, end);
|
||||
}
|
||||
|
||||
// Handle status filter dropdown
|
||||
var handleStatusFilter = () => {
|
||||
const filterStatus = document.querySelector('[data-kt-ecommerce-order-filter="status"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if (value === 'all') {
|
||||
value = '';
|
||||
}
|
||||
datatable.column(2).search(value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Hook export buttons
|
||||
var exportButtons = () => {
|
||||
const documentTitle = 'Customer Orders Report';
|
||||
var buttons = new $.fn.dataTable.Buttons(table, {
|
||||
buttons: [
|
||||
{
|
||||
extend: 'copyHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'csvHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'pdfHtml5',
|
||||
title: documentTitle
|
||||
}
|
||||
]
|
||||
}).container().appendTo($('#kt_ecommerce_report_customer_orders_export'));
|
||||
|
||||
// Hook dropdown menu click event to datatable export buttons
|
||||
const exportButtons = document.querySelectorAll('#kt_ecommerce_report_customer_orders_export_menu [data-kt-ecommerce-export]');
|
||||
exportButtons.forEach(exportButton => {
|
||||
exportButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Get clicked export value
|
||||
const exportValue = e.target.getAttribute('data-kt-ecommerce-export');
|
||||
const target = document.querySelector('.dt-buttons .buttons-' + exportValue);
|
||||
|
||||
// Trigger click event on hidden datatable export buttons
|
||||
target.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-order-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_report_customer_orders_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
initDaterangepicker();
|
||||
exportButtons();
|
||||
handleSearchDatatable();
|
||||
handleStatusFilter();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceReportCustomerOrders.init();
|
||||
});
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceReportReturns = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "MMM DD, YYYY").format(); // select date from 4th column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
});
|
||||
}
|
||||
|
||||
// Init daterangepicker
|
||||
var initDaterangepicker = () => {
|
||||
var start = moment().subtract(29, "days");
|
||||
var end = moment();
|
||||
var input = $("#kt_ecommerce_report_returns_daterangepicker");
|
||||
|
||||
function cb(start, end) {
|
||||
input.html(start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY"));
|
||||
}
|
||||
|
||||
input.daterangepicker({
|
||||
startDate: start,
|
||||
endDate: end,
|
||||
ranges: {
|
||||
"Today": [moment(), moment()],
|
||||
"Yesterday": [moment().subtract(1, "days"), moment().subtract(1, "days")],
|
||||
"Last 7 Days": [moment().subtract(6, "days"), moment()],
|
||||
"Last 30 Days": [moment().subtract(29, "days"), moment()],
|
||||
"This Month": [moment().startOf("month"), moment().endOf("month")],
|
||||
"Last Month": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
|
||||
}
|
||||
}, cb);
|
||||
|
||||
cb(start, end);
|
||||
}
|
||||
|
||||
// Hook export buttons
|
||||
var exportButtons = () => {
|
||||
const documentTitle = 'Returns Report';
|
||||
var buttons = new $.fn.dataTable.Buttons(table, {
|
||||
buttons: [
|
||||
{
|
||||
extend: 'copyHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'csvHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'pdfHtml5',
|
||||
title: documentTitle
|
||||
}
|
||||
]
|
||||
}).container().appendTo($('#kt_ecommerce_report_returns_export'));
|
||||
|
||||
// Hook dropdown menu click event to datatable export buttons
|
||||
const exportButtons = document.querySelectorAll('#kt_ecommerce_report_returns_export_menu [data-kt-ecommerce-export]');
|
||||
exportButtons.forEach(exportButton => {
|
||||
exportButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Get clicked export value
|
||||
const exportValue = e.target.getAttribute('data-kt-ecommerce-export');
|
||||
const target = document.querySelector('.dt-buttons .buttons-' + exportValue);
|
||||
|
||||
// Trigger click event on hidden datatable export buttons
|
||||
target.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-order-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_report_returns_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
initDaterangepicker();
|
||||
exportButtons();
|
||||
handleSearchDatatable();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceReportReturns.init();
|
||||
});
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceReportSales = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "MMM DD, YYYY").format(); // select date from 4th column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
});
|
||||
}
|
||||
|
||||
// Init daterangepicker
|
||||
var initDaterangepicker = () => {
|
||||
var start = moment().subtract(29, "days");
|
||||
var end = moment();
|
||||
var input = $("#kt_ecommerce_report_sales_daterangepicker");
|
||||
|
||||
function cb(start, end) {
|
||||
input.html(start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY"));
|
||||
}
|
||||
|
||||
input.daterangepicker({
|
||||
startDate: start,
|
||||
endDate: end,
|
||||
ranges: {
|
||||
"Today": [moment(), moment()],
|
||||
"Yesterday": [moment().subtract(1, "days"), moment().subtract(1, "days")],
|
||||
"Last 7 Days": [moment().subtract(6, "days"), moment()],
|
||||
"Last 30 Days": [moment().subtract(29, "days"), moment()],
|
||||
"This Month": [moment().startOf("month"), moment().endOf("month")],
|
||||
"Last Month": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
|
||||
}
|
||||
}, cb);
|
||||
|
||||
cb(start, end);
|
||||
}
|
||||
|
||||
// Hook export buttons
|
||||
var exportButtons = () => {
|
||||
const documentTitle = 'Sales Report';
|
||||
var buttons = new $.fn.dataTable.Buttons(table, {
|
||||
buttons: [
|
||||
{
|
||||
extend: 'copyHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'csvHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'pdfHtml5',
|
||||
title: documentTitle
|
||||
}
|
||||
]
|
||||
}).container().appendTo($('#kt_ecommerce_report_sales_export'));
|
||||
|
||||
// Hook dropdown menu click event to datatable export buttons
|
||||
const exportButtons = document.querySelectorAll('#kt_ecommerce_report_sales_export_menu [data-kt-ecommerce-export]');
|
||||
exportButtons.forEach(exportButton => {
|
||||
exportButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Get clicked export value
|
||||
const exportValue = e.target.getAttribute('data-kt-ecommerce-export');
|
||||
const target = document.querySelector('.dt-buttons .buttons-' + exportValue);
|
||||
|
||||
// Trigger click event on hidden datatable export buttons
|
||||
target.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-order-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_report_sales_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
initDaterangepicker();
|
||||
exportButtons();
|
||||
handleSearchDatatable();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceReportSales.init();
|
||||
});
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceReportShipping = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const realDate = moment(dateRow[0].innerHTML, "MMM DD, YYYY").format(); // select date from 4th column in table
|
||||
dateRow[0].setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
});
|
||||
}
|
||||
|
||||
// Init daterangepicker
|
||||
var initDaterangepicker = () => {
|
||||
var start = moment().subtract(29, "days");
|
||||
var end = moment();
|
||||
var input = $("#kt_ecommerce_report_shipping_daterangepicker");
|
||||
|
||||
function cb(start, end) {
|
||||
input.html(start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY"));
|
||||
}
|
||||
|
||||
input.daterangepicker({
|
||||
startDate: start,
|
||||
endDate: end,
|
||||
ranges: {
|
||||
"Today": [moment(), moment()],
|
||||
"Yesterday": [moment().subtract(1, "days"), moment().subtract(1, "days")],
|
||||
"Last 7 Days": [moment().subtract(6, "days"), moment()],
|
||||
"Last 30 Days": [moment().subtract(29, "days"), moment()],
|
||||
"This Month": [moment().startOf("month"), moment().endOf("month")],
|
||||
"Last Month": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
|
||||
}
|
||||
}, cb);
|
||||
|
||||
cb(start, end);
|
||||
}
|
||||
|
||||
// Handle status filter dropdown
|
||||
var handleStatusFilter = () => {
|
||||
const filterStatus = document.querySelector('[data-kt-ecommerce-order-filter="status"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if (value === 'all') {
|
||||
value = '';
|
||||
}
|
||||
datatable.column(3).search(value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Hook export buttons
|
||||
var exportButtons = () => {
|
||||
const documentTitle = 'Shipping Report';
|
||||
var buttons = new $.fn.dataTable.Buttons(table, {
|
||||
buttons: [
|
||||
{
|
||||
extend: 'copyHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'csvHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'pdfHtml5',
|
||||
title: documentTitle
|
||||
}
|
||||
]
|
||||
}).container().appendTo($('#kt_ecommerce_report_shipping_export'));
|
||||
|
||||
// Hook dropdown menu click event to datatable export buttons
|
||||
const exportButtons = document.querySelectorAll('#kt_ecommerce_report_shipping_export_menu [data-kt-ecommerce-export]');
|
||||
exportButtons.forEach(exportButton => {
|
||||
exportButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Get clicked export value
|
||||
const exportValue = e.target.getAttribute('data-kt-ecommerce-export');
|
||||
const target = document.querySelector('.dt-buttons .buttons-' + exportValue);
|
||||
|
||||
// Trigger click event on hidden datatable export buttons
|
||||
target.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-order-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_report_shipping_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
initDaterangepicker();
|
||||
exportButtons();
|
||||
handleSearchDatatable();
|
||||
handleStatusFilter();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceReportShipping.init();
|
||||
});
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceReportViews = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
});
|
||||
}
|
||||
|
||||
// Init daterangepicker
|
||||
var initDaterangepicker = () => {
|
||||
var start = moment().subtract(29, "days");
|
||||
var end = moment();
|
||||
var input = $("#kt_ecommerce_report_views_daterangepicker");
|
||||
|
||||
function cb(start, end) {
|
||||
input.html(start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY"));
|
||||
}
|
||||
|
||||
input.daterangepicker({
|
||||
startDate: start,
|
||||
endDate: end,
|
||||
ranges: {
|
||||
"Today": [moment(), moment()],
|
||||
"Yesterday": [moment().subtract(1, "days"), moment().subtract(1, "days")],
|
||||
"Last 7 Days": [moment().subtract(6, "days"), moment()],
|
||||
"Last 30 Days": [moment().subtract(29, "days"), moment()],
|
||||
"This Month": [moment().startOf("month"), moment().endOf("month")],
|
||||
"Last Month": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
|
||||
}
|
||||
}, cb);
|
||||
|
||||
cb(start, end);
|
||||
}
|
||||
|
||||
// Handle rating filter dropdown
|
||||
var handleStatusFilter = () => {
|
||||
const filterStatus = document.querySelector('[data-kt-ecommerce-order-filter="rating"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if (value === 'all') {
|
||||
value = '';
|
||||
}
|
||||
datatable.column(2).search(value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Hook export buttons
|
||||
var exportButtons = () => {
|
||||
const documentTitle = 'Product Views Report';
|
||||
var buttons = new $.fn.dataTable.Buttons(table, {
|
||||
buttons: [
|
||||
{
|
||||
extend: 'copyHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'csvHtml5',
|
||||
title: documentTitle
|
||||
},
|
||||
{
|
||||
extend: 'pdfHtml5',
|
||||
title: documentTitle
|
||||
}
|
||||
]
|
||||
}).container().appendTo($('#kt_ecommerce_report_views_export'));
|
||||
|
||||
// Hook dropdown menu click event to datatable export buttons
|
||||
const exportButtons = document.querySelectorAll('#kt_ecommerce_report_views_export_menu [data-kt-ecommerce-export]');
|
||||
exportButtons.forEach(exportButton => {
|
||||
exportButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Get clicked export value
|
||||
const exportValue = e.target.getAttribute('data-kt-ecommerce-export');
|
||||
const target = document.querySelector('.dt-buttons .buttons-' + exportValue);
|
||||
|
||||
// Trigger click event on hidden datatable export buttons
|
||||
target.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-order-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_report_views_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
initDaterangepicker();
|
||||
exportButtons();
|
||||
handleSearchDatatable();
|
||||
handleStatusFilter();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceReportViews.init();
|
||||
});
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceSalesListing = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
var flatpickr;
|
||||
var minDate, maxDate;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 0 }, // Disable ordering on column 0 (checkbox)
|
||||
{ orderable: false, targets: 7 }, // Disable ordering on column 7 (actions)
|
||||
]
|
||||
});
|
||||
|
||||
// Re-init functions on datatable re-draws
|
||||
datatable.on('draw', function () {
|
||||
handleDeleteRows();
|
||||
});
|
||||
}
|
||||
|
||||
// Init flatpickr --- more info :https://flatpickr.js.org/getting-started/
|
||||
var initFlatpickr = () => {
|
||||
const element = document.querySelector('#kt_ecommerce_sales_flatpickr');
|
||||
flatpickr = $(element).flatpickr({
|
||||
altInput: true,
|
||||
altFormat: "d/m/Y",
|
||||
dateFormat: "Y-m-d",
|
||||
mode: "range",
|
||||
onChange: function (selectedDates, dateStr, instance) {
|
||||
handleFlatpickr(selectedDates, dateStr, instance);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-order-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle status filter dropdown
|
||||
var handleStatusFilter = () => {
|
||||
const filterStatus = document.querySelector('[data-kt-ecommerce-order-filter="status"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if (value === 'all') {
|
||||
value = '';
|
||||
}
|
||||
datatable.column(3).search(value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle flatpickr --- more info: https://flatpickr.js.org/events/
|
||||
var handleFlatpickr = (selectedDates, dateStr, instance) => {
|
||||
minDate = selectedDates[0] ? new Date(selectedDates[0]) : null;
|
||||
maxDate = selectedDates[1] ? new Date(selectedDates[1]) : null;
|
||||
|
||||
// Datatable date filter --- more info: https://datatables.net/extensions/datetime/examples/integration/datatables.html
|
||||
// Custom filtering function which will search data in column four between two values
|
||||
$.fn.dataTable.ext.search.push(
|
||||
function (settings, data, dataIndex) {
|
||||
var min = minDate;
|
||||
var max = maxDate;
|
||||
var dateAdded = new Date(moment($(data[5]).text(), 'DD/MM/YYYY'));
|
||||
var dateModified = new Date(moment($(data[6]).text(), 'DD/MM/YYYY'));
|
||||
|
||||
if (
|
||||
(min === null && max === null) ||
|
||||
(min === null && max >= dateModified) ||
|
||||
(min <= dateAdded && max === null) ||
|
||||
(min <= dateAdded && max >= dateModified)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
datatable.draw();
|
||||
}
|
||||
|
||||
// Handle clear flatpickr
|
||||
var handleClearFlatpickr = () => {
|
||||
const clearButton = document.querySelector('#kt_ecommerce_sales_flatpickr_clear');
|
||||
clearButton.addEventListener('click', e => {
|
||||
flatpickr.clear();
|
||||
});
|
||||
}
|
||||
|
||||
// Delete cateogry
|
||||
var handleDeleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-ecommerce-order-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get category name
|
||||
const orderID = parent.querySelector('[data-kt-ecommerce-order-filter="order_id"]').innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete order: " + orderID + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + orderID + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: orderID + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_ecommerce_sales_table');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
initFlatpickr();
|
||||
handleSearchDatatable();
|
||||
handleStatusFilter();
|
||||
handleDeleteRows();
|
||||
handleClearFlatpickr();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceSalesListing.init();
|
||||
});
|
||||
+338
@@ -0,0 +1,338 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceSalesSaveOrder = function () {
|
||||
// Shared variables
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
const initSaveOrder = () => {
|
||||
// Init flatpickr
|
||||
$('#kt_ecommerce_edit_order_date').flatpickr({
|
||||
altInput: true,
|
||||
altFormat: "d F, Y",
|
||||
dateFormat: "Y-m-d",
|
||||
});
|
||||
|
||||
// Init select2 country options
|
||||
// Format options
|
||||
const optionFormat = (item) => {
|
||||
if ( !item.id ) {
|
||||
return item.text;
|
||||
}
|
||||
|
||||
var span = document.createElement('span');
|
||||
var template = '';
|
||||
|
||||
template += '<img src="' + item.element.getAttribute('data-kt-select2-country') + '" class="rounded-circle h-20px me-2" alt="image"/>';
|
||||
template += item.text;
|
||||
|
||||
span.innerHTML = template;
|
||||
|
||||
return $(span);
|
||||
}
|
||||
|
||||
// Init Select2 --- more info: https://select2.org/
|
||||
$('#kt_ecommerce_edit_order_billing_country').select2({
|
||||
placeholder: "Select a country",
|
||||
minimumResultsForSearch: Infinity,
|
||||
templateSelection: optionFormat,
|
||||
templateResult: optionFormat
|
||||
});
|
||||
|
||||
$('#kt_ecommerce_edit_order_shipping_country').select2({
|
||||
placeholder: "Select a country",
|
||||
minimumResultsForSearch: Infinity,
|
||||
templateSelection: optionFormat,
|
||||
templateResult: optionFormat
|
||||
});
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
table = document.querySelector('#kt_ecommerce_edit_order_product_table');
|
||||
datatable = $(table).DataTable({
|
||||
'order': [],
|
||||
"scrollY": "400px",
|
||||
"scrollCollapse": true,
|
||||
"paging": false,
|
||||
"info": false,
|
||||
'columnDefs': [
|
||||
{ orderable: false, targets: 0 }, // Disable ordering on column 0 (checkbox)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-ecommerce-edit-order-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle shipping form
|
||||
const handleShippingForm = () => {
|
||||
// Select elements
|
||||
const element = document.getElementById('kt_ecommerce_edit_order_shipping_form');
|
||||
const checkbox = document.getElementById('same_as_billing');
|
||||
|
||||
// Show/hide shipping form
|
||||
checkbox.addEventListener('change', e => {
|
||||
if (e.target.checked) {
|
||||
element.classList.add('d-none');
|
||||
} else {
|
||||
element.classList.remove('d-none');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle product select
|
||||
const handleProductSelect = () => {
|
||||
// Define variables
|
||||
const checkboxes = table.querySelectorAll('[type="checkbox"]');
|
||||
const target = document.getElementById('kt_ecommerce_edit_order_selected_products');
|
||||
const totalPrice = document.getElementById('kt_ecommerce_edit_order_total_price');
|
||||
|
||||
// Loop through all checked products
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', e => {
|
||||
// Select parent row element
|
||||
const parent = checkbox.closest('tr');
|
||||
|
||||
// Clone parent element as variable
|
||||
const product = parent.querySelector('[data-kt-ecommerce-edit-order-filter="product"]').cloneNode(true);
|
||||
|
||||
// Create inner wrapper
|
||||
const innerWrapper = document.createElement('div');
|
||||
|
||||
// Store inner content
|
||||
const innerContent = product.innerHTML;
|
||||
|
||||
// Add & remove classes on parent wrapper
|
||||
const wrapperClassesAdd = ['col', 'my-2'];
|
||||
const wrapperClassesRemove = ['d-flex', 'align-items-center'];
|
||||
|
||||
// Define additional classes
|
||||
const additionalClasses = ['border', 'border-dashed', 'rounded', 'p-3', 'bg-body'];
|
||||
|
||||
// Update parent wrapper classes
|
||||
product.classList.remove(...wrapperClassesRemove);
|
||||
product.classList.add(...wrapperClassesAdd);
|
||||
|
||||
// Remove parent default content
|
||||
product.innerHTML = '';
|
||||
|
||||
// Update inner wrapper classes
|
||||
innerWrapper.classList.add(...wrapperClassesRemove);
|
||||
innerWrapper.classList.add(...additionalClasses);
|
||||
|
||||
// Apply stored inner content into new inner wrapper
|
||||
innerWrapper.innerHTML = innerContent;
|
||||
|
||||
// Append new inner wrapper to parent wrapper
|
||||
product.appendChild(innerWrapper);
|
||||
|
||||
// Get product id
|
||||
const productId = product.getAttribute('data-kt-ecommerce-edit-order-id');
|
||||
|
||||
if (e.target.checked) {
|
||||
// Add product to selected product wrapper
|
||||
target.appendChild(product);
|
||||
} else {
|
||||
// Remove product from selected product wrapper
|
||||
const selectedProduct = target.querySelector('[data-kt-ecommerce-edit-order-id="' + productId + '"]');
|
||||
if (selectedProduct) {
|
||||
target.removeChild(selectedProduct);
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger empty message logic
|
||||
detectEmpty();
|
||||
});
|
||||
});
|
||||
|
||||
// Handle empty list message
|
||||
const detectEmpty = () => {
|
||||
// Select elements
|
||||
const message = target.querySelector('span');
|
||||
const products = target.querySelectorAll('[data-kt-ecommerce-edit-order-filter="product"]');
|
||||
|
||||
// Detect if element is empty
|
||||
if (products.length < 1) {
|
||||
// Show message
|
||||
message.classList.remove('d-none');
|
||||
|
||||
// Reset price
|
||||
totalPrice.innerText = '0.00';
|
||||
} else {
|
||||
// Hide message
|
||||
message.classList.add('d-none');
|
||||
|
||||
// Calculate price
|
||||
calculateTotal(products);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total cost
|
||||
const calculateTotal = (products) => {
|
||||
let countPrice = 0;
|
||||
|
||||
// Loop through all selected prodcucts
|
||||
products.forEach(product => {
|
||||
// Get product price
|
||||
const price = parseFloat(product.querySelector('[data-kt-ecommerce-edit-order-filter="price"]').innerText);
|
||||
|
||||
// Add to total
|
||||
countPrice = parseFloat(countPrice + price);
|
||||
});
|
||||
|
||||
// Update total price
|
||||
totalPrice.innerText = countPrice.toFixed(2);
|
||||
}
|
||||
}
|
||||
|
||||
// Submit form handler
|
||||
const handleSubmit = () => {
|
||||
// Define variables
|
||||
let validator;
|
||||
|
||||
// Get elements
|
||||
const form = document.getElementById('kt_ecommerce_edit_order_form');
|
||||
const submitButton = document.getElementById('kt_ecommerce_edit_order_submit');
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'payment_method': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Payment method is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'shipping_method': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Shipping method is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'order_date': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Order date is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'billing_order_address_1': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Address line 1 is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'billing_order_postcode': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Postcode is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'billing_order_state': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'State is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
'billing_order_country': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Country is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Handle submit button
|
||||
submitButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable submit button whilst loading
|
||||
submitButton.disabled = true;
|
||||
|
||||
setTimeout(function () {
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
// Enable submit button after loading
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Redirect to customers list page
|
||||
window.location = form.getAttribute("data-kt-redirect");
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
html: "Sorry, looks like there are some errors detected, please try again.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
|
||||
initSaveOrder();
|
||||
handleSearchDatatable();
|
||||
handleShippingForm();
|
||||
handleProductSelect();
|
||||
handleSubmit();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceSalesSaveOrder.init();
|
||||
});
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppEcommerceSettings = function () {
|
||||
// Shared variables
|
||||
|
||||
|
||||
// Private functions
|
||||
const initForms = () => {
|
||||
const forms = [
|
||||
'kt_ecommerce_settings_general_form',
|
||||
'kt_ecommerce_settings_general_store',
|
||||
'kt_ecommerce_settings_general_localization',
|
||||
'kt_ecommerce_settings_general_products',
|
||||
'kt_ecommerce_settings_general_customers',
|
||||
];
|
||||
|
||||
// Init all forms
|
||||
forms.forEach(formId => {
|
||||
// Select form
|
||||
const form = document.getElementById(formId);
|
||||
|
||||
if(!form){
|
||||
return;
|
||||
}
|
||||
|
||||
// Dynamically create validation non-empty rule
|
||||
const requiredFields = form.querySelectorAll('.required');
|
||||
var detectedField;
|
||||
var validationFields = {
|
||||
fields: {},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Detect required fields
|
||||
requiredFields.forEach(el => {
|
||||
const input = el.closest('.row').querySelector('input');
|
||||
if (input) {
|
||||
detectedField = input;
|
||||
}
|
||||
|
||||
const textarea = el.closest('.row').querySelector('textarea');
|
||||
if (textarea) {
|
||||
detectedField = textarea;
|
||||
}
|
||||
|
||||
const select = el.closest('.row').querySelector('select');
|
||||
if (select) {
|
||||
detectedField = select;
|
||||
}
|
||||
|
||||
// Add validation rule
|
||||
const name = detectedField.getAttribute('name');
|
||||
validationFields.fields[name] = {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: el.innerText + ' is required'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
var validator = FormValidation.formValidation(
|
||||
form,
|
||||
validationFields
|
||||
);
|
||||
|
||||
// Submit button handler
|
||||
const submitButton = form.querySelector('[data-kt-ecommerce-settings-type="submit"]');
|
||||
submitButton.addEventListener('click', function (e) {
|
||||
// Prevent default button action
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Show loading indication
|
||||
submitButton.setAttribute('data-kt-indicator', 'on');
|
||||
|
||||
// Disable button to avoid multiple click
|
||||
submitButton.disabled = true;
|
||||
|
||||
// Simulate form submission. For more info check the plugin's official documentation: https://sweetalert2.github.io/
|
||||
setTimeout(function () {
|
||||
// Remove loading indication
|
||||
submitButton.removeAttribute('data-kt-indicator');
|
||||
|
||||
// Enable button
|
||||
submitButton.disabled = false;
|
||||
|
||||
// Show popup confirmation
|
||||
Swal.fire({
|
||||
text: "Form has been successfully submitted!",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
|
||||
//form.submit(); // Submit form
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show popup error
|
||||
Swal.fire({
|
||||
text: "Oops! There are some error(s) detected.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary"
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Init Tagify
|
||||
const initTagify = () => {
|
||||
// Get tagify elements
|
||||
const elements = document.querySelectorAll('[data-kt-ecommerce-settings-type="tagify"]');
|
||||
|
||||
// Init tagify
|
||||
elements.forEach(element => {
|
||||
new Tagify(element);
|
||||
});
|
||||
}
|
||||
|
||||
// Init Select2 with flags
|
||||
const initSelect2Flags = () => {
|
||||
// Format options
|
||||
const optionFormat = (item) => {
|
||||
if ( !item.id ) {
|
||||
return item.text;
|
||||
}
|
||||
|
||||
var span = document.createElement('span');
|
||||
var template = '';
|
||||
|
||||
template += '<img src="' + item.element.getAttribute('data-kt-select2-country') + '" class="rounded-circle h-20px me-2" alt="image"/>';
|
||||
template += item.text;
|
||||
|
||||
span.innerHTML = template;
|
||||
|
||||
return $(span);
|
||||
}
|
||||
|
||||
// Init Select2 --- more info: https://select2.org/
|
||||
$('[data-kt-ecommerce-settings-type="select2_flags"]').select2({
|
||||
placeholder: "Select a country",
|
||||
minimumResultsForSearch: Infinity,
|
||||
templateSelection: optionFormat,
|
||||
templateResult: optionFormat
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
|
||||
initForms();
|
||||
initTagify();
|
||||
initSelect2Flags();
|
||||
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppEcommerceSettings.init();
|
||||
});
|
||||
+939
@@ -0,0 +1,939 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTFileManagerList = function () {
|
||||
// Define shared variables
|
||||
var datatable;
|
||||
var table
|
||||
|
||||
// Define template element variables
|
||||
var uploadTemplate;
|
||||
var renameTemplate;
|
||||
var actionTemplate;
|
||||
var checkboxTemplate;
|
||||
|
||||
|
||||
// Private functions
|
||||
const initTemplates = () => {
|
||||
uploadTemplate = document.querySelector('[data-kt-filemanager-template="upload"]');
|
||||
renameTemplate = document.querySelector('[data-kt-filemanager-template="rename"]');
|
||||
actionTemplate = document.querySelector('[data-kt-filemanager-template="action"]');
|
||||
checkboxTemplate = document.querySelector('[data-kt-filemanager-template="checkbox"]');
|
||||
}
|
||||
|
||||
const initDatatable = () => {
|
||||
// Set date data order
|
||||
const tableRows = table.querySelectorAll('tbody tr');
|
||||
|
||||
tableRows.forEach(row => {
|
||||
const dateRow = row.querySelectorAll('td');
|
||||
const dateCol = dateRow[3]; // select date from 4th column in table
|
||||
const realDate = moment(dateCol.innerHTML, "DD MMM YYYY, LT").format();
|
||||
dateCol.setAttribute('data-order', realDate);
|
||||
});
|
||||
|
||||
const foldersListOptions = {
|
||||
"info": false,
|
||||
'order': [],
|
||||
"scrollY": "700px",
|
||||
"scrollCollapse": true,
|
||||
"paging": false,
|
||||
'ordering': false,
|
||||
'columns': [
|
||||
{ data: 'checkbox' },
|
||||
{ data: 'name' },
|
||||
{ data: 'size' },
|
||||
{ data: 'date' },
|
||||
{ data: 'action' },
|
||||
],
|
||||
'language': {
|
||||
emptyTable: `<div class="d-flex flex-column flex-center">
|
||||
<img src="${hostUrl}media/illustrations/sketchy-1/5.png" class="mw-400px" />
|
||||
<div class="fs-1 fw-bolder text-dark">No items found.</div>
|
||||
<div class="fs-6">Start creating new folders or uploading a new file!</div>
|
||||
</div>`
|
||||
}
|
||||
};
|
||||
|
||||
const filesListOptions = {
|
||||
"info": false,
|
||||
'order': [],
|
||||
'pageLength': 10,
|
||||
"lengthChange": false,
|
||||
'ordering': false,
|
||||
'columns': [
|
||||
{ data: 'checkbox' },
|
||||
{ data: 'name' },
|
||||
{ data: 'size' },
|
||||
{ data: 'date' },
|
||||
{ data: 'action' },
|
||||
],
|
||||
'language': {
|
||||
emptyTable: `<div class="d-flex flex-column flex-center">
|
||||
<img src="${hostUrl}media/illustrations/sketchy-1/5.png" class="mw-400px" />
|
||||
<div class="fs-1 fw-bolder text-dark mb-4">No items found.</div>
|
||||
<div class="fs-6">Start creating new folders or uploading a new file!</div>
|
||||
</div>`
|
||||
},
|
||||
conditionalPaging: true
|
||||
};
|
||||
|
||||
// Define datatable options to load
|
||||
var loadOptions;
|
||||
if (table.getAttribute('data-kt-filemanager-table') === 'folders') {
|
||||
loadOptions = foldersListOptions;
|
||||
} else {
|
||||
loadOptions = filesListOptions;
|
||||
}
|
||||
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable(loadOptions);
|
||||
|
||||
// Re-init functions on every table re-draw -- more info: https://datatables.net/reference/event/draw
|
||||
datatable.on('draw', function () {
|
||||
initToggleToolbar();
|
||||
handleDeleteRows();
|
||||
toggleToolbars();
|
||||
resetNewFolder();
|
||||
KTMenu.createInstances();
|
||||
initCopyLink();
|
||||
countTotalItems();
|
||||
handleRename();
|
||||
});
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
const handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-filemanager-table-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
// Delete customer
|
||||
const handleDeleteRows = () => {
|
||||
// Select all delete buttons
|
||||
const deleteButtons = table.querySelectorAll('[data-kt-filemanager-table-filter="delete_row"]');
|
||||
|
||||
deleteButtons.forEach(d => {
|
||||
// Delete button on click
|
||||
d.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get customer name
|
||||
const fileName = parent.querySelectorAll('td')[1].innerText;
|
||||
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete " + fileName + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted " + fileName + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove current row
|
||||
datatable.row($(parent)).remove().draw();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: customerName + " was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Init toggle toolbar
|
||||
const initToggleToolbar = () => {
|
||||
// Toggle selected action toolbar
|
||||
// Select all checkboxes
|
||||
var checkboxes = table.querySelectorAll('[type="checkbox"]');
|
||||
if (table.getAttribute('data-kt-filemanager-table') === 'folders') {
|
||||
checkboxes = document.querySelectorAll('#kt_file_manager_list_wrapper [type="checkbox"]');
|
||||
}
|
||||
|
||||
// Select elements
|
||||
const deleteSelected = document.querySelector('[data-kt-filemanager-table-select="delete_selected"]');
|
||||
|
||||
// Toggle delete selected toolbar
|
||||
checkboxes.forEach(c => {
|
||||
// Checkbox on click event
|
||||
c.addEventListener('click', function () {
|
||||
console.log(c);
|
||||
setTimeout(function () {
|
||||
toggleToolbars();
|
||||
}, 50);
|
||||
});
|
||||
});
|
||||
|
||||
// Deleted selected rows
|
||||
deleteSelected.addEventListener('click', function () {
|
||||
// SweetAlert2 pop up --- official docs reference: https://sweetalert2.github.io/
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to delete selected files or folders?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, delete!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have deleted all selected files or folders!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Remove all selected customers
|
||||
checkboxes.forEach(c => {
|
||||
if (c.checked) {
|
||||
datatable.row($(c.closest('tbody tr'))).remove().draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Remove header checked box
|
||||
const headerCheckbox = table.querySelectorAll('[type="checkbox"]')[0];
|
||||
headerCheckbox.checked = false;
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Selected files or folders was not deleted.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle toolbars
|
||||
const toggleToolbars = () => {
|
||||
// Define variables
|
||||
const toolbarBase = document.querySelector('[data-kt-filemanager-table-toolbar="base"]');
|
||||
const toolbarSelected = document.querySelector('[data-kt-filemanager-table-toolbar="selected"]');
|
||||
const selectedCount = document.querySelector('[data-kt-filemanager-table-select="selected_count"]');
|
||||
|
||||
// Select refreshed checkbox DOM elements
|
||||
const allCheckboxes = table.querySelectorAll('tbody [type="checkbox"]');
|
||||
|
||||
// Detect checkboxes state & count
|
||||
let checkedState = false;
|
||||
let count = 0;
|
||||
|
||||
// Count checked boxes
|
||||
allCheckboxes.forEach(c => {
|
||||
if (c.checked) {
|
||||
checkedState = true;
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle toolbars
|
||||
if (checkedState) {
|
||||
selectedCount.innerHTML = count;
|
||||
toolbarBase.classList.add('d-none');
|
||||
toolbarSelected.classList.remove('d-none');
|
||||
} else {
|
||||
toolbarBase.classList.remove('d-none');
|
||||
toolbarSelected.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle new folder
|
||||
const handleNewFolder = () => {
|
||||
// Select button
|
||||
const newFolder = document.getElementById('kt_file_manager_new_folder');
|
||||
|
||||
// Handle click action
|
||||
newFolder.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Ignore if input already exist
|
||||
if (table.querySelector('#kt_file_manager_new_folder_row')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add new blank row to datatable
|
||||
const tableBody = table.querySelector('tbody');
|
||||
const rowElement = uploadTemplate.cloneNode(true); // Clone template markup
|
||||
tableBody.prepend(rowElement);
|
||||
|
||||
// Define template interactive elements
|
||||
const rowForm = rowElement.querySelector('#kt_file_manager_add_folder_form');
|
||||
const rowButton = rowElement.querySelector('#kt_file_manager_add_folder');
|
||||
const cancelButton = rowElement.querySelector('#kt_file_manager_cancel_folder');
|
||||
const folderIcon = rowElement.querySelector('#kt_file_manager_folder_icon');
|
||||
const rowInput = rowElement.querySelector('[name="new_folder_name"]');
|
||||
|
||||
// Define validator
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
var validator = FormValidation.formValidation(
|
||||
rowForm,
|
||||
{
|
||||
fields: {
|
||||
'new_folder_name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Folder name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Handle add new folder button
|
||||
rowButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Activate indicator
|
||||
rowButton.setAttribute("data-kt-indicator", "on");
|
||||
|
||||
// Validate form before submit
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Simulate process for demo only
|
||||
setTimeout(function () {
|
||||
// Create folder link
|
||||
const folderLink = document.createElement('a');
|
||||
const folderLinkClasses = ['text-gray-800', 'text-hover-primary'];
|
||||
folderLink.setAttribute('href', '?page=apps/file-manager/blank');
|
||||
folderLink.classList.add(...folderLinkClasses);
|
||||
folderLink.innerText = rowInput.value;
|
||||
|
||||
const newRow = datatable.row.add({
|
||||
'checkbox': checkboxTemplate.innerHTML,
|
||||
'name': folderIcon.outerHTML + folderLink.outerHTML,
|
||||
"size": '-',
|
||||
"date": '-',
|
||||
'action': actionTemplate.innerHTML
|
||||
}).node();
|
||||
$(newRow).find('td').eq(4).attr('data-kt-filemanager-table', 'action_dropdown');
|
||||
$(newRow).find('td').eq(4).addClass('text-end'); // Add custom class to last 'td' element --- more info: https://datatables.net/forums/discussion/22341/row-add-cell-class
|
||||
|
||||
// Re-sort datatable to allow new folder added at the top
|
||||
var index = datatable.row(0).index(),
|
||||
rowCount = datatable.data().length - 1,
|
||||
insertedRow = datatable.row(rowCount).data(),
|
||||
tempRow;
|
||||
|
||||
for (var i = rowCount; i > index; i--) {
|
||||
tempRow = datatable.row(i - 1).data();
|
||||
datatable.row(i).data(tempRow);
|
||||
datatable.row(i - 1).data(insertedRow);
|
||||
}
|
||||
|
||||
toastr.options = {
|
||||
"closeButton": true,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toastr-top-right",
|
||||
"preventDuplicates": false,
|
||||
"showDuration": "300",
|
||||
"hideDuration": "1000",
|
||||
"timeOut": "5000",
|
||||
"extendedTimeOut": "1000",
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut"
|
||||
};
|
||||
|
||||
toastr.success(rowInput.value + ' was created!');
|
||||
|
||||
// Disable indicator
|
||||
rowButton.removeAttribute("data-kt-indicator");
|
||||
|
||||
// Reset input
|
||||
rowInput.value = '';
|
||||
|
||||
datatable.draw(false);
|
||||
|
||||
}, 2000);
|
||||
} else {
|
||||
// Disable indicator
|
||||
rowButton.removeAttribute("data-kt-indicator");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Handle cancel new folder button
|
||||
cancelButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Activate indicator
|
||||
cancelButton.setAttribute("data-kt-indicator", "on");
|
||||
|
||||
setTimeout(function () {
|
||||
// Disable indicator
|
||||
cancelButton.removeAttribute("data-kt-indicator");
|
||||
|
||||
// Toggle toastr
|
||||
toastr.options = {
|
||||
"closeButton": true,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toastr-top-right",
|
||||
"preventDuplicates": false,
|
||||
"showDuration": "300",
|
||||
"hideDuration": "1000",
|
||||
"timeOut": "5000",
|
||||
"extendedTimeOut": "1000",
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut"
|
||||
};
|
||||
|
||||
toastr.error('Cancelled new folder creation');
|
||||
resetNewFolder();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Reset add new folder input
|
||||
const resetNewFolder = () => {
|
||||
const newFolderRow = table.querySelector('#kt_file_manager_new_folder_row');
|
||||
|
||||
if (newFolderRow) {
|
||||
newFolderRow.parentNode.removeChild(newFolderRow);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle rename file or folder
|
||||
const handleRename = () => {
|
||||
const renameButton = table.querySelectorAll('[data-kt-filemanager-table="rename"]');
|
||||
|
||||
renameButton.forEach(button => {
|
||||
button.addEventListener('click', renameCallback);
|
||||
});
|
||||
}
|
||||
|
||||
// Rename callback
|
||||
const renameCallback = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// Define shared value
|
||||
let nameValue;
|
||||
|
||||
// Stop renaming if there's an input existing
|
||||
if (table.querySelectorAll('#kt_file_manager_rename_input').length > 0) {
|
||||
Swal.fire({
|
||||
text: "Unsaved input detected. Please save or cancel the current item",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger"
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Select parent row
|
||||
const parent = e.target.closest('tr');
|
||||
|
||||
// Get name column
|
||||
const nameCol = parent.querySelectorAll('td')[1];
|
||||
const colIcon = nameCol.querySelector('.icon-wrapper');
|
||||
nameValue = nameCol.innerText;
|
||||
|
||||
// Set rename input template
|
||||
const renameInput = renameTemplate.cloneNode(true);
|
||||
renameInput.querySelector('#kt_file_manager_rename_folder_icon').innerHTML = colIcon.outerHTML;
|
||||
|
||||
// Swap current column content with input template
|
||||
nameCol.innerHTML = renameInput.innerHTML;
|
||||
|
||||
// Set input value with current file/folder name
|
||||
parent.querySelector('#kt_file_manager_rename_input').value = nameValue;
|
||||
|
||||
// Rename file / folder validator
|
||||
var renameValidator = FormValidation.formValidation(
|
||||
nameCol,
|
||||
{
|
||||
fields: {
|
||||
'rename_folder_name': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Name is required'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Rename input button action
|
||||
const renameInputButton = document.querySelector('#kt_file_manager_rename_folder');
|
||||
renameInputButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Detect if valid
|
||||
if (renameValidator) {
|
||||
renameValidator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Pop up confirmation
|
||||
Swal.fire({
|
||||
text: "Are you sure you want to rename " + nameValue + "?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, rename it!",
|
||||
cancelButtonText: "No, cancel",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-danger",
|
||||
cancelButton: "btn fw-bold btn-active-light-primary"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
text: "You have renamed " + nameValue + "!.",
|
||||
icon: "success",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
}).then(function () {
|
||||
// Get new file / folder name value
|
||||
const newValue = document.querySelector('#kt_file_manager_rename_input').value;
|
||||
|
||||
// New column data template
|
||||
const newData = `<div class="d-flex align-items-center">
|
||||
${colIcon.outerHTML}
|
||||
<a href="?page=apps/file-manager/files/" class="text-gray-800 text-hover-primary">${newValue}</a>
|
||||
</div>`;
|
||||
|
||||
// Draw datatable with new content -- Add more events here for any server-side events
|
||||
datatable.cell($(nameCol)).data(newData).draw();
|
||||
});
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: nameValue + " was not renamed.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn fw-bold btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Cancel rename input
|
||||
const cancelInputButton = document.querySelector('#kt_file_manager_rename_folder_cancel');
|
||||
cancelInputButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Simulate process for demo only
|
||||
cancelInputButton.setAttribute("data-kt-indicator", "on");
|
||||
|
||||
setTimeout(function () {
|
||||
const revertTemplate = `<div class="d-flex align-items-center">
|
||||
${colIcon.outerHTML}
|
||||
<a href="?page=apps/file-manager/files/" class="text-gray-800 text-hover-primary">${nameValue}</a>
|
||||
</div>`;
|
||||
|
||||
// Remove spinner
|
||||
cancelInputButton.removeAttribute("data-kt-indicator");
|
||||
|
||||
// Draw datatable with new content -- Add more events here for any server-side events
|
||||
datatable.cell($(nameCol)).data(revertTemplate).draw();
|
||||
|
||||
// Toggle toastr
|
||||
toastr.options = {
|
||||
"closeButton": true,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toastr-top-right",
|
||||
"preventDuplicates": false,
|
||||
"showDuration": "300",
|
||||
"hideDuration": "1000",
|
||||
"timeOut": "5000",
|
||||
"extendedTimeOut": "1000",
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut"
|
||||
};
|
||||
|
||||
toastr.error('Cancelled rename function');
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
// Init dropzone
|
||||
const initDropzone = () => {
|
||||
// set the dropzone container id
|
||||
const id = "#kt_modal_upload_dropzone";
|
||||
const dropzone = document.querySelector(id);
|
||||
|
||||
// set the preview element template
|
||||
var previewNode = dropzone.querySelector(".dropzone-item");
|
||||
previewNode.id = "";
|
||||
var previewTemplate = previewNode.parentNode.innerHTML;
|
||||
previewNode.parentNode.removeChild(previewNode);
|
||||
|
||||
var myDropzone = new Dropzone(id, { // Make the whole body a dropzone
|
||||
url: "path/to/your/server", // Set the url for your upload script location
|
||||
parallelUploads: 10,
|
||||
previewTemplate: previewTemplate,
|
||||
maxFilesize: 1, // Max filesize in MB
|
||||
autoProcessQueue: false, // Stop auto upload
|
||||
autoQueue: false, // Make sure the files aren't queued until manually added
|
||||
previewsContainer: id + " .dropzone-items", // Define the container to display the previews
|
||||
clickable: id + " .dropzone-select" // Define the element that should be used as click trigger to select files.
|
||||
});
|
||||
|
||||
myDropzone.on("addedfile", function (file) {
|
||||
// Hook each start button
|
||||
file.previewElement.querySelector(id + " .dropzone-start").onclick = function () {
|
||||
// myDropzone.enqueueFile(file); -- default dropzone function
|
||||
|
||||
// Process simulation for demo only
|
||||
const progressBar = file.previewElement.querySelector('.progress-bar');
|
||||
progressBar.style.opacity = "1";
|
||||
var width = 1;
|
||||
var timer = setInterval(function () {
|
||||
if (width >= 100) {
|
||||
myDropzone.emit("success", file);
|
||||
myDropzone.emit("complete", file);
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
width++;
|
||||
progressBar.style.width = width + '%';
|
||||
}
|
||||
}, 20);
|
||||
};
|
||||
|
||||
const dropzoneItems = dropzone.querySelectorAll('.dropzone-item');
|
||||
dropzoneItems.forEach(dropzoneItem => {
|
||||
dropzoneItem.style.display = '';
|
||||
});
|
||||
dropzone.querySelector('.dropzone-upload').style.display = "inline-block";
|
||||
dropzone.querySelector('.dropzone-remove-all').style.display = "inline-block";
|
||||
});
|
||||
|
||||
// Hide the total progress bar when nothing's uploading anymore
|
||||
myDropzone.on("complete", function (file) {
|
||||
const progressBars = dropzone.querySelectorAll('.dz-complete');
|
||||
setTimeout(function () {
|
||||
progressBars.forEach(progressBar => {
|
||||
progressBar.querySelector('.progress-bar').style.opacity = "0";
|
||||
progressBar.querySelector('.progress').style.opacity = "0";
|
||||
progressBar.querySelector('.dropzone-start').style.opacity = "0";
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// Setup the buttons for all transfers
|
||||
dropzone.querySelector(".dropzone-upload").addEventListener('click', function () {
|
||||
// myDropzone.processQueue(); --- default dropzone process
|
||||
|
||||
// Process simulation for demo only
|
||||
myDropzone.files.forEach(file => {
|
||||
const progressBar = file.previewElement.querySelector('.progress-bar');
|
||||
progressBar.style.opacity = "1";
|
||||
var width = 1;
|
||||
var timer = setInterval(function () {
|
||||
if (width >= 100) {
|
||||
myDropzone.emit("success", file);
|
||||
myDropzone.emit("complete", file);
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
width++;
|
||||
progressBar.style.width = width + '%';
|
||||
}
|
||||
}, 20);
|
||||
});
|
||||
});
|
||||
|
||||
// Setup the button for remove all files
|
||||
dropzone.querySelector(".dropzone-remove-all").addEventListener('click', function () {
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to remove all files?",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, remove it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
dropzone.querySelector('.dropzone-upload').style.display = "none";
|
||||
dropzone.querySelector('.dropzone-remove-all').style.display = "none";
|
||||
myDropzone.removeAllFiles(true);
|
||||
} else if (result.dismiss === 'cancel') {
|
||||
Swal.fire({
|
||||
text: "Your files was not removed!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// On all files completed upload
|
||||
myDropzone.on("queuecomplete", function (progress) {
|
||||
const uploadIcons = dropzone.querySelectorAll('.dropzone-upload');
|
||||
uploadIcons.forEach(uploadIcon => {
|
||||
uploadIcon.style.display = "none";
|
||||
});
|
||||
});
|
||||
|
||||
// On all files removed
|
||||
myDropzone.on("removedfile", function (file) {
|
||||
if (myDropzone.files.length < 1) {
|
||||
dropzone.querySelector('.dropzone-upload').style.display = "none";
|
||||
dropzone.querySelector('.dropzone-remove-all').style.display = "none";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Init copy link
|
||||
const initCopyLink = () => {
|
||||
// Select all copy link elements
|
||||
const elements = table.querySelectorAll('[data-kt-filemanger-table="copy_link"]');
|
||||
|
||||
elements.forEach(el => {
|
||||
// Define elements
|
||||
const button = el.querySelector('button');
|
||||
const generator = el.querySelector('[data-kt-filemanger-table="copy_link_generator"]');
|
||||
const result = el.querySelector('[data-kt-filemanger-table="copy_link_result"]');
|
||||
const input = el.querySelector('input');
|
||||
|
||||
// Click action
|
||||
button.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
// Reset toggle
|
||||
generator.classList.remove('d-none');
|
||||
result.classList.add('d-none');
|
||||
|
||||
var linkTimeout;
|
||||
clearTimeout(linkTimeout);
|
||||
linkTimeout = setTimeout(() => {
|
||||
generator.classList.add('d-none');
|
||||
result.classList.remove('d-none');
|
||||
input.select();
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle move to folder
|
||||
const handleMoveToFolder = () => {
|
||||
const element = document.querySelector('#kt_modal_move_to_folder');
|
||||
const form = element.querySelector('#kt_modal_move_to_folder_form');
|
||||
const saveButton = form.querySelector('#kt_modal_move_to_folder_submit');
|
||||
const moveModal = new bootstrap.Modal(element);
|
||||
|
||||
// Init form validation rules. For more info check the FormValidation plugin's official documentation:https://formvalidation.io/
|
||||
var validator = FormValidation.formValidation(
|
||||
form,
|
||||
{
|
||||
fields: {
|
||||
'move_to_folder': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please select a folder.'
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap: new FormValidation.plugins.Bootstrap5({
|
||||
rowSelector: '.fv-row',
|
||||
eleInvalidClass: '',
|
||||
eleValidClass: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
saveButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
saveButton.setAttribute("data-kt-indicator", "on");
|
||||
|
||||
if (validator) {
|
||||
validator.validate().then(function (status) {
|
||||
console.log('validated!');
|
||||
|
||||
if (status == 'Valid') {
|
||||
// Simulate process for demo only
|
||||
setTimeout(function () {
|
||||
|
||||
Swal.fire({
|
||||
text: "Are you sure you would like to move to this folder",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Yes, move it!",
|
||||
cancelButtonText: "No, return",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
cancelButton: "btn btn-active-light"
|
||||
}
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
form.reset(); // Reset form
|
||||
moveModal.hide(); // Hide modal
|
||||
|
||||
toastr.options = {
|
||||
"closeButton": true,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toastr-top-right",
|
||||
"preventDuplicates": false,
|
||||
"showDuration": "300",
|
||||
"hideDuration": "1000",
|
||||
"timeOut": "5000",
|
||||
"extendedTimeOut": "1000",
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut"
|
||||
};
|
||||
|
||||
toastr.success('1 item has been moved.');
|
||||
|
||||
saveButton.removeAttribute("data-kt-indicator");
|
||||
} else {
|
||||
Swal.fire({
|
||||
text: "Your action has been cancelled!.",
|
||||
icon: "error",
|
||||
buttonsStyling: false,
|
||||
confirmButtonText: "Ok, got it!",
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
}
|
||||
});
|
||||
|
||||
saveButton.removeAttribute("data-kt-indicator");
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
} else {
|
||||
saveButton.removeAttribute("data-kt-indicator");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Count total number of items
|
||||
const countTotalItems = () => {
|
||||
const counter = document.getElementById('kt_file_manager_items_counter');
|
||||
|
||||
// Count total number of elements in datatable --- more info: https://datatables.net/reference/api/count()
|
||||
counter.innerText = datatable.rows().count() + ' items';
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_file_manager_list');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initTemplates();
|
||||
initDatatable();
|
||||
initToggleToolbar();
|
||||
handleSearchDatatable();
|
||||
handleDeleteRows();
|
||||
handleNewFolder();
|
||||
initDropzone();
|
||||
initCopyLink();
|
||||
handleRename();
|
||||
handleMoveToFolder();
|
||||
countTotalItems();
|
||||
KTMenu.createInstances();
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTFileManagerList.init();
|
||||
});
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppFileManagerSettings = function () {
|
||||
var form;
|
||||
|
||||
// Private functions
|
||||
var handleForm = function() {
|
||||
const saveButton = form.querySelector('#kt_file_manager_settings_submit');
|
||||
|
||||
saveButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
saveButton.setAttribute("data-kt-indicator", "on");
|
||||
|
||||
// Simulate process for demo only
|
||||
setTimeout(function(){
|
||||
toastr.options = {
|
||||
"closeButton": true,
|
||||
"debug": false,
|
||||
"newestOnTop": false,
|
||||
"progressBar": false,
|
||||
"positionClass": "toast-top-right",
|
||||
"preventDuplicates": false,
|
||||
"showDuration": "300",
|
||||
"hideDuration": "1000",
|
||||
"timeOut": "5000",
|
||||
"extendedTimeOut": "1000",
|
||||
"showEasing": "swing",
|
||||
"hideEasing": "linear",
|
||||
"showMethod": "fadeIn",
|
||||
"hideMethod": "fadeOut"
|
||||
};
|
||||
|
||||
toastr.success('File manager settings have been saved');
|
||||
|
||||
saveButton.removeAttribute("data-kt-indicator");
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function(element) {
|
||||
form = document.querySelector('#kt_file_manager_settings');
|
||||
|
||||
handleForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppFileManagerSettings.init();
|
||||
});
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppInboxCompose = function () {
|
||||
// Private functions
|
||||
// Init reply form
|
||||
const initForm = () => {
|
||||
// Set variables
|
||||
const form = document.querySelector('#kt_inbox_compose_form');
|
||||
const allTagify = form.querySelectorAll('[data-kt-inbox-form="tagify"]');
|
||||
|
||||
// Handle CC and BCC
|
||||
handleCCandBCC(form);
|
||||
|
||||
// Handle submit form
|
||||
handleSubmit(form);
|
||||
|
||||
// Init tagify
|
||||
allTagify.forEach(tagify => {
|
||||
initTagify(tagify);
|
||||
});
|
||||
|
||||
// Init quill editor
|
||||
initQuill(form);
|
||||
|
||||
// Init dropzone
|
||||
initDropzone(form);
|
||||
}
|
||||
|
||||
// Handle CC and BCC toggle
|
||||
const handleCCandBCC = (el) => {
|
||||
// Get elements
|
||||
const ccElement = el.querySelector('[data-kt-inbox-form="cc"]');
|
||||
const ccButton = el.querySelector('[data-kt-inbox-form="cc_button"]');
|
||||
const ccClose = el.querySelector('[data-kt-inbox-form="cc_close"]');
|
||||
const bccElement = el.querySelector('[data-kt-inbox-form="bcc"]');
|
||||
const bccButton = el.querySelector('[data-kt-inbox-form="bcc_button"]');
|
||||
const bccClose = el.querySelector('[data-kt-inbox-form="bcc_close"]');
|
||||
|
||||
// Handle CC button click
|
||||
ccButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
ccElement.classList.remove('d-none');
|
||||
ccElement.classList.add('d-flex');
|
||||
});
|
||||
|
||||
// Handle CC close button click
|
||||
ccClose.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
ccElement.classList.add('d-none');
|
||||
ccElement.classList.remove('d-flex');
|
||||
});
|
||||
|
||||
// Handle BCC button click
|
||||
bccButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
bccElement.classList.remove('d-none');
|
||||
bccElement.classList.add('d-flex');
|
||||
});
|
||||
|
||||
// Handle CC close button click
|
||||
bccClose.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
bccElement.classList.add('d-none');
|
||||
bccElement.classList.remove('d-flex');
|
||||
});
|
||||
}
|
||||
|
||||
// Handle submit form
|
||||
const handleSubmit = (el) => {
|
||||
const submitButton = el.querySelector('[data-kt-inbox-form="send"]');
|
||||
|
||||
// Handle button click event
|
||||
submitButton.addEventListener("click", function () {
|
||||
// Activate indicator
|
||||
submitButton.setAttribute("data-kt-indicator", "on");
|
||||
|
||||
// Disable indicator after 3 seconds
|
||||
setTimeout(function () {
|
||||
submitButton.removeAttribute("data-kt-indicator");
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
// Init tagify
|
||||
const initTagify = (el) => {
|
||||
var inputElm = el;
|
||||
|
||||
const usersList = [
|
||||
{ value: 1, name: 'Emma Smith', avatar: 'avatars/300-6.jpg', email: 'e.smith@kpmg.com.au' },
|
||||
{ value: 2, name: 'Max Smith', avatar: 'avatars/300-1.jpg', email: 'max@kt.com' },
|
||||
{ value: 3, name: 'Sean Bean', avatar: 'avatars/300-5.jpg', email: 'sean@dellito.com' },
|
||||
{ value: 4, name: 'Brian Cox', avatar: 'avatars/300-25.jpg', email: 'brian@exchange.com' },
|
||||
{ value: 5, name: 'Francis Mitcham', avatar: 'avatars/300-9.jpg', email: 'f.mitcham@kpmg.com.au' },
|
||||
{ value: 6, name: 'Dan Wilson', avatar: 'avatars/300-23.jpg', email: 'dam@consilting.com' },
|
||||
{ value: 7, name: 'Ana Crown', avatar: 'avatars/300-12.jpg', email: 'ana.cf@limtel.com' },
|
||||
{ value: 8, name: 'John Miller', avatar: 'avatars/300-13.jpg', email: 'miller@mapple.com' }
|
||||
];
|
||||
|
||||
function tagTemplate(tagData) {
|
||||
return `
|
||||
<tag title="${(tagData.title || tagData.email)}"
|
||||
contenteditable='false'
|
||||
spellcheck='false'
|
||||
tabIndex="-1"
|
||||
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ""}"
|
||||
${this.getAttributes(tagData)}>
|
||||
<x title='' class='tagify__tag__removeBtn' role='button' aria-label='remove tag'></x>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class='tagify__tag__avatar-wrap ps-0'>
|
||||
<img onerror="this.style.visibility='hidden'" class="rounded-circle w-25px me-2" src="${hostUrl}media/${tagData.avatar}">
|
||||
</div>
|
||||
<span class='tagify__tag-text'>${tagData.name}</span>
|
||||
</div>
|
||||
</tag>
|
||||
`
|
||||
}
|
||||
|
||||
function suggestionItemTemplate(tagData) {
|
||||
return `
|
||||
<div ${this.getAttributes(tagData)}
|
||||
class='tagify__dropdown__item d-flex align-items-center ${tagData.class ? tagData.class : ""}'
|
||||
tabindex="0"
|
||||
role="option">
|
||||
|
||||
${tagData.avatar ? `
|
||||
<div class='tagify__dropdown__item__avatar-wrap me-2'>
|
||||
<img onerror="this.style.visibility='hidden'" class="rounded-circle w-50px me-2" src="${hostUrl}media/${tagData.avatar}">
|
||||
</div>` : ''
|
||||
}
|
||||
|
||||
<div class="d-flex flex-column">
|
||||
<strong>${tagData.name}</strong>
|
||||
<span>${tagData.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
// initialize Tagify on the above input node reference
|
||||
var tagify = new Tagify(inputElm, {
|
||||
tagTextProp: 'name', // very important since a custom template is used with this property as text. allows typing a "value" or a "name" to match input with whitelist
|
||||
enforceWhitelist: true,
|
||||
skipInvalid: true, // do not remporarily add invalid tags
|
||||
dropdown: {
|
||||
closeOnSelect: false,
|
||||
enabled: 0,
|
||||
classname: 'users-list',
|
||||
searchKeys: ['name', 'email'] // very important to set by which keys to search for suggesttions when typing
|
||||
},
|
||||
templates: {
|
||||
tag: tagTemplate,
|
||||
dropdownItem: suggestionItemTemplate
|
||||
},
|
||||
whitelist: usersList
|
||||
})
|
||||
|
||||
tagify.on('dropdown:show dropdown:updated', onDropdownShow)
|
||||
tagify.on('dropdown:select', onSelectSuggestion)
|
||||
|
||||
var addAllSuggestionsElm;
|
||||
|
||||
function onDropdownShow(e) {
|
||||
var dropdownContentElm = e.detail.tagify.DOM.dropdown.content;
|
||||
|
||||
if (tagify.suggestedListItems.length > 1) {
|
||||
addAllSuggestionsElm = getAddAllSuggestionsElm();
|
||||
|
||||
// insert "addAllSuggestionsElm" as the first element in the suggestions list
|
||||
dropdownContentElm.insertBefore(addAllSuggestionsElm, dropdownContentElm.firstChild)
|
||||
}
|
||||
}
|
||||
|
||||
function onSelectSuggestion(e) {
|
||||
if (e.detail.elm == addAllSuggestionsElm)
|
||||
tagify.dropdown.selectAll.call(tagify);
|
||||
}
|
||||
|
||||
// create a "add all" custom suggestion element every time the dropdown changes
|
||||
function getAddAllSuggestionsElm() {
|
||||
// suggestions items should be based on "dropdownItem" template
|
||||
return tagify.parseTemplate('dropdownItem', [{
|
||||
class: "addAll",
|
||||
name: "Add all",
|
||||
email: tagify.settings.whitelist.reduce(function (remainingSuggestions, item) {
|
||||
return tagify.isTagDuplicate(item.value) ? remainingSuggestions : remainingSuggestions + 1
|
||||
}, 0) + " Members"
|
||||
}]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Init quill editor
|
||||
const initQuill = (el) => {
|
||||
var quill = new Quill('#kt_inbox_form_editor', {
|
||||
modules: {
|
||||
toolbar: [
|
||||
[{
|
||||
header: [1, 2, false]
|
||||
}],
|
||||
['bold', 'italic', 'underline'],
|
||||
['image', 'code-block']
|
||||
]
|
||||
},
|
||||
placeholder: 'Type your text here...',
|
||||
theme: 'snow' // or 'bubble'
|
||||
});
|
||||
|
||||
// Customize editor
|
||||
const toolbar = el.querySelector('.ql-toolbar');
|
||||
|
||||
if (toolbar) {
|
||||
const classes = ['px-5', 'border-top-0', 'border-start-0', 'border-end-0'];
|
||||
toolbar.classList.add(...classes);
|
||||
}
|
||||
}
|
||||
|
||||
// Init dropzone
|
||||
const initDropzone = (el) => {
|
||||
// set the dropzone container id
|
||||
const id = '[data-kt-inbox-form="dropzone"]';
|
||||
const dropzone = el.querySelector(id);
|
||||
const uploadButton = el.querySelector('[data-kt-inbox-form="dropzone_upload"]');
|
||||
|
||||
// set the preview element template
|
||||
var previewNode = dropzone.querySelector(".dropzone-item");
|
||||
previewNode.id = "";
|
||||
var previewTemplate = previewNode.parentNode.innerHTML;
|
||||
previewNode.parentNode.removeChild(previewNode);
|
||||
|
||||
var myDropzone = new Dropzone(id, { // Make the whole body a dropzone
|
||||
url: "https://preview.keenthemes.com/api/dropzone/void.php", // Set the url for your upload script location
|
||||
parallelUploads: 20,
|
||||
maxFilesize: 1, // Max filesize in MB
|
||||
previewTemplate: previewTemplate,
|
||||
previewsContainer: id + " .dropzone-items", // Define the container to display the previews
|
||||
clickable: uploadButton // Define the element that should be used as click trigger to select files.
|
||||
});
|
||||
|
||||
|
||||
myDropzone.on("addedfile", function (file) {
|
||||
// Hookup the start button
|
||||
const dropzoneItems = dropzone.querySelectorAll('.dropzone-item');
|
||||
dropzoneItems.forEach(dropzoneItem => {
|
||||
dropzoneItem.style.display = '';
|
||||
});
|
||||
});
|
||||
|
||||
// Update the total progress bar
|
||||
myDropzone.on("totaluploadprogress", function (progress) {
|
||||
const progressBars = dropzone.querySelectorAll('.progress-bar');
|
||||
progressBars.forEach(progressBar => {
|
||||
progressBar.style.width = progress + "%";
|
||||
});
|
||||
});
|
||||
|
||||
myDropzone.on("sending", function (file) {
|
||||
// Show the total progress bar when upload starts
|
||||
const progressBars = dropzone.querySelectorAll('.progress-bar');
|
||||
progressBars.forEach(progressBar => {
|
||||
progressBar.style.opacity = "1";
|
||||
});
|
||||
});
|
||||
|
||||
// Hide the total progress bar when nothing"s uploading anymore
|
||||
myDropzone.on("complete", function (progress) {
|
||||
const progressBars = dropzone.querySelectorAll('.dz-complete');
|
||||
|
||||
setTimeout(function () {
|
||||
progressBars.forEach(progressBar => {
|
||||
progressBar.querySelector('.progress-bar').style.opacity = "0";
|
||||
progressBar.querySelector('.progress').style.opacity = "0";
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
initForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppInboxCompose.init();
|
||||
});
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppInboxListing = function () {
|
||||
var table;
|
||||
var datatable;
|
||||
|
||||
// Private functions
|
||||
var initDatatable = function () {
|
||||
// Init datatable --- more info on datatables: https://datatables.net/manual/
|
||||
datatable = $(table).DataTable({
|
||||
"info": false,
|
||||
'order': [],
|
||||
// 'paging': false,
|
||||
// 'pageLength': false,
|
||||
});
|
||||
|
||||
datatable.on('draw', function () {
|
||||
handleDatatableFooter();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle datatable footer spacings
|
||||
var handleDatatableFooter = () => {
|
||||
const footerElement = document.querySelector('#kt_inbox_listing_wrapper > .row');
|
||||
const spacingClasses = ['px-9', 'pt-3', 'pb-5'];
|
||||
footerElement.classList.add(...spacingClasses);
|
||||
}
|
||||
|
||||
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
|
||||
var handleSearchDatatable = () => {
|
||||
const filterSearch = document.querySelector('[data-kt-inbox-listing-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function (e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
table = document.querySelector('#kt_inbox_listing');
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
initDatatable();
|
||||
handleSearchDatatable();
|
||||
handleDatatableFooter();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppInboxListing.init();
|
||||
});
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppInboxReply = function () {
|
||||
|
||||
// Private functions
|
||||
const handlePreviewText = () => {
|
||||
// Get all messages
|
||||
const accordions = document.querySelectorAll('[data-kt-inbox-message="message_wrapper"]');
|
||||
accordions.forEach(accordion => {
|
||||
// Set variables
|
||||
const header = accordion.querySelector('[data-kt-inbox-message="header"]');
|
||||
const previewText = accordion.querySelector('[data-kt-inbox-message="preview"]');
|
||||
const details = accordion.querySelector('[data-kt-inbox-message="details"]');
|
||||
const message = accordion.querySelector('[data-kt-inbox-message="message"]');
|
||||
|
||||
// Init bootstrap collapse -- more info: https://getbootstrap.com/docs/5.1/components/collapse/#via-javascript
|
||||
const collapse = new bootstrap.Collapse(message, { toggle: false });
|
||||
|
||||
// Handle header click action
|
||||
header.addEventListener('click', e => {
|
||||
// Return if KTMenu or buttons are clicked
|
||||
if (e.target.closest('[data-kt-menu-trigger="click"]') || e.target.closest('.btn')) {
|
||||
return;
|
||||
} else {
|
||||
previewText.classList.toggle('d-none');
|
||||
details.classList.toggle('d-none');
|
||||
collapse.toggle();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Init reply form
|
||||
const initForm = () => {
|
||||
// Set variables
|
||||
const form = document.querySelector('#kt_inbox_reply_form');
|
||||
const allTagify = form.querySelectorAll('[data-kt-inbox-form="tagify"]');
|
||||
|
||||
// Handle CC and BCC
|
||||
handleCCandBCC(form);
|
||||
|
||||
// Handle submit form
|
||||
handleSubmit(form);
|
||||
|
||||
// Init tagify
|
||||
allTagify.forEach(tagify => {
|
||||
initTagify(tagify);
|
||||
});
|
||||
|
||||
// Init quill editor
|
||||
initQuill(form);
|
||||
|
||||
// Init dropzone
|
||||
initDropzone(form);
|
||||
}
|
||||
|
||||
// Handle CC and BCC toggle
|
||||
const handleCCandBCC = (el) => {
|
||||
// Get elements
|
||||
const ccElement = el.querySelector('[data-kt-inbox-form="cc"]');
|
||||
const ccButton = el.querySelector('[data-kt-inbox-form="cc_button"]');
|
||||
const ccClose = el.querySelector('[data-kt-inbox-form="cc_close"]');
|
||||
const bccElement = el.querySelector('[data-kt-inbox-form="bcc"]');
|
||||
const bccButton = el.querySelector('[data-kt-inbox-form="bcc_button"]');
|
||||
const bccClose = el.querySelector('[data-kt-inbox-form="bcc_close"]');
|
||||
|
||||
// Handle CC button click
|
||||
ccButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
ccElement.classList.remove('d-none');
|
||||
ccElement.classList.add('d-flex');
|
||||
});
|
||||
|
||||
// Handle CC close button click
|
||||
ccClose.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
ccElement.classList.add('d-none');
|
||||
ccElement.classList.remove('d-flex');
|
||||
});
|
||||
|
||||
// Handle BCC button click
|
||||
bccButton.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
bccElement.classList.remove('d-none');
|
||||
bccElement.classList.add('d-flex');
|
||||
});
|
||||
|
||||
// Handle CC close button click
|
||||
bccClose.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
|
||||
bccElement.classList.add('d-none');
|
||||
bccElement.classList.remove('d-flex');
|
||||
});
|
||||
}
|
||||
|
||||
// Handle submit form
|
||||
const handleSubmit = (el) => {
|
||||
const submitButton = el.querySelector('[data-kt-inbox-form="send"]');
|
||||
|
||||
// Handle button click event
|
||||
submitButton.addEventListener("click", function () {
|
||||
// Activate indicator
|
||||
submitButton.setAttribute("data-kt-indicator", "on");
|
||||
|
||||
// Disable indicator after 3 seconds
|
||||
setTimeout(function () {
|
||||
submitButton.removeAttribute("data-kt-indicator");
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
// Init tagify
|
||||
const initTagify = (el) => {
|
||||
var inputElm = el;
|
||||
|
||||
const usersList = [
|
||||
{ value: 1, name: 'Emma Smith', avatar: 'avatars/300-6.jpg', email: 'e.smith@kpmg.com.au' },
|
||||
{ value: 2, name: 'Max Smith', avatar: 'avatars/300-1.jpg', email: 'max@kt.com' },
|
||||
{ value: 3, name: 'Sean Bean', avatar: 'avatars/300-5.jpg', email: 'sean@dellito.com' },
|
||||
{ value: 4, name: 'Brian Cox', avatar: 'avatars/300-25.jpg', email: 'brian@exchange.com' },
|
||||
{ value: 5, name: 'Francis Mitcham', avatar: 'avatars/300-9.jpg', email: 'f.mitcham@kpmg.com.au' },
|
||||
{ value: 6, name: 'Dan Wilson', avatar: 'avatars/300-23.jpg', email: 'dam@consilting.com' },
|
||||
{ value: 7, name: 'Ana Crown', avatar: 'avatars/300-12.jpg', email: 'ana.cf@limtel.com' },
|
||||
{ value: 8, name: 'John Miller', avatar: 'avatars/300-13.jpg', email: 'miller@mapple.com' }
|
||||
];
|
||||
|
||||
function tagTemplate(tagData) {
|
||||
return `
|
||||
<tag title="${(tagData.title || tagData.email)}"
|
||||
contenteditable='false'
|
||||
spellcheck='false'
|
||||
tabIndex="-1"
|
||||
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ""}"
|
||||
${this.getAttributes(tagData)}>
|
||||
<x title='' class='tagify__tag__removeBtn' role='button' aria-label='remove tag'></x>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class='tagify__tag__avatar-wrap ps-0'>
|
||||
<img onerror="this.style.visibility='hidden'" class="rounded-circle w-25px me-2" src="${hostUrl}media/${tagData.avatar}">
|
||||
</div>
|
||||
<span class='tagify__tag-text'>${tagData.name}</span>
|
||||
</div>
|
||||
</tag>
|
||||
`
|
||||
}
|
||||
|
||||
function suggestionItemTemplate(tagData) {
|
||||
return `
|
||||
<div ${this.getAttributes(tagData)}
|
||||
class='tagify__dropdown__item d-flex align-items-center ${tagData.class ? tagData.class : ""}'
|
||||
tabindex="0"
|
||||
role="option">
|
||||
|
||||
${tagData.avatar ? `
|
||||
<div class='tagify__dropdown__item__avatar-wrap me-2'>
|
||||
<img onerror="this.style.visibility='hidden'" class="rounded-circle w-50px me-2" src="${hostUrl}media/${tagData.avatar}">
|
||||
</div>` : ''
|
||||
}
|
||||
|
||||
<div class="d-flex flex-column">
|
||||
<strong>${tagData.name}</strong>
|
||||
<span>${tagData.email}</span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
// initialize Tagify on the above input node reference
|
||||
var tagify = new Tagify(inputElm, {
|
||||
tagTextProp: 'name', // very important since a custom template is used with this property as text. allows typing a "value" or a "name" to match input with whitelist
|
||||
enforceWhitelist: true,
|
||||
skipInvalid: true, // do not remporarily add invalid tags
|
||||
dropdown: {
|
||||
closeOnSelect: false,
|
||||
enabled: 0,
|
||||
classname: 'users-list',
|
||||
searchKeys: ['name', 'email'] // very important to set by which keys to search for suggesttions when typing
|
||||
},
|
||||
templates: {
|
||||
tag: tagTemplate,
|
||||
dropdownItem: suggestionItemTemplate
|
||||
},
|
||||
whitelist: usersList
|
||||
})
|
||||
|
||||
tagify.on('dropdown:show dropdown:updated', onDropdownShow)
|
||||
tagify.on('dropdown:select', onSelectSuggestion)
|
||||
|
||||
var addAllSuggestionsElm;
|
||||
|
||||
function onDropdownShow(e) {
|
||||
var dropdownContentElm = e.detail.tagify.DOM.dropdown.content;
|
||||
|
||||
if (tagify.suggestedListItems.length > 1) {
|
||||
addAllSuggestionsElm = getAddAllSuggestionsElm();
|
||||
|
||||
// insert "addAllSuggestionsElm" as the first element in the suggestions list
|
||||
dropdownContentElm.insertBefore(addAllSuggestionsElm, dropdownContentElm.firstChild)
|
||||
}
|
||||
}
|
||||
|
||||
function onSelectSuggestion(e) {
|
||||
if (e.detail.elm == addAllSuggestionsElm)
|
||||
tagify.dropdown.selectAll.call(tagify);
|
||||
}
|
||||
|
||||
// create a "add all" custom suggestion element every time the dropdown changes
|
||||
function getAddAllSuggestionsElm() {
|
||||
// suggestions items should be based on "dropdownItem" template
|
||||
return tagify.parseTemplate('dropdownItem', [{
|
||||
class: "addAll",
|
||||
name: "Add all",
|
||||
email: tagify.settings.whitelist.reduce(function (remainingSuggestions, item) {
|
||||
return tagify.isTagDuplicate(item.value) ? remainingSuggestions : remainingSuggestions + 1
|
||||
}, 0) + " Members"
|
||||
}]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Init quill editor
|
||||
const initQuill = (el) => {
|
||||
var quill = new Quill('#kt_inbox_form_editor', {
|
||||
modules: {
|
||||
toolbar: [
|
||||
[{
|
||||
header: [1, 2, false]
|
||||
}],
|
||||
['bold', 'italic', 'underline'],
|
||||
['image', 'code-block']
|
||||
]
|
||||
},
|
||||
placeholder: 'Type your text here...',
|
||||
theme: 'snow' // or 'bubble'
|
||||
});
|
||||
|
||||
// Customize editor
|
||||
const toolbar = el.querySelector('.ql-toolbar');
|
||||
|
||||
if (toolbar) {
|
||||
const classes = ['px-5', 'border-top-0', 'border-start-0', 'border-end-0'];
|
||||
toolbar.classList.add(...classes);
|
||||
}
|
||||
}
|
||||
|
||||
// Init dropzone
|
||||
const initDropzone = (el) => {
|
||||
// set the dropzone container id
|
||||
const id = '[data-kt-inbox-form="dropzone"]';
|
||||
const dropzone = el.querySelector(id);
|
||||
const uploadButton = el.querySelector('[data-kt-inbox-form="dropzone_upload"]');
|
||||
|
||||
// set the preview element template
|
||||
var previewNode = dropzone.querySelector(".dropzone-item");
|
||||
previewNode.id = "";
|
||||
var previewTemplate = previewNode.parentNode.innerHTML;
|
||||
previewNode.parentNode.removeChild(previewNode);
|
||||
|
||||
var myDropzone = new Dropzone(id, { // Make the whole body a dropzone
|
||||
url: "https://preview.keenthemes.com/api/dropzone/void.php", // Set the url for your upload script location
|
||||
parallelUploads: 20,
|
||||
maxFilesize: 1, // Max filesize in MB
|
||||
previewTemplate: previewTemplate,
|
||||
previewsContainer: id + " .dropzone-items", // Define the container to display the previews
|
||||
clickable: uploadButton // Define the element that should be used as click trigger to select files.
|
||||
});
|
||||
|
||||
|
||||
myDropzone.on("addedfile", function (file) {
|
||||
// Hookup the start button
|
||||
const dropzoneItems = dropzone.querySelectorAll('.dropzone-item');
|
||||
dropzoneItems.forEach(dropzoneItem => {
|
||||
dropzoneItem.style.display = '';
|
||||
});
|
||||
});
|
||||
|
||||
// Update the total progress bar
|
||||
myDropzone.on("totaluploadprogress", function (progress) {
|
||||
const progressBars = dropzone.querySelectorAll('.progress-bar');
|
||||
progressBars.forEach(progressBar => {
|
||||
progressBar.style.width = progress + "%";
|
||||
});
|
||||
});
|
||||
|
||||
myDropzone.on("sending", function (file) {
|
||||
// Show the total progress bar when upload starts
|
||||
const progressBars = dropzone.querySelectorAll('.progress-bar');
|
||||
progressBars.forEach(progressBar => {
|
||||
progressBar.style.opacity = "1";
|
||||
});
|
||||
});
|
||||
|
||||
// Hide the total progress bar when nothing"s uploading anymore
|
||||
myDropzone.on("complete", function (progress) {
|
||||
const progressBars = dropzone.querySelectorAll('.dz-complete');
|
||||
|
||||
setTimeout(function () {
|
||||
progressBars.forEach(progressBar => {
|
||||
progressBar.querySelector('.progress-bar').style.opacity = "0";
|
||||
progressBar.querySelector('.progress').style.opacity = "0";
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function () {
|
||||
handlePreviewText();
|
||||
initForm();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppInboxReply.init();
|
||||
});
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
"use strict";
|
||||
|
||||
// Class definition
|
||||
var KTAppInvoicesCreate = function () {
|
||||
var form;
|
||||
|
||||
// Private functions
|
||||
var updateTotal = function() {
|
||||
var items = [].slice.call(form.querySelectorAll('[data-kt-element="items"] [data-kt-element="item"]'));
|
||||
var grandTotal = 0;
|
||||
|
||||
var format = wNumb({
|
||||
//prefix: '$ ',
|
||||
decimals: 2,
|
||||
thousand: ','
|
||||
});
|
||||
|
||||
items.map(function (item) {
|
||||
var quantity = item.querySelector('[data-kt-element="quantity"]');
|
||||
var price = item.querySelector('[data-kt-element="price"]');
|
||||
|
||||
var priceValue = format.from(price.value);
|
||||
priceValue = (!priceValue || priceValue < 0) ? 0 : priceValue;
|
||||
|
||||
var quantityValue = parseInt(quantity.value);
|
||||
quantityValue = (!quantityValue || quantityValue < 0) ? 1 : quantityValue;
|
||||
|
||||
price.value = format.to(priceValue);
|
||||
quantity.value = quantityValue;
|
||||
|
||||
item.querySelector('[data-kt-element="total"]').innerText = format.to(priceValue * quantityValue);
|
||||
|
||||
grandTotal += priceValue * quantityValue;
|
||||
});
|
||||
|
||||
form.querySelector('[data-kt-element="sub-total"]').innerText = format.to(grandTotal);
|
||||
form.querySelector('[data-kt-element="grand-total"]').innerText = format.to(grandTotal);
|
||||
}
|
||||
|
||||
var handleEmptyState = function() {
|
||||
if (form.querySelectorAll('[data-kt-element="items"] [data-kt-element="item"]').length === 0) {
|
||||
var item = form.querySelector('[data-kt-element="empty-template"] tr').cloneNode(true);
|
||||
form.querySelector('[data-kt-element="items"] tbody').appendChild(item);
|
||||
} else {
|
||||
KTUtil.remove(form.querySelector('[data-kt-element="items"] [data-kt-element="empty"]'));
|
||||
}
|
||||
}
|
||||
|
||||
var handeForm = function (element) {
|
||||
// Add item
|
||||
form.querySelector('[data-kt-element="items"] [data-kt-element="add-item"]').addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var item = form.querySelector('[data-kt-element="item-template"] tr').cloneNode(true);
|
||||
|
||||
form.querySelector('[data-kt-element="items"] tbody').appendChild(item);
|
||||
|
||||
handleEmptyState();
|
||||
updateTotal();
|
||||
});
|
||||
|
||||
// Remove item
|
||||
KTUtil.on(form, '[data-kt-element="items"] [data-kt-element="remove-item"]', 'click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
KTUtil.remove(this.closest('[data-kt-element="item"]'));
|
||||
|
||||
handleEmptyState();
|
||||
updateTotal();
|
||||
});
|
||||
|
||||
// Handle price and quantity changes
|
||||
KTUtil.on(form, '[data-kt-element="items"] [data-kt-element="quantity"], [data-kt-element="items"] [data-kt-element="price"]', 'change', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
updateTotal();
|
||||
});
|
||||
}
|
||||
|
||||
var initForm = function(element) {
|
||||
// Due date. For more info, please visit the official plugin site: https://flatpickr.js.org/
|
||||
var invoiceDate = $(form.querySelector('[name="invoice_date"]'));
|
||||
invoiceDate.flatpickr({
|
||||
enableTime: false,
|
||||
dateFormat: "d, M Y",
|
||||
});
|
||||
|
||||
// Due date. For more info, please visit the official plugin site: https://flatpickr.js.org/
|
||||
var dueDate = $(form.querySelector('[name="invoice_due_date"]'));
|
||||
dueDate.flatpickr({
|
||||
enableTime: false,
|
||||
dateFormat: "d, M Y",
|
||||
});
|
||||
}
|
||||
|
||||
// Public methods
|
||||
return {
|
||||
init: function(element) {
|
||||
form = document.querySelector('#kt_invoice_form');
|
||||
|
||||
handeForm();
|
||||
initForm();
|
||||
updateTotal();
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
// On document ready
|
||||
KTUtil.onDOMContentLoaded(function () {
|
||||
KTAppInvoicesCreate.init();
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user