Pushing Podio

Fun Experiments pushing Citrix Podio to the limit so you can get more done.
... with a little help from GlobiFlow, ProcFu, and other friends ...

Creating new Podio Items and Navigating there Automatically

- Posted in Uncategorized by

In the GlobiFlow and Podio forums it has been requested often to be able to create an item, and then automatically navigate to the newly created item.

This is possible if you are using the Podio SuperMenu Chrome Extension with an HTML widget from ProcFu.

Here is the example we're going to set up in this post:

video

The Podio Setup

Before we get into the Podio setup, log into your ProcFu account and navigate to the Configure page (Conf on the menu). Then create a new HTML widget, and get the ID of the new widget. We'll need this.

In Podio, I'm just using pretty standard Projects and Deliverables apps, where Deliverables has a relationship field to Projects. Nothing complex here.

All we need to do is add a new calculation field to the Projects app to show the "Create Deliverable" button. The calculation should return a markdown link to your PF widget, using the SuperMenu addition of "#globiflowiframe:native".

The "native" option is new to SuperMenu. If added, SuperMenu will not create an iframe with the content, but will side-load the HTML content into a div directly into the Podio UI.

The calculation field should look like this:

"[Create Deliverable](https://procfuwidgets.b-cdn.net/html/YOUR_WIDGET_ID?item="+@Unique ID+"#globiflowiframe:native)";

Note that we're sending the app_item_id and not the item_id here, because Podio calculation fields do not have access to the actual item_id. If you wanted to save on actions in PF, you could use a GlobiFlow flow to populate the actual item_id and send it instead. But for this example, the app_item_id is enough.

If someone doesn't have the SuperMenu installed, they at least will see a link to the PF widget which will still perform the required action.

The ProcFu Widget

The full source for the widget can be found here.

Let's go through some of the more interesting parts in detail to help explain.

This is just the configuration for our apps. Replace the ID's with the Projects and Deliverables app ids in your own setup:

// config
$projects_app_id = 123456;
$deliverables_app_id = 234567;

Here we are decoding the payload from the link (which includes the app_item_id from Podio):

$data = @json_decode($pf_payload, true);

This is just validating our payload to make sure we have everything we need:

if ( ! isset($data['widget_id']) ) return "Must be called from PF widget";
if ( ! isset($data['GET']['item']) ) return "Missing item id";

And here we set up some variables and set the session.

$app_item_id = intval($data['GET']['item']);
$widget_id = $data['widget_id'];
pf_session_start(md5($app_item_id));
$html = '';

The below sets up the HTML for the button:

$html .= '<style>';
$html .= '.mybtn { color: white !important; background: red; padding: 2px 5px; cursor: pointer; text-decoration: none; font-weight: bold; }';
$html .= '.mybtn:hover { background: green; }';
$html .= '</style>';

$html .= '<div id="mypfdiv"><a href="" onclick="dopfaction(); return false;" class="mybtn">Create Deliverable</a></div>';
$html .= '<script>var widgetdirect = "https://procfu.com/widgets/html/'.$widget_id.'?item='.$app_item_id.'&go=1"; </script>';

$html .= <<<'EOF'
    <script>
        function dopfaction() {
            el = document.getElementById("mypfdiv");
            el.innerHTML = '<img src="https://secure.globiflow.com/images/progressbar.gif">';
            var request = new XMLHttpRequest();
            request.open('GET', widgetdirect, true);
            request.send(null);
            request.onload = function() {
                if (request.status >= 200 && request.status < 400) {
                    el.innerHTML = request.responseText;
                    var arr = el.getElementsByTagName('script');
                    for (var n = 0; n < arr.length; n++) { eval(arr[n].innerHTML) } //run script inside div
                }
            };
        }
    </script>
EOF;

Basically it creates a div with the button (and a little bit of styling), and a javascript function to handle the click event on the button.

What the javascript function does, is first replace the button with a loader animated gif to give the user some feedback, and then fetches the PF widget content again, but with an added "go" URL parameter (which we'll check for just now).

It's also important to note that when the function replaces the div content with whatever the widget returns, it goes through the return and executes any script tags, which we need to do the redirection.

But, we're not returning this html yet. First we need to check for the "go" parameter and do the real work required:

if ( isset($data['GET']['go']) ) {
    $item = @json_decode(call_pf_script("podio_app_item_get_raw.pf", ["app_id" => $projects_app_id, "app_item_id" => $app_item_id]), true);
    $podio_item_id = $item['item_id'];
    $values = json_encode([
        "title" => "New Deliverable",
        "project" => $podio_item_id,
        "status" => "New"
    ]);
    $new_item_id = call_pf_script("podio_item_create.pf", ["app_id" => $deliverables_app_id, "fields" => $values, "hook" => "true", "silent" => "true"]);
    return '<script>document.location.href="https://podio.com/x/y/item/'.$new_item_id.'";</script>';
}

Because we chose to use the app_item_id instead of the item_id (which is not available in Podio calculations), we need to first fetch the item from Podio using the app_id and app_item_id. For this example, we only need to do this to get the real item_id, but in your case, you may need some of the Project's data to create your new deliverable.

The only thing we're pre-filling on our new deliverable is the name as "New Deliverable", the related Project (where we clicked the button), and the status.

Once created, we return a tiny piece of javascript to just redirect to the new Deliverable that we created.

If we go to this point in the code, we can assume that nothing was clicked, and we simply return the html for the button we generated earlier:

return $html;

The Result

And that's all there's to it. Every project will now have a button to "Create Deliverable" which will create a new deliverable with some initial values, and then take you to the new deliverable.

video

Comments