Help Implementing Javascript

Hi,

I am new relatively new to Yii and new to Javascript.

I am trying to implement some javascript from JQWidgets (http://http://www.jqwidgets.com). I know this is a large task for a newbie but I really need the grid components ability to show related items from different tables together in nested grids. Cgridview just doesn’t do it.

So I am trying their basic code which is:




<!DOCTYPE html>

<html lang="en">

<head>

    <title id='Description'>This example shows how to create a Grid from Array data.</title>

    <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" />

    <script type="text/javascript" src="../../scripts/jquery-1.8.3.min.js"></script>

    <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script>

    <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script> 

    <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script>

    <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script>

    <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script>

    <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script>

    <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script> 

    <script type="text/javascript" src="../../jqwidgets/jqxgrid.columnsresize.js"></script> 

    <script type="text/javascript" src="../../scripts/gettheme.js"></script>

    <script type="text/javascript">

        $(document).ready(function () {

            var theme = getDemoTheme();

            // prepare the data

            var data = new Array();

            var firstNames =

            [

                "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene"

            ];

            var lastNames =

            [

                "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier"

            ];

            var productNames =

            [

                "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Cramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist"

            ];

            var priceValues =

            [

                "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0"

            ];

            for (var i = 0; i < 200; i++) {

                var row = {};

                var productindex = Math.floor(Math.random() * productNames.length);

                var price = parseFloat(priceValues[productindex]);

                var quantity = 1 + Math.round(Math.random() * 10);

                row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)];

                row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)];

                row["productname"] = productNames[productindex];

                row["price"] = price;

                row["quantity"] = quantity;

                row["total"] = price * quantity;

                data[i] = row;

            }

            var source =

            {

                localdata: data,

                datatype: "array",

                datafields:

                [

                    { name: 'firstname', type: 'string' },

                    { name: 'lastname', type: 'string' },

                    { name: 'productname', type: 'string' },

                    { name: 'quantity', type: 'number' },

                    { name: 'price', type: 'number' },

                    { name: 'total', type: 'number' }

                ]

            };

            var dataAdapter = new $.jqx.dataAdapter(source);

       

            $("#jqxgrid").jqxGrid(

            {

                width: 670,

                source: dataAdapter,

                theme: theme,

                columnsresize: true,

                columns: [

                  { text: 'Name', dataField: 'firstname', width: 100 },

                  { text: 'Last Name', dataField: 'lastname', width: 100 },

                  { text: 'Product', editable: false, dataField: 'productname', width: 180 },

                  { text: 'Quantity', dataField: 'quantity', width: 80, cellsalign: 'right' },

                  { text: 'Unit Price', dataField: 'price', width: 90, cellsalign: 'right', cellsformat: 'c2' },

                  { text: 'Total', dataField: 'total', cellsalign: 'right', minwidth: 100, cellsformat: 'c2' }

                ]

            });

        });

    </script>

</head>

<body class='default'>

    <div id='jqxWidget'>

        <div id="jqxgrid">

        </div>

    </div>

</body>

</html>



Now, I have created an extensions folder for all of the js files and have put this into my main.php:


'application.extensions.JQXWidgets.*',

I then have the following in the view:




if($baseJQXGridUrl===null)

    $baseJQXGridUrl=Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('ext.JQXWidgets'));


$cs=Yii::app()->getClientScript();


$cs->registerCSSFile($baseJQXGridUrl.'/scripts/jquery-1.8.3.min.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/jqxcore.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/jqxbuttons.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/jqxscrollbar.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/jqxmenu.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/jqxgrid.selection.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/jqxgrid.columnsresize.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/jqxdata.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/jqwidgets/gettheme.js',CClientScript::POS_END);

$cs->registerScriptFile($baseJQXGridUrl.'/scripts/gettheme.js',CClientScript::POS_END);


$cs = Yii::app()->getClientScript();  

