Utilizing jQuery Mobile to Load Google Charts

Hey everyone,

I've been working on a jQuery Mobile app and trying to integrate Google Charts into it. However, I'm facing an issue where the chart isn't displaying when I move the code to my main.js file. It works fine when it's all in the head section of the HTML.

Here is the basic structure of the HTML page I'm using:

<!DOCTYPE html>
<html>
<head>
    <title>Manufacturing Dashboard</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="./css/grey-orange.min.css" />
    <link rel="stylesheet" href="./css/jquery.mobile.custom.structure.min" />
    <link rel="stylesheet" href="./fonts/font-awesome/css/font-awesome.min.css"/>
    <script type="text/javascript" src="./js/jquery.min.js"></script>
    <script type="text/javascript" src="./js/jquery.mobile.custom.min.js"></script>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
        google.load("visualization", "1", {packages:["piechart", "corechart", "geomap"]});
    </script>
</head>
<body>
    <div data-role="page" data-theme="a" id="main-project-page">
        <div data-role="panel" class="project-menu" data-position="left" data-theme="c">
        </div><!-- /panel --> 
        <div data-role="header" data-position="fixed">
        </div><!-- /header -->
        <div data-role="content">
            <h3 id="project-name"></h3>
            <div id="project-overall-chart"></div>
        </div><!-- /content --> 
        <div data-role="footer" data-position="fixed">
        </div><!-- /footer --> 
    </div><!-- /page -->
    <script src="./js/main.js"></script>
</body>
</html>

Currently, I'm using a placeholder from Google's API Documentation as I call an API to fetch project information from a database. This is how I am approaching it...

//Global variables
var request;
var project_id = "null";
var equipment_id = "null";

//Main Project Page
$(document).on("pageinit", "#main-project-page", function() {

    //Menu Panel slide effect
    $('.menu-button').click(function(event) {
        $('.project-menu').panel("open");
    });

    //Populate project view with current project...
    populate_project_view();


});

function populate_project_view()
{
    //Check if there is a project to retrieve
    if (project_id != 'null')
    {
        //Construct the JSON
        var json = new Object();
        var info = new Object();

        json.type = "info";
        info.type = "project";
        info.id = project_id;
        json.info = info;

        json = JSON.stringify(json);

        //Make the request
        request = getHTTPObject();
        request.onreadystatechange = function () {
            //If request object received response
            if (request.readyState == 4)
            {
                var json = JSON.parse(request.responseText);
                if (json.error == true)
                {
                    alert('Error: ' + json.msg);
                    //Return to main screen
                    $.mobile.changePage('#main-page', 'slide', true, true);
                }
                else
                {
                    //Populate the #main-project-page DOM with project object
                    var project = json.project;

                    //Populate Project's name
                    var name = document.createTextNode(project.name);
                    $('#project-name').append(name);

                    // Set a callback to run when the Google Visualization API is loaded.
                    google.setOnLoadCallback(drawChart);

                    // Callback that creates and populates a data table,
                    // instantiates the pie chart, passes in the data and
                    // draws it.
                    function drawChart() {

                        // Create the data table.
                        var data = new google.visualization.DataTable();
                        data.addColumn('string', 'Topping');
                        data.addColumn('number', 'Slices');
                        data.addRows([
                          ['Mushrooms', 3],
                          ['Onions', 1],
                          ['Olives', 1],
                          ['Zucchini', 1],
                          ['Pepperoni', 2]
                        ]);

                        // Set chart options
                        var options = {'title':'How Much Pizza I Ate Last Night',
                                       'width':400,
                                       'height':300};

                        // Instantiate and draw our chart, passing in some options.
                        var chart = new google.visualization.PieChart(document.getElementById('project-overall-chart'));
                        chart.draw(data, options);
                    }
                }
            }
        }
        request.open("GET", "./php/api.php?package=" + json + '&qs=' + new Date().getTime(), true);
        request.send(null);
    }
}

/*
    Supporting functions 
*/

