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'? `${title}` : title if(type==='Error') vtitle = `${title}` 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'? `${title}` : title if(type==='Error') vtitle = `${title}` 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: '

Chức năng này đang được xây dựng, vui lòng trở lại sau

', 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.lengthv.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=colors.length? ('#' + Math.floor(Math.random()*16777215).toString(16)) : colors[i] } } })