I want to pass string value from c# to JavaScript using JSON. So I created an example plugin name: Echo.cs (in CordovaWP namespace), and an "echo" method in Echo class. Like this tutorial.
In index.js, I called:
cordova.exec(function (result)
{
alert("OK");
}, function (error) {
alert("KO");
}, "CordovaWP.Echo", "echo", "ok");
But I can't get debug in echo method. And have nothing found!
Use as below:
cordova.exec(function (result)
{
alert("OK");
}, function (error) {
alert("KO");
}, "CordovaWP.Echo", "echo", ["ok"]);
Parameters should always be sent as an array from JS to cs
Please can you also post your CS code:
Check sample below SMS example:
JS:
var sendSMS = function(phoneNumber,smsBody){
cordova.exec(function(){console.log("success SMS");},function(){console.log("Error SMS");},"SMS", "sendSMS", [phoneNumber,smsBody]);
};
CS:
namespace Cordova.Extension.Commands{
public class SMS : BaseCommand
{
public void sendSMS(string arg)
{
string recipient = JsonHelper.Deserialize<string[]>(arg)[0];
string smsBody = JsonHelper.Deserialize<string[]>(arg)[1];
SmsComposeTask composeSMS = new SmsComposeTask();
composeSMS.Body = smsBody;
composeSMS.To = recipient;
composeSMS.Show();
this.DispatchCommandResult();
}
}
}
Related
This will be a post where I ask the question and propose a solution
Since having had several trouble and having looked around a lot I decided to post my final solution for anyone else to take profit from it.
Question:
How to render google's reCaptcha v2.0 widget and verifying it in a Marionettejs app with a java back end.
After the common steps and following google guides to render the re captcha my captcha still didn't render, so here comes my solution:
Rendering the captcha and the inclusion of the script are both made inside the itemview onRender function:
'text!login/templates/form.html',
'app'
], function (app, Marionette, Backbone, _, $, Handlebars, FormTemplate) {
return Marionette.ItemView.extend({
template: Handlebars.compile(FormTemplate),
ui: {
form: '
},
events: {
'submit #ui.form': 'onSubmit'
},
onRender: function() {
this.loadCaptcha();
},
loadCaptcha: function() {
var self = this;
var getRecaptchaResponse = function(response) {
self.captchaResponse = response;
};
window.renderCaptcha = function () {
self.captchaWidgetId = grecaptcha.render('yourCaptchaDiv', {
sitekey: 'YourSiteKey',
callback: getRecaptchaResponse
});
};
$.getScript('https://www.google.com/recaptcha/api.js?onload=renderCaptcha&render=explicit', function() {});
},
...
}
I tried other ways of loading the script with several errors, like the script loaded before the div for it, or the browser says de Dom has completely loaded but the onRender gets called after
I had to include a div for the captcha widget to load in, this is in
form.html
<div id="reCaptcha" class="btn"></div>
That will have your widget rendered, now you need to both verify it has been filled and it is a valid user response with google, for this I use the same module and use the next function:
onSubmit: function (e) {
//only act if the captcha has been filled - This could be easily erased from a browser, but a back end verification takes place too
if (grecaptcha.getResponse() !== "") {
e.preventDefault();
var _view = this;
this.blockForm();
$.ajax({
url: 'yourLoginService',
type: 'POST',
data: {
userLogin: this.ui.user.val(),
userPassword: this.ui.password.val(),
//get the captcha response
captchaResponse: grecaptcha.getResponse()
}
}).done(function (data) {
app.router.navigate('', {trigger: true});
_view.destroy();
}).fail(function (jqXHR, textStatus, errorThrown) {
// your fail handling
});
}
},
Then comes the time to verify your captcha server side using the secret key provided by google (note this is a Java6 app, therefore the clumbersome exception Handling):
//some other imports ignored
import org.apache.commons.io.IOUtils;
import org.json.JSONException;
import org.json.JSONObject;
class Captcha {
private static final String CAPTCHA_SECRET_KEY = "YourSecretKey";
private static final Logger LOGGER = Logger.getLogger(Captcha.class);
static boolean isCaptchaValid(String response) {
try {
String url = "https://www.google.com/recaptcha/api/siteverify?"
+ "secret=" + CAPTCHA_SECRET_KEY
+ "&response=" + response;
InputStream res = new URL(url).openStream();
JSONObject json = new JSONObject(getJsonResponse(res));
res.close();
return json.getBoolean("success");
} catch (JSONException e) {
LOGGER.error("Can not parse captcha response Json: " + e);
return false;
} catch (MalformedURLException e) {
LOGGER.error("Malformed URL: " + e);
return false;
} catch (IOException e) {
LOGGER.error("Error reading response from captcha verification response: " + e);
return false;
}
}
private static String getJsonResponse(InputStream res) throws IOException {
BufferedReader rd = new BufferedReader(new InputStreamReader(res, Charset.forName("UTF-8")));
/*TODO in java 8+ use this and avoid using the external library
return rd.lines().collect(Collectors.joining());
*/
return IOUtils.toString(rd);
}
}
im trying to working on this project https://www.youtube.com/watch?v=bu0J-j5qYas
so i can charge multiple times with dummy credit-card.
But i got exception error message when i try to check out, it say must provide source or customer, below is the javascript i wrote.
Stripe.setPublishableKey(''); // im not showingt this key (censored)
var $form = $('#checkout-form');
$form.submit(function(event) {
$('#charge-error').addClass('hidden');
$form.find('button').prop('disabled', true);
Stripe.card.createToken({
number: $('#card-number').val(),
cvc: $('#card-cvc').val(),
exp_month: $('#card-expiry-month').val(),
exp_year: $('#card-expiry-year').val(),
name: $('#card-name').val()
}, stripeResponseHandler);
return false;
});
function stripeResponseHandler(status, response) {
if (response.error) {
$('#charge-error').removeClass('hidden');
$('#charge-error').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
var token = response.id;
$form.append($('<input type="hidden" name="stripeToken" />').val(token)); // this will generate the stripeToken
// Submit the form:
$form.get(0).submit();
}
}
and i make this functionc below inside the controller directory just like the guide say
public function postCheckout(Request $request)
{
if (!Session::has('cart')) {
return redirect()->route('shop.shoppingCart');
}
$oldCart = Session::get('cart');
$cart = new Cart($oldCart);
Stripe::setApiKey(''); // not showing this key (censored)
try {
Charge::create(array(
"amount" => $cart->totalPrice * 100,
"currency" => "usd",
"source" => $request->input('stripeToken'), // obtained with first code i wrote above
"description" => "Test Charge"
));
} catch (\Exception $e) {
return redirect()->route('checkout')->with('error', $e->getMessage());
}
Session::forget('cart');
return redirect()->route('product.index')->with('success', 'Successfully purchased products!');
}
}
it keep return the catch that throw exception error message, is this mean it failed to get the stripetoken, how am i suppose to fix this? please help me
hi i think i figured out the problem, i rest the the api keys and also i check your spaces between the quotation marks in the public and secret keys,
Stripe.setPublishableKey('pk_anjndjxnh8hih9u220822');
and
Stripe::setApiKey('sk_dkneijhf9u9ue9ujednf9hefnie'); // not showing this key (censored)
try this Stripe: Must provide source or customer it is work for me!
just adding script with jquery-3.1.1.min.js like <script type="text/javascript" src="/javascripts/jquery-3.1.1.min.js"></script> before calling your checkout js file.
I have got to know toaster.js from this site and trying to implement it in my web app. I have done it according to the example but it doesn't work.
Here is my service where I Implemented:
function () {
angular
.module('FoursquareApp')
.factory('DataService', DataService);
DataService.$inject = ['$http','toaster'];
function DataService($http, toaster) {
.id,
venueName: venue.name,var serviceBase = '/api/places/';
var placesDataFactory = {};
var userInContext = null;
var _getUserInCtx = function () {
return userInContext;
};
var _setUserInCtx = function (userInCtx) {
userInContext = userInCtx;
};
var _savePlace = function (venue) {
//process venue to take needed properties
var minVenue = {
userName: userInContext,
venueID: venue
address: venue.location.address,
category: venue.categories[0].shortName,
rating: venue.rating
};
return $http.post(serviceBase, minVenue).then(
function (results) {
toaster.pop('success', "Bookmarked Successfully", "Place saved to your bookmark!");
},
function (results) {
if (results.status == 304) {
toaster.pop('note', "Faield to Bookmark", "Something went wrong while saving :-(");
}
else {
toaster.pop('error', "Failed to Bookmark", "Something went wrong while saving :-(");
}
return results;
});
};
I have called the library scripts in index.html and also the css files.
Any ideas of what I might be doing wrong?
Are you sure that you use toaster.js library? The popular one is toastr.js
Try to modify your code to
DataService.$inject = ['$http','toastr'];
function DataService($http, toastr) {
...
Also ensure, that you link this js file in you index.html and also refer this package in main app module definition as a second (dependency) parameter
I have a controller. The code is below The javavascript that works with this controller is also below. This code was created in Visual Studio 2013 using MVC 5. The code was published to IIS and has worked as expected for several weeks. Because of changing requirements the code was ported to a project using Katana and is now self-hosed using a console application. The Controller and javascript are the same. The issue is that when I make a call to add a location the Get method is called, but the location variable is now null. Why does this code work hosted in Internet Information Server and not as a self hosted application using Katana?
Controller:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Mvc;
using PatientCommunication.Model;
using PatientCommunication.Repository;
using PatientCommunication.DataAccess;
using Walden.Utility;
namespace PatientCommunication.Web.Controllers
{
public class LocationController : ApiController
{
// GET api/location
private ILocations locations = new Locations();
public IEnumerable<Location> Get()
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
List<Location> locationList = new List<Location>();
locationList = locations.GetLocationList();
return locationList;
}
public void Post([FromBody] Location locationList)
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
locations.UpdateLocation(locationList);
}
public ActionResult Put(IEnumerable<Location> location)
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
string toBeVoiced = string.Empty;
try
{
foreach (var loc in location)
{
Location singlelocation = new Location();
singlelocation.LocationID = loc.LocationID;
singlelocation.LocationName = loc.LocationName;
locations.AddLocation(singlelocation);
}
return new JsonResult { Data = new { Success = true } };
}
catch (Exception er)
{
string s1 = er.Message;
return new JsonResult { Data = new { Success = false } };
}
}
public void Delete([FromBody] Location locationList)
{
Database.ReminderConnection = ConfigurationManager.AppSettings["reminderConnection"];
locations.DeleteLocation(locationList);
}
}
}
Javascript:
$('#addLocation').click(function (e) {
if ($('#locationID').val().length < 1) {
ShowAlert("No Text", "Please Input Location ID")
e.preventDefault();
return;
}
if ($('#locationName').val().length < 1) {
ShowAlert("No Text", "Please Input Location Name")
e.preventDefault();
return;
}
locations.push({
ID: 0,
LocationID: $('#locationID').val(),
LocationName: $('#locationName').val()
});
$.ajax({
url: "api/location",
type: "PUT",
datatype: "json",
data: $.toJSON(locations),
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.Data.Success) {
ShowAlert("Insert", "Record Inserted");
$("#gridLocations").data("kendoGrid").dataSource.read();
$('#locationID').val('');
$('#locationName').val('');
locations = [];
}
else {
alert("Error'");
}
}
});
e.preventDefault();
});
Figured out the issue. I am using Nancy to deliver static content and in the pipeline I had the call to use Nancy before the call to Web API. This is what was causing my problem
When posting a form in my web app I perform a couple of checks in javascript before validating the form in the backend. The js validation is dependent upon I18 messages and images.
If this was a scala template I would of course use #Messages and #routes.Assets.at but I don't want to mix the two(scala template and .js file).
E.g I have this check in my js file where currently the image routes is hardcoded:
$("form input[type=submit]").click(function (e) {
e.preventDefault();
var email = $("#username");
var emailPattern = /^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*#([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$/;
if (email.val() == "") {
email.css("background-image", "url('/assets/images/general/input-row-red.jpg')");
return e.preventDefault();
} else {
email.css("background-image", "url(/images/general/inputTextBg.png)");
}
});
I have tried to prepare the js files with the messages they need like this:
.js file:
/* Prepare messages*/
var messages = "";
$.getJSON("/messages/source", {
"keys": "sms.form.login.hide,sms.form.login"},
function (data) {
messages = data.messages;
});
MessageSource controller:
object MessageSource extends Controller {
def getMessages(keys : String) = Action { request =>
if(keys.isEmpty) {
BadRequest(Json.obj("status" -> "KO", "message" -> "key plix!"))
}
else {
var js = Map.empty[String, String]
for (k <- keys.split(",")) {
js = js + (k -> Messages(k))
}
Ok(Json.obj("status" -> "OK", "messages" -> js))
}
}
}
But I don't feel that this is the best solution. I have looked at http://www.playframework.com/documentation/2.1.0/ScalaRouting but I can't figure it out.
Maybe you have some nice solution for me?
Maybe this way?
jsfile:
#scripts = {
<script type="text/javascript" src="#routes.Application.javascriptRoutes"></script>
<script type="text/javascript">
jsRoutes.controllers.Application.messages("admin.venue.1,admin.venue.2,admin.venue.3" ).ajax({
type: 'GET',
success: function (data) {
console.log(data.messages);
},
error: function () {
console.log("error");
}
});
</script>
}
Controller:
object Application extends Controller {
def javascriptRoutes = Action {
implicit request =>
import routes.javascript._
Ok(
Routes.javascriptRouter("jsRoutes")
(
routes.javascript.Application.messages
)
).as("text/javascript")
}
def messages(keys : String) = Action {
implicit request => {
val messages = keys.split(",").map { key =>
key -> Messages(key)
}.toMap
Ok(Json.obj("status" -> "OK", "messages" -> messages))
}
}
}
routes:
# Javascript routes
GET /javascriptRoutes controllers.Application.javascriptRoutes
GET /messages controllers.Application.messages(keys: String)