View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFPROP:Proposal Zone Template}
{composition-setup}

{zone-data:component-name}
ZendX_JQuery_View_Helper_JQuery
{zone-data}

{zone-data:proposer-list}
[Benjamin Eberlei|mailto:benny@whitewashing.de]
{zone-data}

{zone-data:liaison}
[~matthew]
{zone-data}

{zone-data:revision}
1.0 - 14 July 2008: Initial Draft.
1.1 - 16 August 2008: Final Review Version
{zone-data}

{zone-data:overview}
The jQuery helper allows to simplify the setup of an enviroment that uses jQuery as Javascript library and provides the possibilty to construct a wide range of ajax calls.
{zone-data}

{zone-data:references}
* [Zend_Dojo_View_Helper|http://framework.zend.com/wiki/display/ZFPROP/Zend_View_Helper_Dojo]
* [jQuery|http://www.jquery.com]
* [CakePHP Ajax Helper|http://book.cakephp.org/view/208/ajax]
* [symfony Ajax Helper|http://www.symfony-project.org/book/1_1/11-Ajax-Integration]
{zone-data}

{zone-data:requirements}
* *MUST* be a single view helper with multiple methods
* *MUST* be able to render as string
* *MUST* support direct deployment via CDN (Google Ajax Library API), using specified version
* *MUST* support using local install, via path
* *SHOULD* default to CDN if no path specified
* *MUST* have method for requiring plugin files (js and css)
* *SHOULD* be base component for further jQuery Plugins that use its infrastructure methods

The jQuery Ajax Helper should provide methods to build Ajax Requests using the jQuery Helper.

* *MUST* integrate with jQuery Library to append requests to onLoad Event.
* *MUST* add value to simply using jQuery Ajax Requests (Auto building most wanted callbacks)
* *SHOULD* allow inlining Javascript, but *MUST* default to stack Javascript to onLoad
{zone-data}

{zone-data:dependencies}
* Zend_View_Exception
* Zend_Json
{zone-data}

{zone-data:operation}
Theory of Operation:
Using the jQuery Helper enables one to setup an jQuery enviroment in a ZF MVC implementation very fast, specifing helper methods to include jQuery Javascript Files and additional plugin requirements.

The jQuery Link Helper allows to construct simple ajax calls from within a view template. The following call signature is proposed:

{code}
<?php
/**
* Build an AJAX Link using jQuery $.get or $.post calls.
*
* $options
* 'update' Update a container with the content fetched from $url
* 'type' Explicit Requesting method mimicing the jQuery functionality: GET, POST
* 'inline' True or false, wheater to inline the javascript in onClick=""
* atttribute or append it to jQuery onLoad Stack.
* 'callback' String specifies a javascript function called after successful
* request or array with possible keys 'beforeSend' and/or 'complete'
* 'dataType' Which type of data is the result: xml, html, text, json and so forth.
* 'id', 'class',
* 'title' HTML Attributes for the link
*
* BeforeSend Callbacks:
* Can include shortcuts as a string assignment to fire of effects before sending of request.
* Possible shortcuts are 'fadeOut', 'fadeOutSlow', 'fadeOutFast' 'hide', 'hideSlow', 'hideFast', 'slideUp'
* @example $options = array('callback' => array('beforeSend' => 'hideSlow'));
*
* Complete Callbacks:
* Can include shortcuts as a string assignment to fire of effects after finishing the request.
* Works only when specified together with $options['update'] which is the target of the effect.
* Possible shortcuts are: show, showslow, showfast, fadein, fadeinslow, fadeinfast, slidedown,
* slidedownslow, slidedownfast.
* @example $options = array('callback' => array('complete' => 'fadeIn'));
*
* @param String $label Urls Title
* @param String $url Link to Point to
* @param Array $options
* @param Array $params Key Value Pairs of GET/POST Parameters
* @return String $html
*/
$this->jqLink($label, $url, $options, $params);
?>
{code}
{zone-data}

{zone-data:milestones}
* Milestone 1: Finish First Proposal *[DONE]*
* Milestone 2: Community Review *[DONE]*
* Milestone 3: Finish First Implementation *DONE* (SVN: [http://www.beberlei.de/dev/svn/ZendX_JQuery/])
* Milestone 4: Complete Unit Test Coverage *[DONE]*
* Milestone 5: Finish Component
* Milestone 6: Documentation
{zone-data}

{zone-data:class-list}
* ZendX_JQuery
* ZendX_JQuery_View_Helper_JQuery
* ZendX_JQuery_View_Helper_JqLink
{zone-data}

{zone-data:use-cases}
{deck:id=Usecase}
{card:label=UC 00: jQuery View Helper Setup}
{code}
// Loading in Controller init() function:
$this->view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');

// Loading on View Object directly
$view->addHelperPath('ZendX/JQuery/View/Helper/', 'ZendX_JQuery_View_Helper');
{code}
{card}

{card:label=UC 01 : Simple jQuery Helper Usage}
{code}<html>
<head>
<title>jQuery Test Project</title>

<?php
// enable and configure jQuery View Helper
$this->jQuery()->enable()
->setJavascriptDirectory("/shared/js/")
->setStylesheetDirectory("/shared/css/");

// build the jQuery script tag pointing to google cdn (default usage)
echo $this->jQuery();
?>
</head>
{code}
{card}

{card:label=UC 02 : Your own jQuery Helper}
{code}<?php
class My_JQuery_View_Helper_Magic extends Zend_View_Helper_Abstract
{
public $jQuery;

public function setView(Zend_View_Interface $view)
{
$this->view = $view;
$this->jQuery = $this->view->jQuery();
}

public function magic($param1, $param2)
{
// Will show Popup when Anchor Id Container $param1 is clicked
$js_exec = "$('a#{$param1}').click(function {".
" alert('MAGIC! {$param2}');".
" return false; ".
"});";

$this->jQuery->addJavascriptFile("my_magic.js")
->addStylesheet("my_magic.css")
->addOnLoad($js_exec);
return '<a href="#" id="'.$param1.'">Magic Helper</a>';
}
}
{code}

{card}

{card:label=UC 03 : jQuery disabled}
{code}
<?php
$this->jQuery()->disable(); // disable jQuery helper

// output nothing. Good if you want to refactor
// your javascript in a later development stage,
// to make use of file inclusion and jquery
// selector optimizations.
echo $this->jQuery();
?>
{code}
{card}

{card:label=UC 04 : local jQuery}
{code}<?php
// uses local jquery include in "/js/jquery.min.js"
// (See default $_javascriptDir). This will overwrite
// the use of Google CDN
$this->jQuery()->setLocalPath("jquery.min.js");

// setLibraryPath() and setJavascriptDirectory() are
// split, because using Google CDN and having to
// additionally load jQuery plugin file requirements may coexist.
?>
{code}
{card}

{deck}

{deck:id=UsecaseJqLink}
{card:label=UC 05 : jqLink Simple Example}
{code}<?php
$this->jqLink("Zend Framework", "http://framework.zend.com");
?>{code}

results to:

additional line in jquery onLoad (See jQuery Helper addOnLoad()):

{code}
<script language="javascript" type="text/javascript><!--
$(document).ready(function() {
$("a.jqLinkCallback1").onClick(function() { $.get("http://framework.zend.com"); });
});
--></script>

<a href="http://framework.zend.com" class="jqLinkCallback1">Zend Framework</a>
{code}
{card}

{card:label=UC 06 : jqLink with Params}
{code}<?php
$this->jqLink("Zend Framework", "http://framework.zend.com", false, array("limit" => 25));
?>{code}

results to:

{code}
<script language="javascript" type="text/javascript><!--
$(document).ready(function() {
$("a.jqLinkCallback1").onClick(function() { $.post("http://framework.zend.com", {limit: 25}); });
});
--></script>

<a href="http://framework.zend.com" class="jqLinkCallback1">Zend Framework</a>
{code}
{card}

{card:label=UC 07 : jqLink with Options}
{code}<?php
$this->jqLink("Zend Framework", "http://framework.zend.com", array('update' => '#inlineTab', 'inline' => true));
?>{code}

results to:

{code}<a href="http://framework.zend.com" onClick="$('#inlineTab').load('http://framework.zend.com');">Zend Framework</a>{code}
{card}

{card:label=UC 08 : Multiple Links with jqLink}
{code}
<ul>
<li><?= $this->jqLink("Link to Inject", "inject.html", array('update' => '#test')); ?></li>
<li><?= $this->jqLink("Link to Inject2", "inject.php", array('update' => '#test', 'class' => 'someClass'), array('key' => 'value')); ?></li>
<li><?= $this->jqLink("Link with popup", "inject.php", array('callback' => 'alert(data.key);', 'dataType' => 'json'), array('key' => 'kekse')); ?></li>
<li><?= $this->jqLink("JSON Response with Callback", "inject.php", array('callback' => 'jsonCallback(data);', 'dataType' => 'json'), array('name' => 'Someguy', 'email' => 'somemail@example.com')); ?></li>
<li><?= $this->jqLink("BeforeSend Event", "inject.html", array('update' => '#test', 'callback' => array('beforeSend' => 'if(confirm("Really?"))'))); ?></li>
<li><?= $this->jqLink("BeforeSend Effect", "inject.html", array('update' => '#test', 'callback' => array('beforeSend' => 'hide'), 'inline' => true)); ?></li>
</ul>
{code}

Leads to a jQuery onLoad Code of:

{code}
<script type="text/javascript">
//<!--
$(document).ready(function() {
$('a.jqlink1').click(function() { $.get('inject.html', {}, function(data, textStatus) { $('#test').html(data); }, 'html');return false; });
$('a.jqlink2').click(function() { $.post('inject.php', {"key":"value"}, function(data, textStatus) { $('#test').html(data); }, 'html');return false; });
$('a.jqlink3').click(function() { $.post('inject.php', {"key":"kekse"}, function(data, textStatus) { alert(data.key); }, 'json');return false; });
$('a.jqlink4').click(function() { $.post('inject.php', {"name":"Someguy","email":"somemail@example.com"}, function(data, textStatus) { jsonCallback(data); }, 'json');return false; });
$('a.jqlink5').click(function() { if(confirm("Really?"))$.get('inject.html', {}, function(data, textStatus) { $('#test').html(data); }, 'html');return false; });
$('a.jqlink6').click(function() { showSlow$.get('inject.html', {}, function(data, textStatus) { $('#hiding').html(data); }, 'html');return false; });
});
//-->

</script>{code}
{card}

{card:label=UC-09: Using jQuery UI}
{code}
<?php $this->jQuery()->onLoadCaptureStart(); ?>
$(".highlightTest").click(function() {
$("#test").effect("highlight", {},
2000);
});
<?php $this->jQuery()->onLoadCaptureEnd(); ?>
<?= $this->jQuery()->addJQueryUiFromCDN(); ?>
{code}

This loads jQuery and jQuery UI from Googles CDN and adds an onLoad
effect that highlights #test on clicking '.highlightTest':

{code}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.5.2/jquery-ui.min.js"></script>

<script type="text/javascript">
//<!--
$(document).ready(function() {
$('a.jqlink1').click(function() { $.get('index.php?do=ajax', {}, function(data, textStatus) { $('#test').html(data); }, 'html');return false; });
$(".highlightTest").click(function() {
$("#test").effect("highlight", {},
2000);
});

});
//-->
</script>
{code}
{card}

{deck}
{zone-data}

{zone-data:skeletons}
{deck:id=Skeletons}
{card:label=ZendX_JQuery}
{code}
<?php
class ZendX_JQuery
{
/**
* @see http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery
* @const string Base path to CDN
*/
const CDN_BASE_GOOGLE = 'http://ajax.googleapis.com/ajax/libs/jquery/';

/**
* Always uses compressed version, because this is assumed to be the use case
* in production enviroment. An uncompressed version has to included manually.
*
* @see http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery
* @const string File path after base and version
*/
const CDN_JQUERY_PATH_GOOGLE = '/jquery.min.js';

/**
* Which parts of the the jQuery library should be rendered on echo'ing
* the jQuery library to the View. The constants act as bit-mask. This
* way the jQuery autogenerated code can be refactored based on personal needs.
*
* @see ZendX_JQuery_Helper_JQuery::setRenderMode
* @const Integer
*/
const RENDER_LIBRARY = 1;
const RENDER_SOURCES = 2;
const RENDER_STYLESHEETS = 4;
const RENDER_JAVASCRIPT = 8;
const RENDER_JQUERY_ON_LOAD = 16;
const RENDER_ALL = 255;

/**
* jQuery-enable a view instance
*
* @param Zend_View_Interface $view
* @return void
*/
public static function enableView(Zend_View_Interface $view);
}
?>
{code}
{card}

{card:label=ZendX_JQuery_View_Helper_JQuery}
{code}
<?php
class ZendX_JQuery_View_Helper_JQuery_Container
{
/**
* Run jQuery in NoConflict Mode to other Javascript Libraries
* @var boolean
*/
private static $noConflictMode = false;

/**
* Path to local webserver jQuery library
*
* @var String
*/
protected $_jqueryLibraryPath = null;

/**
* Default javascript directory, used for loading additional
* javascript files that belong to jQuery (for example jQuery UI)
*
* @var String
*/
protected $_jqueryIncludeDir = "/js/";

/**
* Default stylesheet directory, used for loading additional
* Stylesheets that belong to jQuery Helper components.
*
* @var String
*/
protected $_stylesheetDirectory = "/css/";

/**
* Additional javascript files that needs to be included
* for jQuery Helper components.
*
* @var Array
*/
protected $_javascriptSources = array();

/**
* Indicates wheater the jQuery View Helper is activated and
* will be displayed when echo $jQueryHelper; is called.
*
* @var Boolean
*/
protected $_enabled = false;

/**
* Indicates if a capture start method for javascript or onLoad
* has been called.
*
* @var Boolean
*/
protected $_captureLock = false;

/**
* Additional javascript statements that need to be executed after
* jQuery Library loading.
*
* @var Array
*/
protected $_javascriptStatements = array();

/**
* Additional stylesheet files that are included from the given
* local webserver stylesheet directory.
*
* @var Array
*/
protected $_stylesheets = array();

/**
* jQuery onLoad statements Stack
*
* @var Array
*/
protected $_onLoadActions = array();

/**
* View is rendered in XHTML or not.
*
* @var Boolean
*/
protected $_isXhtml = false;

/**
* Default CDN jQuery Library version
*
* @var String
*/
protected $_version = "1.2.6";

/**
* Default Render Mode (all parts)
*
* @var Integer
*/
protected $_renderMode = ZendX_JQuery::RENDER_ALL;

protected $_uiEnabled = false;
protected $_uiPath = null;
protected $_uiVersion = "1.5.2";

/**
* View Instance
*
* @var Zend_View_Interface
*/
public $view = null;

/**
* Set view object
*
* @param Zend_View_Interface $view
* @return void
*/
public function setView(Zend_View_Interface $view);

/**
* Enable jQuery
*
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function enable();

/**
* Disable jQuery
*
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function disable();

/**
* Is jQuery enabled?
*
* @return bool
*/
public function isEnabled();

/**
* Use CDN, using version specified. Currently supported
* by Googles Ajax Library API are: 1.2.3, 1.2.6
*
* @param string $version
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function setCdnVersion($version = null);

/**
* Get CDN version
*
* @return string
*/
public function getCdnVersion();

/**
* Are we using the CDN?
*
* @return void
*/
public function useCdn();

/**
* Set path to local jQuery library
*
* @param string $path
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function setLocalPath($path);

public function uiEnable();

public function uiDisable();

/**
* Set jQuery UI CDN Version
*
* @param String $version
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function setUiCdnVersion($version="1.5.2");

/**
* Return jQuery UI CDN Version
*
* @return String
*/
public function getUiCdnVersion();

/**
* Set local path to jQuery UI library
*
* @param String $path
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function setUiLocalPath($path);

/**
* Return the local jQuery UI Path if set.
*
* @return String
*/
public function getUiPath();

/**
* Is the jQuery Ui enabled and loaded from local scope?
*
* @return Boolean
*/
public function useUiLocal();

/**
* Is the jQuery Ui enabled and loaded from CDN?
*
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function useUiCdn();

/**
* Set the default directory where javascript files added
* by addJavascriptFile() are included from. By default
* the Zend Project Structure Directory "/js/" is set.
*
* @param String $directory
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function setJavascriptDirectory($directory);

/**
* Return the currently set Javascript include dir.
*
* @return String
*/
public function getJavascriptDirectory();

/**
* Set the default directory where Stylesheets added
* by addStylesheet() are included from. By default
* the Zend Project Structure Directory "/css/" is set.
*
* @param String $directory
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function setStylesheetDirectory($directory);

/**
* Return the current Stylesheet include directory
*
* @return String
*/
public function getStylesheetDirectory();

/**
* Get local path to jQuery
*
* @return string
*/
public function getLocalPath()
{
return $this->_jqueryLibraryPath;
}

/**
* Are we using a local path?
*
* @return bool
*/
public function useLocalPath();

/**
* Start capturing routines to run onLoad
*
* @return bool
*/
public function onLoadCaptureStart();

/**
* Stop capturing routines to run onLoad
*
* @return bool
*/
public function onLoadCaptureEnd();

/**
* Capture arbitrary javascript to include in jQuery script
*
* @return void
*/
public function javascriptCaptureStart();

/**
* Finish capturing arbitrary javascript to include in jQuery script
*
* @return true
*/
public function javascriptCaptureEnd();

/**
* Add a Javascript File to the include stack.
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function addJavascriptFile($path);

/**
* Return all currently registered Javascript files. This does
* not include the jQuery library, which is handled by another retrieval
* strategy.
* @return Array
*/
public function getJavascriptFiles();

/**
* Clear all currently registered Javascript files
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function clearJavascriptFiles();

/**
* Add arbitrary javascript to execute in jQuery JS container
*
* @param string $js
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function addJavascript($js);

/**
* Return all registered javascript statements
*
* @return array
*/
public function getJavascript();

/**
* Clear arbitrary javascript stack
*
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function clearJavascript();

/**
* Add a stylesheet
*
* @param string $path
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function addStylesheet($path);

/**
* Retrieve registered stylesheets
*
* @return array
*/
public function getStylesheets();

/**
* Add a script to execute onLoad
*
* @param string $callback Lambda
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function addOnLoad($callback);

/**
* Retrieve all registered onLoad actions
*
* @return array
*/
public function getOnLoadActions();

/**
* Set which parts of the jQuery enviroment should be rendered
* on __toString() of the component. Use ZendX_JQuery::RENDER_*
* constants. All parts of the enviroment are rendered by default.
* @param Integer $mask
* @return ZendX_JQuery_View_Helper_JQuery_Container
*/
public function setRenderMode($mask);

/**
* Return bitmask of the current Render Mode
* @return Integer
*/
public function getRenderMode();

/**
* String representation of jQuery environment
*
* @return string
*/
public function __toString();

// enables $j = jQuery.noConflict();
// http://docs.jquery.com/Using_jQuery_with_Other_Libraries
public static function enableNoConflictMode();

public static function disableNoConflictMode();

public static function getNoConflictMode();
}
{code}
{card}

{card:label=ZendX_JQuery_View_Helper_JqLink}
{code}
class ZendX_JQuery_View_Helper_JqLink extends Zend_View_Helper_Abstract
{
public function jqLink($title, $href, $options=null, $params=null);
}
{code}
{card}
{deck}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>