Draw Google Chart after clicking submit button in a form - forms

I'm having problem loading a google chart after clicking the submit button in a form. I came across many similar questions posted online but none solve my question, including this.
The structure of my code: I wrap the google chart code inside a submitHandler: function(form) , then wrap the whole submitHandler with a $("#timeuseform").validate({}), then the most outside is a $(document).ready(function(){}) .
When I remove the google chart code, everything worked fine. When I copy and paste the google chart code into submitHandler: function(form) , the whole page broke down.
here the HTML:
<head>
<meta charset="utf-8">
<title>Time Use Survey 2014</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.12.0/jquery.validate.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>Do you sleep, work and play more than fellow Americans?</h1>
<br>
<hr width="100%" size="3" noshade="noshade" color="#8A8A8A"/>
<br>
<form name="myForm" id="timeuseform" method="get" action="#">
1. On average, how much you sleep per day?<br>
<input type="text" name="sleep" value="" id="inputsleep"/><br><br>
<div id="sleepbox"></div><br><br>
2. On average, how much time you work on your workday (excludes travel related to work)?<br>
<input type="text" name="work" value="" id="inputwork"/><br> and you are working
<SELECT NAME="workstatus" SIZE="1" id="inputworkstatus">
<OPTION>full-time
<OPTION>part-time
</SELECT><br><br>
<div id="workbox"></div><br><br>
<input type="submit" value="Submit" id="button"/>
<INPUT TYPE="reset">
</form>
<br><br>
<div id="chart_div" style="width: 500px; height: 300px;"></div>
<script type="text/javascript" src="chart.js"></script>
</body>
</html>
and this is the JS:
$(document).ready(function(){
//form validation using jquery validation plugin
$("#timeuseform").validate({
rules: {
sleep: {
required: true,
number: true
},
work: {
required: true,
number: true
},
},
//messages to be displayed if input cannot be validated
messages: {
sleep: {
required: "Please answer this question",
number: "Your answer must be a number with maximum 1 decimal point"
},
work: {
required: "Please answer this question",
number: "Your answer must be a number with maximum 1 decimal point"
},
},
//display error messages style if input cannot be validated
errorPlacement: function(label, element) {
label.insertAfter(element);
},
wrapper: 'span',
submitHandler: function(form) {
//setting the input variables
var inputsleep = $('#inputsleep').val(),
inputwork = $('#inputwork').val();
//code for question 1 on sleep
if(inputsleep>8){
$("#sleepbox").text("You sleep too much!");
$("#sleepbox").addClass("more");
}
else{
$("#sleepbox").text("You sleep too little!");
$("#sleepbox").addClass("less");
}
//code for question 2 on work
if(inputwork>6){
$("#workbox").text("You work too much!");
$("#workbox").addClass("more");
}
else{
$("#workbox").text("You work too little!");
$("#workbox").addClass("less");
}
//code for google bar chart starts here
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data1 = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses'],
['2004', 1000, 400],
['2005', 1170, 460],
['2006', 660, 1120],
['2007', 1030, 540]
]);
var options = {
title: 'Company Performance',
vAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data1, options);
}
}
});
});
I have uploaded both working (without google chart code) and broken (with google chart code) in my github.
Working without google chart: http://kuangkeng.github.io/keng-data-journalism/timeuseform/nochart.html
Broken with google chart: http://kuangkeng.github.io/keng-data-journalism/timeuseform/chart.html
Appreciate if anyone can guide me to fix this problem. Thanks.

Move the google.load and google.setOnLoadCallback calls outside your jQuery code. Use the callback to initialize your validator instead of using document ready:
function init () {
$("#timeuseform").validate({
// validator stuff
});
}
google.load("visualization", "1", {packages:["corechart"], callback: init});

Related

How to fix overlapping Google Chart legend

