Files
login/plugins/common.js
Xuan Loi 56f3509d4d changes
2025-12-05 17:53:49 +07:00

236 lines
10 KiB
JavaScript
Executable File

import Vue from 'vue'
Vue.use( {
install(Vue){
Vue.prototype.$dialog = function(content, title, type, duration, width, height, vbind) {
if(typeof content == 'string') {
let vtitle = type==='Success'? `<span class="has-text-primary">${title}</span>` : title
if(type==='Error') vtitle = `<span class="has-text-danger">${title}</span>`
let data = {id: this.$id(), component: `dialog/${type || 'Info'}`,
vbind: {content: content, duration: duration, vbind: vbind}, title: vtitle, width: width || '500px', height: height || '100px'}
this.$store.commit('updateStore', {name: 'showmodal', data: data})
} else this.$store.commit('updateStore', {name: 'showmodal', data: content})
}
Vue.prototype.$snackbar = function(content, title, type, width, height) {
if(typeof content == 'string') {
let vtitle = type==='Success'? `<span class="has-text-primary">${title}</span>` : title
if(type==='Error') vtitle = `<span class="has-text-danger">${title}</span>`
let data = {id: this.$id(), component: `snackbar/${type || 'Info'}`,
vbind: {content: content}, title: vtitle, width: width || '400px', height: height || '100px'}
this.$store.commit('updateStore', {name: 'snackbar', data: data})
} else this.$store.commit('updateStore', {name: 'snackbar', data: content})
}
Vue.prototype.$pending = function() {
this.$dialog({width: '500px', icon: ' mdi mdi-wrench-clock',
content: '<p class="fs-16">Chức năng này đang được xây dựng, vui lòng trở lại sau</p>', type: 'is-dark', progress:true, duration: 5})
}
Vue.prototype.$getLink = function(val) {
if(val === undefined || val === null || val === '' || val==="") return ''
let json = val.indexOf('{')>=0? JSON.parse(val) : {path: val}
return json
}
Vue.prototype.$timeFormat = function(startDate, endDate) {
let milliseconds = startDate - endDate
let secs = Math.floor(Math.abs(milliseconds) / 1000);
let mins = Math.floor(secs / 60);
let hours = Math.floor(mins / 60);
let days = Math.floor(hours / 24);
const millisecs = Math.floor(Math.abs(milliseconds)) % 1000;
function pad2(n) { return (n < 10 ? '0' : '') + n }
let display = undefined
if(days>=1) {
display = pad2(startDate.getHours()) + ':' + pad2(startDate.getMinutes()) + ' ' + pad2(startDate.getDate()) + '/' + pad2(startDate.getMonth())
}
else if(hours>0) display = hours + 'h trước'
else if(mins>0) display = mins + "' trước"
else if(secs>0 || millisecs>0) display = 'Vừa xong'
return {
days: days,
hours: hours % 24,
minutes: mins % 60,
seconds: secs % 60,
milliSeconds: millisecs,
display: display
}
}
Vue.prototype.$errPhone = function(phone) {
var text = undefined
if (this.$empty(phone)) {
text = 'Số điện thoại di động không được bỏ trống.'
} else if (isNaN(phone)) {
text = 'Số điện thoại di động không hợp lệ.'
} else if(phone.length<9 || phone.length>11) {
text = 'Số điện thoại di động phải có từ 9-11 số.'
}
return text
},
Vue.prototype.$errEmail = function(email) {
const re = /^(([^<>()\[\]\\.,;:\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,}))$/
var text = undefined
if (this.$empty(email)) {
text = 'Email không được bỏ trống.'
} else if (!(re.test(String(email).toLowerCase()))) {
text = 'Email không hợp lệ.'
}
return text
}
Vue.prototype.$errPhoneEmail = function(contact) {
const re = /^(([^<>()\[\]\\.,;:\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,}))$/
var text = undefined
if (this.$empty(contact)) {
text = 'Số điện thoại di động hoặc Email không được bỏ trống.'
} else if (!(re.test(String(contact).toLowerCase()) || !isNaN(contact))) {
text = 'Số điện thoại di động hoặc Email không hợp lệ.'
} else if(!isNaN(contact) && (contact.length<9 || contact.length>11)) {
text = 'Số điện thoại di động không hợp lệ.'
}
return text
}
Vue.prototype.$dummy = function(data, count) {
let list = this.$copy(data)
for (let index = 0; index < count; index++) {
if(data.length<index+1) list.push({dummy: true})
}
return list
}
Vue.prototype.$upload = function(file, type, user) {
var fileFormat = [{type: 'image', format: ['.png', '.jpg', 'jpeg', '.bmp', '.gif', '.svg']},
{type: 'video', format: ['.wmv', '.avi', '.mp4', '.flv', '.mov', '.mpg', '.amv', '.rm']}
]
var valid = undefined
if(type==='image' || type==='video') {
valid = false
let found = fileFormat.find(v=>v.type===type)
found.format.map(x=>{
if(file.name.toLowerCase().indexOf(x)>=0) valid = true
})
}
if(valid===false) return {error: true, text: 'Định dạng file không hợp lệ'}
if((type==='image' || type==='file') && file.size > 500*1024*1024) {
return {error: true, text: 'Kích thước ' + (type==='image'? 'hình ảnh' : 'tài liệu') + ' phải dưới 500MB'}
} else if(type==='video' && file.size > 1073741274) {
return {error: true, text: 'Kích thước video phải dưới 1GB'}
}
let data = new FormData()
let fileName = this.$dayjs(new Date()).format("YYYYMMDDhhmmss") + '-' + file.name
data.append('name', fileName)
data.append('file', file)
data.append('type', type)
data.append('size', file.size)
data.append('user', user)
return {form: data, name: fileName, type: type, size: file.size, file: file}
}
Vue.prototype.$change = function(obj1, obj2, list) {
var change = false
if(list) {
list.map(v=>{if(obj1[v]!==obj2[v]) change = true})
} else {
for (var k in obj1 ) {
if(obj1[k]!==obj2[k]) change = true
}
}
return change
}
Vue.prototype.$resetNull = function(obj) {
for (const [key, value] of Object.entries(obj)) {
if(typeof value==='string') {
let val = value.trim()
if(val==='' || val==="") val = null
obj[key] = val
}
}
return obj
}
Vue.prototype.$responsiveMenu = function() {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Check if there are any navbar burgers
if ($navbarBurgers.length > 0) {
// Add a click event on each of them
$navbarBurgers.forEach( el => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
})
}
}
Vue.prototype.$copyToClipboard = function(text) {
if (window.clipboardData && window.clipboardData.setData) {
// IE specific code path to prevent textarea being shown while dialog is visible.
return clipboardData.setData("Text", text);
} else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
var textarea = document.createElement("textarea");
textarea.textContent = text;
textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in MS Edge.
document.body.appendChild(textarea);
textarea.select();
try {
return document.execCommand("copy"); // Security exception may be thrown by some browsers.
} catch (ex) {
console.warn("Copy to clipboard failed.", ex);
return false;
} finally {
document.body.removeChild(textarea);
}
}
}
Vue.prototype.$nonAccent = function(str) {
if(this.$empty(str)) return null
str = str.replaceAll('/', '-').replaceAll('%', '-').replaceAll('?', '-')
str = str.toLowerCase();
str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, "a");
str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, "e");
str = str.replace(/ì|í|ị|ỉ|ĩ/g, "i");
str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, "o");
str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, "u");
str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, "y");
str = str.replace(/đ/g, "d");
// Some system encode vietnamese combining accent as individual utf-8 characters
str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, ""); // Huyền sắc hỏi ngã nặng
str = str.replace(/\u02C6|\u0306|\u031B/g, ""); // Â, Ê, Ă, Ơ, Ư
str = str.split(' ').filter(s => s).join('-')
return str
}
Vue.prototype.$linkID = function(link) {
link = link? link : this.$route.params.slug
if(this.$empty(link)) return
let idx = link.lastIndexOf('-')
let id = (idx>-1 && idx<link.length-1)? link.substring(idx+1, link.length) : undefined
return id
},
Vue.prototype.$height = function(id) {
let doc = document.getElementById(id)
return doc? doc.clientHeight : undefined
}
Vue.prototype.$color = function(i) {
var colors = ['#4285F4','#0F9D58', '#f8961e', '#008000', '#e01e37','#090c02', '#390099','#335c67','#C46210','#FFBF00','#288D85','#89B700','#EFDECD','#E52B50','#9F2B68','#F19CBB','#AB274F','#D3212D','#3B7A57','#FFBF00','#FF7E00','#9966CC','#3DDC84','#CD9575','#665D1E','#915C83','#841B2D','#FAEBD7']
return i>=colors.length? ('#' + Math.floor(Math.random()*16777215).toString(16)) : colors[i]
}
}
})