Filling Out A Web Form e.g. Halawai Scheduling Top of Form A Dozen Widgets to Fill/Select AppleScript Commands Browser -- Fills a Halawai scheduling page form with the needed information so that it csn be submitted -- Author Jan Stelovsky Copyright 2013 (open source under MIT license) tell application "Safari" -- show the 1st tab of Safari's front window and display the title of its document -- note: clicking Cancel quits tell front window to set current tab to tab 1 set title to do JavaScript "document.getElementsByTagName('title')[0].innerHTML" in document 1 display dialog "Safari opened document \"" & title & "\" in 1-st tab" -- execute the script from a text file set scriptFile to "/Users/jan/Documents/ics/script.txt" set sourceScript to my readFile(scriptFile) do JavaScript sourceScript in document 1 -- ask which course fo fill in set course to display dialog "Choose ICS Course" buttons {"ICS 215", "ICS 665", "Cancel"} default button 3 -- unless Cancelled, fill form with data specific to the selected course if button returned of course is "ICS 665" then set specs to "{title:'ICS 665 UI & Hypermedia', at:'12:00pm-1:15pm', starts:'August 26, 2013', size:14, participants:’email-1 email-2 email-n'}" my fill(specs) else if button returned of course is "ICS 215" then set specs to "{title:'ICS 215 Intro to Scripting', at:'10:00am-11:45am', starts:'August 26, 2013', size:34, participants:’email-1 email-2 email-n'}" my fill(specs) end if end tell -- Ask for lecture number and with 'specs' executes JavaScript script that fills the form page in the browser on fill(specs) set lecture to text returned of (display dialog "Lecture No.:" default answer "") set fillScript to "new FormFiller(" & lecture - 1 & "," & specs & ");" tell application "Safari" to do JavaScript fillScript in document 1 end fill -- Returns the content of the text file 'unixPath' on readFile(unixPath) set textFile to (open for access (POSIX file unixPath)) set content to (read textFile for (get eof textFile)) close access textFile return content end readFile JavaScript & jQuery Change HTML (1) /* Fills a Halawai scheduling page form with the needed information so that it csn be submitted Author: Jan Stelovsky Copyright 2013 (open source under MIT license) */ // Filler of Halawai scheduling page according to the 'specs' function FormFiller(lecture, specs){ ...... // Initialize // fill/parse 'fields' from 'specs'; define 'date' this.specs = specs; //alert('specs=' + JSON.stringify(specs)); //debug var startDate = new Date(specs.starts); var times = specs.at.split('-'); var from = getTime(times[0]); var to = getTime(times[1]); var date; // generate fields according to specs var fields = [ {type: 'textarea', key:'description'}, {type: 'input', key:'sessiondate'}, {type: 'input', key:'sessiontitle', value:specs.title}, {type: 'select', key:'hour', value:from.hour}, {type: 'select', key:'minute', value:from.minutes}, {type: 'select', key:'ampm', value:from.suffix}, {type: 'select', key:'endhour', value:to.hour}, {type: 'select', key:'endminute', value:to.minutes}, {type: 'select', key:'endampm', value:to.suffix}, {type: 'select', key:'sizelimit', value:specs.size}, {type: 'textarea', key:'participants', value:specs.participants} ]; //alert('fields=' + JSON.stringify(fields)); //debug // once jQuery is loaded, fill the form addJQuery(fillIn); } JavaScript & jQuery Change HTML (2) // Loads jQuery; when ready call 'doIt' function addJQuery(doIt) { // Waits till jQuery is loaded; if not, initiates another 'waiting' call function waiting(){ if (countDown < 0) { alert("jQuery couldn't be loaded; sorry..."); } else if (typeof $ === 'undefined') { // retry in 1s countDown--; setTimeout(waiting, 1000); } else {doIt();} // jQuery is loaded: go on } var countDown = 10; // if jQuery isn't loaded, appends a <script> that loads it to <body> if (typeof $ === 'undefined') { var body = document.getElementsByTagName('body')[0]; var jQuery = document.createElement('script'); jQuery.setAttribute('src','http://code.jquery.com/jquery-1.10.1.min.js'); body.appendChild(jQuery); // wait till jQuery is loaded waiting(); } else {doIt();} // jQuery is loaded, go on } // Fills all widgets in the page's form with values from 'fields' function fillIn() { update(); $.each(fields, function(dummy, specs){ $(specs.type + '[name="' + specs.key + '"]').val(specs.value); }); //testDates(); } JavaScript & jQuery Change HTML (3) // Returns 2 digits string of 'number', i.e., prepends '0' to 0..9 function format(number) { return (number < 10 ? '0' : '') + number; } // Returns date of the 'lecture' ordinal // Assumes 2 lectures per week function lectureDate() { var monday = lecture % 2 == 0; // whether it starts on Monday var week = (lecture + (monday ? 0 : -1)) / 2; // 0-indexed //alert((lecture + 1) + '. lecture on ' + (monday ? 'Mon' : 'Wed') + ' of week ' + (week + 1)); var date = new Date(); date.setDate(startDate.getDate() + week * 7 + (monday ? 0 : 2)); return date; } //debug // Returns date in halawai-required format (mm-dd-yyy) function shortDate(date) { // note: while getMonth() is 0-indexed, getDate() is 1-indexed; go figure... return format(date.getMonth() + 1) + '-' + format(date.getDate()) + '-' + date.getFullYear(); } // Updates 'lecture'-dependent items of 'fields' // Note: further improvement would be a better lecture title function update() { fields[0].value = 'Lecture ' + (lecture + 1) + '.'; fields[1].value = shortDate(lectureDate()); //alert('fields=' + JSON.stringify(fields)); //debug } // Test of lectures and dates (visual) function testDates() { toLecture = 17; var dates = ''; for (; lecture <= toLecture; lecture++) { update(); dates += (lecture + 1) + '. lecture' + lectureDate().toDateString() + '\n'; } alert(dates); } // Splits time in hh:mm[am|pm] format into {hour, minutes, suffix} object // Note the use of regular expression function getTime(at) { var parts = at.split(':'); return {hour:Number(parts[0]), minutes:Number(/\d+/.exec(parts[1])[0]), suffix:/[ap]m/.exec(parts[1])[0]}; } Widgets Filled and/or Selected (1) Widgets Filled and/or Selected (2) Widgets Filled and/or Selected (3) Widgets Filled and/or Selected (4) Widgets Filled and/or Selected (5)