This has been something I've been working on for hours now and I can't seem to find a solution that works. I have a page (ASP.NET Core) that has bootstrap tabs on it. Each tab displays a different chart. I've read various answers and tried so many different things from this and other sites but I'm sure what I'm doing wrong.
This is a proof of concept page I'm making and from what I understand I need to stall the loading of the chart until the nav-tab is selected. That is what I am unsure of how to do.
My View:
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
#Html.Partial("~/Views/Shared/Chart_ByMonth.cshtml")
#Html.Partial("~/Views/Shared/Chart_ByMonthAndQuarter.cshtml")
#Html.Partial("~/Views/Shared/Chart_ByLeaseAdmin.cshtml")
#Html.Partial("~/Views/Shared/Chart_Fourth.cshtml")
<script type="text/javascript">
// Load the Visualization API and the corechart package.
google.charts.load('current', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawMonthChart);
google.charts.setOnLoadCallback(drawMonthAndQuarterChart);
google.charts.setOnLoadCallback(drawLeaseAdminChart);
google.charts.setOnLoadCallback(drawFourthChart);
</script>
<body>
<ul class="nav nav-tabs" id="tabs">
<li class="active" id="tab_1"><a data-toggle="tab" href="#home">By Month</a></li>
<li id="tab_2"><a data-toggle="tab" href="#menu1">By Month & Quarter</a></li>
<li id="tab_3"><a data-toggle="tab" href="#menu2">By Lease Admin</a></li>
<li id="tab_4"><a data-toggle="tab" href="#menu3">Fourth Chart</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade in active">
<h3>By Month</h3>
<select>
<option selected>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
<select>
<option>2016</option>
<option>2017</option>
</select>
<button type="submit" class="btn btn-success">Submit</button>
<div id="chart_month_div" style="padding-top: 20px;"></div>
</div>
.....
</div>
</body>
The partial view for that chart is just hard-coded data, again a proof of concept page:
<script type="text/javascript">
function drawMonthAndQuarterChart() {
// Create the data table.
var data = google.visualization.arrayToDataTable([
['Type', 'Cash', 'Credit', { role: 'annotation' }],
['January', 10, 24, ''],
['February', 16, 22, ''],
['March', 28, 19, '']
]);
// Set chart options
var options = {
width: 1200,
height: 400,
legend: { position: 'top', maxLines: 3 },
bar: { groupWidth: '75%' },
isStacked: true,
hAxis: {
minValue: 0,
title: 'Approvals for the month & quarter'
}
};
// Instantiate and draw our chart, passing in some options.
var chartMonthandquarter = new google.visualization.BarChart(document.getElementById('chart_monthandquarter_div'));
chartMonthandquarter.draw(data, options);
}
The charts all load fine when tabs are selected. The legend is overlapped with itself on all but the initially shown chart. I've tried defaulting the chart divs to be hidden and having an onclick event for each tab that overrides the styling, I've tried doing events where a tab is active, nothing seems to work and I've just been banging my head against the wall.
I suspect it has something to do with the fact that I'm calling
google.charts.setOnLoadCallback(drawMonthAndQuarterChart);
google.charts.setOnLoadCallback(drawLeaseAdminChart);
google.charts.setOnLoadCallback(drawFourthChart);
and since the charts are already drawn right on page creation, there's no way to redraw them. What I am not sure how to do is successfully get the charts to draw only when a new tab is active or something similar.
as you've gathered,
the problem is a result of drawing the chart while the tab is hidden
need to wait until the tab is shown before drawing for the first time
as such, only draw the first chart using the callback...
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawMonthChart);
once the callback fires, you don't have to call it again,
you can draw as many charts as needed afterwards
then wait for the tabs to be clicked before drawing the next chart...
here, a switch statement is used on the href attribute,
to determine which tab was clicked,
then draw its chart...
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
switch ($(e.target).attr('href')) {
case '#home':
drawMonthChart();
break;
case '#menu1':
drawMonthAndQuarterChart();
break;
case '#menu2':
drawLeaseAdminChart();
break;
case '#menu3':
drawFourthChart();
break;
}
});

