vue-json-excel containing data issue for multiple excel download - php

I have the following table in vue component.
when click the download button what I need is to download an excel file including multiple data of a Spare Part. So the excel file looks like follows:
<download-excel v-if="spare_parts.length"
class="btn btn-view"
:data="json_data"
:fields="json_fields"
:title="['Equipments - Spare Part - '+ spare_part.name,'' ]"
worksheet="My Worksheet"
:name="'Equipments - Spare Part - '+spare_part.name+'.xls'">
<i class="fa fa-download sky-fa" title="Download Report" #click="getReportDetails(spare_part.sap)"></i>
</download-excel>
json_fields: {
'Equipment - Serial Number': {
callback: (value) => {
return `${value.maintenance.equipment.serial_number}`;
}
},
'Customer Name': {
callback: (value) => {
return `${value.maintenance.equipment.technical_customer.name}`;
}
},
'Unit Price (LKR) - Without VAT': {
callback: (value) => {
let final = '';
let VAT = '';
let decimalCount = 2;
let decimal = ".";
let thousands = ",";
let amount = `${value.cost}`;
try {
let decimalCount = Math.abs(decimalCount);
decimalCount = isNaN(decimalCount) ? 2 : decimalCount;
const negativeSign = amount < 0 ? "-" : "";
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
let j = (i.length > 3) ? i.length % 3 : 0;
final = negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "")
// return final;
} catch (e) {
console.log("Errors " + e);
}
return final;
}
},
'Unit Price (LKR) - With VAT': {
callback: (value) => {
let final = '';
let VAT = '';
VAT = (`${value.vat}` == 1) ? `${value.cost + (value.cost * (value.vat_percentage / 100))}` : '-';
if (`${value.vat}` == 1) {
let decimalCount = 2;
let decimal = ".";
let thousands = ",";
let amount = VAT;
try {
let decimalCount = Math.abs(decimalCount);
decimalCount = isNaN(decimalCount) ? 2 : decimalCount;
const negativeSign = amount < 0 ? "-" : "";
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
let j = (i.length > 3) ? i.length % 3 : 0;
final = negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "")
} catch (e) {
console.log("Errors " + e);
}
} else {
final = '-';
}
return final;
}
},
},
json_data: [],
json_meta: [
[
{
'key': 'charset',
'value': 'utf-8'
}
]
],
when clicking the icon it triggers the getReportDetails(spare_part.sap) function.
getReportDetails(name){
axios.get('/technical/sparepart/get-report/'+name)
.then(function (response) {
this.json_data = response.data;
if (this.json_data.length == 0) {
alert('No Data in this Spare Part');
}
}.bind(this))
.catch(error => {
console.log("Errors : " + error);
});
},
So the data which need to display inside the excel sheet is getting from this function by calling the following method in the SparePartController:
public function getReportDetails($name)
{
$maintenance_spare_parts = MaintenanceSparePart::with('maintenance.equipment.technicalCustomer')->where('spare_part', $name)->get();
return $maintenance_spare_parts;
}
I have 2 questions here.
When I click on the download icon downloading started at the second time click. But after that every next click the downloading is happening. Why always the second time?
After I download I can see the correct data in the excel sheet. But when I click the download icon in another row without page refreshing I'm getting the previous data in my excel file. What's the reason for that?
Can anyone point me where I did wrong in this case?

Related

what can be used in place of window.location.replace to avoid page reloading?

