one function in 2 controllers[JS] - javascript

Here is my question: I've got this little JS programm here in which are 2 controllers.. my problem is I need one function in both controllers (data.duration). Because one time I need the function for the features themselves and one time for the summary. Btw I get my informations via a JSON report and the function proofes itself if it is a feature or only a value. At the time the function is in the code 2 times...
So is there a way use the function in both controllers?
(function() {
var loader = ['$http',
function($http) {
return $http.get('report.json')
.success(function(data) {
function getFailedScenarioCount(feature) {
var failedScenarios = 0;
feature.scenarios.forEach(function(scenario) {
if (scenario.result.failedStepCount)
failedScenarios++;
});
return failedScenarios;
}
function getUnknownScenarioCount(feature) {
var unknownScenarios = 0;
feature.scenarios.forEach(function(scenario) {
if (scenario.result.unknownStepCount)
unknownScenarios++;
});
return unknownScenarios;
}
angular.forEach(data.features, function(feature) {
if (feature.scenarios.length) {
feature.result.failedScenarioCount = getFailedScenarioCount(feature);
feature.result.unknownScenarioCount = getUnknownScenarioCount(feature);
feature.result.passedScenarioCount = feature.result.scenarioCount - feature.result.failedScenarioCount - feature.result.unknownScenarioCount;
if (feature.result.failedScenarioCount === 0)
feature.result.failedScenarioCount = null;
if (feature.result.unknownScenarioCount === 0)
feature.result.unknownScenarioCount = null;
if (feature.result.passedScenarioCount === 0)
feature.result.passedScenarioCount = null;
}
feature.status = feature.result.failedScenarioCount ? "FAILED" : "OK";
angular.forEach(feature.scenarios, function(scenario) {
angular.forEach(scenario.steps, function(step) {
if (step.result.status === "undefined")
step.result.status = "unknown";
});
scenario.status = scenario.result.failedStepCount ? "failed" : (scenario.result.unknownStepCount ? 'unknown' : 'passed');
});
});
data.duration = function(feature) {
var day = 0;
var h = 0;
var min = 0;
var sec = 0;
var value = 0;
var substract = function(v, b) {
var result = v - (b);
return result;
};
if (isNaN(feature)) {
value = feature.result.duration;
} else {
value = feature;
}
console.log("value: " + value);
if (value % (1000000000 * 60 * 60 * 24) >= 0) //day
{
day = (value / (1000000000 * 60 * 60 * 24)) | 0;
value = substract(value, (day * (1000000000 * 60 * 60 * 24)));
}
if (value % (1000000000 * 60 * 60) >= 0) //hour
{
h = (value / (1000000000 * 60 * 60)) | 0;
value = substract(value, (h * (1000000000 * 60 * 60)));
if (h % 24 === 0 && h !== 0) {
day++;
h = 0;
}
}
if (value % (1000000000 * 60) >= 0) //minute
{
min = (value / (1000000000 * 60)) | 0;
value = substract(value, (min * (1000000000 * 60)));
if (min % 60 === 0 && min !== 0) {
h++;
min = 0;
}
}
if (value % (1000000000) >= 0) //second
{
sec = (value / (1000000000)) | 0;
value = substract(value, (sec * (1000000000)));
if (sec % 60 === 0 && sec !== 0) {
min++;
sec = 0;
}
}
if (day === 0 && h === 0 && min === 0 && sec === 0) {
var msec = 0;
if (value % 1000000 >= 0) {
msec = (value / 1000000) | 0;
}
return msec > 0 ? msec + 'ms' : '<1ms';
} else if (day > 0) {
return (' ' + '(' + day + 'Day/s) ' + ' ' + ' ' + h + ' ' + ':' + ' ' + min + ' ' + ':' + ' ' + sec);
} else {
return (' ' + h + ' ' + ':' + ' ' + min + ' ' + ':' + ' ' + sec);
}
};
});
}
];
var app = window.angular.module('cucumber', ['ui.bootstrap']);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.when('/features', {
templateUrl: 'features.html',
controller: 'FeatureListCtrl',
resolve: {
report: loader
}
}).when('/feature/:featureId', {
templateUrl: 'feature.html',
controller: 'FeatureCtrl',
resolve: {
report: loader
}
}).otherwise({
redirectTo: '/features'
});
}
]);
app.controller('FeatureListCtrl', function($rootScope, $scope, $location, $filter, report) {
$scope.report = report.data;
$rootScope.reportDate = $scope.report.date;
$scope.duration = $scope.report.duration;
$scope.featureDetails = function(feature) {
$location.path('/feature/' + feature.id);
};
$scope.sum = function(features, field) {
if (!features) return null;
var sum = features.reduce(function(sum, feature) {
var value = parseInt(feature.result[field], 10);
return isNaN(value) ? sum : sum + value;
}, 0);
return sum > 0 ? sum : null;
};
$scope.$watch("searchText", function(query) {
$scope.filteredFeatures = $filter("filter")($scope.report.features, query);
});
$scope.isCollapsed = true;
});
app.controller('FeatureCtrl', function($rootScope, $scope, $location, $routeParams, report) {
$scope.duration = report.data.duration;
function getFeature(featureId, features) {
for (var i = 0; i < features.length; i++) {
if (featureId === features[i].id) {
return features[i];
}
}
}
$scope.feature = getFeature($routeParams.featureId, report.data.features);
$rootScope.reportDate = report.data.date;
});
}());

