JQuery Mobile with Google Apps Script

I made Google Apps Script deployed as a stand-alone web application using HTMLService, which provides a simple interface for entering budget data into a Google spreadsheet. I use jQuery Mobile for some of javascript, and also to style it for mobile devices, since my main use case for this application is to enter purchases from my mobile phone.

My problem is that the application does not scale properly in the mobile browser. This is the width of the browser, but it is as if "reduced". All controls become unusable on mobile devices.

If Script is embedded in the Google Site, it scales properly, but I would rather directly browse the web application rather than embed it in Google Sites.

EDIT: My reputation is high enough to post photos now, so here they are (below code).

EDIT: The beginning of my HTML is below. I originally had javascript and full HTML, and I can add snippets if necessary, but I looked at it again and I don’t think it is addicted to the problem that is causing the problem, so I deleted it.

HTML:

<!DOCTYPE html> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css"> <?!= include('javascript'); ?> <div data-role="page" data-theme="a" id="main"> <div data-role="content"> <form id="myForm"> ... 

Code.gs:

 function doGet() { return HtmlService.createTemplateFromFile('index').evaluate() .setSandboxMode(HtmlService.SandboxMode.IFRAME).setTitle('Budget Entry'); } 

Direct Access (left) and Embedded in Google Sites (right).

Snippet with full code:

 //<script> function formSuccess() { var dateSelect = document.getElementById("date"); var dateSelected = dateSelect.options[dateSelect.selectedIndex].text; var catSelect = document.getElementById("category"); var catSelected = catSelect.options[catSelect.selectedIndex].text; var amountEntered = document.getElementById("amount").value; var noteEntered = document.getElementById("note").value; var successMsg = 'Date: ' + dateSelected + '<br>Category: ' + catSelected + '<br>Amount: $' + amountEntered + '<br>Note: ' + noteEntered; $('#dialogMain').html(successMsg); $.mobile.silentScroll(0); $.mobile.changePage( "#dialog", { role: "dialog" } ); requestCategoryInfo(document.getElementById("status")); document.getElementById("amount").value = ''; document.getElementById("note").value = ''; } function submitForm() { if (document.getElementById('amount').value.length == 0) { alert('Please enter an amount.'); return; } $.mobile.loading( 'show' ); $('#status').html(''); google.script.run .withSuccessHandler(formSuccess) .processForm(document.getElementById('myForm')); } function loadUI() { $.mobile.loading( 'show' ); loadDateSelect(); google.script.run.withSuccessHandler(loadCategoryNamesAndValues).withFailureHandler(sendLog) .getCategoryNamesAndValues(); $.mobile.loading( 'hide' ); } function loadDateSelect(){ var d = new Date(); var month = d.getMonth()+1; var today = d.getDate(); var daysInAMonth = [0,31,28,31,30,31,30,31,31,30,31,30,31]; for (var n=1; n <= daysInAMonth[month]; n++) { var option = $("<option>").attr('value',n).text(month+"/"+n); $('#date').append(option); } $('#date').val(today); $('#date').selectmenu('refresh', true); } function loadCategoryNamesAndValues(catNamesAndValues){ var namesAndValues = catNamesAndValues; var optionHTML = ''; var currentGroup = ''; var catName = ''; var catID = ''; for (var i=0; i<namesAndValues.length; i++) { catName = namesAndValues[i][0]; catID = namesAndValues[i][1]; if (catID.toString() == "Group"){ // Handle Group Name if (currentGroup.length > 0) { // close previous optgroup tag optionHTML += "</optGroup>"; } // Open optGroup currentGroup = catName; optionHTML += "<optGroup label='" + currentGroup + "'>"; } else if (isNaN(parseInt(catID)) || parseInt(catID) == 0){ //Do Nothing } else { // Create Option HTML as: <option value=namesAndValues[i][1]>namesAndValues[i][0]</option> optionHTML += "<option value='" + catID + "'>" + catName + "</option>"; } } // Close current OptGroup optionHTML += "</optGroup>" document.getElementById('category').innerHTML = optionHTML; $('#category').selectmenu('refresh', true); } function categoryChanged() { setStatus(''); requestCategoryInfo(document.getElementById('status')); } function requestCategoryInfo(container) { $.mobile.loading( 'show' ); google.script.run .withSuccessHandler(displayCategoryInfo) .withFailureHandler(sendLog) .withUserObject(container) .getCategoryInfo(document.getElementById('category').value); } function displayCategoryInfo(categoryInfo, container){ var spentStr = 'Spent $' + categoryInfo.actual.toFixed(2) + ' of $' + categoryInfo.budgeted.toFixed(2); var remainingStr = 'Remaining: $' + categoryInfo.remaining.toFixed(2); var statusDiv = container; if (statusDiv.innerHTML.length > 0){ statusDiv.innerHTML += '<br>'}; statusDiv.innerHTML += spentStr + '<br>' + remainingStr; if (String(categoryInfo.fundAmount).length > 0) { var fundAmountStr = ''; if (categoryInfo.remaining < 0) { fundAmountStr = (categoryInfo.fundAmount + categoryInfo.remaining).toFixed(2); } else { fundAmountStr = categoryInfo.fundAmount.toFixed(2); } statusDiv.innerHTML += '<br>Fund: $' + fundAmountStr; } $.mobile.loading( 'hide' ); } function setStatus(html){ document.getElementById('status').innerHTML = html; } function appendStatus(html){ setStatus(document.getElementById('status').innerHTML + '<br>' + html); } function sendLog(){ google.script.run.sendLog(); } //</script> 
 <!DOCTYPE html> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css"> <?!= include('javascript'); ?> <div data-role="page" data-theme="a" id="main"> <div data-role="content"> <form id="myForm"> <div>Date</div> <div><select name="date" id="date"></select></div> <div>Category</div> <div><select name=category id="category" onchange="categoryChanged()" required></select></div> <div>Amount</div> <div><input type="text" name="amount" id="amount" required></div> <div>Note</div> <div><input type="text" name="note" id="note"></div> <div><input type="button" id="submit" value="Submit" onclick="submitForm()"/></div> </form> <!--<a href="#dialog" data-role="button" data-rel="dialog" data-transition="pop">Dialog</a>--> </div><!-- /content --> <div data-role="footer"> <div id="status"></div> </div><!-- /footer --> </div><!-- /page --> <div data-role="page" id="dialog" data-close-btn="none"> <div data-role="header"> <h1 id="dialogHeading">Success!</h1> </div> <div data-role="main" class="ui-content" id="dialogMain"> <p>Text goes here.</p> </div> <div class="ui-grid-b"> <div class="ui-block-a"></div> <div class="ui-block-b"><a href="#main" data-role="button" data-icon="check">OK</a></div> <div class="ui-block-c"></div> </div><!-- /grid-a --> <!--><div data-role="footer"></div>--> </div> <script type="text/javascript"> $(loadUI); </script> 
