I have a Google Library with HTML form, process form script addNewItemand script to run the form in popup window addItem.
function addItem()
{
var html = HtmlService.createHtmlOutputFromFile('input/form.html');
SpreadsheetApp.getUi()
.showModalDialog(html, 'Add New Recipe');
}
function addNewItem(form_data)
{
var url = "SPREADSHEET_URL_TO_DATA_COLLECTION";
var ss = SpreadsheetApp.openByUrl(url);
var sheet = ss.getSheetByName('List');
var asiaTime = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd");
var dishName = form_data.dish_name;
var cuisineName = form_data.cuisine_name;
var placeName = form_data.place_name;
var categoryName = form_data.category_name;
var num = sheet.getRange(sheet.getLastRow(), 1).getValue() + 1 || sheet.getLastRow();
sheet.appendRow([num, dishName, cuisineName, placeName, categoryName, asiaTime]);
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<form id="myform">
<div class="block form-group">
<label for="dish_name">Dish name</label>
<input type='text' name='dish_name' id="dish_name" required="required"/>
</div>
<div class="block form-group">
<label for="place_name">Place</label>
<select id="place_name" name="place_name" type="text" required>
<option value="LL4H">LL4H</option>
<option value="LL4T">LL4T</option>
</select>
</div>
<div class="block form-group">
<label for="cuisine_name">Cuisine</label>
<select id="cuisine_name" name="cuisine_name" type="text" required>
<option value="Asian">Asian</option>
<option value="Western">Western</option>
</select>
</div>
<div class="block form-group">
<label for="category_name">Category</label>
<input id="category_name" name="category_name" type="text" list="quote-choices" required>
<datalist id="quote-choices">
<option value="Starter">Starter</option>
<option value="Main course">Main course</option>
<option value="Veggi side">Veggi side</option>
<option value="Carbs side">Carbs side</option>
<option value="Dessert">Dessert</option>
<option value="Dough">Dough</option>
<option value="Sauce">Sauce</option>
<option value="Drink">Drink</option>
<option value="Other">Other</option>
</datalist>
</div>
<div class="block">
<button type="submit" class="action">Submit</button>
</div>
</form>
<script>
document.querySelector("#myform").addEventListener("submit",
function(e)
{
e.preventDefault(); //stop form from submitting
console.log(this)
google.script.run.withSuccessHandler(()=> google.script.host.close()).addNewItem(this);
}
);
</script>
</body>
</html>
I connected this Library with the Google Spreadsheet and declared new function to run library script to open the form.
function createRecipe() {
RecipeBuilder.addItem();
}
function addNewItem(form_data) {
RecipeBuilder.addNewItem(form_data);
}
Form appears in popup window well.
I click Submit to submit my data from the form, but serverside process does not start.
How to run this form correct? Where I'm wrong? How to fix it?
UPDATED
It's still does not work with library but works well if I put it in bound-container script of some spreadsheet. Unfortunately, I can't use it in bound-container because full code of addNewItem(form_data) function must replicate current spreadsheet. Finally it will be 1000+ Google Spreadsheets with same numbers of bound-containers. It will be super complicated to update it
I believe your goal and situation as follows.
You want to use addItem(), addNewItem(form_data) and input/form.html as a GAS library.
When you call this library from the client side, when the submit button is clicked, the data is not sent.
You want to remove this issue.
The library name is RecipeBuilder.
For this, how about this modification?
Modification points:
I think that the reason of your issue is google.script.run.addNewItem(this);. In this case, when addNewItem(this) is run, this function is searched from the GAS project. By this, an error occurs like Uncaught TypeError: google.script.run.addNewItem is not a function. I think that this is the reason of your issue.
In order to remove this issue, how about the following modification? In this modification, one more function is added to the client side.
Modified script:
function createRecipe() {
RecipeBuilder.addItem();
}
// Added
function addNewItem(form_data) {
RecipeBuilder.addNewItem(form_data);
}
By this, when google.script.run.addNewItem(this); is run at the library side, addNewItem of client side is run, and then, RecipeBuilder.addNewItem of the library side is run.
Note:
In your Javascript of library side, google.script.run.addNewItem(this); and google.script.host.close(); are run in order. But google.script.run works with the asynchronous process. So if the process of addNewItem(this) is slow, the dialog might be closed before addNewItem(this) is run. So I think that the following modification might be also used.
From
google.script.run.addNewItem(this);
google.script.host.close();//close this dialogbox
To
google.script.run.withSuccessHandler(()=> google.script.host.close()).addNewItem(this);
Reference:
Class google.script.run
I recommend you put your scripts into:
document.addEventListener('DOMContentLoaded', event => {
// your code here
});
Related
I'm trying to use the Google Chrome Storage API (https://developer.chrome.com/extensions/storage) to persist a textarea that acts as a persistent notes field in my plugin
In the HTML I have a handler setup to run save_notes on blur.
I want to fire load_notes() immediately if the textarea is blank. save_notes should save the textarea to object key 'stored_obj'
I didn't code it right and it's not working, anyone see the issue?
notes.js
///// select the text area
// var note_area = document.getElementById("textarea")
var note_area = document.querySelector("#textarea")
//// create a function to save the textarea to local storage
// I'll also want to check & load previously saved notes
;(function load_notes () {
if (!note_area) {
note_area.value = chrome.storage.sync.get(stored_obj)
}
})()
function save_notes () {
chrome.storage.sync.set({
stored_obj: note_area
}, function () {
console.log("Saved into Chrome Storage")
})
}
//// setup a blur handler in notes.html to fire function save_notes
notes.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Note Screen</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
<link rel="stylesheet" href="style.css">
<script src="scripts/notes.js"></script>
</head>
<body>
<div class="container">
<ul class="nav nav-tabs">
<li>Settings</li>
<li role="presentation" class="active">Notes</li>
</ul>
<div id="notes-header">
<h1 id="noteh1">Note Screen</h1>
</div>
<hr>
<div class="row">
<div class="col-sm-8" id="notes-section">
<h2>Websurf Notes</h2>
<p>Write notes here. Reference them to do searches and checks during free time</p>
<!--<button id='notesave' class="btn btn-primary">Save Notes & Close Tab</button>-->
<br>
<textarea name="ntxt" id="notetext" cols="20" rows="20" class="form-control" onblur="save_notes()"></textarea>
</div>
<div class="col-sm-4">
<h2>Override</h2>
<p>Things that demand an immediate view are the ONLY intended targets of this override</p>
<div class="form-group">
<!--<form action="" class="form-control">-->
<select name="" id="bypass-limit" class="form-control">
<option value="">Bypass Time Limit</option>
<option value="5">5 minutes</option>
<option value="10">10 minutes</option>
<option value="15">15 minutes</option>
<option value="20">20 minutes</option>
<option value="30">30 minutes</option>
</select>
</div>
<div class="form-group">
<button id="bypass-button" class="btn btn-danger">
Bypass Now (action will be logged)
</button>
<!--</form>-->
</div>
</div>
</div>
</div>
</body>
</html>
chrome.storage.sync.get() is an asynchronous function just like set() is. You have the proper callback function set up for set(), but not get:
chrome.storage.sync.get("stored_obj", function(result) { note_area.value = result } );
That is the first thing that jumps out at me, there may be other errors.
Wrong id
In var note_area = document.querySelector("#textarea")
note_area will always return null. There is id such as textarea it is notetext or use
var note_area = document.querySelector("textarea")
Also in the if statement if(note_area.val === "")
Inline event handler
Extension produces following error on run
Refused to execute inline event handler because it violates CSP.
this because of onblur="save_notes()"
It is not allowed now. Instead, use this in your js file document.querySelector("#notetext").addEventListener("blur", save_notes);
chrome.storage.sync
chrome.storage.sync.get(stored_obj)
stored_obj does not exit! so it can't get you anything from the store use this instead.
chrome.storage.sync.get("stored_obj")
It will return you an object resultObject do resultObject.stored_obj to get the value.
You need to pass note_area.val in set
The JSFiddle in question seems to have no trouble: http://jsfiddle.net/S3LF3/ (if you type a url like google.com it will select the value of ".com" or whatever you put after the dot and it is in the list)
However the jQuery function seems to be faulty?
In chrome I get this error:
Uncaught TypeError: $(...).ready(...) is not a function
Here is my code:
<html>
<head>
<title>Add Site</title>
<script src="js/jquery-3.1.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/msdropdown/dd.css" />
<script src="js/msdropdown/jquery.dd.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/msdropdown/flags.css" />
</head>
<body>
<h1>Add new site</h1>
<div class="contentbox">
<form method="post">
<input type="hidden" name="addsite" value="true"/>
<p>
<label for="site_url">Site url:</label>
<input type="text" name="site_url" id="urlText" placeholder="domain.xxx" value=""/>
</p>
<p>
<label for="site_url">Search locale:</label>
<select name="locale" id="locale">
<option value="">
Select locale
</option>
<optgroup label="Popular">
<option value=".dk" data-image="images/msdropdown/icons/blank.gif" data-imagecss="flag dk" data-title="Denmark">Denmark - Danish</option>
<option value=".de" data-image="images/msdropdown/icons/blank.gif" data-imagecss="flag de" data-title="Germany">Germany - German</option>
<option value=".au" data-image="images/msdropdown/icons/blank.gif" data-imagecss="flag au" data-title="Australia">Australia - English</option>
</optgroup>
</select>
</p>
<p>
<label for="site_url"></label>
<input type="submit" name="submit" class="btn" value="Add">
</p>
</form>
</div>
</body>
</html>
<script>
$(document).ready(function() {
$("#locale").msDropdown();
})
(function ($) {
$('#urlText').on('change', function () {
var value = this.value,
parts = this.value.split('.'),
str, $opt;
for (var i = 0; i < parts.length; i++) {
str = '.' + parts.slice(i).join('.');
$opt = $('#locale option[value="' + str + '"]');
if ($opt.length) {
$opt.prop('selected', true);
break;
}
}
})
})(jQuery);
</script>
What I want to do is when a user types a url, like "google.dk" , it should select the value with ".dk" at the end from the dropdown for him.
I played with your code and found out, it's the missing semicolon at the end of $(document).ready();
$(document).ready(function() {
$("#locale").msDropdown();
});
Just try it in the built-in editor:
<html>
<head>
<title>Add Site</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/msdropdown/dd.css" />
<script src="js/msdropdown/jquery.dd.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/msdropdown/flags.css" />
</head>
<body>
<h1>Add new site</h1>
<div class="contentbox">
<form method="post">
<input type="hidden" name="addsite" value="true"/>
<p>
<label for="site_url">Site url:</label>
<input type="text" name="site_url" id="urlText" placeholder="domain.xxx" value=""/>
</p>
<p>
<label for="site_url">Search locale:</label>
<select name="locale" id="locale">
<option value="">
Select locale
</option>
<optgroup label="Popular">
<option value=".dk" data-image="images/msdropdown/icons/blank.gif" data-imagecss="flag dk" data-title="Denmark">Denmark - Danish</option>
<option value=".de" data-image="images/msdropdown/icons/blank.gif" data-imagecss="flag de" data-title="Germany">Germany - German</option>
<option value=".au" data-image="images/msdropdown/icons/blank.gif" data-imagecss="flag au" data-title="Australia">Australia - English</option>
</optgroup>
</select>
</p>
<p>
<label for="site_url"></label>
<input type="submit" name="submit" class="btn" value="Add">
</p>
</form>
</div>
</body>
</html>
<script>
$(document).ready(function() {
//$("#locale").msDropdown();
});
(function ($) {
$('#urlText').on('change', function () {
var value = this.value,
parts = this.value.split('.'),
str, $opt;
for (var i = 0; i < parts.length; i++) {
str = '.' + parts.slice(i).join('.');
$opt = $('#locale option[value="' + str + '"]');
if ($opt.length) {
$opt.prop('selected', true);
break;
}
}
})
})(jQuery);
</script>
The reason the JSFiddle works fine is it doesn't actually use the country flag drop down menu plugin you found. The way the plugin works is different than the way a standard <select> html tag works.
I looked inside the jquery.dd.js file, and it seems there is no way to interact with the dropdown menu using javascript. Therefore, your line $opt.prop('selected', true); is valid for a real drop down menu (a <select> tag), but not for the plugin's drop down menu, which handles the selected state differently. Also, the plugin provides little documentation and has little to no comments in the code, so this makes it diffcult to know how the plugin works.
I can see 2 solutions to your problem:
You can try to understand the plugin's code in the jquery.dd.js file and try to implement a way to tell the plugin which element you want to select. I wouldn't normally recommend editing third-party plugins, but since the site you got the plugin from has not been updated since 2012, there is little chance for the plugin to receive updates in the future, so editing it would be safe in this case. It will require some knowledge in jQuery plugin making, though.
You can try to find another country flag drop down plugin that can be updated using javascript instead of using your mouse only. Such projects can be found on Github (here are some results found on Github: Country flag drop down menu results on Github).
Previous information found:
From the code you provided, you are missing a semi-colon after the call of the $(document).ready() function. It should look like this:
$(document).ready(function() {
$("#locale").msDropdown();
}); // <--- This semi-colon is missing
Also, the code in (function ($) {// code} )(jQuery); may be executed before the document was ready, which means this code could sometimes not work. Try putting this code inside your $(document).ready(); anonymous function. This way, you will be sure all html nodes will be accessible by jQuery.
Finally, you should consider putting your javascript logic somewhere inside the <html> tag (inside the <head>, right after <body> or right before </body>). While putting the <script> tag after the </html> tag may work at first, this is far from valid html and may be the cause of some problems you're having. The best way would be to put your javascript in a .js file and link it in your <head> the same way you linked jQuery and msdropdown:
<head>
<!-- Your other linked files... -->
<script src="js/main-logic.js"></script>
</head>
The JQuery shortcut - $() - seems to have been overridden by another library is my guess.
Try using:
jQuery( document ).ready(function( $ ) {
// Code that uses jQuery's $ can follow here.
});
I have a simple form requesting couple questions from the user. I am attempting to connect my FireBase account so the realtime database can get updated when the user presses the submit button. However, the database is not receiving any information. I have attached the code.
The problem is somewhere in the HTML or JavaScript. I have inserted random alerts to see if they would work, and I get them to come up. I removed some of the "dataLink.push" commands, due to my FireBase only containing 2 values (name, value). I am a beginner with FireBase.
var config = {
apiKey: "AIzaSyCdqgGdZH8bWSMiHEM7ZoeWSNfZ04uA3Y8",
authDomain: "errandboi-f1cf5.firebaseapp.com",
databaseURL: "https://errandboi-f1cf5.firebaseio.com",
storageBucket: "errandboi-f1cf5.appspot.com",
};
firebase.initializeApp(config);
// Creates a variable called databaseLink that links to our database.
var databaseLink = new Firebase('https://errandboi-f1cf5.firebaseio.com/');
// Create javascript variables that link our previous HTML IDs. Remember, we can't use regular HTML inside a script tag, so we need to use JQuery to reference any previous HTML. A $ means we are using JQuery
var messageField = $('#task');
var nameField = $('#name');
var contactField = $('#contact');
var locationField = $('#location');
var miscField = $('#misc');
var messageList = $('#example-messages'); // DELETE MAYBE?????
//alert(messageField);
// If the enter key is pressed, push the values in the text boxes to our database.
function push(){
alert("yo");
messageField.keypress(function (e) {
if (e.keyCode == 13) { //13 is the enter key's keycode
alert("yo");
if (messageField.val() == ""){ //Ensure that an activity was entered.
alert("Please let us know how we can help!");
}else{
//push data to firebase and then clear the text box
databaseLink.push({name:nameField.val(), value:messageField.val()});
messageField.val('');
}
}
}
});//end of keypress function
<DOCTYPE! html>
<html>
<head>
<meta charset="UTF-8">
<!--THIS IS NEEDED TO IMPORT FIREBASE LIBRARIES -->
<script src="https://cdn.firebase.com/js/client/2.2.1/firebase.js"></script>
<!-- THIS IS JUST A NICE LOOKING FONT -->
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<!--THIS IS NEEDED TO IMPORT JQUERY LIBRARIES -->
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js'></script>
<!-- THIS IS TO IMPORT MY JS FILE -->
<script src="index.js"></script>
<link href="style.css" rel="stylesheet" />
<title>ErrandBoi!</title>
</head>
<body>
<div id="container">
<header>
<h1 class="title">ErrandBoi</h1>
</header>
<div id="banner">
<h2>Your Helping Hand in Every Situation</h2>
</div>
<div id="content">
<p class="content">Ever have an emergency while you are in class? Life has got you all tied up but your tasks won't do themselves? Well, you are at the right place for help. Let ErrandBoi take the stress off your shoulders while you can do what really matters. Simply, fill out the form below with any* task that you may need help with and one of our drivers will help you out as soon as possible!</p>
<br><br><br><br><br><br><br><br><br>
<div class="form-style-5">
<form method="POST">
<fieldset>
<legend><span class="number">1</span> Your Information</legend>
<input type="text" name="field1" id="name" placeholder="Your Name *">
<input type="email" name="field2" id="contact"placeholder="Contact Information (Email, Phone Number, etc.) *">
<input type="location" name="field2" id="location" placeholder="Your Location (i.e. McNutt, Hodge Hall, exact address, etc.)*">
<input type="text" name="field3" id="misc" placeholder="Miscellaneous Information That May Be Important"></textarea>
<label for="job">Urgency:</label>
<select id="job" name="field4">
<optgroup label="Urgency level: just for us to prioritize properly">
<option value="Not Urgent">Low (ETA: Up to an hour)</option>
<option value="reading">Normal (ETA: Up to 45 mins)</option>
<option value="boxing">Critical (ETA: ASAP!)</option>
</optgroup>
</select>
</fieldset>
<fieldset>
<legend><span class="number">2</span>Task that needs completion</legend>
<input type="text" name="field3" id="task" placeholder="Let Us Know How We Can Help!*"></input>
</fieldset>
<input type="submit" value="Apply" onClick = "push()"/>
</form>
</div>
</div>
</div>
</body>
</html>
You are trying to mix Firebase v2 and Firebase v3. In order to make it work you should:
1) Import the right Firebase sdk (and remove the old one from your code)
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js"></script>
2) Get a reference to the firebase database
var databaseLink = firebase.database().ref();
NOTE: Firebase has been updated recently, the new documentation is at firebase.google.com (not firebase.com)
Hope it helps ;)
I'm new to Javascript and HTML.
I have the following form in HTML:
<div id="form-select">
<form id="date_form" onsubmit="return myFunction();">
<datalist id="dates">
<option value="February 7">February 7</option>
<option value="February 14">February 14</option>
<option value="February 21">February 21</option>
<option value="February 28">February 28</option>
</datalist>
<input type="text" class="input" name="data" id="date" value="" list="dates" placeholder="pick a date"><br>
<input type="submit">
</form>
</div>
Here's the javascript in a file called script.js. The js file is linked in the header as <script type="text/javascript" src="script.js" />:
function myFunction(){
var input = document.getElementById("date").value;
if(input==="February 7"){
document.getElementById('w1').innerHTML = document.getElementById('w1').innerHTML + "<h2> HEADING </h2>";
}
return false;
};
When I fill out the form and hit submit, the javascript correctly executes the function and adds "HEADING." However, when I press submit again, it adds "HEADING" a second time under the first instance of it.
How do I make it so that the page "refreshes" each time submit is pressed?
Thanks!
You can Use
window.location.reload();
In your Submit event code..
use jQuery, bind('submit', function(e){ e.preventDefault; ....; })
$('#date_form').submit(function(e){
e.preventDefault();
var input = document.getElementById("date").value;
if(input==="February 7"){
document.getElementById('w1').innerHTML = "<h2> HEADING </h2>";
}
return false;
});
Found another way around the issue. I added the statement:
document.getElementById('week').innerHTML = "";
at the beginning of each call of the function. That way, every time the user clicks submit, the div is emptied out before it is repopulated.
I'm trying to learn how to use JS in order to create a unit converter for a site I'm working on.
I did have intentions of trying to accomplish it using PHP but someone pointed out how inefficient it would be and so I'm now trying to learn JS to carry out the same tasks.
I've written a very small test function to add two numbers, it worked fine. I then adjusted it slightly to take in a few more params and to check a couple of conditions, again that worked fine - I created a new object and passed the variables in directly.
I now need to pass the values from the form that I have into this function in order to compute the sum and output the result. I keep getting an error of 'undefined'. I've googled and read but can't seem to find a solution.
so far I have:
<script type="text/javascript">
function Convert(from, to, units){
this.from = $("#from").val();
this.to = $("#to").val();
this.units = $("#units").val();
}
Convert.prototype.convertThem = function(){
if(this.from == "degC"){
if(this.to == "degF"){
return this.units * 347956757524;
}
}
}
calcTempTest = new Convert(this.from, this.to, this.units);
alert(calcTempTest.convertThem());
console.log(calcTempTest);
</script>
Could anyone tell me what I'm doing wrong please? The 'to','from' and 'units' are the id's from the form.
The Form:
<div class="form">
<label for="units">Units:</label>
<input type="text" name="units" id="units" class="required digits" />
</div>
<div class="form">
<label for="from">Convert From:</label>
<select name="from" id="from">
<option value="from">-Select an Option-</option>
</select>
</div>
<div class="form">
<label for="to">Convert Into:</label>
<select name="to" id="to">
<option value="to">-Select an Option-</option>
</select>
</div>
<div class="form">
<label> </label>
<input type="submit" name="submit" value="Convert!" />
</div>
many thanks.
Explanation
Your select selected option value onLoad both are "from" and "to". Since these are not equal to "degF" and "degC", your assignments won't go on, the resulting variable will be undefined since no value will be asssigned to it.
Solution
Add several option to your select or change their default value. I also added a default value to the input.
HTML
<input type="text" name="units" id="units" value="12" class="required digits" />
<option value="degC">-Select an Option-</option>
<option value="degF">-Select an Option-</option>
EDIT
I have added a JSFiddle here which executes the script on the button click with the following modifications to JavaScript:
NOTE: I also added the real formula.
JavaScript/jQuery
$('input[name="submit"]').click(function () {
var c = new Convert();
alert(c.convertThem());
});
function Convert() {
this.from = $("#from").val();
this.to = $("#to").val();
this.units = $("#units").val();
}
Convert.prototype.convertThem = function () {
if (this.from == "degC") {
if (this.to == "degF") {
return this.units * 1.8 + 32;
}
}
}
I think when you create the convert object you're trying to pass variables that don't exist:
calcTempTest = new Convert(this.from, this.to, this.units);
I'm pretty sure this stands for window at that point and windw.from is undefined. You don't seem to be doing anything with these values anyway so you could change it to:
calcTempTest = new Convert();
Maybe the following answer could help you out with what this stands for in JS: Prototypical inheritance - writing up
Here is some minimally working code:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script type="text/javascript" src="jquery-1.10.1.js"></script>
</head>
<body>
<div class="form">
<label for="units">Units:</label>
<input type="text" name="units" id="units" class="required digits" />
</div>
<div class="form">
<label for="from">Convert From:</label>
<select name="from" id="from">
<option value="degC">degC</option>
</select>
</div>
<div class="form">
<label for="to">Convert Into:</label>
<select name="to" id="to">
<option value="degF">degG</option>
</select>
</div>
<div class="form">
<label for="output">Output:</label>
<input type="text" id="output" />
</div>
<div class="form">
<label> </label>
<input type="submit" id="subm" name="submit" value="Convert!" />
</div>
<script type="text/javascript">
(function () {
function Convert(from, to, units) {
// when convert is created set a reference to the input elements
this.$from = $("#from");
this.$to = $("#to");
this.$units = $("#units");
this.$output = $("#output");
}
Convert.prototype.convertThem = function () {
// this.$... is a jQuery object containing the input elements
if (this.$from.val() == "degC") {
if (this.$to.val() == "degF") {
this.$output.val( this.$units.val() * 347956757524);
}
}
}
calcTempTest = new Convert();
$("#subm").on("click", null, null, function () {
calcTempTest.convertThem();
});
})();//anonymous funciton, no variables in global scope
</script>
</body>
</html>
There are several issues with your code. Most of them have been resolved in the accepted answer, but I wanted to provide some more insights that would help you create more reusable code in the future.
Since I have already created a jsfiddle with my own example, it will be a shame to let it go to waste so I will post it anyway with some comments.
Using constructor parameters
function Convert(from, to, units, res){
this.from = from;
//etc...
}
Passing parameters to an object's constructor (and using them) makes it more reusable. You did not use the passed parameters and the selected answer used what I assume was your original solution (hard-coding the element values into the object upon construction).
This way you can have multiple instances of the converter on the same page, you can put its code in an external file as it gets more complex and only put the instantiation logic in the page itself (if your page structure changes, there is no need to change the external file, just update the provided constructor parameters).
Storing node references instead of values
The other thing I wanted to point out is the way the calculation is done.
Your implementation requires a new object to be created for each calculation. I find it much better to create a single Converter and obtain the values only when required. That it the reason I stored a reference to the form field DOM nodes and did not store their values.
$("#btnConvert").click(calcTempTest.convertThem.bind(calcTempTest));
I used bind(...) in the click attachment to preserve the object's scope.
Good luck!