After upgrading to Phonegap 2.0, the datePicker plugin does not work. The error is:
Uncaught TypeError: Cannot read property 'datePicker' of undefined.
the error occcurs on the javascript code:
window.plugins.datePicker.show({...
The DatePicker js file:
/**
* Phonegap DatePicker Plugin Copyright (c) Greg Allen 2011 MIT Licensed
* Reused and ported to Android plugin by Daniel van 't Oever
*/
if (typeof cordova !== "undefined") {
/**
* Constructor
*/
function DatePicker() {
this._callback;
}
/**
* show - true to show the ad, false to hide the ad
*/
DatePicker.prototype.show = function(options, cb) {
if (options.date) {
options.date = (options.date.getMonth() + 1) + "/" + (options.date.getDate()) + "/" + (options.date.getFullYear()) + "/"
+ (options.date.getHours()) + "/" + (options.date.getMinutes());
}
var defaults = {
mode : '',
date : '',
allowOldDates : true
};
for ( var key in defaults) {
if (typeof options[key] !== "undefined")
defaults[key] = options[key];
}
this._callback = cb;
return cordova.exec(cb, failureCallback, 'DatePickerPlugin', defaults.mode, new Array(defaults));
};
DatePicker.prototype._dateSelected = function(date) {
var d = new Date(parseFloat(date) * 1000);
if (this._callback)
this._callback(d);
};
function failureCallback(err) {
console.log("datePickerPlugin.js failed: " + err);
}
cordova.addConstructor(function() {debugger;
if (!window.plugins) {
window.plugins = {};
}
window.plugins.datePicker = new DatePicker();
});
};
The DatePicker plugin java file:
/**
*
*/
package com.phonegap.plugin;
import java.util.Calendar;
import java.util.Date;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.util.Log;
import android.widget.DatePicker;
import android.widget.TimePicker;
import org.apache.cordova.DroidGap;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
/**
* @author ng4e
* @author Daniel van 't Oever
*
* Rewrote plugin so it it similar to the iOS datepicker plugin and it
* accepts prefilled dates and time
*/
public class DatePickerPlugin extends Plugin {
private static final String ACTION_DATE = "date";
private static final String ACTION_TIME = "time";
private final String pluginName = "DatePickerPlugin";
/*
* (non-Javadoc)
*
* @see com.phonegap.api.Plugin#execute(java.lang.String,
* org.json.JSONArray, java.lang.String)
*/
@Override
public PluginResult execute(final String action, final JSONArray data, final String callBackId) {
Log.d(pluginName, "DatePicker called with options: " + data);
PluginResult result = null;
this.show(data, callBackId);
result = new PluginResult(PluginResult.Status.NO_RESULT);
result.setKeepCallback(true);
return result;
}
public synchronized void show(final JSONArray data, final String callBackId) {
final DatePickerPlugin datePickerPlugin = this;
@SuppressWarnings("deprecation")
final DroidGap currentCtx = (DroidGap) ctx.getContext();
final Calendar c = Calendar.getInstance();
final Runnable runnable;
String action = "date";
/*
* Parse information from data parameter and where possible, override
* above date fields
*/
int month = -1, day = -1, year = -1, hour = -1, min = -1;
try {
JSONObject obj = data.getJSONObject(0);
action = obj.getString("mode");
String optionDate = obj.getString("date");
String[] datePart = optionDate.split("/");
month = Integer.parseInt(datePart[0]);
day = Integer.parseInt(datePart[1]);
year = Integer.parseInt(datePart[2]);
hour = Integer.parseInt(datePart[3]);
min = Integer.parseInt(datePart[4]);
/* currently not handled in Android */
// boolean optionAllowOldDates = obj.getBoolean("allowOldDates");
} catch (JSONException e) {
e.printStackTrace();
}
// By default initialize these fields to 'now'
final int mYear = year == -1 ? c.get(Calendar.YEAR) : year;
final int mMonth = month == -1 ? c.get(Calendar.MONTH) : month - 1;
final int mDay = day == -1 ? c.get(Calendar.DAY_OF_MONTH) : day;
final int mHour = hour == -1 ? c.get(Calendar.HOUR_OF_DAY) : hour;
final int mMinutes = min == -1 ? c.get(Calendar.MINUTE) : min;
if (ACTION_TIME.equalsIgnoreCase(action)) {
runnable = new Runnable() {
public void run() {
final TimeSetListener timeSetListener = new TimeSetListener(datePickerPlugin, callBackId);
final TimePickerDialog timeDialog = new TimePickerDialog(currentCtx, timeSetListener, mHour,
mMinutes, true);
timeDialog.show();
}
};
} else if (ACTION_DATE.equalsIgnoreCase(action)) {
runnable = new Runnable() {
public void run() {
final DateSetListener dateSetListener = new DateSetListener(datePickerPlugin, callBackId);
final DatePickerDialog dateDialog = new DatePickerDialog(currentCtx, dateSetListener, mYear,
mMonth, mDay);
dateDialog.show();
}
};
} else {
Log.d(pluginName, "Unknown action. Only 'date' or 'time' are valid actions");
return;
}
//((Activity) ctx).runOnUiThread(runnable);
}
private final class DateSetListener implements OnDateSetListener {
private final DatePickerPlugin datePickerPlugin;
private final String callBackId;
private DateSetListener(DatePickerPlugin datePickerPlugin, String callBackId) {
this.datePickerPlugin = datePickerPlugin;
this.callBackId = callBackId;
}
/**
* Return a string containing the date in the format YYYY/MM/DD
*/
public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
String returnDate = year + "/" + (monthOfYear + 1) + "/" + dayOfMonth;
datePickerPlugin.success(new PluginResult(PluginResult.Status.OK, returnDate), callBackId);
}
}
private final class TimeSetListener implements OnTimeSetListener {
private final DatePickerPlugin datePickerPlugin;
private final String callBackId;
private TimeSetListener(DatePickerPlugin datePickerPlugin, String callBackId) {
this.datePickerPlugin = datePickerPlugin;
this.callBackId = callBackId;
}
/**
* Return the current date with the time modified as it was set in the
* time picker.
*/
public void onTimeSet(final TimePicker view, final int hourOfDay, final int minute) {
/*Date date = new Date();
date.setHours(hourOfDay);
date.setMinutes(minute);*/
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, hourOfDay);
today.set(Calendar.MINUTE, minute);
Date date = today.getTime();
datePickerPlugin.success(new PluginResult(PluginResult.Status.OK, date.toString()), callBackId);
}
}
}
After I spend time on google, I made the following changes:
replace
cordova.addConstructor(function() {debugger;
if (!window.plugins) {
window.plugins = {};
}
window.plugins.datePicker = new DatePicker();
});
with
window.datePicker = new DatePicker();
Update the js code of calling it to
window.datePicker.show({...
Now I can get the datePicker object anyway, but got this new error:
Uncaught TypeError: Object # has no method 'exec'
on
DatePicker.prototype.show = function(options, cb) {
...
return cordova.exec(cb, failureCallback, 'DatePickerPlugin', defaults.mode, new Array(defaults));
})
Thanks for any help!
See Question&Answers more detail:
os