How to add event sources - ruby

In my fullcalendar page, I have a (default) event sources area that looks like such:
eventSources: [{
url: '/events/index/',
color: 'yellow',
textColor: 'black',
ignoreTimezone: false
}],
I have a model (and view) folder titled "rentalcars". How would I make the events automatically be pulled from that model? This model has start and end dates.
I tried:
eventSources: [{
url: '/rentalcars/index/',
color: 'yellow',
textColor: 'black',
ignoreTimezone: false
}],
which certainly does not work. I looked at arshaw's source, and I can tell how to make static events, but I am looking for dynamic ones: ones that will iterate through existing models.
Any suggestions?

Your url parameter needs to return whatever the FullCalendar understands and can parse, so judging by the documentation you will have to make sure that your rentelcars index action returns this particular format:
{
title : 'event1',
start : '2010-01-01'
},
{
title : 'event2',
start : '2010-01-05',
end : '2010-01-07'
},
{
title : 'event3',
start : '2010-01-09 12:30:00',
allDay : false // will make the time show
}
}
So in your rentalcars_controller.rb in the index definition you will have to make sure that you return this format which looks a lot like JSON to me. So, easiest way would be to have this as your JavaScript:
eventSources: [{
url: '/rentalcars.json',
color: 'yellow',
textColor: 'black',
ignoreTimezone: false
}],
And then in your controller you will have something like this:
def index
rentalcar_dates = RentelcarDates.all # assuming this is an object that holds start, end date and maybe the car name
respond_to do |format|
format.html
format.json { render :json => rentalcar_dates }
end
end

Related

Chartkick w/ Highcharts column_chart, specify visibility by series

On Highcharts it is possible to hide by default some selected series :
new Highcharts.Chart({
"chart": {"type":"column","renderTo":"chart-1"},
"categories":["10-2017","11-2017"],
"series": [
{"name":"Metric 1","data":[653.13,683.13]},
{"name":"Metric 2","data":[6.87,6.87], "visible": false}
]})
However, I'm using Chartkick Ruby gem, and I cannot generate the code above.
<%= column_chart([
{ name:"Metric 1", data: { "10-2017" => 653.13, "11-2017" => 683.13 } },
{ name:"Metric 2", data: { "10-2017" => 6.87, "11-2017" => 6.87 }, visible: false }
]) %>
With this erb code snippet, the visible: false option is ignored.
Is there a way (maybe using the library parameter) to acheive this goal?
I agree, it is probably a bug or an unimplemented issue with ChartKick.
I fixed it by manually running this JS code after initialization of column_chart:
var chart = Chartkick.charts["chart-1"].getChartObject();
chart.series[1].setVisible(false);
Verify if chart-1 is the correct ID of your chart.

jqgrid reading form element value and dynamically changing select option

I like to change the Type field drop down option depending on the inputs of Year and Level fields.
I am able to trigger an event when Level is change.
But how do I get the value of the Year field?
Portion of the code are as follows
colModel:[
{name:'Year',index:'Year', width:70,sortable:false,editable:true,align:'center',editoptions:{size:15, maxlength:4}, formoptions:{ rowpos:1, label: "Year (*)"},editrules:{required:true}},
{name:'Level',index:'Level', width:70,sortable:false,editable:true,align:'center',edittype: "select", editoptions: { value: '1:1;2:2;3:3;4:4;5:5;6:6', defaultValue:'1', dataEvents : [
{
'type' : 'change',
'fn' : function ( el ) {
// get the newly selected value from the user
var levelz = $(el.target).val(), yearz ;
var row = $(el.target).closest('tr.jqgrow');
var rowid = row.attr('id');
//yearz = ??
if (parseInt(levelz)==5 || parseInt(levelz)==6)
{
if (parseInt(yearz)>2017)
{
$("#gridmain").jqGrid('setColProp','Term', {editoptions: { value: '1:Sem 1;4:Sem 2;6:EY;9:OVR', defaultValue:'Sem 1'}} );
}else{
$("#gridmain").jqGrid('setColProp','Term', {editoptions: { value: '', defaultValue:''}} );
}
}else{
$("#gridmain").jqGrid('setColProp','Term', {editoptions: { value: '1:TA1/CT1;2:TA2-before 2013;3:MY/TA2/CT2;4:TA3/CT3;5:TA4-before 2013;6:EY/TA4/CT4;9:OVR;D:CW1;E:CW2;F:CW3;G:CW4', defaultValue:'TA1'}} );
}
}
}]}, formoptions:{ rowpos:2, label: "Level (*)"},editrules:{required:true}},
{name:'Term',index:'Term', width:70, sortable:false,editable: true,align:'center',edittype: "select", editoptions: { value: '1:TA1/CT1;2:TA2-before 2013;3:MY/TA2/CT2;4:TA3/CT3;5:TA4-before 2013;6:EY/TA4/CT4;9:OVR;D:CW1;E:CW2;F:CW3;G:CW4', defaultValue:'TA1'}, editrules: { required: true }, formoptions:{ rowpos:3, label: "Type"}},
The codes are from piecing together what I read from google search...
I face 2 issues:
1) I don't know how to get the Year value
2) The drop down option list doesn't seems to change. - hmm it seems that if I close the edit form and open again, the Type field drop down option changes. What I need is to change the option on the fly - wonder how this can be done...
After much googling, managed to get the ans from Oleg's post as shown here
Also from his example, I derive the year value:
var yearz = $("#Year.FormElement", form[0]).val();

