This is a migrated thread and some comments may be shown as answers.

Ajax and RadControl script error

24 Answers 536 Views
UI for ASP.NET AJAX in ASP.NET MVC
This is a migrated thread and some comments may be shown as answers.
gyelle
Top achievements
Rank 1
gyelle asked on 05 Mar 2009, 08:54 PM

hi, i have a simple mvc page which uses ajax to display a set of records depending on the filter provided.  this page works fine but whenever i try to add a telerik control (either a radcombobox or a radgrid) i get this error:

microsoft jscript runtime error: sys.mvc.asynchyperlink is null or not an object

and sometimes this one:
microsoft jscript runtime error: sys.webforms.pagerequestmanager is null or not an object

any help is appreciated.

thanks!

 

 

24 Answers, 1 is accepted

Sort by
0
Sub
Top achievements
Rank 1
answered on 31 Mar 2009, 07:28 PM
Did you find out a solution for this? I am also having a problem displaying the RadGrid using AJAX when a RadCombo selection changes. Any help from Telerik team is appreciated! Thanks

0
Atanas Korchev
Telerik team
answered on 01 Apr 2009, 06:52 AM
Hello,

RadControls currently cannot be updated via MVC's built-in ajax. This is one of the known limitations.

Best wishes,
Albert
the Telerik team

Check out Telerik Trainer , the state of the art learning tool for Telerik products.
0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 02 Apr 2009, 04:35 AM
You guys could use JQuery to do this.  Use the RadGrid's client-side events to call a JS function to populate the RadGrid with the new data.  I am using a RadCombo to filter the data shown in a RadGrid (amongst other things).

For example, use RadCombo's OnClientSelectedIndexChanged event to call a function to update the RadGrid with the value in the RadCombo:

function getProjects(sender, args) {
                $.getJSON(
                '<%= Url.Action("GetProjects", "Capital") %>',
                { facility: sender.get_value() },
                function(data) {
                    fillGrid(sender, data);
                });
            }

The key here is JQuery's getJSON method.  If you need to pass in extra parameters to your Controller Action, then just add them where I have facility: sender...  Once the Controller Action returns your JSON, JQuery will call the function fillGrid (you can name this whatever you want), passing in the the data:

function fillGrid(items) {
                var tableView = $find("<%= radProjects.ClientID %>").get_masterTableView();
                tableView.set_dataSource(items);
                tableView.dataBind();
            }

That's it!  If you want to get fancy, you can also use JQuery's client-side data store to keep the data items locally, so you can do client-side filtering or add rows:

var projects = [];
$(this).data('JQueryProjects', projects);
fillGrid(projects);
// do whatever with projects -> sort, add rows, etc.

If you need to know how to return JSON from a controller:

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetProjects(int facility)
{
      IList<Project> projects = capitalRequestService.GetFacility(facility).Projects;                
     
      return Json(projects);
}

JQuery actually makes JavaScript programming fun; once you get the hang of it, you won't miss the Microsoft AJAX stuff at all.  This is a better solution anyway, since the Microsoft AJAX sends the entire page HTML back instead of just the updated data.

I can bet that Telerik will provide built-in AJAX on MVC using JQuery in the next release or two...

If anyone needs any help, let me know!

-Dallas

0
Sub
Top achievements
Rank 1
answered on 02 Apr 2009, 03:31 PM
Hi Dallas,

Thanks for your response!

I figured out the same approach yesterday. After seeing your reply I feel that I am on a right track. Thank you!

0
Sub
Top achievements
Rank 1
answered on 02 Apr 2009, 09:12 PM
Hi,

I am running into following issues:

1. I needed to initially bind the RadGrid on server in order to bind the grid on client side using JSON and MVC. According to the thread http://www.telerik.com/community/forums/aspnet-ajax/grid/binding-the-grid-on-the-client.aspx
"When you are using client-side data-binding of RadGrid(not declarative one) you should have two things in mind:
 - you should bind initially your RadGrid on server
or
 -
