Change the rangeslider's starting point videojs - javascript

I am using videojs in my react application. I have added rangeslider to it. There is a button near my video player which triggers the rangeslider to show up on the video player. Every thing works fine, but the rangeslider's start arrow is not at the point (time) where I clicked the button. The starting button is always at time 0:0. What I want is: say the video is playing at the current time 30:00 seconds and I clicked the show button, then rangeslider should show it's starting arrow at 30 sec only and not at o sec. I can get my current time of videojs player and pass it to rangeslider.js plugin, but I don't know where to pass it.
This is my rangeslider.js (I know it's a long code but i don't know which part of it to use to achieve the result)
//----------------Load Plugin----------------//
(function () {
var videojsAddClass = function (element, className) {
element.classList.add(className);
};
var videojsRemoveClass = function (element, className) {
element.classList.remove(className);
};
var videojsFindPosition = function (element) {
return element.getBoundingClientRect();
};
var videojsRound = function (n, precision) {
return parseFloat(n.toFixed(precision));
};
var videojsFormatTime = function (totalSeconds) {
var minutes = Math.floor(totalSeconds / 60).toFixed(0);
var seconds = (totalSeconds % 60).toFixed(0);
if (seconds.length === 1) {
seconds = "0" + seconds;
}
return minutes + ':' + seconds;
};
var videojsBlockTextSelection = function () {
// TODO
};
//-- Load RangeSlider plugin in videojs
function RangeSlider_(options) {
var player = this;
player.rangeslider = new RangeSlider(player, options);
//When the DOM and the video media is loaded
function initialVideoFinished(event) {
var plugin = player.rangeslider;
//All components will be initialize after they have been loaded by videojs
for (var index in plugin.components) {
plugin.components[index].init_();
}
if (plugin.options.hidden)
plugin.hide(); //Hide the Range Slider
if (plugin.options.locked)
plugin.lock(); //Lock the Range Slider
if (plugin.options.panel == false)
plugin.hidePanel(); //Hide the second Panel
if (plugin.options.controlTime == false)
plugin.hidecontrolTime(); //Hide the control time panel
plugin._reset();
player.trigger('loadedRangeSlider'); //Let know if the Range Slider DOM is ready
}
if (player.techName == 'Youtube') {
//Detect youtube problems
player.one('error', function (e) {
switch (player.error) {
case 2:
alert("The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.");
case 5:
alert("The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.");
case 100:
alert("The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.");
break;
case 101:
alert("The owner of the requested video does not allow it to be played in embedded players.");
break;
case 150:
alert("The owner of the requested video does not allow it to be played in embedded players.");
break;
default:
alert("Unknown Error");
break;
}
});
player.on('firstplay', initialVideoFinished);
} else {
player.one('playing', initialVideoFinished);
}
}
videojs.plugin('rangeslider', RangeSlider_);
//-- Plugin
function RangeSlider(player, options) {
var player = player || this;
this.player = player;
this.components = {}; // holds any custom components we add to the player
options = options || {}; // plugin options
if (!options.hasOwnProperty('locked'))
options.locked = false; // lock slider handles
if (!options.hasOwnProperty('hidden'))
options.hidden = true; // hide slider handles
if (!options.hasOwnProperty('panel'))
options.panel = true; // Show Second Panel
if (!options.hasOwnProperty('controlTime'))
options.controlTime = true; // Show Control Time to set the arrows in the edition
this.options = options;
this.init();
}
//-- Methods
RangeSlider.prototype = {
/*Constructor*/
init: function () {
var player = this.player || {};
this.updatePrecision = 3;
//position in second of the arrows
this.start = 0;
this.end = 0;
//components of the plugin
var controlBar = player.controlBar;
var seekBar = controlBar.progressControl.seekBar;
this.components.RSTimeBar = seekBar.RSTimeBar;
this.components.ControlTimePanel = controlBar.ControlTimePanel;
//Save local component
this.rstb = this.components.RSTimeBar;
this.box = this.components.SeekRSBar = this.rstb.SeekRSBar;
this.bar = this.components.SelectionBar = this.box.SelectionBar;
this.left = this.components.SelectionBarLeft = this.box.SelectionBarLeft;
this.right = this.components.SelectionBarRight = this.box.SelectionBarRight;
this.tp = this.components.TimePanel = this.box.TimePanel;
this.tpl = this.components.TimePanelLeft = this.tp.TimePanelLeft;
this.tpr = this.components.TimePanelRight = this.tp.TimePanelRight;
this.ctp = this.components.ControlTimePanel;
this.ctpl = this.components.ControlTimePanelLeft = this.ctp.ControlTimePanelLeft;
this.ctpr = this.components.ControlTimePanelRight = this.ctp.ControlTimePanelRight;
},
show: function () {
this.options.hidden = false;
if (typeof this.rstb != 'undefined') {
this.rstb.show();
if (this.options.controlTime)
this.showcontrolTime();
}
},
hide: function () {
this.options.hidden = true;
if (typeof this.rstb != 'undefined') {
this.rstb.hide();
this.ctp.hide();
}
},
showPanel: function () {
this.options.panel = true;
if (typeof this.tp != 'undefined')
videojsRemoveClass(this.tp.el_, 'disable');
},
showcontrolTime: function () {
this.options.controlTime = true;
if (typeof this.ctp != 'undefined')
this.ctp.show();
},
hidecontrolTime: function () {
this.options.controlTime = false;
if (typeof this.ctp != 'undefined')
this.ctp.hide();
},
setValue: function (index, seconds, writeControlTime) {
//index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds
var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
var percent = this._percent(seconds);
var isValidIndex = (index === 0 || index === 1);
var isChangeable = !this.locked;
if (isChangeable && isValidIndex)
this.box.setPosition(index, percent, writeControlTime);
},
setValues: function (start, end, writeControlTime) {
//index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds
var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
this._reset();
this._setValuesLocked(start, end, writeControlTime);
},
getValues: function () { //get values in seconds
var values = {}, start, end;
start = this.start || this._getArrowValue(0);
end = this.end || this._getArrowValue(1);
return {start: start, end: end};
},
_getArrowValue: function (index) {
var index = index || 0;
var duration = this.player.duration();
duration = typeof duration == 'undefined' ? 0 : duration;
var percentage = this[index === 0 ? "left" : "right"].el_.style.left.replace("%", "");
if (percentage == "")
percentage = index === 0 ? 0 : 100;
return videojsRound(this._seconds(percentage / 100), this.updatePrecision - 1);
},
_percent: function (seconds) {
var duration = this.player.duration();
if (isNaN(duration)) {
return 0;
}
return Math.min(1, Math.max(0, seconds / duration));
},
_seconds: function (percent) {
var duration = this.player.duration();
if (isNaN(duration)) {
return 0;
}
return Math.min(duration, Math.max(0, percent * duration));
},
_reset: function () {
var duration = this.player.duration();
this.tpl.el_.style.left = '0%';
this.tpr.el_.style.left = '100%';
this._setValuesLocked(0, duration);
},
_setValuesLocked: function (start, end, writeControlTime) {
var triggerSliderChange = typeof writeControlTime != 'undefined';
var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
if (this.options.locked) {
this.unlock();//It is unlocked to change the bar position. In the end it will return the value.
this.setValue(0, start, writeControlTime);
this.setValue(1, end, writeControlTime);
this.lock();
} else {
this.setValue(0, start, writeControlTime);
this.setValue(1, end, writeControlTime);
}
// Trigger slider change
if (triggerSliderChange) {
this._triggerSliderChange();
}
},
_checkControlTime: function (index, TextInput, timeOld) {
var h = TextInput[0],
m = TextInput[1],
s = TextInput[2],
newHour = h.value,
newMin = m.value,
newSec = s.value,
obj, objNew, objOld;
index = index || 0;
if (newHour != timeOld[0]) {
obj = h;
objNew = newHour;
objOld = timeOld[0];
} else if (newMin != timeOld[1]) {
obj = m;
objNew = newMin;
objOld = timeOld[1];
} else if (newSec != timeOld[2]) {
obj = s;
objNew = newSec;
objOld = timeOld[2];
} else {
return false;
}
var duration = this.player.duration() || 0,
durationSel;
var intRegex = /^\d+$/;//check if the objNew is an integer
if (!intRegex.test(objNew) || objNew > 60) {
objNew = objNew == "" ? "" : objOld;
}
newHour = newHour == "" ? 0 : newHour;
newMin = newMin == "" ? 0 : newMin;
newSec = newSec == "" ? 0 : newSec;
durationSel = videojs.TextTrack.prototype.parseCueTime(newHour + ":" + newMin + ":" + newSec);
if (durationSel > duration) {
obj.value = objOld;
obj.style.border = "1px solid red";
} else {
obj.value = objNew;
h.style.border = m.style.border = s.style.border = "1px solid transparent";
this.setValue(index, durationSel, false);
// Trigger slider change
this._triggerSliderChange();
}
if (index === 1) {
var oldTimeLeft = this.ctpl.el_.children,
durationSelLeft = videojs.TextTrack.prototype.parseCueTime(oldTimeLeft[0].value + ":" + oldTimeLeft[1].value + ":" + oldTimeLeft[2].value);
if (durationSel < durationSelLeft) {
obj.style.border = "1px solid red";
}
} else {
var oldTimeRight = this.ctpr.el_.children,
durationSelRight = videojs.TextTrack.prototype.parseCueTime(oldTimeRight[0].value + ":" + oldTimeRight[1].value + ":" + oldTimeRight[2].value);
if (durationSel > durationSelRight) {
obj.style.border = "1px solid red";
}
}
},
_triggerSliderChange: function () {
this.player.trigger("sliderchange");
}
};
//----------------Public Functions----------------//
//-- Public Functions added to video-js
var videojsPlayer = videojs.getComponent('Player');
//Lock the Slider bar and it will not be possible to change the arrow positions
videojsPlayer.prototype.lockSlider = function () {
return this.rangeslider.lock();
};
//Unlock the Slider bar and it will be possible to change the arrow positions
videojsPlayer.prototype.unlockSlider = function () {
return this.rangeslider.unlock();
};
//Show the Slider Bar Component
videojsPlayer.prototype.showSlider = function () {
return this.rangeslider.show();
};
//Hide the Slider Bar Component
videojsPlayer.prototype.hideSlider = function () {
return this.rangeslider.hide();
};
//Show the Panel with the seconds of the selection
videojsPlayer.prototype.showSliderPanel = function () {
return this.rangeslider.showPanel();
};
//Hide the Panel with the seconds of the selection
videojsPlayer.prototype.hideSliderPanel = function () {
return this.rangeslider.hidePanel();
};
//Show the control Time to edit the position of the arrows
videojsPlayer.prototype.showControlTime = function () {
return this.rangeslider.showcontrolTime();
};
//Hide the control Time to edit the position of the arrows
videojsPlayer.prototype.hideControlTime = function () {
return this.rangeslider.hidecontrolTime();
};
//Set a Value in second for both arrows
videojsPlayer.prototype.setValueSlider = function (start, end) {
return this.rangeslider.setValues(start, end);
};
//The video will be played in a selected section
videojsPlayer.prototype.playBetween = function (start, end) {
return this.rangeslider.playBetween(start, end);
};
//The video will loop between to values
videojsPlayer.prototype.loopBetween = function (start, end) {
return this.rangeslider.loop(start, end);
};
//Set a Value in second for the arrows
videojsPlayer.prototype.getValueSlider = function () {
return this.rangeslider.getValues();
};
//----------------Create new Components----------------//
//--Charge the new Component into videojs
var videojsSeekBar = videojs.getComponent('SeekBar');
videojsSeekBar.prototype.options_.children.push('RSTimeBar'); //Range Slider Time Bar
var videojsControlBar = videojs.getComponent('ControlBar');
videojsControlBar.prototype.options_.children.push('ControlTimePanel'); //Panel with the time of the range slider
//-- Design the new components
var videojsComponent = videojs.getComponent('Component');
/**
* Range Slider Time Bar
* #param {videojs.Player|Object} player
* #param {Object=} options
* #constructor
*/
var videojsRSTimeBar = videojs.extend(videojsComponent, {
/** #constructor */
constructor: function (player, options) {
videojsComponent.call(this, player, options);
}
});
videojsRSTimeBar.prototype.init_ = function () {
this.rs = this.player_.rangeslider;
};
videojsRSTimeBar.prototype.options_ = {
children: {
'SeekRSBar': {}
}
};
videojsRSTimeBar.prototype.createEl = function () {
return videojsComponent.prototype.createEl.call(this, 'div', {
className: 'vjs-timebar-RS',
innerHTML: ''
});
};
videojs.registerComponent('RSTimeBar', videojsRSTimeBar);
/**
* Seek Range Slider Bar and holder for the selection bars
* #param {videojs.Player|Object} player
* #param {Object=} options
* #constructor
*/
var videojsSeekRSBar = videojs.extend(videojsSeekBar, {
/** #constructor */
constructor: function (player, options) {
videojsComponent.call(this, player, options);
this.on('mousedown', this.onMouseDown);
this.on('touchstart', this.onMouseDown);
}
});
videojsSeekRSBar.prototype.init_ = function () {
this.rs = this.player_.rangeslider;
};
videojsSeekRSBar.prototype.options_ = {
children: {
'SelectionBar': {},
'SelectionBarLeft': {},
'SelectionBarRight': {},
'TimePanel': {},
}
};
videojsSeekRSBar.prototype.createEl = function () {
return videojsComponent.prototype.createEl.call(this, 'div', {
className: 'vjs-rangeslider-holder'
});
};
videojsSeekRSBar.prototype.onMouseDown = function (event) {
event.preventDefault();
videojsBlockTextSelection();
if (!this.rs.options.locked) {
this.on(document, "mousemove", videojs.bind(this, this.onMouseMove));
this.on(document, "mouseup", videojs.bind(this, this.onMouseUp));
this.on(document, "touchmove", videojs.bind(this, this.onMouseMove));
this.on(document, "touchend", videojs.bind(this, this.onMouseUp));
}
};
videojsSeekRSBar.prototype.onMouseUp = function (event) {
this.off(document, "mousemove", videojs.bind(this, this.onMouseMove), false);
this.off(document, "mouseup", videojs.bind(this, this.onMouseUp), false);
this.off(document, "touchmove", videojs.bind(this, this.onMouseMove), false);
this.off(document, "touchend", videojs.bind(this, this.onMouseUp), false);
};
videojsSeekRSBar.prototype.onMouseMove = function (event) {
var left = this.calculateDistance(event);
if (this.rs.left.pressed)
this.setPosition(0, left);
else if (this.rs.right.pressed)
this.setPosition(1, left);
//Fix a problem with the presition in the display time
var ctd = this.player_.controlBar.currentTimeDisplay;
ctd.contentEl_.innerHTML = '<span class="vjs-control-text">' + ctd.localize('Current Time') + '</span>' + videojsFormatTime(this.rs._seconds(left), this.player_.duration());
// Trigger slider change
if (this.rs.left.pressed || this.rs.right.pressed) {
this.rs._triggerSliderChange();
}
};
videojsSeekRSBar.prototype.setPosition = function (index, left, writeControlTime) {
var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
//index = 0 for left side, index = 1 for right side
var index = index || 0;
// Position shouldn't change when handle is locked
if (this.rs.options.locked)
return false;
// Check for invalid position
if (isNaN(left))
return false;
// Check index between 0 and 1
if (!(index === 0 || index === 1))
return false;
// Alias
var ObjLeft = this.rs.left.el_,
ObjRight = this.rs.right.el_,
Obj = this.rs[index === 0 ? 'left' : 'right'].el_,
tpr = this.rs.tpr.el_,
tpl = this.rs.tpl.el_,
bar = this.rs.bar,
ctp = this.rs[index === 0 ? 'ctpl' : 'ctpr'].el_;
//Check if left arrow is passing the right arrow
if ((index === 0 ? bar.updateLeft(left) : bar.updateRight(left))) {
Obj.style.left = (left * 100) + '%';
index === 0 ? bar.updateLeft(left) : bar.updateRight(left);
this.rs[index === 0 ? 'start' : 'end'] = this.rs._seconds(left);
//Fix the problem when you press the button and the two arrow are underhand
//left.zIndex = 10 and right.zIndex=20. This is always less in this case:
if (index === 0) {
if ((left) >= 0.9)
ObjLeft.style.zIndex = 25;
else
ObjLeft.style.zIndex = 10;
}
//-- Panel
var TimeText = videojsFormatTime(this.rs._seconds(left)),
tplTextLegth = tpl.children[0].innerHTML.length;
var MaxP, MinP, MaxDisP;
if (tplTextLegth <= 4) //0:00
MaxDisP = this.player_.isFullScreen ? 3.25 : 6.5;
else if (tplTextLegth <= 5)//00:00
MaxDisP = this.player_.isFullScreen ? 4 : 8;
else//0:00:00
MaxDisP = this.player_.isFullScreen ? 5 : 10;
if (TimeText.length <= 4) { //0:00
MaxP = this.player_.isFullScreen ? 97 : 93;
MinP = this.player_.isFullScreen ? 0.1 : 0.5;
} else if (TimeText.length <= 5) {//00:00
MaxP = this.player_.isFullScreen ? 96 : 92;
MinP = this.player_.isFullScreen ? 0.1 : 0.5;
} else {//0:00:00
MaxP = this.player_.isFullScreen ? 95 : 91;
MinP = this.player_.isFullScreen ? 0.1 : 0.5;
}
if (index === 0) {
tpl.style.left = Math.max(MinP, Math.min(MaxP, (left * 100 - MaxDisP / 2))) + '%';
if ((tpr.style.left.replace("%", "") - tpl.style.left.replace("%", "")) <= MaxDisP)
tpl.style.left = Math.max(MinP, Math.min(MaxP, tpr.style.left.replace("%", "") - MaxDisP)) + '%';
tpl.children[0].innerHTML = TimeText;
} else {
tpr.style.left = Math.max(MinP, Math.min(MaxP, (left * 100 - MaxDisP / 2))) + '%';
if (((tpr.style.left.replace("%", "") || 100) - tpl.style.left.replace("%", "")) <= MaxDisP)
tpr.style.left = Math.max(MinP, Math.min(MaxP, tpl.style.left.replace("%", "") - 0 + MaxDisP)) + '%';
tpr.children[0].innerHTML = TimeText;
}
//-- Control Time
if (writeControlTime) {
var time = TimeText.split(":"),
h, m, s;
if (time.length == 2) {
h = 0;
m = time[0];
s = time[1];
} else {
h = time[0];
m = time[1];
s = time[2];
}
ctp.children[0].value = h;
ctp.children[1].value = m;
ctp.children[2].value = s;
}
}
return true;
};
videojs.registerComponent('SeekRSBar', videojsSeekRSBar);
/**
* This is the bar with the selection of the RangeSlider
* #param {videojs.Player|Object} player
* #param {Object=} options
* #constructor
*/
var videojsSelectionBar = videojs.extend(videojsComponent, {
/** #constructor */
constructor: function (player, options) {
videojsComponent.call(this, player, options);
this.on('mouseup', this.onMouseUp);
this.on('touchend', this.onMouseUp);
this.fired = false;
}
});
videojsSelectionBar.prototype.init_ = function () {
this.rs = this.player_.rangeslider;
};
videojsSelectionBar.prototype.createEl = function () {
return videojsComponent.prototype.createEl.call(this, 'div', {
className: 'vjs-selectionbar-RS'
});
};
videojsControlTimePanelRight.prototype.init_ = function () {
this.rs = this.player_.rangeslider;
this.timeOld = {};
};
videojsControlTimePanelRight.prototype.createEl = function () {
return videojsComponent.prototype.createEl.call(this, 'div', {
className: 'vjs-controltimepanel-right-RS',
innerHTML: 'End: <input type="text" id="controltimepanel" maxlength="2" value="00"/>:<input type="text" id="controltimepanel" maxlength="2" value="00"/>:<input type="text" id="controltimepanel" maxlength="2" value="00"/>'
});
};
videojsControlTimePanelRight.prototype.onKeyDown = function (event) {
this.timeOld[0] = this.el_.children[0].value;
this.timeOld[1] = this.el_.children[1].value;
this.timeOld[2] = this.el_.children[2].value;
};
videojsControlTimePanelRight.prototype.onKeyUp = function (event) {
this.rs._checkControlTime(1, this.el_.children, this.timeOld);
};
videojs.registerComponent('ControlTimePanelRight', videojsControlTimePanelRight);
})();
And this is how rangeslider looks everytime it shows up