Vue.js/Vuetify - Autocomplete issue when pre-loading option in a v-select

I'm setting the selected option of a v-select using v-model, so when I open the screen it already comes with the result. That's working fine until I set autocomplete property in v-select tag. When I do that the option is chosen but the select doesn't show it.
Is there any issue with the autocomplete feature or it's the standard behavior for the component?
Vue.use(Vuetify);
var app = new Vue({
el: '#app',
data() {
return {
selected: 2,
country: [{
text: 'USA',
value: 1
}, {
text: 'Canada',
value: 2
}, {
text: 'England',
value: 3
}, {
text: 'France',
value: 4
}]
}
}
})
<script src="https://unpkg.com/vue#2.4.1/dist/vue.js"></script>
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet" />
<script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
<div id="app">
<v-app>
<v-card class="grey lighten-4 elevation-0">
<v-card-text>
<v-container fluid>
<v-layout row wrap>
<v-flex xs4>
<v-flex>
<v-subheader>Origin Country</v-subheader>
</v-flex>
<v-flex>
<v-select
:items="country"
v-model="selected"
label="Select"
class="input-group--focused"
single-line
bottom
autocomplete>
</v-select>
</v-flex>
</v-flex>
<v-flex>
Selected: {{ selected }}
</v-flex>
</v-layout>
</v-container>
</v-card-text>
</v-card>
</v-app>
</div>
Here it is jsfiddle link: https://jsfiddle.net/vcmiranda/huj9L4bq/
Thanks.
I test your code, vuetify will inject its classes after yours, after delete this line in v-select, it works.
class="input-group--focused"
Alternatively, using 'id' instead of 'class' is another option.

google column chart make it responisve

Good day, I have a google column chart and work perfectly but when I re size my browser the column chart overflowed and wont re size. my website is responsive and I dont want to put my bar chart like that. how to get my column chart responsive?
I got this column chart from developers.google.com/chart/interactive/docs/gallery/columnchart
here is the code
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title><?php echo $title;?></title>
<!-- Load Google chart api -->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
},
bars: 'vertical',
vAxis: {format: 'decimal'},
height: 400,
colors: ['#1b9e77', '#d95f02', '#7570b3']
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
var btns = document.getElementById('btn-group');
btns.onclick = function (e) {
if (e.target.tagName === 'BUTTON') {
options.vAxis.format = e.target.id === 'none' ? '' : e.target.id;
chart.draw(data, google.charts.Bar.convertOptions(options));
}
}
}
</script>
</head>
<body>
<div id="chart_div" style="width:100%;"></div>
<br/>
<div id="btn-group">
<button class="button button-blue" id="none">No Format</button>
<button class="button button-blue" id="scientific">Scientific Notation</button>
<button class="button button-blue" id="decimal">Decimal</button>
<button class="button button-blue" id="short">Short</button>
</div>
</body>
</html>
I tried also to add width="100%" from div but its doesn't work at all.
Currently, the problem with Google Charts is that it doesn't have a responsive feature.
From previous explorations over the web, the best solution that I found and implemented was:
$(window).resize(function () {
drawChart();
});
This piece of code calls the drawChart() function each time the browser window is resized. Therefore, this means that the Chart is redrawn each time. This may not be the best or efficient solution, but for me it did the job.
In order to allow the .resize() function, you will require the jQuery Library. More information for this is available here.

Alfresco - Categories Picker

