/** * DHTMLGoodies.com, Alf Magne Kalleland, September 7th, 2015 */ if (!DG)var DG = {}; DG.switches = {}; DG.OnOffSwitchProperties = ["textOn", "textOff", "width", "height", "trackColorOn", "trackColorOff", "textColorOn", "textColorOff", "listener", "trackBorderColor", "textSizeRatio", "isReadOnly"]; DG.OnOffSwitch = function (config) { if (config.el != undefined) { this.inputEl = $(config.el); this.name = this.inputEl.attr("name"); DG.switches[this.name] = this; DG.switches["#" + this.inputEl.attr("id")] = this; var t = this.inputEl.attr("type"); this.isCheckbox = t && t.toLowerCase() == "checkbox"; if(this.isCheckbox){ this.checked = this.inputEl.is(":checked"); }else{ this.checked = this.inputEl.val() == 1; } }else if (config.inputEl != undefined) { this.inputEl = config.inputEl; this.name = this.inputEl.attr("name"); DG.switches[this.name] = this; DG.switches["#" + this.inputEl.attr("id")] = this; var t = this.inputEl.attr("type"); this.isCheckbox = t && t.toLowerCase() == "checkbox"; if(this.isCheckbox){ this.checked = this.inputEl.is(":checked"); }else{ this.checked = this.inputEl.val() == 1; } } var properties = DG.OnOffSwitchProperties; for (var i = 0; i < properties.length; i++) { if (config[properties[i]] != undefined) { this[properties[i]] = config[properties[i]]; } } this.render(); }; $.extend(DG.OnOffSwitch.prototype, { inputEl: undefined, listener: undefined, trackBorderColor: undefined, checked: false, width: 0, height: 30, trackBorderWidth: 1, textSizeRatio: 0.40, trackColorOn: undefined, trackColorOff: '#EEE', textColorOn: undefined, textColorOff: undefined, el: undefined, track: undefined, thumb: undefined, thumbColor: undefined, onTextEl: undefined, offTextEl: undefined, onOffTrackContainer: undefined, textOn: "", textOff: "", minX: 0, maxX: 0, trackOn: undefined, trackOff: undefined, innerTrackWidth: 0, name: undefined, dragCurrentX: 0, borderSize: 0, isCheckbox:false, isReadOnly: false, render: function () { if (this.width == 0) { var ratio = this.textSizeRatio / 2; var widthFactor = 2 + Math.max(this.textOff.length * ratio, this.textOn.length * ratio); this.width = this.height * widthFactor; } this.inputEl.css("display", "none"); this.el = $('
'); this.inputEl.after(this.el); this.inputEl.on("change", this.listenToClickEvent.bind(this)); this.renderTrack(); this.renderThumb(); this.applyStyles(); this.track.on("click", this.toggle.bind(this)); this.track.on("touchend", this.toggle.bind(this)); this.addEvents(); }, listenToClickEvent : function(event){ if (this.inputEl.is(':checked')) { if(!this.checked)this.toggle(event, true); }else{ if(this.checked)this.toggle(event, true); } }, addEvents: function () { this.thumb.on("mousedown", this.startDragging.bind(this)); this.thumb.on("touchstart", this.startDragging.bind(this)); this.thumb.on("mouseenter", this.enterThumb.bind(this)); this.thumb.on("mouseleave", this.leaveThumb.bind(this)); $(document.documentElement).on("touchmove", this.drag.bind(this)); $(document.documentElement).on("mousemove", this.drag.bind(this)); $(document.documentElement).on("mouseup", this.endDrag.bind(this)); $(document.documentElement).on("touchend", this.endDrag.bind(this)); }, enterThumb: function () { this.thumbColor.addClass("on-off-switch-thumb-over"); }, leaveThumb: function () { this.thumbColor.removeClass("on-off-switch-thumb-over"); }, renderTrack: function () { var trackWidth = this.width - (this.trackBorderWidth * 2); var innerTrackWidth = trackWidth - (this.height / 2); this.innerTrackWidth = trackWidth; //var trackHeight = this.height - (this.trackBorderWidth * 2); var trackHeight = this.height var borderWidth = this.height / 2; this.track = $('
'); if (this.trackBorderColor) { this.track.css("border-color", this.trackBorderColor); } this.el.append(this.track); this.onOffTrackContainer = $('
'); this.track.append(this.onOffTrackContainer); //this.trackOn = $('
'); this.trackOn = $('
'); this.onOffTrackContainer.append(this.trackOn); this.onTextEl = $('
' + this.textOn + '
'); this.trackOn.append(this.onTextEl); if (this.textColorOn) { this.onTextEl.css("color", this.textColorOn); } //this.trackOff = $('
'); this.trackOff = $('
'); this.offTextEl = $('
' + this.textOff + '
'); this.onOffTrackContainer.append(this.trackOff); this.trackOff.append(this.offTextEl); if (this.textColorOff) { this.offTextEl.css("color", this.textColorOff); } this.styleText(this.onTextEl); this.styleText(this.offTextEl); var whiteHeight = this.height / 2; var whiteBorderRadius = whiteHeight / 2; var horizontalOffset = whiteBorderRadius / 2; var whiteWidth = this.width - (horizontalOffset * 2); var whiteEl = $('
'); var whiteEl2 = $('
'); whiteEl.css("top", this.height / 2); whiteEl2.css("top", this.height / 2); //this.trackOn.append(whiteEl); //this.trackOff.append(whiteEl2); this.maxX = this.width - this.height; }, styleText: function (el) { var textHeight = Math.round(this.height * this.textSizeRatio); var textWidth = Math.round(this.width - this.height); el.css("line-height", (this.height - (this.trackBorderWidth * 2)) + "px"); el.css("font-size", textHeight + "px"); el.css("left", (this.height / 2) + "px"); el.css("width", textWidth + "px"); }, renderThumb: function () { var borderSize = this.getBorderSize(); var size = this.height - (borderSize * 2); var borderRadius = (this.height - this.height % 2) / 2; this.thumb = $('
'); var shadow = $('
'); this.thumb.append(shadow); this.thumbColor = $('
'); this.thumb.append(this.thumbColor); if (this.trackColorOff) { this.trackOff.css("background-color", this.trackColorOff); } if (this.trackColorOn) { this.trackOn.css("background-color", this.trackColorOn); } this.el.append(this.thumb); }, getBorderSize: function () { if (this.borderSize == 0) { this.borderSize = Math.round(this.height / 40); } if(this.borderSize == 0){ this.borderSize = 1; } return this.borderSize; }, applyStyles: function () { this.thumbColor.removeClass("on-off-switch-thumb-on"); this.thumbColor.removeClass("on-off-switch-thumb-off"); this.thumbColor.removeClass("on-off-switch-thumb-over"); if (this.checked) { this.thumbColor.addClass("on-off-switch-thumb-on"); this.thumb.css("left", this.width - this.height); this.onOffTrackContainer.css("left", 0); } else { this.onOffTrackContainer.css("left", this.getTrackPosUnchecked()); this.thumbColor.addClass("on-off-switch-thumb-off"); this.thumb.css("left", 0); } if(this.isCheckbox){ this.inputEl.prop('checked', this.checked); }else{ this.inputEl.val(this.checked ? 1 : 0); } }, isDragging: false, hasBeenDragged: false, startDragging: function (e) { if(this.isReadOnly){ return false; } this.isDragging = true; this.hasBeenDragged = false; var position = this.thumb.position(); this.startCoordinates = { x: this.getX(e), elX: position.left, }; return false; }, drag: function (e) { if (!this.isDragging) { return true; } if(this.isReadOnly){ return false; } this.hasBeenDragged = true; var x = this.startCoordinates.elX + this.getX(e) - this.startCoordinates.x; if (x < this.minX)x = this.minX; if (x > this.maxX)x = this.maxX; this.onOffTrackContainer.css("left", x - this.width + (this.height)); this.thumb.css("left", x); return false; }, getX: function (e) { var x = e.pageX; if (e.type && (e.type == "touchstart" || e.type == "touchmove")) { x = e.originalEvent.touches[0].pageX; } this.dragCurrentX = x; return x; }, endDrag: function () { if (!this.isDragging)return true; if (!this.hasBeenDragged) { this.toggle(); } else { var center = this.width / 2 - (this.height / 2); var x = this.startCoordinates.elX + this.dragCurrentX - this.startCoordinates.x; if (x < center) { this.animateLeft(); } else { this.animateRight(); } } this.isDragging = false; }, getTrackPosUnchecked: function () { return 0 - this.width + this.height; }, animateLeft: function () { this.onOffTrackContainer.animate({left: this.getTrackPosUnchecked()}, 100); this.thumb.animate({left: 0}, 100,"swing", this.uncheck.bind(this)); }, animateRight: function () { this.onOffTrackContainer.animate({left: 0}, 100); this.thumb.animate({left: this.maxX}, 100, "swing", this.check.bind(this)); }, check: function () { if (!this.checked) { this.checked = true; this.notifyListeners(); } this.applyStyles(); }, uncheck: function () { if (this.checked){ this.checked = false; this.notifyListeners(); } this.applyStyles(); }, toggle: function (event, isIgnoreReadOnly) { if(!isIgnoreReadOnly && this.isReadOnly){ return false; } if (!this.checked) { this.checked = true; this.animateRight(); } else { this.checked = false; this.animateLeft(); } this.notifyListeners(); }, notifyListeners: function () { if (this.listener != undefined) { this.listener.call(this, this.name, this.checked); } }, getValue: function () { return this.checked; } });