I use
video.currentTime
But it looks like rangeslider is using
e.currentPoint

Related

Block a JavaScript function in a page

I have a javascript function for a slider in the JS file of my site. When we are in a page where the slider is not called or there is no trigger element, it displays an error in the console "Uncaught TypeError: Cannot read properties of null (reading 'querySelector') ", This error is not displayed when the slider is in the page.
I would like to know how to avoid this error, and how to prevent this function from loading in pages where this slider is not present?
function slider(set) {
const sliderContainer = document.querySelector(set.name),
slider = sliderContainer.querySelector('.slider'),
sliderItem = slider.querySelectorAll('.slider__item'),
sliderArrows = sliderContainer.querySelectorAll('.arrows__item');
let dotsCreate,
dotsClass,
dotsFunk,
numberSlider,
numberSliderWork,
sliderExecutionLine,
sliderExecutionLineWork;
// calculate the maximum width of all slides
function forSliderItem(t) {
t = 0;
for(let i = 0; i < sliderItem.length - 1; i++) {
t += sliderItem[i].clientWidth;
}
return t;
}
let maxWidth = forSliderItem(sliderItem), // maximum width of all slides
slidWidth = 0, // main variable for calculating the movement of the slider
count = 0; // counter
//===== flip left
sliderArrows[0].addEventListener('click', function() {
if(count !== 0) {
count--;
slidWidth -= sliderItem[count].clientWidth;
slider.style.transform = `translateX(-${slidWidth}px)`;
} else {
count = sliderItem.length - 1;
slidWidth = maxWidth;
slider.style.transform = `translateX(-${slidWidth}px)`;
}
if(set.dots) {
dotsFunk();
}
if(set.numberSlid) {
numberSliderWork(count);
}
if(set.line) {
sliderExecutionLineWork(count);
}
});
//===== flip right
sliderArrows[1].addEventListener('click', function() {
if(count < sliderItem.length - 1) {
count++;
slidWidth += sliderItem[count].clientWidth;
slider.style.transform = `translateX(-${slidWidth}px)`;
} else {
count = 0;
slidWidth = 0;
slider.style.transform = `translateX(-${slidWidth}px)`;
}
if(set.dots) {
dotsFunk();
}
if(set.numberSlid) {
numberSliderWork(count);
}
if(set.line) {
sliderExecutionLineWork(count);
}
});
//===== dots
if(set.dots) {
dotsCreate = function() {
const dotContainer = document.createElement('div'); // create dots container
dotContainer.classList.add('dots');
// create the required number of dots and insert a container into the dots
sliderItem.forEach(() => {
let dotsItem = document.createElement('span');
dotContainer.append(dotsItem);
});
sliderContainer.append(dotContainer);
};
dotsCreate();
// add the class to the desired dots, and remove from the rest
dotsClass = function(remove, add) {
remove.classList.remove('dots_active');
add.classList.add('dots_active');
};
// move slides by clicking on the dot
dotsFunk = function() {
const dotsWork = sliderContainer.querySelectorAll('.dots span'); // we get dots
dotsWork.forEach((item, i) => {
dotsClass(dotsWork[i], dotsWork[count]);
item.addEventListener('click', function() {
count = i;
// multiply the slide size by the number of the dots, and get the number by which you need to move the slider
slidWidth = sliderItem[0].clientWidth * i;
slider.style.transform = `translateX(-${slidWidth}px)`;
for(let j = 0; j < dotsWork.length; j++) {
dotsClass(dotsWork[j], dotsWork[count]);
}
if(set.dots && set.numberSlid) {
numberSliderWork(count);
}
if(set.line) {
sliderExecutionLineWork(count);
}
});
});
};
dotsFunk();
}
//===== count slider
if(set.numberSlid) {
numberSlider = function(item) {
const countContainer = document.createElement('div'),
sliderNumber = document.createElement('span'),
slash = document.createElement('span'),
allSliderNumber = document.createElement('span');
casClient = document.createElement('p');
sliderNumber.innerHTML = item + 1;
casClient.innerHTML = 'Cas client N°';
slash.innerHTML = '/';
allSliderNumber.innerHTML = sliderItem.length;
countContainer.classList.add('count-slides');
countContainer.append(casClient, sliderNumber, slash, allSliderNumber);
sliderContainer.append(countContainer);
};
numberSlider(0);
numberSliderWork = function(item) {
const sliderNumberNow = sliderContainer.querySelector('.count-slides span');
sliderNumberNow.innerHTML = item + 1;
if(set.line) {
sliderExecutionLineWork(item);
}
};
}
}
slider({
name: ".video_users",
numberSlid: true
});
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Example of a page without the slider</title>
</head>
<body class="error_404">
<h1>Example of a page without the slider</h1>
<script src="media/js/faveod.js" async></script>
</body>
</html>
Just return if the element isn't present if you don't want it to show an error.
const sliderContainer = document.querySelector(set.name);
if (!sliderContainer) return;
const slider = sliderContainer.querySelector('.slider'),
sliderItem = slider.querySelectorAll('.slider__item'),
sliderArrows = sliderContainer.querySelectorAll('.arrows__item');
If you want it to only execute on certain pages, then just add:
if (location.pathname !== '/the/page/with/slider') return;
to the beginning of the function
/*
* SCROLLBAR 2 COLUMN / SOLUTIONS
*/
var ssb = {
aConts : [],
mouseY : 0,
N : 0,
asd : 0, /*active scrollbar element*/
sc : 0,
sp : 0,
to : 0,
// constructor
scrollbar : function (cont_id) {
var cont = document.getElementById(cont_id);
// perform initialization
if (! ssb.init()) return false;
var cont_clone = cont.cloneNode(false);
cont_clone.style.overflow = "hidden";
cont.parentNode.appendChild(cont_clone);
cont_clone.appendChild(cont);
cont.style.position = 'absolute';
cont.style.left = cont.style.top = '0px';
cont.style.width = cont.style.height = '100%';
// adding new container into array
ssb.aConts[ssb.N++] = cont;
cont.sg = false;
//creating scrollbar child elements
cont.st = this.create_div('ssb_st', cont, cont_clone);
cont.sb = this.create_div('ssb_sb', cont, cont_clone);
cont.su = this.create_div('ssb_up', cont, cont_clone);
cont.sd = this.create_div('ssb_down', cont, cont_clone);
// on mouse down processing
cont.sb.onmousedown = function (e) {
if (! this.cont.sg) {
if (! e) e = window.event;
ssb.asd = this.cont;
this.cont.yZ = e.screenY;
this.cont.sZ = cont.scrollTop;
this.cont.sg = true;
// new class name
this.className = 'ssb_sb ssb_sb_down';
}
return false;
}
// on mouse down on free track area - move our scroll element too
cont.st.onmousedown = function (e) {
if (! e) e = window.event;
ssb.asd = this.cont;
ssb.mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
for (var o = this.cont, y = 0; o != null; o = o.offsetParent) y += o.offsetTop;
this.cont.scrollTop = (ssb.mouseY - y - (this.cont.ratio * this.cont.offsetHeight / 2) - this.cont.sw) / this.cont.ratio;
this.cont.sb.onmousedown(e);
}
// onmousedown events
cont.su.onmousedown = cont.su.ondblclick = function (e) { ssb.mousedown(this, -1); return false; }
cont.sd.onmousedown = cont.sd.ondblclick = function (e) { ssb.mousedown(this, 1); return false; }
//onmouseout events
cont.su.onmouseout = cont.su.onmouseup = ssb.clear;
cont.sd.onmouseout = cont.sd.onmouseup = ssb.clear;
// on mouse over - apply custom class name: ssb_sb_over
cont.sb.onmouseover = function (e) {
if (! this.cont.sg) this.className = 'ssb_sb ssb_sb_over';
return false;
}
// on mouse out - revert back our usual class name 'ssb_sb'
cont.sb.onmouseout = function (e) {
if (! this.cont.sg) this.className = 'ssb_sb';
return false;
}
// onscroll - change positions of scroll element
cont.ssb_onscroll = function () {
this.ratio = (this.offsetHeight - 2 * this.sw) / this.scrollHeight;
this.sb.style.top = Math.floor(this.sw + this.scrollTop * this.ratio) + 'px';
}
// scrollbar width
cont.sw = 16;
// start scrolling
cont.ssb_onscroll();
ssb.refresh();
// binding own onscroll event
cont.onscroll = cont.ssb_onscroll;
return cont;
},
// initialization
init : function () {
if (window.oper || (! window.addEventListener && ! window.attachEvent)) { return false; }
// temp inner function for event registration
function addEvent (o, e, f) {
if (window.addEventListener) { o.addEventListener(e, f, false); ssb.w3c = true; return true; }
if (window.attachEvent) return o.attachEvent('on' + e, f);
return false;
}
// binding events
addEvent(window.document, 'mousemove', ssb.onmousemove);
addEvent(window.document, 'mouseup', ssb.onmouseup);
addEvent(window, 'resize', ssb.refresh);
return true;
},
// create and append div finc
create_div : function(c, cont, cont_clone) {
var o = document.createElement('div');
o.cont = cont;
o.className = c;
cont_clone.appendChild(o);
return o;
},
// do clear of controls
clear : function () {
clearTimeout(ssb.to);
ssb.sc = 0;
return false;
},
// refresh scrollbar
refresh : function () {
for (var i = 0, N = ssb.N; i < N; i++) {
var o = ssb.aConts[i];
o.ssb_onscroll();
o.sb.style.width = o.st.style.width = o.su.style.width = o.su.style.height = o.sd.style.width = o.sd.style.height = o.sw + 'px';
o.sb.style.height = Math.ceil(Math.max(o.sw * .5, o.ratio * o.offsetHeight) + 1) + 'px';
}
},
// arrow scrolling
arrow_scroll : function () {
if (ssb.sc != 0) {
ssb.asd.scrollTop += 6 * ssb.sc / ssb.asd.ratio;
ssb.to = setTimeout(ssb.arrow_scroll, ssb.sp);
ssb.sp = 32;
}
},
/* event binded functions : */
// scroll on mouse down
mousedown : function (o, s) {
if (ssb.sc == 0) {
// new class name
o.cont.sb.className = 'ssb_sb ssb_sb_down';
ssb.asd = o.cont;
ssb.sc = s;
ssb.sp = 100;
ssb.arrow_scroll();
}
},
// on mouseMove binded event
onmousemove : function(e) {
if (! e) e = window.event;
// get vertical mouse position
ssb.mouseY = e.screenY;
if (ssb.asd.sg) ssb.asd.scrollTop = ssb.asd.sZ + (ssb.mouseY - ssb.asd.yZ) / ssb.asd.ratio;
},
// on mouseUp binded event
onmouseup : function (e) {
if (! e) e = window.event;
var tg = (e.target) ? e.target : e.srcElement;
if (ssb.asd && document.releaseCapture) ssb.asd.releaseCapture();
// new class name
if (ssb.asd) ssb.asd.sb.className = (tg.className.indexOf('scrollbar') > 0) ? 'ssb_sb ssb_sb_over' : 'ssb_sb';
document.onselectstart = '';
ssb.clear();
ssb.asd.sg = false;
}
}
window.onload = function() {
ssb.scrollbar('container'); // scrollbar initialization
}

