├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bower.json ├── demo ├── bower.json └── index.html ├── dist ├── framework7.indexed-list.css ├── framework7.indexed-list.js ├── framework7.indexed-list.min.css └── framework7.indexed-list.min.js └── src ├── framework7.indexed-list.css └── framework7.indexed-list.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## Framework7-Indexed-List-plugin v0.1.0 - Updated on 17 Sep 2014 4 | * Initial release. 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 boynet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Framework7 Indexed List Plugin 2 | ============================= 3 | Demo: https://boynet.github.io/boynet/ 4 | 5 | 6 | This plugin is for Indexed-List scroll like iOS and Android have, currently works only with Contacts List 7 | 8 | ![''](http://i58.tinypic.com/2608tmo.jpg) 9 | 10 | 11 | ## Installation 12 | 13 | Just grab plugin files from `dist/` folder or using bower: 14 | 15 | ``` 16 | bower install framework7-indexed-list-plugin 17 | ``` 18 | 19 | And link them to your app's right AFTER Framework7's scripts and styles: 20 | 21 | ``` 22 | 23 | 24 | ... 25 | 26 | 27 | ``` 28 | 29 | ## Usage 30 | put this html code inside .page 31 | ```` 32 | 33 | ```` 34 | 35 | ## Demo: 36 | https://boynet.github.io/boynet/ 37 | 38 | OR: 39 | 40 | Plugin comes with demo example to see how it works and looks. To make demo works you need: 41 | 42 | * install bower dependencies. Go to `demo/` folder and execute in terminal `bower install` 43 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Framework7 Indexed List Plugin", 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/boynet/Framework7-Indexed-List-plugin.git" 6 | }, 7 | "description": "Framework7 plugin to add Indexed-List scroll", 8 | "version": "0.2.0", 9 | "author": "boynet", 10 | "homepage": "https://github.com/boynet/Framework7-Indexed-List-plugin", 11 | "keywords": ["mobile", "framework", "ios 7", "ios7", "ios8", "ios 8", "iphone", "ipad", "apple", "phonegap", "native", "touch", "appstore", "app", "f7","indexed list"], 12 | "scripts": [ 13 | "dist/framework7.indexed-list.js" 14 | ], 15 | "main": [ 16 | "dist/framework7.indexed-list.js", 17 | "framework7.indexed-list.css" 18 | ], 19 | "license": ["MIT"], 20 | "dependencies": { 21 | }, 22 | "ignore": [ 23 | ".*", 24 | "build", 25 | "Gruntfile.js", 26 | "node_modules", 27 | "package.json" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /demo/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Framework7-Indexed-List-plugin-Demo", 3 | "description": "Demo for Framework7-Indexed-List-plugin plugin", 4 | "author": "boynet", 5 | "license": ["MIT"], 6 | "dependencies": { 7 | "framework7": "~1.2.0" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Indexed List 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 | 22 | 569 |
570 |
571 | 572 | 573 | 577 | 578 | 579 | -------------------------------------------------------------------------------- /dist/framework7.indexed-list.css: -------------------------------------------------------------------------------- 1 | .list-index { 2 | color: #057bf7; 3 | list-style: none; 4 | margin: 0; 5 | padding: 0; 6 | position:absolute; 7 | font-size: 11px; 8 | font-weight: bold; 9 | position:absolute; 10 | z-index:199; 11 | top:0%; 12 | height: 100%; 13 | right: 0; 14 | background: #fff; 15 | width: 15px; 16 | text-align: center; 17 | display: -webkit-box; 18 | display: -ms-flexbox; 19 | display: -webkit-flex; 20 | display: flex; 21 | -webkit-box-pack: center; 22 | -ms-flex-pack: center; 23 | -webkit-justify-content: center; 24 | justify-content: center; 25 | -webkit-box-orient: vertical; 26 | -moz-box-orient: vertical; 27 | -ms-flex-direction: column; 28 | -webkit-flex-direction: column; 29 | flex-direction: column; 30 | } 31 | .list-index li{ 32 | position: relative; 33 | z-index: 10; 34 | } 35 | .list-index li:before { 36 | content: ''; 37 | position: absolute; 38 | right: 100%; 39 | width: 10px; 40 | height: 100%; 41 | top: 0; 42 | } 43 | html[dir="rtl"] .list-index { 44 | right: auto; 45 | left: 0; 46 | } 47 | html[dir="rtl"] .list-index li:before { 48 | right: auto; 49 | left: 100%; 50 | } 51 | -------------------------------------------------------------------------------- /dist/framework7.indexed-list.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Framework7 Indexed List 0.2.0 3 | * Framework7 plugin to add Alphabet indexed list 4 | * 5 | * https://github.com/boynet/Framework7-Indexed-List-plugin 6 | * 7 | * Copyright 2015, boynet 8 | * 9 | * Licensed under MIT 10 | * 11 | * Released on: 17 Sep, 2014 12 | */ 13 | Framework7.prototype.plugins.indexedlist = function (app, params) { 14 | var $ = window.Dom7; 15 | 16 | 17 | function initIndexedList(page) { 18 | var eventsTarget = $(page.container).find('.list-index'); 19 | if (eventsTarget.length === 0) return; 20 | 21 | var pageContent = $(page.container).find('.page-content'); 22 | buildLetters(); 23 | var isTouched, isMoved; 24 | var letterToScroll; 25 | var elementHover; 26 | var fixedNavbar = pageContent.parents('.navbar-fixed').length > 0 || pageContent.parents('.navbar-through').length > 0; 27 | var searchBar = $(page.container).find('.searchbar').length > 0; 28 | 29 | if (searchBar) { 30 | eventsTarget.css('margin-top', '44px'); 31 | } 32 | 33 | function handleTouchStart(e) { 34 | e.preventDefault(); 35 | isTouched = true; 36 | 37 | var target = $(e.target); 38 | if (!target.is('li')) target = target.parents('li'); 39 | if (target.length > 0) { 40 | scrollToLetter(target.eq(0).data('index-letter')); 41 | } 42 | } 43 | 44 | function handleTouchMove(e) { 45 | if (!isTouched) return; 46 | e.preventDefault(); 47 | var target; 48 | if (e.type === 'mousemove') { 49 | target = $(e.target); 50 | } 51 | else { 52 | target = $(document.elementFromPoint(e.touches[0].pageX, e.touches[0].pageY)); 53 | } 54 | if (!target.is('li')) target = target.parents('li'); 55 | 56 | if (target.length === 0) return; 57 | if (target.length > 0 && !target.is('.list-index li')) return; 58 | 59 | scrollToLetter(target.eq(0).data('index-letter')); 60 | } 61 | 62 | function handleTouchEnd(e) { 63 | isTouched = isMoved = false; 64 | } 65 | 66 | $(page.container).on('click', '.list-index li', function (e) { 67 | var target = $(e.target); 68 | if (!target.is('li')) target = target.parents('li'); 69 | if (target.length > 0) { 70 | scrollToLetter(target.eq(0).data('index-letter')); 71 | } 72 | }); 73 | 74 | function buildLetters() { 75 | var _letters = []; 76 | var lettersHtml = ''; 77 | pageContent.find('.list-group').each(function () { 78 | var _letterDiv = $(this).find('ul .list-group-title'); 79 | var _letter = _letterDiv.html().trim().charAt(0).toUpperCase(); 80 | _letterDiv.attr('data-index-letter', _letter); 81 | lettersHtml += '
  • ' + _letter + '
  • '; 82 | _letters.push(_letter); 83 | }); 84 | eventsTarget.html(lettersHtml); 85 | return _letters; 86 | } 87 | 88 | function scrollToLetter(letter) { 89 | var scrollToEl = pageContent.find('.list-group ul li[data-index-letter="' + letter + '"]').parent(); 90 | if (!scrollToEl.length) return; 91 | var scrollTop = scrollToEl.offset().top + pageContent.scrollTop() - (fixedNavbar ? 44 : 0) - (searchBar ? 44 : 0); 92 | pageContent.scrollTop(scrollTop); 93 | } 94 | 95 | eventsTarget.on(app.touchEvents.start, handleTouchStart); 96 | eventsTarget.on(app.touchEvents.move, handleTouchMove); 97 | eventsTarget.on(app.touchEvents.end, handleTouchEnd); 98 | } 99 | 100 | 101 | return { 102 | hooks: { 103 | pageInit: initIndexedList, 104 | } 105 | }; 106 | }; 107 | -------------------------------------------------------------------------------- /dist/framework7.indexed-list.min.css: -------------------------------------------------------------------------------- 1 | .list-index{color:#057bf7;list-style:none;margin:0;padding:0;font-size:11px;font-weight:700;position:absolute;z-index:199;top:0;height:100%;right:0;background:#fff;width:15px;text-align:center;display:-webkit-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.list-index li{position:relative;z-index:10}.list-index li:before{content:'';position:absolute;right:100%;width:10px;height:100%;top:0}html[dir=rtl] .list-index{right:auto;left:0}html[dir=rtl] .list-index li:before{right:auto;left:100%} 2 | -------------------------------------------------------------------------------- /dist/framework7.indexed-list.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Framework7 Indexed List 0.2.0 3 | * Framework7 plugin to add Alphabet indexed list 4 | * 5 | * https://github.com/boynet/Framework7-Indexed-List-plugin 6 | * 7 | * Copyright 2015, boynet 8 | * 9 | * Licensed under MIT 10 | * 11 | * Released on: 17 Sep, 2014 12 | */ 13 | Framework7.prototype.plugins.indexedlist=function(t,e){function n(e){function n(t){t.preventDefault(),c=!0;var e=i(t.target);e.is("li")||(e=e.parents("li")),e.length>0&&o(e.eq(0).data("index-letter"))}function a(t){if(c){t.preventDefault();var e;(e=i("mousemove"===t.type?t.target:document.elementFromPoint(t.touches[0].pageX,t.touches[0].pageY))).is("li")||(e=e.parents("li")),0!==e.length&&(e.length>0&&!e.is(".list-index li")||o(e.eq(0).data("index-letter")))}}function r(t){c=d=!1}function o(t){var e=s.find('.list-group ul li[data-index-letter="'+t+'"]').parent();if(e.length){var n=e.offset().top+s.scrollTop()-(p?44:0)-(u?44:0);s.scrollTop(n)}}var l=i(e.container).find(".list-index");if(0!==l.length){var s=i(e.container).find(".page-content");!function(){var t=[],e="";s.find(".list-group").each(function(){var n=i(this).find("ul .list-group-title"),a=n.html().trim().charAt(0).toUpperCase();n.attr("data-index-letter",a),e+='
  • '+a+"
  • ",t.push(a)}),l.html(e)}();var c,d,p=s.parents(".navbar-fixed").length>0||s.parents(".navbar-through").length>0,u=i(e.container).find(".searchbar").length>0;u&&l.css("margin-top","44px"),i(e.container).on("click",".list-index li",function(t){var e=i(t.target);e.is("li")||(e=e.parents("li")),e.length>0&&o(e.eq(0).data("index-letter"))}),l.on(t.touchEvents.start,n),l.on(t.touchEvents.move,a),l.on(t.touchEvents.end,r)}}var i=window.Dom7;return{hooks:{pageInit:n}}}; 14 | -------------------------------------------------------------------------------- /src/framework7.indexed-list.css: -------------------------------------------------------------------------------- 1 | .list-index { 2 | color: #057bf7; 3 | list-style: none; 4 | margin: 0; 5 | padding: 0; 6 | position:absolute; 7 | font-size: 11px; 8 | font-weight: bold; 9 | position:absolute; 10 | z-index:199; 11 | top:0%; 12 | height: 100%; 13 | right: 0; 14 | background: #fff; 15 | width: 15px; 16 | text-align: center; 17 | display: -webkit-box; 18 | display: -ms-flexbox; 19 | display: -webkit-flex; 20 | display: flex; 21 | -webkit-box-pack: center; 22 | -ms-flex-pack: center; 23 | -webkit-justify-content: center; 24 | justify-content: center; 25 | -webkit-box-orient: vertical; 26 | -moz-box-orient: vertical; 27 | -ms-flex-direction: column; 28 | -webkit-flex-direction: column; 29 | flex-direction: column; 30 | } 31 | .list-index li{ 32 | position: relative; 33 | z-index: 10; 34 | } 35 | .list-index li:before { 36 | content: ''; 37 | position: absolute; 38 | right: 100%; 39 | width: 10px; 40 | height: 100%; 41 | top: 0; 42 | } 43 | html[dir="rtl"] .list-index { 44 | right: auto; 45 | left: 0; 46 | } 47 | html[dir="rtl"] .list-index li:before { 48 | right: auto; 49 | left: 100%; 50 | } 51 | -------------------------------------------------------------------------------- /src/framework7.indexed-list.js: -------------------------------------------------------------------------------- 1 | Framework7.prototype.plugins.indexedlist = function (app, params) { 2 | var $ = window.Dom7; 3 | 4 | 5 | function initIndexedList(page) { 6 | var eventsTarget = $(page.container).find('.list-index'); 7 | if (eventsTarget.length === 0) return; 8 | 9 | var pageContent = $(page.container).find('.page-content'); 10 | buildLetters(); 11 | var isTouched, isMoved; 12 | var letterToScroll; 13 | var elementHover; 14 | var fixedNavbar = pageContent.parents('.navbar-fixed').length > 0 || pageContent.parents('.navbar-through').length > 0; 15 | var searchBar = $(page.container).find('.searchbar').length > 0; 16 | 17 | if (searchBar) { 18 | eventsTarget.css('margin-top', '44px'); 19 | } 20 | 21 | function handleTouchStart(e) { 22 | e.preventDefault(); 23 | isTouched = true; 24 | 25 | var target = $(e.target); 26 | if (!target.is('li')) target = target.parents('li'); 27 | if (target.length > 0) { 28 | scrollToLetter(target.eq(0).data('index-letter')); 29 | } 30 | } 31 | 32 | function handleTouchMove(e) { 33 | if (!isTouched) return; 34 | e.preventDefault(); 35 | var target; 36 | if (e.type === 'mousemove') { 37 | target = $(e.target); 38 | } 39 | else { 40 | target = $(document.elementFromPoint(e.touches[0].pageX, e.touches[0].pageY)); 41 | } 42 | if (!target.is('li')) target = target.parents('li'); 43 | 44 | if (target.length === 0) return; 45 | if (target.length > 0 && !target.is('.list-index li')) return; 46 | 47 | scrollToLetter(target.eq(0).data('index-letter')); 48 | } 49 | 50 | function handleTouchEnd(e) { 51 | isTouched = isMoved = false; 52 | } 53 | 54 | $(page.container).on('click', '.list-index li', function (e) { 55 | var target = $(e.target); 56 | if (!target.is('li')) target = target.parents('li'); 57 | if (target.length > 0) { 58 | scrollToLetter(target.eq(0).data('index-letter')); 59 | } 60 | }); 61 | 62 | function buildLetters() { 63 | var _letters = []; 64 | var lettersHtml = ''; 65 | pageContent.find('.list-group').each(function () { 66 | var _letterDiv = $(this).find('ul .list-group-title'); 67 | var _letter = _letterDiv.html().trim().charAt(0).toUpperCase(); 68 | _letterDiv.attr('data-index-letter', _letter); 69 | lettersHtml += '
  • ' + _letter + '
  • '; 70 | _letters.push(_letter); 71 | }); 72 | eventsTarget.html(lettersHtml); 73 | return _letters; 74 | } 75 | 76 | function scrollToLetter(letter) { 77 | var scrollToEl = pageContent.find('.list-group ul li[data-index-letter="' + letter + '"]').parent(); 78 | if (!scrollToEl.length) return; 79 | var scrollTop = scrollToEl.offset().top + pageContent.scrollTop() - (fixedNavbar ? 44 : 0) - (searchBar ? 44 : 0); 80 | pageContent.scrollTop(scrollTop); 81 | } 82 | 83 | eventsTarget.on(app.touchEvents.start, handleTouchStart); 84 | eventsTarget.on(app.touchEvents.move, handleTouchMove); 85 | eventsTarget.on(app.touchEvents.end, handleTouchEnd); 86 | } 87 | 88 | 89 | return { 90 | hooks: { 91 | pageInit: initIndexedList, 92 | } 93 | }; 94 | }; 95 | --------------------------------------------------------------------------------