AmChart not appearing in md-dialog

I have an AmChart that I want to appear in an md-dialog. It's passed a JSON dataProvider and yet nothing appears.
dialog.tmpl.html:
<md-dialog aria-label="Project Zone Chart">
<md-toolbar>
<div class="md-toolbar-tools">
<h2>Project Zone Chart</h2>
<span flex></span>
<md-button class="md-icon-button" ng-click="closeDialog()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<p><div id="projZoneChart" style="width: 100%; height: auto;"></div></p>
</md-dialog-content>
</md-dialog>
controller.js:
var projZoneChartOps = {
type: "serial",
valueAxes: [{
minorGridAlpha: 0.08,
minorGridEnabled: true,
position: "top",
gridAlpha: 0,
precision: 0
}],
startDuration: 1,
graphs: [{
type: "column",
fillAlphas: 1,
lineAlpha: 0,
valueField: "value",
colorField: "color",
lineAlpha: 0
}],
rotate: true,
categoryField: "metric",
categoryAxis: {
gridPosition: "start",
parseDates: false,
gridAlpha: 0
}
};
createChart($scope.chartdata, projZoneChartOps);
function createChart(chartData, chartOps){
$scope.projZoneChart = AmCharts.makeChart("projZoneChart", chartOps);
$scope.projZoneChart.dataProvider = chartData;
However nothing appears in the dialog at all. Is there a problem with my chartOps?
Note: the chartData variable is a JSON object with two fields, startOfWeek (supposed to be the x-axis) and metric (supposed to be the y-axis)
There are a few issues/comments:
1) Why aren't you assigning the data to the chartOps object before calling makeChart?
chartOps.dataProvider = chartData;
$scope.projZoneChart = AmCharts.makeChart("projZoneChart", chartOps);
This will actually make the chart start off with your data. The way you're doing it will require that you call validateData() on your chart object after manually setting the dataProvider, which is unnecessary overhead compared to including it directly in makeChart.
$scope.projZoneChart = AmCharts.makeChart("projZoneChart", chartOps);
$scope.projZoneChart.dataProvider = chartData;
$scope.projZoneChart.validateData(); //required if you're doing it this way but unneccessary overhead compared to simply including it inside of makeChart directly as you're essentially remaking the chart after you create it for the sake of rendering your data.
2) Make sure your *field properties match. startOfWeek isn't mentioned in your chart config at all, even though you're saying it's in your JSON data. Your valueField is set to "value" - you might want to set it to "startOfWeek" instead unless you're modifying your JSON object somewhere else.
3) Displaying charts inside a modal or other dynamic/hidden elements typically require that you call the chart object's invalidateSize method when the modal/tab/etc containing the chart is visible so that it will render correctly. You'll want to check for whatever event md-dialog offers to determine when it is visible before calling $scope.projZoneChart.invalidateSize().

KendoUI - Chart data labels

