Highcharts, Yii and body content reloading - javascript

I have a view that renders some data in a CListView and a Highcharts graphic.
Please note that the pager of the CListView works the following way: it requests the "new page" to the server, the servers renders the entire content of the page and sends it to the CListView. The body is then replaced with the content that is being sent, with something like this: $('body').html(rendered_html_response).
I also have a dropDownList that imitates this behavior. This is the code:
<?php
echo CHtml::dropDownList('usage', 'cg', array(
'd'=>'Daily',
'm'=>'Monhly'
), array(
'ajax'=>array(
'type'=>'POST',
'url'=>$this->createUrl('admin/user', array(
'id'=>$user->id)
),
'update'=>'body',
'data'=>array('cg'=>'js:$(this).val()'),
'options'=>array(
Yii::app()->session['cg']=>array(
'selected'=>true
)
)
)
));
?>
Anyways, there is a problem. When I use the CListView, everything works fine (as in: the page's content is refreshed without the page being reloaded, the charts and the data are rendered correctly, etc...), but when I select something using the dropDownList, the server renders the reply, sends it to the client, the client starts replacing the content of body, but then I get this error: http://www.highcharts.com/errors/16.
I tried disabling highcharts.src.js this way:
public function beforeAction(){
if(Yii::app()->request->isAjaxRequest){
Yii::app()->clientScript->scriptMap['highcharts.src.js'] = false;
}
return true;
}
but then I get the typical undefined javascript error (means that something is trying to use Highcharts, which is not defined).
Where is the problem and how can I fix it?

//init
$('#container').highcharts({});
//select onchange
$('#container').highcharts().destroy();

As following the error link says
Highcharts already defined in the page
This error happens the second time Highcharts or Highstock is loaded in the same page, so the Highcharts namespace is already defined. Keep in mind that the Highcharts.Chart constructor and all features of Highcharts are included in Highstock, so if you are running Chart and StockChart in combination, you only need to load the highstock.js file.
You are loading the highcharts javascript twice. You can try
a) enabling highcharts on the first load and then disabling it on the next e.g perhaps checking if ajax
b) use custom javascript to check whether highcharts has been loaded as in this blog post
c) use the NLSClientScript extension that handles js and css loading for you
I suggest you use the last one. I was bitten by this problem a couple of times until I discovered it. It eliminates the need to single out each javascript function/file.
EDIT
Instead of editing the listview js, you can edit your code to use the same update function:
<?php
echo CHtml::dropDownList('usage', 'cg', array(
'd'=>'Daily',
'm'=>'Monhly'
), array(
'onChange'=>'$.fn.yiiListView.update("your-list-id", {
data: {"usage":$(this).val()},
type: "POST"
});'
));
?>

Related

Why does this TinyMCE AJAX integration work 9/10 times?

I've got a TinyMCE implementation that works somewhere around 80-90% of the time, but for that last percent, the content of the editor fails to populate - for lack of better phrasing.
Effectively, upon page load, a jQuery AJAX call reaches out to a PHP page that grabs some content from my database. Upon retrieval, I set the value of the TinyMCE instance to the content of the response. I've gone a few rounds with this, first with a custom AJAX build, and recently a jQuery build. In both cases I get about the same results - that the editor loads, the content comes back from the server, and every once in a while, the text area ends up blank.
The latest attempt at this is much shorter than the earlier ones, but either way, I still end up with effectively the same result. I've also tried repainting the TinyMCE instance after the content is loaded to no avail.
The result of the two console logs are identical - and the expected response from my server - even in the case of a failure. So the value IS getting set, but the content is not visible.
function LoadAgenda()
{
$.ajax(
{
url: 'http://www.example.com/agenda.php?AgencyID=' + AgencyID + '&date=' + AgendaDate,
cache: false,
dataType: 'html'
})
.done(function(Response)
{
console.log(Response);
$('#AgendaContent').val(Response);
tinyMCE.execCommand("mceRepaint");
console.log($('#AgendaContent').val());
});
}
And finally, for the record, I'm using TinyMCE 4.1.6.
If anyone needs more information than this, I'm happy to oblige.
What happens first? The editor getting loaded or the ajax call completing? If your ajax call is happening after the editor is loaded, I don't think .val() is going to work, since it's no longer a simple textarea after TinyMCE initializes it. Try this:
Make the ajax call only after the editor is initialized
Change .val() to setContent()

Adding jQuery script to a single view in Yii2

I am working on the basic template of Yii2. I have got a jQuery script views/usuario/js/create.js that it's only going to be used in one view views/usuario/create.php.
I'd prefer not to use ...
public $jsOptions = array(
'position' => \yii\web\View::POS_HEAD
);
... in assets/AppAsset.php in order to mantain loading of scripts at the end of the page.
create.js it's only needed in the create.php view so I'd prefer to load it just for the create.php view.
So I've tried unsuccessfuly to follow ippi's instructions
Firebug keeps throwing me this error:
SyntaxError: expected expression, got '<'
http://www.example.com/usuario/js/create.js
Line 1
I guess there could be a problem with the route param of ...
$this->registerJsFile('js/create.js');
... but I can't find it out.
Any help would be appreciated.
registerJsFile() needs an url, you should simply publish (make it web accessible) your file before registering it, e.g. :
$pub = Yii::$app->assetManager->publish(__DIR__ . '/create.js');
$this->registerJsFile($pub[1], ['depends' => ['yii\web\JqueryAsset']]);
Or you could create an asset bundle and registering it in your view.
Read more about publish() and registerJsFile().
Try to use $this->registerScriptFile('views/usuario/js/create.js');

