In the first part of this serie we've learnt how to build a simple Raffle using Google Sheet ( https://dev.to/jagedn/build-a-raffle-with-google-sheet-5da )
In this second part we'll refactor some parts of the code and improve it with new features
Separate business logic from UI
Open the script editor (as explained in the previous post) and create a new html file called Client.html
and another file called Dialog.html
Client.html
Paste this code into the Client.html
<!DOCTYPE html> | |
<html> | |
<head> | |
<base target="_top"> | |
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css"> | |
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> | |
</head> | |
<body> | |
<h1><?!= LanguageApp.translate('Bienvenido','',Session.getActiveUserLocale()) ?></h1> | |
<div> | |
<p> | |
<?!= LanguageApp.translate('Total Participantes activos','',Session.getActiveUserLocale()) ?> | |
</p> | |
<p> | |
<?!= totalRemains ?> | |
</p> | |
</div> | |
<? for(var i in prizzes){ ?> | |
<div> | |
<? for(var c=0; c < prizzes[i][1]; c++){ ?> | |
<p> | |
<input type="button" value="<?!=prizzes[i][0]?>" onclick="google.script.run.raffle('<?!=prizzes[i][0]?>')"/> | |
</p> | |
<? } ?> | |
</div> | |
<? } ?> | |
</body> | |
</html> | |
This will render the sidebar once the user select the Raffle option in the menu.
We'll show how many participants remains to participate and we'll build a list of buttons, once per prizze. In this way the admin can choose what prizze to raffle in every moment
As you can see, when the admin click a prizze button we'll call a remote function sending the prizze selected.
Dialog.html
Paste this code into the Dialog.html
<script> | |
var suertudoIdx = <?=suertudo[0]?>; | |
var prizze = '<?=prizze?>'; | |
function yepes(){ | |
google.script.run.withSuccessHandler(google.script.host.close).yepes(suertudoIdx,prizze) | |
} | |
function nopes(){ | |
google.script.run.withSuccessHandler(google.script.host.close).nopes(suertudoIdx,prizze) | |
} | |
function notPresent(){ | |
google.script.run.withSuccessHandler(google.script.host.close).notPresent(suertudoIdx,prizze) | |
} | |
</script> | |
<h1> | |
Congratulations <?=suertudo[1]+" "+suertudo[2]?> | |
</h1> | |
<p> | |
<image src="https://media.giphy.com/media/11sBLVxNs7v6WA/giphy.gif"/> | |
</p> | |
<p> | |
<div> | |
<input type="button" value="Yepes" onclick="yepes()" /> | |
| |
<input type="button" value="Nopes" onclick="nopes()" /> | |
| |
<input type="button" value="No Present" onclick="notPresent()" /> | |
</div> | |
</p> |
This file is the template to render the winner of a prizze and let to choose an action (accept, denied, and not pressent)
Once the admin click one of buttons following actions happen:
- the dialog call a remote function to notify the action selected
- when the remote function is executed the dialog is closed.
For example if the winner accept the prizze the dialog will execute this:
google.script.run.withSuccessHandler(google.script.host.close).yepes(suertudoIdx,prizze)
where yepes
is a remote function
Business
Paste this code into the Code.gs
(replace all the code if you followed the previous post)
//Called by Google Sheet | |
function onOpen(e) { | |
var ui = SpreadsheetApp.getUi(); | |
ui.createAddonMenu().addItem('Raffle', 'raffleUI').addToUi(); | |
} | |
// Read G3:H999 searching prizzes (title and quantity) | |
function getPrizzes(){ | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var sheet = ss.getActiveSheet(); | |
var ret = []; | |
for(var i=3; i<ss.getLastRow()+1; i++){ | |
var row = ss.getRange("G"+i+":H"+i).getValues()[0]; | |
if( !row[0] ){ | |
break | |
} | |
// extract the title and the quantity | |
ret.push( [row[0],row[1]] ) | |
} | |
return ret; | |
} | |
// Write the G3:H999 range with new prizzes status | |
function updatePrizzes(prizzes){ | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var sheet = ss.getActiveSheet(); | |
ss.getRange("G3:H"+(2+prizzes.length)).setValues(prizzes) | |
} | |
// Search particpants without prizzes in range A3:D999 | |
function getRemains(){ | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var sheet = ss.getActiveSheet(); | |
var ret = []; | |
for(var i=3; i<ss.getLastRow()+1; i++){ | |
var row = ss.getRange("A"+i+":D"+i).getValues()[0]; | |
if( !row[0] ){ | |
break | |
} | |
if( !row[3] ){ | |
// rowIndex, name and surname | |
ret.push( [i,row[0],row[1]] ) | |
} | |
} | |
return ret; | |
} | |
// The winner accept the prizze: | |
// update their cell and decrement the prizze | |
function yepes(idx, prizze){ | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var sheet = ss.getActiveSheet(); | |
var cell = sheet.getRange("D"+idx); | |
cell.setValue("winner of "+prizze); | |
var prizzes = getPrizzes(); | |
for(var i in prizzes){ | |
if( prizzes[i][0] === prizze ){ | |
prizzes[i][1]--; | |
updatePrizzes(prizzes) | |
break; | |
} | |
} | |
raffleUI(); | |
} | |
// the winner decline the prizze: do nothing | |
function nopes(idx, prizze){ | |
raffleUI(); | |
} | |
// the winner is not pressent: bad guy | |
function notPresent(idx){ | |
var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
var sheet = ss.getActiveSheet(); | |
var cell = sheet.getRange("D"+idx); | |
cell.setValue("no present"); | |
raffleUI(); | |
} | |
// Show the winner and ask if they want the prizze | |
function raffle(prizze){ | |
var remains = getRemains(); | |
var suertudoIndex = Math.floor(Math.random()*remains.length); | |
var suertudo = remains[suertudoIndex]; | |
var template = HtmlService.createTemplateFromFile('Dialog'); | |
template.suertudo = suertudo; | |
template.prizze = prizze; | |
var html = template.evaluate(); | |
var htmlOutput = HtmlService | |
.createHtmlOutput(html) | |
.setWidth(640) | |
.setHeight(480); | |
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Wooaaaaa'); | |
} | |
// main: prepare a sidebar with prizzes | |
function raffleUI(){ | |
var remains = getRemains(); | |
var template = HtmlService.createTemplateFromFile('Client'); | |
template.totalRemains = remains.length; | |
template.prizzes = getPrizzes(); | |
var html = template.evaluate(); | |
html.setTitle("Raffle") | |
.setSandboxMode(HtmlService.SandboxMode.IFRAME) | |
.setWidth(300); | |
SpreadsheetApp.getUi().showSidebar(html); | |
} | |
Prepare your Raffle
In a clean sheet write the participants and the prizzes following this screen:
Pay attention to use the same rows and columns or if you want to use different ranges remember to adjust them into the Code.gs
file
See in action
In this video you can see the raffle in action
Top comments (0)