Add songs to Jquery JAudio playlist without refreshing player - javascript

I am building a custom mp3 player for a entertainment web site and i need to add songs continuously even when playing a song. to do that i'm using this function.
var temp = [];
var tempObj = [];
function popUp(file,thumb,trackName,trackArtist,trackAlbum) {
var validate = true;
if (temp.length>0) {
for (var x = 0; x < temp.length; x++) {
if (temp[x]['trackName'] == trackName) {
validate = false;
}
}
}
if (validate==true){
// Save data to object
tempObj = { file: file, thumb: thumb, trackName: trackName, trackArtist: trackArtist, trackAlbum: trackAlbum };
temp.push(tempObj); // push object to existing array
$("#player").jAudio({playlist: temp});
}
}
Problem is that to add songs to player we need to run that "jAudio()" function. because of that every time "popUp()" function called it calling the "jAudio()" function. if any one have a solution, please shear it..
This is the JAudio API.
!function (t) {
function i(i, a) {
this.settings = t.extend(!0, r, a), this.$context = i, this.domAudio = this.$context.find("audio")[0], this.$domPlaylist = this.$context.find(".jAudio--playlist"), this.$domControls = this.$context.find(".jAudio--controls"), this.$domVolumeBar = this.$context.find(".jAudio--volume"), this.$domDetails = this.$context.find(".jAudio--details"), this.$domStatusBar = this.$context.find(".jAudio--status-bar"), this.$domProgressBar = this.$context.find(".jAudio--progress-bar-wrapper"), this.$domTime = this.$context.find(".jAudio--time"), this.$domElapsedTime = this.$context.find(".jAudio--time-elapsed"), this.$domTotalTime = this.$context.find(".jAudio--time-total"), this.$domThumb = this.$context.find(".jAudio--thumb"), this.currentState = "pause", this.currentTrack = this.settings.defaultTrack, this.timer = void 0, this.init()
}
function a(t, i) {
for (var t = String(t); t.length < i;)t = "0" + t;
return t
}
var e = "jAudio", r = {
playlist: [],
defaultAlbum: void 0,
defaultArtist: void 0,
defaultTrack: 0,
autoPlay: !1,
debug: !1
};
i.prototype = {
init: function () {
var t = this;
t.renderPlaylist(), t.preLoadTrack(), t.highlightTrack(), t.updateTotalTime(), t.events(), t.debug(), t.domAudio.volume = .2
}, play: function () {
var t = this, i = t.$domControls.find("#btn-play");
t.currentState = "play", t.domAudio.play(), clearInterval(t.timer), t.timer = setInterval(t.run.bind(t), 50), i.data("action", "pause"), i.attr("id", "btn-pause"), i.toggleClass("active")
}, pause: function () {
var t = this, i = t.$domControls.find("#btn-pause");
t.domAudio.pause(), clearInterval(t.timer), t.currentState = "pause", i.data("action", "play"), i.attr("id", "btn-play"), i.toggleClass("active")
}, stop: function () {
var t = this;
t.domAudio.pause(), t.domAudio.currentTime = 0, t.animateProgressBarPosition(), clearInterval(t.timer), t.updateElapsedTime(), t.currentState = "stop"
}, prev: function () {
var t, i = this;
t = 0 === i.currentTrack ? i.settings.playlist.length - 1 : i.currentTrack - 1, i.changeTrack(t)
}, next: function () {
var t, i = this;
t = i.currentTrack === i.settings.playlist.length - 1 ? 0 : i.currentTrack + 1, i.changeTrack(t)
}, preLoadTrack: function () {
var t = this;
t.changeTrack(t.settings.defaultTrack), t.settings.autoPlay && t.play()
}, changeTrack: function (t) {
var i = this;
i.currentTrack = t, i.domAudio.src = i.settings.playlist[t].file, i.highlightTrack(), i.updateThumb(), i.renderDetails(), "play" === i.currentState && i.play()
}, events: function () {
var i = this;
i.$domControls.on("click", "button", function () {
var a = t(this).data("action");
switch (a) {
case"prev":
i.prev.call(i);
break;
case"next":
i.next.call(i);
break;
case"pause":
i.pause.call(i);
break;
case"stop":
i.stop.call(i);
break;
case"play":
i.play.call(i)
}
}), i.$domPlaylist.on("click", ".jAudio--playlist-item", function () {
var a = t(this), e = (a.data("track"), a.index());
i.currentTrack !== e && i.changeTrack(e)
}), i.$domProgressBar.on("click", function (t) {
i.updateProgressBar(t), i.updateElapsedTime()
}), t(i.domAudio).on("loadedmetadata", function () {
i.animateProgressBarPosition.call(i), i.updateElapsedTime.call(i), i.updateTotalTime.call(i)
})
}, getAudioSeconds: function (t) {
var t = t % 60;
return t = a(Math.floor(t), 2), t = 60 > t ? t : "00"
}, getAudioMinutes: function (t) {
var t = t / 60;
return t = a(Math.floor(t), 2), t = 60 > t ? t : "00"
}, highlightTrack: function () {
var t = this, i = t.$domPlaylist.children(), a = "active";
i.removeClass(a), i.eq(t.currentTrack).addClass(a)
}, renderDetails: function () {
var t = this, i = t.settings.playlist[t.currentTrack], a = (i.file, i.thumb, i.trackName), e = i.trackArtist, r = (i.trackAlbum, "");
r += "<p>", r += "<span>" + a + "</span>", r += "<span>" + e + "</span>", r += "</p>", t.$domDetails.html(r)
}, renderPlaylist: function () {
var i = this, a = "";
t.each(i.settings.playlist, function (t, i) {
{
var e = i.file, r = i.thumb, o = i.trackName, s = i.trackArtist;
i.trackAlbum
}
trackDuration = "00:00", a += "<div class='jAudio--playlist-item' data-track='" + e + "'>", a += "<div class='jAudio--playlist-thumb'><img src='" + r + "'></div>", a += "<div class='jAudio--playlist-meta-text'>", a += "<h4>" + o + "</h4>", a += "<p>" + s + "</p>", a += "</div>", a += "</div>"
}), i.$domPlaylist.html(a)
}, run: function () {
var t = this;
t.animateProgressBarPosition(), t.updateElapsedTime(), t.domAudio.ended && t.next()
}, animateProgressBarPosition: function () {
var t = this, i = 100 * t.domAudio.currentTime / t.domAudio.duration + "%", a = {width: i};
t.$domProgressBar.children().eq(0).css(a)
}, updateProgressBar: function (t) {
var i, a, e, r = this;
t.offsetX && (i = t.offsetX), void 0 === i && t.layerX && (i = t.layerX), a = i / r.$domProgressBar.width(), e = r.domAudio.duration * a, r.domAudio.currentTime = e, r.animateProgressBarPosition()
}, updateElapsedTime: function () {
var t = this, i = t.domAudio.currentTime, a = t.getAudioMinutes(i), e = t.getAudioSeconds(i), r = a + ":" + e;
t.$domElapsedTime.text(r)
}, updateTotalTime: function () {
var t = this, i = t.domAudio.duration, a = t.getAudioMinutes(i), e = t.getAudioSeconds(i), r = a + ":" + e;
t.$domTotalTime.text(r)
}, updateThumb: function () {
var t = this, i = t.settings.playlist[t.currentTrack].thumb, a = {"background-image": "url(" + i + ")"};
t.$domThumb.css(a)
}, debug: function () {
var t = this;
t.settings.debug && console.log(t)
}
}, t.fn[e] = function (a) {
var e = function () {
return new i(t(this), a)
};
t(this).each(e)
}
}(jQuery);
// initialize
(function () {
}());

