Reputation: 2290
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
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
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
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
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