Video JS Range Slider Not Working

I am trying to implement Range slider plugin to my video js player in my react project. I am already markers plugin integrated to my player. I have see the documentation of Rangeslider Plugin and followed the instructions given https://github.com/iamjem/rangeslider-videojs , couldn't get it working. When I do it, neither I get rangeslider on my player nor I get markers (which were working before adding rangeslider). Here is my code.
PlayerLogic.js (I initailize my player in this)
class PlayerLogic extends Component {
constructor() {
super();
this.state = {
player: {}
};
}
componentDidMount() {
var self = this;
var player = videojs(this.refs.video, this.props.options).ready(function () {
self.player = this;
self.player.on('play', self.handlePlay);
});
if (this.props.onPlayerInit) this.props.onPlayerInit(player);
var options = {};
player.rangeslider(options);
player.markers({
markerStyle: {},
markers: [
{length: 8, startTime: 10, endTime: 15, time: 9.5, text: "Cigarette"},
{length: 2, startTime: 20, endTime: 25, time: 16, text: "Cigarette"},
{length: 15, startTime: 30, endTime: 38, time: 23.6, text: "Cigarette"},
{length: 11, startTime: 30, endTime: 38, time: 23.6, text: "Alcohol"},
{length: 25, startTime: 51, endTime: 55, time: 28, text: "Cigarette"},
{length: 10, startTime: 60, endTime: 80, time: 35, text: "Alcohol"},
{length: 15, startTime: 70, endTime: 115, time: 50, text: "Alcohol"},
],
onMarkerReached: function () {
player.pause();
},
});
this.setState({player: player});
}
handlePlay() {
console.log("handle play ")
}
render() {
var props = blacklist(this.props, 'children', 'className', 'src', 'type', 'onPlay');
props.className = cx(this.props.className, 'videojs', 'video-js vjs-default-skin', 'vjs-big-play-centered');
assign(props, {
ref: 'video',
controls: true,
width: "700", height: "450"
});
return (
<div>
<video {... props}>
<source src={this.props.src} type={this.props.type} id={this.props.id}/>
</video>
</div>)
}
}
part of rangeslider.js (as the actual code is too long)
//----------------Load Plugin----------------//
(function () {
//-- Load RangeSlider plugin in videojs
function RangeSlider(options) {
player.rangeslider = new RangeSlider(player, options);
//When the DOM and the video media is loaded
function initialVideoFinished(event) {
var plugin = player.rangeslider;
//All components will be initialize after they have been loaded by videojs
for (var index in plugin.components) {
plugin.components[index].init_();
}
if (plugin.options.hidden)
plugin.hide(); //Hide the Range Slider
if (plugin.options.locked)
plugin.lock(); //Lock the Range Slider
if (plugin.options.panel == false)
plugin.hidePanel(); //Hide the second Panel
if (plugin.options.controlTime == false)
plugin.hidecontrolTime(); //Hide the control time panel
plugin._reset();
player.trigger('loadedRangeSlider'); //Let know if the Range Slider DOM is ready
}
if (player.techName == 'Youtube') {
//Detect youtube problems
player.one('error', function (e) {
switch (player.error) {
case 2:
alert("The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.");
case 5:
alert("The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.");
case 100:
alert("The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.");
break;
case 101:
alert("The owner of the requested video does not allow it to be played in embedded players.");
break;
case 150:
alert("The owner of the requested video does not allow it to be played in embedded players.");
break;
default:
alert("Unknown Error");
break;
}
});
player.on('firstplay', initialVideoFinished);
} else {
player.one('playing', initialVideoFinished);
}
console.log("Loaded Plugin RangeSlider");
}
videojs.plugin('rangeslider', RangeSlider);
//-- Plugin
function RangeSlider(player, options) {
var player = player || this;
this.player = player;
this.components = {}; // holds any custom components we add to the player
options = options || {}; // plugin options
if (!options.hasOwnProperty('locked'))
options.locked = false; // lock slider handles
if (!options.hasOwnProperty('hidden'))
options.hidden = true; // hide slider handles
if (!options.hasOwnProperty('panel'))
options.panel = true; // Show Second Panel
if (!options.hasOwnProperty('controlTime'))
options.controlTime = true; // Show Control Time to set the arrows in the edition
this.options = options;
this.init();
}
//-- Methods
RangeSlider.prototype = {
/*Constructor*/
init: function () {
var player = this.player || {};
this.updatePrecision = 3;
//position in second of the arrows
this.start = 0;
this.end = 0;
//components of the plugin
var controlBar = player.controlBar;
var seekBar = controlBar.progressControl.seekBar;
this.components.RSTimeBar = seekBar.RSTimeBar;
this.components.ControlTimePanel = controlBar.ControlTimePanel;
//Save local component
this.rstb = this.components.RSTimeBar;
this.box = this.components.SeekRSBar = this.rstb.SeekRSBar;
this.bar = this.components.SelectionBar = this.box.SelectionBar;
this.left = this.components.SelectionBarLeft = this.box.SelectionBarLeft;
this.right = this.components.SelectionBarRight = this.box.SelectionBarRight;
this.tp = this.components.TimePanel = this.box.TimePanel;
this.tpl = this.components.TimePanelLeft = this.tp.TimePanelLeft;
this.tpr = this.components.TimePanelRight = this.tp.TimePanelRight;
this.ctp = this.components.ControlTimePanel;
this.ctpl = this.components.ControlTimePanelLeft = this.ctp.ControlTimePanelLeft;
this.ctpr = this.components.ControlTimePanelRight = this.ctp.ControlTimePanelRight;
},
lock: function () {
this.options.locked = true;
this.ctp.enable(false);
if (typeof this.box != 'undefined')
videojs.addClass(this.box.el_, 'locked');
},
unlock: function () {
this.options.locked = false;
this.ctp.enable();
if (typeof this.box != 'undefined')
videojs.removeClass(this.box.el_, 'locked');
},
show: function () {
this.options.hidden = false;
if (typeof this.rstb != 'undefined') {
this.rstb.show();
if (this.options.controlTime)
this.showcontrolTime();
}
},
hide: function () {
this.options.hidden = true;
if (typeof this.rstb != 'undefined') {
this.rstb.hide();
this.ctp.hide();
}
},
showPanel: function () {
this.options.panel = true;
if (typeof this.tp != 'undefined')
videojs.removeClass(this.tp.el_, 'disable');
},
hidePanel: function () {
this.options.panel = false;
if (typeof this.tp != 'undefined')
videojs.addClass(this.tp.el_, 'disable');
},
showcontrolTime: function () {
this.options.controlTime = true;
if (typeof this.ctp != 'undefined')
this.ctp.show();
},
hidecontrolTime: function () {
this.options.controlTime = false;
if (typeof this.ctp != 'undefined')
this.ctp.hide();
},
setValue: function (index, seconds, writeControlTime) {
//index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds
var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
var percent = this._percent(seconds);
var isValidIndex = (index === 0 || index === 1);
var isChangeable = !this.locked;
if (isChangeable && isValidIndex)
this.box.setPosition(index, percent, writeControlTime);
},
setValues: function (start, end, writeControlTime) {
//index = 0 for the left Arrow and 1 for the right Arrow. Value in seconds
var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
this._reset();
this._setValuesLocked(start, end, writeControlTime);
},
getValues: function () { //get values in seconds
var values = {}, start, end;
start = this.start || this._getArrowValue(0);
end = this.end || this._getArrowValue(1);
return {start: start, end: end};
},
playBetween: function (start, end, showRS) {
showRS = typeof showRS == 'undefined' ? true : showRS;
this.player.currentTime(start);
this.player.play();
if (showRS) {
this.show();
this._reset();
} else {
this.hide();
}
this._setValuesLocked(start, end);
this.bar.activatePlay(start, end);
},
loop: function (start, end, show) {
var player = this.player;
if (player) {
player.on("pause", videojs.bind(this, function () {
this.looping = false;
}));
show = typeof show === 'undefined' ? true : show;
if (show) {
this.show();
this._reset();
}
else {
this.hide();
}
this._setValuesLocked(start, end);
this.timeStart = start;
this.timeEnd = end;
this.looping = true;
this.player.currentTime(start);
this.player.play();
this.player.on("timeupdate", videojs.bind(this, this.bar.process_loop));
}
},
_getArrowValue: function (index) {
var index = index || 0;
var duration = this.player.duration();
duration = typeof duration == 'undefined' ? 0 : duration;
var percentage = this[index === 0 ? "left" : "right"].el_.style.left.replace("%", "");
if (percentage == "")
percentage = index === 0 ? 0 : 100;
return videojs.round(this._seconds(percentage / 100), this.updatePrecision - 1);
},
_percent: function (seconds) {
var duration = this.player.duration();
if (isNaN(duration)) {
return 0;
}
return Math.min(1, Math.max(0, seconds / duration));
},
_seconds: function (percent) {
var duration = this.player.duration();
if (isNaN(duration)) {
return 0;
}
return Math.min(duration, Math.max(0, percent * duration));
},
_reset: function () {
var duration = this.player.duration();
this.tpl.el_.style.left = '0%';
this.tpr.el_.style.left = '100%';
this._setValuesLocked(0, duration);
},
_setValuesLocked: function (start, end, writeControlTime) {
var triggerSliderChange = typeof writeControlTime != 'undefined';
var writeControlTime = typeof writeControlTime != 'undefined' ? writeControlTime : true;
if (this.options.locked) {
this.unlock();//It is unlocked to change the bar position. In the end it will return the value.
this.setValue(0, start, writeControlTime);
this.setValue(1, end, writeControlTime);
this.lock();
} else {
this.setValue(0, start, writeControlTime);
this.setValue(1, end, writeControlTime);
}
// Trigger slider change
if (triggerSliderChange) {
this._triggerSliderChange();
}
},
_checkControlTime: function (index, TextInput, timeOld) {
var h = TextInput[0],
m = TextInput[1],
s = TextInput[2],
newHour = h.value,
newMin = m.value,
newSec = s.value,
obj, objNew, objOld;
index = index || 0;
if (newHour != timeOld[0]) {
obj = h;
objNew = newHour;
objOld = timeOld[0];
} else if (newMin != timeOld[1]) {
obj = m;
objNew = newMin;
objOld = timeOld[1];
} else if (newSec != timeOld[2]) {
obj = s;
objNew = newSec;
objOld = timeOld[2];
} else {
return false;
}
var duration = this.player.duration() || 0,
durationSel;
var intRegex = /^\d+$/;//check if the objNew is an integer
if (!intRegex.test(objNew) || objNew > 60) {
objNew = objNew == "" ? "" : objOld;
}
newHour = newHour == "" ? 0 : newHour;
newMin = newMin == "" ? 0 : newMin;
newSec = newSec == "" ? 0 : newSec;
durationSel = videojs.TextTrack.prototype.parseCueTime(newHour + ":" + newMin + ":" + newSec);
if (durationSel > duration) {
obj.value = objOld;
obj.style.border = "1px solid red";
} else {
obj.value = objNew;
h.style.border = m.style.border = s.style.border = "1px solid transparent";
this.setValue(index, durationSel, false);
// Trigger slider change
this._triggerSliderChange();
}
if (index === 1) {
var oldTimeLeft = this.ctpl.el_.children,
durationSelLeft = videojs.TextTrack.prototype.parseCueTime(oldTimeLeft[0].value + ":" + oldTimeLeft[1].value + ":" + oldTimeLeft[2].value);
if (durationSel < durationSelLeft) {
obj.style.border = "1px solid red";
}
} else {
var oldTimeRight = this.ctpr.el_.children,
durationSelRight = videojs.TextTrack.prototype.parseCueTime(oldTimeRight[0].value + ":" + oldTimeRight[1].value + ":" + oldTimeRight[2].value);
if (durationSel > durationSelRight) {
obj.style.border = "1px solid red";
}
}
},
_triggerSliderChange: function () {
this.player.trigger("sliderchange");
}
};
//----------------Public Functions----------------//
//-- Public Functions added to video-js
//Lock the Slider bar and it will not be possible to change the arrow positions
videojs.Player.prototype.lockSlider = function () {
return this.rangeslider.lock();
};
//Unlock the Slider bar and it will be possible to change the arrow positions
videojs.Player.prototype.unlockSlider = function () {
return this.rangeslider.unlock();
};
//Show the Slider Bar Component
videojs.Player.prototype.showSlider = function () {
return this.rangeslider.show();
};
//Hide the Slider Bar Component
videojs.Player.prototype.hideSlider = function () {
return this.rangeslider.hide();
};
//Show the Panel with the seconds of the selection
videojs.Player.prototype.showSliderPanel = function () {
return this.rangeslider.showPanel();
};
//Hide the Panel with the seconds of the selection
videojs.Player.prototype.hideSliderPanel = function () {
return this.rangeslider.hidePanel();
};
//Show the control Time to edit the position of the arrows
videojs.Player.prototype.showControlTime = function () {
return this.rangeslider.showcontrolTime();
};
//Hide the control Time to edit the position of the arrows
videojs.Player.prototype.hideControlTime = function () {
return this.rangeslider.hidecontrolTime();
};
//Set a Value in second for both arrows
videojs.Player.prototype.setValueSlider = function (start, end) {
return this.rangeslider.setValues(start, end);
};
//The video will be played in a selected section
videojs.Player.prototype.playBetween = function (start, end) {
return this.rangeslider.playBetween(start, end);
};
//The video will loop between to values
videojs.Player.prototype.loopBetween = function (start, end) {
return this.rangeslider.loop(start, end);
};
//Set a Value in second for the arrows
videojs.Player.prototype.getValueSlider = function () {
return this.rangeslider.getValues();
};
//----------------Create new Components----------------//
//--Charge the new Component into videojs
videojs.SeekBar.prototype.options_.children.RSTimeBar = {}; //Range Slider Time Bar
videojs.ControlBar.prototype.options_.children.ControlTimePanel = {}; //Panel with the time of the range slider
//-- Design the new components
/**
* Range Slider Time Bar
* #param {videojs.Player|Object} player
* #param {Object=} options
* #constructor
})();
This plugin is not compatible with videojs version over 4.2.
You can look issue here
AND Owner of plugin wroten to github that at the begining of readme "This plugin will no longer be maintained. Welcome those who want to continue the project."

How to implement ipad-like password field behaviour in a text input field using jquery

Is there any plugin similar to the iPad-like password field behaviour. We need to show only the focus number that the customer enters when they enter their credit card number, and then switch to a bullet once the customer types the next number.
For numbers that have been entered prior to the number being entered, they all need to be changed to the bullet style.
Not sure about Jquery plugin. tried this out. Hope this works for you - http://jsfiddle.net/Lhw7xcy6/12/
(function () {
var config = {},
bulletsInProgress = false,
bulletTimeout = null,
defaultOpts = {
className: 'input-long',
maxLength: '16',
type: 'tel',
autoComplete: 'off'
};
var generateBullets = function (n) {
var bullets = '';
for (var i = 0; i < n; i++) {
bullets += "\u25CF";
}
return bullets;
},
getCursorPosition = function (elem) {
var el = $(elem).get(0);
var pos = 0;
var posEnd = 0;
if ('selectionStart' in el) {
pos = el.selectionStart;
posEnd = el.selectionEnd;
} else if ('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
posEnd = Sel.text.length;
}
return [pos, posEnd];
},
keyInputHandler = function (e, elem, $inpField) {
var keyCode = e.which || e.keyCode,
timeOut = 0,
$bulletField = $(elem),
tempInp = $bulletField.data('tempInp'),
numBullets = $bulletField.data('numBullets');
var position = getCursorPosition(elem);
if (keyCode >= 48 && keyCode <= 57) {
e.preventDefault();
clearTimeout(bulletTimeout);
$bulletField.val(generateBullets(numBullets) + String.fromCharCode(keyCode));
tempInp += String.fromCharCode(keyCode);
numBullets += 1;
bulletsInProgress = true;
timeOut = 3000;
} else if (keyCode == 8) {
clearTimeout(bulletTimeout);
tempInp = (position[0] == position[1]) ? tempInp.substring(0, position[0] - 1) + tempInp.substring(position[1]) : tempInp.substring(0, position[0]) + tempInp.substring(position[1]);
numBullets = (position[0] == position[1]) ? numBullets - 1 : numBullets - (position[1] - position[0]);
tempInp = ($.trim($bulletField.val()) === '') ? '' : tempInp;
numBullets = ($.trim($bulletField.val()) === '') ? 0 : numBullets;
timeOut = 0;
} else {
e.preventDefault();
return false;
}
$bulletField.data('numBullets', numBullets);
$bulletField.data('tempInp', tempInp);
$inpField.val(tempInp);
$('#output').val(tempInp); // testing purpose
bulletTimeout = setTimeout(function () {
$bulletField.val(generateBullets(numBullets));
bulletsInProgress = false;
}, timeOut);
};
$.fn.bulletField = function (options) {
var opts = $.extend({}, defaultOpts, options);
//console.log(opts);
this.each(function () {
var $inpField = $(this),
id = $inpField.attr('id');
$inpField.after('<input id="bullet_' + id + '" type=' + opts.type + ' maxlength=' + opts.maxLength + ' autocomplete=' + opts.autoComplete + ' class=' + opts.className + '>');
$inpField.hide();
var bulletFieldId = 'bullet_' + id;
var $bulletField = $('#' + bulletFieldId);
$bulletField.data('numBullets', 0);
$bulletField.data('tempInp', '');
$('#' + bulletFieldId).on('keydown', function (e) {
keyInputHandler(e, this, $inpField);
});
$('#' + bulletFieldId).on('blur', function () {
//$inpField.trigger('blur');
});
});
return this;
};
}());
$(function () {
/*USAGE - invoke the plugin appropriately whenever needed. example -onclick,onfocus,mousedown etc.*/
//$('body').on('mousedown', '#bulletField', function () {
$('#bulletField').bulletField();
//$('body').off('mousedown');
// });
/* ---OR ----
$('#bulletField').bulletField({
className: 'input-short',
maxLength : '4'
});*/
});