This is old, but if you are willing to go a little nasty, I have a working workaround. Forgive me for the nasty approach, in the end though - it works.
We are gonna make use of window here to use as a global scope across the functions.
init: function()
{
var self = this;
self.renderPlaylist();
self.preLoadTrack();
self.highlightTrack();
self.updateTotalTime();
self.events();
self.debug();
self.domAudio.volume = 0.05;
window.jAudioCore = self; // This line returns the self
},
Now you can change the playlist accordingly, anytime, just by changing window.playlist global variable, everywhere in the code.
renderPlaylist: function()
{
var self = this,
template = "";
$.each(window.playlist, function(i, a) //added window.playlist as the parameter
Your renderPlaylist function should look the one above.
To test this here's a simple code for you to use :
(function(){
window.playlist = [
{
file: "http://192.168.1.99:5000/mpeg",
thumb: "https://i.ytimg.com/vi/Kd57YHWqrsI/mqdefault.jpg",
trackName: "Carnival Of Rust",
trackArtist: "Poets Of The Fall",
trackAlbum: "Single",
trackDuration:"04:06",
},
{
file: "http://127.0.0.1:5000/mpeg",
thumb: "https://i.ytimg.com/vi/Kd57YHWqrsI/mqdefault.jpg",
trackName: "Carnival Of Rust",
trackArtist: "Poets Of The Fall",
trackAlbum: "Single",
trackDuration:"04:06",
}
];
var t = {
playlist: [], // this is no longer needed, you can remove it from the source code later
debug:true
}
$(".jAudio").jAudio(t);
setTimeout(function(){
window.playlist.push({
file: "http://127.0.0.1:5000/mpeg",
thumb: "https://i.ytimg.com/vi/Kd57YHWqrsI/mqdefault.jpg",
trackName: "Carnival Of Rust",
trackArtist: "Poets Of The Fall",
trackAlbum: "Single",
trackDuration:"04:06",
});
window.jAudioCore.renderPlaylist(); // renders the playlists
window.jAudioCore.preLoadTrack(); // will preload the current track
window.jAudioCore.highlightTrack(); // will highlight in the css
},3000);
})();
As I said, in the end, it works dynamically without refresh. There might be some underlying bugs, I couldn't test much on this. Cheers.

Related

How to force my script to load after an asynchronous, external script?

I have a script that is modifying a Shopify App (Which means the scripts are attached through a third party process and I can't access them.) I want my script to load only after their script is completely finished executing, but I can't figure out what to use to signal this process is complete.
This is my script (currently using setInterval as a stopgap):
$(window).load(function(){
var check = setInterval(function() {
let sprCheck = window['SPR'];
var spr = $("#shopify-product-reviews"),
container = spr.find(".spr-content"),
reviewButton = spr.find(".spr-summary-actions-newreview");
if (sprCheck) {
clearInterval(check);
var reviews = spr.find('.spr-reviews'),
reviewButtonWrap = spr.find('.spr-summary-actions'),
form = spr.find('.spr-form'),
toggleContainer = spr.find('.spr-summary-actions-togglereviews'),
reviewButtonLabel = reviewButton.text();
reviewButtonWrap.detach().appendTo(container);
spr.css('overflow','visible');
form.detach().insertAfter(reviews);
if (reviews.children().length) {
reviewButtonWrap.css('display', 'none');
}
toggleContainer.click(function() {
reviewButtonWrap.toggle();
});
spr.fadeTo(300, 1);
reviewButton.click(function(){
if (form.is(':visible')) {
reviewButton.text('Cancel Review');
reviewButton.addClass('spr-close-form');
} else {
reviewButton.text(reviewButtonLabel);
reviewButton.removeClass('spr-close-form');
}
});
}
}, 300);
})
This is where their script is attached:
(function() {
function asyncLoad() {
var urls = ["\/\/productreviews.shopifycdn.com\/assets\/v4\/spr.js?shop=sukker-sweet-phase-2.myshopify.com"];
for (var i = 0; i < urls.length; i++) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = urls[i];
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
}
};
if(window.attachEvent) {
window.attachEvent('onload', asyncLoad);
} else {
window.addEventListener('load', asyncLoad, false);
}
})();
This is their script itself:
e = function() {
"use strict";
window.innerShiv = function() {
function n(e, t, r) {
return /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i.test(r) ? e : t + "></" + r + ">"
}
var s, o = document,
d = "abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video".split(" ");
return function(e, t) {
if (!s && ((s = o.createElement("div")).innerHTML = "<nav></nav>", 1 !== s.childNodes.length)) {
for (var r = o.createDocumentFragment(), a = d.length; a--;) r.createElement(d[a]);
r.appendChild(s)
}
if (e = e.replace(/^\s\s*/, "").replace(/\s\s*$/, "").replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/(<([\w:]+)[^>]*?)\/>/g, n), s.innerHTML = (r = e.match(/^<(tbody|tr|td|col|colgroup|thead|tfoot)/i)) ? "<table>" + e + "</table>" : e, r = r ? s.getElementsByTagName(r[1])[0].parentNode : s, !1 === t) return r.childNodes;
a = o.createDocumentFragment();
for (var i = r.childNodes.length; i--;) a.appendChild(r.firstChild);
return a
}
}()
}, t = {
exports: {}
}, e.call(t.exports, t, t.exports), t.exports;
var e, t;
(function() {
window.SPR = function() {
function n() {}
return n.shop = Shopify.shop, n.host = "//productreviews.shopifycdn.com", n.version = "v4", n.api_url = n.host + "/proxy/" + n.version, n.badgeEls = [], n.reviewEls = [], n.elSettings = {}, n.$ = void 0, n.extraAjaxParams = {
shop: n.shop
}, n.registerCallbacks = function() {
return this.$(document).bind("spr:badge:loaded", "undefined" != typeof SPRCallbacks && null !== SPRCallbacks ? SPRCallbacks.onBadgeLoad : void 0), this.$(document).bind("spr:product:loaded", "undefined" != typeof SPRCallbacks && null !== SPRCallbacks ? SPRCallbacks.onProductLoad : void 0), this.$(document).bind("spr:reviews:loaded", "undefined" != typeof SPRCallbacks && null !== SPRCallbacks ? SPRCallbacks.onReviewsLoad : void 0), this.$(document).bind("spr:form:loaded", "undefined" != typeof SPRCallbacks && null !== SPRCallbacks ? SPRCallbacks.onFormLoad : void 0), this.$(document).bind("spr:form:success", "undefined" != typeof SPRCallbacks && null !== SPRCallbacks ? SPRCallbacks.onFormSuccess : void 0), this.$(document).bind("spr:form:failure", "undefined" != typeof SPRCallbacks && null !== SPRCallbacks ? SPRCallbacks.onFormFailure : void 0)
}, n.loadStylesheet = function() {
var e;
return (e = document.createElement("link")).setAttribute("rel", "stylesheet"), e.setAttribute("type", "text/css"), e.setAttribute("href", "https://productreviews.shopifycdn.com/assets/v4/spr-805222bdeda8199e3a86a468a398e3070e6126868692225ffa23ac7502b1eca2.css"), e.setAttribute("media", "screen"), document.getElementsByTagName("head")[0].appendChild(e)
}, n.initRatingHandler = function() {
return n.$(document).on("mouseover mouseout", "form a.spr-icon-star", function(e) {
var t, r, a;
return t = e.currentTarget, a = n.$(t).attr("data-value"), r = n.$(t).parent(), "mouseover" === e.type ? (r.find("a.spr-icon:lt(" + a + ")").addClass("spr-icon-star-hover"), r.find("a.spr-icon:gt(" + (a - 1) + ")").removeClass("spr-icon-star-hover")) : r.find("a.spr-icon").removeClass("spr-icon-star-hover")
})
}, n.initDomEls = function() {
return this.badgeEls = this.$(".shopify-product-reviews-badge[data-id]"), this.reviewEls = this.$("#shopify-product-reviews[data-id]"), this.$.each(this.reviewEls, (a = this, function(e, t) {
var r;
return r = a.$(t).attr("data-id"), a.elSettings[r] = {}, a.elSettings[r].reviews_el = "#" + (a.$(t).attr("data-reviews-prefix") ? a.$(t).attr("data-reviews-prefix") : "reviews_"), a.elSettings[r].form_el = "#" + (a.$(t).attr("data-form-prefix") ? a.$(t).attr("data-form-prefix") : "form_")
}));
var a
}, n.loadProducts = function() {
return this.$.each(this.reviewEls, (i = this, function(e, t) {
var r, a;
if (r = i.$(t).attr("data-id"), "false" !== i.$(t).attr("data-autoload")) return a = i.$.extend({
product_id: r,
version: i.version
}, i.extraAjaxParams), i.$.get(i.api_url + "/reviews/product", a, i.productCallback, "jsonp")
}));
var i
}, n.loadBadges = function() {
var e, t, r, a, i, n;
if (0 < (r = this.$.map(this.badgeEls, (n = this, function(e) {
return n.$(e).attr("data-id")
}))).length) {
for (t = 7, i = []; 0 < (e = r.splice(0, t)).length;) a = this.$.extend(this.extraAjaxParams, {
product_ids: e
}), i.push(this.$.get(this.api_url + "/reviews/badges", a, this.badgesCallback, "jsonp"));
return i
}
}, n.pageReviews = function(e) {
var t, r, a;
return a = this.$(e).data("product-id"), r = this.$(e).data("page"), t = this.$.extend({
page: r,
product_id: a
}, this.extraAjaxParams), this.$.get(this.api_url + "/reviews", t, this.paginateCallback, "jsonp"), !1
}, n.submitForm = function(e) {
var t, r, a;
return t = this.$(e).serializeObject(), t = this.$.extend(t, this.extraAjaxParams), t = (t = this.$.param(t)).replace(/%0D%0A/g, "%0A"), this.$.ajax({
url: this.api_url + "/reviews/create",
type: "GET",
dataType: "jsonp",
data: t,
success: this.formCallback,
beforeSend: (a = this, function() {
return a.$(".spr-button-primary").attr("disabled", "disabled")
}),
complete: (r = this, function() {
return r.$(".spr-button-primary").removeAttr("disabled")
})
}), !1
}, n.reportReview = function(e) {
var t;
return confirm("Are you sure you want to report this review as inappropriate?") && (t = this.$.extend({
id: e
}, this.extraAjaxParams), this.$.get(this.api_url + "/reviews/report", t, this.reportCallback, "jsonp")), !1
}, n.toggleReviews = function(e) {
return this.$("#shopify-product-reviews[data-id='" + e + "']").find(".spr-reviews").toggle()
}, n.toggleForm = function(e) {
return this.$("#shopify-product-reviews[data-id='" + e + "']").find(".spr-form").toggle()
}, n.setRating = function(e) {
var t, r, a;
return t = this.$(e).parents("form"), a = this.$(e).attr("data-value"), r = this.$(e).parent(), t.find("input[name='review[rating]']").val(a), this.setStarRating(a, r)
}, n.setStarRating = function(e, t) {
return t.find("a:lt(" + e + ")").removeClass("spr-icon-star-empty spr-icon-star-hover"), t.find("a:gt(" + (e - 1) + ")").removeClass("spr-icon-star-hover").addClass("spr-icon-star-empty")
}, n.badgesCallback = function(e) {
var r;
return r = e.badges, n.$.map(n.badgeEls, function(e) {
var t;
if (t = n.$(e).attr("data-id"), r[t] !== undefined) return n.$(e).replaceWith(r[t]), n.triggerEvent("spr:badge:loaded", {
id: t
})
})
}, n.productCallback = function(e) {
var t;
return t = e.remote_id.toString(), n.renderProduct(t, e.product_stripped, e.aggregate_rating), n.renderForm(t, e.form), n.renderReviews(t, e.reviews)
}, n.renderProduct = function(t, r, a) {
return this.$.map(this.reviewEls, (i = this, function(e) {
if (t === i.$(e).attr("data-id")) return i.$(e).html([innerShiv(r, !1), a]), i.triggerEvent("spr:product:loaded", {
id: t
})
}));
var i
}, n.renderForm = function(e, t) {
return this.$(this.elSettings[e].form_el + e).html(t), this.triggerEvent("spr:form:loaded", {
id: e
})
}, n.renderReviews = function(e, t) {
return n.$(n.elSettings[e].reviews_el + e).html(t), n.triggerEvent("spr:reviews:loaded", {
id: e
})
}, n.formCallback = function(e) {
var t, r, a, i;
return i = e.status, a = e.remote_id, r = e.form, (t = n.$(n.elSettings[a].form_el + a)).html(r), "failure" === i && n.initStarRating(t), "success" === i && (n.$("#shopify-product-reviews[data-id='" + a + "'] .spr-summary-actions-newreview").hide(), n.$(".spr-form-message-success").focus()), n.triggerEvent("spr:form:" + i, {
id: a
})
}, n.initStarRating = function(e) {
var t, r, a;
if ((a = e.find("input[name='review[rating]']")) && a.val()) return r = a.val(), t = e.find(".spr-starrating"), this.setStarRating(r, t)
}, n.paginateCallback = function(e) {
var t, r;
return r = e.remote_id.toString(), t = e.reviews, n.renderReviews(r, t)
}, n.reportCallback = function(e) {
var t;
return t = "#report_" + e.id, n.$(t).replaceWith("<span class='spr-review-reportreview'>" + n.$(t).attr("data-msg") + "</span>")
}, n.loadjQuery = function(e) {
return n.loadScript("//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", function() {
return n.$ = jQuery.noConflict(!0), e()
})
}, n.loadScript = function(e, t) {
var r;
return (r = document.createElement("script")).type = "text/javascript", r.readyState ? r.onreadystatechange = function() {
if ("loaded" === r.readyState || "complete" === r.readyState) return r.onreadystatechange = null, t()
} : r.onload = function() {
return t()
}, r.src = e, document.getElementsByTagName("head")[0].appendChild(r)
}, n.loadjQueryExtentions = function(r) {
return r.fn.serializeObject = function() {
var e, t;
return e = {}, t = this.serializeArray(), r.each(t, function() {
return e[this.name] ? (e[this.name].push || (e[this.name] = [e[this.name]]), e[this.name].push(this.value || "")) : e[this.name] = this.value || ""
}), e
}
}, n.triggerEvent = function(e, t) {
return this.$(document).trigger(e, t)
}, n
}(), SPR.loadStylesheet(), SPR.loadjQuery(function() {
return SPR.$.ajaxSetup({
cache: !1
}), SPR.loadjQueryExtentions(SPR.$), SPR.$(document).ready(function() {
return SPR.registerCallbacks(), SPR.initRatingHandler(), SPR.initDomEls(), SPR.loadProducts(), SPR.loadBadges()
})
})
}).call(this)
}("undefined" != typeof global ? global : "undefined" != typeof window && window);
Where their script is attached, you could try adding an onload attribute:
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.onload = "functionToRunMyOwnScript()"
If you can't access the place where it's attached, I personally don't think there's anything wrong with using the interval, as you're currently doing.
I think you have 2 options.
like you do it (check again and again if the changes are done)
use MutationObserver , if you wanna go this way, make sure to test this heavly.
To your solution, I think what you miss is a better check (sprCheck). If you say sometimes the function is triggered when the element exists, but is not at the right spot yet, then you also have to check if the element is on the right check before you continue.