$cs->registerScript('nw',

        "

        $(document).ready(function () {

            var theme = getDemoTheme();

            // prepare the data

            var data = new Array();

            var firstNames =

            [

                'Andrew', 'Nancy', 'Shelley', 'Regina', 'Yoshi', 'Antoni', 'Mayumi', 'Ian', 'Peter', 'Lars', 'Petra', 'Martin', 'Sven', 'Elio', 'Beate', 'Cheryl', 'Michael', 'Guylene'

            ];

            var lastNames =

            [

                'Fuller', 'Davolio', 'Burke', 'Murphy', 'Nagase', 'Saavedra', 'Ohno', 'Devling', 'Wilson', 'Peterson', 'Winkler', 'Bein', 'Petersen', 'Rossi', 'Vileid', 'Saylor', 'Bjorn', 'Nodier'

            ];

            var productNames =

            [

                'Black Tea', 'Green Tea', 'Caffe Espresso', 'Doubleshot Espresso', 'Caffe Latte', 'White Chocolate Mocha', 'Cramel Latte', 'Caffe Americano', 'Cappuccino', 'Espresso Truffle', 'Espresso con Panna', 'Peppermint Mocha Twist'

            ];

            var priceValues =

            [

                '2.25', '1.5', '3.0', '3.3', '4.5', '3.6', '3.8', '2.5', '5.0', '1.75', '3.25', '4.0'

            ];

            for (var i = 0; i < 200; i++) {

                var row = {};

                var productindex = Math.floor(Math.random() * productNames.length);

                var price = parseFloat(priceValues[productindex]);

                var quantity = 1 + Math.round(Math.random() * 10);

                row['firstname'] = firstNames[Math.floor(Math.random() * firstNames.length)];

                row['lastname'] = lastNames[Math.floor(Math.random() * lastNames.length)];

                row['productname'] = productNames[productindex];

                row['price'] = price;

                row['quantity'] = quantity;

                row['total'] = price * quantity;

                data[i] = row;

            }

            var source =

            {

                localdata: data,

                datatype: 'array',

                datafields:

                [

                    { name: 'firstname', type: 'string' },

                    { name: 'lastname', type: 'string' },

                    { name: 'productname', type: 'string' },

                    { name: 'quantity', type: 'number' },

                    { name: 'price', type: 'number' },

                    { name: 'total', type: 'number' }

                ]

            };

            var dataAdapter = new $.jqx.dataAdapter(source);

       

            $('#jqxgrid').jqxGrid(

            {

                width: 670,

                source: dataAdapter,

                theme: theme,

                columnsresize: true,

                columns: [

                  { text: 'Name', dataField: 'firstname', width: 100 },

                  { text: 'Last Name', dataField: 'lastname', width: 100 },

                  { text: 'Product', editable: false, dataField: 'productname', width: 180 },

                  { text: 'Quantity', dataField: 'quantity', width: 80, cellsalign: 'right' },

                  { text: 'Unit Price', dataField: 'price', width: 90, cellsalign: 'right', cellsformat: 'c2' },

                  { text: 'Total', dataField: 'total', cellsalign: 'right', minwidth: 100, cellsformat: 'c2' }

                ]

            });

        });

    ",

  CClientScript::POS_END

);


//$cs = Yii::app()->getClientScript();  

//$cs->registerScript(

//  'my-hello-world-1',

//  'var greetings = "Hello" + " " + "World";

//  alert(greetings);',

//  CClientScript::POS_END

//);

?>


    <div id='jqxWidget'>

        <div id="jqxgrid">

        </div>

    </div>



It does not work.

If I uncomment the my-hello-world-1 javascript I get the Hello World Alert.

Can someone help me here?

Or if there is an extension that allows nested grids then point me to it. I have seen the following discussion and I don’t think it gives me what I want:

http://www.yiiframework.com/forum/index.php/topic/33178-is-it-possible-to-have-nested-cgridviews/

Regards,

neil

Hello,

I think the first step is check the resulting HTML code, and also if there are any JS errors (using Firebug for instance)

Cheers

Hi,

Thanks for that. :D

Certainly helped identify a lot of issues. Some of which are they way the js scripts are written by the provider. I am guessing I need to re-examine how this is implemented but I have fixed some of the code for now manually (I know not a good idea but I wanted to get this at least working as a proof of concept).

There is now one more javascript error left that I am a bit confused by.




http://localhost/lagosyii/assets/lib/bootstrap/less/mixins.less



I have checked all the scripts I am loading and I can’t find it.

However, I have tried other pages that do not use this javascript library and they have the same error (They use CGridView). So this is probably misleading to this issue.

At the end of the day I still do not get the nested grid for jqwidgets coming up. So I can only assume something is wrong with the way I am implementing this.

Any more ideas?

Thanks,

Neil

OK.

I have discovered that I was getting more errors than I thought.

I have simplified this to try and get rid of extraneous info.

So I have removed all the js files except what I think is for the core.

I now get only the following error, which was also in amongst all the other errors:


 $(...).jqxGrid is not a function

