Send ajax request in PeriodSelector AMChart - grails

I have this javascript code to draw an amchart stock, just the PeriodSelector part:
var periodSelectorAjax = new AmCharts.PeriodSelector();
periodSelectorAjax.periods = [
{period: "F1", label: "Phase 1"},
{period: "F2", label: "Phase 2"},
{period: "F3", label: "Phase 3"},
{period: "MAX", selected: true, label: "MAX"}
];
I need to intercept when user click on period to reload the graph, I see that I can do it with this, from here:
var chart = AmCharts.makeChart( "chartdiv", {
"type": "stock",
// ...
"periodSelector": {
"position": "left",
"periods": [ {
"period": "MM",
"selected": true,
"count": 1,
"label": "1 month"
}, {
"period": "YYYY",
"count": 1,
"label": "1 year"
}, {
"period": "YTD",
"label": "YTD"
}, {
"period": "MAX",
"label": "MAX"
} ],
"listeners": [ {
"event": "changed",
"method": function( event ) {
if ( event.predefinedPeriod !== undefined ) {
console.log( event.predefinedPeriod, event.count );
}
}
} ]
},
// ...
} );
But I don't know how to put the last listeners part and use it with my code.
thanks

You can either use the addListener method or just set the listeners array directly on your periodSelectorAjax variable.
addListener example:
periodSelectorAjax.addListener("changed", function(event) {
// your code here
});
listeners property example:
periodSelectorAjax.listeners = [{
"event": "changed",
"method": function(event) {
// ...
}
}]

Related

Is there a way to enter dollars/cents via DTMF?