Pretty simple, write a service and inject it into both controllers.
app.service("utilityService", function () {
return {
duration: function (feature) {
...your code
}
}
});
Then inject it into each controller:
app.controller('FeatureListCtrl', function($rootScope, $scope, $location, $filter, report, utilityService) {
});
Then reference it:
utilityService.duration($scope.whatEverData)

Related

how to modify below function to read 3 decimal places

I am using tafgeet javascript function to convert numbers into Arabic words, but the problem is that it supports only 2 decimal places, how can I modify the function to make it read 3 decimal places:
It actually translates upto a million on the left hand side, so it would be possible to apply the same methodology on the right side.
I tried to fiddle with it, but it doesn't work. I am posting the original javascript.
/**
* TafgeetJS module.
* #module TafgeetJS
* #description Converts currency digits into written Arabic words
* #author Mohammed Mahgoub <mmahgoub#gmail.com>
*/
function Tafgeet(digit) {
var currency = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "SDG";
//Split fractions
var splitted = digit.toString().split(".");
this.fraction = 0;
if (splitted.length > 1) {
var fraction = parseInt(splitted[1]);
if (fraction >= 1 && fraction <= 99) {
this.fraction = splitted[1].length === 1 ? fraction * 10 : fraction;
} else {
//trim it
var trimmed = Array.from(splitted[1]);
this.fraction = "" + trimmed[0] + trimmed[1];
}
}
this.digit = splitted[0];
this.currency = currency;
}
Tafgeet.prototype.parse = function () {
var serialized = [];
var tmp = [];
var inc = 1;
var count = this.length();
var column = this.getColumnIndex();
if (count >= 16) {
console.error("Number out of range!");
return;
}
//Sperate the number into columns
Array.from(this.digit.toString()).reverse().forEach(function (d, i) {
tmp.push(d);
if (inc == 3) {
serialized.unshift(tmp);
tmp = [];
inc = 0;
}
if (inc == 0 && count - (i + 1) < 3 && count - (i + 1) != 0) {
serialized.unshift(tmp);
}
inc++;
});
// Generate concatenation array
var concats = []
for (i = this.getColumnIndex(); i < this.columns.length; i++) {
concats[i] = " و";
}
//We do not need some "و"s check last column if 000 drill down until otherwise
if (this.digit > 999) {
if (parseInt(Array.from(serialized[serialized.length - 1]).join("")) == 0) {
concats[parseInt(concats.length - 1)] = ""
for (i = serialized.length - 1; i >= 1; i--) {
if (parseInt(Array.from(serialized[i]).join("")) == 0) {
concats[i] = ""
} else {
break;
}
}
}
}
var str = "";
str += "فقط ";
if (this.length() >= 1 && this.length() <= 3) {
str += this.read(this.digit);
} else {
for (i = 0; i < serialized.length; i++) {
var joinedNumber = parseInt(serialized[i].reverse().join(""));
if (joinedNumber == 0) {
column++;
continue;
}
if (column == null || column + 1 > this.columns.length) {
str += this.read(joinedNumber);
} else {
str += this.addSuffixPrefix(serialized[i], column) + concats[column];
}
column++;
}
}
if (this.currency != "") {
if (this.digit >= 3 && this.digit <= 10) {
str += " " + this.currencies[this.currency].plural;
} else {
str += " " + this.currencies[this.currency].singular;
}
if (this.fraction != 0) {
if (this.digit >= 3 && this.digit <= 10) {
str +=
" و" +
this.read(this.fraction) +
" " +
this.currencies[this.currency].fractions;
} else {
str +=
" و" +
this.read(this.fraction) +
" " +
this.currencies[this.currency].fraction;
}
}
}
str += " لا غير";
return str;
};
Tafgeet.prototype.addSuffixPrefix = function (arr, column) {
if (arr.length == 1) {
if (parseInt(arr[0]) == 1) {
return this[this.columns[column]].singular;
}
if (parseInt(arr[0]) == 2) {
return this[this.columns[column]].binary;
}
if (parseInt(arr[0]) > 2 && parseInt(arr[0]) <= 9) {
return (
this.readOnes(parseInt(arr[0])) +
" " +
this[this.columns[column]].plural
);
}
} else {
var joinedNumber = parseInt(arr.join(""));
if (joinedNumber > 1) {
return this.read(joinedNumber) + " " + this[this.columns[column]].singular;
} else {
return this[this.columns[column]].singular;
}
}
};
Tafgeet.prototype.read = function (d) {
var str = "";
var len = Array.from(d.toString()).length;
if (len == 1) {
str += this.readOnes(d);
} else if (len == 2) {
str += this.readTens(d);
} else if (len == 3) {
str += this.readHundreds(d);
}
return str;
};
Tafgeet.prototype.readOnes = function (d) {
if (d == 0) return;
return this.ones["_" + d.toString()];
};
Tafgeet.prototype.readTens = function (d) {
if (Array.from(d.toString())[1] === "0") {
return this.tens["_" + d.toString()];
}
if (d > 10 && d < 20) {
return this.teens["_" + d.toString()];
}
if (d > 19 && d < 100 && Array.from(d.toString())[1] !== "0") {
return (
this.readOnes(Array.from(d.toString())[1]) +
" و" +
this.tens["_" + Array.from(d.toString())[0] + "0"]
);
}
};
Tafgeet.prototype.readHundreds = function (d) {
var str = "";
str += this.hundreds["_" + Array.from(d.toString())[0] + "00"];
if (
Array.from(d.toString())[1] === "0" &&
Array.from(d.toString())[2] !== "0"
) {
str += " و" + this.readOnes(Array.from(d.toString())[2]);
}
if (Array.from(d.toString())[1] !== "0") {
str +=
" و" +
this.readTens(
(Array.from(d.toString())[1] + Array.from(d.toString())[2]).toString()
);
}
return str;
};
Tafgeet.prototype.length = function () {
return Array.from(this.digit.toString()).length;
};
Tafgeet.prototype.getColumnIndex = function () {
var column = null;
if (this.length() > 12) {
column = 0;
} else if (this.length() <= 12 && this.length() > 9) {
column = 1;
} else if (this.length() <= 9 && this.length() > 6) {
column = 2;
} else if (this.length() <= 6 && this.length() >= 4) {
column = 3;
}
return column;
};
Tafgeet.prototype.ones = {
_1: "واحد",
_2: "ٱثنين",
_3: "ثلاثة",
_4: "أربعة",
_5: "خمسة",
_6: "ستة",
_7: "سبعة",
_8: "ثمانية",
_9: "تسعة"
};
Tafgeet.prototype.teens = {
_11: "أحد عشر",
_12: "أثني عشر",
_13: "ثلاثة عشر",
_14: "أربعة عشر",
_15: "خمسة عشر",
_16: "ستة عشر",
_17: "سبعة عشر",
_18: "ثمانية عشر",
_19: "تسعة عشر"
};
Tafgeet.prototype.tens = {
_10: "عشرة",
_20: "عشرون",
_30: "ثلاثون",
_40: "أربعون",
_50: "خمسون",
_60: "ستون",
_70: "سبعون",
_80: "ثمانون",
_90: "تسعون"
};
Tafgeet.prototype.hundreds = {
_100: "مائة",
_200: "مائتين",
_300: "ثلاثمائة",
_400: "أربعمائة",
_500: "خمسمائة",
_600: "ستمائة",
_700: "سبعمائة",
_800: "ثمانمائة",
_900: "تسعمائة"
};
Tafgeet.prototype.thousands = {
singular: "ألف",
binary: "ألفين",
plural: "ألآف"
};
Tafgeet.prototype.milions = {
singular: "مليون",
binary: "مليونين",
plural: "ملايين"
};
Tafgeet.prototype.bilions = {
singular: "مليار",
binary: "مليارين",
plural: "مليارات"
};
Tafgeet.prototype.trilions = {
singular: "ترليون",
binary: "ترليونين",
plural: "ترليونات"
};
Tafgeet.prototype.columns = ["trilions", "bilions", "milions", "thousands"];
Tafgeet.prototype.currencies = {
SDG: {
singular: "جنيه سوداني",
plural: "جنيهات سودانية",
fraction: "قرش",
fractions: "قروش"
},
SAR: {
singular: "ريال سعودي",
plural: "ريالات سعودية",
fraction: "هللة",
fractions: "هللات"
},
QAR: {
singular: "ريال قطري",
plural: "ريالات قطرية",
fraction: "درهم",
fractions: "دراهم"
},
AED: {
singular: "درهم أماراتي",
plural: "دراهم أماراتية",
fraction: "فلس",
fractions: "فلوس"
},
EGP: {
singular: "جنيه مصري",
plural: "جنيهات مصرية",
fraction: "قرش",
fractions: "قروش"
},
USD: {
singular: "دولار أمريكي",
plural: "دولارات أمريكية",
fraction: "سنت",
fractions: "سنتات"
},
AUD: {
singular: "دولار أسترالي",
plural: "دولارات أسترالية",
fraction: "سنت",
fractions: "سنتات"
},
TND: {
singular: "دينار تونسي",
plural: "دنانير تونسية",
fraction: "مليم",
fractions: "مليمات"
}
};
module.exports = Tafgeet;
Thanks.
Change this:
this.fraction = "" + trimmed[0] + trimmed[1];
To this:
this.fraction = "" + trimmed[0] + trimmed[1] + trimmed[2];
But this is a crude solution you need to do some validations and checks before you deploy this to production

