Chronicles of a build – qTranslate Headway Theme block 04

This post picks up from a previous one and the code can be found on GitHub.

Appending the proper way

In the previous post I was able to output an alert whenever the block options panel for the block was shown and now it’s time to append a less trivial and useful script to the page.
As detailed in this StackOverflow post I can’t simply echo jQuery code the page because code will be executed and the script will then be deleted.
In the same post comes a solution and I’ve encapsulated it in my code in qtblock\Block::appendScript

protected function appendScript($src)
{
    $out = '';
    $out .= '<script type="text/javascript">';
    $out .= 'var script   = document.createElement("script");
    script.type  = "text/javascript";
    script.src  = "' . $src . '"
    document.body.appendChild(script)';
    $out .= '</script>';
    echo $out;
}

the function is a simple parametrized wrapping of the one proposed in the post but what’s relevant is that it’s ehcoing vanilla javascript code to the page to permanently append a script to the page.

The script

The script that will act upon the user choice of a display mode is, again, not very complicated and is pasted here in its non-minified version

/*global jQuery:false, document:false, console:false*/
jQuery(document).ready(function($) {
    'use strict';

    function maybeHideOptions(current) {
        var selected = current.find('option:selected').text();
        if (selected === '') {
            // if no option selected then do nothing
            return;
        }
        // get all actors and targets
        var parent = $('#sub-tab-settings-content').has(current);
        var layoutModeSelector = parent.find('#input-layout-mode');
        var horizontalSpacingSelector = parent.find('#input-horizontal-spacing');
        var verticalSpacingSelector = parent.find('#input-vertical-spacing');
        // if the selected option is drop-down then
        // hide non relevant options
        if (selected === 'Dropdown') {
            // hide all the other selectors
            layoutModeSelector.hide();
            horizontalSpacingSelector.hide();
            verticalSpacingSelector.hide();
        } else {
            // show the other selectors
            layoutModeSelector.show();
            horizontalSpacingSelector.show();
            verticalSpacingSelector.show();
        }
    }
    // run the script on each select
    jQuery('.panel-block-type-qtblock #input-display-mode select').each(
        function() {
            maybeHideOptions($(this));
            // when selected option change make a check and
            // and hide or show options
            $(this).change(function() {
                maybeHideOptions($(this));
            });
        });
});

it will show or hide options that make sense according to the current display mode.

Assembling it all

The qtblock\Block class is the glue of the whole thing and now reads like this (I’m pasting the relevant part alone)

<?php
namespace qtblock;

class Block extends \HeadwayBlockAPI
{

    public $id = 'qtblock';
    public $name = 'qTranslate language chooser';
    public $options_class = '\qtblock\BlockOptions';
    public $description = 'An Headway block to display qTranslate plugin language chooser on the page.';

    public function init()
    {
        add_action('headway_block_options_' . $this->id, array($this,'printVisualEditorScripts'));
    }

    public function printVisualEditorScripts()
    {
        // load minified script version by default
        $postfix = '.min';
        if (defined('SCRIPT_DEBUG')) {
            // load non minified script version if script debug is active
            $postfix = '';
        }
        $src = QTBLOCK_BLOCK_URL . "assets/js/qtblock_visual_editor$postfix.js";
        $this->appendScript($src);
    }

    protected function appendScript($src)
    {
        $out = '';
        $out .= '<script type="text/javascript">';
        $out .= 'var script   = document.createElement("script");
        script.type  = "text/javascript";
        script.src  = "' . $src . '"
        document.body.appendChild(script)';
        $out .= '</script>';
        echo $out;
    }

    ...

The flow is the same the methods are defined and someone familiar with WordPress code can easily find its way there.

Final result

The final result is not incredible but, sticking to the “less is more” motto, I feel the possibility to hide or show relevant block options makes the block usage tidier and more streamlined. I could not find references to anything like that googling but did like the idea.