├── LICENSE ├── README.md ├── bower.json ├── demo.html ├── jquery-textrange.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Daniel Imhoff 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | 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 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This jQuery plugin is for easily finding the starting and ending positions of 2 | selected text in text fields and textareas. It can also be used to set the 3 | selection, and replace the selection with given text (or insert text wherever 4 | the cursor is in the text field or textarea). 5 | 6 | * jquery-textrange may not work with WYSIWYG editors. See [issue 7 | #3](https://github.com/dwieeb/jquery-textrange/issues/3) and [this 8 | question](https://wordpress.stackexchange.com/questions/105961/insert-text-a-cursor-position-in-to-tinymce-text-editor). 9 | 10 | ## Demo 11 | 12 | * https://dwieeb.github.com/jquery-textrange/ 13 | 14 | ## Browser Support 15 | 16 | * Chrome 17 | * Firefox 18 | * Microsoft Edge 19 | * *yes, even* Internet Explorer 5.5+ 20 | 21 | ## Include 22 | 23 | Include the file directly using ` 27 | 28 | ``` 29 | 30 | :memo: *note*: jquery-textrange can be loaded through any 31 | [UMD](https://github.com/umdjs/umd/blob/master/README.md)-compatible Javascript 32 | Module Loader. 33 | 34 | ## Methods 35 | 36 | You can use this method to get all the information on the selected text of an 37 | element or a specific bit of information. 38 | 39 | ### 'get' 40 | 41 | ##### Get everything 42 | 43 | ```javascript 44 | $('input[name="example"]').textrange('get'); 45 | ``` 46 | 47 | or for short: 48 | 49 | ```javascript 50 | $('input[name="example"]').textrange(); 51 | ``` 52 | 53 | This will return a JSON object with the following information: 54 | 55 | ```javascript 56 | { 57 | "position": // cursor location in the text field) 58 | "start": //starting position of the selected text in the text field 59 | "end": // ending position of the selected text in the text field 60 | "length": // the length of the selected text in the text field 61 | "text": // the text that is selected 62 | } 63 | ``` 64 | 65 | ##### Get a particular property 66 | 67 | This function can also be used to get a particular property of the object. 68 | 69 | For example, this will obtain the starting location of the selected text: 70 | 71 | ```javascript 72 | var start = $('input[name="example"]').textrange('get', 'start'); 73 | ``` 74 | 75 | ### 'set' 76 | 77 | You can use this method to set the starting and ending locations of the 78 | selected text in an element. 79 | 80 | It works much like [PHP's 81 | substr()](https://secure.php.net/manual/en/function.substr.php), so if you're 82 | familiar with that, it should be a breeze! Here are some examples, anyway. 83 | 84 | For the following examples, let's say `input[name="example"]` contains the text 85 | `abcdef`. 86 | 87 | ```javascript 88 | $('input[name="example"]').textrange('set'); // selects "abcdef" (select all) 89 | $('input[name="example"]').textrange('set', 2); // selects "cdef" 90 | $('input[name="example"]').textrange('set', 2, 3); // selects "cde" 91 | $('input[name="example"]').textrange('set', 2, -2); // selects "cd" 92 | $('input[name="example"]').textrange('set', -3); // selects "def" 93 | $('input[name="example"]').textrange('set', -2, 1); // selects "e" 94 | $('input[name="example"]').textrange('set', -4, -1); // selects "cde" 95 | ``` 96 | 97 | If you're looking to set the cursor at one specific location, you can use `0` 98 | for length, or you can use `$().textrange('setcursor')` (see below). 99 | 100 | ### 'setcursor' 101 | 102 | You can use this method to set the location of the cursor in your text field. 103 | 104 | To set the cursor at the fifth character position: 105 | 106 | ```javascript 107 | $('input[name="example"]').textrange('setcursor', 5); 108 | ``` 109 | 110 | ### 'replace' 111 | 112 | You can use this method to replace the selection with given text. 113 | 114 | ```javascript 115 | $('input[name="example"]').textrange('replace', 'some text'); 116 | ``` 117 | 118 | There is also an `insert` alias for `replace` if you're using this method to 119 | insert text at the cursor location. They work the same way. 120 | 121 | ## Options 122 | 123 | For the first parameter of each method, you can pass an object instead of a 124 | string with additional options: 125 | 126 | ```javascript 127 | $('input[name="example"]').textrange({ method: 'get' }); 128 | $('input[name="example"]').textrange({ method: 'set', nofocus: true }, 2); 129 | $('input[name="example"]').textrange({ method: 'get', nofocus: true }, 'start'); 130 | ``` 131 | 132 | * `method` (defaults to `'get'`): One of the methods above. 133 | * `nofocus`: Do not call `.focus()` on the dom element. See [PR 134 | #20](https://github.com/dwieeb/jquery-textrange/pull/20). 135 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-textrange", 3 | "version": "1.4.0", 4 | "main": "jquery-textrange.js", 5 | "dependencies": { 6 | "jquery": ">=1.3" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jquery-textrange 6 | 7 | 8 | 25 | 74 | 75 | 76 |

jquery-textrange

77 | created by Daniel Imhoff 78 | See README.md for all features and documentation. 79 |
80 | 84 |
85 |
86 | Object returned: 87 | 88 | { 89 | position: 0, 90 | start: 0, 91 | end: 0, 92 | length: 0, 93 | text: "" 94 | } 95 | 96 | 97 |
98 |
99 | Select a substring starting at with a length of 100 |
101 |
102 | Replace the selected text with: 103 |
104 | 105 | 106 | -------------------------------------------------------------------------------- /jquery-textrange.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery-textrange 3 | * 4 | * A jQuery plugin for getting, setting and replacing the selected text in input fields and textareas. 5 | * See the [README](https://github.com/dwieeb/jquery-textrange/blob/1.x/README.md) for usage and examples. 6 | * 7 | * (c) 2012-2017 Daniel Imhoff - dwieeb.com 8 | */ 9 | 10 | (function(factory) { 11 | 12 | if (typeof define === 'function' && define.amd) { 13 | define(['jquery'], factory); 14 | } else if (typeof exports === 'object') { 15 | factory(require('jquery')); 16 | } else { 17 | factory(jQuery); 18 | } 19 | 20 | })(function($) { 21 | 22 | var browserType, 23 | 24 | textrange = { 25 | 26 | /** 27 | * $().textrange() or $().textrange('get') 28 | * 29 | * Retrieves an object containing the start and end location of the text range, the length of the range and the 30 | * substring of the range. 31 | * 32 | * @param (optional) property 33 | * @return An object of properties including position, start, end, length, and text or a specific property. 34 | */ 35 | get: function(property) { 36 | return _textrange[browserType].get.apply(this, [property]); 37 | }, 38 | 39 | /** 40 | * $().textrange('set') 41 | * 42 | * Sets the selected text of an object by specifying the start and length of the selection. 43 | * 44 | * The start and length parameters are identical to PHP's substr() function with the following changes: 45 | * - excluding start will select all the text in the field. 46 | * - passing 0 for length will set the cursor at start. See $().textrange('setcursor') 47 | * 48 | * @param (optional) start 49 | * @param (optional) length 50 | * 51 | * @see https://secure.php.net/manual/en/function.substr.php 52 | */ 53 | set: function(start, length) { 54 | var s = parseInt(start), 55 | l = parseInt(length), 56 | e; 57 | 58 | if (typeof start === 'undefined') { 59 | s = 0; 60 | } else if (start < 0) { 61 | s = this[0].value.length + s; 62 | } 63 | 64 | if (typeof length !== 'undefined') { 65 | if (length >= 0) { 66 | e = s + l; 67 | } else { 68 | e = this[0].value.length + l; 69 | } 70 | } 71 | 72 | _textrange[browserType].set.apply(this, [s, e]); 73 | 74 | return this; 75 | }, 76 | 77 | /** 78 | * $().textrange('setcursor') 79 | * 80 | * Sets the cursor at a position of the text field. 81 | * 82 | * @param position 83 | */ 84 | setcursor: function(position) { 85 | return this.textrange('set', position, 0); 86 | }, 87 | 88 | /** 89 | * $().textrange('replace') 90 | * Replaces the selected text in the input field or textarea with text. 91 | * 92 | * @param text The text to replace the selection with. 93 | */ 94 | replace: function(text) { 95 | _textrange[browserType].replace.apply(this, [String(text)]); 96 | 97 | return this; 98 | }, 99 | 100 | /** 101 | * Alias for $().textrange('replace') 102 | */ 103 | insert: function(text) { 104 | return this.textrange('replace', text); 105 | } 106 | }, 107 | 108 | _textrange = { 109 | xul: { 110 | get: function(property) { 111 | var props = { 112 | position: this[0].selectionStart, 113 | start: this[0].selectionStart, 114 | end: this[0].selectionEnd, 115 | length: this[0].selectionEnd - this[0].selectionStart, 116 | text: this.val().substring(this[0].selectionStart, this[0].selectionEnd) 117 | }; 118 | 119 | return typeof property === 'undefined' ? props : props[property]; 120 | }, 121 | 122 | set: function(start, end) { 123 | if (typeof end === 'undefined') { 124 | end = this[0].value.length; 125 | } 126 | 127 | this[0].selectionStart = start; 128 | this[0].selectionEnd = end; 129 | }, 130 | 131 | replace: function(text) { 132 | var start = this[0].selectionStart; 133 | var end = this[0].selectionEnd; 134 | var val = this.val(); 135 | this.val(val.substring(0, start) + text + val.substring(end, val.length)); 136 | this[0].selectionStart = start; 137 | this[0].selectionEnd = start + text.length; 138 | } 139 | }, 140 | 141 | msie: { 142 | get: function(property) { 143 | var range = document.selection.createRange(); 144 | 145 | if (typeof range === 'undefined') { 146 | var props = { 147 | position: 0, 148 | start: 0, 149 | end: this.val().length, 150 | length: this.val().length, 151 | text: this.val() 152 | }; 153 | 154 | return typeof property === 'undefined' ? props : props[property]; 155 | } 156 | 157 | var start = 0; 158 | var end = 0; 159 | var length = this[0].value.length; 160 | var lfValue = this[0].value.replace(/\r\n/g, '\n'); 161 | var rangeText = this[0].createTextRange(); 162 | var rangeTextEnd = this[0].createTextRange(); 163 | rangeText.moveToBookmark(range.getBookmark()); 164 | rangeTextEnd.collapse(false); 165 | 166 | if (rangeText.compareEndPoints('StartToEnd', rangeTextEnd) === -1) { 167 | start = -rangeText.moveStart('character', -length); 168 | start += lfValue.slice(0, start).split('\n').length - 1; 169 | 170 | if (rangeText.compareEndPoints('EndToEnd', rangeTextEnd) === -1) { 171 | end = -rangeText.moveEnd('character', -length); 172 | end += lfValue.slice(0, end).split('\n').length - 1; 173 | } else { 174 | end = length; 175 | } 176 | } else { 177 | start = length; 178 | end = length; 179 | } 180 | 181 | var props = { 182 | position: start, 183 | start: start, 184 | end: end, 185 | length: length, 186 | text: range.text 187 | }; 188 | 189 | return typeof property === 'undefined' ? props : props[property]; 190 | }, 191 | 192 | set: function(start, end) { 193 | var range = this[0].createTextRange(); 194 | 195 | if (typeof range === 'undefined') { 196 | return; 197 | } 198 | 199 | if (typeof end === 'undefined') { 200 | end = this[0].value.length; 201 | } 202 | 203 | var ieStart = start - (this[0].value.slice(0, start).split("\r\n").length - 1); 204 | var ieEnd = end - (this[0].value.slice(0, end).split("\r\n").length - 1); 205 | 206 | range.collapse(true); 207 | 208 | range.moveEnd('character', ieEnd); 209 | range.moveStart('character', ieStart); 210 | 211 | range.select(); 212 | }, 213 | 214 | replace: function(text) { 215 | document.selection.createRange().text = text; 216 | } 217 | } 218 | }; 219 | 220 | $.fn.extend({ 221 | textrange: function(arg) { 222 | var method = 'get'; 223 | var options = {}; 224 | 225 | if (typeof this[0] === 'undefined') { 226 | return this; 227 | } 228 | 229 | if (typeof arg === 'string') { 230 | method = arg; 231 | } else if (typeof arg === 'object') { 232 | method = arg.method || method; 233 | options = arg; 234 | } 235 | 236 | if (typeof browserType === 'undefined') { 237 | browserType = 'selectionStart' in this[0] ? 'xul' : document.selection ? 'msie' : 'unknown'; 238 | } 239 | 240 | // I don't know how to support this browser. :c 241 | if (browserType === 'unknown') { 242 | return this; 243 | } 244 | 245 | // Focus on the element before operating upon it. 246 | if (!options.nofocus && document.activeElement !== this[0]) { 247 | this[0].focus(); 248 | } 249 | 250 | if (typeof textrange[method] === 'function') { 251 | return textrange[method].apply(this, Array.prototype.slice.call(arguments, 1)); 252 | } else { 253 | $.error("Method " + method + " does not exist in jQuery.textrange"); 254 | } 255 | } 256 | }); 257 | }); 258 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-textrange", 3 | "version": "1.4.0", 4 | "description": "A jQuery plugin for getting, setting and replacing the selected text in input fields and textareas.", 5 | "main": "jquery-textrange.js", 6 | "dependencies": { 7 | "jquery": "*" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/dwieeb/jquery-textrange.git" 16 | }, 17 | "keywords": [ 18 | "jquery", 19 | "jquery-plugin", 20 | "caret", 21 | "cursor", 22 | "field", 23 | "highlight", 24 | "input", 25 | "range", 26 | "replace", 27 | "select", 28 | "selection", 29 | "substr", 30 | "substring", 31 | "text", 32 | "textarea", 33 | "textrange" 34 | ], 35 | "author": "Daniel Imhoff", 36 | "license": "MIT", 37 | "bugs": { 38 | "url": "https://github.com/dwieeb/jquery-textrange/issues" 39 | } 40 | } 41 | --------------------------------------------------------------------------------