which is related to this code:


            $('#jqxgrid').jqxGrid(

            {

                width: 670,

                source: dataAdapter,

                theme: theme,

                columnsresize: true,

                columns: [

                  { text: 'Name', dataField: 'firstname', width: 100 },

                  { text: 'Last Name', dataField: 'lastname', width: 100 },

                  { text: 'Product', editable: false, dataField: 'productname', width: 180 },

                  { text: 'Quantity', dataField: 'quantity', width: 80, cellsalign: 'right' },

                  { text: 'Unit Price', dataField: 'price', width: 90, cellsalign: 'right', cellsformat: 'c2' },

                  { text: 'Total', dataField: 'total', cellsalign: 'right', minwidth: 100, cellsformat: 'c2' }

                ]



Is it that I cannot do inline js and I need to get more complicated and write a proper extension (I hope not as I think this would be way beyond my skill level)

Any help would be greatly appreciated.

Neil

I guess this could be caused by your JS library not loaded, or maybe some jQuery compatibility issue, or even double inclusion of jQuery?

I’m not sure I can help, but can you put your page online or share the full resulting HTML code?

Thanks again,

this is the complete HTML code from the page:


<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

	<meta name="language" content="en" />


    <link rel="stylesheet" type="text/css" href="/lagosyii/themes/bootstrap/css/styles.css" />


	<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<link rel="stylesheet" type="text/css" href="/lagosyii/assets/299efa4e/jqwidgets/styles/jqx.base.css" media="2" />

<link rel="stylesheet" type="text/css" href="/lagosyii/assets/94eb9a27/css/bootstrap.css" />

<link rel="stylesheet" type="text/css" href="/lagosyii/assets/94eb9a27/css/bootstrap-responsive.css" />

<link rel="stylesheet" type="text/css" href="/lagosyii/assets/94eb9a27/css/yii.css" />

<script type="text/javascript" src="/lagosyii/assets/9c2746d9/jquery.js"></script>

<script type="text/javascript" src="/lagosyii/assets/94eb9a27/js/bootstrap.js"></script>

<title>Lagos - Admin RabbitSection</title>


	</head>


<body>


<div class="navbar navbar-fixed-top"><div class="navbar-inner"><div class="container"><a href="#" class="brand">Lagos</a><ul id="yw2" class="nav"><li><a href="/lagosyii/index.php/site/index">Home</a></li><li><a href="/lagosyii/index.php/site/page?view=about">About</a></li><li><a href="/lagosyii/index.php/site/contact">Contact</a></li><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Secretary <span class="caret"></span></a><ul id="yw3" class="dropdown-menu"><li class="active"><a tabindex="-1" href="/lagosyii/index.php/rabbitSection/admin">Classes</a></li><li><a tabindex="-1" href="/lagosyii/index.php/rabbitShow/admin">Shows</a></li></ul></li><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Steward <span class="caret"></span></a><ul id="yw4" class="dropdown-menu"><li class="active"><a tabindex="-1" href="/lagosyii/index.php/rabbitSection/admin">Classes</a></li><li><a tabindex="-1" href="/lagosyii/index.php/rabbitShow/admin">Shows</a></li></ul></li><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Member <span class="caret"></span></a><ul id="yw5" class="dropdown-menu"><li><a tabindex="-1" href="/lagosyii/index.php/rabbitShow/admin">Shows</a></li></ul></li><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Admin <span class="caret"></span></a><ul id="yw6" class="dropdown-menu"><li><a tabindex="-1" href="/lagosyii/index.php/auth">Auth</a></li></ul></li><li><a href="/lagosyii/index.php/site/logout">Logout (admin)</a></li></ul></div></div></div>

<div class="container" id="page">


			<ul class="breadcrumbs breadcrumb"><li><a href="/lagosyii/index.php">Home</a><span class="divider">/</span></li><li><a href="/lagosyii/index.php/rabbitSection/index">Rabbitsections</a><span class="divider">/</span></li><li class="active">Manage</li></ul><!-- breadcrumbs -->

	

	<div class="row">

    <div class="span9">

        <div id="content">

            

<h1>Manage Sections</h1>


<p>

You may optionally enter a comparison operator (<b>&lt;</b>, <b>&lt;=</b>, <b>&gt;</b>, <b>&gt;=</b>, <b>&lt;&gt;</b>

or <b>=</b>) at the beginning of each of your search values to specify how the comparison should be done.

</p>


    <div id='jqxWidget'>

        <div id="jqxgrid">

        </div>

    </div>        </div><!-- content -->

    </div>

    <div class="span3">

        <div id="sidebar">

        <div class="portlet" id="yw0">

<div class="portlet-decoration">

<div class="portlet-title">Operations</div>

</div>

<div class="portlet-content">

<ul class="operations nav" id="yw1"><li><a href="/lagosyii/index.php/rabbitSection/index">List Rabbitsection</a></li><li><a href="/lagosyii/index.php/rabbitSection/create">Create Rabbitsection</a></li></ul></div>

</div>        </div><!-- sidebar -->

    </div>

</div>


	<div class="clear"></div>


	<div id="footer">

		Copyright &copy; 2013 by My Company.<br/>

		All Rights Reserved.<br/>

		Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a>.	</div><!-- footer -->


</div><!-- page -->


<script type="text/javascript" src="/lagosyii/assets/299efa4e/scripts/jquery-1.8.3.min.js"></script>

<script type="text/javascript" src="/lagosyii/assets/299efa4e/jqwidgets/jqxcore.js"></script>

<script type="text/javascript" src="/lagosyii/assets/299efa4e/jqwidgets/jqxdata.js"></script>

<script type="text/javascript" src="/lagosyii/assets/299efa4e/scripts/gettheme.js"></script>

<script type="text/javascript">

/*<![CDATA[*/


        $(document).ready(function () {

            var theme = getDemoTheme();

            // prepare the data

            var data = new Array();

            var firstNames =

            [

                'Andrew', 'Nancy', 'Shelley', 'Regina', 'Yoshi', 'Antoni', 'Mayumi', 'Ian', 'Peter', 'Lars', 'Petra', 'Martin', 'Sven', 'Elio', 'Beate', 'Cheryl', 'Michael', 'Guylene'

            ];

            var lastNames =

            [

                'Fuller', 'Davolio', 'Burke', 'Murphy', 'Nagase', 'Saavedra', 'Ohno', 'Devling', 'Wilson', 'Peterson', 'Winkler', 'Bein', 'Petersen', 'Rossi', 'Vileid', 'Saylor', 'Bjorn', 'Nodier'

            ];

            var productNames =

            [

                'Black Tea', 'Green Tea', 'Caffe Espresso', 'Doubleshot Espresso', 'Caffe Latte', 'White Chocolate Mocha', 'Cramel Latte', 'Caffe Americano', 'Cappuccino', 'Espresso Truffle', 'Espresso con Panna', 'Peppermint Mocha Twist'

            ];

            var priceValues =

            [

                '2.25', '1.5', '3.0', '3.3', '4.5', '3.6', '3.8', '2.5', '5.0', '1.75', '3.25', '4.0'

            ];

            for (var i = 0; i < 200; i++) {

                var row = {};

                var productindex = Math.floor(Math.random() * productNames.length);

                var price = parseFloat(priceValues[productindex]);

                var quantity = 1 + Math.round(Math.random() * 10);

                row['firstname'] = firstNames[Math.floor(Math.random() * firstNames.length)];

                row['lastname'] = lastNames[Math.floor(Math.random() * lastNames.length)];

                row['productname'] = productNames[productindex];

                row['price'] = price;

                row['quantity'] = quantity;

                row['total'] = price * quantity;

                data[i] = row;

            }

            var source =

            {

                localdata: data,

                datatype: 'array',

                datafields:

                [

                    { name: 'firstname', type: 'string' },

                    { name: 'lastname', type: 'string' },

                    { name: 'productname', type: 'string' },

                    { name: 'quantity', type: 'number' },

                    { name: 'price', type: 'number' },

                    { name: 'total', type: 'number' }

                ]

            };

            var dataAdapter = new $.jqx.dataAdapter(source);

       

            $('#jqxgrid').jqxGrid(

            {

                width: 670,

                source: dataAdapter,

                theme: theme,

                columnsresize: true,

                columns: [

                  { text: 'Name', dataField: 'firstname', width: 100 },

                  { text: 'Last Name', dataField: 'lastname', width: 100 },

                  { text: 'Product', editable: false, dataField: 'productname', width: 180 },

                  { text: 'Quantity', dataField: 'quantity', width: 80, cellsalign: 'right' },

                  { text: 'Unit Price', dataField: 'price', width: 90, cellsalign: 'right', cellsformat: 'c2' },

                  { text: 'Total', dataField: 'total', cellsalign: 'right', minwidth: 100, cellsformat: 'c2' }

                ]

            });

        });

    

jQuery(function($) {

jQuery('body').tooltip({'selector':'a[rel=tooltip]'});

jQuery('body').popover({'selector':'a[rel=popover]'});

});

/*]]>*/

</script>

</body>

</html>



jQuery is indeed included twice, which is wrong:


<script type="text/javascript" src="/lagosyii/assets/9c2746d9/jquery.js"></script>

…

<script type="text/javascript" src="/lagosyii/assets/299efa4e/scripts/jquery-1.8.3.min.js"></script>

Maybe it’s not the only cause of your issue, but it should be one cause.

Hi bennouna,

Yeah I did see that as well and commented out that bit of the script and it made no difference.

What gets me is that appears to be some js code inside of the jqwidget code itself. But it must wrok because I know people who have used it but i think they do so inside a .net environment.

Regards,

Neil