I'm currently working on a pay-by-phone system with this flow:
<Gather> customer's account number with us
<Gather> amount to pay
<Pay> - with the previous 2 <Gather>s passed as variables to Stripe
The issue I am having is collecting the amount. Is there a way to convert the amount from a single string to a decimal string?
eg. 12300 becomes 123.00
All suggestions welcome as the current working theory is to add a third <Gather> just for the cents but this feels cumbersome from a UX/UI perspective.
I edited this answer, since I was successful in accomplishing this.
I did it with STUDIO and FUNCTIONS.
Prompt the caller to enter the amount using star key () as a decimal. For example to enter $5.43 they should enter 543 and then press #.
then I took the gathered digits and sent them out as a parameter in the FUNCTION widget by inserting "amount" as the KEY and {{widgets.gather_1.digits}} as the VALUE of the parameter.
I wrote the following function:
exports.handler = function(context, event, callback) {
const rawamount = event.amount;
const decimalamount = rawamount.replace("*",".");
const response = decimalamount;
callback(null, response);
};
then in the <pay> widget I inserted {{widget.function_1.body}} in the AMOUNT field.
Your payment should process with dollars and cents.
Let me know if this worked. If you need screenshots of my studio flow let me know.
ADDED:
Here is a sample flow if someone wants to use as a template (someone requested it)
Open a blank Studio flow.
In the trigger widget under "config" tab click on "SHOW FLOW JSON" delete all previous code and paste code below inside and save.
Your flow should generate.
Then create function. Code and instructions below after JSON.
PLEASE NOTE: though a function may pop up in the flow, you won't be able to access it, and will have to create it under your account.
{
"description": "A New Flow",
"states": [
{
"name": "Trigger",
"type": "trigger",
"transitions": [
{
"event": "incomingMessage"
},
{
"next": "gather_1",
"event": "incomingCall"
},
{
"event": "incomingRequest"
}
],
"properties": {
"offset": {
"x": 0,
"y": 0
}
}
},
{
"name": "gather_1",
"type": "gather-input-on-call",
"transitions": [
{
"next": "function_1",
"event": "keypress"
},
{
"event": "speech"
},
{
"event": "timeout"
}
],
"properties": {
"voice": "man",
"speech_timeout": "auto",
"offset": {
"x": 30,
"y": 270
},
"loop": 1,
"finish_on_key": "#",
"say": "Please enter an amount, then press pound. To enter with cents use the star key. for example to enter $6.25 press six star two five.",
"language": "en-US",
"stop_gather": true,
"gather_language": "en",
"profanity_filter": "true",
"timeout": 5
}
},
{
"name": "function_1",
"type": "run-function",
"transitions": [
{
"next": "say_play_2",
"event": "success"
},
{
"event": "fail"
}
],
"properties": {
"offset": {
"x": -60,
"y": 530
},
"parameters": [
{
"value": "{{widgets.gather_1.Digits}}",
"key": "amount"
}
],
"url": "https://charcoal-sloth-2579.twil.io/insert-decimal"
}
},
{
"name": "say_play_2",
"type": "say-play",
"transitions": [
{
"next": "pay_1",
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": -59,
"y": 839
},
"loop": 1,
"say": "You entered ${{widgets.function_1.body}}",
"language": "en-US"
}
},
{
"name": "pay_1",
"type": "capture-payments",
"transitions": [
{
"next": "say_play_3",
"event": "success"
},
{
"next": "say_play_4",
"event": "maxFailedAttempts"
},
{
"next": "say_play_4",
"event": "providerError"
},
{
"next": "say_play_4",
"event": "payInterrupted"
},
{
"next": "say_play_4",
"event": "hangup"
},
{
"next": "say_play_4",
"event": "validationError"
}
],
"properties": {
"security_code": true,
"offset": {
"x": -70,
"y": 1140
},
"max_attempts": 2,
"payment_connector": "Stripe_Connector",
"payment_amount": "{{widgets.function_1.body}}",
"currency": "usd",
"language": "en-US",
"postal_code": "false",
"payment_token_type": "one-time",
"timeout": 5,
"valid_card_types": [
"visa",
"master-card",
"amex",
"discover"
]
}
},
{
"name": "say_play_3",
"type": "say-play",
"transitions": [
{
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": -185,
"y": 1433
},
"loop": 1,
"say": "Your payment ${{widgets.function_1.body}}was successful, Thank you.",
"language": "en-US"
}
},
{
"name": "say_play_4",
"type": "say-play",
"transitions": [
{
"event": "audioComplete"
}
],
"properties": {
"voice": "man",
"offset": {
"x": 190,
"y": 1456
},
"loop": 1,
"say": "There was an error with your payment. Goodbye!",
"language": "en-US"
}
}
],
"initial_state": "Trigger",
"flags": {
"allow_concurrent_calls": true
}
}
Create a function with this code:
exports.handler = function(context, event, callback) {
const amount = event.amount;
const convert = amount.replace('*', '.');
callback(null, convert);
};
Make sure in the flow you check that the function widget has the right function selected and that you insert the following parameter KEY:amount VALUE: {{widgets.YOUR_GATHER_WIDGET NAME.body}}

How to Insert Options with Ajax while Having Option Group in select2?

I have a multiselect dropdown with below data:
var fruitArray = [];
var fruitGreen = [];
var fruitNotGreen = [];
fruitGreen = {
"text": "Green",
"children": [
{ "id": "Watermelon", "text": "Watermelon" },
{ "id": "Lime", "text": "Lime" },
{ "id": "Guava", "text": "Guava" },
{ "id": "Avocado", "text": "Avocado" },
{ "id": "Kiwi", "text": "Kiwi" },
]};
fruitNotGreen = {
"text": "Not Green",
"children": [
{ "id": "Apple", "text": "Apple" },
{ "id": "Orange", "text": "Orange" },
{ "id": "Berries", "text": "Berries" },
{ "id": "Grape", "text": "Grape" },
{ "id": "Pineapple", "text": "Pineapple" },
]};
fruitArray.push(fruitGreen, fruitNotGreen);
$(".select2").select2({
placeholder: "-- Select Fruits --",
allowClear: true,
maximumSelectionLength: 50,
dropdownAutoWidth: true,
data: fruitArray,
multiple: true,
closeOnSelect: false
});
How to Insert Options with Ajax while Having Option Group? Please help
I'm using select2 multiple dropdown from https://select2.org

