Yii 1.1: jii

Javascript library for Yii
19 followers

Jii allows you to encode models - and their relations - variables (strings, integers, arrays, floats, booleans) and urls into their Javascript equivalents. You can also use Jii to store your Javascript functions without polluting the global scope. Since version 0.0.3beta, Jii allows you to perform some basic operation on Javascript models and introduces some functions to interact with Knockout js observables. The aim of this extensions is to keep your server side code as well as your client side one more maintainable. Moreover it aims to ease the process of sharing data beetween PHP and Javascript.

Requirements

Yii 1.1 or above PHP 5 or above

Configuring Yii

Copy Jii folder to your applications protected/components folder. And add the following lines to your config/main.php.

'components' => array(
    ...
    'jii' => array(
        'class' => 'application.components.Jii.Jii',
            // uncomment the following 
            // if you do not want to use the minified version
            // 'script' => 'jii-0.0.4.js',
        ),
    ...
),

Add Jii to your page

Adding Jii to your page is easy and can be done as follows:

Yii::app()->clientScript->registerScript('jii', Yii::app()->jii->getScript(), CClientScript::POS_END);

Sample usage

You can add params, urls, models and functions to Jii as follows:

// adding params
// you can use any kind of php variable
Yii::app()->jii->addParam('your_param', 10);
 
// adding urls
Yii::app()->jii->addUrl('view_test_url', $this->createUrl('test/view'));
 
// adding functions
Yii::app()->jii->addFunction('function', 'function(){ 
    alert("This is an alert!");
}');

Other usage examples

Adding Models to Jii

As regards CActiveRecord instances (or class instances inheriting from CModel), you can select which attribute you want Javascript have access to by adding the following method to each of the CActiveRecord class files you wish to convert ...

...
    public function getJsonizeables()
    {
        return array(
            'attribute_label_1',
            'attribute_label_3',
            'attribute_label_4',
        );
    }
    ...

... and then you can use the following code to add it to Jii:

$jsonized_model = Yii::app()->jii->jsonize($model);
 
    // adding models to jii
    Yii::app()->jii->addModel('model', $jsonized_model);

Since version 0.0.3beta, Yii::app()->jii->addModel() accepts models and dataproviders as well as jsonized data:

$model = new Model();
Yii::app()->jii->addModel('javascript_model', $model);

Jsonizing CActiveDataProviders

Since jii 0.0.2 you can jsonize CActiveDataProviders as you do with model instances or model arrays:

$jsonized_data_provider = Yii::app()->jii->jsonize($data_provider);
 
    // adding data provider to jii
    Yii::app()->jii->addModel('model', $jsonized_data_provider);

Adding binding functions

You can add any function that needs to be executed after the page has finished loading with the following code:

Yii::app()->jii->addBindings('function(){
    // the following alert will be shown after
    // page has finished loading
    alert("Hello world!");
}');

Jsonizing custom attributes

Sometimes you may need to perform additional operation on models' attributes values before passing them to Javascript. In such cases, you can jsonize custom attributes in the following way. Create or add to the model/model's you wish to jsonize the getJsonizeables method and add to the array a custom attribute name such as custom_attribute_1. After that, create a public method named getcustom_attribute_1() which performs some operation over one ore more model attributes and return a value.

...
 
    public function getJsonizeables()
    {
        return array(
            'attribute_label_1',
            'attribute_label_3',
            'attribute_label_4',
            ...
            'custom_attribute_1',
        );
    }
 
    // the following method allows you to jsonize custom attributes
    public function getCustom_attribute_1()
    {
        return $this->_performSomeOperation($this->attribute_label_1);
    }
 
    ...

Javascript Models

Since version 0.0.3beta each Jii model is an object providing the following methods:

/**
 * Finds one model instance based on the specified attribute
 * @param object {attribute: "attribute_name", value: attribute_value}
 * @return object or null if none object is found
*/
jii.models.javascript_model.findByAttribute();
 
// the Javascript object representation of a jii Model
jii.models.javascript_model.toJS();
 
// the number of model instances found
jii.models.javascript_model.count();

Knockout js utilities

Since Jii 0.0.3beta you will have at your disposition a couple of functions:

/**
 * Converts a jii model into an Knockout observable
 * @param object model
 * @return observable
*/
jii.utils.observable();
 
// the same as above except that it returns an observable array
jii.utils.observableArray();

Changelog

2012-12-14 jii 0.0.4

  • jii script is added through CClientScript and no longer interferes with PHP code
  • jii can be used across the whole page without concurrencies
  • Added function bindings
  • Fixed some minor bugs