WP "TypeError: blacklist is undefined" password-strength-meter.js

I am creating a custom profile page for one of my WP plugins, where I want the user to have a regular page instead of seeing the WP Dashboard. All works fine so far, except the script for the password-strength. When I start typing the password, I get this in my Firebug console:
TypeError: blacklist is undefined
blacklist = [ blacklist.toString() ];
Which is thrown when the "meter" event is called at the beginning:
meter : function( password1, blacklist, password2 ) {
if ( ! $.isArray( blacklist ) )
blacklist = [ blacklist.toString() ];
I have no idea what it's working fine in the WP dashboard. I spend about an hour searching, then I decided to use a workaround. If anybody could point me into the right direction, what I am missing here, I would appreciate that.
My workaround for now is to put this into a try/catch block:
meter : function( password1, blacklist, password2 ) {
try {
if ( ! $.isArray( blacklist ) )
blacklist = [ blacklist.toString() ];
}
catch (e){}
Which works fine now, even when I use it on the WP front end. But it's not an optimal solution, as I have to copy the JS files password-strenght-meter.js to my own plugin and enqueue it from there. Since I also need to use the user-profile.js, I also have to copy this too, so I need to duplicate these two JS files which is not a good solution.
Any ideas, why jQuery is stopping the script when used on a front end page, while it works fine on the admin backend?
==== EDIT ========
I just found that the problem is related to another plugin "WP User Frontend" which seems to override the password-strenght-meter script with their own code. So I think I will be able to fix this now.
Sorry for the misleading question. I have checked that this problem was related to having another plugin "WP User Frontent" activated, that did interfere with the existing admin scripts from WordPress. So here is how I solved it.
First of all, I put this into a custom page template, so this needs to be placed in the theme directory:
<?php
/**
* Template Name: User Profile Dashboard
*/
// remove other conflicting scripts
if (class_exists('WPUF_Main'))
{
global $wpuf;
remove_action( 'wp_enqueue_scripts', array($wpuf, 'enqueue_scripts') );
}
get_header();
wp_enqueue_script('user-profile');
wp_enqueue_style('wp-admin');
include_once(ABSPATH . '/wp-admin/includes/template.php');
... other code that handles the user profile fields ...
<?php get_footer() ?>
The tricky part was to get rid of the already enqueued scripts that came from the WPUF_Main class. It seems that WP User Frontend instantiates the class into a global variable $wpuf when the plugin is active, so I had to use this variable to remove the action for enqueuing the scripts. Then I enqueued the scripts and styles for user-profile and wp-admin, and included template.php from wp-admin, because I needed the function submit_button() which is declared here.
I hope this will help others who come up with the same problem, because the combination of WP User Frontend and having a custom Profile page, does make sense, when the webmaster don't want to have their users to see the WP Dashboard at all.

Using Jquery methods on Data Returned from Ajax, with out printing out the data

So I have a rather unique situation. I am using JQuery to gather some data based on two date ranges, what is returned as a response in the $data variable (I am using Ajax) I have set, is a html table.
Now I don't want the user to ever see this table, I want to use This jquery plugin to download the CSV file of that table. The question is, if the table sits inside of a $data and can be seen via the network tab in Chrom Dev Tools, under Response, is it possible to be manipulated with Jquery?
In our inhouse framework, we do the following to get Ajax Data:
// The following belongs to a JS class method.
data = {
startDate : $('.startDate').val(),
endDate : $('.endDate').val()
}
CT.postSynch('report/payRollReport/downloadPayRoleReport', {data : data}, function(data){
console.log(data);
});
We pass a data object to our Ajax wrapper, call a controller with an action (in this case downloadPayRoleReport translates to ajaxDownloadPayRoleReport()) which in turn returns an HTML table, which I can view via console.log(data)
I want to use the above linked plugin on data to then turn this html table into a csv and instant download.
Question is, can this be done?
You can create a jQuery object from the table. Then you can do anything to the jQuery object just like you could if it were actually on the DOM. You can always put the table on the DOM as well off screen, but I think any chance you have to not touch the DOM you should take it.
var myTable = $(data);
myTable.mySpecialTableMethodToExportToCSV();

Javascript variable & ajax ; with JsonForm. Using .jsonForm() with a variable

I'm using JsonForm: https://github.com/joshfire/jsonform/wiki#wiki-getting-started
I'm trying to load a form schema into $('form').Jsonfrom(), from an external .txt file,
attempting this by loading it into my .html file with ajax, putting it in a javascript variable , then calling $('form').Jsonfrom() with a click event .
Here is my code:
<script>
#Load in .txt to javascript variable using ajax
var stringData = $.ajax({
url: "schema.txt",
async: false
}).responseText;
#check that file is loaded correctly .- have check this works.
#alert(stringData);
#on clicking of a piece of text in a <p> wrapper call jsonForm function.
$(document).ready(function(){
$("p").click(function(){
$('form').jsonForm(stringData )
});
});
</script>
the error I'm getting in firebug is:
"TypeError: this.formDesc.schema is undefined"
& my stack trace is this:
http://tinypic.com/r/2uiybo4/5
Think my problem may be in the way in loading in the .txt file with ajax.
however if I comment in: alert(stringData); . . . the scheme for the for is displayed perfectly.
Like so: http://tinypic.com/r/2ynl9qh/5
Also there is no problem with the scheme, as i have tried putting it directly into in $('form').Jsonfrom("here") & it works fine.
Managed to solve this .
had to use a templating language (jinja2) instead of ajax, to get my form schema into my html document.. so that json form ( a jquery form builder) couple execute on a full html doc on the page loading .
Silly !
Hope this helps .

Categories