I don't think that this will be integrated in the core because most time it will be a special solution for a special problem. To generalize will be very problematic -- but I will try to handle this
ajax+clientScript Definitive solution for all clientScript problem in ajax request
#21
Posted 09 November 2010 - 11:26 AM
I don't think that this will be integrated in the core because most time it will be a special solution for a special problem. To generalize will be very problematic -- but I will try to handle this
#22
Posted 17 December 2010 - 06:41 AM
Nice hack you made! Tho I ran into a bug. The core scripts don't get registered ergo it can cause js errors. For example:
CListView::registerClientScript() has this row:
$cs->registerCoreScript('bbq');It won't get registered because you included only the user scripts in ZClientScript::renderOnRequest().
I'm trying to find a workaround now.
The missing of the above script causes this javascript error:
$.param.querystring is not a function
m(o_O)m
#23
Posted 17 December 2010 - 05:09 PM
I modified CListView's html code, so rows could be updated, deleted and more rows could be added. (used inputs + ajaxbuttons) After each deletion or addition I updated the content of the list. I managed to give each button an unique id this way:
<?php echo CHtml::ajaxButton('Save',
array('attributeValue/update', 'id' => $data->id),
array(
'success' => "js: function(data, textStatus, XMLHttpRequest) { $.fn.yiiListView.update('list'); }",
'type' => 'post',
),
array('name' => 'tl'.CHtml::$count)
); ?>
<?php CHtml::$count++; ?>When I updated the content it didn't interfere with the selectors from the main code.
If you include the main script again in the widget, you could get errors, like I did with loading jquery again. (CListWidget's JS crashed), you have to manually include the files:
Yii::app()->getClientScript()->registerCoreScript('bbq');I modified zaccaria's code, so the scripts could be placed where they belong and this way js script can be surrounded by onload & ondomready events. (JQuery undefined error!)
public function renderOnRequest()
{
$html='';
foreach($this->scriptFiles as $scriptFiles)
{
foreach($scriptFiles as $scriptFile)
$html.=CHtml::scriptFile($scriptFile)."\n";
}
$scripts=isset($this->scripts[self::POS_END]) ? $this->scripts[self::POS_END] : array();
foreach($this->scripts as $k=>$script) {
if ($k == self::POS_READY) {
$scripts[] = "jQuery(function($) {\n".implode("\n",$script)."\n});";
}
elseif($k == self::POS_LOAD) {
$scripts[] ="jQuery(window).load(function() {\n".implode("\n",$script)."\n});";
}
}
if (!empty($scripts)) $html .= CHtml::script(implode("\n",$scripts))."\n";
if($html!=='')
return $html;
}The problem was, that when I updated list content the <script> tags were removed via the jquery functions. You cannot add/modifiy <script> tags via JQuery, only hardcoded style. You have to get it as a string and eval() it.
So, after refresh you would have to "reassign" JQuery delegates, because the ids could have been modified, assigned to other objects:
jQuery('body').delegate('#tl0','click',function(){jQuery.ajax({'success': function(data, textStatus, XMLHttpRequest) { $.fn.yiiListView.update('tulajdonsag-lista'); },'type':'post','url':'/yii-gsmhome/admin/attributeValue/update/id/2','cache':false,'data':jQuery(this).parents("form").serialize()});return false;});
jQuery('body').delegate('#tl1','click',function(){jQuery.ajax({'success': function(data, textStatus, XMLHttpRequest) { $.fn.yiiListView.update('tulajdonsag-lista'); },'type':'post','url':'/yii-gsmhome/admin/attributeValue/delete/id/2','cache':false,'data':jQuery(this).parents("form").serialize()});return false;});I could try to examine the right <script> tag's content and eval it, so it always becomes updated.
By the way the same kind of thing happens if you have custom buttons in CGridView. When you paginate through ajax, and change page, you have to reassign the events attached to the "new" buttons loaded via ajax. Otherwise it doesnt work.
Any thoughts of this?
m(o_O)m
#24
Posted 30 December 2010 - 09:28 AM
- CSS files required by some widgets are not included in the AJAX response
- reloading core scripts will invalidate previously registered $.fn method calls (and render them unusable)
An alternative solution; just perform a renderPartial for the AJAX request, and filter the resulting HTML on the client side. First, register all statically loaded CSS and JS files:
Yii::app()->clientScript->registerScript('register_static_css_js', "
$(function() {
script_files = $('script[src]').map(function() { return $(this).attr('src'); }).get();
css_files = $('link[href]').map(function() { return $(this).attr('href'); }).get();
});");Then, in the AJAX success callback, only include external script and stylesheets that are not yet present in the DOM. Inline Javascript is always included.
success: function(data) {
var reply = $(data);
var target = $('#some_element');
target.html('');
target.append(reply.filter('script[src]').filter(function() { return $.inArray($(this).attr('src'), script_files) === -1; }));
target.append(reply.filter('link[href]').filter(function() { return $.inArray($(this).attr('href'), css_files) === -1; }));
target.append(reply.filter('#content'));
target.append(reply.filter('script:not([src])'));
}I'm pretty sure the jQuery code can be optimized, still working on that. Any suggestions?
#26
Posted 04 January 2011 - 07:25 AM
szako, on 03 January 2011 - 06:27 PM, said:
Thanks for the feedback
Slight improvement to the success callback to prevent redundant requests in case more than one AJAX request is done:
success: function(data) {
var reply = $(data);
var target = $('#some_element');
target.html('');
target.append(reply.filter('script[src]').filter(function() {
if ($.inArray($(this).attr('src'), script_files) === -1) {
script_files.push($(this).attr('src'));
return true;
}
return false;
}));
target.append(reply.filter('link[href]').filter(function() {
if ($.inArray($(this).attr('href'), css_files) === -1) {
css_files.push($(this).attr('href'));
return true;
}
return false;
}));
target.append(reply.filter('#content'));
target.append(reply.filter('script:not([src])'));
}
#28
Posted 06 January 2011 - 02:59 PM
http://code.google.c.../detail?id=1961
Quote
Yii::app()->getClientScript()->renderScriptFiles = false;
$this->renderPartial('someView', null, false, true);This results in a partial view being rendered, with inline JS intact, and the jquery.js file excluded.
Not necessarily a complete solution, but works for me, and may hopefully rope Qiang into the discussion for his input ;-)
#30
Posted 27 January 2011 - 08:37 PM
Yii::app()->getClientScript()->renderScriptFiles = false; // use #1961
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
'id'=>'HistoryDivPopup',
'options'=>array(
'title'=>Yii::t('DR','Change History'),
'autoOpen'=>true,
'modal'=>true,
'width'=>600,
'position'=>array(300,200),
),
));
echo $out; // dialog content
$this->endWidget('zii.widgets.jui.CJuiDialog');
the CJuiDialog does not auto-open, as it does when jQuery is present.
But without renderScriptFiles = false, then after I close the dialog, ajax elements that were already present in the page no longer work. I get "jQuery.yii is undefined". Specifically, I have a "Cancel" button which was rendered in the original view, like this:
echo CHtml::resetButton(Yii::t('DR','Cancel'),array('submit'=>$this->createUrl($return)));
can anyone help me with this? I am at the very beginning stage of learning javascript and jQuery.
#31
Posted 27 January 2011 - 09:18 PM
If you need more direct help, contact me at jon [at] phpsitesolutions.com
#32
Posted 27 January 2011 - 10:09 PM
Maybe I should have mentioned this is all CRUD-generated code (very simple form) using CActiveForm widget.
Also tried @zaccaria's solution, which works, but as others pointed out it also blocks the css for the CJuiWidget.
{EDIT}: <duh> the solution in my case was much simpler. before rendering the widget in my partial view, I do:
Yii::app()->getClientScript()->scriptMap=array('jquery.js'=>false,'jquery.min.js'=>false); // don't resend jquery.cs
{/EDIT}
#33
Posted 28 January 2011 - 03:05 PM
http://www.yiiframew...lientscriptpos/
worked around it by using patch #1961, plus loaded jquery-ui in my main layout. I'm not crazy about this solution, and hoping for an improvement. Maybe patching the widgets per post 12697, and then using scriptMap to exclude jquery.js from loading again ?
#34
Posted 04 February 2011 - 06:47 AM
#35
Posted 16 March 2011 - 07:40 AM
I can't extend 'components/Contoller.php' to ZController because I'm using the new version of 'Rights' module and the components/Contoller.php' extends to RController
I can't find solution for this problem
#36
Posted 20 March 2011 - 10:08 AM
ClaCS, on 16 March 2011 - 07:40 AM, said:
I can't extend 'components/Contoller.php' to ZController because I'm using the new version of 'Rights' module and the components/Contoller.php' extends to RController
I can't find solution for this problem
#37
Posted 24 March 2011 - 01:30 AM
#38
Posted 12 April 2011 - 08:32 AM
jeremy, on 20 March 2011 - 10:08 AM, said:
Hi!
the cascade inheritance is works! but the ajax+clientScript problem is still
#39
Posted 14 April 2011 - 08:36 AM
Thanks so much for this solutions. With my implementation, the CJuiDialog worked only on the 1st click (after) page rendered, now when I close the dialog and click on the open dialog link again, it gave a $().dialog('open') not defined error.
I got it to work with your solutions plus I also added the CSS files for the widget with this code:
public function renderOnRequest() {
$html = '';
foreach ($this->scriptFiles as $scriptFiles) {
foreach ($scriptFiles as $scriptFile)
$html.=CHtml::scriptFile($scriptFile) . "\n";
}
// Addition to register CSS files
foreach ($this->cssFiles as $key => $value) {
$html .= CHtml::cssFile($key) . "\n";
}
foreach ($this->scripts as $script)
$html.=CHtml::script(implode("\n", $script)) . "\n";
if ($html !== '')
return $html;
}
#40
Posted 02 June 2011 - 04:01 PM

Help














