WME Form Filler

Use info from WME to automatically fill out related forms

当前为 2016-09-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WME Form Filler
  3. // @description Use info from WME to automatically fill out related forms
  4. // @namespace https://greasyfork.org/users/6605
  5. // @version 1.2
  6. // @match https://www.waze.com/*editor/*
  7. // @match https://beta.waze.com/*editor/*
  8. // @exclude https://www.waze.com/*user/editor/*
  9. // @author crazycaveman
  10. // @license MIT
  11. // @run-at document-end
  12. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NUIzRDdFNzAwRTlGMTFFNkIyRDZGMzNERUFDMUM1NDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NUIzRDdFNzEwRTlGMTFFNkIyRDZGMzNERUFDMUM1NDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1QjNEN0U2RTBFOUYxMUU2QjJENkYzM0RFQUMxQzU0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1QjNEN0U2RjBFOUYxMUU2QjJENkYzM0RFQUMxQzU0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtdrqLIAAAOCSURBVHjatJdLaBNBGMdn81ITQ2mLNqlIKInGkpSgFooPpKGHIlZPJqgoIvQivooPfFUsxYNVW62KiuItPah48RaUSlFEaDzEqgeV+sBUxag1rZa8Nv6nfMKaZpNssx34kdnN7sx/5nvNCtFolAUCAW8ymdwtCIKZMZZh6jQBjIIL4EkikWA+n485HI7/HtLFYjHH0NDQnXQ6XQkBbAbaGrAsHo+PNDc3T/lTF4lEVouiWKnX62O4DgBRpYn1YBuoAkuxwBGNRjNVAP7QZjKTu/4V7FJ59euAEWjlHtBg2//ZXEOq1WpzaUyWz690Ms5jUDhZcrqm0+UYyAPuKxyH2zqohgC++j/gmcJxRot5yGAwFBTAr9+AtWrHIqKMBYNBFgqFmlKpVLympuax1+udIiBD9reUON/nLMcTtFotC4fDBoR8H5JSVV1dXVdjY+OxbAEpUA8GSxRQC95KrkUe6jABzwnbkQ/OmUwmPSJQzBbAw+YL6C5hcr7y72TO2TTeI9AA7oErELNBp9NF5HzgEziogtnNZM6j4BfoAfNBB0XZu1wCuAkWggMKJ7sBXmbd4xmwH1wHW8FKut/Hi5NcFIiUu/cpFNCfQ0ACHKGdOM0LHbx/DE54HJWX92XDMEy7oKRFc9z7SXSBBZiYWSyWs0aj8QMvzVarVTYRJckP1GhLwN7J7Ugkhv1+f4/H48mbiPi+LOKeWmIUtIKP4AxFAiNn/F0oE/KX5wB3iQLSoAmsp3sPwW0q+3kF8HL8HFgVTqrJqvn8upf6XMyhYotRhsKnVqEAXj9ikuv9wEX9m/mKWy4fWA6eKhSwEdylfjVop/4PcEJJOebbOAz2KDgdC1kr7ATl1O+gUFwMXhcjgNvuG7g8TQdcAXZQ/xW4RLvxXk6ARmagBhqoTHJvFdhCUSLX2iVjttH7h8GEEh9wggEwiw4mfirRA2Sia2CnzHjV9HuLCs5FOpwmlERBGU3Om41+50nCzJ4nFCM0eTftlI/XAJ778WHCeDou5kg2SNtXLzkXPAAnKbWeymOCzWCM+nwRGT55S0sLs9lszG635xQgSCphivq9OU7LnQUcUJRMzts4T0JozOl0Ci6Xq6AJ+GHhPGUuNRo/jJRTGZbPAyiLIZzRJrBVZXi4bQY+TsfNZvMLWQEVFRVht9u9CQJaIcCk8uf5GArQVRxAh+Ue+ivAAAY7DIf3WTuXAAAAAElFTkSuQmCC
  13. // @grant none
  14. // ==/UserScript==
  15.  
  16. /*****************
  17. To-Do:
  18. *Allow manual user entries
  19. ******************/
  20.  
  21. var WMEFFName = GM_info.script.name;
  22. var WMEFFVersion = GM_info.script.version;
  23. var WMEFFIcon = GM_info.script.icon;
  24. var forms = {};
  25.  
  26. function formfiller_bootstrap()
  27. {
  28. formfiller_log("Running bootstrap");
  29. /*var bGreasemonkeyServiceDefined = false;
  30. try
  31. {
  32. if ("object" === typeof Components.interfaces.gmIGreasemonkeyService)
  33. {
  34. bGreasemonkeyServiceDefined = true;
  35. }
  36. }
  37. catch (err)
  38. {
  39. //Ignore
  40. }
  41. if ("undefined" === typeof unsafeWindow || ! bGreasemonkeyServiceDefined)
  42. {
  43. unsafeWindow = ( function ()
  44. {
  45. var dummyElem = document.createElement('p');
  46. dummyElem.setAttribute('onClick','return window;');
  47. return dummyElem.onclick ();
  48. } )();
  49. }*/
  50.  
  51. if (typeof Waze.app === 'undefined' || !window.Waze.map)
  52. {
  53. setTimeout(formfiller_bootstrap,500);
  54. return;
  55. }
  56. formfiller_log("Starting init");
  57. formfiller_init();
  58. }
  59.  
  60. function formfiller_init()
  61. {
  62. // Check document elements are ready
  63. var userInfo = document.getElementById("user-info");
  64. if (userInfo === null)
  65. {
  66. window.setTimeout(formfiller_init,500);
  67. return;
  68. }
  69. var userTabs = document.getElementById("user-tabs");
  70. if (userTabs === null)
  71. {
  72. window.setTimeout(formfiller_init,500);
  73. return;
  74. }
  75. var navTab = userInfo.getElementsByTagName("ul");
  76. if (navTab.length === 0)
  77. {
  78. window.setTimeout(formfiller_init,500);
  79. return;
  80. }
  81. if (typeof navTab[0] === "undefined")
  82. {
  83. window.setTimeout(formfiller_init,500);
  84. return;
  85. }
  86. var tabContent = userInfo.getElementsByTagName("div");
  87. if (tabContent.length === 0)
  88. {
  89. window.setTimeout(formfiller_init,500);
  90. return;
  91. }
  92. if (typeof tabContent[0] === "undefined")
  93. {
  94. window.setTimeout(formfiller_init,500);
  95. return;
  96. }
  97.  
  98. ff_addUserTab();
  99. ff_addFormBtn();
  100. var formFillerObserver = new MutationObserver(function(mutations) {
  101. mutations.forEach(function(mutation) {
  102. // Mutation is a NodeList and doesn't support forEach like an array
  103. for (var i = 0; i < mutation.addedNodes.length; i++) {
  104. var addedNode = mutation.addedNodes[i];
  105.  
  106. // Only fire up if it's a node
  107. if (addedNode.nodeType === Node.ELEMENT_NODE) {
  108. var selectionDiv = addedNode.querySelector('div.selection');
  109.  
  110. if (selectionDiv) {
  111. ff_addFormBtn();
  112. }
  113. }
  114. }
  115. });
  116. });
  117. formFillerObserver.observe(document.getElementById("edit-panel"), { childList: true, subtree: true });
  118. //Waze.selectionManager.events.register("selectionchanged", null, ff_addFormBtn);
  119. if (Waze.app.modeController) {
  120. Waze.app.modeController.model.bind('change:mode', function(model, modeId) {
  121. if (modeId == 0) {
  122. ff_addUserTab();
  123. }
  124. });
  125. }
  126. formfiller_log("Init done");
  127. return;
  128. }
  129.  
  130. //Shamelessly copied from https://gist.github.com/CalebGrove/c285a9510948b633aa47
  131. function abbrState(input, to)
  132. {
  133. var states = [
  134. ['Arizona', 'AZ'],
  135. ['Alabama', 'AL'],
  136. ['Alaska', 'AK'],
  137. ['Arizona', 'AZ'],
  138. ['Arkansas', 'AR'],
  139. ['California', 'CA'],
  140. ['Colorado', 'CO'],
  141. ['Connecticut', 'CT'],
  142. ['Delaware', 'DE'],
  143. ['Florida', 'FL'],
  144. ['Georgia', 'GA'],
  145. ['Hawaii', 'HI'],
  146. ['Idaho', 'ID'],
  147. ['Illinois', 'IL'],
  148. ['Indiana', 'IN'],
  149. ['Iowa', 'IA'],
  150. ['Kansas', 'KS'],
  151. ['Kentucky', 'KY'],
  152. ['Kentucky', 'KY'],
  153. ['Louisiana', 'LA'],
  154. ['Maine', 'ME'],
  155. ['Maryland', 'MD'],
  156. ['Massachusetts', 'MA'],
  157. ['Michigan', 'MI'],
  158. ['Minnesota', 'MN'],
  159. ['Mississippi', 'MS'],
  160. ['Missouri', 'MO'],
  161. ['Montana', 'MT'],
  162. ['Nebraska', 'NE'],
  163. ['Nevada', 'NV'],
  164. ['New Hampshire', 'NH'],
  165. ['New Jersey', 'NJ'],
  166. ['New Mexico', 'NM'],
  167. ['New York', 'NY'],
  168. ['North Carolina', 'NC'],
  169. ['North Dakota', 'ND'],
  170. ['Ohio', 'OH'],
  171. ['Oklahoma', 'OK'],
  172. ['Oregon', 'OR'],
  173. ['Pennsylvania', 'PA'],
  174. ['Rhode Island', 'RI'],
  175. ['South Carolina', 'SC'],
  176. ['South Dakota', 'SD'],
  177. ['Tennessee', 'TN'],
  178. ['Texas', 'TX'],
  179. ['Utah', 'UT'],
  180. ['Vermont', 'VT'],
  181. ['Virginia', 'VA'],
  182. ['Washington', 'WA'],
  183. ['West Virginia', 'WV'],
  184. ['Wisconsin', 'WI'],
  185. ['Wyoming', 'WY'],
  186. ];
  187.  
  188. if (to == 'abbr'){
  189. input = input.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
  190. for(i = 0; i < states.length; i++){
  191. if(states[i][0] == input){
  192. return(states[i][1]);
  193. }
  194. }
  195. } else if (to == 'name'){
  196. input = input.toUpperCase();
  197. for(i = 0; i < states.length; i++){
  198. if(states[i][1] == input){
  199. return(states[i][0]);
  200. }
  201. }
  202. }
  203. }
  204.  
  205. function formfiller_log(message)
  206. {
  207. if (typeof message === 'string')
  208. console.log('FormFiller: ' + message);
  209. else
  210. console.log('FormFiller: ', message);
  211. }
  212.  
  213. function ff_getStreetName(sel)
  214. {
  215. var streetName = "";
  216.  
  217. for (i=0; i<sel.length; i++)
  218. {
  219. var newStreet = Waze.model.streets.get(sel[i].model.attributes.primaryStreetID);
  220. if (typeof newStreet === "undefined" || newStreet.name === null)
  221. newStreet = "No Name";
  222. if (streetName === "")
  223. streetName = newStreet.name;
  224. else if (streetName != newStreet.name)
  225. streetName += ", "+newStreet.name;
  226. }
  227. return streetName;
  228. }
  229.  
  230. function ff_getState(sel)
  231. {
  232. var stateName = "";
  233.  
  234. for (i=0; i<sel.length; i++)
  235. {
  236. var cID = Waze.model.streets.get(sel[i].model.attributes.primaryStreetID).cityID;
  237. var sID = Waze.model.cities.get(cID).attributes.stateID;
  238. var newState = Waze.model.states.get(sID).name;
  239. if (stateName === "")
  240. stateName = newState;
  241. else if (stateName != newState)
  242. {
  243. stateName = "";
  244. break;
  245. }
  246. }
  247. return stateName;
  248. }
  249.  
  250. function ff_getCounty(sel)
  251. {
  252. var county = "";
  253. var center = Waze.map.center.clone().transform(Waze.map.projection.projCode,Waze.map.displayProjection.projCode);
  254. //formfiller_log("Getting county for "+center.lat.toString()+","+center.lon.toString());
  255. var xhr = new XMLHttpRequest();
  256. xhr.open("GET",'https://maps.googleapis.com/maps/api/geocode/json?latlng='+center.lat+','+center.lon,false);
  257. xhr.onload = function () {
  258. if (xhr.readyState === 4) {
  259. if (xhr.status === 200) {
  260. var response = JSON.parse(xhr.responseText);
  261. var addrComps = response.results[0].address_components;
  262. for (comp = 0; comp < addrComps.length; comp++)
  263. {
  264. if (addrComps[comp].types.indexOf("administrative_area_level_2") !== -1)
  265. {
  266. county = addrComps[comp].long_name;
  267. //formfiller_log("ff_getCounty: "+county);
  268. var countyIndex = (county.indexOf(" County") !== -1 ? county.indexOf(" County") : county.indexOf(" Parish"));
  269. if (countyIndex !== -1)
  270. county = county.slice(0,countyIndex);
  271. break;
  272. }
  273. }
  274. }
  275. }
  276. };
  277. xhr.send(null);
  278. return county;
  279.  
  280. //Async call. Figure this out!
  281. /*return $.getJSON('https://maps.googleapis.com/maps/api/geocode/json?latlng='+center.lat+','+center.lon, function(data) {
  282. if (data.status === "OK")
  283. {
  284. var addrComps = data.results[0].address_components;
  285. for (comp = 0; comp < addrComps.length; comp++)
  286. {
  287. if (addrComps[comp].types.indexOf("administrative_area_level_2") !== -1)
  288. {
  289. county = addrComps[comp].long_name;
  290. county = county.slice(0,county.indexOf(" County"));
  291. formfiller_log("JSON func "+county);
  292. break;
  293. }
  294. }
  295. }
  296. if (county === "")
  297. county = "Not found";
  298. formfiller_log("Got county");
  299. formfiller_log(county);
  300. return county;
  301. });*/
  302. }
  303.  
  304. function ff_closureActive(sel)
  305. {
  306. for (i=0; i<sel.length; i++)
  307. {
  308. if (sel[i].model.hasClosures())
  309. if (Waze.model.roadClosures.getByAttributes({segID: sel[i].model.attributes.id})[0].active)
  310. return true;
  311. }
  312. return false;
  313. }
  314.  
  315. function ff_getClosureInfo(seg)
  316. {
  317. var closureInfo = {
  318. direction: "",
  319. endDate: "",
  320. idFwd: "",
  321. idRev: "",
  322. reason: ""
  323. };
  324. var segID = seg.model.attributes.id;
  325. var closureList = Waze.model.roadClosures.getByAttributes({segID: segID,active: true});
  326. /*if (closureList.length > 2)
  327. return closureList;
  328.  
  329. if (closureList.length == 2 && closureList[0].forward != closureList[1].forward)
  330. closureInfo.direction = "Two-Way";
  331. else
  332. closureInfo.direction = "One-Way";*/
  333.  
  334. for (i=0; i<closureList.length; i++)
  335. {
  336. if (closureList[i].active === true)
  337. {
  338. if (closureInfo.endDate === "")
  339. {
  340. closureInfo.endDate = closureList[i].endDate;
  341. }
  342. else if (closureInfo.endDate > closureList[i].endDate)
  343. {
  344. closureInfo.endDate = closureList[i].endDate;
  345. }
  346. if (closureList[i].forward === true)
  347. {
  348. closureInfo.idFwd = closureList[i].id;
  349. }
  350. else
  351. {
  352. closureInfo.idRev = closureList[i].id;
  353. }
  354. if (closureInfo.reason === "")
  355. {
  356. closureInfo.reason = closureList[i].reason;
  357. }
  358. }
  359. }
  360.  
  361. if (closureInfo.idFwd !== "" && closureInfo.idRev !== "")
  362. closureInfo.direction = "Two-Way";
  363. else
  364. closureInfo.direction = "One-Way";
  365.  
  366. return closureInfo;
  367. }
  368.  
  369. function ff_createPermalink(selection)
  370. {
  371. //https://www.waze.com/editor/?env=usa&lon=-79.79248&lat=32.86150&layers=12709&zoom=5&mode=0&mapProblemFilter=1&mapUpdateRequestFilter=0&venueFilter=0&segments=504534141
  372. //https://www.waze.com/editor/?env=usa&lon=-79.79248&lat=32.86150&layers=12709&zoom=5&mode=0&mapProblemFilter=1&mapUpdateRequestFilter=0&venueFilter=0&venues=183632201.1836387542.3102948
  373. var permalink = "https://www.waze.com/editor/?", segIDs = [];
  374. var latLon = Waze.map.center.clone().transform(Waze.map.projection.projCode,Waze.map.displayProjection.projCode);
  375. var lat = latLon.lat, lon = latLon.lon;
  376. var env = Waze.location.code;
  377. var type = "segments";
  378. var zoom = Waze.map.zoom;
  379.  
  380. /*if (zoom == 3)
  381. alert('Current zoom level (3) will not select street segments! If your selection includes street segments, please increase the zoom level');
  382. else if (zoom == 2)
  383. alert ('Current zoom level (2) will only select PS+ segments! If you have any other segment type selected, please increase the zoom level');
  384. else if (zoom <= 1)
  385. {
  386. alert ('Current zoom level ('+ zoom.toString() +') will not select any segments! Increase the zoom level before submitting!');
  387. return;
  388. }*/
  389.  
  390. //To get lat and long centered on segment
  391. if (selection.length == 1)
  392. {
  393. latLon = selection[0].model.getCenter().clone();
  394. latLon.transform(Waze.map.projection.projCode,Waze.map.displayProjection.projCode);
  395. lat = latLon.x;
  396. lon = latLon.y;
  397. }
  398.  
  399. var maxzoom = 2,
  400. zoomToRoadType = Waze.Config.segments.zoomToRoadType;
  401. for (i=0; i<selection.length; i++)
  402. {
  403. var segment = selection[i].model;
  404. if (segment.type != "segment")
  405. continue;
  406. segIDs.push(segment.attributes.id);
  407. if (zoomToRoadType[zoom] !== -1 && zoomToRoadType[zoom].indexOf(segment.attributes.roadType) === -1)
  408. {
  409. alert("This zoom level ("+ zoom.toString() +") cannot be used for this road type! Please increase your zoom:\n"+
  410. "Streets: 4+\nOther drivable and Non-drivable: 3+\nHighways and PS: 2+");
  411. formfiller_log("Zoom level not correct for segment: "+ zoom.toString() +" "+ segment.attributes.roadType.toString());
  412. return;
  413. }
  414. }
  415. permalink += "env="+env+"&lon="+lon+"&lat="+lat+"&zoom="+zoom.toString()+"&"+type+"="+segIDs.join();
  416. return permalink;
  417. }
  418.  
  419. function ff_createFormLink(formIndx)
  420. {
  421. var selection = Waze.selectionManager.selectedItems;
  422. var formInfo = {};
  423. var formDt = forms[formIndx];
  424. var formLink = formDt.url;
  425. if (selection.length === 0 || selection[0].model.type != "segment")
  426. {
  427. formfiller_log("No segments selected.");
  428. return;
  429. }
  430.  
  431. formInfo.username = encodeURIComponent(Waze.loginManager.user.userName);
  432. formInfo.streetname = encodeURIComponent(ff_getStreetName(selection));
  433. formInfo.permalink = encodeURIComponent(ff_createPermalink(selection));
  434. if (formInfo.permalink === "undefined")
  435. {
  436. formfiller_log("No permalink generated");
  437. return;
  438. }
  439. formInfo.state = abbrState(ff_getState(selection),"abbr"); //Abbreviation
  440. formInfo.county = ff_getCounty(selection);
  441.  
  442. formInfo.status = "REPORTED";
  443. formInfo.direction = "Two-Way";
  444. formInfo.reason = document.getElementById("ff-closure-reason").value;
  445. formInfo.endDate = document.getElementById("ff-closure-endDate").value +"+"+ document.getElementById("ff-closure-endTime").value;
  446. if (ff_closureActive(selection))
  447. {
  448. formInfo.status = "CLOSED";
  449. var closureInfo = ff_getClosureInfo(selection[0]);
  450. formInfo.direction = closureInfo.direction;
  451. formInfo.reason = encodeURIComponent(closureInfo.reason);
  452. formInfo.endDate = encodeURIComponent(closureInfo.endDate);
  453. }
  454. formInfo.notes = "Form+filled+by+"+WMEFFName+"+v"+WMEFFVersion;
  455.  
  456. //Need to do this part better, works for now
  457. formLink += "?entry."+formDt.username+"="+formInfo.username;
  458. formLink += "&entry."+formDt.streetname+"="+formInfo.streetname;
  459. formLink += "&entry."+formDt.permalink+"="+formInfo.permalink;
  460. formLink += "&entry."+formDt.state+"="+formInfo.state;
  461. formLink += "&entry."+formDt.county+"="+formInfo.county;
  462. formLink += "&entry."+formDt.status+"="+formInfo.status;
  463. formLink += "&entry."+formDt.direction+"="+formInfo.direction;
  464. formLink += "&entry."+formDt.reason+"="+formInfo.reason;
  465. formLink += "&entry."+formDt.endDate+"="+formInfo.endDate;
  466. formLink += "&entry."+formDt.notes+"="+formInfo.notes;
  467. formfiller_log(formLink);
  468. return formLink;
  469. }
  470.  
  471. function ff_addFormBtn()
  472. {
  473. var selection = Waze.selectionManager.selectedItems;
  474. if (selection.length === 0 || selection[0].model.type != "segment")
  475. {
  476. //formfiller_log("No segments selected.");
  477. return;
  478. }
  479. if (document.getElementById("formfillerDiv"))
  480. {
  481. //formfiller_log("Div already created");
  482. return;
  483. }
  484.  
  485. forms = [
  486. {
  487. //https://docs.google.com/forms/d/e/1FAIpQLScY_5WKyYTqvH1fdiBThqLO4DRIzFzgdBtBexw5-iKL_LOzBw/viewform?entry.1553765347=username&entry.1264424583=CLOSED&entry.1811077109=permalink&entry.792657790=Two-Way&entry.345142186=reason&entry.1102521735=2016-09-20+03:00&entry.2015424420=street+name&entry.1547375393=from+street&entry.1335391716=to+street&entry.1867193205=SC&entry.1714138473=county&entry.1803937317=source&entry.1648634142=notes
  488. name: 'USA Weather related closures',
  489. url: 'https://docs.google.com/forms/d/e/1FAIpQLScY_5WKyYTqvH1fdiBThqLO4DRIzFzgdBtBexw5-iKL_LOzBw/viewform',
  490. username: '1553765347',
  491. status: '1264424583',
  492. permalink: '1811077109',
  493. direction: '792657790',
  494. reason: '345142186',
  495. endDate: '1102521735',
  496. streetname: '2015424420',
  497. fromStreet: '1547375393',
  498. toStreet: '1335391716',
  499. state: '1867193205',
  500. county: '1714138473',
  501. source: '1803937317',
  502. notes: '1648634142',
  503. },
  504. {
  505. //https://docs.google.com/forms/d/e/1FAIpQLSeRVbj9DNsbP4GOeYr_6_2KjgS2TGi3f_Z5d9FVX1MmqMrZDQ/viewform?entry.1553765347=username&entry.1264424583=REPORTED&entry.1811077109=permalink&entry.792657790=Two-Way&entry.345142186=reason&entry.1102521735=2016-09-12+19:15&entry.2015424420=streetname&entry.1547375393=closure_from&entry.1335391716=closure_to&entry.1867193205=SC&entry.1714138473=county&entry.1803937317=source&entry.1648634142=notes
  506. name: 'Testing form weather closures',
  507. url: 'https://docs.google.com/forms/d/e/1FAIpQLSeRVbj9DNsbP4GOeYr_6_2KjgS2TGi3f_Z5d9FVX1MmqMrZDQ/viewform',
  508. username: '1553765347',
  509. status: '1264424583',
  510. permalink: '1811077109',
  511. direction: '792657790',
  512. reason: '345142186',
  513. endDate: '1102521735',
  514. streetname: '2015424420',
  515. fromStreet: '1547375393',
  516. toStreet: '1335391716',
  517. state: '1867193205',
  518. county: '1714138473',
  519. source: '1803937317',
  520. notes: '1648634142',
  521. },
  522. /*{
  523. //https://docs.google.com/forms/d/1uXS-Z0-5aJbOrzcZtT8CM-qpUNMonU1iH9NWiPQ5w2o/viewform?entry.728513350=HavanaDay&entry.167700229=REPORTED&entry.1331253387=http://&entry.1363270254=Two-Way&entry.1681433373=Reason+Text&entry.12817715=2016-06-01+12:00&entry.1761873222=CLOSED+STREET+TEXT&entry.798060845=CLOSURE+FROM+TEXT&entry.1536374235=CLOSURE+TO+TEXT&entry.1030293134=NC&entry.1012282273=County+Text&entry.1223225270=Source+Text&entry.150335656=Notes+Text
  524. name: 'Old USA Weather related closures',
  525. url: 'https://docs.google.com/forms/d/1uXS-Z0-5aJbOrzcZtT8CM-qpUNMonU1iH9NWiPQ5w2o/viewform',
  526. username: '728513350',
  527. streetname: '1761873222',
  528. permalink: '1331253387',
  529. state: '1030293134',
  530. county: '1012282273',
  531. status: '167700229',
  532. direction: '1363270254',
  533. reason: '1681433373',
  534. endDate: '12817715',
  535. }*/
  536. ];
  537.  
  538. var ffDiv = document.createElement("div"),
  539. ffMnu = document.createElement("select"),
  540. ffBtn = document.createElement("button");
  541. ffDiv.id = "formfillerDiv";
  542. var formWindowName = "WME Form Filler result",
  543. formWindowSpecs = "resizable=1,menubar=0,scrollbars=1,status=0,toolbar=0";
  544. var editPanel, selElem, formLink;
  545. editPanel = document.getElementById("edit-panel");
  546. selElem = editPanel.getElementsByClassName("selection");
  547.  
  548. for (i=0; i<forms.length; i++)
  549. {
  550. ffMnu.options.add(new Option(forms[i].name,i));
  551. }
  552. ffBtn.innerHTML = "Go to Form";
  553. ffBtn.onclick = function()
  554. {
  555. //alert(ffMnu.options[ffMnu.selectedIndex].value+": "+forms[ffMnu.options[ffMnu.selectedIndex].value].name);
  556. ff_saveSettings();
  557. formLink = ff_createFormLink(ffMnu.options[ffMnu.selectedIndex].value);
  558. if (typeof formLink === "undefined")
  559. return;
  560.  
  561. if ($("#ff-open-in-tab").prop("checked"))
  562. window.open(formLink,"_blank");
  563. else
  564. window.open(formLink,formWindowName,formWindowSpecs);
  565. };
  566. ffDiv.appendChild(ffMnu);
  567. ffDiv.appendChild(ffBtn);
  568. selElem[0].appendChild(ffDiv);
  569.  
  570. return;
  571. }
  572.  
  573. function ff_loadSettings()
  574. {
  575. var todayDate = new Date();
  576. var today = todayDate.getFullYear() +"-"+ (todayDate.getMonth()+1<10 ? "0"+(todayDate.getMonth()+1) : todayDate.getMonth()+1) +"-"+ todayDate.getDate();
  577.  
  578. var ffOpenInTab = localStorage.getItem("ff-open-in-tab");
  579. if (ffOpenInTab === "1")
  580. $("#ff-open-in-tab").trigger("click");
  581. var ffClosureReason = localStorage.getItem("ff-closure-reason");
  582. if (ffClosureReason !== null)
  583. $("#ff-closure-reason").val(ffClosureReason);
  584. var ffClosureEndDate = localStorage.getItem("ff-closure-endDate");
  585. if (ffClosureEndDate !== null && ffClosureEndDate !== "" && ffClosureEndDate >= today)
  586. $("#ff-closure-endDate").val(ffClosureEndDate);
  587. else
  588. {
  589. today = todayDate.getFullYear() +"-"+ (todayDate.getMonth()+1<10 ? "0"+(todayDate.getMonth()+1) : todayDate.getMonth()+1) +"-"+ (todayDate.getDate()+3);
  590. $("#ff-closure-endDate").val(today.toString("yyyy-MM-dd"));
  591. }
  592. var ffClosureEndTime = localStorage.getItem("ff-closure-endTime");
  593. if (ffClosureEndTime !== null && ffClosureEndTime !== "")
  594. $("#ff-closure-endTime").val(ffClosureEndTime);
  595. //formfiller_log("Settings loaded");
  596. return;
  597. }
  598.  
  599. function ff_saveSettings()
  600. {
  601. /*formfiller_log("Saving settings:\n"+$("#ff-open-in-tab").prop("checked")+
  602. "\n"+$("#ff-closure-reason").val()+
  603. "\n"+$("#ff-closure-endDate").val()+
  604. "\n"+$("#ff-closure-endTime").val());*/
  605. if ($("#ff-open-in-tab").prop("checked"))
  606. localStorage.setItem("ff-open-in-tab", "1");
  607. else
  608. localStorage.setItem("ff-open-in-tab", "0");
  609. localStorage.setItem("ff-closure-reason", $("#ff-closure-reason").val());
  610. localStorage.setItem("ff-closure-endDate", $("#ff-closure-endDate").val());
  611. localStorage.setItem("ff-closure-endTime", $("#ff-closure-endTime").val());
  612. //formfiller_log("Settings saved");
  613. return;
  614. }
  615.  
  616. function ff_addUserTab()
  617. {
  618. var userInfo = document.getElementById("user-info"),
  619. userTabs = document.getElementById("user-tabs"),
  620. navTabs = userTabs.getElementsByClassName("nav-tabs"),
  621. tabContent = userInfo.getElementsByClassName("tab-content");
  622. var ffTab = document.createElement("li"),
  623. ffPanel = document.createElement("div"),
  624. ffReason = document.createElement("div"),
  625. ffEndDate = document.createElement("div"),
  626. ffNewTabBox = document.createElement("input"),
  627. ffNewTabLabel = document.createElement("label"),
  628. ffTabInfo = document.createElement("div");
  629.  
  630. ffTab.innerHTML = '<a title="Form Filler" href="#sidepanel-formfill" data-toggle="tab"><img class="fa" src="'+WMEFFIcon+'" width="15px" /></a>';
  631. ffPanel.id = "sidepanel-formfill";
  632. ffPanel.className = "tab-pane";
  633.  
  634. ffTabInfo.innerHTML = '<b>'+ WMEFFName +'</b> v'+ WMEFFVersion;
  635.  
  636. ffNewTabBox.id = "ff-open-in-tab";
  637. ffNewTabBox.type = "checkbox";
  638. ffNewTabBox.name = "ff_open_tab";
  639.  
  640. ffNewTabLabel.innerHTML = "Open form in new tab";
  641. ffNewTabLabel.for = "ff_open_tab";
  642.  
  643. ffReason.className = "form-group";
  644. ffReason.innerHTML = '<label class="control-label" for="ff_closure_reason">Closures reason:</label><div class="controls"><input id="ff-closure-reason" class="form-control" type="text" name="ff_closure_reason"></div>';
  645.  
  646. ffEndDate.className = "form-group";
  647. ffEndDate.innerHTML = '<label class="control-label" for="ff_closure_endDate">Closures end:</label><div class="controls"><div class="date date-input-group input-group pull-left" style="width: 62%"><input id="ff-closure-endDate" class="form-control end-date" type="text" name="ff_closure_endDate"><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div><div class="bootstrap-timepicker input-group style="width: 38%""><input id="ff-closure-endTime" class="end-time form-control" type="text" name="ff_closure_endTime"><span class="input-group-addon"><i class="fa fa-clock-o"></i></span></div></div>';
  648.  
  649. ffPanel.appendChild(ffTabInfo);
  650. ffPanel.appendChild(ffNewTabBox);
  651. ffPanel.appendChild(ffNewTabLabel);
  652. ffPanel.appendChild(ffReason);
  653. ffPanel.appendChild(ffEndDate);
  654. navTabs[0].appendChild(ffTab);
  655. tabContent[0].appendChild(ffPanel);
  656.  
  657. if (typeof $.fn.datepicker !== "undefined") {
  658. $("#ff-closure-endDate").datepicker({format:"yyyy-mm-dd", todayHighlight:true, autoclose:true});
  659. } else {
  660. if (typeof $.fn.daterangepicker !== "undefined") {
  661. $("#ff-closure-endDate").daterangepicker({singleDatePicker:true, locale:{format:"YYYY-MM-DD"}});
  662. }
  663. }
  664.  
  665. if (typeof $.fn.timepicker !== "undefined") {
  666. $("#ff-closure-endTime").timepicker({template:false,defaultTime:"00:00",showMeridian:false});
  667. }
  668.  
  669. ff_loadSettings();
  670. $("#ff-closure-reason").change(function() {ff_saveSettings();});
  671. $("#ff-closure-endDate").change(function() {ff_saveSettings();});
  672. $("#ff-closure-endTime").change(function() {ff_saveSettings();});
  673. $("#ff-open-in-tab").click(function() {ff_saveSettings();});
  674. }
  675.  
  676. setTimeout(formfiller_bootstrap,2000);
  677.