2012-12-13 jii 0.0.3beta

  • Some bug fixes

2012-12-12 jii 0.0.3beta

  • Knockout js functions
  • Direct jsonization of models
  • Javascript models functions

2012-12-10 jii 0.0.2

  • Jsonizer support for CActiveDataProvider

Resources

Total 10 comments

#11101 report it
cgabbanini at 2012/12/17 01:56am
Comments regarding implementations

I have just moved a few comments about further or future implementations or request for support of particular features to Jii forum page, in order to make it easier for us to discuss about any topic. Nonetheless I would like to thank you for your feedback, which I always appreciate: thank you. :)

#11086 report it
Cherif at 2012/12/15 02:11pm
@cgabbanini Forum page

+1 for the forum page (github, roadmap suggestion etc...)

#11084 report it
pmaselkowski at 2012/12/15 11:21am
KO Mapping

You could also include support for ko mapping plugin, its very good for complex models (ie. nested models).

I haven't tested your code yet, as I already use my own encoding with mapping plugin. Basicly I convert model into array and then encode into json and then pass it to ko.mapping. It supports deeply nested models, arrays of models, just any complex object.

#11041 report it
cgabbanini at 2012/12/12 01:32am
RE: Behaviors, Interesting

@Cherif Thank you. That is clear. Even if I do not think that behaviors are a suitable approach to this extension (there are a few reasons that it would take to long to explain outside a forum), I think that what you are looking for - and that perhaps will be useful to others and to me too - can be achieved in the following way (of course it actually requires a little more typing:

// this should make available 
// eager loaded relations: BELONGS_TO, HAS_MANY, MANY_MANY
// i.e. : $model = Model::model()->with('name_of_relation')->findAll();
$json_model = Yii::app()->jii->jsonize($model);
Yii::app()->jii->addModel('model', $json_model);

On your Javascript code:

...
// the following feature will be available in jii-0.0.3
var observable_attribute = jii.models.model.attribute_one.getObservable();
...

Anyway I think Jii could become in a near future a Javascript library for Yii. I suggest we use Jii forum page for further comments on this issue: in this way we hopefully will benefit from other people's opinions and suggestions. Many thanks :D

@AustinGeek Well, If you need to encode models to JSON you can use Jii Jsonizer:

$json = Yii::app()->jii->jsonize($model);

If your aim is to decode JSON data into models you can create your own CModel classes defining your custom attributes and validation rules, than you can:

// json from REST API
// this returns an array
// see http://php.net/manual/en/function.json-decode.php
$json_array = json_decode($json_string, true);
 
$your_model = new YourModel();
$your_model->attributes = $json_array;
#11038 report it
AustinGeek at 2012/12/11 01:59pm
Interesting

Nice!

I have an external site I need to extract data from and will probably push data to in the future. They have a great API that is REST-FUL and return JSON formatted data. I just don't know how to deal with all the data I get back from the api calls.

#11031 report it
Cherif at 2012/12/11 05:59am
Behaviors

The behavior extends CActiveRecordBehavior or CModelBehavior is to place where I suggest to put the code for this extension I want to generate Models for Knockout and convert the Model.attributes to observables and relations (HAS_MANY, MANY_MANY) to obervableArray consider this extension to have an idea ejsonbehavior.

Hope it helps

#11026 report it
cgabbanini at 2012/12/11 01:04am
Re: Nice extension

Thank you for your comment Cherif. I never went deep into behaviours, that is why I'd like you could explain with a few more words which way they could make this extensions easier to use and to maintain. Furthermore I see behaviors as something that can deviate the application flow under particular conditions. But I am not able to identify which conditions you could be thinking about.

#11021 report it
Cherif at 2012/12/10 09:26pm
Nice extension

Thank you for this, but I suggest to think about it as a behavior will be much easier to use and maintain.

#11005 report it
cgabbanini at 2012/12/10 05:10am
Re: BackBone.js ?

Thank you for your comment. :D I am mainly using knockout js as a Javascript library and this extension have been developed to ease Yii to knockout interactions. I guess this aswers your question. Anyway, I still haven't planned future developements yet, so I am open to and I will appreciate any contribution.

#10999 report it
Tibor Katelbach at 2012/12/10 01:57am
BackBone.js ?

Hi Excellent extension, I can stop wondering if this extension is linked to a much broader prject as using it with frameworks like Backbone ? or other . If it is I'd really be interested in particiapting :) Cheers

Leave a comment

Please to leave your comment.

Create extension