you should attached ClientSettings.ClientEvents.OnCommand client event

This way RadGrid will manage to create it's MasterTableView initially and later(on client-side) you will be able to get_masterTableView set_dataSource and call dataBind()"

Now I want to conditionally format the cells based on the data. I am doing this in OnRowDataBound client side event. It will not reflect during initial bind which was done on the server. I also dont want to repeat the conditional formatting logic on the server side just for the first time. Is there a workaround to handle this?

2. Does the client side binding support creating the columns dynamically If I am not sure the column details at design time.

Thanks in advance!


0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 03 Apr 2009, 03:27 AM
Sub-

Things work a little differently under MVC.  You can bind a RadGrid on the client-side without first binding on the server-side.  The most important thing is to override VerifyRenderingInServerForm in your View:

<script runat="server">
 public override void VerifyRenderingInServerForm(Control control)
 {
 }
</script>

Then define your RadGrid, paying attention to the AutoGenerateColumns="False" and the ClientSettings block:

<telerik:RadGrid runat="server" ID="radDevices" AutoGenerateColumns="false" GridLines="None">
                        <MasterTableView TableLayout="Fixed" ShowFooter="false">
                            <Columns>
                                 // typical GridBoundColumns here...
                            </Columns>
                            <NoRecordsTemplate>
                                There are no devices for this request yet. Please add an item from above.
                            </NoRecordsTemplate>
                        </MasterTableView>
                        <ClientSettings>
                            <ClientEvents OnCommand="radGrid_Command" />
                            <DataBinding EnableCaching="false">
                            </DataBinding>
                        </ClientSettings>
                    </telerik:RadGrid>

You'll need to latch on the OnCommand event, to handle all the paging and sorting with JQuery.  You'll also need to cancel the default RadGrid behavior:

function radGrid_Command(sender, args) {
         args.set_cancel(true);
// do whatever with JQuery here for paging/sorting...
}

After that, you'll need to load the data on the client-side when the page loads:
function pageLoad() {                                  // you can use JQuery instead: $(document).ready(function() {
                var devices = [];
                $(this).data('Devices', devices);
                fillGrid(devices);
}

You'll want to do this, even if your datasource doesn't have any items initially.  Otherwise, the RadGrid will show 11 empty rows.

As for your second question you may want to ask yourself why you want to add columns dynamically.  A better solution might be to define all the columns declaritively, then set Visible="false".  You can then call hideColumn / showColumn on the client-side, and you will already have the data for it in your data source:

http://www.telerik.com/help/aspnet-ajax/grid_hidecolumn.html


Good luck,

-Dallas


0
Sub
Top achievements
Rank 1
answered on 03 Apr 2009, 06:24 PM
Thanks again for your detailed response.

The reason for creating columns dynamically is to support the configurable UI and the number of columns and the type of columns are unknown at compile time. I can probably create more number of columns than required and hide the remaining unwanted columns. But it seems odd and feel less flexible
0
Sub
Top achievements
Rank 1
answered on 09 Apr 2009, 09:15 PM
Hi,

I am getting 11 empty rows even if I bind the grid in client side page load.

Here is what the steps are:

1. Load the dropdown on server side during initial load.
2. In pageLoad, based on the first selected item in the dropdown, use JQuery to call Controller action to get the JSON.
3. Bind the grid at client side in pageLoad.

When the page is requested it displays populated the dropdown and displays 11 empty rows and then displays the actual data immediately after that. It seems to be a timing issue.

Is there a way to work around this situation. Thanks for the help in advance!
0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 10 Apr 2009, 04:18 AM
Sub,

In your JavaScript pageLoad set the RadGrid datasource to an empty array (or follow the code I posted earlier).  This is happening because the page loads with the default 11 rows (which is probably a bug that Telerik should be made aware of), then JQuery is making an AJAX call to update the RadGrid- this takes a momment and causes the flicker.