"Invalid JSON payload received." when creating a new sheet

I'm just starting out with the Sheets API, and I'm following this setup to create a new sheet: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create
In this code, the spreadsheetBody object is empty. For this I've used the example on this page: https://developers.google.com/sheets/api/samples/writing and added this code to the spreadsheetBody variable:
{
"range": "Sheet1!A1:D5",
"majorDimension": "ROWS",
"values": [
["Item", "Cost", "Stocked", "Ship Date"],
["Wheel", "$20.50", "4", "3/1/2016"],
["Door", "$15", "2", "3/15/2016"],
["Engine", "$100", "1", "30/20/2016"],
["Totals", "=SUM(B2:B4)", "=SUM(C2:C4)", "=MAX(D2:D4)"]
],
}
However, when I post this I get the error "Invalid JSON payload received. Unknown name "range" at 'spreadsheet': Cannot find field.". What might be wrong here?
The request body you are using is for spreadsheets.values.update.
As a sample, the request body for creating Spreadsheet is as follows. In this sample request body, ["Item", "Cost", "Stocked", "Ship Date"], ["Wheel", "$20.50", "4", "3/1/2016"] was used from the document you use.
Sample request body:
{
"properties":
{
"title": "sampleSpreadsheet"
},
"sheets":
[
{
"data":
[
{
"startRow": 0,
"startColumn": 0,
"rowData":
[
{
"values":
[
{
"userEnteredValue":
{
"stringValue": "Item"
}
},
{
"userEnteredValue":
{
"stringValue": "Cost"
}
},
{
"userEnteredValue":
{
"stringValue": "Stocked"
}
},
{
"userEnteredValue":
{
"stringValue": "Ship Date"
}
}
]
},
{
"values":
[
{
"userEnteredValue":
{
"stringValue": "Wheel"
}
},
{
"userEnteredValue":
{
"numberValue": 20.5
},
"userEnteredFormat":
{
"numberFormat":
{
"type": "NUMBER",
"pattern": "$##.00"
}
}
},
{
"userEnteredValue":
{
"numberValue": 4
}
},
{
"userEnteredValue":
{
"numberValue": 42372
},
"userEnteredFormat":
{
"numberFormat":
{
"type": "DATE",
"pattern": "d/m/yyyy"
}
}
}
]
}
]
}
]
}
]
}
Note:
When this request body is used for spreadsheets.create, a Spreadsheet with the filename of sampleSpreadsheet is created. The sheet has the values of ["Item", "Cost", "Stocked", "Ship Date"], ["Wheel", "$20.50", "4", "3/1/2016"] at "A1:D2".
References:
spreadsheets.create- spreadsheets.batchUpdate

Highcharts export module giving error