how to move the controller code in factory

I have some code in my controller, but the code is reusable.. So I would like to move it in a factory and then use the factory everytime I need it... I am not able to move this code to the factory.. If I move it, nothing works anymore. Here the code I have in my controller and that I would like to move in the factory:
var app = angular.module("clock.app");
app.controller('timer',['$scope','$interval','$timeout','timerFactory',
function($scope, $interval,$timeout,timerFactory){
var framework7App = new Framework7();
var $$ = Dom7;
$scope.timeList = [
{"hour":0, "minutes":1, "seconds": 6},
{"hour":0, "minutes":3, "seconds": 180},
{"hour":0, "minutes":5, "seconds": 300}];
var today = new Date();
var arr,hour, minutes, seconds,convertedSec;
var getStoredList = JSON.parse(localStorage.getItem("timeListDetails"));
if(getStoredList !=null){
if(getStoredList.length != 0){
$scope.timeList = getStoredList;
}else{
localStorage.setItem("timeListDetails", JSON.stringify($scope.timeList));
}
}else{
getStoredList = $scope.timeList;
}
$scope.timerWithInterval = 0;
$scope.startTimerWithInterval = function() {
$scope.timerWithInterval = 0;
if($scope.myInterval){
$interval.cancel($scope.myInterval);
}
$scope.onInterval = function(){
$scope.timerWithInterval++;
}
$scope.myInterval = $interval($scope.onInterval,1000);
};
$scope.resetTimerWithInterval = function(){
$scope.timerWithInterval = 0;
$interval.cancel($scope.myInterval);
}
$scope.timeCounterInSeconds= function(seconds) {
$scope.startTimerWithInterval();
$timeout(function () {
$scope.timeCounter(seconds)
}, 1000);
};
$scope.timeCounter = function(seconds) {
if($scope.timerWithInterval==seconds) {
$scope.resetTimerWithInterval();
framework7App.alert('Time Over','');
}
else {
$timeout(function () {
$scope.timeCounter(seconds)
}, 1000);
}
};
$scope.submit = function() {
$scope.timeList.push({"hour":hour,
"minutes":minutes,
"seconds":seconds,
"convertedSec":convertedSec,
"timeFlag": true});
localStorage.setItem("timeListDetails", JSON.stringify($scope.timeList));
$scope.hidePopup();
};
$scope.displayPopup = function(){
$scope.popupAddTimer = true;
}
$scope.hidePopup = function(){
$scope.popupAddTimer = false;
}
timerFactory.picker();
}]);
I have used below factory method:
var factoryApp = angular.module('clock.factories');
factoryApp.factory('timerFactory',[
function() {
var timerFactory = {};
var framework7App = new Framework7();
var $$ = Dom7;
var today = new Date();
var arr,hour, minutes, seconds,convertedSec;
timerFactory.picker = function() {
framework7App.picker({
input: '#picker-date',
container: '#picker-date-container',
toolbar: false,
rotateEffect: true,
value: [today.getHours(), (today.getMinutes() < 10 ? '0' + today.getMinutes() : today.getMinutes()), today.getSeconds()],
onOpen: function(p){
},
formatValue: function (p, values, displayValues) {
arr = displayValues[0] + ':' + values[1] + ':' +values[2];
hour = displayValues[0];
var arrVal = arr.split(":");
convertedSec = (+arrVal[0] * 60 * 60 +(arrVal[1]) *60 +(+arrVal[2]));
minutes = values[1];
seconds = values[2];
return arr;
},
cols: [
// Hours
{
values: (function () {
var arr = [];
for (var i = 0; i <= 23; i++) { arr.push(i); }
return arr;
})(),
},
// Divider
{
divider: true,
content: ':'
},
// Minutes
{
values: (function () {
var arr = [];
for (var i = 0; i <= 59; i++) { arr.push(i < 10 ? '0' + i : i); }
return arr;
})(),
},
// Divider
{
divider: true,
content: ':'
},
// Seconds
{
values: (function () {
var arr = [];
for (var i = 0; i <= 59; i++) { arr.push(i < 10 ? '0' + i : i); }
return arr;
})(),
},
]
});
}
return timerFactory;
}]);
Successfully called picker method but unable to write another methods ($scope methods) in factory. Can anyone please guide me how to do that, as I am new to angularJS.
Also let me know, how to use variables from factory (i.e hour,seconds, minutes) into the controller?
It also not allowing me to use $scope and $interval.
no its not allowed $interval as well
To use the $interval service in a factory, simply inject it in the factory construction function:
app.factory("timerFactory", function($interval) {
//inject here ^^^^^^^^^^
var timer = {};
timer.count = 0;
var intervalPromise;
timer.start = function() {
if (intervalPromise) return;
intervalPromise = $interval(()=>(timer.count++), 1000);
};
timer.stop = function() {
$interval.cancel(intervalPromise);
intervalPromise = null;
};
return timer;
});
The DEMO on JSFiddle.

