On a project, I use datatables 1.10.2 with, to have pagination with bootstrap style, this script :
$.extend($.fn.dataTableExt.oPagination, {
bootstrap: {
fnInit: function(oSettings, nPaging, fnDraw) {
var els, fnClickHandler, oLang;
oLang = oSettings.oLanguage.oPaginate;
fnClickHandler = function(e) {
e.preventDefault();
if (oSettings.oApi._fnPageChange(oSettings, e.data.action)) {
return fnDraw(oSettings);
}
};
$(nPaging).addClass("pagination").append("<ul>" + "<li class=\"prev disabled\">← " + oLang.sPrevious + "</li>" + "<li class=\"next disabled\">" + oLang.sNext + " → </li>" + "</ul>");
els = $("a", nPaging);
$(els[0]).bind("click.DT", {
action: "previous"
}, fnClickHandler);
return $(els[1]).bind("click.DT", {
action: "next"
}, fnClickHandler);
},
fnUpdate: function(oSettings, fnDraw) {
var an, i, iEnd, iHalf, iListLength, iStart, ien, j, oPaging, sClass, _results;
oPaging = oSettings.oInstance.fnPagingInfo();
iListLength = 5;
an = oSettings.aanFeatures.p;
i = void 0;
ien = void 0;
j = void 0;
sClass = void 0;
iStart = void 0;
iEnd = void 0;
iHalf = Math.floor(iListLength / 2);
if (oPaging.iTotalPages < iListLength) {
iStart = 1;
iEnd = oPaging.iTotalPages;
} else if (oPaging.iPage <= iHalf) {
iStart = 1;
iEnd = iListLength;
} else if (oPaging.iPage >= (oPaging.iTotalPages - iHalf)) {
iStart = oPaging.iTotalPages - iListLength + 1;
iEnd = oPaging.iTotalPages;
} else {
iStart = oPaging.iPage - iHalf + 1;
iEnd = iStart + iListLength - 1;
}
i = 0;
ien = an.length;
_results = [];
while (i < ien) {
$("li:gt(0)", an[i]).filter(":not(:last)").remove();
j = iStart;
while (j <= iEnd) {
sClass = (j === oPaging.iPage + 1 ? "class=\"active\"" : "");
$("<li " + sClass + ">" + j + "</li>").insertBefore($("li:last", an[i])[0]).bind("click", function(e) {
e.preventDefault();
oSettings._iDisplayStart = (parseInt($("a", this).text(), 10) - 1) * oPaging.iLength;
return fnDraw(oSettings);
});
j++;
}
if (oPaging.iPage === 0) {
$("li:first", an[i]).addClass("disabled");
} else {
$("li:first", an[i]).removeClass("disabled");
}
if (oPaging.iPage === oPaging.iTotalPages - 1 || oPaging.iTotalPages === 0) {
$("li:last", an[i]).addClass("disabled");
} else {
$("li:last", an[i]).removeClass("disabled");
}
_results.push(i++);
}
return _results;
}
}
});
if ($.fn.DataTable.TableTools) {
$.extend(true, $.fn.DataTable.TableTools.classes, {
container: "DTTT btn-group",
buttons: {
normal: "btn",
disabled: "disabled"
},
collection: {
container: "DTTT_dropdown dropdown-menu",
buttons: {
normal: "",
disabled: "disabled"
}
},
print: {
info: "DTTT_print_info modal"
},
select: {
row: "active"
}
});
$.extend(true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
collection: {
container: "ul",
button: "li",
liner: "a"
}
});
}
}).call(this);
It works when I have a single datatable but when I have multiple datatables it break at the line if (oPaging.iTotalPages < iListLength) {. I seen than oSettings.oInstance is null for all datatables expect the last one.
What can I do to make it working?
add the plugin below
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
{
return {
"iStart": oSettings._iDisplayStart,
"iEnd": oSettings.fnDisplayEnd(),
"iLength": oSettings._iDisplayLength,
"iTotal": oSettings.fnRecordsTotal(),
"iFilteredTotal": oSettings.fnRecordsDisplay(),
"iPage": oSettings._iDisplayLength === -1 ?
0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
"iTotalPages": oSettings._iDisplayLength === -1 ?
0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
};
};
Related
I have a js pagination system that find .classname elems and paginate them on-the-fly. Clicking on navigation pages the script shows only .classname elements in that interval.
When too much items have to be paginated I would like to add an arrow system to let navigate pages links. The main script is here: https://jsfiddle.net/gyzo2u9c/
(function($) {
var pagify = {
items: {},
container: null,
totalPages: 1,
perPage: 3,
currentPage: 0,
createNavigation: function() {
this.totalPages = Math.ceil(this.items.length / this.perPage);
$('.pagination', this.container.parent()).remove();
var pagination = $('<div class="pagination"></div>').append('<a class="nav prev disabled" data-next="false"><i class="fas fa-caret-left"></i></a>');
for (var i = 0; i < this.totalPages; i++) {
var pageElClass = "page";
if (!i)
pageElClass = "page current";
var pageEl = '<a class="' + pageElClass + '" data-page="' + (
i + 1) + '">' + (
i + 1) + "</a>";
pagination.append(pageEl);
}
pagination.append('<a class="nav next" data-next="true"><i class="fas fa-caret-right"></i></a>');
/*aggiungiamo la paginazione sopra nel calendario*/
if ($(this.container).selector == '#calendario .archivio') {
this.container.before(pagination);
} else {
/*sotto, in tutti gli altri casi*/
this.container.after(pagination);
}
var that = this;
$("body").off("click", ".nav");
this.navigator = $("body").on("click", ".nav", function() {
var el = $(this);
that.navigate(el.data("next"));
});
$("body").off("click", ".page");
this.pageNavigator = $("body").on("click", ".page", function() {
var el = $(this);
that.goToPage(el.data("page"));
$([document.documentElement, document.body]).animate({
scrollTop: ($(".archivio").offset().top - 120)
}, 1);
});
},
navigate: function(next) {
// default perPage to 5
if (isNaN(next) || next === undefined) {
next = true;
}
$(".pagination .nav").removeClass("disabled");
if (next) {
this.currentPage++;
if (this.currentPage > (this.totalPages - 1))
this.currentPage = (this.totalPages - 1);
if (this.currentPage == (this.totalPages - 1))
$(".pagination .nav.next").addClass("disabled");
} else {
this.currentPage--;
if (this.currentPage < 0)
this.currentPage = 0;
if (this.currentPage == 0)
$(".pagination .nav.prev").addClass("disabled");
}
this.showItems();
},
updateNavigation: function() {
var pages = $(".pagination .page");
pages.removeClass("current");
$('.pagination .page[data-page="' + (
this.currentPage + 1) + '"]').addClass("current");
},
goToPage: function(page) {
this.currentPage = page - 1;
$(".pagination .nav").removeClass("disabled");
if (this.currentPage == (this.totalPages - 1))
$(".pagination .nav.next").addClass("disabled");
if (this.currentPage == 0)
$(".pagination .nav.prev").addClass("disabled");
this.showItems();
},
showItems: function() {
this.items.hide().removeClass('item_visibile');
var base = this.perPage * this.currentPage;
this.items.slice(base, base + this.perPage).show().addClass('item_visibile');
this.updateNavigation();
},
init: function(container, items, perPage, currentPage) {
// default perPage to 5
if (isNaN(currentPage) || currentPage === undefined) {
currentPage = 0;
}
this.container = container;
this.currentPage = currentPage;
this.totalPages = 1;
this.perPage = perPage;
this.items = items;
this.createNavigation();
this.showItems();
}
};
// stuff it all into a jQuery method!
$.fn.pagify = function(perPage, itemSelector, currentPage) {
var el = $(this);
var items = $(itemSelector, el);
// default perPage to 5
if (isNaN(perPage) || perPage === undefined) {
perPage = 3;
}
// don't fire if fewer items than perPage
if (items.length <= perPage) {
return true;
}
pagify.init(el, items, perPage, currentPage);
};
})(jQuery);
jQuery(".archive").pagify(2, ".item");
How/Where I have to add the arrow alghoritm?
Thank you in advanced
Solution:
(function($) {
var pagify = {
items: {},
container: null,
totalPages: 1,
perPage: 3,
currentPage: 0,
nextpageInterval: 20,
createNavigation: function() {
this.generateUI();
var that = this;
$("body").off("click", ".nav");
this.navigator = $("body").on("click", ".nav", function() {
var el = $(this);
that.navigate(el.data("next"));
});
$("body").off("click", ".page");
this.pageNavigator = $("body").on("click", ".page", function() {
var el = $(this);
that.goToPage(el.data("page"));
$([document.documentElement, document.body]).animate({
scrollTop: ($(".archivio").offset().top-120)
}, 1);
});
},
getPageList: function(totalPages, page, maxLength) {
if (maxLength < 5) throw "maxLength must be at least 5";
function range(start, end) {
return Array.from(Array(end - start + 1), (_, i) => i + start);
}
var sideWidth = 1;
var leftWidth = (maxLength - sideWidth*2 - 3) >> 1;
var rightWidth = (maxLength - sideWidth*2 - 2) >> 1;
if (totalPages <= maxLength) {
// no breaks in list
return range(1, totalPages);
}
if (page <= maxLength - sideWidth - 1 - rightWidth) {
// no break on left of page
return range(1, maxLength - sideWidth - 1)
.concat(0, range(totalPages - sideWidth + 1, totalPages));
}
if (page >= totalPages - sideWidth - 1 - rightWidth) {
// no break on right of page
return range(1, sideWidth)
.concat(0, range(totalPages - sideWidth - 1 - rightWidth - leftWidth, totalPages));
}
// Breaks on both sides
return range(1, sideWidth)
.concat(0, range(page - leftWidth, page + rightWidth),
0, range(totalPages - sideWidth + 1, totalPages));
},
generateUI: function(){
this.totalPages = Math.ceil(this.items.length / this.perPage);
var pages = this.getPageList(this.totalPages, this.currentPage, this.nextpageInterval);
$('.pagination', this.container.parent()).remove();
var pagination = $('<div class="pagination"></div>');
for (var i = 0; i < pages.length; i++) {
var pageElClass = "page";
if (pages[i] == (this.currentPage + 1)){
pageElClass = "page current";
}
if(pages[i] != 0){
var lbl = pages[i];
if(i == 0 && pages[i + 1] == 0){
lbl = '<i class="fas fa-step-backward"></i>';
}else if(i == (pages.length-1) && pages[i - 1] == 0){
lbl = '<i class="fas fa-step-forward"></i>';
}
var pageEl = '<a class="' + pageElClass + '" data-page="' + (
pages[i]) + '">' + (
lbl) + "</a>";
pagination.append(pageEl);
}else{
if(i == 1){
var prevEl = '<a class="nav prev disabled" data-next="false"><i class="fas fa-caret-left"></i></a>';
pagination.append(prevEl);
}else{
var nextEl = '<a class="nav next" data-next="true"><i class="fas fa-caret-right"></i></a>';
pagination.append(nextEl);
}
}
}
/*aggiungiamo la paginazione sopra nel calendario*/
if ($(this.container).selector == '#calendario .archivio'){
this.container.before(pagination);
} else {
/*sotto, in tutti gli altri casi*/
this.container.after(pagination);
}
},
navigate: function(next) {
// default perPage to 5
if (isNaN(next) || next === undefined) {
next = true;
}
$(".pagination .nav").removeClass("disabled");
if (next) {
this.currentPage++;
if (this.currentPage > (this.totalPages - 1))
this.currentPage = (this.totalPages - 1);
if (this.currentPage == (this.totalPages - 1))
$(".pagination .nav.next").addClass("disabled");
}
else {
this.currentPage--;
if (this.currentPage < 0)
this.currentPage = 0;
if (this.currentPage == 0)
$(".pagination .nav.prev").addClass("disabled");
}
this.showItems();
},
updateNavigation: function() {
var pages = $(".pagination .page");
pages.removeClass("current");
$('.pagination .page[data-page="' + (
this.currentPage + 1) + '"]').addClass("current");
this.generateUI();
},
goToPage: function(page) {
this.currentPage = page - 1;
$(".pagination .nav").removeClass("disabled");
if (this.currentPage == (this.totalPages - 1))
$(".pagination .nav.next").addClass("disabled");
if (this.currentPage == 0)
$(".pagination .nav.prev").addClass("disabled");
this.showItems();
},
showItems: function() {
this.items.hide().removeClass('item_visibile');
var base = this.perPage * this.currentPage;
this.items.slice(base, base + this.perPage).show().addClass('item_visibile');
this.updateNavigation();
},
init: function(container, items, perPage, currentPage) {
// default perPage to 5
if (isNaN(currentPage) || currentPage === undefined) {
currentPage = 0;
}
this.container = container;
this.currentPage = currentPage;
this.totalPages = 1;
this.perPage = perPage;
this.items = items;
this.createNavigation();
this.showItems();
}
};
// stuff it all into a jQuery method!
$.fn.pagify = function(perPage, itemSelector, currentPage) {
var el = $(this);
var items = $(itemSelector, el);
// default perPage to 5
if (isNaN(perPage) || perPage === undefined) {
perPage = 3;
}
// don't fire if fewer items than perPage
if (items.length <= perPage) {
return true;
}
pagify.init(el, items, perPage, currentPage);
};
})(jQuery);
This is my multiplication game made using javascript which asks the user to answer questions and provides feedback. the game currently performs multiplication questions and I want it to ask the user addition questions without changing the parameters of the game. I want the game to display the same and function exactly like my multiplication game except it performs addition instead of multiplication using random numbers.
var Counter = {
PlayingState: null,
IsStoped: true,
Score: 0,
TimeRemaining: 0,
FirstNumber: 0,
SecondNumber: 0,
CorrectAnswer: 0,
CorrectPosition: 0,
WrongAnswer: 0,
AddContentToElement: function(selector, content)
{
document.querySelector(selector).innerHTML = content;
},
ChangeStyle: function(selector, property, value)
{
document.querySelector(selector).setAttribute(property, value);
},
Initialize: function(timeRemaining)
{
this.TimeRemaining = timeRemaining;
},
GenerateRandomNumber: function(multiplier)
{
return Math.round( Math.random() * multiplier ) + 1;
},
Refresh: function(selector, data)
{
document.querySelector(selector).innerText = (data < 10 ? "0" : "") + data;
},
LoopThroughElements: function()
{
var answers = [this.CorrectAnswer];
for (var index = 1; index < 5; index++)
{
this.ChangeStyle("ul#choices > li:nth-of-type(" + index + ")", "style", "height:auto;");
if (index !== this.CorrectPosition)
{
do
{
this.WrongAnswer = this.GenerateRandomNumber(9) * this.GenerateRandomNumber(9);
} while ( answers.indexOf(this.WrongAnswer) > -1 );
this.AddContentToElement( "ul#choices > li:nth-of-type(" + index + ")", this.WrongAnswer );
answers.push(this.WrongAnswer);
}
}
},
Launch: function()
{
this.IsStoped = false;
this.Action();
this.ChangeStyle("aside#time-remaining", "style", "visibility:visible;");
this.ChangeStyle("#game-over", "style", "display:none;");
this.ChangeStyle("ul#choices", "style", "pointer-events:initial; opacity:1;");
this.ChangeStyle("button#start-reset", "style", "visibility:hidden;");
this.AddContentToElement("button#start-reset", "Reset Game");
this.Refresh("aside#time-remaining > span", this.TimeRemaining);
this.GenerateQuestionAndAnswers();
},
GenerateQuestionAndAnswers: function()
{
this.FirstNumber = this.GenerateRandomNumber(9);
this.SecondNumber = this.GenerateRandomNumber(9);
this.CorrectAnswer = this.FirstNumber * this.SecondNumber;
this.CorrectPosition = this.GenerateRandomNumber(3);
this.ChangeStyle("section#question", "style", "height:auto;");
this.AddContentToElement("section#question", this.FirstNumber + "x" + this.SecondNumber);
this.AddContentToElement( "ul#choices > li:nth-of-type(" + this.CorrectPosition + ")", this.CorrectAnswer );
this.LoopThroughElements();
},
Action: function()
{
Counter.PlayingState = setInterval( function()
{
Counter.TimeRemaining--;
if (Counter.TimeRemaining <= 50)
{
Counter.ChangeStyle("button#start-reset", "style", "visibility:visible;");
}
if (Counter.TimeRemaining < 1)
{
Counter.Stop();
}
else
{
Counter.Refresh("aside#time-remaining > span", Counter.TimeRemaining);
}
}, 1000 );
},
EventListener: function(event)
{
if ( Number(event.currentTarget.innerText) === Number(Counter.CorrectAnswer) )
{
Counter.Score++;
Counter.Refresh("aside#score > span", Counter.Score);
Counter.GenerateQuestionAndAnswers();
Counter.ChangeStyle("p#message", "style", "visibility:visible; background-color:#23A230;");
Counter.AddContentToElement("p#message", "Correct");
}
else
{
if (Counter.Score >= 1)
{
Counter.Score -= 0.5;
Counter.Refresh("aside#score > span", Counter.Score);
}
Counter.ChangeStyle("p#message", "style", "visibility:visible; background-color:#DE401A;");
Counter.AddContentToElement("p#message", "Try again");
}
setTimeout( function()
{
Counter.ChangeStyle("p#message", "style", "visibility:hidden;");
}, 1000 );
},
CheckClickOnRightAnswer: function()
{
for (var index = 1; index < 5; index++)
{
document.querySelector("ul#choices > li:nth-of-type(" + index + ")").removeEventListener("click", this.EventListener, false);
document.querySelector("ul#choices > li:nth-of-type(" + index + ")").addEventListener("click", this.EventListener);
}
},
Stop: function()
{
this.IsStoped = true;
clearInterval(this.PlayingState);
this.ChangeStyle("ul#choices", "style", "pointer-events:none; opacity:0.4;");
this.ChangeStyle("aside#time-remaining", "style", "visibility:hidden;");
this.ChangeStyle("div#game-over", "style", "display:block;");
this.AddContentToElement("button#start-reset", "Start Game");
this.AddContentToElement( "div#game-over > p:last-of-type > span", (this.Score !== "00" && this.Score < 10 ? "0" : "") + this.Score );
this.AddContentToElement("aside#score > span", this.Score = "00");
}
};
document.addEventListener('DOMContentLoaded', function()
{
document.getElementById("start-reset").addEventListener("click", function()
{
Counter.Initialize(60);
Counter.IsStoped ? Counter.Launch() : Counter.Stop();
Counter.CheckClickOnRightAnswer();
});
});
Change this line
this.CorrectAnswer = this.FirstNumber * this.SecondNumber;
to this
this.CorrectAnswer = this.FirstNumber + this.SecondNumber;
and probably change this
this.WrongAnswer = this.GenerateRandomNumber(9) * this.GenerateRandomNumber(9);
to this
this.WrongAnswer = this.GenerateRandomNumber(9) + this.GenerateRandomNumber(9);
VUE debug mode report an error in this line of my code:
:style="{transform : 'translate3d(' + translateX + 'px,0, 0)'}"\
In the docs they don't explain how to paint a variable within a style binding.
You can check my vuejs component here:
Vue.component('vue-tab', {
template: '<template>\
<div class="tab-container">\
<ul class="tab-title-container">\
<li class="tab-title"\
v-for="(title,index) in tabtitles"\
:class="{active: index+1===currentPage}"\
:key="index"\
#click="setPage(index+1)">{{title}}\
</li>\
</ul>\
<!-- decide if bind touchstart -->\
<div v-if="slidable"\
class="tabswiper"\
:class="{invisible:invisible}"\
#touchstart="_onTouchStart">\
<div class="tabswiper-wrap"\
ref="tabswiper-wrap"\
:class="{dragging: dragging}"\
:style="{transform : 'translate3d(' + translateX + 'px,0, 0)'}"\
#transitionend="_onTransitionEnd">\
<slot></slot>\
</div>\
</div>\
<div v-else class="tabswiper"\
:class="{invisible:invisible}">\
<div class="tabswiper-wrap"\
ref="tabswiper-wrap"\
:class="{dragging: dragging}"\
:style="{'transform' : 'translate3d(' + translateX + 'px,0, 0)'}"\
#transitionend="_onTransitionEnd">\
<slot></slot>\
</div>\
</div>\
</div>\
</template>',
props: {
tabtitles: {
type: Array,
default: []
},
curPage: {
type: Number,
default: 1
},
slidable: {
type: Boolean,
default: true
}
},
watch: {
curPage: function (val) {
this.setPage(val)
}
},
data() {
return {
lastPage: 1,
currentPage: this.curPage,
translateX: 0,
startTranslateX: 0,
delta: 0,
deltaY: 0,
dragging: false,
startPos: null,
startPosY: null,
transitioning: false,
slideEls: [],
invisible: true,
judge: JUDGE_INITIAL,
};
},
mounted(){
this.$nextTick(function () {
this._onTouchMove = this._onTouchMove.bind(this);
this._onTouchEnd = this._onTouchEnd.bind(this);
this.slideEls = this.$refs['tabswiper-wrap'].children;
this.dragging = true;
this.setPage(this.currentPage);
let _this = this;
setTimeout(() => {
_this.dragging = _this.invisible = false;
}, 100)
window.onresize=()=>{
_this.setPage(_this.currentPage)
}
})
},
methods: {
next() {
var page = this.currentPage;
if (page < this.slideEls.length) {
page++;
this.setPage(page);
} else {
this._revert();
}
},
prev() {
var page = this.currentPage;
if (page > 1) {
page--;
this.setPage(page);
} else {
this._revert();
}
},
setPage(page) {
this.lastPage = this.currentPage;
this.currentPage = page;
this.translateX = -[].reduce.call(this.slideEls, function (total, el, i) {
//previousValue,currentValue,currentIndex
return i > page - 2 ? total : total + el['clientWidth'];
}, 0);
this._onTransitionStart();
},
_onTouchStart(e) {
this.startPos = this._getTouchPos(e);
this.startYPos = this._getTouchYPos(e);
this.delta = 0;
this.startTranslateX = this.translateX;
this.startTime = new Date().getTime();
this.dragging = true;
document.addEventListener('touchmove', this._onTouchMove, false);
document.addEventListener('touchend', this._onTouchEnd, false);
},
_onTouchMove(e) {
this.delta = this._getTouchPos(e) - this.startPos;
this.deltaY = Math.abs(this._getTouchYPos(e) - this.startYPos);
switch (this.judge) {
case JUDGE_INITIAL:
// if (Math.abs(this.delta) > 20 && this.deltaY<25) {//judge to allow/prevent scroll
if (Math.abs(this.delta) / this.deltaY > 1.5) {//judge to allow/prevent scroll
this.judge = JUDGE_SLIDEING
e.preventDefault();
e.stopPropagation()
} else {
this.judge = JUDGE_SCROLLING
}
break;
case JUDGE_SCROLLING:
break;
case JUDGE_SLIDEING:
e.preventDefault();
e.stopPropagation()
this.translateX = this.startTranslateX + this.delta;
break;
default:
break;
}
},
_onTouchEnd(e) {
this.dragging = false;
if (this.judge == JUDGE_SLIDEING) {
var isQuickAction = new Date().getTime() - this.startTime < 1000;
if (this.delta < -100 || (isQuickAction && this.delta < -15 && this.deltaY / this.delta > -6)) {
this.next();
} else if (this.delta > 100 || (isQuickAction && this.delta > 15 && this.deltaY / this.delta < 6)) {
this.prev();
} else {
this._revert();
}
}
this.judge = JUDGE_INITIAL
document.removeEventListener('touchmove', this._onTouchMove);
document.removeEventListener('touchend', this._onTouchEnd);
},
_revert() {
this.setPage(this.currentPage);
},
_getTouchPos(e) {
var key = 'pageX';
return e.changedTouches ? e.changedTouches[0][key] : e[key];
},
_getTouchYPos(e) {
var key = 'pageY';
return e.changedTouches ? e.changedTouches[0][key] : e[key];
},
_onTransitionStart() {
this.transitioning = true;
if (this._isPageChanged()) {
this.$emit('tab-change-start', this.currentPage);
//FIX:remove the height of the hidden tab-items
[].forEach.call(this.slideEls,(item,index)=>{
if (index== (this.currentPage-1)) {
removeClass(item,'hide-height')
}
else {
addClass(item,'hide-height')
}
})
} else {
this.$emit('tab-revert-start', this.currentPage);
}
},
_onTransitionEnd(e) {
e.stopPropagation()
if (e.target.className != 'tabswiper-wrap') return;
this.transitioning = false;
if (this._isPageChanged()) {
this.$emit('tab-change-end', this.currentPage);
} else {
this.$emit('tab-revert-end', this.currentPage);
}
},
_isPageChanged() {
return this.lastPage !== this.currentPage;
}
}
});
You could use a computed property.
computed: {
//however you want to call it
style() {
return {transform : 'translate3d(' + this.translateX + 'px, 0, 0)'}
}
}
To use it just change your binding to :style="this.style"
Using the following script I am not able to swift and set the focus for an array back in the list when clicking PREV.
It should work as this example:
http://jsfiddle.net/QAsQj/2/
my code here
http://jsfiddle.net/Eq4js/
Could you point me out what am I doing wrong here, I would appreciate a sample of code on
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
.focus { color: red; }
</style>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.6.1.min.js"></script>
<script>
$(document).ready(function() {
var snippet = {
index: 0,
indexNew: 0,
start: 0,
$el: 'div.snippet-categories',
config: {
itemsVisible: 4
},
data: {
items: {
models: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}
},
navigate: function(direction) {
if (direction === 'right') {
if (this.index < this.config.itemsVisible - 1) {
if (this.index < this.config.itemsVisible - 1) {
this.index++;
var result = '#' + this.index + '';
$('li.focus').removeClass('focus');
$(result).addClass('focus');
} else {
this.start++;
}
} else {
if (this.start < this.data.items.models.length - this.config.itemsVisible) {
this.start++;
this.renderItems();
var result = '#' + (this.config.itemsVisible - 1 + this.start) + '';
$('li.focus').removeClass('focus');
$(result).addClass('focus');
}
}
}
else if (direction === 'left') {
if (this.index > this.config.itemsVisible - 1) {
if (this.index > this.config.itemsVisible - 1) {
this.index--;
(Focus.to(this.getFocusable(-1, true)));
} else {
this.start++;
}
} else {
if (this.start > this.data.items.models.length - this.config.itemsVisible) {
this.index--;
this.renderItems();
} else {
}
}
}
},
render: function() {
this.renderItems();
},
renderItems: function(reverse) {
var reverse = reverse || false;
var html = '', result = '', subset = null;
var range = this.data.items.models;
var limit = range.length - this.config.itemsVisible;
if (this.indexNew !== null) {
if (reverse === false) {
} else {
}
subset = range.slice(this.start, this.start + this.config.itemsVisible);
var i = 0;
while (i < subset.length) {
var x = subset[i];
result += '<li id="' + this.data.items.models[x] + '" data-idx="' + this.data.items.models[x] + '" class="focusable">' + this.data.items.models[x] + '</li>';
i++;
}
html = result + '</ul>';
var el = $(this.$el);
el.empty();
el.append(html);
} else {
console.log('limit STOP');
}
},
};
snippet.render();
$('#next').click(function() {
snippet.navigate("right");
});
$('#prev').click(function() {
snippet.navigate("left");
});
});
</script>
</head>
<body>
<div class="snippet-categories"></div>
<div id="prev">prev</div>
<div id="next">next</div>
</body>
</html>
This question is related to
Are you able to solve it? JavaScript carousel implementation using an array
Finally I solved it
Algo example here
http://jsfiddle.net/QwATR/
Snippet_Categories = (function(Snippet) {
var Snippet_Categories = function() {
this.config = {
curPos: 0, // index for selected element
itemVisible: 4, // number of items visible
minIndex: 0, // define visible area start
maxIndex: 4 - 1, // define visible area end = "itemVisible -1"
outItems: 0 // number of element out of visible area
};
this.data = {
items: arguments[1].items
};
this.construct.apply(this, arguments);
};
$.extend(true, Snippet_Categories.prototype, Snippet.prototype, {
init: function() {
this.index = 0; // set default index
this.indexNew = 0; // set next index
this.start = 0;
this.render();
},
create: function() {
return this.parent.$el.find('.snippet-categories');
},
removeFocus: function() {
var test = $('li.focus');
Focus.blur(test);
//$('li.focus').removeClass('focus');
},
focus: function() {
//$('ul > li:eq(' + this.config.curPos + ')').addClass('focus');
var test = $('ul > li:eq(' + this.config.curPos + ')');
return Focus.to(test, true);
},
render: function() {
//debugger
this.renderItems();
this.focus();
},
renderItems: function() {
var html = '<ul>';
for (var i = 0; i < this.config.itemVisible; i++) {
html += '<li data-idx="' + this.data.items.at(i + this.config.outItems).get('id') + '" class="">' + this.data.items.at(i + this.config.outItems).get('label') + '</li>';
}
html += '</ul>';
$('.snippet-categories').empty();
$('.snippet-categories').html(html);
},
navigate: function(direction) {
if (direction === 'right') {
if (this.config.curPos < this.config.maxIndex)
{
this.removeFocus();
if (this.config.curPos < this.config.maxIndex)
this.config.curPos++;
else
{
this.config.outItems++;
}
} else {
if (this.config.outItems < this.data.items.length - this.config.itemVisible)
this.config.outItems++;
}
this.renderItems();
this.focus();
}
else if (direction === 'left') {
if (this.config.curPos > this.config.minIndex)
{
this.removeFocus();
if (this.config.curPos > this.config.minIndex)
this.config.curPos--;
else
{
this.config.clicks--;
}
} else {
if (this.config.outItems > 0)
this.config.outItems--;
}
this.renderItems();
this.focus();
}
},
onFocus: function() {
//this.index = parseInt(Focus.focused[0].dataset.idx, 10);
console.log('element in focus ' + this.index);
}
});
return Snippet_Categories;
})(Snippet);
I am using the following JS code from the fiddle provided in the answer here:
How to display messages from jQuery Validate plugin inside of Tooltipster tooltips?
Here's the fiddle: http://jsfiddle.net/kyK4G/
The error shows up on line 36, which is: submitHandler: function (form) { // for demo
And this is the error:
TypeError: $(...).validate is not a function
submitHandler: function (form) { // for demo
Code:
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
$(document).ready(function () {
// initialize tooltipster on text input elements
$('#myform input[type="text"]').tooltipster({
trigger: 'custom',
onlyOne: false,
position: 'right'
});
// initialize validate plugin on the form
$('#myform').validate({
errorPlacement: function (error, element) {
$(element).tooltipster('update', $(error).text());
$(element).tooltipster('show');
},
success: function (label, element) {
$(element).tooltipster('hide');
},
rules: {
field1: {
required: true,
email: true
},
field2: {
required: true,
minlength: 5
}
},
submitHandler: function (form) { // for demo
alert('valid form');
return false;
}
});
});
// no CDN - including plugin below
(function (d, f, g, b) {
var e = "tooltipster",
c = {
animation: "fade",
arrow: true,
arrowColor: "",
content: "",
delay: 200,
fixedWidth: 0,
maxWidth: 0,
functionBefore: function (l, m) {
m()
},
functionReady: function (l, m) {},
functionAfter: function (l) {},
icon: "(?)",
iconDesktop: false,
iconTouch: false,
iconTheme: ".tooltipster-icon",
interactive: false,
interactiveTolerance: 350,
offsetX: 0,
offsetY: 0,
onlyOne: true,
position: "top",
speed: 350,
timer: 0,
theme: ".tooltipster-default",
touchDevices: true,
trigger: "hover"
};
function h(m, l) {
this.element = m;
this.options = d.extend({}, c, l);
this._defaults = c;
this._name = e;
this.init()
}
function j() {
return !!("ontouchstart" in f)
}
function a() {
var l = g.body || g.documentElement;
var n = l.style;
var o = "transition";
if (typeof n[o] == "string") {
return true
}
v = ["Moz", "Webkit", "Khtml", "O", "ms"], o = o.charAt(0).toUpperCase() + o.substr(1);
for (var m = 0; m < v.length; m++) {
if (typeof n[v[m] + o] == "string") {
return true
}
}
return false
}
var k = true;
if (!a()) {
k = false
}
h.prototype = {
init: function () {
var r = d(this.element);
var n = this;
var q = true;
if ((n.options.touchDevices == false) && (j())) {
q = false
}
if (g.all && !g.querySelector) {
q = false
}
if (q == true) {
if ((this.options.iconDesktop == true) && (!j()) || ((this.options.iconTouch == true) && (j()))) {
var m = r.attr("title");
r.removeAttr("title");
var p = n.options.iconTheme;
var o = d('<span class="' + p.replace(".", "") + '" title="' + m + '">' + this.options.icon + "</span>");
o.insertAfter(r);
r.data("tooltipsterIcon", o);
r = o
}
var l = d.trim(n.options.content).length > 0 ? n.options.content : r.attr("title");
r.data("tooltipsterContent", l);
r.removeAttr("title");
if ((this.options.touchDevices == true) && (j())) {
r.bind("touchstart", function (t, s) {
n.showTooltip()
})
} else {
if (this.options.trigger == "hover") {
r.on("mouseenter.tooltipster", function () {
n.showTooltip()
});
if (this.options.interactive == true) {
r.on("mouseleave.tooltipster", function () {
var t = r.data("tooltipster");
var u = false;
if ((t !== b) && (t !== "")) {
t.mouseenter(function () {
u = true
});
t.mouseleave(function () {
u = false
});
var s = setTimeout(function () {
if (u == true) {
t.mouseleave(function () {
n.hideTooltip()
})
} else {
n.hideTooltip()
}
}, n.options.interactiveTolerance)
} else {
n.hideTooltip()
}
})
} else {
r.on("mouseleave.tooltipster", function () {
n.hideTooltip()
})
}
}
if (this.options.trigger == "click") {
r.on("click.tooltipster", function () {
if ((r.data("tooltipster") == "") || (r.data("tooltipster") == b)) {
n.showTooltip()
} else {
n.hideTooltip()
}
})
}
}
}
},
showTooltip: function (m) {
var n = d(this.element);
var l = this;
if (n.data("tooltipsterIcon") !== b) {
n = n.data("tooltipsterIcon")
}
if ((d(".tooltipster-base").not(".tooltipster-dying").length > 0) && (l.options.onlyOne == true)) {
d(".tooltipster-base").not(".tooltipster-dying").not(n.data("tooltipster")).each(function () {
d(this).addClass("tooltipster-kill");
var o = d(this).data("origin");
o.data("plugin_tooltipster").hideTooltip()
})
}
n.clearQueue().delay(l.options.delay).queue(function () {
l.options.functionBefore(n, function () {
if ((n.data("tooltipster") !== b) && (n.data("tooltipster") !== "")) {
var w = n.data("tooltipster");
if (!w.hasClass("tooltipster-kill")) {
var s = "tooltipster-" + l.options.animation;
w.removeClass("tooltipster-dying");
if (k == true) {
w.clearQueue().addClass(s + "-show")
}
if (l.options.timer > 0) {
var q = w.data("tooltipsterTimer");
clearTimeout(q);
q = setTimeout(function () {
w.data("tooltipsterTimer", b);
l.hideTooltip()
}, l.options.timer);
w.data("tooltipsterTimer", q)
}
if ((l.options.touchDevices == true) && (j())) {
d("body").bind("touchstart", function (B) {
if (l.options.interactive == true) {
var D = d(B.target);
var C = true;
D.parents().each(function () {
if (d(this).hasClass("tooltipster-base")) {
C = false
}
});
if (C == true) {
l.hideTooltip();
d("body").unbind("touchstart")
}
} else {
l.hideTooltip();
d("body").unbind("touchstart")
}
})
}
}
} else {
d("body").css("overflow-x", "hidden");
var x = n.data("tooltipsterContent");
var u = l.options.theme;
var y = u.replace(".", "");
var s = "tooltipster-" + l.options.animation;
var r = "-webkit-transition-duration: " + l.options.speed + "ms; -webkit-animation-duration: " + l.options.speed + "ms; -moz-transition-duration: " + l.options.speed + "ms; -moz-animation-duration: " + l.options.speed + "ms; -o-transition-duration: " + l.options.speed + "ms; -o-animation-duration: " + l.options.speed + "ms; -ms-transition-duration: " + l.options.speed + "ms; -ms-animation-duration: " + l.options.speed + "ms; transition-duration: " + l.options.speed + "ms; animation-duration: " + l.options.speed + "ms;";
var o = l.options.fixedWidth > 0 ? "width:" + l.options.fixedWidth + "px;" : "";
var z = l.options.maxWidth > 0 ? "max-width:" + l.options.maxWidth + "px;" : "";
var t = l.options.interactive == true ? "pointer-events: auto;" : "";
var w = d('<div class="tooltipster-base ' + y + " " + s + '" style="' + o + " " + z + " " + t + " " + r + '"><div class="tooltipster-content">' + x + "</div></div>");
w.appendTo("body");
n.data("tooltipster", w);
w.data("origin", n);
l.positionTooltip();
l.options.functionReady(n, w);
if (k == true) {
w.addClass(s + "-show")
} else {
w.css("display", "none").removeClass(s).fadeIn(l.options.speed)
}
var A = x;
var p = setInterval(function () {
var B = n.data("tooltipsterContent");
if (d("body").find(n).length == 0) {
w.addClass("tooltipster-dying");
l.hideTooltip()
} else {
if ((A !== B) && (B !== "")) {
A = B;
w.find(".tooltipster-content").html(B);
w.css({
width: "",
"-webkit-transition-duration": l.options.speed + "ms",
"-moz-transition-duration": l.options.speed + "ms",
"-o-transition-duration": l.options.speed + "ms",
"-ms-transition-duration": l.options.speed + "ms",
"transition-duration": l.options.speed + "ms",
"-webkit-transition-property": "-webkit-transform",
"-moz-transition-property": "-moz-transform",
"-o-transition-property": "-o-transform",
"-ms-transition-property": "-ms-transform",
"transition-property": "transform"
}).addClass("tooltipster-content-changing");
setTimeout(function () {
w.removeClass("tooltipster-content-changing");
setTimeout(function () {
w.css({
"-webkit-transition-property": "",
"-moz-transition-property": "",
"-o-transition-property": "",
"-ms-transition-property": "",
"transition-property": ""
})
}, l.options.speed)
}, l.options.speed);
tooltipWidth = w.outerWidth(false);
tooltipInnerWidth = w.innerWidth();
tooltipHeight = w.outerHeight(false);
l.positionTooltip()
}
}
if ((d("body").find(w).length == 0) || (d("body").find(n).length == 0)) {
clearInterval(p)
}
}, 200);
if (l.options.timer > 0) {
var q = setTimeout(function () {
w.data("tooltipsterTimer", b);
l.hideTooltip()
}, l.options.timer + l.options.speed);
w.data("tooltipsterTimer", q)
}
if ((l.options.touchDevices == true) && (j())) {
d("body").bind("touchstart", function (B) {
if (l.options.interactive == true) {
var D = d(B.target);
var C = true;
D.parents().each(function () {
if (d(this).hasClass("tooltipster-base")) {
C = false
}
});
if (C == true) {
l.hideTooltip();
d("body").unbind("touchstart")
}
} else {
l.hideTooltip();
d("body").unbind("touchstart")
}
})
}
w.mouseleave(function () {
l.hideTooltip()
})
}
});
n.dequeue()
})
},
hideTooltip: function (m) {
var p = d(this.element);
var l = this;
if (p.data("tooltipsterIcon") !== b) {
p = p.data("tooltipsterIcon")
}
var o = p.data("tooltipster");
if (o == b) {
o = d(".tooltipster-dying")
}
p.clearQueue();
if ((o !== b) && (o !== "")) {
var q = o.data("tooltipsterTimer");
if (q !== b) {
clearTimeout(q)
}
var n = "tooltipster-" + l.options.animation;
if (k == true) {
o.clearQueue().removeClass(n + "-show").addClass("tooltipster-dying").delay(l.options.speed).queue(function () {
o.remove();
p.data("tooltipster", "");
d("body").css("verflow-x", "");
l.options.functionAfter(p)
})
} else {
o.clearQueue().addClass("tooltipster-dying").fadeOut(l.options.speed, function () {
o.remove();
p.data("tooltipster", "");
d("body").css("verflow-x", "");
l.options.functionAfter(p)
})
}
}
},
positionTooltip: function (O) {
var A = d(this.element);
var ab = this;
if (A.data("tooltipsterIcon") !== b) {
A = A.data("tooltipsterIcon")
}
if ((A.data("tooltipster") !== b) && (A.data("tooltipster") !== "")) {
var ah = A.data("tooltipster");
ah.css("width", "");
var ai = d(f).width();
var B = A.outerWidth(false);
var ag = A.outerHeight(false);
var al = ah.outerWidth(false);
var m = ah.innerWidth() + 1;
var M = ah.outerHeight(false);
var aa = A.offset();
var Z = aa.top;
var u = aa.left;
var y = b;
if (A.is("area")) {
var T = A.attr("shape");
var af = A.parent().attr("name");
var P = d('img[usemap="#' + af + '"]');
var n = P.offset().left;
var L = P.offset().top;
var W = A.attr("coords") !== b ? A.attr("coords").split(",") : b;
if (T == "circle") {
var N = parseInt(W[0]);
var r = parseInt(W[1]);
var D = parseInt(W[2]);
ag = D * 2;
B = D * 2;
Z = L + r - D;
u = n + N - D
} else {
if (T == "rect") {
var N = parseInt(W[0]);
var r = parseInt(W[1]);
var q = parseInt(W[2]);
var J = parseInt(W[3]);
ag = J - r;
B = q - N;
Z = L + r;
u = n + N
} else {
if (T == "poly") {
var x = [];
var ae = [];
var H = 0,
G = 0,
ad = 0,
ac = 0;
var aj = "even";
for (i = 0; i < W.length; i++) {
var F = parseInt(W[i]);
if (aj == "even") {
if (F > ad) {
ad = F;
if (i == 0) {
H = ad
}
}
if (F < H) {
H = F
}
aj = "odd"
} else {
if (F > ac) {
ac = F;
if (i == 1) {
G = ac
}
}
if (F < G) {
G = F
}
aj = "even"
}
}
ag = ac - G;
B = ad - H;
Z = L + G;
u = n + H
} else {
ag = P.outerHeight(false);
B = P.outerWidth(false);
Z = L;
u = n
}
}
}
}
if (ab.options.fixedWidth == 0) {
ah.css({
width: m + "px",
"padding-left": "0px",
"padding-right": "0px"
})
}
var s = 0,
V = 0;
var X = parseInt(ab.options.offsetY);
var Y = parseInt(ab.options.offsetX);
var p = "";
function w() {
var an = d(f).scrollLeft();
if ((s - an) < 0) {
var am = s - an;
s = an;
ah.data("arrow-reposition", am)
}
if (((s + al) - an) > ai) {
var am = s - ((ai + an) - al);
s = (ai + an) - al;
ah.data("arrow-reposition", am)
}
}
function t(an, am) {
if (((Z - d(f).scrollTop() - M - X - 12) < 0) && (am.indexOf("top") > -1)) {
ab.options.position = an;
y = am
}
if (((Z + ag + M + 12 + X) > (d(f).scrollTop() + d(f).height())) && (am.indexOf("bottom") > -1)) {
ab.options.position = an;
y = am;
V = (Z - M) - X - 12
}
}
if (ab.options.position == "top") {
var Q = (u + al) - (u + B);
s = (u + Y) - (Q / 2);
V = (Z - M) - X - 12;
w();
t("bottom", "top")
}
if (ab.options.position == "top-left") {
s = u + Y;
V = (Z - M) - X - 12;
w();
t("bottom-left", "top-left")
}
if (ab.options.position == "top-right") {
s = (u + B + Y) - al;
V = (Z - M) - X - 12;
w();
t("bottom-right", "top-right")
}
if (ab.options.position == "bottom") {
var Q = (u + al) - (u + B);
s = u - (Q / 2) + Y;
V = (Z + ag) + X + 12;
w();
t("top", "bottom")
}
if (ab.options.position == "bottom-left") {
s = u + Y;
V = (Z + ag) + X + 12;
w();
t("top-left", "bottom-left")
}
if (ab.options.position == "bottom-right") {
s = (u + B + Y) - al;
V = (Z + ag) + X + 12;
w();
t("top-right", "bottom-right")
}
if (ab.options.position == "left") {
s = u - Y - al - 12;
myLeftMirror = u + Y + B + 12;
var K = (Z + M) - (Z + A.outerHeight(false));
V = Z - (K / 2) - X;
if ((s < 0) && ((myLeftMirror + al) > ai)) {
var o = parseFloat(ah.css("border-width")) * 2;
var l = (al + s) - o;
ah.css("width", l + "px");
M = ah.outerHeight(false);
s = u - Y - l - 12 - o;
K = (Z + M) - (Z + A.outerHeight(false));
V = Z - (K / 2) - X
} else {
if (s < 0) {
s = u + Y + B + 12;
ah.data("arrow-reposition", "left")
}
}
}
if (ab.options.position == "right") {
s = u + Y + B + 12;
myLeftMirror = u - Y - al - 12;
var K = (Z + M) - (Z + A.outerHeight(false));
V = Z - (K / 2) - X;
if (((s + al) > ai) && (myLeftMirror < 0)) {
var o = parseFloat(ah.css("border-width")) * 2;
var l = (ai - s) - o;
ah.css("width", l + "px");
M = ah.outerHeight(false);
K = (Z + M) - (Z + A.outerHeight(false));
V = Z - (K / 2) - X
} else {
if ((s + al) > ai) {
s = u - Y - al - 12;
ah.data("arrow-reposition", "right")
}
}
}
if (ab.options.arrow == true) {
var I = "tooltipster-arrow-" + ab.options.position;
if (ab.options.arrowColor.length < 1) {
var R = ah.css("background-color")
} else {
var R = ab.options.arrowColor
}
It sounds like you don't have the validate plugin script on the page:
http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js
It looks like you are not including the jQuery plugin that provides the .validate() method. You should include it after jQuery:
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"><script>
Generally, if you have an object, you can try and access different attributes using dot notation as follows:
var myAwesomeObject = {
coolProperty: "whooooa!"
, coolMethod: function() {return this;}
};
myAwesomeObject.coolProperty; // "whooooa!"
myAwesomeObject.coolMethod; // function(){return this;}
If the property happens to be a method, you can call it like:
myAwesomeObject.coolMethod(); // Object {coolProperty: ...
If the property you are trying to access doesn't exist on the object, you will get back undefined
myAwesomeObject.missingProperty; // undefined
Since undefined is not a function, trying to call a missing property as a method will result in the error you saw:
myAwesomeObject.missingMethod(); // TypeError: you messed up.
I also got this problem. I have fixed this problem other way. That I got in the documentation
To fix the problem you have to declared a specific class.
Using the
mfp-TYPE CSS class (where TYPE is the desired content type). For example: <a class="mfp-image image-link">Open image</a>, $('.image-link').magnificPopup().
Another Example: <a class="mfp-iframe video-link">Open Video</a>, $('.video-link').magnificPopup().