//Returns an HTTPObject
function getHTTPObject()
{
    var xhr = false;
    if (window.XMLHttpRequest)
    {
        xhr = new XMLHttpRequest();
    } 
    else if (window.ActiveXObject) 
    {
        try
        {
            xhr = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch(e)
        {
            try
            {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch(e)
            {
                xhr = false;
            }
        }
    }
    return xhr;
}

I'm still learning about JavaScript's AJAX operations and its behavior in browsers. Any help or insight into this issue would be greatly appreciated!

Cheers, Nathan

Answer №1

I finally cracked the code! Instead of relying on a callback to trigger once the API is loaded, I've realized that in my specific case, the API should always be ready by the time I need to use a chart. So, now I simply call the drawChart() function whenever necessary.

Revised

// Defining a callback for when the Google Visualization API loads.
google.setOnLoadCallback(drawChart);
function drawChart() {
    // Implementing the chart here...
}

This can be simplified to

*Main Function* {
    drawChart();
}

function drawChart() {
    // Implementing the chart here...
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Flip words that have over 4 characters

I need some assistance understanding why my function is consistently returning undefined. The desired output involves reversing each word in a string that has more than 4 characters. As a bit of a JavaScript beginner, this issue has been quite baffling f ...

Detecting button clicks in different views using Backbone.js

In my current setup, I have a main parent view called View.A which is responsible for managing two child views - View.B and View.C. Specifically, View.B contains buttons that trigger events on that view. Configuration View.A View.B view.B.template. ...

To display a pattern with a series of alternating addition and subtraction operators, starting from -1 and ending at n, use JavaScript to iterate through the numbers and implement the pattern -1+

I've been struggling to locate the values despite numerous attempts. What steps can I take to resolve this issue? Below is my code snippet: var numVal = prompt(""); for (var i = 1; i <= numVal; i++) { if (i % 2 !== 0) { console.log("-"); ...

Is there an easier method to assign text to a modal-body using a specific classname?

Utilizing Bootstrap 5.1.3 alongside Pure Vanilla JavaScript, I have successfully been able to populate the .modal-body with content using the following code: function showBSModal(modalid, inputid) { var myModal = new bootstrap.Modal(document.getElement ...

"Enhance your website with a unique Bootstrap 5 carousel featuring multiple

As a beginner in Bootstrap, I am currently working on an ecommerce template to learn about Bootstrap 5. I am interested in creating a carousel that displays multiple slides at once, like a products slider with left and right arrows. Is this possible in Bo ...

The <div> element is not displaying the JSON response when using Ajax

I have created a basic login form and I am attempting to validate it using an AJAX call. The validation process is successful, but the issue arises when the correct email or password is entered. Instead of displaying the JSON success or error message in a ...

Expanding Text Area in AngularJS

I came across this directive and I want to integrate it into my project, but I need the text area to expand as soon as the content is loaded. Angular-Autogrow.js: (function(){ 'use strict'; angular.module('angular-autogrow', [ ...

Display user profile pictures from Vue.js in the Laravel public directory

I have been working on implementing a commenting system and recently incorporated vue.js into my laravel project. One of the features I want to include in my comment area is displaying user profile images from the laravel public folder. However, I am u ...

Is there a way to postpone these animations without relying on setTimeout?

As I develop a single-page website, my goal is to smoothly transition between sections by first animating out the current content and then animating in the new content. Currently, I have achieved this using setTimeout(), where I animate out the current con ...

In Angular/Typescript, dynamically add a class to a `td` element when it is clicked. Toggle the class on and off

My problem arises when trying to individually control the arrow icons for each column in my COVID-19 data table. By using Angular methods, I aim to show ascending and descending arrows upon sorting but run into the challenge of changing arrows across all c ...

Exploring Amcharts using detailed JSON data

[{"SUM_PTS":{"datatype":"INTEGER","length":"8","value":"29903727","obfuscated":"false"},"SUM_TOTAL":{"datatype":"INTEGER","length":"10","value":"1644704985","obfuscated":"false"},"MID":{"datatype":"ALPHANUMERIC","length":"27","value":"Vendor 1","obfuscated ...

Click outside to toggle dropdown and hide it

My dropdown menu is currently working, but I would like it to close when I click outside of it. I've tried various solutions provided in other posts, but I just can't seem to get it right. Can someone please help me figure out what I am missing? ...

Making a second Ajax call to a servlet during an initial Ajax request

Hey there! I've been using an AJAX call to a servlet with jQuery: function updateMapping() { $.ajax({ type : "POST", url : "/tool/updateMap", data : "mapArray=" + mapArrayVar+ "&submit=Update", ...

What is preventing me from manipulating this Object outside of the ngOnInit() function?

I've been working on a project that involves fetching data from the server and manipulating it within the .ts file. However, I seem to be facing a common issue related to Typescript/angular concepts that I'm struggling to grasp...I would really a ...

Adding a MTL texture to an OBJ in your three.js project is a simple process that can enhance

Hello! I am currently working on adding an MTL file to my OBJ in three.js. I had successfully loaded my OBJ and went back to address this issue. However, after adding the code to load the MTL file using MTLLoader, the code seems to be getting stuck at mt ...

Tips for grabbing specific column header text in tables with different id, name, or class using Jquery

I utilized the each() method to extract the table header text. However, my goal is to specifically target and retrieve the table header text labeled as 4.1. Here are the results: Below is the HTML table code: <form enctype="multipart/form-data&quo ...

Connect the plotly library to interact with the data in a Vue.js application through

I'm currently working on a project that involves using vue.js and the plot.ly JavaScript graph library. I am trying to figure out how to bind "pts" to the data's "TestSentences" in Vue. Below is my code snippet, thanks to everyone who has provide ...

What is the method to identify the key responsible for triggering a textbox input event?

Suppose there is a textbox on the webpage: <input id='Sub' type='text'> To capture each time the input changes, you can use the following code: sub = document.getElementById('Sub'); sub.addEventListener('input&a ...

.htaccess file is causing js and css files to not load

I followed an MVC tutorial by howcode on YouTube, but I encountered an issue where my CSS and JS files were not loading due to the htaccess configuration. .htaccess file: RewriteEngine On RewriteRule ^([^/]+)/? index.php?url=$1 [L,QSA] I attempted vario ...

Multi-validation for user input in JavaScript

When working with JavaScript, I have encountered a challenge where I need to validate an input that can only accept either 11 numeric characters or 17 alphabetic characters. Individually, I am able to check for one of these conditions but struggling to im ...