Issue with returning a string

I have written this code to get the value of the Timer in a div :
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = document.createElement("div");
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container.innerHTML = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
};
var boundTimeUpdate = timeUpdate.bind(time);
window.setInterval(boundTimeUpdate,10);
console.log(container);
return container;
})();
This code works when I link the var timerGenartor with a div. But, now I would like to return the var container into a string. So I changed my code to this : (I just changed the initialization of container and this value)
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = "";
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
};
var boundTimeUpdate = timeUpdate.bind(time);
window.setInterval(boundTimeUpdate,10);
console.log(container);
return container;
})();
With this modification nothing is returned or display in the console and I don't understand why. However, the comment "console.log" gives me good the timer. So, why the first console.log displays the good result and not the second one ?
The working code as you expected with two JS functions
// JS 1
var timerGenerator = (function() {
var time = {
centiSec: 0,
secondes: 0,
minutes: 0,
hours: 0
};
var container = "";
var timeDisplay = function() {
function smoothDisplay(value) {
return (value < 10 ? '0' : '') + value;
}
return "" + smoothDisplay(this.hours) + ":" + smoothDisplay(this.minutes) + ":" + smoothDisplay(this.secondes) + "." + smoothDisplay(this.centiSec);
};
var boundTimeDisplay = timeDisplay.bind(time);
var timeUpdate = function() {
container = boundTimeDisplay();
//console.log(container);
this.centiSec++;
if(this.centiSec === 100) {
this.centiSec = 0;
this.secondes++;
}
if(this.secondes === 60) {
this.secondes = 0;
this.minutes++;
}
if(this.minutes === 60) {
this.minutes = 0;
this.hours++;
}
return container;
};
var boundTimeUpdate = timeUpdate.bind(time);
return boundTimeUpdate;
})();
// JS 2
var spanGenerator = (function() {
var container = document.createElement('span');
window.setInterval(function(){
container.innerHTML = timerGenerator();
}, 10);
return container;
})();
document.getElementById('timer').appendChild(spanGenerator);
<div id="timer"></div>
It can be because your container is empty as it is initialized in timeUpdate function which is eventually called 10ms later(for the first time) because of the setInterval. U will have to call the timeUpdate function before putting it in setInterval.

