Jeffrey Coleman
Jeffrey Coleman

Reputation: 31

Chrome Extension - Modify Google Calendar Event UI to accept Extended Properties via input field

I'm looking to create a Chrome Extension that simply adds some functionality when creating new events. I would like to insert an extra field into the 'create event' view that will accept new meta data to be stored, ie: project name, client name, etc etc.

So far I have managed to create the extension, setup a popup view, insert some new html into the core calendar view via contentscripts.js, but am unable to figure out the following:

1) Add new text input field to event creation view
2) Save text from above field as an 'Extended Property' as per Google API (https://developers.google.com/google-apps/calendar/extended-properties) for later retrieval

Does anyone have any advice or resources around trying to accomplish such a task?

Here is my Manifest.json file:

{
  "name": "DoviChrome",
  "version": "0.1.1",
  "manifest_version":2,
  "description": "DoviChrome",
  "background": {
    "persistent": false,
    "scripts": ["background.html"]
  },
  "icons": { "16": "icon.png",
           "48": "icon.png",
          "128": "icon.png" 
  },
  "browser_action": {
    "default_icon": {                    // optional
      "16": "icon2.png",           // optional
      "24": "icon2.png",           // optional
      "32": "icon2.png"            // optional
    },
    "default_title": "DoviChrome",      // optional; shown in tooltip
    "default_popup": "popup.html"        // optional
  },
  "permissions": [
    "notifications",
    "identity",
    "storage",
    "activeTab"
  ],
  "content_scripts": [
    {
      // Change 'matches' attribute to load content
      // script only in pages you want to.
      "matches": ["*://calendar.google.com/calendar/render"],
      "css": ["css/style.css"],
      "js": ["js/lib/jquery-3.1.1.min.js", "js/lib/angular1.6.1.min.js", "contentscript.js"],
      "run_at":     "document_idle",
      "all_frames": false
    }
  ],
  "web_accessible_resources": [ "img/*", "node_modules/*","*.png","https://www.parsecdn.com/js/parse-latest.js"],
}

...and here is what I am using in my contentscript.js to insert some other functions in the main calendar view.

$(document).ready(function() {
    console.log("contentscript.js loaded")
    var iconURL = chrome.extension.getURL("icon.png");
    console.log("Injecting UI...")
    $("#calcontent #vr-nav").before("<div class='new-menu'>" +
        "<div class='my-logo inline'><img src='" + iconURL + "'/></div>" +
        "<div class='quick-report'>Create Timesheet</div>" +
        "<div class='quick-settings'>Settings</div>" +
        "</div>"
    )
    $('.quick-report').on("click",function(){
    	console.log("clicked reports")
    })
    $('div.quick-settings').on("click",function(){
	console.log("Clicked settings")
    })
});

Upvotes: 1

Views: 2152

Answers (1)

Yascob
Yascob

Reputation: 11

Okay, I'm going to start off by assuming the following things:

  1. What you mean by the "event creation view" is what the view changes to when you click the create button.
  2. You want this to be incorporated into the contentscript.js

If both of those are true I might be able to help you to some extent. However I can only help you with the first half of the problem due to limited knowledge of the API.

First off, for your settings, I would look into using an option page. It is cleaner and all you need to do very little to change your manifest. Most of the time the chrome.storage API is used for saving and getting your settings. The page in the google developer docs is here.

Second, you will have to do a lot of looking at the Google Calendar page's HTML to extend their code more naturally. Here is the easiest way that I can think of modifying your contentscript.js to make it extend the event creation form:

$(document).ready(function() {
      console.log("contentscript.js loaded")
      console.log("Injecting UI...")

      // On clicking the button to navigate to event view
      $("div.goog-inline-block.goog-imageless-button.goog-imageless-button-collapse-right").click(function() {

          // if the view has been made visible (you may need to add a time delay to make it work)
          if ($("div#coverinner").is(":visible")) {

            // selects an appropriate place in the create event view to add custom options
            var target = $("div.ep-dp-dt tbody tr#:3c.reminders-row").next().next().next()

            //Add a new option. It will be added at the FRONT of the new options.
            target.after(textInput("Test", 1))

            // More options can be added in a similar style
          }

        }
      });

    // This is just an example of a text input generator. I made it by basically copy pasting the html I found in google then modifying it appropriately.
    function textInput(name, rows) {

      var text = $([
        "<tr id='" + name + "'>",
        "	<th class='ep-dp-dt-th'>",
        "		<label>" + name + "</label>",
        "	</th>",
        "	<td class='ep-dp-dt-td'>",
        "		<div class='ep-dp-" + name + "'>",
        "			<div class='ui-sch'>",
        "				<textarea class='textinput' style='overflow: hidden; resize: vertical;' rows='" + rows + "'>",
        "				</textarea>",
        "			</div>",
        "		</div>",
        "	</td>",
        "</tr>"
      ].join("\n"));

      return text
    }

You can extend your script by doing the following Have your custom values temporarily store themselves somewhere (maybe as a global variable in the document) and maybe update them on changing of the value. Then on or after clicking the submit button, finding out the calendar and event id and update from the stored value.

However, if you don't mind trying a different method, the best way I can think of doing it is overriding the create event button to navigate to a custom event creation view made by you. From there you submit everything through the API. This would definitely leave less up to chance especially if google changes something interface-wise.

Also using this method you could have the user navigate to that page (probably by clicking the extension's icon which can be handled by a background.js file) without having to go to the official website itself since most of the work would be done by the API.

Anyways, this is just how I would tackle a problem like this, it may not be the best nor the greatest method but I hope it helps.

Upvotes: 1

Related Questions