I had to find this out the hard way, and this was the best solution I was able to come up with.  There are actually quite a few nuances that you most overcome to use Telerik in MVC.  Once you know/understand them, the controls work great.

I hope this works for you- if you still need help, post some of your JS code and I'll try to help you out.

Thanks,

-Dallas
0
Sub
Top achievements
Rank 1
answered on 13 Apr 2009, 02:13 PM

Hi Dallas,

Eventhough, in my JavaScript pageLoad, I set the RadGrid datasource to an empty array it initially displays No Record Found template and then after a moment it displays the correct data. The flicker is so obvious and could not get around it. Here is my code:

 

 

function pageLoad() {

 

 

var res = [];

 

 

var tableView = $find("<%= lGrid.ClientID %>").get_masterTableView();

 

tableView.set_dataSource(res);

tableView.dataBind();

 

 

// Update the grid with real data using JQuery

 

 

updateGrid();}

Hi Telerik Guys,

Is there any plans on fixing this issue in the future release or as hot fix?

Thanks

0
Nikolay Rusev
Telerik team
answered on 14 Apr 2009, 11:10 AM
Hello Sub,

When you attach OnCommand client event and do not bind RadGrid on server it will bind itself to fake PageSize rows. Those are the rows which you initially see as empty. Later when client pageLoad event  occurs this rows are populated with data.

Once possible way to make this rows invisible initially is to set GridDataItem.Display="false" on ItemCreated event:
protected void ItemCreated(object sender, GridItemEventArgs e)  
        {  
            if (e.Item is GridDataItem)  
            {  
                e.Item.Display = false;  
            }  
        } 


Sincerely yours,
Nikolay
the Telerik team

Check out Telerik Trainer , the state of the art learning tool for Telerik products.
0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 14 Apr 2009, 03:48 PM
Nikolay-

Is it possible for Telerik to remove the 11 "fake PageSize rows" so we won't have this problem.  I understand the 11 rows are probably there to get the grid to show the pager with more than 1 page, but having this arbitrarily defined is causing issues for people.  I undserstand there are workarounds, but in your example Sub will need to explicitly remember to set the items to visable once JQuery returns data.

Sub-

You may want to try to set the RadGrid to an array with "empty" data on page load- try setting the array to empty strings.  This should trick the RadGrid into thinking it has data (albeit blank)- once JQuery returns, the flicker shouldn't happened since everything is defined already (just blank).  If that doesn't work, then bind your RadGrid to the DataSource from ViewData and just use JQuery for the AJAX calls (not page load).  I don't experience the flicker myself, but I'm interested in seeing what helps fix your issue.

-Dallas
0
Zeev
Top achievements
Rank 1
answered on 20 Apr 2009, 04:28 PM
Hi Dallas,

I am trying to follow your example and get RadGrid client side binding to work and ran into problems I don;t know how to solve

when I run my project I get this error:  Microsoft JScript runtime error: '$' is null or not an object

it happens here:

$.getJSON(

 

                '/Home/GetProjects',

 

                { facility: sender.get_value() },

 

                function(data) {

 

                fillGrid(sender, data);

                });


in my Home Controller I define the follwing action:

[

AcceptVerbs(HttpVerbs.Get)]

 

 

public JsonResult GetProjects(int facility)

 

{

 

    IList<Project> projects = new List<Project>()

 

    {

 

        new Project("A", 1),

 

 

        new Project("B", 2)

 

    };

 

    return Json(projects);

 

}


and the project class is defined like this:

public

class Project

 

{

 

    public string Name { get; set;}

 

 

    public int Id { get; set; }

 

 

    public Project(string name, int id)

 

    {

 

        this.Name = name;

 

 

        this.Id = id;

 

    }

}


Can anyone spot what am I missing here ?

Thanks in advance

Zeev


0
Sub
Top achievements
Rank 1
answered on 20 Apr 2009, 04:42 PM
Check your reference to JQuery script file to make sure you specified the correct path.
0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 20 Apr 2009, 04:52 PM
Zeev,