I am trying to get image from Highchart export module, and it is giving image with
chart input data error, syntax error : Unexpected EOF.
Please see code in this js fiddle.
http://jsfiddle.net/GopinathGD/3xy8aeb7/
$(function () {
$("#b").click(testPOST);
var exportUrl = 'http://export.highcharts.com/';
function testPOST() {
var dataStr= {
"colors": [
"#C00000"
],
"chart": {
"type": "bar"
},
"title": {
"text": "Current Analysis Competitive Index",
"style": {
"fontWeight": "bold",
"color": "rgba(164, 0, 31, 0.96)"
}
},
"subtitle": {
"text": "Source: © 2017 Current Analysis, Inc."
},
"xAxis": {
"tickWidth": 1,
"minPadding": 0,
"maxPadding": 0,
"categories": [
"Overall",
"Vision/Strategy",
"Momentum & Stability",
"Innovation",
"Product Portfolio",
"Go-to-Market",
"Service & Support"
],
"title": {
"text": null
},
"labels": {
"style": {
"color": "#000000",
"fontWeight": "bold",
"fontSize": "12px"
}
}
},
"yAxis": {
"min": 0,
"max": 10,
"tickInterval": 1,
"tickmarkPlacement": "off",
"categories": [
"",
"Vulnerable",
"",
"Competitive",
"",
"Strong",
"",
"Very Strong",
"",
"Leader",
""
],
"title": {
"text": "",
"align": "high"
},
"labels": {
"style": {
"color": "#000000",
"fontWeight": "bold",
"fontSize": "12px"
}
}
},
"plotOptions": {
"bar": {
"dataLabels": {
"enabled": false
},
"pointpadding": 0,
"groupPadding": 0
},
"series": {
"animation": false,
"pointWidth": 9,
"pointPadding": 0,
"groupPadding": 0.1
}
},
"legend": {
"margin": 30
},
"series": [
{
"name": "BlackBerry - Consumer Platforms and Devices",
"data": [
3,
3,
3,
3,
2,
6,
6
]
}
]
};
var optionsStr = JSON.stringify(dataStr),
dataString = encodeURI('async=true&options='+optionsStr+'&type=jpeg&width=400');
if (window.XDomainRequest) {
var xdr = new XDomainRequest();
xdr.open("post", exportUrl+ '?' + dataString);
xdr.onload = function () {
console.log(xdr.responseText);
$('#container').html('<img src="' + exporturl + xdr.responseText + '"/>');
};
xdr.send();
} else {
$.ajax({
type: 'POST',
data: dataString,
url: exportUrl,
success: function (data) {
console.log('get the file from relative url: ', data);
$('#container').html('<img src="' + exportUrl + data + '"/>');
},
error: function (err) {
debugger;
console.log('error', err.statusText)
}
});
}
}
});
<script src="http://code.highcharts.com/highcharts.js"></script>
Run Code
The reason is two ampersands used in the xAxis.categories.
"categories": [
"Momentum & Stability",
...
"Service & Support"
],
Change ampersands to %26
"categories": [
"Overall",
"Vision/Strategy",
"Momentum %26 Stability",
"Innovation",
"Product Portfolio",
"Go-to-Market",
"Service %26 Support"
],
create a callback which encodes ampersands (callback is called on the server):
function callback () {
const categories = this.xAxis[0].categories.map(decodeURIComponent)
this.xAxis[0].setCategories(categories)
}
Append the callback to dataString:
dataString = encodeURI('async=true&options='+optionsStr+'&type=jpeg&width=400&callback=' + callback.toString());
example: http://jsfiddle.net/erayy8jn/

angular-ui-grid load state on controller creation

I want to load the last state of a ui-grid when the controller is created.
I've set up a plunkr. http://plnkr.co/edit/cOhLUUABVStfoTH6QVZd?p=preview
In my controller I use a restoreOnLoad function which is called immediately at the end of the controller. I get a TypeError: Cannot read property 'saveState' of undefined because the gridApi is undefined at the time of controller creation.
restoreOnLoad = function(){
//retrieve stateinfo. For simplicity: inline object...
var stateInfo = {
"columns": [
{
"name": "",
"visible": true,
"width": 50,
"sort": {
"direction": "asc",
"priority": 0
},
"filters": [
]
},
{
"name": "M",
"visible": true,
"width": 50,
"sort": {
},
"filters": [
]
},
{
"name": "Company",
"visible": true,
"width": 200,
"sort": {
},
"filters": [
]
}
],
"scrollFocus": {
},
"selection": {
}
}
$scope.gridApi.saveState.restore($scope, stateInfo);
}
restoreOnLoad();
Any ideas how to avoid this error?
Your restore call is running before the grid's API is registered, so you just need to wait for that to happen.
You can move your restoreOnLoad() call to your onRegisterApi handler:
vm.gridOptions = {
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
restoreOnLoad();
}
}

Resources