Infovis not Iterating over Root Node

I'm facing weird behaviour of Jit Infovis i'm using. I have two different html files that include a load json function from a Javascript file. The function is using infovis library to display a hypertree map from a json file. Both two html files load the same json file.
One html file has been succeeded rendering the map properly. But another one has not. It renders the map almost properly, but after i debugged it, i got it not iterating over the root node. Then, the root node becames inactive without label and clickability.
This is the js function i'm using.
var labelType, useGradients, nativeTextSupport, animate;
(function () {
var ua = navigator.userAgent,
iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
typeOfCanvas = typeof HTMLCanvasElement,
nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
textSupport = nativeCanvasSupport
&& (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
//I'm setting this based on the fact that ExCanvas provides text support for IE
//and that as of today iPhone/iPad current text support is lame
labelType = (!nativeCanvasSupport || (textSupport && !iStuff)) ? 'Native' : 'HTML';
nativeTextSupport = labelType == 'Native';
useGradients = nativeCanvasSupport;
animate = !(iStuff || !nativeCanvasSupport);
})();
var Log = {
elem: false,
write: function (text) {
if (!this.elem)
this.elem = document.getElementById('log');
this.elem.innerHTML = text;
this.elem.style.left = (350 - this.elem.offsetWidth / 2) + 'px';
}
};
function init(slugParam, pageParam) {
var isFirst = true;
var isSetAsRoot = false;
// alert(slugParam+ " | "+pageParam);
var url = Routing.generate('trade_map_buyer_json', { slug : slugParam, page : pageParam });
//init data
$.getJSON(url, function (json) {
var type = 'Buyer';
//end
var infovis = document.getElementById('infovis');
infovis.style.align = "center";
infovis.innerHTML = '';
// infovis.innerHTML = '<img align="center" id="gifloader" style="margin-left:50%; margin-top:50%" src="{{ asset('/bundles/jariffproject/frontend/images/preloader.gif') }}" width="30px" height="30px"/>'
var w = infovis.offsetWidth - 50, h = infovis.offsetHeight - 50;
url = url.replace("/json/", "/");
window.history.pushState("object or string", "Title", url);
//init Hypertree
var ht = new $jit.Hypertree({
//id of the visualization container
injectInto: 'infovis',
Navigation: {
enable: false,
panning: 'avoid nodes',
},
//canvas width and height
width: w,
height
: h,
//Change node and edge styles such as
//color, width and dimensions.
Node: {
dim: 9,
overridable: true,
color: "#66FF33"
},
Tips: {
enable: true,
type: 'HTML',
offsetX: 0,
offsetY: 0,
onShow: function(tip, node) {
// dump(tip);
tip.innerHTML = "<div style='background-color:#F8FFC9;text-align:center;border-radius:5px; padding:10px 10px;' class='node-tip'><p style='font-size:100%;font-weight:bold;'>"+node.name+"</p><p style='font-size:50%pt'>"+node.data.address+"</p></div>";
}
},
Events: {
enable: true,
type: 'HTML',
onMouseEnter: function(node, eventInfo, e){
var nodeId = node.id;
var menu1 = [
{'set as Root':function(menuItem,menu) {
menu.hide();
isSetAsRoot = true;
console.log(nodeId);
init(nodeId, 0);
}},
$.contextMenu.separator,
{'View details':function(menuItem,menu) {
}}
];
$('.node').contextMenu(menu1,{theme:'vista'});
}
},
Edge: {
lineWidth: 1,
color: "#52D5DE",
overridable: true,
},
onBeforePlotNode: function(node)
{
if (isFirst) {
console.log(node._depth);
var odd = isOdd(node._depth);
if (odd) {
node.setData('color', "#66FF33"); // hijau (supplier)
} else {
node.setData('color', "#FF3300"); // merah (buyer)
}
isFirst = false;
}
},
onPlotNode: function(node)
{
if (isSetAsRoot) {
var nodeInstance = node.getNode();
var nodeId = nodeInstance.id;
init(nodeId, 0);
isSetAsRoot = false;
}
},
onBeforeCompute: function (domElement, node) {
var dot = ht.graph.getClosestNodeToOrigin("current");
type = isOdd(dot._depth) ? 'Supplier' : 'Buyer';
},
//Attach event handlers and add text to the
//labels. This method is only triggered on label
//creation
onCreateLabel: function (domElement, node) {
var odd = isOdd(node._depth);
if (odd) {
node.setData('color', "#66FF33"); // hijau (supplier)
} else {
node.setData('color', "#FF3300"); // merah (buyer)
}
domElement.innerHTML = node.name;
// if (node._depth == 1) {
console.log("|"+node.name+"|"+node._depth+"|");
// }
$jit.util.addEvent(domElement, 'click', function () {
ht.onClick(node.id, {
onComplete: function () {
console.log(node.id);
ht.controller.onComplete(node);
}
});
});
},
onPlaceLabel: function (domElement, node) {
var style = domElement.style;
style.display = '';
style.cursor = 'pointer';
if (node._depth <= 1) {
style.fontSize = "0.8em";
style.color = "#000";
style.fontWeight = "normal";
} else if (node._depth == 2) {
style.fontSize = "0.7em";
style.color = "#555";
} else {
style.display = 'none';
}
var left = parseInt(style.left);
var w = domElement.offsetWidth;
style.left = (left - w / 2) + 'px';
},
onComplete: function (node) {
var dot = ht.graph.getClosestNodeToOrigin("current");
console.log(dot._depth);
var connCount = dot.data.size;
var showingCount = '';
if (connCount != undefined) {
var pageParamInt = (parseInt(pageParam)+1) * 10;
var modulus = connCount%10;
showingCount = (pageParamInt - 9) + " - " + pageParamInt;
if (connCount - (pageParamInt - 9) < 10) {
showingCount = (pageParamInt - 10) + " - " + ((pageParamInt - 10) + modulus);
}
} else {
connCount = '0';
showingCount = 'No Connections Shown'
}
}
});
//load JSON data.
ht.loadJSON(json);
//compute positions and plot.
ht.refresh();
//end
ht.controller.onComplete();
});
}
function isEven(n)
{
return isNumber(n) && (n % 2 == 0);
}
function isOdd(n)
{
return isNumber(n) && (n % 2 == 1);
}
function isNumber(n)
{
return n === parseFloat(n);
}
function processAjaxData(response, urlPath){
}
function dump(obj) {
var out = '';
for (var i in obj) {
out += i + ": " + obj[i] + "\n";
}
out = out + "\n\n"
console.log(out);
// or, if you wanted to avoid alerts...
var pre = document.createElement('pre');
pre.innerHTML = out;
document.body.appendChild(pre)
}
What's probably causing this?
Please check whether there is conflict id. Basically infovis render each nodes by the id.
And if there is an DOM element that has the same id with one DOM element of a node. It would conflict and won't render
you can check it by duming dom element iterating over the nodes.

Up/Down/Left/Right keyboard navigation with jQuery?

I have a list of div's all with a set and equal height/width that are float:left so they sit next to each other and fold under if that parent is smaller than the combined with of the items.
Pretty standard.
This is to create a list of the twitter bootstrap icons, it gives something like this:
I have added next/previous keyboard navigation using the code below, however you will notice that the up/down arrow keys are mapped to call the left/right functions. What I have no idea how to do is to actually do the up/down navigation?
JsFiddle
(function ($) {
$.widget("ui.iconSelect", {
// default options
options: {
},
$select: null,
$wrapper: null,
$list: null,
$filter: null,
$active: null,
icons: {},
keys: {
left: 37,
up: 38,
right: 39,
down: 40
},
//initialization function
_create: function () {
var that = this;
that.$select = that.element;
that.$wrapper = $('<div class="select-icon" tabindex="0"></div>');
that.$filter = $('<input class="span12" tabindex="-1" placeholder="Filter by class name..."/>').appendTo(that.$wrapper);
that.$list = $('<div class="select-icon-list"></div>').appendTo(that.$wrapper);
//build the list of icons
that.element.find('option').each(function () {
var $option = $(this);
var icon = $option.val();
that.icons[icon] = $('<a data-class="' + icon + '"><i class="icon ' + icon + '"></i></a>');
if ($option.is(':selected')) {
that.icons[icon].addClass('selected active');
}
that.$list.append(that.icons[icon]);
});
that.$wrapper.insertBefore(that.$select);
that.$select.addClass('hide');
that._setupArrowKeysHandler();
that._setupClickHandler();
that._setupFilter();
that.focus('selected');
},
focus: function (type) {
var that = this;
if (that.$active === null || that.$active.length == 0) {
if (type == 'first') {
that.$active = that.$list.find('a:visible:first');
} else if (type == 'last') {
that.$active = that.$list.find('a:visible:last');
} else if (type == 'selected') {
that.$active = that.$list.find('a.selected:visible:first');
that.focus('first');
}
}
that.$active.addClass('active');
var toScroll = ((that.$list.scrollTop() + that.$active.position().top)-that.$list.height()/2)+that.$active.height()/2;
//that.$list.scrollTop((that.$list.scrollTop() + top)-that.$list.height()/2);
that.$list.stop(true).animate({
scrollTop: toScroll,
queue: false,
easing: 'linear'
}, 200);
if (type === 'selected') {
return false;
}
that.$select.val(that.$active.data('class'));
that.$select.trigger('change');
},
_setupArrowKeysHandler: function () {
var that = this;
that.$wrapper.on('keydown', function (e) {
switch (e.which) {
case that.keys.left:
that.moveLeft();
break;
case that.keys.up:
that.moveUp();
break;
case that.keys.right:
that.moveRight();
break;
case that.keys.down:
that.moveDown();
break;
case 16:
return true;
case 9:
return true;
break;
default:
that.$filter.focus();
return true;
}
return false;
});
},
_setupFilter: function(){
var that = this;
that.$filter.on('keydown keyup keypress paste cut change', function(e){
that.filter(that.$filter.val());
});
},
_setupClickHandler: function () {
var that = this;
that.$list.on('click', 'a', function () {
that.$wrapper.focus();
that.$active.removeClass('active');
that.$active = $(this);
that.focus('first');
});
},
moveUp: function () {
var that = this;
return that.moveLeft();
},
moveDown: function () {
var that = this;
return that.moveRight();
},
moveLeft: function () {
var that = this;
that.$active.removeClass('active');
that.$active = that.$active.prevAll(':visible:first');
that.focus('last');
return false;
},
moveRight: function () {
var that = this;
that.$active.removeClass('active');
that.$active = that.$active.nextAll(':visible:first');
that.focus('first');
return false;
},
filter: function(word){
var that = this;
var regexp = new RegExp(word.toLowerCase());
var found = false;
$.each(that.icons, function(i, $v){
found = regexp.test(i);
if(found && !$v.is(':visible')){
$v.show();
} else if(!found && $v.is(':visible')){
$v.hide();
}
});
}
});
})(jQuery);
Perhaps something like this: http://jsfiddle.net/QFzCY/
var blocksPerRow = 4;
$("body").on("keydown", function(e){
var thisIndex = $(".selected").index();
var newIndex = null;
if(e.keyCode === 38) {
// up
newIndex = thisIndex - blocksPerRow;
}
else if(e.keyCode === 40) {
// down
newIndex = thisIndex + blocksPerRow;
}
if(newIndex !== null) {
$(".test").eq(newIndex).addClass("selected").siblings().removeClass("selected");
}
});
Basically, you set how many items there are in a row and then find the current index and subtract or add that amount to select the next element via the new index.
If you need to know how many blocks per row there are, you could do this:
var offset = null;
var blocksPerRow = 0;
$(".test").each(function(){
if(offset === null) {
offset = $(this).offset().top;
}
else if($(this).offset().top !== offset) {
return false;
}
blocksPerRow++;
});
To deal with your 'edge' cases, you could do:
if(newIndex >= $(".test").length) {
newIndex = $(".test").length - newIndex;
}
moveUp: function () {
var that = this;
var index = $(this).index();
var containerWidth = parseInt( $('.select-icon-list').innerWidth(), 10);
var iconWidth = parseInt( $('.select-icon-list > a').width(), 10);
var noOfCols = Math.floor( containerWidth / iconWidth );
var newIndex = ( (index - noOfCols) < 0 ) ? index : (index - noOfCols);
var elem = $('.select-icon-list > a')[index];
},
Cache what ever remains static.

Categories