I'm creating a Google TimeLine chart, which works well except for the fact that when there's no data to return a broken text is shown inside the chart area, which should just remain blank.
I already checked if it was some wrong return from my DB (I commented all the DB access code to ensure the list that fills the chart would return empty) and the error persist.
So my best shot is that the error is with some misconfiguration of the Google timeline chart area itself.
This is the code that works perfectly when there is data return:
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChartTimeLine);
function reloadChartTimeLine(){
var inidate=document.getElementById("inidate").value;
var enddate=document.getElementById("enddate").value;
var idRack=document.getElementById("idRack").value;
jQuery.ajax({
type: "POST",
url: '<c:url value="/tracking/searchRackTimeLineByDate" />',
data: { idRack: idRack, inidate: inidate, enddate:enddate },
success: function(data) { drawChartTimeLine(data);}
});
}
function drawChartTimeLine(response) {
var data = new google.visualization.DataTable();
var container = document.getElementById('chart_div');
var chart = new google.visualization.Timeline(container);
data.addColumn( 'string','Local' );
data.addColumn( 'string','Situação' );
data.addColumn( 'date', 'Início' );
data.addColumn( 'date', 'Fim' );
if(response!=undefined){
response.forEach(function (row) {
data.addRow([
row.local,
row.movementStatus,
new Date(row.startDate),
new Date(row.endDate)
]);
});
}
data.insertColumn(2, {type: 'string', role: 'tooltip', p: {html: true}});
var dateFormat = new google.visualization.DateFormat({
pattern: 'd/M/yy HH:mm:ss'
});
var options = {
tooltip: {isHtml: true},
hAxis:{format:"dd/M" },
timeline: { showBarLabels: false},
colors: ['#0f434c','#a30404'],
};
var ticks = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
ticks.push(data.getValue(i, 0));
var duration = (data.getValue(i, 4).getTime() - data.getValue(i, 3).getTime()) / 1000;
var days = parseInt( duration / 86400 )
var hours = parseInt( duration / 3600 ) % 24;
var minutes = parseInt( duration / 60 ) % 60;
var seconds = duration % 60;
var tooltip = '<div class="ggl-tooltip"><span>' +
data.getValue(i, 1) + '</span></div><div class="ggl-tooltip"><span>' +
data.getValue(i, 0) + '</span>: ' +
dateFormat.formatValue(data.getValue(i, 3)) + ' - ' +
dateFormat.formatValue(data.getValue(i, 4)) + '</div>' +
'<div class="ggl-tooltip"><span>Duração : </span>' +
days + 'd '+hours + 'h ' + minutes + 'm ' + seconds + 's ';
data.setValue(i, 2, tooltip);
}
options["hAxis"]["ticks"] = [0]
chart.draw(data, options);
}
Here's a screenshot to the issue (there's no data to be returned in the selected period);
https://imgur.com/yKN9j9j
I selected and pasted the broken text and it goes "31/12" although in the chart canvas only a broken "/12" is visible. This same text occurs for every empty period.
A little late but I managed to show the chart without the canvas area when there's nothing to return just adding a lenght condition to use the response from ajax and putting all the code inside this condition as shown below; thanks for all the tips:
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChartTimeLine);
function reloadChartTimeLine(){
var inidate=document.getElementById("inidate").value;
var enddate=document.getElementById("enddate").value;
var idRack=document.getElementById("idRack").value;
jQuery.ajax({
type: "POST",
url: '<c:url value="/tracking/searchRackTimeLineByDate" />',
data: { idRack: idRack, inidate: inidate, enddate:enddate },
success: function(data) { drawChartTimeLine(data);}
});
}
function drawChartTimeLine(response) {
var data = new google.visualization.DataTable();
var container = document.getElementById('chart_div');
var chart = new google.visualization.Timeline(container);
data.addColumn( 'string','Local' );
data.addColumn( 'string','Situação' );
data.addColumn( 'date', 'Início' );
data.addColumn( 'date', 'Fim' );
if(response!=undefined && response.length>0){
response.forEach(function (row) {
data.addRow([
row.local,
row.movementStatus,
new Date(row.startDate),
new Date(row.endDate)
]);
});
data.insertColumn(2, {type: 'string', role: 'tooltip', p: {html: true}});
var dateFormat = new google.visualization.DateFormat({
pattern: 'd/M/yy HH:mm:ss'
});
var options = {
tooltip: {isHtml: true},
hAxis:{format:"dd/M" },
timeline: { showBarLabels: false},
colors: ['#0f434c','#a30404'],
};
var ticks = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
ticks.push(data.getValue(i, 0));
var duration = (data.getValue(i, 4).getTime() - data.getValue(i, 3).getTime()) / 1000;
var days = parseInt( duration / 86400 )
var hours = parseInt( duration / 3600 ) % 24;
var minutes = parseInt( duration / 60 ) % 60;
var seconds = duration % 60;
var tooltip = '<div class="ggl-tooltip"><span>' +
data.getValue(i, 1) + '</span></div><div class="ggl-tooltip"><span>' +
data.getValue(i, 0) + '</span>: ' +
dateFormat.formatValue(data.getValue(i, 3)) + ' - ' +
dateFormat.formatValue(data.getValue(i, 4)) + '</div>' +
'<div class="ggl-tooltip"><span>Duração : </span>' +
days + 'd '+hours + 'h ' + minutes + 'm ' + seconds + 's ';
data.setValue(i, 2, tooltip);
}
options["hAxis"]["ticks"] = [0]
chart.draw(data, options);
}
}
Related
I am using YQL to parse an RSS feed on my wordpress website. I have the code working and displaying entries from my RSS feed, but how do I limit the number of entries it displays? Is there a way to display 5 at a time? My code is as follows:
function parseFeed(url, container) {
// yql query
var query = 'https://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from feednormalizer where url="' + url + '"' ) + '&format=json';
// send request
$.getJSON(query, function (data, status, errorThrown) {
// if successful... *
if (status === 'success') {
// log object data in console
console.log(data);
// append feed link and title in container
$(container).append('<span class="iconicstroke-rss-alt"></span>');
$(container).append('<h1 class="feed">' + data.query.results.rss.channel.title );
// for each entry... *
$.each(data.query.results.rss.channel.item, function (key, value) {
// * create new date object and pass in entry date
var date = new Date(value.pubDate);
// * create months array
var months = new Array(12);
months[0] = 'January';
months[1] = 'February';
months[2] = 'March';
months[3] = 'April';
months[4] = 'May';
months[5] = 'June';
months[6] = 'July';
months[7] = 'August';
months[8] = 'September';
months[9] = 'October';
months[10] = 'November';
months[11] = 'December';
// * parse month, day and year
var month = date.getMonth();
var day = date.getDate();
var year = date.getFullYear();
// * build content snippet
var content = $(value.description).text().substring(0, 340);
if (value.description.length > content.length ) {
content += ' ...';
}
// * assign entry variables
var title = '<h3 class="title">' + value.title + '</h3>';
var time = '<p class="time">' + day + ' ' + months[month] + ' ' + year + '</p>';
var snippet = '<p class="snippet">' + content + '</p>';
var entry = '<div class="entry">' + title + time + snippet + '</div>';
// * append entire entry in container
$(container).append(entry);
});
// if there's an error... *
} else if (status === 'error' || status === 'parsererror') {
// * log error message in console
console.log(errorThrown);
// * show error message
alert('Could not load RSS feed!');
}
});
}
$(document).ready(function () {
parseFeed('http://www.vatlive.com/feed/', '#vatrss', '');
});
How can I get the current date, current year, current month, and current week in sapui5? This is the code I started with:
var oType = new sap.ui.model.type.Date();
oType = new sap.ui.model.type.Date({ source: {}, pattern: "MM/dd/yyyy" });
I have no idea where to go from here. Any help would be greatly appreciated.
EDIT: How do I get the following javascript function into a sapui5 table?
function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
function dateFunction() {
var today = new Date();
var dd = addZero(today.getDate());
var MM = addZero(today.getMonth() + 1);
var yyyy = today.getFullYear();
var hours = addZero(today.getHours());
var min = addZero(today.getMinutes());
var sec = addZero(today.getSeconds());
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
today = MM + '/' + dd + '/' + yyyy + " " + hours + ":" + min + ":" + sec + " " + ampm;
}
To get Current Date:
there is NO predefined function in SAPUI5, hence use native JavaScript Method:
var oDate = new Date();
How to put date in a table?
JS Fiddle
var oData = {
results: [{
name: "Today",
date: new Date()
}, {
name: "Someday",
date: new Date("2015/01/01")
}, {
name: "New Year",
date: new Date("2016/01/01")
}]
}
var oModel = new sap.ui.model.json.JSONModel(oData);
// create table:
var oTable = new sap.m.Table({
columns: [
new sap.m.Column({
header: new sap.m.Label({
text: "When"
})
}),
new sap.m.Column({
header: new sap.m.Label({
text: "Date"
})
})]
});
var oType = new sap.ui.model.type.Date({
pattern: "MM/dd/yyyy"
});
var oTemplate = new sap.m.ColumnListItem({
cells: [
new sap.m.Text({
text: "{name}"
}),
new sap.m.Text({
text: {
path: 'date',
type: oType
}
})]
});
oTable.setModel(oModel);
oTable.bindItems("/results", oTemplate);
oTable.placeAt("content");
Update: Based on comment request
All you need is this:
var oType = new sap.ui.model.type.Date({
pattern: "MM/dd/yyyy"
});
oTable.addColumn(new sap.ui.table.Column("today", {
label: new sap.m.Label({
text: {
path: 'today',
type: oType
}
})
sortProperty: 'today',
filterProperty: 'today'
}));
I'm using a JQuery/PHP script which displays 12 clocks on a page. The Javascript file calls a PHP file to determine the timezone offset, but with 12 clocks to display, 12 PHP requests is crashing my page.
JS FILE
/*these are the div id names you added to your html*/
var clockAllDivs = [
"clock0",
"clockNYC",
"clockTOR",
"clockVAN",
"clockLAX",
"clockFRNK",
"clockSAO",
"clockTOK",
"clockBEI",
"clockHON",
"clockLONDON",
"clockPARIS",
"clockSYDNEY"
];
var tz = jstz.determine(); // Determines the time zone of the browser client
tz.name();
/*get timezone from this list: http://php.net/manual/en/timezones.php*/
var timeZones = [
tz.name(),
"America/New_York",
"America/Toronto",
"America/Vancouver",
"America/Vancouver",
"Europe/Zurich",
"America/Sao_Paulo",
"Asia/Tokyo",
"Asia/Hong_Kong",
"Asia/Hong_Kong",
"Europe/London",
"Europe/Paris",
"Australia/Sydney"
];
/*titles you want to show for each clock*/
var clockTitles = [
tz.name(),
"Los Angeles",
"Melbourne",
"Kathmandu",
"Tokyo",
"Johannesburg"
];
var useTitle1 = false;
var useTitle2 = false;
var clockWidthHeight = 118;//width and height of the clock
var distanceBetweenClockTitle = 5;
var secondHandSpeed = 100;//in ms, the lower the number, the faster
var smoothRotation = false;//true or false
var useSecondHand = false;//set to false if you don't want to see the 2nd hand
/*location of the images*/
var clockFaceImg = "img/clockBg.png";
var hourHandImg = "images/hourHand.png";
var minuteHandImg = "images/minuteHand.png";
var secondHandImg = "images/secondHand.png";
var amImg = "images/am.png";
var pmImg = "images/pm.png";
/*location of the high res images for retina display*/
var clockFaceHighResImg = "img/clockBgHighRes.png";
var hourHandHighResImg = "images/hourHandHighRes.png";
var minuteHandHighResImg = "images/minuteHandHighRes.png";
var secondHandHighResImg = "images/secondHandHighRes.png";
var amHighResImg = "images/amHighRes.png";
var pmHighResImg = "images/pmHighRes.png";
/*text for days and months*/
var dayText = [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
];
var monthText = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
];
///////////////////////////////
//Do not edit below this line//
///////////////////////////////
var clockDivs = [];
var offsets = [];
var minuteHand;
var hourHand;
var secondHands = [];
var minuteHands = [];
var hourHands = [];
var ams = [];
var pms = [];
var retina = false;
var imgsLoaded = 0;
var imagesToLoad = 6;
var callInterval = 1000;
var thisOffset;
var formerHr = [];
var isStart = true;
var tzChecked = 0;
//once the page is ready . . .
$( document ).ready(function() {
var dNow = new Date();
thisOffset = dNow.getTimezoneOffset();//figure out user's timezone
//get the timezone info for each of your clocks
for(var i = 0;i<clockAllDivs.length;i++){
getTZOutput(i);
}
});
//build each clock
function AnalogClock(){
retina = window.devicePixelRatio > 1;//check if retina
//if it's high res, use the high res images
if(retina){
clockFaceImg = clockFaceHighResImg;
hourHandImg = hourHandHighResImg;
minuteHandImg = minuteHandHighResImg;
secondHandImg = secondHandHighResImg;
amImg = amHighResImg;
pmImg = pmHighResImg;
}
//determine if you want to use the second hand
if(useSecondHand == false){
imagesToLoad = imagesToLoad - 1;
}
//change the call interval for smooth rotation
if(smoothRotation == true && useSecondHand){
callInterval = 50;
}
//create each clock visually
for(var i = 0;i<clockAllDivs.length;i++){
var clockAllDiv = $("#" + clockAllDivs[i]);
//add bg
clockAllDiv.append("<div id='analog-clock" + i + "' class='myClock'></div>")
//add title
if(useTitle1 || useTitle2){
var clockTitlePos = distanceBetweenClockTitle + clockWidthHeight;
if(useTitle1)clockAllDiv.append("<div><p class='clockTitle'>" + clockTitles[i] + "</p></div>");
if(useTitle2){
clockAllDiv.append("<div><p id='title2_" + i + "' class='clockTitle2'></p></div>");
}
$('.clockTitle').css({"margin-top":clockTitlePos + 'px'});
if(useTitle2 && !useTitle1)$('.clockTitle2').css({"margin-top":clockTitlePos + 'px'});
}
clockDivs[i] = "analog-clock" + i;
var clockDiv = $("#" + clockDivs[i]);
//set clock holder css
clockDiv.css({"height":clockWidthHeight + "px", "width":clockWidthHeight + "px", "position":"relative"});
//add more graphical elements
clockDiv.append("<img id='bg' src=" + clockFaceImg + " height="+clockWidthHeight+" width="+clockWidthHeight+" />");
//add the div for am/pm
clockDiv.append("<img id='am' class='ampm' src='" + amImg + "' width='28' height='18' />");
clockDiv.append("<img id='pm' class='ampm' src='" + pmImg + "' width='28' height='18' />");
//add hands
$("<img id='hourHand' src=" + hourHandImg + " />").appendTo("#" + clockDivs[i]);
clockDiv.append("<img id='minuteHand' src=" + minuteHandImg + " />");
if(useSecondHand)clockDiv.append("<img id='secondHand' src=" + secondHandImg + " />");
//define elements
if(useSecondHand)secondHands[i] = $("#" + clockDivs[i] + " #secondHand");
minuteHands[i] = $("#" + clockDivs[i] + " #minuteHand");
hourHands[i] = $("#" + clockDivs[i] + " #hourHand");
ams[i] = $("#" + clockDivs[i] + " #am");
pms[i] = $("#" + clockDivs[i] + " #pm");
if(i == 0){
//check to see if the images are loaded
$('#bg').load(function() { checkIfImagesLoaded(); });
if(useSecondHand)secondHands[i].load(function() { checkIfImagesLoaded(); });
minuteHands[i].load(function() { checkIfImagesLoaded(); });
hourHands[i].load(function() { checkIfImagesLoaded(); });
ams[i].load(function() { checkIfImagesLoaded(); });
pms[i].load(function() { checkIfImagesLoaded(); });
}
//set clock css
var handIds = $("#" + clockDivs[i] + " #bg, #hourHand, #minuteHand, #secondHand");
handIds.css({"position":"absolute"});
}
};
function checkIfImagesLoaded(){
//this gets called each time an image is loaded
imgsLoaded++;
if(imgsLoaded == imagesToLoad){//once all the images are loaded
for(var i = 0;i<clockAllDivs.length;i++){
//adjust widths and heights if 2x resolution
if(retina){
if(useSecondHand)secondHands[i].css( { "height":secondHands[i].height()/2, "width":secondHands[i].width()/2 } );
minuteHands[i].css( { "height":minuteHands[i].height()/2, "width":minuteHands[i].width()/2 } );
hourHands[i].css( { "height":hourHands[i].height()/2, "width":hourHands[i].width()/2 } );
}
//set the position of the hands
if(useSecondHand)secondHands[i].css( { "left": (clockWidthHeight - secondHands[i].width())/2 + "px", "top": (clockWidthHeight - secondHands[i].height())/2 + "px" });//set x and y pos
minuteHands[i].css( { "left": (clockWidthHeight - minuteHands[i].width())/2 + "px", "top": (clockWidthHeight - minuteHands[i].height())/2 + "px" });//set x and y pos
hourHands[i].css( { "left": (clockWidthHeight - hourHands[i].width())/2 + "px", "top": (clockWidthHeight - hourHands[i].height())/2 + "px" });//set x and y pos
//if(useSecondHand)setSecondStart();
//fade the clocks in
$("#" + clockAllDivs[i]).animate({ opacity:1 }, "slow");
}
//call rotatehands function
setInterval(function(){
rotateHands();
}, callInterval);//1000 = 1 second
if(!smoothRotation)rotateHands();//make sure they start in the right position
}
}
function rotateHands(){
for(var i = 0;i<clockAllDivs.length;i++){
//get current time/date from local computer
var now = new Date();
now.setMinutes(now.getMinutes() + offsets[i] + thisOffset);
//set the second hand
var secondAngle = 6 * now.getSeconds();//turn the time into angle
if(smoothRotation)var smoothSecondAngle = now.getMilliseconds()/1000 * 6 + secondAngle;
var currentHr = now.getHours();
if(formerHr[i] && currentHr != formerHr[i]){
getTZOutput(i);
setDayMonthTxt(now, i);
}
formerHr[i] = currentHr;
if(useSecondHand){
if(smoothRotation){
secondHands[i].rotate(smoothSecondAngle, 'abs');//set the hand angle
}else{
if(secondAngle == 0){
secondHands[i].rotate(-6, 'abs');//set the hand angle
}
secondHands[i].rotate({ animateTo:secondAngle, duration:secondHandSpeed}, 'abs');
}
}
//set the minute hand
var minuteAngle = 6 * now.getMinutes() + secondAngle/60;//turn the time into angle
minuteHands[i].rotate(minuteAngle, 'abs');//set the hand angle
//set the hour hand
var hourAngle = 360/12 * currentHr;//turn the time into angle
var hourAngleWOffset = hourAngle + minuteAngle/12;
hourHands[i].rotate(hourAngleWOffset%360, 'abs');//set the hand angle
}
isStart = false;
}
//get timezone info from the
function getTZOutput(thisNum) {
$.ajax({
type: "POST",
url:'timezone-clock-scripts/getTimezoneTime.php',
data: {thisTz:timeZones[thisNum]},
dataType: "json",
success: function (response) {
offsets[thisNum] = response/60;
allTZChecked();
},
error: function (){
console.log("error");
}
});
}
//make sure the php script has called first
function allTZChecked(){
tzChecked++;
if(tzChecked == clockAllDivs.length){
AnalogClock();
for(var i = 0;i<clockAllDivs.length;i++){
var now = new Date();
now.setMinutes(now.getMinutes() + offsets[i] + thisOffset);
setDayMonthTxt(now, i);
}
}
}
function setDayMonthTxt(now, thisNum){
var thisDay = dayText[now.getDay()];
var thisMonth = monthText[now.getMonth()];
var thisDate = now.getDate();
var thisYear = now.getFullYear();
//this is what the actual strong of text looks like, but you can modify it as you please.
if(useTitle2)$("#title2_" + thisNum ).html(thisDay + " " + thisMonth + " " + thisDate + ", " + thisYear);
//determine am/pm
if(now.getHours() < 12){
ams[thisNum].fadeIn();
pms[thisNum].fadeOut();
}else{
ams[thisNum].fadeOut();
pms[thisNum].fadeIn();
}
}
PHP FILE
<?php
$tzTxt = $_REQUEST['thisTz'];
$date = new DateTime();
$tz = new DateTimeZone($tzTxt);
$date->setTimezone($tz);
echo $date->format(Z);
//echo $date;
?>
Sometimes the page will reload, other times I get a a "Connection Was Reset" error.
When I disable this script, everything works fine.
Is there a way to alter my PHP settings to allow this script to work, or should I explore another option?
If the problem is that your server cannot handle the simultaneous requests, there are a few options:
Only call your php script once and send the information of all clocks at once. You can have your script return a json object that contains all offsets. This is what I would do.
Call the function when the previous version has finished (in the callback or have it return a promise). Possible, but overly complicated and you will hit your server still with an extra request for each clock.
i have implemented code to disable dates using beforeShow and beforeShowDay callbacks
below code is for binding calendar to input
$("#start_on").datepicker({
onSelect: function(date) {
date_check(date);
}, minDate: 0, dateFormat: "yy-mm-dd",
beforeShow: get_booked,
beforeShowDay: disable_if_not_available
});
yes this is binding calendar to element
callback for beforeShow
function get_booked(inpput, inst) {
var D = new Date();
var month = (inst.selectedMonth == 0 ? D.getMonth() : inst.selectedMonth) + 1;
var year = (inst.selectedYear == 0 ? D.getYear() : inst.selectedYear);
dis_date = new Array();
$.ajax({
url: BASE_URL + "contest/get_booked",
data: {year: year, month: month, id:<?php echo (isset($contest_data->id)) ? $contest_data->id : 0; ?>},
dataType: "json", type: "POST",
success: function(data) {
for (var d in data) {
var D = data[d];
var start = D.start_on;
var d = start.split("-");
var sD = new Date(d[0], d[1] - 1, d[2]);
var end = D.end_on;
var d = end.split("-");
var eD = new Date(d[0], d[1] - 1, d[2]);
while (sD <= eD) {
dis_date.push(sD.getFullYear() + "-" + (sD.getMonth() + 1) + "-" + sD.getDate());
sD.setDate(sD.getDate() + 1);
}
}
}
});
}
callback for beforeShowDay
function disable_if_not_available(date) {
var y = date.getFullYear(), m = date.getMonth() + 1, d = date.getDate();
return [dis_date.indexOf(y + "-" + m + "-" + d) == -1];
}
problem with this is that disable_if_not_available is getting called before dis_date get filled from get_booked. currently disable_if_not_available return always true because dis_date is empty so what i want to do is to call/return disable_if_not_available only after i get response from get_booked
please ask if any doubt
This happens because the entire initialization of the datepicker ends before the ajax call returns any value.
what you could do is start the ajax call and when the call ends, call the initialization of the datepicker.
example:
...
...
$.ajax({
url: BASE_URL + "contest/get_booked",
data: {year: year, month: month, id:<?php echo (isset($contest_data->id)) ? $contest_data->id : 0; ?>},
dataType: "json",
type: "POST",
success: function(data) {
for (var d in data) {
var D = data[d];
var start = D.start_on;
var d = start.split("-");
var sD = new Date(d[0], d[1] - 1, d[2]);
var end = D.end_on;
var d = end.split("-");
var eD = new Date(d[0], d[1] - 1, d[2]);
while (sD <= eD) {
dis_date.push(sD.getFullYear() + "-" + (sD.getMonth() + 1) + "-" + sD.getDate());
sD.setDate(sD.getDate() + 1);
}
}
//CALL YOUR DatePicker Initialization
initDatePicker();
}
});
...
...
function initDatePicker(){
$("#start_on").datepicker({/*Initialization values*/});
}
Simple Solution for this.just use 'async:false' in your ajax call.
Example:
...
...
$.ajax({
url: BASE_URL + "contest/get_booked",
data: {year: year, month: month, id:id)) ? $contest_data->id : 0; ?>},
dataType: "json",
type: "POST",
async:false,
success: function(data) {
...
...
I'm using smarty template engine. I'm using datepicker js plugin. My HTML code is as follows:
<tr>
<td valign="middle" align="right"><b>From Date </b> : </td>
<td align="left" > <input type="text" style="width:100px;" class="inputfield" name="from_date" id="from_date" value="{$from_date}" maxlength="10"/></td>
<td valign="middle" align="right"><b>To Date </b> : </td>
<td> <input type="text" style="width:100px;" class="inputfield" name="to_date" id="to_date" value="{$to_date}" maxlength="10"/></td>
</tr>
The jQuery function code is as below :
{literal}
<script language="javascript" type="application/javascript">
$(function() {
$( "#from_date" ).datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'dd/mm/yy'
});
});
$(function() {
$( "#to_date" ).datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'dd/mm/yy'
});
});
$(document).ready(function() {
$("#questions_listing").tablesorter({
widgets:['zebra'],
// sort on the fourth column and first column, order asc
sortList: [[1,0]]
});
});
$(".submit_form").click(function(e) {
var result = validateDate();
if(!result)
return false;
else
document.questions_filter.submit();
});
</script>
{/literal}
The datepicker.js file is as follows:
/* $(function() {
$( "#cal_from_date" ).datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'dd/mm/yy'
});
$( "#cal_to_date" ).datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'dd/mm/yy'
});
});*/
var datePickerDivID = "datepicker";
var iFrameDivID = "datepickeriframe";
var dayArrayShort = new Array('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa');
var dayArrayMed = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
var dayArrayLong = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
var monthArrayShort = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
var monthArrayMed = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec');
var monthArrayLong = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
var defaultDateSeparator = "/"; // common values would be "/" or "."
var defaultDateFormat = "dmy" // valid values are "mdy", "dmy", and "ymd"
var dateSeparator = defaultDateSeparator;
var dateFormat = defaultDateFormat;
function displayDatePicker(dateFieldName, displayBelowThisObject, dtFormat, dtSep)
{
var targetDateField = document.getElementsByName (dateFieldName).item(0);
if (!displayBelowThisObject)
displayBelowThisObject = targetDateField;
if (dtSep)
dateSeparator = dtSep;
else
dateSeparator = defaultDateSeparator;
if (dtFormat)
dateFormat = dtFormat;
else
dateFormat = defaultDateFormat;
var x = displayBelowThisObject.offsetLeft;
var y = displayBelowThisObject.offsetTop + displayBelowThisObject.offsetHeight ;
var parent = displayBelowThisObject;
while (parent.offsetParent) {
parent = parent.offsetParent;
x += parent.offsetLeft;
y += parent.offsetTop ;
}
drawDatePicker(targetDateField, x, y);
}
function drawDatePicker(targetDateField, x, y)
{
var dt = getFieldDate(targetDateField.value );
if (!document.getElementById(datePickerDivID)) {
// don't use innerHTML to update the body, because it can cause global variables
// that are currently pointing to objects on the page to have bad references
//document.body.innerHTML += "<div id='" + datePickerDivID + "' class='dpDiv'></div>";
var newNode = document.createElement("div");
newNode.setAttribute("id", datePickerDivID);
newNode.setAttribute("class", "dpDiv");
newNode.setAttribute("style", "visibility: hidden;");
document.body.appendChild(newNode);
}
// move the datepicker div to the proper x,y coordinate and toggle the visiblity
var pickerDiv = document.getElementById(datePickerDivID);
pickerDiv.style.position = "absolute";
pickerDiv.style.left = x + "px";
pickerDiv.style.top = y + "px";
pickerDiv.style.visibility = (pickerDiv.style.visibility == "visible" ? "hidden" : "visible");
pickerDiv.style.display = (pickerDiv.style.display == "block" ? "none" : "block");
pickerDiv.style.zIndex = 10000;
// draw the datepicker table
refreshDatePicker(targetDateField.name, dt.getFullYear(), dt.getMonth(), dt.getDate());
}
function refreshDatePicker(dateFieldName, year, month, day)
{
var thisDay = new Date();
if ((month >= 0) && (year > 0)) {
thisDay = new Date(year, month, 1);
} else {
day = thisDay.getDate();
thisDay.setDate(1);
}
var crlf = "\r\n";
var TABLE = "<table cols=7 class='dpTable'>" + crlf;
var xTABLE = "</table>" + crlf;
var TR = "<tr class='dpTR'>";
var TR_title = "<tr class='dpTitleTR'>";
var TR_days = "<tr class='dpDayTR'>";
var TR_todaybutton = "<tr class='dpTodayButtonTR'>";
var xTR = "</tr>" + crlf;
var TD = "<td class='dpTD' onMouseOut='this.className=\"dpTD\";' onMouseOver=' this.className=\"dpTDHover\";' ";
var TD_title = "<td colspan=5 class='dpTitleTD'>";
var TD_buttons = "<td class='dpButtonTD'>";
var TD_todaybutton = "<td colspan=7 class='dpTodayButtonTD'>";
var TD_days = "<td class='dpDayTD'>";
var TD_selected = "<td class='dpDayHighlightTD' onMouseOut='this.className=\"dpDayHighlightTD\";' onMouseOver='this.className=\"dpTDHover\";' "; // leave this tag open, because we'll be adding an onClick event
var xTD = "</td>" + crlf;
var DIV_title = "<div class='dpTitleText'>";
var DIV_selected = "<div class='dpDayHighlight'>";
var xDIV = "</div>";
// start generating the code for the calendar table
var html = TABLE;
// this is the title bar, which displays the month and the buttons to
// go back to a previous month or forward to the next month
html += TR_title;
html += TD_buttons + getButtonCode(dateFieldName, thisDay, -1, "<") + xTD;
html += TD_title + DIV_title + monthArrayLong[ thisDay.getMonth()] + " " + thisDay.getFullYear() + xDIV + xTD;
html += TD_buttons + getButtonCode(dateFieldName, thisDay, 1, ">") + xTD;
html += xTR;
// this is the row that indicates which day of the week we're on
html += TR_days;
for(i = 0; i < dayArrayShort.length; i++)
html += TD_days + dayArrayShort[i] + xTD;
html += xTR;
// now we'll start populating the table with days of the month
html += TR;
// first, the leading blanks
for (i = 0; i < thisDay.getDay(); i++)
html += TD + " " + xTD;
// now, the days of the month
do {
dayNum = thisDay.getDate();
TD_onclick = " onclick=\"updateDateField('" + dateFieldName + "', '" + getDateString(thisDay) + "');\">";
if (dayNum == day)
html += TD_selected + TD_onclick + DIV_selected + dayNum + xDIV + xTD;
else
html += TD + TD_onclick + dayNum + xTD;
// if this is a Saturday, start a new row
if (thisDay.getDay() == 6)
html += xTR + TR;
// increment the day
thisDay.setDate(thisDay.getDate() + 1);
} while (thisDay.getDate() > 1)
// fill in any trailing blanks
if (thisDay.getDay() > 0) {
for (i = 6; i > thisDay.getDay(); i--)
html += TD + " " + xTD;
}
html += xTR;
// add a button to allow the user to easily return to today, or close the calendar
var today = new Date();
var todayString = "Today is " + dayArrayMed[today.getDay()] + ", " + monthArrayMed[ today.getMonth()] + " " + today.getDate();
html += TR_todaybutton + TD_todaybutton;
html += "<button class='dpTodayButton' onClick='refreshDatePicker(\"" + dateFieldName + "\");'>this month</button> ";
html += "<button class='dpTodayButton' onClick='updateDateField(\"" + dateFieldName + "\");'>close</button>";
html += xTD + xTR;
// and finally, close the table
html += xTABLE;
document.getElementById(datePickerDivID).innerHTML = html;
// add an "iFrame shim" to allow the datepicker to display above selection lists
adjustiFrame();
}
/**
Convenience function for writing the code for the buttons that bring us back or forward
a month.
*/
function getButtonCode(dateFieldName, dateVal, adjust, label)
{
var newMonth = (dateVal.getMonth () + adjust) % 12;
var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12);
if (newMonth < 0) {
newMonth += 12;
newYear += -1;
}
return "<button class='dpButton' onClick='refreshDatePicker(\"" + dateFieldName + "\", " + newYear + ", " + newMonth + ");'>" + label + "</button>";
}
/**
Convert a JavaScript Date object to a string, based on the dateFormat and dateSeparator
variables at the beginning of this script library.
*/
function getDateString(dateVal)
{
var dayString = "00" + dateVal.getDate();
var monthString = "00" + (dateVal.getMonth()+1);
dayString = dayString.substring(dayString.length - 2);
monthString = monthString.substring(monthString.length - 2);
switch (dateFormat) {
case "dmy" :
return dayString + dateSeparator + monthString + dateSeparator + dateVal.getFullYear();
case "ymd" :
return dateVal.getFullYear() + dateSeparator + monthString + dateSeparator + dayString;
case "mdy" :
default :
return monthString + dateSeparator + dayString + dateSeparator + dateVal.getFullYear();
}
}
/**
Convert a string to a JavaScript Date object.
*/
function getFieldDate(dateString)
{
var dateVal;
var dArray;
var d, m, y;
try {
dArray = splitDateString(dateString);
if (dArray) {
switch (dateFormat) {
case "dmy" :
d = parseInt(dArray[0], 10);
m = parseInt(dArray[1], 10) - 1;
y = parseInt(dArray[2], 10);
break;
case "ymd" :
d = parseInt(dArray[2], 10);
m = parseInt(dArray[1], 10) - 1;
y = parseInt(dArray[0], 10);
break;
case "mdy" :
default :
d = parseInt(dArray[1], 10);
m = parseInt(dArray[0], 10) - 1;
y = parseInt(dArray[2], 10);
break;
}
dateVal = new Date(y, m, d);
} else if (dateString) {
dateVal = new Date(dateString);
} else {
dateVal = new Date();
}
} catch(e) {
dateVal = new Date();
}
return dateVal;
}
function splitDateString(dateString)
{
var dArray;
if (dateString.indexOf("/") >= 0)
dArray = dateString.split("/");
else if (dateString.indexOf(".") >= 0)
dArray = dateString.split(".");
else if (dateString.indexOf("-") >= 0)
dArray = dateString.split("-");
else if (dateString.indexOf("\\") >= 0)
dArray = dateString.split("\\");
else
dArray = false;
return dArray;
}
function updateDateField(dateFieldName, dateString)
{
var targetDateField = document.getElementsByName (dateFieldName).item(0);
if (dateString)
targetDateField.value = dateString;
var pickerDiv = document.getElementById(datePickerDivID);
pickerDiv.style.visibility = "hidden";
pickerDiv.style.display = "none";
adjustiFrame();
targetDateField.focus();
// after the datepicker has closed, optionally run a user-defined function called
// datePickerClosed, passing the field that was just updated as a parameter
// (note that this will only run if the user actually selected a date from the datepicker)
if ((dateString) && (typeof(datePickerClosed) == "function"))
datePickerClosed(targetDateField);
}
function adjustiFrame(pickerDiv, iFrameDiv)
{
// we know that Opera doesn't like something about this, so if we
// think we're using Opera, don't even try
var is_opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
if (is_opera)
return;
// put a try/catch block around the whole thing, just in case
try {
if (!document.getElementById(iFrameDivID)) {
var newNode = document.createElement("iFrame");
newNode.setAttribute("id", iFrameDivID);
newNode.setAttribute("src", "javascript:false;");
newNode.setAttribute("scrolling", "no");
newNode.setAttribute ("frameborder", "0");
document.body.appendChild(newNode);
}
if (!pickerDiv)
pickerDiv = document.getElementById(datePickerDivID);
if (!iFrameDiv)
iFrameDiv = document.getElementById(iFrameDivID);
try {
iFrameDiv.style.position = "absolute";
iFrameDiv.style.width = pickerDiv.offsetWidth;
iFrameDiv.style.height = pickerDiv.offsetHeight ;
iFrameDiv.style.top = pickerDiv.style.top;
iFrameDiv.style.left = pickerDiv.style.left;
iFrameDiv.style.zIndex = pickerDiv.style.zIndex - 1;
iFrameDiv.style.visibility = pickerDiv.style.visibility ;
iFrameDiv.style.display = pickerDiv.style.display;
} catch(e) {
}
} catch (ee) {
}
}
When I tested in firbug it is giving me the error TypeError: $(...).datepicker is not a function
I've included the files reuired i.e. jquery1.9.1 and datepicker .js, but still it's not working. Can anyone help me to resolve this issue?
Your code is just working perfectly! Check out this.
You just missed to include jquery-ui
Try including : <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script> in you <head> tag.
UPDATE: The fiddle is by #Safiuddin