How to use Formatting for large numbers

I have a large number issue here. I'm using the nFormatter for large numbers in javascript but i have no idea how to use it with my existing code.
Here is the formatter im using.
function nFormatter(num) {
if (num >= 1000000000000) {
return (num / 1000000000000).toFixed(1).replace(/\.0$/, '') + 'Trillion';
}
if (num >= 1000000000) {
return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + 'Billion';
}
if (num >= 1000000) {
return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'Million';
}
if (num >= 1000) {
return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'Thousand';
}
return num;
}
nFormatter;
I need to add this code to my other code but i am not sure how i am going to do this.
Here is my current code.
var gameProfit = 5000;
var tinyOwned = 0;
var tinyCost = 5000;
var tinyIncome = 0;
function tinyGamePlay() {
if (gameProfit >= tinyCost) {
tinyOwned++;
gameProfit -= tinyCost;
tinyIncome = 15000 * tinyOwned;
tinyCost = 5000 * tinyOwned;
document.getElementById('tiny-owned').innerHTML = tinyOwned;
document.getElementById('tiny-income').innerHTML = "Income : $ " + tinyIncome;
document.getElementById('tiny-cost').innerHTML = "Next Cost : $ " + tinyCost;
document.getElementById('currentProfit').innerHTML = "Profit : $ " + gameProfit;
}
}
tinyGamePlay;
So all of the my variable will be more than 1000 at one point so the formatter needs to be used on all my variables.
I dont mind using a JS plugin either if anyone knows of something that could help,
Can anyone help please?
You just need to call this nFormatter function when you are printing the output, see snipped below, for bigger numbers you can use http://jsfromhell.com/classes/bignumber :
function nFormatter(num) {
if (num >= 1000000000000) {
return (num / 1000000000000).toFixed(1).replace(/\.0$/, '') + ' Trillion';
}
if (num >= 1000000000) {
return (num / 1000000000).toFixed(1).replace(/\.0$/, '') + ' Billion';
}
if (num >= 1000000) {
return (num / 1000000).toFixed(1).replace(/\.0$/, '') + ' Million';
}
if (num >= 1000) {
return (num / 1000).toFixed(1).replace(/\.0$/, '') + ' Thousand';
}
return num;
}
var gameProfit = 5100;
var tinyOwned = 0;
var tinyCost = 5000;
var tinyIncome = 0;
function tinyGamePlay() {
if (gameProfit >= tinyCost) {
tinyOwned++;
gameProfit -= tinyCost;
tinyIncome = 15000 * tinyOwned;
tinyCost = 5000 * tinyOwned;
console.log(tinyCost);
document.getElementById('tiny-owned').innerHTML = nFormatter(tinyOwned);
document.getElementById('tiny-income').innerHTML = "Income : $ " + nFormatter(tinyIncome);
document.getElementById('tiny-cost').innerHTML = "Next Cost : $ " + nFormatter(tinyCost);
document.getElementById('currentProfit').innerHTML = "Profit : $ " + nFormatter(gameProfit);
}
}
tinyGamePlay();
<p id="tiny-owned"></p>
<p id="tiny-income"></p>
<p id="tiny-cost"></p>
<p id="currentProfit"></p>

