ultimix
paginator3000.js
Go to the documentation of this file.
1 /*
2  Paginator 3000
3  - idea by ecto (ecto.ru)
4  - coded by karaboz (karaboz.ru)
5 
6  How to implement:
7  <div class="paginator" id="paginator_example"></div>
8  <script type="text/javascript">
9  paginator_example = new Paginator('paginator_example', 2048, 10, 1, 'http://www.yourwebsite.com/pages/');
10  </script>
11 
12  Be sure that width of your paginator does not change after page is loaded
13  If it happens you must call Paginator.resizePaginator(paginator_example) function to redraw paginator
14 
15 */
16 
17 /*
18  Paginator class
19  paginatorHolderId - id of the html element where paginator will be placed as innerHTML (String): required
20  pagesTotal - number of pages (Number, required)
21  pagesSpan - number of pages which are visible at once (Number, required)
22  pageCurrent - the number of current page (Number, required)
23  baseUrl - the url of the website (String)
24  if baseUrl is 'http://www.yourwebsite.com/pages/' the links on the pages will be:
25  http://www.yourwebsite.com/pages/1, http://www.yourwebsite.com/pages/2, etc
26 */
27 var Paginator = function(paginatorHolderId, pagesTotal, pagesSpan, pageCurrent, baseUrl){
28  if(!document.getElementById(paginatorHolderId) || !pagesTotal || !pagesSpan) return false;
29 
30  this.inputData = {
31  paginatorHolderId: paginatorHolderId,
32  pagesTotal: pagesTotal,
33  pagesSpan: pagesSpan < pagesTotal ? pagesSpan : pagesTotal,
34  pageCurrent: pageCurrent,
35  baseUrl: baseUrl ? baseUrl : '/pages/'
36  };
37 
38  this.html = {
39  holder: null,
40 
41  table: null,
42  trPages: null,
43  trScrollBar: null,
44  tdsPages: null,
45 
46  scrollBar: null,
47  scrollThumb: null,
48 
49  pageCurrentMark: null
50  };
51 
52 
53  this.prepareHtml();
54 
55  this.initScrollThumb();
56  this.initPageCurrentMark();
57  this.initEvents();
58 
59  this.scrollToPageCurrent();
60 }
61 
62 /*
63  Set all .html properties (links to dom objects)
64 */
65 Paginator.prototype.prepareHtml = function(){
66 
67  this.html.holder = document.getElementById(this.inputData.paginatorHolderId);
68  this.html.holder.innerHTML = this.makePagesTableHtml();
69 
70  this.html.table = this.html.holder.getElementsByTagName('table')[0];
71 
72  var trPages = this.html.table.getElementsByTagName('tr')[0];
73  this.html.tdsPages = trPages.getElementsByTagName('td');
74 
75  this.html.scrollBar = getElementsByClassName(this.html.table, 'div', 'scroll_bar')[0];
76  this.html.scrollThumb = getElementsByClassName(this.html.table, 'div', 'scroll_thumb')[0];
77  this.html.pageCurrentMark = getElementsByClassName(this.html.table, 'div', 'current_page_mark')[0];
78 
79  // hide scrollThumb if there is no scroll (we see all pages at once)
80  if(this.inputData.pagesSpan == this.inputData.pagesTotal){
81  addClass(this.html.holder, 'fullsize');
82  }
83 }
84 
85 /*
86  Make html for pages (table)
87 */
88 Paginator.prototype.makePagesTableHtml = function(){
89  var tdWidth = (100 / this.inputData.pagesSpan) + '%';
90 
91  var html = '' +
92  '<table width="100%">' +
93  '<tr>'
94  for (var i=1; i<=this.inputData.pagesSpan; i++){
95  html += '<td width="' + tdWidth + '"></td>';
96  }
97  html += '' +
98  '</tr>' +
99  '<tr>' +
100  '<td colspan="' + this.inputData.pagesSpan + '">' +
101  '<div class="scroll_bar">' +
102  '<div class="scroll_trough"></div>' +
103  '<div class="scroll_thumb">' +
104  '<div class="scroll_knob"></div>' +
105  '</div>' +
106  '<div class="current_page_mark"></div>' +
107  '</div>' +
108  '</td>' +
109  '</tr>' +
110  '</table>';
111 
112  return html;
113 }
114 
115 /*
116  Set all needed properties for scrollThumb and it's width
117 */
118 Paginator.prototype.initScrollThumb = function(){
119  this.html.scrollThumb.widthMin = '8'; // minimum width of the scrollThumb (px)
120  this.html.scrollThumb.widthPercent = this.inputData.pagesSpan/this.inputData.pagesTotal * 100;
121 
122  this.html.scrollThumb.xPosPageCurrent = (this.inputData.pageCurrent - Math.round(this.inputData.pagesSpan/2))/this.inputData.pagesTotal * this.html.table.offsetWidth;
123  this.html.scrollThumb.xPos = this.html.scrollThumb.xPosPageCurrent;
124 
125  this.html.scrollThumb.xPosMin = 0;
126  this.html.scrollThumb.xPosMax;
127 
128  this.html.scrollThumb.widthActual;
129 
130  this.setScrollThumbWidth();
131 
132 }
133 
134 Paginator.prototype.setScrollThumbWidth = function(){
135  // Try to set width in percents
136  this.html.scrollThumb.style.width = this.html.scrollThumb.widthPercent + "%";
137 
138  // Fix the actual width in px
139  this.html.scrollThumb.widthActual = this.html.scrollThumb.offsetWidth;
140 
141  // If actual width less then minimum which we set
142  if(this.html.scrollThumb.widthActual < this.html.scrollThumb.widthMin){
143  this.html.scrollThumb.style.width = this.html.scrollThumb.widthMin + 'px';
144  }
145 
146  this.html.scrollThumb.xPosMax = this.html.table.offsetWidth - this.html.scrollThumb.widthActual;
147 }
148 
149 Paginator.prototype.moveScrollThumb = function(){
150  this.html.scrollThumb.style.left = this.html.scrollThumb.xPos + "px";
151 }
152 
153 
154 /*
155  Set all needed properties for pageCurrentMark, it's width and move it
156 */
157 Paginator.prototype.initPageCurrentMark = function(){
158  this.html.pageCurrentMark.widthMin = '3';
159  this.html.pageCurrentMark.widthPercent = 100 / this.inputData.pagesTotal;
160  this.html.pageCurrentMark.widthActual;
161 
162  this.setPageCurrentPointWidth();
163  this.movePageCurrentPoint();
164 }
165 
166 Paginator.prototype.setPageCurrentPointWidth = function(){
167  // Try to set width in percents
168  this.html.pageCurrentMark.style.width = this.html.pageCurrentMark.widthPercent + '%';
169 
170  // Fix the actual width in px
171  this.html.pageCurrentMark.widthActual = this.html.pageCurrentMark.offsetWidth;
172 
173  // If actual width less then minimum which we set
174  if(this.html.pageCurrentMark.widthActual < this.html.pageCurrentMark.widthMin){
175  this.html.pageCurrentMark.style.width = this.html.pageCurrentMark.widthMin + 'px';
176  }
177 }
178 
179 Paginator.prototype.movePageCurrentPoint = function(){
180  if(this.html.pageCurrentMark.widthActual < this.html.pageCurrentMark.offsetWidth){
181  this.html.pageCurrentMark.style.left = (this.inputData.pageCurrent - 1)/this.inputData.pagesTotal * this.html.table.offsetWidth - this.html.pageCurrentMark.offsetWidth/2 + "px";
182  } else {
183  this.html.pageCurrentMark.style.left = (this.inputData.pageCurrent - 1)/this.inputData.pagesTotal * this.html.table.offsetWidth + "px";
184  }
185 }
186 
187 
188 
189 /*
190  Drag, click and resize events
191 */
192 Paginator.prototype.initEvents = function(){
193  var _this = this;
194 
195  this.html.scrollThumb.onmousedown = function(e){
196  if (!e) var e = window.event;
197  e.cancelBubble = true;
198  if (e.stopPropagation) e.stopPropagation();
199 
200  var dx = getMousePosition(e).x - this.xPos;
201  document.onmousemove = function(e){
202  if (!e) var e = window.event;
203  _this.html.scrollThumb.xPos = getMousePosition(e).x - dx;
204 
205  // the first: draw pages, the second: move scrollThumb (it was logically but ie sucks!)
206  _this.moveScrollThumb();
207  _this.drawPages();
208 
209 
210  }
211  document.onmouseup = function(){
212  document.onmousemove = null;
213  _this.enableSelection();
214  }
215  _this.disableSelection();
216  }
217 
218  this.html.scrollBar.onmousedown = function(e){
219  if (!e) var e = window.event;
220  if(matchClass(_this.paginatorBox, 'fullsize')) return;
221 
222  _this.html.scrollThumb.xPos = getMousePosition(e).x - getPageX(_this.html.scrollBar) - _this.html.scrollThumb.offsetWidth/2;
223 
224  _this.moveScrollThumb();
225  _this.drawPages();
226 
227 
228  }
229 
230  // Comment the row beneath if you set paginator width fixed
231  addEvent(window, 'resize', function(){Paginator.resizePaginator(_this)});
232 }
233 
234 /*
235  Redraw current span of pages
236 */
237 Paginator.prototype.drawPages = function(){
238  var percentFromLeft = this.html.scrollThumb.xPos/(this.html.table.offsetWidth);
239  var cellFirstValue = Math.round(percentFromLeft * this.inputData.pagesTotal);
240 
241  var html = "";
242  // drawing pages control the position of the scrollThumb on the edges!
243  if(cellFirstValue < 1){
244  cellFirstValue = 1;
245  this.html.scrollThumb.xPos = 0;
246  this.moveScrollThumb();
247  } else if(cellFirstValue >= this.inputData.pagesTotal - this.inputData.pagesSpan) {
248  cellFirstValue = this.inputData.pagesTotal - this.inputData.pagesSpan + 1;
249  this.html.scrollThumb.xPos = this.html.table.offsetWidth - this.html.scrollThumb.offsetWidth;
250  this.moveScrollThumb();
251  }
252 
253 
254 
255  for(var i=0; i<this.html.tdsPages.length; i++){
256  var cellCurrentValue = cellFirstValue + i;
257  if(cellCurrentValue == this.inputData.pageCurrent){
258  html = "<span>" + "<strong>" + cellCurrentValue + "</strong>" + "</span>";
259  } else {
260  html = "<span>" + "<a href='" + this.inputData.baseUrl + cellCurrentValue + "'>" + cellCurrentValue + "</a>" + "</span>";
261  }
262  this.html.tdsPages[i].innerHTML = html;
263  }
264 }
265 
266 /*
267  Scroll to current page
268 */
269 Paginator.prototype.scrollToPageCurrent = function(){
270  this.html.scrollThumb.xPosPageCurrent = (this.inputData.pageCurrent - Math.round(this.inputData.pagesSpan/2))/this.inputData.pagesTotal * this.html.table.offsetWidth;
271  this.html.scrollThumb.xPos = this.html.scrollThumb.xPosPageCurrent;
272 
273  this.moveScrollThumb();
274  this.drawPages();
275 
276 }
277 
278 
279 
280 Paginator.prototype.disableSelection = function(){
281  document.onselectstart = function(){
282  return false;
283  }
284  this.html.scrollThumb.focus();
285 }
286 
287 Paginator.prototype.enableSelection = function(){
288  document.onselectstart = function(){
289  return true;
290  }
291 }
292 
293 /*
294  Function is used when paginator was resized (window.onresize fires it automatically)
295  Use it when you change paginator with DHTML
296  Do not use it if you set fixed width of paginator
297 */
298 Paginator.resizePaginator = function (paginatorObj){
299 
300  paginatorObj.setPageCurrentPointWidth();
301  paginatorObj.movePageCurrentPoint();
302 
303  paginatorObj.setScrollThumbWidth();
304  paginatorObj.scrollToPageCurrent();
305 }
306 
307 
308 
309 
310 /*
311  Global functions which are used
312 */
313 function getElementsByClassName(objParentNode, strNodeName, strClassName){
314  var nodes = objParentNode.getElementsByTagName(strNodeName);
315  if(!strClassName){
316  return nodes;
317  }
318  var nodesWithClassName = [];
319  for(var i=0; i<nodes.length; i++){
320  if(matchClass( nodes[i], strClassName )){
321  nodesWithClassName[nodesWithClassName.length] = nodes[i];
322  }
323  }
324  return nodesWithClassName;
325 }
326 
327 
328 function addClass( objNode, strNewClass ) {
329  replaceClass( objNode, strNewClass, '' );
330 }
331 
332 function removeClass( objNode, strCurrClass ) {
333  replaceClass( objNode, '', strCurrClass );
334 }
335 
336 function replaceClass( objNode, strNewClass, strCurrClass ) {
337  var strOldClass = strNewClass;
338  if ( strCurrClass && strCurrClass.length ){
339  strCurrClass = strCurrClass.replace( /\s+(\S)/g, '|$1' );
340  if ( strOldClass.length ) strOldClass += '|';
341  strOldClass += strCurrClass;
342  }
343  objNode.className = objNode.className.replace( new RegExp('(^|\\s+)(' + strOldClass + ')($|\\s+)', 'g'), '$1' );
344  objNode.className += ( (objNode.className.length)? ' ' : '' ) + strNewClass;
345 }
346 
347 function matchClass( objNode, strCurrClass ) {
348  return ( objNode && objNode.className.length && objNode.className.match( new RegExp('(^|\\s+)(' + strCurrClass + ')($|\\s+)') ) );
349 }
350 
351 
352 function addEvent(objElement, strEventType, ptrEventFunc) {
353  if (objElement.addEventListener)
354  objElement.addEventListener(strEventType, ptrEventFunc, false);
355  else if (objElement.attachEvent)
356  objElement.attachEvent('on' + strEventType, ptrEventFunc);
357 }
358 function removeEvent(objElement, strEventType, ptrEventFunc) {
359  if (objElement.removeEventListener) objElement.removeEventListener(strEventType, ptrEventFunc, false);
360  else if (objElement.detachEvent) objElement.detachEvent('on' + strEventType, ptrEventFunc);
361 }
362 
363 
364 function getPageY( oElement ) {
365  var iPosY = oElement.offsetTop;
366  while ( oElement.offsetParent != null ) {
367  oElement = oElement.offsetParent;
368  iPosY += oElement.offsetTop;
369  if (oElement.tagName == 'BODY') break;
370  }
371  return iPosY;
372 }
373 
374 function getPageX( oElement ) {
375  var iPosX = oElement.offsetLeft;
376  while ( oElement.offsetParent != null ) {
377  oElement = oElement.offsetParent;
378  iPosX += oElement.offsetLeft;
379  if (oElement.tagName == 'BODY') break;
380  }
381  return iPosX;
382 }
383 
384 function getMousePosition(e) {
385  if (e.pageX || e.pageY){
386  var posX = e.pageX;
387  var posY = e.pageY;
388  }else if (e.clientX || e.clientY) {
389  var posX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
390  var posY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
391  }
392  return {x:posX, y:posY}
393 }