As Sub as said, check your script references.  Go here for Telerik's help on the matter: Telerik + JQuery.

If you already have it defined, then you need to create an alias for JQuery's $.

-Dallas
0
Zeev
Top achievements
Rank 1
answered on 20 Apr 2009, 05:13 PM
Sorry for my previous post, The problem I had was that I did not include JQuery.js in my source.
After doing that I verified the my JavaScript function :

 

function fillGrid(items) {

 

 

var tableView = $find("<%= RadProjects.ClientID %>").get_masterTableView();

 

tableView.set_dataSource(items);

tableView.dataBind();

}


Execute correctly but it does not display the results on the screen.

Any Idea ?

Thanks again
Zeev
0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 20 Apr 2009, 05:21 PM
The next step is to use FireBug to visually inspect the Json returned from your controller.  If the controller is actually returning results, then you should double-check your RadGrid column names making sure they match the Json.

If that doesn't help, then post your Repsonse from FireBug, and your JS code and I'll take a look...

-Dallas
0
Zeev
Top achievements
Rank 1
answered on 20 Apr 2009, 06:19 PM

Hi Dallas,

I followed your advice except that we are not allowed here to use  any other browsers than IE6 for security reasons. In any event I did use Nickhil's Web Development Helper and ran the program and got the follwing response:
[{"Name":"A","Id":1},{"Name":"B","Id":2}]  which I expected. I inspected the DataField values of my DataBoundGrid columns and they match the object property names :

 

 

<Columns>

 

 

    <telerik:GridBoundColumn DataField="Name", HeaderText="Project Name"></telerik:GridBoundColumn>

 

 

    <telerik:GridBoundColumn DataField="Id", HeaderText="Project Id"></telerik:GridBoundColumn>

 

 

</Columns>

 

 

So, I am out of luck again. Is it possible that after this the pageLoad is being invoked again and refill the grid with no data again ?

Here are my two most relevant JS functions:

 

 

function fillGrid(items) {

 

 

var tableView = $find("<%= RadProjects.ClientID %>").get_masterTableView();

 

tableView.set_dataSource(items);

tableView.dataBind();

}

 

function pageLoad() { // you can use JQuery instead: $(document).ready(function() {

 

 

var devices = [];

 

 

/* $(this).data('Devices', devices); */

 

fillGrid(devices);

}

 

and here is the Action in the controller

 

[

AcceptVerbs(HttpVerbs.Get)]

 

 

public JsonResult GetProjects(int facility)

 

{

 

List<Project> projects = new List<Project>()

 

{

 

new Project("A", 1),

 

 

new Project("B", 2)

 

};

 

JsonResult res = Json(projects);

 

 

return res;

 

}

 


Thanks for your help so far it was very helpful, I still seem to miss something here
Zeev

0
Zeev
Top achievements
Rank 1
answered on 20 Apr 2009, 07:31 PM
Hi Again,
I modified the Controller Action to return different # of items based on the input parameter(named facility inthis example) and noticed that the Grid is getting re-painted with the correct numberof rows except that they are empty. Anyone has any idea for possbile reasons why the text doesn't show up in the corrsponding cells ?

Thanks
Zeev
0
Sub
Top achievements
Rank 1
answered on 20 Apr 2009, 09:04 PM
HI Dallas,

I was able to avoid flickering by following Nikolay's suggestion by setting GridDataItem.Display="false" on ItemCreated event. To answer your question "If that doesn't work, then bind your RadGrid to the DataSource from ViewData and just use JQuery for the AJAX calls (not page load).  "

I have many conditional cell formatting that I used to handle in server side ItemDataBound event. Now I have to conver it to client side to make it work with MVC.  The reason why I am loading the grid during initial load in client side is I dont want to write the conditional formatting logic in both client side and server side. I want to write it in one place. I have to update the grid in 3 differnt scenarios:

1. Initial Page load
2. When ever the dropdown selection changes
3. auto refresh the grid every n number of seconds

