├── flags.png ├── README.md ├── jquery.geokbd.css └── jquery.geokbd.js /flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jayarjo/jquery-geokbd/HEAD/flags.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jquery-geokbd 2 | 3 | Type Georgian letters without having Georgian keyboard installed in the system 4 | 5 | ## Getting Started 6 | First of all this is jQuery plugin, which means that you have to include jQuery first, then the plugin: 7 | 8 | ```html 9 | 10 | 11 | 12 | 13 | Very Important Document #5 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ... 23 | ``` 24 | 25 | It is possible to switch the plugin for specific forms, or even input elements (input[type="text"] and textarea) only, but right now plugin operates only in the simplest mode, thus activates georgian keyboard on all input elements that exist on the page. 26 | 27 | ```html 28 | 29 | 30 | 33 | ``` 34 | 35 | ## Credits 36 | Plugin is inspired and partially based on Ioseb Dzmanashvili's GeoKBD (https://github.com/ioseb/geokbd) 37 | 38 | 39 | ## License 40 | Copyright (c) 2012 Davit Barbakadze 41 | Licensed under the MIT license. 42 | -------------------------------------------------------------------------------- /jquery.geokbd.css: -------------------------------------------------------------------------------- 1 | .gk-switcher { 2 | position: relative; 3 | display: inline; /* for ancient IEs */ 4 | zoom: 1; 5 | display: inline-block; 6 | vertical-align: middle; 7 | width: 24px; 8 | height: 19px; 9 | -webkit-perspective: 50px; 10 | -moz-perspective: 50px; 11 | -moz-perspective-origin: 50% 50%; 12 | -webkit-perspective-origin: 50% 50%; 13 | } 14 | 15 | .gk-ka, 16 | .gk-us { 17 | -webkit-transition: all 300ms ease; 18 | -moz-transition: all 300ms ease; 19 | transition: all 300ms ease; 20 | -webkit-transform-style: preserve-3d; 21 | -moz-transform-style: preserve-3d; 22 | transform-style: preserve-3d; 23 | -webkit-transform-origin: 100% 0%; 24 | -moz-transform-origin: 100% 0%; 25 | transform-origin: 100% 0%; 26 | -webkit-backface-visibility: hidden; 27 | -moz-backface-visibility: hidden; 28 | backface-visibility: hidden; 29 | background: url(flags.png) no-repeat; 30 | cursor: pointer; 31 | } 32 | 33 | .gk-ka { 34 | -webkit-transform-origin: 0% 100%; 35 | -moz-transform-origin: 0% 100%; 36 | transform-origin: 0% 100%; 37 | -webkit-transform: translate3d(100%, 0, 0) rotateY(90deg); 38 | -moz-transform: translate3d(100%, 0, 0) rotateY(90deg); 39 | transform: translate3d(100%, 0, 0) rotateY(90deg); 40 | background-position: 0 -19px; 41 | z-index: 0; 42 | } 43 | 44 | .gk-us { 45 | background-position: 0 0; 46 | z-index: 1; 47 | } 48 | 49 | .gk-on .gk-us { 50 | -webkit-transform: translate3d(-100%, 0, 0) rotateY(-90deg); 51 | -moz-transform: translate3d(-100%, 0, 0) rotateY(-90deg); 52 | transform: translate3d(-100%, 0, 0) rotateY(-90deg); 53 | z-index: 0; 54 | } 55 | 56 | .gk-on .gk-ka { 57 | -webkit-transform: none; 58 | -moz-transform: none; 59 | transform: none; 60 | z-index: 1; 61 | } 62 | 63 | .gk-ka, 64 | .gk-us, 65 | .gk-switcher input { 66 | position: absolute; 67 | top: 0; 68 | left: 0; 69 | width: 100%; 70 | height: 100%; 71 | cursor: pointer; 72 | } 73 | 74 | .gk-switcher input { 75 | padding: 0; 76 | margin: 0; 77 | -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 78 | filter: alpha(opacity=0); 79 | opacity: 0; 80 | z-index: 2; 81 | } -------------------------------------------------------------------------------- /jquery.geokbd.js: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012 Davit Barbakadze 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 5 | and associated documentation files (the "Software"), to deal in the Software without restriction, 6 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial 11 | portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 14 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 15 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 16 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | */ 19 | 20 | ;(function($, undefined) { 21 | 22 | $.fn.geokbd = function(options) { 23 | var 24 | isOn, 25 | inputs = $([]), 26 | switchers = $([]), 27 | defaults = { 28 | on: true, 29 | hotkey: '`' 30 | }, 31 | settings = (typeof options === 'object' ? $.extend({}, defaults, options) : defaults); 32 | 33 | // first come up with affected set of input elements 34 | this.each(function() { 35 | var $this = $(this); 36 | 37 | if ($this.is(':text, textarea')) { 38 | inputs = inputs.add($this); 39 | } else if ($this.is('form')) { 40 | inputs = inputs.add($this.find(':text, textarea')); 41 | } else if ($this.is(':checkbox')) { 42 | if (!inputs.length) { 43 | inputs = $(':text, textarea'); 44 | } 45 | switchers = switchers.add($this); // store the checkboxes for further manipulation 46 | } 47 | 48 | if (typeof settings.exclude === 'string') { 49 | inputs = inputs.not(settings.exclude); 50 | } 51 | }); 52 | 53 | // mutate switchers 54 | switchers 55 | .click(function() { toggleLang() }) 56 | .wrap('
') 57 | .parent() 58 | .append('
'); 59 | 60 | // turn on/off all switchers 61 | toggleLang(isOn = settings.on); 62 | 63 | $(document).keypress(function(e) { 64 | var ch = String.fromCharCode(e.which), kach; 65 | 66 | if (settings.hotkey === ch) { 67 | toggleLang(); 68 | e.preventDefault(); 69 | } 70 | 71 | if (!isOn || !inputs.filter(e.target).length) { 72 | return; 73 | } 74 | 75 | kach = translateToKa.call(ch); 76 | 77 | if (ch != kach) { 78 | if (navigator.appName.indexOf("Internet Explorer")!=-1) { 79 | window.event.keyCode = kach.charCodeAt(0); 80 | } else { 81 | pasteTo.call(kach, e.target); 82 | e.preventDefault(); 83 | } 84 | } 85 | }); 86 | 87 | function toggleLang() { 88 | isOn = arguments[0] !== undefined ? arguments[0] : !isOn; 89 | switchers 90 | .each(function() { 91 | this.checked = isOn; 92 | }) 93 | .closest('.gk-switcher')[isOn ? 'addClass' : 'removeClass']('gk-on'); 94 | } 95 | 96 | // the following functions come directly from Ioseb Dzmanashvili's GeoKBD (https://github.com/ioseb/geokbd) 97 | 98 | function translateToKa() { 99 | /** 100 | * Original idea by Irakli Nadareishvili 101 | * http://www.sapikhvno.org/viewtopic.php?t=47&postdays=0&postorder=asc&start=10 102 | */ 103 | var index, chr, text = [], symbols = "abgdevzTiklmnopJrstufqRySCcZwWxjh"; 104 | 105 | for (var i = 0; i < this.length; i++) { 106 | chr = this.substr(i, 1); 107 | if ((index = symbols.indexOf(chr)) >= 0) { 108 | text.push(String.fromCharCode(index + 4304)); 109 | } else { 110 | text.push(chr); 111 | } 112 | } 113 | return text.join(''); 114 | } 115 | 116 | function pasteTo(field) { 117 | field.focus(); 118 | if (document.selection) { 119 | var range = document.selection.createRange(); 120 | if (range) { 121 | range.text = this; 122 | } 123 | } else if (field.selectionStart != undefined) { 124 | var scroll = field.scrollTop, start = field.selectionStart, end = field.selectionEnd; 125 | var value = field.value.substr(0, start) + this + field.value.substr(end, field.value.length); 126 | field.value = value; 127 | field.scrollTop = scroll; 128 | field.setSelectionRange(start + this.length, start + this.length); 129 | } else { 130 | field.value += this; 131 | field.setSelectionRange(field.value.length, field.value.length); 132 | } 133 | }; 134 | } 135 | 136 | }(jQuery)); 137 | --------------------------------------------------------------------------------