ptheofan
ptheofan

Reputation: 2290

CJSON::encode a javascript function

I use jQuery widget factory (jQuery widgets) for my js widgets.

$.widget('cool.someWidget', {
     options: {
         onSomething: null
     }
     // other js code
});

Normally to run the widget from js you write

$(selector).someWidget({
    onSomething: function() { ..... }
});

In Yii I use CJSON::encode to compile all the initialization properties which include the onSomething event.

echo CJSON::encode(array(
    'onSomething' => 'function() {....}',
));

However due to the conversion (CJSON), it converts the function() {...} to a string so in the document it is written the following

$(selector).someWidget({
    onSomething: "function() { .... }"
});

because the onSomething is actually a string when I call the this._trigger('onSomething') it doesn't run the code.

This problem I have only when I "generate" the view and not with Ajax requests (which I handle differently in the system). Is there some "normal" way of making Yii actually write in the document the function withought the quotes?

Upvotes: 3

Views: 3757

Answers (4)

Igor Parra
Igor Parra

Reputation: 10348

I solved like this:

if ($this->user_options !== null && is_array($this->user_options))
{
    $reqs = CJavaScript::encode(
        array_merge(
            $this->user_options,
            array(
                // adding a default callback to options 
                'onLoad' => 'js: function() {$("#info").text("Hi")}'
                )
            )
        );
}

NOTE: js: only works for CJavaScript not forCJSON

Upvotes: 0

Nader Roua
Nader Roua

Reputation: 621

There is actually a build in way to prevent the encode function from wrapping function declaration with quotes , you should add js: before your function declaration

CJavaScript::enocde(array(
   'prop'=>'value',
   'callback' => 'js:function(){}'
))

Upvotes: 3

Jon
Jon

Reputation: 437664

IMHO the premise of the question is flawed, and it would be much better if you side-stepped this issue entirely.

What is the problem here? You cannot supply JavaScript code as a PHP string.

Why do you want to do that? I don't believe a compelling reason exists. JavaScript code should be written as JavaScript code; writing it as a string is simply worse.

It is quite probable that you wanted to pass a bunch of options available to you as PHP variables to the plugin, and in the excitement it seemed a good idea to pass all the options (including those that are functions) in the same manner.

But there is another way, courtesy of $.extend: use CJSON::encode for all the scalars (strings, numbers) and switch back to pure JavaScript for the callbacks.

$(selector).someWidget($.extend(
    <?php echo CJSON::encode(array(/* no functions here, just scalars */));?>,
    { // and now, back in JavaScript-land, code follows:
        onSomething: function() { ..... }
    }
));

Upvotes: 1

ptheofan
ptheofan

Reputation: 2290

I wrote the following function which does exactly what I wanted. Still if there's some native Yii solution I'd really love to know it.

public function encodeOpts($data, $jsCode = null) {
    $rVal = CJSON::encode($data);

    if ($jsCode == null)
        return $rVal;

    foreach($jsCode as $key => $code) {
        $codeEntries[] = "\"{$key}\": {$code}";
    }

    return substr_replace($rVal, ', ' . implode(', ', $codeEntries), -1) . '}';
}

Upvotes: 0

Related Questions