#Js Helper rebuild
So as discussed many times I would want to rebuild the Ajax helper to make it more extensible and allow for greater compatibility with other non-prototype libraries. Originally I planned on making these changes directly to the AjaxHelper. However, gwoo suggested I make these changes to the unfinished JsHelper instead. I was planning on implementing an adapter system similar to how the toolbar helper works in DebugKit. This would allow a developer to use the same API for all libraries, and even switch out libraries and have all generated code continue working. Furthermore, this doesn't require users to rename ```$js->request();``` everywhere.
### Using the new helper
The most simple use would still be
{{{ var $helpers = array('Js') }}}
This would use the default library js, which would probably be jQuery. Considering it is the most questioned about library, optionally you could declare a backend _engine_ to use
{{{ var $helpers = array('Js' => 'Prototype'); }}}
This would load the Prototype library engine instead of the default library. I was planning on converting the existing ajax helper into the Prototype engine, as well as creating an engine for jquery and mootools, as they other popular libraries.
### Userland Extensions
Creating an adapter pattern as described above allows for easy userland extensions as well. A user could easily implement his/her favorite Js library and share it. These files could be placed in ```app/views/helpers```
#### naming conventions
There are several approaches we could take, one that I thought of (using dojo as an example)
* Option 1
* classname - DojoJsEngine
* filename - app/views/helpers/dojo_js_engine.php
* Option 2
* classname - DojoJs
* filename - app/views/helpers/dojo_js.php
* Option 3
* classname - DojoEngine
* filename - app/views/helpers/adapters/dojo_engine.php
* **Winner**
* classname - DojoEngineHelper
* filename - app/views/helpers/dojo_engine.php
When discussing this with jperras the issue of namespace conflicts came up which is valid concern and a reason why we can't use the simple approach of Jquery / jquery.php
### JsHelper Api
I was going to try and maintain the existing JsHelper methods and try to port over as many of Javascript and AjaxHelper features as well. Perhaps adding methods in for things like datepicker generation. I figured an abstract Engine class could handle missing method errors much like ```Cache``` as well as provide commonly used methods like parsing of options.
The methods I wanted to implement for all engines are
- **confirm()** Create a confirm message.
- **prompt()** Create a prompt.
- **alert()** Create an alert.
- **request()** Create an Ajax request on click
- **form()** Create an onSubmit event listener
- **slider()** - Create a slider widget based on a CSS selector
- **sortable()** - Convert a group of elements into a sortable list
- **drag()** - Convert a group of elements into a draggable elements
- **drop()** - Convert elements based on a selector into Dropzones
- **autocomplete()** - Create a text input that has autocomplete features attached
- **uses()** - Include Additional javascript files with JsEngine ie. $.getScript();
- **object()** - Convert PHP into JSON
- **escape()** - Escape strings for Js output.
- **event()** - Bind an event listener ie. click, etc.
- **cacheScript()** - Caches a script snippet to the helpers internal script cache
- **writeScript()** - Output the internal script cache inside a domReady Event.
#### Script output
All Javascript generated by the Js helper will be cached and output in ```$scripts_for_layout``` if generated in the view, and inline for $js->xx() use in the layout. Each library with planned support has an easy to use syntax to bind to DOMContentLoaded event. Cached scripts, would be output with writeScript(). writeScript() once called, will disable further caching and all scripts would be output into script blocks. This solves the issue of having methods in the layout. Of coures writing cacheEvents at the end of the layout should capture all cached scripts.
#### Options and variations on implementation.
There are obviously going to be differences in how options are implemented between the libraries. I was hoping to abstract a set of commonly used and commonly available options. These options would be handled by the adapters, but common options would be aliased between their concrete option names and the abstract name. This would allow for easy library swaps. Option arrays will be passed off to the adapter to handle, from there the engine can determine the validity of different options, as well as convert any abstract option names.
##Other Ideas
### Autoinclude JS files
#### This won't make the cut this time around.
With more and more Javascript being required for web app's I thought it might be prudent to provide a built in way for developers to easily organize their JS like they organize their view files. Felix presented about this once as well, and I've used in on a few apps, and really like it. It works something like this
{{{
/js/views/default.js
/js/views/users/add.js
}}}
Both of these files would be included when viewing /users/add and having the default layout. This gives the developer an easy way to have scripts automatically loaded. There would be a kill switch as well ```$js->noAutoload()``` Could be used to negate the automatic inclusion of scripts.