I am worrying about the client side performance that now I am moving to client side code more simply because of the AJAX call that I need to to to update the grid. Previously I had the grid in AJAXPanel and AJAXTimer does auto refresh.

Another way I am thingking is (not sure whether it would work) have the Grid in a Partial view, make a getJSON call to the Controller to render the partial view that has all the logic to populate the grid.

Also there is a HTML tooltip associated with each cell of the grid for which I used a TooltipManager.

Is there any suggestion from you regarding how to approach this scenario.

I appreciate any feedback!

Thanks
0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 20 Apr 2009, 10:17 PM
Zeev-

From what you've posted, everything looks correct.  If you can, post your entire JS script so we can go over it.  The 2 methods you posted only get the grid to populate to an empty data source on load, and fill the data once the data gets called (you didn't include this vital function, and I suspect this is where the issue lies).  Make sure you are overriding VerifyRenderingInServerForm. Also, are you using server-side binding at all with your ViewData, and are you using ItemCreated for anything (in your case you don't need to)?

Sub-

If your code already works, I would not pull it out in its own PartialView unless you need the place this on multiple pages.  I tried that and the Telerik controls have issues with the Skins and Script References that while can be overcome, the trouble wasn't worth it IMO.

I would keep things as they are, and just use a simple JQuery Timer to achieve what you're after.  The Timer will just call your updateGrid() function and use the JQuery AJAX mechanism already in place.  This works, because I am doing something similar.

-Dallas
0
Zeev
Top achievements
Rank 1
answered on 20 Apr 2009, 10:35 PM
Hi Dallas, Hi Sub

First, I want to thankboth of you for following up on that and really helping out. We really want touse the telerik RadGrid but needed to prove that we can use it with client side binding in MVC and you helped me a great deal doing that.

as far as the last problem I had when data didn;t show up in the grid, it has to do with the way I defiend the DataBoundGrifColumn objects:

I originally defined it like that:

 

<telerik:GridBoundColumn DataField="Name" HeaderText="Project Name"></telerik:GridBoundColumn>

 


then changed it to be defined like that:

 

<telerik:GridBoundColumn DataField="Name" DataFormatString="{0}" HeaderText="Project Name" Display="true"></telerik:GridBoundColumn>

 


and that solved my problem

Thanks again
Zeev
0
Sub
Top achievements
Rank 1
answered on 29 Apr 2009, 03:09 PM

Hi Dallas,

In your ealier post you mentioned this:
" If you want to get fancy, you can also use JQuery's client-side data store to keep the data items locally, so you can do client-side filtering or add rows:"

I am trying to store the JSON object returned by the controller action in a datastore and retrieve it for later use in another function. It looks like the scope of the data store is only with in the funciton. Please clarify. Basically I want to persist the JSON object so after populating the grid if the user clicks a cell I can display more information about it in the tooltip by getting the value form datastore without amking another call to the server. Is there any efficient way to this?

I define it in pageLoad

 

$(

this).data('DataList', result);

 

 

and trying to retrieve it on cell click of the grid as

 

var

 

data = $(this).data('DataList');

 

The data is undefined and is available only with in page load. Please advice!

Thanks
subha

0
Dallas Sehlhorst
Top achievements
Rank 1
answered on 29 Apr 2009, 11:11 PM
Sub,

JQuery's data source works beyond a single function.  The problem you are having is that you're using the "this" alias which is different in your two functions (scope).  To fix it, all you need to do is replace "this" with an actual html element on the form.  I have been using the RadGrid instance and it's been working fine:

var vendors = $($find("<%= radVendors.ClientID %>")).data('Vendors'); 

Hope this helps,

-Dallas
Tags
UI for ASP.NET AJAX in ASP.NET MVC
Asked by
gyelle
Top achievements
Rank 1
Answers by
Sub
Top achievements
Rank 1
Atanas Korchev
Telerik team
Dallas Sehlhorst
Top achievements
Rank 1
Nikolay Rusev
Telerik team
Zeev
Top achievements
Rank 1
Share this question
or