addRule('li.item', 'onmouseover', 'dosomejavscript..'); * @example $behaviour->addAjaxRule('#myForm', 'onsubmit', array('url'=>'ajax/users/login')); * @example $behvaiour->addLoadEvent('loadMyMenu()'); */ class BehaviourHelper extends Helper { /** * This propertie contains all rules as formatted string which * will be extended by addRule and used to create the temp file * * @var string */ var $behaviourRules = null; /** * This propertie contains loadEvents as formatted string * which will be appended to the rules and so to the resulting file * * @var string */ var $behaviourLoads = null; /** * Contains the Path to the app/tmp/ - directory * I dont know the global var yet... hook me up on irc ;) * * @var string */ var $behaviourTempPath; /** * Behaviour uses Ajax- and Javascript-Helper * * @var array */ var $helpers = array('Ajax', 'Javascript'); /** * Array with all possible eventhandlers. * * @var array */ var $events = array('onabort', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onerror', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload'); /** * This creates a Ajax.Request or Ajax.Updater Rule based upon the first two arguments. * It uses the Ajax Helper, so for all possible options refer to the AjaxHelper Manual. * * Little sidenote: If you leave out $options['update'] the Ajax Call will become a Request. * * @param string $target This can be a html-tagname, a id, a classname or a combination of all, like "li.listclass" or "a.menu". For id: "pre#myid" * @param string $event This is the event handler. For example: "onsubmit" or "onkeydown" * @param array $options Array with the AjaxHelper options for building an Prototype Ajax Function * @param boolean $returnFalse If 'false' the call will not "return false;". Generally not a good idea but just in case, here you can control this. */ function addAjaxRule($target = null, $event = null, $options = array(), $returnFalse = true) { // Used for validating Rule before adding it $error = false; // Check if a there is a previous rule, append (,) for array if (!empty($this->behaviourRules)) { $this->behaviourRules = $this->behaviourRules . ",\n"; } // Does the Rule contain a target ? if (empty($target)) { echo ''; return; } // Is valid event? if (!in_array($event, $this->events)) { $error = true; $event = 'onclick'; } // Does the Rule contain any script ? if (count($options) == 0) { $error = true; } // Check if a URL is present. // This is a Ajax Call so a URL is mandatory. if (!isset($options['url'])) { $error = true; } // This is building the actual Call $script = $this->Ajax->remoteFunction($options); // This changes the Call because an error occured // If something is wrong then this will create a Alert Popup on Event. if ($error) { $script = "alert('Fix the rule-setup for \"" . $target . "\" in your view')"; } // This adds a return false to the javascript (default) $returnSnippet = "\n\t\t\treturn false;"; // If that is not wanted then empty the string if (!$returnFalse) { $returnSnippet = ""; } // Create the rule, add to global $this->behaviourRules .= "\t'" . $target . "' : function(element){\n\t\telement." . $event . " = function(){\n\t\t\t" . $script . ";" . $returnSnippet . "\n\t\t}\n\t}"; // write to File $this->__writeRuleScript(); } /** * This is for simple Javascript. For example if you are using the Scriptaculous Effects in * your application. $behaviour->addRule('a.menu', 'onmouseover', 'Effect.highlight(element)'); * * @param string $target This can be a html-tagname, a id, a classname or a combination of all, like "li.listclass" or "a.menu". For id: "pre#myid" * @param string $event This is the event handler. For example: "onsubmit" or "onkeydown" * @param string $script Any javscript you want.. * @param boolean $returnFalse If 'false' the call will not "return false;". Generally not a good idea but just in case, here you can control this. */ function addRule($target = null, $event = null, $script = null, $returnFalse = true) { // Used for validating Rule before adding it $error = false; // Check if a there is a previous rule, append (,) for array if (!empty($this->behaviourRules)) { $this->behaviourRules = $this->behaviourRules . ",\n"; } // Does the Rule contain a target ? if (empty($target)) { echo ''; return; } // Is valid event? if (!in_array($event, $this->events)) { $error = true; $event = 'onclick'; } // Does the Rule contain any script ? if (empty($script)) { $error = true; } // This changes the Call because an error occured // If something is wrong then this will create a Alert Popup on Event. if ($error) { $script = "alert('Fix the rule-setup for \"" . $target . "\" in your view')"; } // This adds a return false to the javascript (default) $returnSnippet = "\n\t\t\treturn false;"; // If that is not wanted then empty the string if (!$returnFalse) { $returnSnippet = ""; } // Create the rule, add to global $this->behaviourRules .= "\t'" . $target . "' : function(element){\n\t\telement." . $event . " = function(){\n\t\t\t" . $script . ";" . $returnSnippet . "\n\t\t}\n\t}"; // write to File $this->__writeRuleScript(); } /** * addLoadEvent allows you to add functions to the window.onload handler. * * @example $behaviour->addLoadEvent('yourJsFunc()'); * @param mixed $script Can be a javascript function as string, or you can pass a array with javascript functions. The functions will be added to window.onload(). */ function addLoadEvent($script = null) { if (!empty($script)) { if (is_array($script)) { $this->behaviourLoads .= "Behaviour.addLoadEvent(function(){\n"; foreach($script as $loadfunc) { $this->behaviourLoads .= "\t" . $loadfunc . ";\n"; } $this->behaviourLoads .= "});\n"; } else { $this->behaviourLoads .= "Behaviour.addLoadEvent(function(){\n\t" . $script . ";\n});\n"; } } $this->__writeRuleScript(); } /** * Shortcut to Javscript->link. * Points to the correct file which should be in webroot/js/ * * @return string */ function linkRulesJS() { return $this->Javascript->link('behaviourRules.php'); } /** * Creates a block with the formatted rules. * * @param boolean $return If set to true then this function will just return the content. Default is 'echo' * @return string */ function outputScriptBlock($return = false) { if ($return) { return $this->Javascript->codeBlock($this->__makeRuleScript()); } else { echo $this->Javascript->codeBlock($this->__makeRuleScript()); } } /** * Creates a file with the given data as content. * Just like file_put_contents. For compat with PHP4 * i've chosen the good old way.. * * @param unknown_type $filename * @param unknown_type $data * @return unknown */ function __write($filename, $data) { if (($handle = fopen($filename, 'w+')) === false) { return false; } if (($bytes = fwrite($handle, $data)) === false) { return false; } fclose($handle); return $bytes; } /** * Writes the current Behaviour Rules into /tmp/behaviourTmp.js * * @return void */ function __writeRuleScript() { $this->behaviourTempPath = dirname(__FILE__) . DS . '..' . DS . '..' . DS . 'tmp' . DS . 'behaviourTmp.js'; $this->__write($this->behaviourTempPath, $this->__makeRuleScript()); } /** * Wraps the Behaviour Rules into their main Object and appends the * actual BehaviourJS function to parse this Ruleset. * * @return string */ function __makeRuleScript() { return "\nvar behaviourRules = {\n" . $this->behaviourRules . "}\nBehaviour.register(behaviourRules);\n" . $this->behaviourLoads; } } ?>