I am using product filtering in a site like Flipkart. And I do not want to reload the page after filtering data. This is my jquery code for filtering data. Filter class is used in all the filters. Give some suggestions plz.
$('.filter').click(function() {
var typef = '';
var currentURL = location.protocol + '//' + location.host + location.pathname;
if (window.location.href.indexOf("search") > -1) {
var searchParams = new URLSearchParams(window.location.search);
var aquery = searchParams.get('query');
typef = 'search';
}
var brands = [];
var colors = [];
var price = [];
if ($(this).is(":checked")) {
$("input:checkbox[name=brand_check]:checked").each(function() {
brands.push($(this).val());
});
$("input:checkbox[name=color_check]:checked").each(function() {
colors.push($(this).val());
});
$("input:radio[name=price_check]:checked").each(function() {
price.push($(this).val());
});
var filterdata = {
brands: jQuery.unique(brands),
color: jQuery.unique(colors),
price: jQuery.unique(price)
};
var filteruri = jQuery.param(filterdata);
if (typef == 'search' && typeof aquery !== "undefined" && aquery !== '') {
window.location.replace(currentURL + '?query=' + encodeURIComponent(aquery) + '&f=' + encodeURIComponent(filteruri));
} else {
window.location.replace(currentURL + '?f=' + encodeURIComponent(filteruri));
}
} else {
$('input:checkbox[value="' + $(this).val() + '"]').attr('checked', false);
$("input:checkbox[name=brand_check]:checked").each(function() {
brands.push($(this).val());
});
$("input:checkbox[name=color_check]:checked").each(function() {
colors.push($(this).val());
});
$("input:radio[name=price_check]:checked").each(function() {
price.push($(this).val());
});
var filterdata = {
brands: jQuery.unique(brands),
color: jQuery.unique(colors),
price: jQuery.unique(price)
};
var filteruri = jQuery.param(filterdata);
if (typef == 'search' && typeof aquery !== "undefined" && aquery !== '') {
if (filteruri.length > 0) {
window.location.replace(currentURL + '?query=' + encodeURIComponent(aquery) + '&f=' + encodeURIComponent(filteruri));
} else {
window.location.replace(currentURL + '?query=' + encodeURIComponent(aquery));
}
} else {
if (filteruri.length > 0) {
window.location.replace(currentURL + '?f=' + encodeURIComponent(filteruri));
} else {
window.location.replace(currentURL);
}
}
}
});
If I understood correctly, you want to change url without page reloading.
Read some about manipulating browser history (https://developer.mozilla.org/en-US/docs/Web/API/History_API), in particular: pushState.
In your case you can use window.history.pushState (https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_pushState()_method).
Instead window.location.replace you can write something like this one:
window.history.pushState({ page: filteruri }, 'Page title', currentURL + '?somethingnew');

Indian grouping of thousand, lakhs and crores separator jquery [duplicate]

I have the following code to display in Indian numbering system.
var x=125465778;
var res= x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
Am getting this output :125,465,778.
I need output like this: 12,54,65,778.
Please help me to sort out this problem .
i'm late but i guess this will help :)
you can use Number.prototype.toLocaleString()
Syntax
numObj.toLocaleString([locales [, options]])
var number = 123456.789;
// India uses thousands/lakh/crore separators
document.getElementById('result').innerHTML = number.toLocaleString('en-IN');
// → 1,23,456.789
document.getElementById('result1').innerHTML = number.toLocaleString('en-IN', {
maximumFractionDigits: 2,
style: 'currency',
currency: 'INR'
});
// → ₹1,23,456.79
<div id="result"></div>
<div id="result1"></div>
For Integers:
var x=12345678;
x=x.toString();
var lastThree = x.substring(x.length-3);
var otherNumbers = x.substring(0,x.length-3);
if(otherNumbers != '')
lastThree = ',' + lastThree;
var res = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree;
alert(res);
Live Demo
For float:
var x=12345652457.557;
x=x.toString();
var afterPoint = '';
if(x.indexOf('.') > 0)
afterPoint = x.substring(x.indexOf('.'),x.length);
x = Math.floor(x);
x=x.toString();
var lastThree = x.substring(x.length-3);
var otherNumbers = x.substring(0,x.length-3);
if(otherNumbers != '')
lastThree = ',' + lastThree;
var res = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree + afterPoint;
alert(res);
Live Demo
Simple way to do,
1. Direct Method using LocalString()
(1000.03).toLocaleString()
(1000.03).toLocaleString('en-IN') # number followed by method
2. using Intl - Internationalization API
The Intl object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting.
eg: Intl.NumberFormat('en-IN').format(1000)
3. Using Custom Function:
function numberWithCommas(x) {
return x.toString().split('.')[0].length > 3 ? x.toString().substring(0,x.toString().split('.')[0].length-3).replace(/\B(?=(\d{2})+(?!\d))/g, ",") + "," + x.toString().substring(x.toString().split('.')[0].length-3): x.toString();
}
console.log("0 in indian format", numberWithCommas(0));
console.log("10 in indian format", numberWithCommas(10));
console.log("1000.15 in indian format", numberWithCommas(1000.15));
console.log("15123.32 in indian format", numberWithCommas(15123.32));
if your input is 10000.5,
numberWithCommas(10000.5)
You will get output like this, 10,000.5
For integers only no additional manipulations needed.
This will match every digit from the end, having 1 or more double digits pattern after, and replace it with itself + ",":
"125465778".replace(/(\d)(?=(\d\d)+$)/g, "$1,");
-> "1,25,46,57,78"
But since we want to have 3 in the end, let's state this explicitly by adding extra "\d" before match end of input:
"125465778".replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
-> "12,54,65,778"
Given a number to below function, it returns formatted number in Indian format of digit grouping.
ex: input: 12345678567545.122343
output: 1,23,45,67,85,67,545.122343
function formatNumber(num) {
input = num;
var n1, n2;
num = num + '' || '';
// works for integer and floating as well
n1 = num.split('.');
n2 = n1[1] || null;
n1 = n1[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
num = n2 ? n1 + '.' + n2 : n1;
console.log("Input:",input)
console.log("Output:",num)
return num;
}
formatNumber(prompt("Enter Number",1234567))
https://jsfiddle.net/scLtnug8/1/
I am little late in the game.
But here is the implicit way to do this.
var number = 3493423.34;
console.log(new Intl.NumberFormat('en-IN', { style: "currency", currency: "INR" }).format(number));
if you dont want currency symbol, use it like this
console.log(new Intl.NumberFormat('en-IN').format(number));
The easiest way is just to use Globalize plugin (read more about it here and here):
var value = 125465778;
var formattedValue = Globalize.format(value, 'n');
Try like below, I have found a number formatter Plugin here : Java script number Formatter
By using that i have done the below code, It works fine, Try this, It will help you..
SCRIPT :
<script src="format.20110630-1100.min.js" type="text/javascript"></script>
<script>
var FullData = format( "#,##0.####", 125465778)
var n=FullData.split(",");
var part1 ="";
for(i=0;i<n.length-1;i++)
part1 +=n[i];
var part2 = n[n.length-1]
alert(format( "#0,#0.####", part1) + "," + part2);
</script>
Inputs :
1) 125465778
2) 1234567.89
Outputs :
1) 12,54,65,778
2) 12,34,567.89
Simply use https://osrec.github.io/currencyFormatter.js/
Then all you need is:
OSREC.CurrencyFormatter.format(2534234, { currency: 'INR' });
// Returns ₹ 25,34,234.00
These will format the value in the respective systems.
$(this).replace(/\B(?=(?:\d{3})+(?!\d))/g, ',');
For US number system (millions & billions)
$(this).replace(/\B(?=(?:(\d\d)+(\d)(?!\d))+(?!\d))/g, ',');
For Indian number system (lakhs & crores)
This function can handle float value properly just addition to another answer
function convertNumber(num) {
var n1, n2;
num = num + '' || '';
n1 = num.split('.');
n2 = n1[1] || null;
n1 = n1[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
num = n2 ? n1 + '.' + n2 : n1;
n1 = num.split('.');
n2 = (n1[1]) || null;
if (n2 !== null) {
if (n2.length <= 1) {
n2 = n2 + '0';
} else {
n2 = n2.substring(0, 2);
}
}
num = n2 ? n1[0] + '.' + n2 : n1[0];
return num;
}
this function will convert all function to float as it is
function formatAndConvertToFloatFormat(num) {
var n1, n2;
num = num + '' || '';
n1 = num.split('.');
if (n1[1] != null){
if (n1[1] <= 9) {
n2 = n1[1]+'0';
} else {
n2 = n1[1]
}
} else {
n2 = '00';
}
n1 = n1[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
return n1 + '.' + n2;
}
Improvised Slopen's approach above, Works for both int and floats.
function getIndianFormat(str) {
str = str.split(".");
return str[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,") + (str[1] ? ("."+str[1]): "");
}
console.log(getIndianFormat("43983434")); //4,39,83,434
console.log(getIndianFormat("1432434.474")); //14,32,434.474
Based on Nidhinkumar's question i have checked the above answers and
while handling negative numbers the output won't be correct for eg: -300 it should display as -300 but the above answers will display it as -,300 which is not good so i have tried with the below code which works even during the negative cases.
var negative = input < 0;
var str = negative ? String(-input) : String(input);
var arr = [];
var i = str.indexOf('.');
if (i === -1) {
i = str.length;
} else {
for (var j = str.length - 1; j > i; j--) {
arr.push(str[j]);
}
arr.push('.');
}
i--;
for (var n = 0; i >= 0; i--, n++) {
if (n > 2 && (n % 2 === 1)) {
arr.push(',');
}
arr.push(str[i]);
}
if (negative) {
arr.push('-');
}
return arr.reverse().join('');
Improvising #slopen's answer with decimal support and test cases.
Usage: numberToIndianFormat(555555.12) === "5,55,555.12"
utils.ts
export function numberToIndianFormat(x: number): string {
if (isNaN(x)) {
return "NaN"
} else {
let string = x.toString();
let numbers = string.split(".");
numbers[0] = integerToIndianFormat(parseInt(numbers[0]))
return numbers.join(".");
}
}
function integerToIndianFormat(x: number): string {
if (isNaN(x)) {
return "NaN"
} else {
let integer = x.toString();
if (integer.length > 3) {
return integer.replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
} else {
return integer;
}
}
}
utils.spec.ts
describe('numberToIndianFormat', () => {
it('nan should output NaN', () => {
expect(numberToIndianFormat(Number.NaN)).toEqual("NaN")
});
describe('pure integer', () => {
it('should leave zero untouched', () => {
expect(numberToIndianFormat(0)).toEqual("0")
});
it('should leave simple numbers untouched', () => {
expect(numberToIndianFormat(10)).toEqual("10")
});
it('should add comma at thousand place', () => {
expect(numberToIndianFormat(5555)).toEqual("5,555")
});
it('should add comma at lakh place', () => {
expect(numberToIndianFormat(555555)).toEqual("5,55,555")
});
it('should add comma at crore place', () => {
expect(numberToIndianFormat(55555555)).toEqual("5,55,55,555")
});
});
describe('with fraction', () => {
it('should leave zero untouched', () => {
expect(numberToIndianFormat(0.12)).toEqual("0.12")
});
it('should leave simple numbers untouched', () => {
expect(numberToIndianFormat(10.12)).toEqual("10.12")
});
it('should add comma at thousand place', () => {
expect(numberToIndianFormat(5555.12)).toEqual("5,555.12")
});
it('should add comma at lakh place', () => {
expect(numberToIndianFormat(555555.12)).toEqual("5,55,555.12")
});
it('should add comma at crore place', () => {
expect(numberToIndianFormat(55555555.12)).toEqual("5,55,55,555.12")
});
});
})
Indian money format function
function indian_money_format(amt)
{
amt=amt.toString();
var lastThree = amt.substring(amt.length-3);
var otherNumbers = amt.substring(0,amt.length-3);
if(otherNumbers != '')
lastThree = ',' + lastThree;
var result = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree;
alert(result)
return result;
}
indian_money_format(prompt("Entry amount",123456))

Algolia Geo Search Not Working

I am having some trouble with Algolia's geo search feature which was working properly before. Here is the record of interest.
I also had that indexed as described by the doc in order for me to sort it by the nearest distance:
'attributesToIndex' => ['name', 'description', 'geo']
In my client script:
let settings = {
aroundLatLng: '10.309813,123.893154',
getRankingInfo: true,
aroundRadius: 2000
};
index.search(keyword, settings, (err, data) => {
console.log(data);
});
But this gives me 0 hit. Notice the aroundLatLng value -- its the same value from the record of interest.
Am I missing something here?
I have implemented same requirement in node.js as per given in document and its working fine.
Here i am copying my whole code. Hopefully it may help you.
Code
/*
I have used async.water model to create the setting of the index and then searching data as per given parameter. few function is custom so no need to bother about that. read each line patently.
*/
try {
var self = this;
var post = req.body;
var user_id = post.user_id;
var created_mode = post.user_mode == 'requester' ? 'provider' : 'requester';
var kword = post.kword;
var geo = post.geo_loc;
var aroundLatLng = post.aroundLatLng;
var aroundRadius = !cmnFn.empty(post.radious) ? post.radious : 4500;
var hitsPerPage = !cmnFn.empty(post.hitsPerPage) ? post.hitsPerPage : 20;
var offset = !cmnFn.empty(post.offset) ? post.offset : 0;
var length = !cmnFn.empty(post.length) ? post.length : 50;
var budget_from = !cmnFn.empty(post.budget_from) ? post.budget_from : 0;
var budget_to = !cmnFn.empty(post.budget_to) ? post.budget_to : 0;
var day_preference = !cmnFn.empty(post.day_preference) ? post.day_preference : '';
var time_preference = !cmnFn.empty(post.time_preference) ? post.time_preference : '';
var start_date = !cmnFn.empty(post.start_date) ? post.start_date : '';
job_index is index created on Algolia
var job_index = algClient.initIndex('jobs');
var cond = {};
If you are using facet & filter then you need to use filter key to execute your condition same as you may have done in sql using where clouse
cond.filters = 'created_mode:"' + created_mode + '" AND (NOT user_id:"' + user_id + '")';
// Query which need to be search
if (!cmnFn.empty(kword)) {
cond.query = !cmnFn.empty(post.kword) ? post.kword : '';
}
if ((!cmnFn.empty(budget_from) && !cmnFn.empty(budget_to)) && budget_from > 0) {
cond.filters += ' AND min_charge: ' + budget_from + ' TO ' + budget_to;
}
if (!cmnFn.empty(day_preference)) {
cond.filters += ' AND day_preference:"' + day_preference + '"';
}
if (!cmnFn.empty(time_preference)) {
cond.filters += ' AND time_preference:"' + time_preference + '"';
}
if (!cmnFn.empty(start_date) && (new Date(start_date)).getTime() > 0) {
cond.filters += ' AND start_date:"' + start_date + '"';
}
Here i am setting aroundLatLng to get data nearest to far
/*
Do not fogot one thing, before using geo search, your records must have _geoloc key having following format
"_geoloc": {
"lat": 40.639751,
"lng": -73.778925
}
*/
// Around geo search by given lat lng
if (!cmnFn.empty(aroundLatLng) && !cmnFn.empty(aroundLatLng.lat)) {
cond.aroundLatLng = aroundLatLng.lat + ', ' + aroundLatLng.lng;
if (!cmnFn.empty(aroundRadius) && cond.aroundRadius > 0) {
cond.aroundRadius = aroundRadius;
}
}
// total number of searched record
if (!cmnFn.empty(hitsPerPage)) {
cond.hitsPerPage = hitsPerPage;
}
// Record starting position
if (!cmnFn.empty(offset)) {
cond.offset = offset;
}
// Page Limitation
if (!cmnFn.empty(length)) {
cond.length = length;
}
// Don't show attributesToHighlight in result set
cond.attributesToHighlight = false;
/*
restrictSearchableAttributes: List of object key, where to search in given list defined in searchableAttributes
*/
cond.restrictSearchableAttributes = [
'user_id',
'title',
'description',
'_geoloc'
];
/*
It will return raning info of result when search come under geo search
Following output will return
"_rankingInfo": {
"nbTypos": 0,
"firstMatchedWord": 0,
"proximityDistance": 0,
"userScore": 31,
"geoDistance": 9, // Calculated distance between data geolocation given in _geoloc and search criteria in aroundLatLng
"geoPrecision": 1,
"nbExactWords": 0,
"words": 1,
"filters": 0,
"matchedGeoLocation": {
"lat": 28.5503,
"lng": 77.2501,
"distance": 9
}
}
*/
cond.getRankingInfo = true;
async.waterfall([
function (callback) {
job_index.setSettings({
'attributesForFaceting': ['user_id', 'created_mode', 'min_charge', 'day_preference', 'time_preference', 'start_date'],
/*
searchableAttributes: List of object key , where to search
eg: ['title', 'description']
Like in sql: Where title='your searched text' AND description='your searched text'
_geoloc is reserved keyword of algolia which will used to search geo location
*/
searchableAttributes: [
'title',
'description',
'user_id',
'_geoloc'
],
/*
attributesToRetrieve: Here you can specify list of key name which you want to retrive
eg: ['name','address','age']
Like in sql: Select name, address, age
*/
attributesToRetrieve: [
'*'
]
}).then(() => {
return callback(null, 'success');
});
}
], function (err, results) {
if (err) {
console.log('error: ' + err);
}
job_index.search(cond).then(results => {
if (results.nbHits > 0) {
var rows = new Array();
for (i in results.hits) {
var row = {};
var item = results.hits[i];
var user_info = {};
user_info = item.user_info;
// Get distance and calculate
if (!cmnFn.empty(item._rankingInfo)) {
item.distance = cmnFn.meterToKM(item._rankingInfo['geoDistance']);
} else {
let loc = {
geoLoc_1: { latitude: aroundLatLng.lat, longitude: aroundLatLng.lng },
geoLoc_2: { latitude: item._geoloc.lat, longitude: item._geoloc.lng }
}
cmnFn.getDistance(loc, function (distance) {
item.distance = distance
})
}
/* self.isFav({ user_id: item.user_id, job_id: item.job_id }), function (err, flag) {
item.is_favorite = flag;
}; */
self.isFav({ user_id: item.user_id, job_id: item.job_id }).then(function (flag) {
item.is_favorite = flag;
}, function (err) {
item.is_favorite = false;
});
if (cmnFn.empty(item.currency)) {
item.currency = "₹";
}
//Delete few key from object which does not need to send in response
delete item['user_info'];
delete item['objectID'];
delete item['_geoloc'];
delete item['_rankingInfo'];
row.job_info = item;
row.user_info = user_info;
rows.push(row);
}
info = { status: 1, message: util.format(lang.TOTAL_RECORD_FOUND, results.nbHits), data: rows };
cmnFn.showMsg(res, info);
} else {
info = { status: 0, message: lang.RECORD_NOT_FOUND, data: null };
cmnFn.showMsg(res, info);
}
}).catch(err => {
console.log(err);
info = { status: 0, message: lang.RECORD_NOT_FOUND, data: null };
cmnFn.showMsg(res, info);
});
//res.end('' + JSON.stringify(results));
});
} catch (error) {
info = { status: 0, message: lang.RECORD_NOT_FOUND, data: null };
cmnFn.showMsg(res, info);
}
My bad. Malformed indexed data for _geoloc. Should be keyed with lat and lng

JSONP and GET with callbacks - help needed correcting errors

This is my JSONP file:
<?php
header('Content-type: application/javascript;');
header("access-control-allow-origin: *");
header("Access-Control-Allow-Methods: GET");
//db connection detils
$host = "localhost";
$user = "test";
$password = "test";
$database = "myradiostation1";
//make connection
$server = mysql_connect($host, $user, $password);
$connection = mysql_select_db($database, $server);
//query the database
$query = mysql_query("SELECT *, DATE_FORMAT(start, '%d/%m/%Y %H:%i:%s') AS start,
DATE_FORMAT(end, '%d/%m/%Y %H:%i:%s') AS end FROM radiostation1");
//loop through and return results
for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
$row = mysql_fetch_assoc($query);
$shows[$x] = array("id" => $row["id"], "startminutes" => $row["startminutes"], "start" => $row["start"], "endminutes" => $row["endminutes"],"end" => $row["end"],"mediumname" => $row["mediumname"], "longname" => $row["longname"], "description" => $row["description"],"short_id" => $row["short_id"],"promomessage" => $row["promomessage"],"email" => $row["email"],"phonenumber" => $row["phonenumber"],"textnumber" => $row["textnumber"],"textprefix" => $row["textprefix"],"showimage" => $row["showimage"],"longdescription" => $row["longdescription"],"facebooklink" => $row["facebooklink"],"otherlink" => $row["otherlink"],"websitelink" => $row["websitelink"],"keywords" => $row["keywords"] );
}
//echo JSON to page
$response = $_GET["callback"] . "(" . json_encode($shows) . ");";
echo $response;
?>
It does work, up to a point, but getting the {"success":true,"error":"","data":{"schedule": as seen at this site before my json_encode is where I am.
However, I cannot get it to display any data in my table, although it DOES produce code on-screen when I view it at http://www.myradio1.localhost/onairschedule.php.
The actual code is stored at http://www.myradiostations.localhost/schedule.php
and the callback function works OK, one example being http://www.myradiostations.localhost/schedule.php?callback=?&name=Northern+FM and http://www.myradiostations.localhost/schedule.php?callback=?&name=Southern+FM but what do I need to do to make it change like in these examples:
this example and this example, and to generate an error message like this if no such file exists.
I'm halfway there, just need some advice on fixing my code!
Basically, what I'm trying to do... get a JSONP to work in my HTML table which will vary the content depending on the URL in my javascript file on my page, which is:
var doFades = true;
var LocalhostRadioStations = {
Schedule : {}
};
$(document).ready(function(){
LocalhostRadioStations.Schedule.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
LocalhostRadioStations.Schedule.Show = function () {
_s = null;
_startDate = null;
_endDate = null;
this.days = LocalhostRadioStations.Schedule.days;
_selector = '';
this.setShow = function(s) {
this._s = s;
this._startDate = new Date( parseInt(s.startminutes, 10) * 1000);
this._endDate = new Date(parseInt(s.endminutes, 10) * 1000 );
};
this.getEndDate = function(){
return this._endDate;
}
this.getStartDate = function(){
return this._startDate;
}
this._getShowDay = function (){
return this.days[this.getStartDate().getDay()];
};
this._getShowUnitsTaken = function(){
// if it's the same day
return this._getEndUnits() - this._getStartUnits();
};
this._getEndUnits = function(){
if(this.getEndDate().getHours() == 0)
{
//console.log(this._s.longname +' ends at midnight');
return 48;
}
return this.getEndDate().getMinutes() !== 0 ? (this.getEndDate().getHours() * 2) : (this.getEndDate().getHours() * 2);
};
this._getStartUnits = function(){
if(this.getStartDate().getHours() == 0)
{
return 0;
}
return this.getStartDate().getMinutes() !== 0 ? (this.getStartDate().getHours() * 2) : (this.getStartDate().getHours() * 2);
};
this.getCellPositions = function() {
return {
'start' : this.getStartDate(),
'end' : this.getEndDate(),
'colIndex' : this.getStartDate().getDay() + 2,
'startUnits' : this._getStartUnits(),
'endUnits' : this._getEndUnits(),
'unitsTaken' : this._getShowUnitsTaken()
}
};
this.pad = function(number){
return number < 10 ? '0'+number : number;
};
// return the table cell html.
this.toHtml = function () {
var d = new Date();
var units = this._getStartUnits();
var rowspan = this._getShowUnitsTaken();
var desc = this._s.description;
var name = this._s.longname;
var starttime = this.pad(this.getStartDate().getHours()) + ':' + this.pad(this.getStartDate().getMinutes());
var endtime = this.pad(this.getEndDate().getHours()) + ':' + this.pad(this.getEndDate().getMinutes());
var site = this._s.websitelink;
var cls = this.isActive() ? 'current-program' : '';
var isToday = this.getStartDate().getDay() === d.getDay() ? 'active-program' : '';
var html = '<td class="schedule-show ' + isToday + ' ' + cls + '" rowspan="' + rowspan + '" data-start="' + this.getStartDate() + '" data-end="' + this.getEndDate() + '">';
html += '<div>';
html += '' + name + '';
html += '</div>';
if(doFades)
{
html += '<div class="schedule_details clearfix" style="display:none;">';
html += '<img width="105px" height="105px" alt="' + desc + '" src="' + this._s.showimage + '">';
html += '<strong>' + name + '</strong>';
html += '<p>' + desc + '</p>';
html += '<span>' + starttime + ' - ' + endtime +'</span>';
html += '</div>';
}
html += '</td>';
return html;
};
this.setTableSelector = function(sel){
this._selector = sel;
};
// check if we should add the active class.
this.isActive = function(){
var t = new Date();
return t >= this.getStartDate() && t <= this.getEndDate();
};
};
LocalhostRadioStations.Schedule.ScheduleGen = function(){
return {
insertShow : function(show) {
var p = show.getCellPositions();
$('tr#units-' + p.startUnits).append(show.toHtml());
},
init : function (stationName){
var self = this;
// load the schedule.
$.getJSON('http://www.myradiostations.localhost/schedule.php?callback=?&name=', {
name: 'Northern FM'
}, function(json){
// loop each show and append to our giant table.
// this is well sick.
if(json.success === false)
{
$('.content-inner table').remove();
$('<div>errors</div>').appendTo('.content-inner');
}
else
{
var currentDay = '';
var day = 0;
// highlight the current time..
var d = new Date();
var weekStart = new Date();
weekStart.setDate(d.getDate()-6-(d.getDay()||7));
$.each(json.data.schedule, function(i, broadcast){
var dStart = new Date( parseInt(broadcast.startminutes, 10) * 1000);
var dEnd = new Date(parseInt(broadcast.endminutes, 10) * 1000 );
/*// transform to a show object defined above, if the show spans 2 days we create two show objects.
// IF THE SHOW STARTS/ENDS AT MIDNIGHT, DON'T SPLIT IT.
if(dStart.getHours() !== 0 && dEnd.getHours() !== 0 && dStart.getDate() != dEnd.getDate())
{
var showOne = new LocalhostRadioStations.Schedule.Show();
showOne.setShow(broadcast);
// set to midnight
showOne.getEndDate().setHours(0);
showOne.getEndDate().setMinutes(dStart.getMinutes());
// append first half of show.
self.insertShow(showOne);
// handle second half.
var showTwo = new LocalhostRadioStations.Schedule.Show();
showTwo.setShow(broadcast);
showTwo.getStartDate().setDate(showTwo.getStartDate().getDate() + 1);
showTwo.getStartDate().setHours(0);
showTwo.getStartDate().setMinutes(dEnd.getMinutes());
//console.log('2nd Half Start: ' + showTwo.getStartDate());
//console.log('2nd Half End: ' + showTwo.getEndDate());
self.insertShow(showTwo);
}
else
{*/
var show = new LocalhostRadioStations.Schedule.Show();
show.setShow(broadcast);
show.setTableSelector('table#schedule');
// add the show to the table. Thankfully the order these come out the API means they get added
// in the right place. So don't change the schedule builder code!
self.insertShow(show);
//}
});
var days = LocalhostRadioStations.Schedule.days;
// apply the current day / time classes
$('th:contains('+ days[d.getDay()]+')').addClass('active');
$('td.time').each(function(i, cell){
// get the value, convert to int.
var hours = $(cell).html().split(':')[0];
// compare the hours with now, add class if matched.
if(parseInt(hours, 10) === d.getHours())
{
$(cell).addClass('current_time');
}
});
}
if(doFades)
{
// apply events to show info fade in / out.
$('td.schedule-show').hover(function(){
$(this).find('.schedule_details').fadeIn('fast');
}, function(){
$(this).find('.schedule_details').fadeOut('fast');
});
}
});
}
};
}();
LocalhostRadioStations.Schedule.ScheduleGen.init(twittiName);
});
It should change the schedule according to the JSONP, but what do I do to fix it?
Basically, I am trying to make my own localhost version of http://radioplayer.bauerradio.com/schedule.php?callback=&name=Rock+FM and its JSON / JSONP (I am not sure exactly what type the original is, but then again the site is experimental and on a .localhost domain) for testing purposes where the content is taken from the database, and changes according to station name, e.g. http://radioplayer.bauerradio.com/schedule.php?callback=&name=Metro+Radio and http://radioplayer.bauerradio.com/schedule.php?callback=&name=Forth+One etc.
Edit: The full code for my page can be seen at http://pastebin.com/ENhR6Q9j
I'm not sure exactly what's missing, but from the code you gave so far, I made a jsfiddle:
Demo
I modified some things to make it work (mostly appending stuff), because I don't know your original HTML file. But I also made some changes based on what you say you wanted. First of all I modified your $.getJSON call to be something like:
$.getJSON('http://radioplayer.bauerradio.com/schedule.php?callback=?', {
name: stationName //stationName is from the argument passed
}, function(json){...})
Which should give back the station based on what is passed to
LocalhostRadioStations.Schedule.ScheduleGen.init(twittiName);
To make it more interesting, I also added a bit of code that reads from the url. In this case if you go to the page with a domain.htm/page?Northern FM it will read the text after the ? and put it in twittiName.
var twittiName="Rock FM"; //default station
if(window.location.search){
twittiName=window.location.search.substring(1) //or window.location.hash
}
Tried to look for other stations that might be on your publics site, but so far I could only test with "?Rock+FM". But does mean you can show the errors, which your code can handle as it is.
?Rock+FM
?Random Name
So it seems that your code mostly works but do comment if I have missed anything.

JSON/PHP script and callbacks [duplicate]

This is my JSONP file:
<?php
header('Content-type: application/javascript;');
header("access-control-allow-origin: *");
header("Access-Control-Allow-Methods: GET");
//db connection detils
$host = "localhost";
$user = "test";
$password = "test";
$database = "myradiostation1";
//make connection
$server = mysql_connect($host, $user, $password);
$connection = mysql_select_db($database, $server);
//query the database
$query = mysql_query("SELECT *, DATE_FORMAT(start, '%d/%m/%Y %H:%i:%s') AS start,
DATE_FORMAT(end, '%d/%m/%Y %H:%i:%s') AS end FROM radiostation1");
//loop through and return results
for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
$row = mysql_fetch_assoc($query);
$shows[$x] = array("id" => $row["id"], "startminutes" => $row["startminutes"], "start" => $row["start"], "endminutes" => $row["endminutes"],"end" => $row["end"],"mediumname" => $row["mediumname"], "longname" => $row["longname"], "description" => $row["description"],"short_id" => $row["short_id"],"promomessage" => $row["promomessage"],"email" => $row["email"],"phonenumber" => $row["phonenumber"],"textnumber" => $row["textnumber"],"textprefix" => $row["textprefix"],"showimage" => $row["showimage"],"longdescription" => $row["longdescription"],"facebooklink" => $row["facebooklink"],"otherlink" => $row["otherlink"],"websitelink" => $row["websitelink"],"keywords" => $row["keywords"] );
}
//echo JSON to page
$response = $_GET["callback"] . "(" . json_encode($shows) . ");";
echo $response;
?>
It does work, up to a point, but getting the {"success":true,"error":"","data":{"schedule": as seen at this site before my json_encode is where I am.
However, I cannot get it to display any data in my table, although it DOES produce code on-screen when I view it at http://www.myradio1.localhost/onairschedule.php.
The actual code is stored at http://www.myradiostations.localhost/schedule.php
and the callback function works OK, one example being http://www.myradiostations.localhost/schedule.php?callback=?&name=Northern+FM and http://www.myradiostations.localhost/schedule.php?callback=?&name=Southern+FM but what do I need to do to make it change like in these examples:
this example and this example, and to generate an error message like this if no such file exists.
I'm halfway there, just need some advice on fixing my code!
Basically, what I'm trying to do... get a JSONP to work in my HTML table which will vary the content depending on the URL in my javascript file on my page, which is:
var doFades = true;
var LocalhostRadioStations = {
Schedule : {}
};
$(document).ready(function(){
LocalhostRadioStations.Schedule.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
LocalhostRadioStations.Schedule.Show = function () {
_s = null;
_startDate = null;
_endDate = null;
this.days = LocalhostRadioStations.Schedule.days;
_selector = '';
this.setShow = function(s) {
this._s = s;
this._startDate = new Date( parseInt(s.startminutes, 10) * 1000);
this._endDate = new Date(parseInt(s.endminutes, 10) * 1000 );
};
this.getEndDate = function(){
return this._endDate;
}
this.getStartDate = function(){
return this._startDate;
}
this._getShowDay = function (){
return this.days[this.getStartDate().getDay()];
};
this._getShowUnitsTaken = function(){
// if it's the same day
return this._getEndUnits() - this._getStartUnits();
};
this._getEndUnits = function(){
if(this.getEndDate().getHours() == 0)
{
//console.log(this._s.longname +' ends at midnight');
return 48;
}
return this.getEndDate().getMinutes() !== 0 ? (this.getEndDate().getHours() * 2) : (this.getEndDate().getHours() * 2);
};
this._getStartUnits = function(){
if(this.getStartDate().getHours() == 0)
{
return 0;
}
return this.getStartDate().getMinutes() !== 0 ? (this.getStartDate().getHours() * 2) : (this.getStartDate().getHours() * 2);
};
this.getCellPositions = function() {
return {
'start' : this.getStartDate(),
'end' : this.getEndDate(),
'colIndex' : this.getStartDate().getDay() + 2,
'startUnits' : this._getStartUnits(),
'endUnits' : this._getEndUnits(),
'unitsTaken' : this._getShowUnitsTaken()
}
};
this.pad = function(number){
return number < 10 ? '0'+number : number;
};
// return the table cell html.
this.toHtml = function () {
var d = new Date();
var units = this._getStartUnits();
var rowspan = this._getShowUnitsTaken();
var desc = this._s.description;
var name = this._s.longname;
var starttime = this.pad(this.getStartDate().getHours()) + ':' + this.pad(this.getStartDate().getMinutes());
var endtime = this.pad(this.getEndDate().getHours()) + ':' + this.pad(this.getEndDate().getMinutes());
var site = this._s.websitelink;
var cls = this.isActive() ? 'current-program' : '';
var isToday = this.getStartDate().getDay() === d.getDay() ? 'active-program' : '';
var html = '<td class="schedule-show ' + isToday + ' ' + cls + '" rowspan="' + rowspan + '" data-start="' + this.getStartDate() + '" data-end="' + this.getEndDate() + '">';
html += '<div>';
html += '' + name + '';
html += '</div>';
if(doFades)
{
html += '<div class="schedule_details clearfix" style="display:none;">';
html += '<img width="105px" height="105px" alt="' + desc + '" src="' + this._s.showimage + '">';
html += '<strong>' + name + '</strong>';
html += '<p>' + desc + '</p>';
html += '<span>' + starttime + ' - ' + endtime +'</span>';
html += '</div>';
}
html += '</td>';
return html;
};
this.setTableSelector = function(sel){
this._selector = sel;
};
// check if we should add the active class.
this.isActive = function(){
var t = new Date();
return t >= this.getStartDate() && t <= this.getEndDate();
};
};
LocalhostRadioStations.Schedule.ScheduleGen = function(){
return {
insertShow : function(show) {
var p = show.getCellPositions();
$('tr#units-' + p.startUnits).append(show.toHtml());
},
init : function (stationName){
var self = this;
// load the schedule.
$.getJSON('http://www.myradiostations.localhost/schedule.php?callback=?&name=', {
name: 'Northern FM'
}, function(json){
// loop each show and append to our giant table.
// this is well sick.
if(json.success === false)
{
$('.content-inner table').remove();
$('<div>errors</div>').appendTo('.content-inner');
}
else
{
var currentDay = '';
var day = 0;
// highlight the current time..
var d = new Date();
var weekStart = new Date();
weekStart.setDate(d.getDate()-6-(d.getDay()||7));
$.each(json.data.schedule, function(i, broadcast){
var dStart = new Date( parseInt(broadcast.startminutes, 10) * 1000);
var dEnd = new Date(parseInt(broadcast.endminutes, 10) * 1000 );
/*// transform to a show object defined above, if the show spans 2 days we create two show objects.
// IF THE SHOW STARTS/ENDS AT MIDNIGHT, DON'T SPLIT IT.
if(dStart.getHours() !== 0 && dEnd.getHours() !== 0 && dStart.getDate() != dEnd.getDate())
{
var showOne = new LocalhostRadioStations.Schedule.Show();
showOne.setShow(broadcast);
// set to midnight
showOne.getEndDate().setHours(0);
showOne.getEndDate().setMinutes(dStart.getMinutes());
// append first half of show.
self.insertShow(showOne);
// handle second half.
var showTwo = new LocalhostRadioStations.Schedule.Show();
showTwo.setShow(broadcast);
showTwo.getStartDate().setDate(showTwo.getStartDate().getDate() + 1);
showTwo.getStartDate().setHours(0);
showTwo.getStartDate().setMinutes(dEnd.getMinutes());
//console.log('2nd Half Start: ' + showTwo.getStartDate());
//console.log('2nd Half End: ' + showTwo.getEndDate());
self.insertShow(showTwo);
}
else
{*/
var show = new LocalhostRadioStations.Schedule.Show();
show.setShow(broadcast);
show.setTableSelector('table#schedule');
// add the show to the table. Thankfully the order these come out the API means they get added
// in the right place. So don't change the schedule builder code!
self.insertShow(show);
//}
});
var days = LocalhostRadioStations.Schedule.days;
// apply the current day / time classes
$('th:contains('+ days[d.getDay()]+')').addClass('active');
$('td.time').each(function(i, cell){
// get the value, convert to int.
var hours = $(cell).html().split(':')[0];
// compare the hours with now, add class if matched.
if(parseInt(hours, 10) === d.getHours())
{
$(cell).addClass('current_time');
}
});
}
if(doFades)
{
// apply events to show info fade in / out.
$('td.schedule-show').hover(function(){
$(this).find('.schedule_details').fadeIn('fast');
}, function(){
$(this).find('.schedule_details').fadeOut('fast');
});
}
});
}
};
}();
LocalhostRadioStations.Schedule.ScheduleGen.init(twittiName);
});
It should change the schedule according to the JSONP, but what do I do to fix it?
Basically, I am trying to make my own localhost version of http://radioplayer.bauerradio.com/schedule.php?callback=&name=Rock+FM and its JSON / JSONP (I am not sure exactly what type the original is, but then again the site is experimental and on a .localhost domain) for testing purposes where the content is taken from the database, and changes according to station name, e.g. http://radioplayer.bauerradio.com/schedule.php?callback=&name=Metro+Radio and http://radioplayer.bauerradio.com/schedule.php?callback=&name=Forth+One etc.
Edit: The full code for my page can be seen at http://pastebin.com/ENhR6Q9j
I'm not sure exactly what's missing, but from the code you gave so far, I made a jsfiddle:
Demo
I modified some things to make it work (mostly appending stuff), because I don't know your original HTML file. But I also made some changes based on what you say you wanted. First of all I modified your $.getJSON call to be something like:
$.getJSON('http://radioplayer.bauerradio.com/schedule.php?callback=?', {
name: stationName //stationName is from the argument passed
}, function(json){...})
Which should give back the station based on what is passed to
LocalhostRadioStations.Schedule.ScheduleGen.init(twittiName);
To make it more interesting, I also added a bit of code that reads from the url. In this case if you go to the page with a domain.htm/page?Northern FM it will read the text after the ? and put it in twittiName.
var twittiName="Rock FM"; //default station
if(window.location.search){
twittiName=window.location.search.substring(1) //or window.location.hash
}
Tried to look for other stations that might be on your publics site, but so far I could only test with "?Rock+FM". But does mean you can show the errors, which your code can handle as it is.
?Rock+FM
?Random Name
So it seems that your code mostly works but do comment if I have missed anything.

Categories