Get/Set in Object-Oriented JavaScript

Counter = function ()
{
var _count;
_count = 0;
this.AddCounter = function()
{
_count++;
};
this.Reset = function ()
{
_count = 10;
};
Object.defineProperty( Counter, 'Value', {
get : function(){ return _count; },
set : function(){ _count = Value; },
configurable: true } );
}
Clock = function ()
{
var second = new Counter();
var minute = new Counter ();
var hour = new Counter();
this.Reset = function()
{
second.Reset();
minute.Reset();
hour.Reset();
};
this.Tick = function()
{
second.AddCounter();
if (second.Value == 60)
{
second.Reset();
minute.AddCounter();
if (minute.Value == 60)
{
minute.Reset();
hour.AddCounter();
}
}
};
this.ReadClock = function()
{
var sz = 0;
var mz = 0;
var hz = 0;
if (second.Value == 9)
{sz = null;}
if (minute.Value == 9)
{mz = null;}
if (hour.Value == 9)
{hz = null;}
document.getElementById("clock").innerHTML = ("" + hz + hour.Value + ":" + mz + minute.Value + ":" + sz +second.Value);
};
}
function Init()
{
var myClock = new Clock();
myClock.Tick();
myClock.ReadClock();
}
window.onload = Init;
The result I'm getting is:
0undefined:0undefined:0undefined
I think the issue is something to do with my Get/Set Property.
Also struggling to get the clock to tick, but that might be solvable once I put the Tick() function in a for loop.
You're creating the accessor property on the Counter constructor function (i.e. Counter.Value), not on the currently created instance:
function Counter() {
var _count = 0;
this.AddCounter = function() {
_count++;
};
this.Reset = function() {
_count = 10;
};
Object.defineProperty(this, 'Value', {
// ^^^^
get: function(){ return _count; },
set: function(val){ _count = val; },
configurable: true
});
}

Call .js file in UpdatePanel from CodeBehind