+7
javascript jquery-mobile google-apps-script google-sites
source share
4 answers
 var output = HtmlService.createHtmlOutput('<b>Hello, world!</b>'); output.addMetaTag('viewport', 'width=device-width, initial-scale=1'); 

it will help

+2
source share

You can determine the size of the display using CSS Media queries. For example, adding this to your CSS causes the form to display differently depending on the screen size of the device:

 @media only screen and (min-device-width: 413px) and (max-device-width: 415px) { /* iPhone 6+ */ #main, #dialog { zoom: 3; background: red; } } @media only screen and (min-device-width: 374px) and (max-device-width: 376px) { /* iPhone6 Styles */ #main, #dialog { transform: scale(2); background: blue; } } @media only screen and (min-device-width: 359px) and (max-device-width: 361px) { /* iPhone6+ Alt Styles */ #main, #dialog { transform: scale(2); background: green; } } @media only screen and (min-device-width: 319px) and (max-device-width: 321px) { /* iPhone5 or less Styles */ #main, #dialog { transform: scale(2); background: grey; } } 

Using emulation of a Chrome device, the form looked pretty good. (The red background is set by the above css.) But when I turned to the application from my real iPhone 6+, not all the elements were the same. (For example, the Submit button). Thus, there is a possibility that some other specific css are necessary for further adaptation of the result.

screenshot screenshot

+1
source share

I had this exact problem. All I tried to do was check out some jQuery mobile website templates without deploying them using either the Google App Engine or Google Cloud Storage .

Google Drive no longer allows you to directly serve HTML , so a script application is the next best option.

Problem that iframe application scripts are all, creating problems with the viewspace for things designed to be viewed on mobile devices (even after fixing the problem when jQuery src= should be https instead of http ).

The hotfix should include a META tag on the iframe page in addition to the HTML you serve.

In any case, the two answers that say to add a META tag worked fine.

If you use the jQuery mobile page, this code.gs code worked for me:

 function doGet() { var output = HtmlService.createHtmlOutputFromFile('test'); output.addMetaTag('viewport', 'width=device-width, initial-scale=1'); return output; } 

Where test is your test.html file.

+1
source share

This should help addmetatagname () of the HtmlOutput class . You must change the meta tag through the code.

0
source share

All Articles