-
Notifications
You must be signed in to change notification settings - Fork 0
/
execForm.gs
195 lines (161 loc) · 5.59 KB
/
execForm.gs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//Created by Raymond Zhang (zhangraymond05@gmail.com)
//global variables (not very important can just be local)
Logger.log("Initializing");
var d = new Date();
var year = d.getFullYear();
//when the sheet is opened
function onOpen() {
//add "generate form" option to taskbar on top (file, edit, view, etc)
var ss = SpreadsheetApp.getActive();
var menu = [{name: 'Generate Form', functionName: 'generate'}]; //run the function called generate
menu.push(null);
menu.push({name: 'Generate Results', functionName: 'tallyVotes'});
ss.addMenu('Generator', menu);
}
//makes the form
function generate() {
//variables
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('Candidates');
var endpoint = ss.getSheetByName('Results');
var range = sheet.getDataRange();
var values = range.getValues();
var parentFolder = DriveApp.getFolderById('1_J5QVewVApOJKh5FGNszah0wt9dlkzW7');
var ui = SpreadsheetApp.getUi();
var grade = "";
do {
var response = ui.prompt('Grade Selection', 'Enter a grade', ui.ButtonSet.OK_CANCEL);
grade = response.getResponseText().trim();
} while(response.getSelectedButton() == ui.Button.CANCEL || response.getSelectedButton() == ui.Button.CLOSE);
var newFolder = parentFolder.createFolder(year + ' Grade ' + grade + ' Election');
//stores old sheet data and resets to base
var sheets = ss.getSheets();
if(sheets.length>2) {
Logger.log('Archived previous election');
var archive = SpreadsheetApp.create('[rename this] Previous senator election archive');
sheets[1].copyTo(archive);
sheets[2].copyTo(archive);
moveForm('[rename this] Previous senator election archive', newFolder.getId());
var formURL = sheets[0].getFormUrl();
FormApp.openByUrl(formURL).removeDestination();
ss.deleteSheet(sheets[0]);
}
//delete names
var h = endpoint.getDataRange().getHeight()-1;
if(h>0) endpoint.deleteRows(2, h);
//add new names
var names = [];
for(i=1;i<values.length;i++) {
if(values[i][0]==="") break;
names.push(values[i][0]);
endpoint.appendRow([values[i][0],0]);
}
//make the form
makeOurForm(names, grade, newFolder.getId());
}
//function which creates the form
function makeOurForm(names, grade, fileId) {
var ss = SpreadsheetApp.getActive();
Logger.log('Starting to create form');
var name = 'Grade ' + grade + ' Student Senator Ballot';
var form = FormApp.create(name);
//make sure only one response per user is allowed
form.setCollectEmail(true);
form.setLimitOneResponsePerUser(true);
form.setRequireLogin(true);
var item = form.addCheckboxItem();
item.setTitle('Vote for at most two candidates');
item.setChoiceValues(names);
item.setRequired(true);
//ensures that max two is allowed
var checkBoxValidation = FormApp.createCheckboxValidation()
.setHelpText('Select at most two candidates.')
.requireSelectAtMost(2)
.build();
item.setValidation(checkBoxValidation);
//make the results go to the master sheet
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
//create an event that runs when the spreadsheet recieves a result from the form
deleteTriggers();
ScriptApp.newTrigger('onFormSubmit').forSpreadsheet(ss).onFormSubmit().create();
//move form into archive folder
moveForm(name, fileId);
Logger.log('Form successfully created');
Logger.log('Published URL: ' + form.getPublishedUrl());
Logger.log('Editor URL: ' + form.getEditUrl());
}
//function which moves files around
function moveForm(name, fileId) {
Logger.log('Moving ' + name + ' to correct location');
var rootFolder = DriveApp.getRootFolder();
var archiveFolder = DriveApp.getFolderById(fileId);
var newForms = rootFolder.getFilesByName(name);
while(newForms.hasNext()) {
var newForm = newForms.next();
archiveFolder.addFile(newForm);
rootFolder.removeFile(newForm);
}
Logger.log(name + ' successfully moved');
}
//function which runs when a response is recieved
function onFormSubmit(e) {
var ss = SpreadsheetApp.getActive();
var sheets = ss.getSheets();
if(sheets[0].getName()!=='Responses') {
ss.getSheets()[0].setName('Responses');
}
}
//count up all the votes
function tallyVotes() {
//variables for manipulating spreadsheet
var ss = SpreadsheetApp.getActive();
var output = ss.getSheetByName('Results');
var r = output.getDataRange();
var v = r.getValues();
var input = ss.getSheetByName('Responses');
var r2 = input.getDataRange();
var v2 = r2.getValues();
var sheet = ss.getSheetByName('Candidates');
var range = sheet.getDataRange();
var values = range.getValues();
//retrieve student numbers of valid participants
var valid = {};
for(i=1;i<values.length;i++) {
valid[values[i][1]] = 1;
}
//clear spreadsheet
output.clear();
output.appendRow(['Name', 'Votes']);
//count votes for every person
for(i=1;i<v.length;i++) {
var name = v[i][0];
var num = v[i][1];
for(j=1;j<v2.length;j++) {
//check validity
var email = v2[j][1];
if(valid[email]===undefined) continue;
var names = v2[j][2].split(", ");
for(k=0;k<names.length;k++) {
if(names[k]===name) {
num++;
break;
}
}
}
output.appendRow([name,num]);
}
//output results
output.sort(2, false);
}
//get rid of previous triggers (a new one is created everytime this code is run)
function deleteTriggers(){
var triggers = ScriptApp.getProjectTriggers();
triggers.forEach(function(trigger){
try{
ScriptApp.deleteTrigger(trigger);
} catch(e) {
throw e.message;
};
Utilities.sleep(1000);
});
};