I am have been trying to teach myself ASP.NET and Javascript for a project and have been stuck on one problem for literally dozens of hours now.
I found a really nice javascript drag-and-drop list online, copied the source offered and split the css into a .css file, the javascript into a .js file and the HTML and reference into my asp.net page. It worked perfectly. Great!
Next, I replaced the javascript list with a static HTML list populated with the same data, wrapped it in an UpdatePanel and set up an "edit order" button to swap the static list's HTML for the javascript list's HTML when the button is pressed.
No Dice!
First, the initial runtime would throw up javascript errors explaining that certain objects could not be found. For example:
Microsoft JScript runtime error: Unable to get value of the property 'getElementsByTagName': object is null or undefined
Understood, because the elements aren't actually there yet. So I removed my reference to the .js in the main header and tried to register the .js file when the update panel is changed instead.
This is my problem.
Most explanations online have focused onRegisterClientScriptBlock, or RegisterStartupScript, or RegisterClientScriptInclude, or myLiteral and I can't get any of them to work. I also find that lots of online explanations are for running a single javascript function, whereas the script I am trying to get working has 700 lines-worth of them! Do I have to reference them all individually?
Sorry for the, no doubt, newbish question. I waited to ask until I had shouted at the screen with sufficient vitriol to warrant begging for help!
Thanks and regards.
EDIT: CODE
As Requested, this is the code:
VB.net (this is in a sub called by the button press. This is when I need to register my script)
Dim script As String = ""
Dim Labelb As Label = CType(FindControl("Labelb"), Label)
Dim con As SqlConnection
Dim cmd As SqlCommand
con = New SqlConnection("[connection string here]")
con.Open()
Dim lrd As SqlDataReader
cmd = New SqlCommand("[command string here]", con)
lrd = cmd.ExecuteReader
Dim item = ""
While lrd.Read()
item = item & "<li style=""position: relative;"">" & lrd(1) & "</li>"
End While
lrd.Close()
item = "<table id=""phonetics""><tbody><tr><td><ul id=""phonetic3"" class=""boxy"">" & item & "</ul></td></tr></tbody></table><br/>"
Labelb.Text = item
This is the HTML update panel in the asp.net master page:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"/>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Labelb" runat="server" Text="" />
</ContentTemplate>
</asp:UpdatePanel>
and finally, this is the .js file that I need to register
var ToolMan = {
events : function() {
if (!ToolMan._eventsFactory) throw "ToolMan Events module isn't loaded";
return ToolMan._eventsFactory
},
css : function() {
if (!ToolMan._cssFactory) throw "ToolMan CSS module isn't loaded";
return ToolMan._cssFactory
},
coordinates : function() {
if (!ToolMan._coordinatesFactory) throw "ToolMan Coordinates module isn't loaded";
return ToolMan._coordinatesFactory
},
drag : function() {
if (!ToolMan._dragFactory) throw "ToolMan Drag module isn't loaded";
return ToolMan._dragFactory
},
dragsort : function() {
if (!ToolMan._dragsortFactory) throw "ToolMan DragSort module isn't loaded";
return ToolMan._dragsortFactory
},
helpers : function() {
return ToolMan._helpers
},
cookies : function() {
if (!ToolMan._cookieOven) throw "ToolMan Cookie module isn't loaded";
return ToolMan._cookieOven
},
junkdrawer : function() {
return ToolMan._junkdrawer
}
}
ToolMan._helpers = {
map : function(array, func) {
for (var i = 0, n = array.length; i < n; i++) func(array[i])
},
nextItem : function(item, nodeName) {
if (item == null) return
var next = item.nextSibling
while (next != null) {
if (next.nodeName == nodeName) return next
next = next.nextSibling
}
return null
},
previousItem : function(item, nodeName) {
var previous = item.previousSibling
while (previous != null) {
if (previous.nodeName == nodeName) return previous
previous = previous.previousSibling
}
return null
},
moveBefore : function(item1, item2) {
var parent = item1.parentNode
parent.removeChild(item1)
parent.insertBefore(item1, item2)
},
moveAfter : function(item1, item2) {
var parent = item1.parentNode
parent.removeChild(item1)
parent.insertBefore(item1, item2 ? item2.nextSibling : null)
}
}
/**
* scripts without a proper home
*
* stuff here is subject to change unapologetically and without warning
*/
ToolMan._junkdrawer = {
serializeList : function(list) {
var items = list.getElementsByTagName("li")
var array = new Array()
for (var i = 0, n = items.length; i < n; i++) {
var item = items[i]
array.push(ToolMan.junkdrawer()._identifier(item))
}
return array.join('|')
},
inspectListOrder : function(id) {
alert(ToolMan.junkdrawer().serializeList(document.getElementById(id)))
},
restoreListOrder : function(listID) {
var list = document.getElementById(listID)
if (list == null) return
var cookie = ToolMan.cookies().get("list-" + listID)
if (!cookie) return;
var IDs = cookie.split('|')
var items = ToolMan.junkdrawer()._itemsByID(list)
for (var i = 0, n = IDs.length; i < n; i++) {
var itemID = IDs[i]
if (itemID in items) {
var item = items[itemID]
list.removeChild(item)
list.insertBefore(item, null)
}
}
},
_identifier : function(item) {
var trim = ToolMan.junkdrawer().trim
var identifier
identifier = trim(item.getAttribute("id"))
if (identifier != null && identifier.length > 0) return identifier;
identifier = trim(item.getAttribute("itemID"))
if (identifier != null && identifier.length > 0) return identifier;
// FIXME: strip out special chars or make this an MD5 hash or something
return trim(item.innerHTML)
},
_itemsByID : function(list) {
var array = new Array()
var items = list.getElementsByTagName('li')
for (var i = 0, n = items.length; i < n; i++) {
var item = items[i]
array[ToolMan.junkdrawer()._identifier(item)] = item
}
return array
},
trim : function(text) {
if (text == null) return null
return text.replace(/^(\s+)?(.*\S)(\s+)?$/, '$2')
}
}
ToolMan._eventsFactory = {
fix : function(event) {
if (!event) event = window.event
if (event.target) {
if (event.target.nodeType == 3) event.target = event.target.parentNode
} else if (event.srcElement) {
event.target = event.srcElement
}
return event
},
register : function(element, type, func) {
if (element.addEventListener) {
element.addEventListener(type, func, false)
} else if (element.attachEvent) {
if (!element._listeners) element._listeners = new Array()
if (!element._listeners[type]) element._listeners[type] = new Array()
var workaroundFunc = function() {
func.apply(element, new Array())
}
element._listeners[type][func] = workaroundFunc
element.attachEvent('on' + type, workaroundFunc)
}
},
unregister : function(element, type, func) {
if (element.removeEventListener) {
element.removeEventListener(type, func, false)
} else if (element.detachEvent) {
if (element._listeners
&& element._listeners[type]
&& element._listeners[type][func]) {
element.detachEvent('on' + type,
element._listeners[type][func])
}
}
}
}
ToolMan._cssFactory = {
readStyle : function(element, property) {
if (element.style[property]) {
return element.style[property]
} else if (element.currentStyle) {
return element.currentStyle[property]
} else if (document.defaultView && document.defaultView.getComputedStyle) {
var style = document.defaultView.getComputedStyle(element, null)
return style.getPropertyValue(property)
} else {
return null
}
}
}
/* FIXME: assumes position styles are specified in 'px' */
ToolMan._coordinatesFactory = {
create : function(x, y) {
// FIXME: Safari won't parse 'throw' and aborts trying to do anything with this file
//if (isNaN(x) || isNaN(y)) throw "invalid x,y: " + x + "," + y
return new _ToolManCoordinate(this, x, y)
},
origin : function() {
return this.create(0, 0)
},
/*
* FIXME: Safari 1.2, returns (0,0) on absolutely positioned elements
*/
topLeftPosition : function(element) {
var left = parseInt(ToolMan.css().readStyle(element, "left"))
var left = isNaN(left) ? 0 : left
var top = parseInt(ToolMan.css().readStyle(element, "top"))
var top = isNaN(top) ? 0 : top
return this.create(left, top)
},
bottomRightPosition : function(element) {
return this.topLeftPosition(element).plus(this._size(element))
},
topLeftOffset : function(element) {
var offset = this._offset(element)
var parent = element.offsetParent
while (parent) {
offset = offset.plus(this._offset(parent))
parent = parent.offsetParent
}
return offset
},
bottomRightOffset : function(element) {
return this.topLeftOffset(element).plus(
this.create(element.offsetWidth, element.offsetHeight))
},
scrollOffset : function() {
if (window.pageXOffset) {
return this.create(window.pageXOffset, window.pageYOffset)
} else if (document.documentElement) {
return this.create(
document.body.scrollLeft + document.documentElement.scrollLeft,
document.body.scrollTop + document.documentElement.scrollTop)
} else if (document.body.scrollLeft >= 0) {
return this.create(document.body.scrollLeft, document.body.scrollTop)
} else {
return this.create(0, 0)
}
},
clientSize : function() {
if (window.innerHeight >= 0) {
return this.create(window.innerWidth, window.innerHeight)
} else if (document.documentElement) {
return this.create(document.documentElement.clientWidth,
document.documentElement.clientHeight)
} else if (document.body.clientHeight >= 0) {
return this.create(document.body.clientWidth,
document.body.clientHeight)
} else {
return this.create(0, 0)
}
},
/**
* mouse coordinate relative to the window (technically the
* browser client area) i.e. the part showing your page
*
* NOTE: in Safari the coordinate is relative to the document
*/
mousePosition : function(event) {
event = ToolMan.events().fix(event)
return this.create(event.clientX, event.clientY)
},
/**
* mouse coordinate relative to the document
*/
mouseOffset : function(event) {
event = ToolMan.events().fix(event)
if (event.pageX >= 0 || event.pageX < 0) {
return this.create(event.pageX, event.pageY)
} else if (event.clientX >= 0 || event.clientX < 0) {
return this.mousePosition(event).plus(this.scrollOffset())
}
},
_size : function(element) {
/* TODO: move to a Dimension class */
return this.create(element.offsetWidth, element.offsetHeight)
},
_offset : function(element) {
return this.create(element.offsetLeft, element.offsetTop)
}
}
function _ToolManCoordinate(factory, x, y) {
this.factory = factory
this.x = isNaN(x) ? 0 : x
this.y = isNaN(y) ? 0 : y
}
_ToolManCoordinate.prototype = {
toString : function() {
return "(" + this.x + "," + this.y + ")"
},
plus : function(that) {
return this.factory.create(this.x + that.x, this.y + that.y)
},
minus : function(that) {
return this.factory.create(this.x - that.x, this.y - that.y)
},
min : function(that) {
return this.factory.create(
Math.min(this.x , that.x), Math.min(this.y , that.y))
},
max : function(that) {
return this.factory.create(
Math.max(this.x , that.x), Math.max(this.y , that.y))
},
constrainTo : function (one, two) {
var min = one.min(two)
var max = one.max(two)
return this.max(min).min(max)
},
distance : function (that) {
return Math.sqrt(Math.pow(this.x - that.x, 2) + Math.pow(this.y - that.y, 2))
},
reposition : function(element) {
element.style["top"] = this.y + "px"
element.style["left"] = this.x + "px"
}
}
ToolMan._dragFactory = {
createSimpleGroup : function(element, handle) {
handle = handle ? handle : element
var group = this.createGroup(element)
group.setHandle(handle)
group.transparentDrag()
group.onTopWhileDragging()
return group
},
createGroup : function(element) {
var group = new _ToolManDragGroup(this, element)
var position = ToolMan.css().readStyle(element, 'position')
if (position == 'static') {
element.style["position"] = 'relative'
} else if (position == 'absolute') {
/* for Safari 1.2 */
ToolMan.coordinates().topLeftOffset(element).reposition(element)
}
// TODO: only if ToolMan.isDebugging()
group.register('draginit', this._showDragEventStatus)
group.register('dragmove', this._showDragEventStatus)
group.register('dragend', this._showDragEventStatus)
return group
},
_showDragEventStatus : function(dragEvent) {
window.status = dragEvent.toString()
},
constraints : function() {
return this._constraintFactory
},
_createEvent : function(type, event, group) {
return new _ToolManDragEvent(type, event, group)
}
}
function _ToolManDragGroup(factory, element) {
this.factory = factory
this.element = element
this._handle = null
this._thresholdDistance = 0
this._transforms = new Array()
// TODO: refactor into a helper object, move into events.js
this._listeners = new Array()
this._listeners['draginit'] = new Array()
this._listeners['dragstart'] = new Array()
this._listeners['dragmove'] = new Array()
this._listeners['dragend'] = new Array()
}
_ToolManDragGroup.prototype = {
/*
* TODO:
* - unregister(type, func)
* - move custom event listener stuff into Event library
* - keyboard nudging of "selected" group
*/
setHandle : function(handle) {
var events = ToolMan.events()
handle.toolManDragGroup = this
events.register(handle, 'mousedown', this._dragInit)
handle.onmousedown = function() { return false }
if (this.element != handle)
events.unregister(this.element, 'mousedown', this._dragInit)
},
register : function(type, func) {
this._listeners[type].push(func)
},
addTransform : function(transformFunc) {
this._transforms.push(transformFunc)
},
verticalOnly : function() {
this.addTransform(this.factory.constraints().vertical())
},
horizontalOnly : function() {
this.addTransform(this.factory.constraints().horizontal())
},
setThreshold : function(thresholdDistance) {
this._thresholdDistance = thresholdDistance
},
transparentDrag : function(opacity) {
var opacity = typeof(opacity) != "undefined" ? opacity : 0.75;
var originalOpacity = ToolMan.css().readStyle(this.element, "opacity")
this.register('dragstart', function(dragEvent) {
var element = dragEvent.group.element
element.style.opacity = opacity
element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')'
})
this.register('dragend', function(dragEvent) {
var element = dragEvent.group.element
element.style.opacity = originalOpacity
element.style.filter = 'alpha(opacity=100)'
})
},
onTopWhileDragging : function(zIndex) {
var zIndex = typeof(zIndex) != "undefined" ? zIndex : 100000;
var originalZIndex = ToolMan.css().readStyle(this.element, "z-index")
this.register('dragstart', function(dragEvent) {
dragEvent.group.element.style.zIndex = zIndex
})
this.register('dragend', function(dragEvent) {
dragEvent.group.element.style.zIndex = originalZIndex
})
},
_dragInit : function(event) {
event = ToolMan.events().fix(event)
var group = document.toolManDragGroup = this.toolManDragGroup
var dragEvent = group.factory._createEvent('draginit', event, group)
group._isThresholdExceeded = false
group._initialMouseOffset = dragEvent.mouseOffset
group._grabOffset = dragEvent.mouseOffset.minus(dragEvent.topLeftOffset)
ToolMan.events().register(document, 'mousemove', group._drag)
document.onmousemove = function() { return false }
ToolMan.events().register(document, 'mouseup', group._dragEnd)
group._notifyListeners(dragEvent)
},
_drag : function(event) {
event = ToolMan.events().fix(event)
var coordinates = ToolMan.coordinates()
var group = this.toolManDragGroup
if (!group) return
var dragEvent = group.factory._createEvent('dragmove', event, group)
var newTopLeftOffset = dragEvent.mouseOffset.minus(group._grabOffset)
// TODO: replace with DragThreshold object
if (!group._isThresholdExceeded) {
var distance =
dragEvent.mouseOffset.distance(group._initialMouseOffset)
if (distance < group._thresholdDistance) return
group._isThresholdExceeded = true
group._notifyListeners(
group.factory._createEvent('dragstart', event, group))
}
for (i in group._transforms) {
var transform = group._transforms[i]
newTopLeftOffset = transform(newTopLeftOffset, dragEvent)
}
var dragDelta = newTopLeftOffset.minus(dragEvent.topLeftOffset)
var newTopLeftPosition = dragEvent.topLeftPosition.plus(dragDelta)
newTopLeftPosition.reposition(group.element)
dragEvent.transformedMouseOffset = newTopLeftOffset.plus(group._grabOffset)
group._notifyListeners(dragEvent)
var errorDelta = newTopLeftOffset.minus(coordinates.topLeftOffset(group.element))
if (errorDelta.x != 0 || errorDelta.y != 0) {
coordinates.topLeftPosition(group.element).plus(errorDelta).reposition(group.element)
}
},
_dragEnd : function(event) {
event = ToolMan.events().fix(event)
var group = this.toolManDragGroup
var dragEvent = group.factory._createEvent('dragend', event, group)
group._notifyListeners(dragEvent)
this.toolManDragGroup = null
ToolMan.events().unregister(document, 'mousemove', group._drag)
document.onmousemove = null
ToolMan.events().unregister(document, 'mouseup', group._dragEnd)
},
_notifyListeners : function(dragEvent) {
var listeners = this._listeners[dragEvent.type]
for (i in listeners) {
listeners[i](dragEvent)
}
}
}
function _ToolManDragEvent(type, event, group) {
this.type = type
this.group = group
this.mousePosition = ToolMan.coordinates().mousePosition(event)
this.mouseOffset = ToolMan.coordinates().mouseOffset(event)
this.transformedMouseOffset = this.mouseOffset
this.topLeftPosition = ToolMan.coordinates().topLeftPosition(group.element)
this.topLeftOffset = ToolMan.coordinates().topLeftOffset(group.element)
}
_ToolManDragEvent.prototype = {
toString : function() {
return "mouse: " + this.mousePosition + this.mouseOffset + " " +
"xmouse: " + this.transformedMouseOffset + " " +
"left,top: " + this.topLeftPosition + this.topLeftOffset
}
}
ToolMan._dragFactory._constraintFactory = {
vertical : function() {
return function(coordinate, dragEvent) {
var x = dragEvent.topLeftOffset.x
return coordinate.x != x
? coordinate.factory.create(x, coordinate.y)
: coordinate
}
},
horizontal : function() {
return function(coordinate, dragEvent) {
var y = dragEvent.topLeftOffset.y
return coordinate.y != y
? coordinate.factory.create(coordinate.x, y)
: coordinate
}
}
}
ToolMan._dragsortFactory = {
makeSortable : function(item) {
var group = ToolMan.drag().createSimpleGroup(item)
group.register('dragstart', this._onDragStart)
group.register('dragmove', this._onDragMove)
group.register('dragend', this._onDragEnd)
return group
},
/**
* Iterates over a list's items, making them sortable, applying
* optional functions to each item.
*
* example: makeListSortable(myList, myFunc1, myFunc2, ... , myFuncN)
*/
makeListSortable : function(list) {
var helpers = ToolMan.helpers()
var coordinates = ToolMan.coordinates()
var items = list.getElementsByTagName("li")
helpers.map(items, function(item) {
var dragGroup = dragsort.makeSortable(item)
dragGroup.setThreshold(4)
var min, max
dragGroup.addTransform(function(coordinate, dragEvent) {
return coordinate.constrainTo(min, max)
})
dragGroup.register('dragstart', function() {
var items = list.getElementsByTagName("li")
min = max = coordinates.topLeftOffset(items[0])
for (var i = 1, n = items.length; i < n; i++) {
var offset = coordinates.topLeftOffset(items[i])
min = min.min(offset)
max = max.max(offset)
}
})
})
for (var i = 1, n = arguments.length; i < n; i++)
helpers.map(items, arguments[i])
},
_onDragStart : function(dragEvent) {
},
_onDragMove : function(dragEvent) {
var helpers = ToolMan.helpers()
var coordinates = ToolMan.coordinates()
var item = dragEvent.group.element
var xmouse = dragEvent.transformedMouseOffset
var moveTo = null
var previous = helpers.previousItem(item, item.nodeName)
while (previous != null) {
var bottomRight = coordinates.bottomRightOffset(previous)
if (xmouse.y <= bottomRight.y && xmouse.x <= bottomRight.x) {
moveTo = previous
}
previous = helpers.previousItem(previous, item.nodeName)
}
if (moveTo != null) {
helpers.moveBefore(item, moveTo)
return
}
var next = helpers.nextItem(item, item.nodeName)
while (next != null) {
var topLeft = coordinates.topLeftOffset(next)
if (topLeft.y <= xmouse.y && topLeft.x <= xmouse.x) {
moveTo = next
}
next = helpers.nextItem(next, item.nodeName)
}
if (moveTo != null) {
helpers.moveBefore(item, helpers.nextItem(moveTo, item.nodeName))
return
}
},
_onDragEnd : function(dragEvent) {
ToolMan.coordinates().create(0, 0).reposition(dragEvent.group.element)
}
}
ToolMan._cookieOven = {
set : function(name, value, expirationInDays) {
if (expirationInDays) {
var date = new Date()
date.setTime(date.getTime() + (expirationInDays * 24 * 60 * 60 * 1000))
var expires = "; expires=" + date.toGMTString()
} else {
var expires = ""
}
document.cookie = name + "=" + value + expires + "; path=/"
},
get : function(name) {
var namePattern = name + "="
var cookies = document.cookie.split(';')
for(var i = 0, n = cookies.length; i < n; i++) {
var c = cookies[i]
while (c.charAt(0) == ' ') c = c.substring(1, c.length)
if (c.indexOf(namePattern) == 0)
return c.substring(namePattern.length, c.length)
}
return null
},
eraseCookie : function(name) {
createCookie(name, "", -1)
}
}
var dragsort = ToolMan.dragsort()
var junkdrawer = ToolMan.junkdrawer()
window.onload = function() {
junkdrawer.restoreListOrder("phonetic3")
//junkdrawer.restoreListOrder("twolists1")
//junkdrawer.restoreListOrder("twolists2")
dragsort.makeListSortable(document.getElementById("phonetic3"),
verticalOnly, saveOrder)
/*
dragsort.makeListSortable(document.getElementById("twolists1"),
saveOrder)
dragsort.makeListSortable(document.getElementById("twolists2"),
saveOrder)
*/
}
function verticalOnly(item) {
item.toolManDragGroup.verticalOnly()
}
function speak(id, what) {
var element = document.getElementById(id);
element.innerHTML = 'Clicked ' + what;
}
function saveOrder(item) {
var group = item.toolManDragGroup
var list = group.element.parentNode
var id = list.getAttribute("id")
if (id == null) return
group.register('dragend', function() {
ToolMan.cookies().set("list-" + id,
junkdrawer.serializeList(list), 365)
})
}
//-->
Thanks so much for your support!
Regards,
If you are seeing "value of the property 'getElementsByTagName' object is null or undefined" there is one of two possible issues:
1) your script file is not properly loaded.
2) You are calling 'getElementsByTagName' inappropriately.
Since you haven't posted any sample code, it would be very difficult for anybody to provide a definitive answer to your question.

Categories