├── README.md ├── examples ├── advanced_usage.html ├── basic_usage.html ├── css │ ├── bootstrap.min.css │ └── style.css ├── images │ ├── sample-image.png │ ├── sample-image1.jpg │ └── sample-image2.jpg └── js │ └── jquery.min.js ├── jquery.hotspot.css ├── jquery.hotspot.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | jQuery - Hotspot 2 | === 3 | 4 | A [jQuery](http://www.jquery.com) plugin for creating *Hotspots* in an HTML element. This plugin operates in two modes, `admin` and `display`. The **admin mode** enables user to create hotspots on desired HTML elements. The **display mode** is used for only displaying the hotspots to the end user. The design of the hotspot created are fully customizable. User can add their own CSS class to style the hotspots. 5 | 6 | ### [View Demo](http://aniruddhanath.github.io/jquery-hotspot/) 7 | 8 | Note: Ensures responsiveness with the latest update. 9 | 10 | The Setup 11 | --------- 12 | 13 | ``` 14 | npm install jquery-hotspot 15 | ``` 16 | 17 | Include `jquery.hotspot.js` at the bottom of the HTML page before the closing body tag. Wrap the HTML element for which the hotspot is to be obtained with another element. Also include the `jquery.hotspot.css` file to go with some of the default design decisions. 18 | ``` 19 |
interactivity: `click`
21 | interactivity: `hover`
27 | t |
This is Admin-mode. Click this Pane to Store Messages
' 160 | }).css({ 161 | 'height': (tHeight/pHeight)*100 + '%', 162 | 'width': (tWidth/pWidth)*100 + '%', 163 | 'left': (tOffset.left - pOffset.left) + 'px', 164 | 'top': (tOffset.top - pOffset.top) + 'px' 165 | }).addClass(widget.config.hotspotOverlayClass).appendTo(widget.element); 166 | 167 | // Handle click on overlay mask 168 | this.element.delegate('span', 'click', function(event) { 169 | event.preventDefault(); 170 | event.stopPropagation(); 171 | 172 | // Get coordinates 173 | var offset = $(this).offset(), 174 | relativeX = (event.pageX - offset.left), 175 | relativeY = (event.pageY - offset.top); 176 | 177 | var height = $(widget.tagElement[0]).height(), 178 | width = $(widget.tagElement[0]).width(); 179 | 180 | var hotspot = { x: relativeX/width*100, y: relativeY/height*100 }; 181 | 182 | var schema = widget.config.schema; 183 | 184 | for (var i = 0; i < schema.length; i++) { 185 | var val = schema[i]; 186 | var fill = prompt('Please enter ' + val.property, val.default); 187 | if (fill === null) { 188 | return; 189 | } 190 | hotspot[val.property] = fill; 191 | } 192 | 193 | data.push(hotspot); 194 | 195 | // Temporarily display the spot 196 | widget.displaySpot(hotspot, true); 197 | }); 198 | 199 | // Register admin controls 200 | var button_id = this.createId(); 201 | 202 | $('', { 203 | text: "Save data" 204 | }).prop('id', ('save' + button_id)).addClass(this.config.save_Button_Class).appendTo(this.element); 205 | 206 | $('', { 207 | text: "Remove data" 208 | }).prop('id', ('remove' + button_id)).addClass(this.config.remove_Button_Class).appendTo(this.element); 209 | 210 | $(this.element).delegate('button#' + ('save' + button_id), 'click', function(event) { 211 | event.preventDefault(); 212 | event.stopPropagation(); 213 | widget.saveData(data); 214 | data = []; 215 | }); 216 | 217 | $(this.element).delegate('button#' + ('remove' + button_id), 'click', function(event) { 218 | event.preventDefault(); 219 | event.stopPropagation(); 220 | widget.removeData(); 221 | }); 222 | 223 | if (this.config.ajax) { 224 | $('', { 225 | text: "Send to server" 226 | }).prop('id', ('send' + button_id)).addClass(this.config.send_Button_Class).appendTo(this.element); 227 | 228 | $(this.element).delegate('button#' + ('send' + button_id), 'click', function(event) { 229 | event.preventDefault(); 230 | event.stopPropagation(); 231 | widget.sendData(); 232 | }); 233 | } 234 | }; 235 | 236 | Hotspot.prototype.fetchData = function() { 237 | var widget = this; 238 | 239 | // Fetch data from a server 240 | var options = { 241 | data: { 242 | HotspotPlugin_mode: "Retrieve" 243 | } 244 | }; 245 | 246 | $.ajax($.extend({}, this.config.ajaxOptions, options)) 247 | .done(function(data) { 248 | // Storing in localStorage 249 | localStorage.setItem(widget.config.LS_Variable, data); 250 | widget.parseData(); 251 | }) 252 | .fail($.noop); 253 | }; 254 | 255 | Hotspot.prototype.parseData = function() { 256 | var widget = this; 257 | 258 | var data = this.config.data, 259 | data_from_storage = localStorage.getItem(this.config.LS_Variable); 260 | 261 | if (data_from_storage && (this.config.mode === 'admin' || !this.config.data.length)) { 262 | data = JSON.parse(data_from_storage); 263 | } 264 | 265 | $.each(data, function(index, hotspot){ 266 | widget.displaySpot(hotspot); 267 | }); 268 | }; 269 | 270 | Hotspot.prototype.displaySpot = function(hotspot, unsaved) { 271 | var widget = this; 272 | 273 | var spot_html = $(''); 274 | 275 | $.each(hotspot, function(index, val) { 276 | if (typeof val === "string") { 277 | $('', { 278 | html: val 279 | }).addClass('Hotspot_' + index).appendTo(spot_html); 280 | } 281 | }); 282 | 283 | var height = $(this.tagElement[0]).height(), 284 | width = $(this.tagElement[0]).width(), 285 | offset = this.tagElement.offset(), 286 | parent_offset = this.element.offset(); 287 | 288 | var spot = $('', { 289 | html: spot_html 290 | }).css({ 291 | 'top': (hotspot.y * height / 100) + (offset.top - parent_offset.top) + 'px', 292 | 'left': (hotspot.x * width / 100) + (offset.left - parent_offset.left) + 'px' 293 | }).addClass(this.config.hotspotClass).appendTo(this.element); 294 | 295 | if (unsaved) { 296 | spot.addClass(this.config.unsavedHotspotClass); 297 | } 298 | 299 | if (this.config.interactivity === 'hover') { 300 | return; 301 | } 302 | 303 | // Overwrite CSS rule for `none` & `click` interactivity 304 | spot_html.css('display', 'block'); 305 | 306 | // Initially keep hidden 307 | if (this.config.interactivity !== 'none') { 308 | spot_html.addClass(this.config.hiddenClass); 309 | } 310 | 311 | if (this.config.interactivity === 'click') { 312 | spot.on('click', function(event) { 313 | spot_html.toggleClass(widget.config.hiddenClass); 314 | }); 315 | } else { 316 | spot_html.removeClass(this.config.hiddenClass); 317 | } 318 | }; 319 | 320 | Hotspot.prototype.saveData = function(data) { 321 | if (!data.length) { 322 | return; 323 | } 324 | 325 | // Get previous data 326 | var raw_data = localStorage.getItem(this.config.LS_Variable); 327 | 328 | var hotspots = []; 329 | 330 | if (raw_data) { 331 | hotspots = JSON.parse(raw_data); 332 | } 333 | 334 | // Append to previous data 335 | $.each(data, function(index, node) { 336 | hotspots.push(node); 337 | }); 338 | 339 | localStorage.setItem(this.config.LS_Variable, JSON.stringify(hotspots)); 340 | 341 | this.element.trigger('afterSave.hotspot', [null, hotspots]); 342 | }; 343 | 344 | Hotspot.prototype.removeData = function() { 345 | if (localStorage.getItem(this.config.LS_Variable) === null) { 346 | return; 347 | } 348 | if (!confirm("Are you sure you wanna do everything?")) { 349 | return; 350 | } 351 | localStorage.removeItem(this.config.LS_Variable); 352 | this.element.trigger('afterRemove.hotspot', [null, 'Removed']); 353 | }; 354 | 355 | Hotspot.prototype.sendData = function() { 356 | if (localStorage.getItem(this.config.LS_Variable) === null || !this.config.ajax) { 357 | return; 358 | } 359 | 360 | var widget = this; 361 | 362 | var options = { 363 | data: { 364 | HotspotPlugin_data: localStorage.getItem(this.config.LS_Variable), 365 | HotspotPlugin_mode: "Store" 366 | } 367 | }; 368 | 369 | $.ajax($.extend({}, this.config.ajaxOptions, options)) 370 | .done(function() { 371 | widget.element.trigger('afterSend.hotspot', [null, 'Sent']); 372 | }) 373 | .fail(function(err) { 374 | widget.element.trigger('afterSend.hotspot', [err]); 375 | }); 376 | }; 377 | 378 | $.fn.hotspot = function (options) { 379 | new Hotspot(this, options); 380 | return this; 381 | }; 382 | 383 | }(jQuery)); 384 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-hotspot", 3 | "version": "2.0.3", 4 | "description": "jQuery plugin to create editable Hotspots on any HTML elements", 5 | "main": "jquery.hotspot.js", 6 | "directories": { 7 | "example": "examples" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/aniruddhanath/jquery-hotspot.git" 15 | }, 16 | "keywords": [ 17 | "jquery-plugin", 18 | "ecosystem:jquery", 19 | "jquery-hotspot" 20 | ], 21 | "author": "Aniruddha Nath", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/aniruddhanath/jquery-hotspot/issues" 25 | }, 26 | "homepage": "http://aniruddhanath.github.io/jquery-hotspot" 27 | } 28 | --------------------------------------------------------------------------------