sapalymahabat/modules/backend/formwidgets/sensitive/assets/js/sensitive.js

193 lines
5.2 KiB
JavaScript

/*
* Sensitive field widget plugin.
*
* Data attributes:
* - data-control="sensitive" - enables the plugin on an element
*
* JavaScript API:
* $('div#someElement').sensitive({...})
*/
+function ($) { "use strict";
var Base = $.oc.foundation.base,
BaseProto = Base.prototype
var Sensitive = function(element, options) {
this.$el = $(element)
this.options = options
this.clean = Boolean(this.$el.data('clean'))
this.hidden = true
this.$input = this.$el.find('[data-input]').first()
this.$toggle = this.$el.find('[data-toggle]').first()
this.$icon = this.$el.find('[data-icon]').first()
this.$loader = this.$el.find('[data-loader]').first()
this.$copy = this.$el.find('[data-copy]').first()
$.oc.foundation.controlUtils.markDisposable(element)
Base.call(this)
this.init()
}
Sensitive.DEFAULTS = {
readOnly: false,
disabled: false,
eventHandler: null,
hideOnTabChange: false,
}
Sensitive.prototype = Object.create(BaseProto)
Sensitive.prototype.constructor = Sensitive
Sensitive.prototype.init = function() {
this.$input.on('keydown', this.proxy(this.onInput))
this.$toggle.on('click', this.proxy(this.onToggle))
if (this.options.hideOnTabChange) {
// Watch for tab change or minimise
document.addEventListener('visibilitychange', this.proxy(this.onTabChange))
}
if (this.$copy.length) {
this.$copy.on('click', this.proxy(this.onCopy))
}
}
Sensitive.prototype.dispose = function () {
this.$input.off('keydown', this.proxy(this.onInput))
this.$toggle.off('click', this.proxy(this.onToggle))
if (this.options.hideOnTabChange) {
document.removeEventListener('visibilitychange', this.proxy(this.onTabChange))
}
if (this.$copy.length) {
this.$copy.off('click', this.proxy(this.onCopy))
}
this.$input = this.$toggle = this.$icon = this.$loader = null
this.$el = null
BaseProto.dispose.call(this)
}
Sensitive.prototype.onInput = function() {
if (this.clean) {
this.clean = false
this.$input.val('')
}
return true
}
Sensitive.prototype.onToggle = function() {
if (this.$input.val() !== '' && this.clean) {
this.reveal()
} else {
this.toggleVisibility()
}
return true
}
Sensitive.prototype.onTabChange = function() {
if (document.hidden && !this.hidden) {
this.toggleVisibility()
}
}
Sensitive.prototype.onCopy = function() {
var that = this,
deferred = $.Deferred(),
isHidden = this.hidden
deferred.then(function () {
if (that.hidden) {
that.toggleVisibility()
}
that.$input.focus()
that.$input.select()
try {
document.execCommand('copy')
} catch (err) {
}
that.$input.blur()
if (isHidden) {
that.toggleVisibility()
}
})
if (this.$input.val() !== '' && this.clean) {
this.reveal(deferred)
} else {
deferred.resolve()
}
}
Sensitive.prototype.toggleVisibility = function() {
if (this.hidden) {
this.$input.attr('type', 'text')
} else {
this.$input.attr('type', 'password')
}
this.$icon.toggleClass('icon-eye icon-eye-slash')
this.hidden = !this.hidden
}
Sensitive.prototype.reveal = function(deferred) {
var that = this
this.$icon.css({
visibility: 'hidden'
})
this.$loader.removeClass('hide')
this.$input.request(this.options.eventHandler, {
success: function (data) {
that.$input.val(data.value)
that.clean = false
that.$icon.css({
visibility: 'visible'
})
that.$loader.addClass('hide')
that.toggleVisibility()
if (deferred) {
deferred.resolve()
}
}
})
}
var old = $.fn.sensitive
$.fn.sensitive = function (option) {
var args = Array.prototype.slice.call(arguments, 1), result
this.each(function () {
var $this = $(this)
var data = $this.data('oc.sensitive')
var options = $.extend({}, Sensitive.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('oc.sensitive', (data = new Sensitive(this, options)))
if (typeof option == 'string') result = data[option].apply(data, args)
if (typeof result != 'undefined') return false
})
return result ? result : this
}
$.fn.sensitive.noConflict = function () {
$.fn.sensitive = old
return this
}
$(document).render(function () {
$('[data-control="sensitive"]').sensitive()
});
}(window.jQuery);