Is is possible to for the KendoUI Chart (Area) to have multiple data labels or even a concatenation of two? I need to display both a value and a percentage for each data point. Is this something that would need to be handled on the data source side or is it on the view?
Thanks for any help.
You can use templates to format both labels and tooltips; see labels.template and tooltip.template.
The key is to reference the Property you want using dataItem ex:
dataItem.TotalDollars
template: "${ category } - #= kendo.format('{0:C}', dataItem.TotalDollars)#"
The answer above wont really help unless you have a strong understanding of the Kendo UI framework. I was having a similar issue and before I found my answer I found this question. I circled back because the answer is simple and some simple example code is really simple. Lets save everyone some clicks.
DATA RESPONSE FROM REMOTE DATA (copy and past for local binding):
[
{
"ProgramName":"Amarr Garage Doors",
"PercentageShare":50.12,
"TotalDollars":5440.000000
},
{
"ProgramName":"Monarch Egress Thermal Hinge C",
"PercentageShare":4.64,
"TotalDollars":504.000000
},
{
"ProgramName":"Monarch Egress Window Wells",
"PercentageShare":15.73,
"TotalDollars":1707.000000
},
{
"ProgramName":"Monarch Premier V Egress Windo",
"PercentageShare":16.25,
"TotalDollars":1764.000000
},
{
"ProgramName":"Organized Living Shelftech Ven",
"PercentageShare":13.27,
"TotalDollars":1440.000000
}
]
**Chart Generation Code: **
function createChart() {
$("#SubmissionSummaryByProgramChart").kendoChart({
title: {
text: "Breakdown by Program"
},
legend: {
position: "right"
},
dataSource: {
transport: {
read: {
url: "GetFooData",
dataType: "json",
data: {
Year : 2014,
Quarter : 1,
}
}
}
},
series: [{
type: "pie",
field: "PercentageShare",
categoryField: "ProgramName"
}],
tooltip: {
visible: true,
template: "${ category } - #= kendo.format('{0:C}', dataItem.TotalDollars)#"
}
});
};
$(document).ready(createChart);

Translating JSON into custom dijit objects

I am looking for an example where JSON constructed from the server side is used to represent objects that are then translated into customized widgets in dojo. The JSON would have to be very specific in its structure, so it would not be a very general solution. Could someone point me to an example of this. It would essentially be the reverse of this
http://docs.dojocampus.org/dojo/formToJson
First of all let me point out that JSON produced by dojo.formToJson() is not enough to recreate the original widgets:
{"field1": "value1", "field2": "value2"}
field1 can be literally anything: a checkbox, a radio button, a select, a text area, a text box, or anything else. You have to be more specific what widgets to use to represent fields. And I am not even touching the whole UI presentation layer: placement, styling, and so on.
But it is possible to a certain degree.
If we want to use Dojo widgets (Dijits), we can leverage the fact that they all are created uniformly:
var myDijit = new dijit.form.DijitName(props, node);
In this line:
dijit.form.DijitName is a dijit's class.
props is a dijit-specific properties.
node is an anchor node where to place this dijit. It is optional, and you don't need to specify it, but at some point you have to insert your dijit manually.
So let's encode this information as a JSON string taking this dijit snippet as an example:
var myDijit = new dijit.form.DropDownSelect({
options: [
{ label: 'foo', value: 'foo', selected: true },
{ label: 'bar', value: 'bar' }
]
}, "myNode");
The corresponding JSON can be something like that:
{
type: "DropDownSelect",
props: {
options: [
{ label: 'foo', value: 'foo', selected: true },
{ label: 'bar', value: 'bar' }
]
},
node: "myNode"
}
And the code to parse it:
function createDijit(json){
if(!json.type){
throw new Error("type is missing!");
}
var cls = dojo.getObject(json.type, false, dijit.form);
if(!cls){
// we couldn't find the type in dijit.form
// dojox widget? custom widget? let's try the global scope
cls = dojo.getObject(json.type, false);
}
if(!cls){
throw new Error("cannot find your widget type!");
}
var myDijit = new cls(json.props, json.node);
return myDijit;
}
That's it. This snippet correctly handles the dot notation in types, and it is smart enough to check the global scope too, so you can use JSON like that for your custom dijits:
{
type: "my.form.Box",
props: {
label: "The answer is:",
value: 42
},
node: "answer"
}
You can treat DOM elements the same way by wrapping dojo.create() function, which unifies the creation of DOM elements:
var myWidget = dojo.create("input", {
type: "text",
value: "42"
}, "myNode", "replace");
Obviously you can specify any placement option, or no placement at all.
Now let's repeat the familiar procedure and create our JSON sample:
{
tag: "input",
props: {
type: "text",
value: 42
},
node: "myNode",
pos: "replace"
}
And the code to parse it is straightforward:
function createNode(json){
if(!json.tag){
throw new Error("tag is missing!");
}
var myNode = dojo.create(json.tag, json.props, json.node, json.pos);
return myNode;
}
You can even categorize JSON items dynamically:
function create(json){
if("tag" in json){
// this is a node definition
return createNode(json);
}
// otherwise it is a dijit definition
return createDijit(json);
}
You can represent your form as an array of JSON snippets we defined earlier and go over it creating your widgets:
function createForm(array){
dojo.forEach(array, create);
}
All functions are trivial and essentially one-liners — just how I like it ;-)
I hope it'll give you something to build on your own custom solution.

Resources