I want to use the JavaScript Alfresco.ObjectPicker component in order to have category picker into the file: dnd-upload.get.html.ftl
<div class="form-field inlineable">
<label >Catégories:</label>
<div class="object-finder inlineable" id="a_default_prop_cm_categories-cntrl">
<div class="current-values inlineable object-finder-items" id="b_default_prop_cm_categories-cntrl-currentValueDisplay"></div>
<input type="hidden" value="" name="prop_cm_categories" id="c_default_prop_cm_categories"/>
<div class="show-picker inlineable" id="d_default_prop_cm_categories-cntrl-itemGroupActions"><span class="yui-button yui-push-button" id="yui-gen7"><span class="first-child"><button type="button" tabindex="0" id="yui-gen7-button" >Sélectionner</button></span></span></div>
<script type="text/javascript"> //<![CDATA[
(function(){
var picker = new Alfresco.ObjectFinder("a_default_prop_cm_categories-cntrl", "c_default_prop_cm_categories").setOptions(
{
field: "prop_cm_categories",
compactMode: true,
mandatory: false,
currentValue: "",
selectActionLabel: "Sélectionner",
minSearchTermLength: 1,
maxSearchResults: 1000
}).setMessages(
{""}
);
picker.setOptions(
{
itemType: "cm:category",
multipleSelectMode: true,
parentNodeRef: "alfresco://category/root",
itemFamily: "category",
maintainAddedRemovedItems: false,
params: "",
createNewItemUri: "",
createNewItemIcon: ""
});
})();
//]]>
</script>
</div>
</div>
And I have declared a JS dependency in the same file: dnd-upload.get.html.ftl
<#script type="text/javascript" src="${url.context}/res/components/object-finder/object-finder.js" group="objectfinder"/>
When I click on the button : "Sélectionner" , nothing happens and I have no console error neither.
Do you , Please, have any idea about how to make this Picker Working ?
Regards,
Sofia.

MVC2 Client side validation within Jquery modal dialog

Using MVC2 I currently have a view creating a jquery dialog box containing an Edit partial view. On submit I am looking for it to perform client side validation on the Email class which has a required data annotation attribute for email address. Server side validation works fine but I want the user to have to fix the error in the modal dialog.
Below is the code
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm())
<div>
<label for="EmailAddress">
Email Address :
</label>
<%= Html.TextBoxFor(model => model.Email.EmailAddress)%>
<%= Html.ValidationMessageFor(model => model.Email.EmailAddress)%>
</div>
Scripts I am loading up are
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery-1.3.2.min.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jqueryUI/js/jquery-ui-1.7.2.custom.min.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/Splitter/splitter-1.5.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/Scripts/Start.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/Scripts/extended/ExtendedControls.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/jquery.validate.js")%>"></script>
<script type="text/javascript" src="<%= ResolveUrl("~/Scripts/MicrosoftMvcJQueryValidation.js")%>"></script>
Looking at the html generated I am not getting any of the JSON data generated for the client side validation to work.
Any solutions gladly appreciated. S
I strongly recommend you to use jquery validation script.
jquery.validate.js has all the features for client-side validation within a jquery dialog.
First of all, add the jquery.validate.js to your Site.Master :
<script src="/Scripts/Using/jquery.validate.js" type="text/javascript"></script>
and then write your script something like that :
<script type="text/javascript">
var createLinkObj;
$(function () {
$('#mydialog').dialog({
autoOpen: false,
width: 500,
modal: true,
buttons: {
"OK": function () {
$("#myForm").validate({
rules: {
Name: {
required: true
},
Email: {
required: true,
email: true
}
},
messages: {
Name: " * ",
Email: {
required: " * ",
email: " Invalid e-mail."
}
});
$("#myForm").submit();
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
$(".mylink").click(function () {
//change the title of the dialog
createLinkObj = $(this);
var dialogDiv = $('#mydialog');
var viewUrl = createLinkObj.attr('href');
$.get(viewUrl, function (data) {
dialogDiv.html(data);
dialogDiv.dialog('open');
});
return false;
});
});
</script>
As you can see when I click the mylink, mydialog appears and before submitting the myForm, I validated the myForm elements namely Name and Email.
Think that your form only contains Name and Email and then you can validate these elments by using jquery validate script.