set caret back to it's original place after formating number

I have an input field which has a data manipulation and is a decimal field. Everything works fine except when I put in more than 3 numbers it will lose the current caret and set it to the end of the field because of the field formatting.
Example:
123 works fine
1234 will result in 1’234.00 and the caret is after the last 0. How is it possible to set the caret back to its original position? (Between 4 and the .)
function thousenderSign(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0)) {
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
} else {
output += "'" + number.substring(mod + 3 * i, mod + 3 * i + 3); // set the sign
}
}
return (output);
} else return number;
}
ko.extenders.numeric = function(target, precision) {
var result = ko.pureComputed({
read: target,
write: function(newValue) {
var current = target();
var roundingMultiplier = Math.pow(10, precision);
var newValueAsNum = null;
if (newValue !== undefined && newValue !== 0 && newValue !== null) {
newValueAsNum = newValue.toString().replace("'", "");
// provide only int fort he function
var onlyInt = newValueAsNum.split(".");
// Remove more then 2 digits after the dot
if (onlyInt.length > 1 && onlyInt[1].length > 2) {
onlyInt[1] = onlyInt[1].toString().substring(0, 2);
}
}
var valueToWrite = (Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier) === 0 ? null : Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
// thousender sign
if (newValueAsNum !== null && newValueAsNum.length > 3) {
valueToWrite = thousenderSign(onlyInt[0]) + "." + (onlyInt.length > 1 ? onlyInt[1] : '00');
}
if (valueToWrite !== current) {
target(valueToWrite);
} else {
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
result(target());
return result;
};
function ExampleViewModel() {
self = this;
self.counterofferPremium = ko.observable().extend({
numeric: 2
});
};
var viewModel = new ExampleViewModel();
ko.applyBindings(viewModel);
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
</head>
<body>
<input data-bind="value: counterofferPremium, valueUpdate: 'afterkeydown'" type="text" />
</body>
</html>
The simplest thing to do is get rid of the valueUpdate setting so that the formatting happens after the user is done editing the number.
To have it work interactively, you need to add an input event handler that
Finds how many digits are behind the cursor (this happens before reformatting)
Does a setTimeout to allow the reformatting to happen
Sets the cursor position after the same number of digits
Also note that your formatter gets weird for very long numbers. You might want to replace it with a call to toLocaleString with some additional substitutions.
function thousenderSign(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0)) {
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
} else {
output += "'" + number.substring(mod + 3 * i, mod + 3 * i + 3); // set the sign
}
}
return (output);
} else return number;
}
ko.extenders.numeric = function(target, precision) {
var result = ko.pureComputed({
read: target,
write: function(newValue) {
var current = target();
var roundingMultiplier = Math.pow(10, precision);
var newValueAsNum = null;
if (newValue !== undefined && newValue !== 0 && newValue !== null) {
newValueAsNum = newValue.toString().replace("'", "");
// provide only int fort he function
var onlyInt = newValueAsNum.split(".");
// Remove more then 2 digits after the dot
if (onlyInt.length > 1 && onlyInt[1].length > 2) {
onlyInt[1] = onlyInt[1].toString().substring(0, 2);
}
}
var valueToWrite = (Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier) === 0 ? null : Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
// thousender sign
if (newValueAsNum !== null && newValueAsNum.length > 3) {
valueToWrite = thousenderSign(onlyInt[0]) + "." + (onlyInt.length > 1 ? onlyInt[1] : '00');
}
if (valueToWrite !== current) {
target(valueToWrite);
} else {
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
result(target());
return result;
};
function ExampleViewModel() {
self = this;
self.counterofferPremium = ko.observable().extend({
numeric: 2
});
self.findPlace = function (data, event) {
const pos = event.target.selectionEnd;
var numbersBeforePos = event.target.value.substr(0, pos).replace(/\D/g, '').length;
setTimeout(function() {
const formattedValue = event.target.value;
const numbersNow = event.target.value.replace(/\D/g, '').length;
if (numbersNow >= numbersBeforePos) {
// find the numbersBeforePos-th number
const re = /\d/g;
var newPos;
while (numbersBeforePos--) {
newPos = 1 + re.exec(formattedValue).index;
}
event.target.setSelectionRange(newPos, newPos);
}
}, 0);
};
};
var viewModel = new ExampleViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<input data-bind="value: counterofferPremium, valueUpdate: 'afterkeydown', event: {input: findPlace}" type="text" />

Ternary operator condition is never true, trying multiline ajax request

I am creating a Slot Machine. The ternary operator is always false, so the ajax request $.ajax("delpoint.php") works, but $.ajax("addpoint") doesn't. What I am sure of, is that the error is in this part:
Javascript snippet:
function check(){
$msg.html(
r[0] === r[1] && r[1] === r[2] ?
'You won! Enjoy your ' + reels[1][ (r[0] / 70 + 1) % 3 | 0 ].split(' ')[0]
var jqxhr = $.ajax( "addpoint.php")
:
'Try again'
var jqxhr = $.ajax( "delpoint.php")
);
}
And here is the full code :
/*
requestAnimationFrame polyfill
*/
(function(w){
var lastTime = 0,
vendors = ['webkit', /*'moz',*/ 'o', 'ms'];
for (var i = 0; i < vendors.length && !w.requestAnimationFrame; ++i){
w.requestAnimationFrame = w[vendors[i] + 'RequestAnimationFrame'];
w.cancelAnimationFrame = w[vendors[i] + 'CancelAnimationFrame']
|| w[vendors[i] + 'CancelRequestAnimationFrame'];
}
if (!w.requestAnimationFrame)
w.requestAnimationFrame = function(callback, element){
var currTime = +new Date(),
timeToCall = Math.max(0, 16 - (currTime - lastTime)),
id = w.setTimeout(function(){ callback(currTime + timeToCall) }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!w.cancelAnimationFrame)
w.cancelAnimationFrame = function(id){
clearTimeout(id);
};
})(this);
/*
Slot Machine
*/
var sm = (function(undefined){
var tMax = 3000, // animation time, ms
height = 210,
speeds = [],
r = [],
reels = [
['coffee maker', 'teapot', 'espresso machine'],
['coffee filter', 'tea strainer', 'espresso tamper'],
['coffee grounds', 'loose tea', 'ground espresso beans']
],
$reels, $msg,
start;
function init(){
$reels = $('.reel').each(function(i, el){
el.innerHTML = '<div><p>' + reels[i].join('</p><p>') + '</p></div><div><p>' + reels[i].join('</p><p>') + '</p></div>'
});
$msg = $('.msg');
$('button').click(action);
}
function action(){
if (start !== undefined) return;
for (var i = 0; i < 3; ++i) {
speeds[i] = Math.random() + .5;
r[i] = (Math.random() * 3 | 0) * height / 3;
}
$msg.html('Spinning...');
animate();
}
function animate(now){
if (!start) start = now;
var t = now - start || 0;
for (var i = 0; i < 3; ++i)
$reels[i].scrollTop = (speeds[i] / tMax / 2 * (tMax - t) * (tMax - t) + r[i]) % height | 0;
if (t < tMax)
requestAnimationFrame(animate);
else {
start = undefined;
check();
}
}
function check(){
$msg.html(
r[0] === r[1] && r[1] === r[2] ?
'You won! Enjoy your ' + reels[1][ (r[0] / 70 + 1) % 3 | 0 ].split(' ')[0]
var jqxhr = $.ajax( "addpoint.php")
:
'Try again'
var jqxhr = $.ajax( "delpoint.php")
);
}
return {init: init}
})();
$(sm.init);
Try this:
function check() {
$msg.html(r[0] === r[1] && r[1] === r[2] ?
('You won! Enjoy your ' + reels[1][(r[0] / 70 + 1) % 3 | 0].split(' ')[0],
jqxhr = $.ajax("addpoint.php"), console.log("Enters"))
:
('Try again',
jqxhr = $.ajax("delpoint.php"))
);
}
It works for me, the only problem I have found is the exception thrown
SyntaxError: missing : in conditional expression var jqxhr = $.ajax( "addpoint.php")
That meant you were not using comma opeartor to split two sentences within the ternary operator.
--> Here you have the test <--

adding autoplay to jquery.roundabout

I have a site I am working on that uses the roundabout from fredhq.com and I would like to make it so it auto plays, I have had a look on their website and can not work out where I need to add the relevant auto play code!
Here is the jquery.roundabout.js code:
// creates a default shape to be used for pathing
jQuery.extend({
roundabout_shape: {
def: 'lazySusan',
lazySusan: function(r, a, t) {
return {
x: Math.sin(r + a),
y: (Math.sin(r + 3*Math.PI/2 + a) / 8) * t,
z: (Math.cos(r + a) + 1) / 2,
scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
};
}
}
});
jQuery.fn.roundabout = function() {
var options = (typeof arguments[0] != 'object') ? {} : arguments[0];
// set options and fill in defaults
options = {
bearing: (typeof options.bearing == 'undefined') ? 0.0 : jQuery.roundabout_toFloat(options.bearing % 360.0),
tilt: (typeof options.tilt == 'undefined') ? 0.0 : jQuery.roundabout_toFloat(options.tilt),
minZ: (typeof options.minZ == 'undefined') ? 100 : parseInt(options.minZ, 10),
maxZ: (typeof options.maxZ == 'undefined') ? 400 : parseInt(options.maxZ, 10),
minOpacity: (typeof options.minOpacity == 'undefined') ? 0.40 : jQuery.roundabout_toFloat(options.minOpacity),
maxOpacity: (typeof options.maxOpacity == 'undefined') ? 1.00 : jQuery.roundabout_toFloat(options.maxOpacity),
minScale: (typeof options.minScale == 'undefined') ? 0.40 : jQuery.roundabout_toFloat(options.minScale),
maxScale: (typeof options.maxScale == 'undefined') ? 1.00 : jQuery.roundabout_toFloat(options.maxScale),
duration: (typeof options.duration == 'undefined') ? 600 : parseInt(options.duration, 10),
btnNext: options.btnNext || null,
btnPrev: options.btnPrev || null,
easing: options.easing || 'swing',
clickToFocus: (options.clickToFocus !== false),
focusBearing: (typeof options.focusBearing == 'undefined') ? 0.0 : jQuery.roundabout_toFloat(options.focusBearing % 360.0),
shape: options.shape || 'lazySusan',
debug: options.debug || false,
childSelector: options.childSelector || 'li',
startingChild: (typeof options.startingChild == 'undefined') ? null : parseInt(options.startingChild, 10),
reflect: (typeof options.reflect == 'undefined' || options.reflect === false) ? false : true
};
// assign things
this.each(function(i) {
var ref = jQuery(this);
var period = jQuery.roundabout_toFloat(360.0 / ref.children(options.childSelector).length);
var startingBearing = (options.startingChild === null) ? options.bearing : options.startingChild * period;
// set starting styles
ref
.addClass('roundabout-holder')
.css('padding', 0)
.css('position', 'relative')
.css('z-index', options.minZ);
// set starting options
ref.data('roundabout', {
'bearing': startingBearing,
'tilt': options.tilt,
'minZ': options.minZ,
'maxZ': options.maxZ,
'minOpacity': options.minOpacity,
'maxOpacity': options.maxOpacity,
'minScale': options.minScale,
'maxScale': options.maxScale,
'duration': options.duration,
'easing': options.easing,
'clickToFocus': options.clickToFocus,
'focusBearing': options.focusBearing,
'animating': 0,
'childInFocus': -1,
'shape': options.shape,
'period': period,
'debug': options.debug,
'childSelector': options.childSelector,
'reflect': options.reflect
});
// bind click events
if (options.clickToFocus === true) {
ref.children(options.childSelector).each(function(i) {
jQuery(this).click(function(e) {
var degrees = (options.reflect === true) ? 360.0 - (period * i) : period * i;
degrees = jQuery.roundabout_toFloat(degrees);
if (!jQuery.roundabout_isInFocus(ref, degrees)) {
e.preventDefault();
if (ref.data('roundabout').animating === 0) {
ref.roundabout_animateAngleToFocus(degrees);
}
return false;
}
});
});
}
// bind next buttons
if (options.btnNext) {
jQuery(options.btnNext).bind('click.roundabout', function(e) {
e.preventDefault();
if (ref.data('roundabout').animating === 0) {
ref.roundabout_animateToNextChild();
}
return false;
});
}
// bind previous buttons
if (options.btnPrev) {
jQuery(options.btnPrev).bind('click.roundabout', function(e) {
e.preventDefault();
if (ref.data('roundabout').animating === 0) {
ref.roundabout_animateToPreviousChild();
}
return false;
});
}
});
// start children
this.roundabout_startChildren();
// callback once ready
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_startChildren = function() {
this.each(function(i) {
var ref = jQuery(this);
var data = ref.data('roundabout');
var children = ref.children(data.childSelector);
children.each(function(i) {
var degrees = (data.reflect === true) ? 360.0 - (data.period * i) : data.period * i;
// apply classes and css first
jQuery(this)
.addClass('roundabout-moveable-item')
.css('position', 'absolute');
// then measure
jQuery(this).data('roundabout', {
'startWidth': jQuery(this).width(),
'startHeight': jQuery(this).height(),
'startFontSize': parseInt(jQuery(this).css('font-size'), 10),
'degrees': degrees
});
});
ref.roundabout_updateChildPositions();
});
return this;
};
jQuery.fn.roundabout_setTilt = function(newTilt) {
this.each(function(i) {
jQuery(this).data('roundabout').tilt = newTilt;
jQuery(this).roundabout_updateChildPositions();
});
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_setBearing = function(newBearing) {
this.each(function(i) {
jQuery(this).data('roundabout').bearing = jQuery.roundabout_toFloat(newBearing % 360, 2);
jQuery(this).roundabout_updateChildPositions();
});
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_adjustBearing = function(delta) {
delta = jQuery.roundabout_toFloat(delta);
if (delta !== 0) {
this.each(function(i) {
jQuery(this).data('roundabout').bearing = jQuery.roundabout_getBearing(jQuery(this)) + delta;
jQuery(this).roundabout_updateChildPositions();
});
}
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_adjustTilt = function(delta) {
delta = jQuery.roundabout_toFloat(delta);
if (delta !== 0) {
this.each(function(i) {
jQuery(this).data('roundabout').tilt = jQuery.roundabout_toFloat(jQuery(this).roundabout_get('tilt') + delta);
jQuery(this).roundabout_updateChildPositions();
});
}
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_animateToBearing = function(bearing) {
bearing = jQuery.roundabout_toFloat(bearing);
var currentTime = new Date();
var duration = (typeof arguments[1] == 'undefined') ? null : arguments[1];
var easingType = (typeof arguments[2] == 'undefined') ? null : arguments[2];
var passedData = (typeof arguments[3] !== 'object') ? null : arguments[3];
this.each(function(i) {
var ref = jQuery(this), data = ref.data('roundabout'), timer, easingFn, newBearing;
var thisDuration = (duration === null) ? data.duration : duration;
var thisEasingType = (easingType !== null) ? easingType : data.easing || 'swing';
if (passedData === null) {
passedData = {
timerStart: currentTime,
start: jQuery.roundabout_getBearing(ref),
totalTime: thisDuration
};
}
timer = currentTime - passedData.timerStart;
if (timer < thisDuration) {
data.animating = 1;
if (typeof jQuery.easing.def == 'string') {
easingFn = jQuery.easing[thisEasingType] || jQuery.easing[jQuery.easing.def];
newBearing = easingFn(null, timer, passedData.start, bearing - passedData.start, passedData.totalTime);
} else {
newBearing = jQuery.easing[thisEasingType]((timer / passedData.totalTime), timer, passedData.start, bearing - passedData.start, passedData.totalTime);
}
ref.roundabout_setBearing(newBearing, function() { ref.roundabout_animateToBearing(bearing, thisDuration, thisEasingType, passedData); });
} else {
bearing = (bearing < 0) ? bearing + 360 : bearing % 360;
data.animating = 0;
ref.roundabout_setBearing(bearing);
}
});
return this;
};
jQuery.fn.roundabout_animateToDelta = function(delta) {
var duration = arguments[1], easing = arguments[2];
this.each(function(i) {
delta = jQuery.roundabout_getBearing(jQuery(this)) + jQuery.roundabout_toFloat(delta);
jQuery(this).roundabout_animateToBearing(delta, duration, easing);
});
return this;
};
jQuery.fn.roundabout_animateToChild = function(childPos) {
var duration = arguments[1], easing = arguments[2];
this.each(function(i) {
var ref = jQuery(this), data = ref.data('roundabout');
if (data.childInFocus !== childPos && data.animating === 0) {
var child = jQuery(ref.children(data.childSelector)[childPos]);
ref.roundabout_animateAngleToFocus(child.data('roundabout').degrees, duration, easing);
}
});
return this;
};
jQuery.fn.roundabout_animateToNearbyChild = function(passedArgs, which) {
var duration = passedArgs[0], easing = passedArgs[1];
this.each(function(i) {
var data = jQuery(this).data('roundabout');
var bearing = jQuery.roundabout_toFloat(360.0 - jQuery.roundabout_getBearing(jQuery(this)));
var period = data.period, j = 0, range;
var reflect = data.reflect;
var length = jQuery(this).children(data.childSelector).length;
bearing = (reflect === true) ? bearing % 360.0 : bearing;
if (data.animating === 0) {
// if we're not reflecting and we're moving to next or
// we are reflecting and we're moving previous
if ((reflect === false && which === 'next') || (reflect === true && which !== 'next')) {
bearing = (bearing === 0) ? 360 : bearing;
// counterclockwise
while (true && j < length) {
range = { lower: jQuery.roundabout_toFloat(period * j), upper: jQuery.roundabout_toFloat(period * (j + 1)) };
range.upper = (j == length - 1) ? 360.0 : range.upper; // adjust for javascript being bad at floats
if (bearing <= range.upper && bearing > range.lower) {
jQuery(this).roundabout_animateToDelta(bearing - range.lower, duration, easing);
break;
}
j++;
}
} else {
// clockwise
while (true) {
range = { lower: jQuery.roundabout_toFloat(period * j), upper: jQuery.roundabout_toFloat(period * (j + 1)) };
range.upper = (j == length - 1) ? 360.0 : range.upper; // adjust for javascript being bad at floats
if (bearing >= range.lower && bearing < range.upper) {
jQuery(this).roundabout_animateToDelta(bearing - range.upper, duration, easing);
break;
}
j++;
}
}
}
});
return this;
};
jQuery.fn.roundabout_animateToNextChild = function() {
return this.roundabout_animateToNearbyChild(arguments, 'next');
};
jQuery.fn.roundabout_animateToPreviousChild = function() {
return this.roundabout_animateToNearbyChild(arguments, 'previous');
};
// moves a given angle to the focus by the shortest means possible
jQuery.fn.roundabout_animateAngleToFocus = function(target) {
var duration = arguments[1], easing = arguments[2];
this.each(function(i) {
var delta = jQuery.roundabout_getBearing(jQuery(this)) - target;
delta = (Math.abs(360.0 - delta) < Math.abs(0.0 - delta)) ? 360.0 - delta : 0.0 - delta;
delta = (delta > 180) ? -(360.0 - delta) : delta;
if (delta !== 0) {
jQuery(this).roundabout_animateToDelta(delta, duration, easing);
}
});
return this;
};
jQuery.fn.roundabout_updateChildPositions = function() {
this.each(function(i) {
var ref = jQuery(this), data = ref.data('roundabout');
var inFocus = -1;
var info = {
bearing: jQuery.roundabout_getBearing(ref),
tilt: data.tilt,
stage: { width: Math.floor(ref.width() * 0.9), height: Math.floor(ref.height() * 0.9) },
animating: data.animating,
inFocus: data.childInFocus,
focusBearingRad: jQuery.roundabout_degToRad(data.focusBearing),
shape: jQuery.roundabout_shape[data.shape] || jQuery.roundabout_shape[jQuery.roundabout_shape.def]
};
info.midStage = { width: info.stage.width / 2, height: info.stage.height / 2 };
info.nudge = { width: info.midStage.width + info.stage.width * 0.05, height: info.midStage.height + info.stage.height * 0.05 };
info.zValues = { min: data.minZ, max: data.maxZ, diff: data.maxZ - data.minZ };
info.opacity = { min: data.minOpacity, max: data.maxOpacity, diff: data.maxOpacity - data.minOpacity };
info.scale = { min: data.minScale, max: data.maxScale, diff: data.maxScale - data.minScale };
// update child positions
ref.children(data.childSelector).each(function(i) {
if (jQuery.roundabout_updateChildPosition(jQuery(this), ref, info, i) && info.animating === 0) {
inFocus = i;
jQuery(this).addClass('roundabout-in-focus');
} else {
jQuery(this).removeClass('roundabout-in-focus');
}
});
// update status of who is in focus
if (inFocus !== info.inFocus) {
jQuery.roundabout_triggerEvent(ref, info.inFocus, 'blur');
if (inFocus !== -1) {
jQuery.roundabout_triggerEvent(ref, inFocus, 'focus');
}
data.childInFocus = inFocus;
}
});
return this;
};
//----------------
jQuery.roundabout_getBearing = function(el) {
return jQuery.roundabout_toFloat(el.data('roundabout').bearing) % 360;
};
jQuery.roundabout_degToRad = function(degrees) {
return (degrees % 360.0) * Math.PI / 180.0;
};
jQuery.roundabout_isInFocus = function(el, target) {
return (jQuery.roundabout_getBearing(el) % 360 === (target % 360));
};
jQuery.roundabout_triggerEvent = function(el, child, eventType) {
return (child < 0) ? this : jQuery(el.children(el.data('roundabout').childSelector)[child]).trigger(eventType);
};
jQuery.roundabout_toFloat = function(number) {
number = Math.round(parseFloat(number) * 1000) / 1000;
return parseFloat(number.toFixed(2));
};
jQuery.roundabout_updateChildPosition = function(child, container, info, childPos) {
var ref = jQuery(child), data = ref.data('roundabout'), out = [];
var rad = jQuery.roundabout_degToRad((360.0 - ref.data('roundabout').degrees) + info.bearing);
// adjust radians to be between 0 and Math.PI * 2
while (rad < 0) {
rad = rad + Math.PI * 2;
}
while (rad > Math.PI * 2) {
rad = rad - Math.PI * 2;
}
var factors = info.shape(rad, info.focusBearingRad, info.tilt); // obj with x, y, z, and scale values
// correct
factors.scale = (factors.scale > 1) ? 1 : factors.scale;
factors.adjustedScale = (info.scale.min + (info.scale.diff * factors.scale)).toFixed(4);
factors.width = (factors.adjustedScale * data.startWidth).toFixed(4);
factors.height = (factors.adjustedScale * data.startHeight).toFixed(4);
// alter item
ref
.css('left', ((factors.x * info.midStage.width + info.nudge.width) - factors.width / 2.0).toFixed(1) + 'px')
.css('top', ((factors.y * info.midStage.height + info.nudge.height) - factors.height / 2.0).toFixed(1) + 'px')
.css('width', factors.width + 'px')
.css('height', factors.height + 'px')
.css('opacity', (info.opacity.min + (info.opacity.diff * factors.scale)).toFixed(2))
.css('z-index', Math.round(info.zValues.min + (info.zValues.diff * factors.z)))
.css('font-size', (factors.adjustedScale * data.startFontSize).toFixed(2) + 'px')
.attr('current-scale', factors.adjustedScale);
if (container.data('roundabout').debug === true) {
out.push('<div style="font-weight: normal; font-size: 10px; padding: 2px; width: ' + ref.css('width') + '; background-color: #ffc;">');
out.push('<strong style="font-size: 12px; white-space: nowrap;">Child ' + childPos + '</strong><br />');
out.push('<strong>left:</strong> ' + ref.css('left') + '<br /><strong>top:</strong> ' + ref.css('top') + '<br />');
out.push('<strong>width:</strong> ' + ref.css('width') + '<br /><strong>opacity:</strong> ' + ref.css('opacity') + '<br />');
out.push('<strong>z-index:</strong> ' + ref.css('z-index') + '<br /><strong>font-size:</strong> ' + ref.css('font-size') + '<br />');
out.push('<strong>scale:</strong> ' + ref.attr('current-scale'));
out.push('</div>');
ref.html(out.join(''));
}
return jQuery.roundabout_isInFocus(container, ref.data('roundabout').degrees);
};
Many thanks in advance for any help and advice.
Phil
The source you posted doesn't seem to be the latest version of Roundabout.
I just tried with the latest version, and it works perfectly:
$(document).ready(function() {
$('ul').roundabout({
autoplay: true,
autoplayDuration: 1000,
autoplayPauseOnHover: true
});
});
See http://jsfiddle.net/SfAuF/ for an example.
Download the latest version from GitHub.

Categories

Resources