When deleting a row in jqgrid, I would like to return a custom error text when server returns 500 error. I am using jqGrid for ASP.NET, and the grid does not seem to have an "loadError" event
Has anyone done this?
jqGrid is defined like this
<trirand:JQGrid runat="server" ID="Jqgrid" ShrinkToFit="true" Width="900px" Height="500" PagerSettings-PageSize="20" PagerSettings-PageSizeOptions="[20,50,100]" OnSearching="JQGrid_Searching" OnSorting="JQGrid_Sorting" OnRowEditing="JQGrid_RowEditing" OnRowDeleting="JQGrid_RowDeleting">
<Columns>
<trirand:JQGridColumn DataField="ID" PrimaryKey="True" Width="40" Visible="False" />
<trirand:JQGridColumn DataField="NAME" SearchType="DropDown" Width="55" SearchControlID="ddlNameFilter"
HeaderText="Name" Editable="true">
<EditClientSideValidators>
<trirand:RequiredValidator />
</EditClientSideValidators>
</trirand:JQGridColumn>
<trirand:JQGridColumn DataField="DESCR" SearchType="DropDown" Width="55" SearchControlID="ddlDescrFilter"
Searchable="True" HeaderText="Descr" Editable="true">
<EditClientSideValidators>
<trirand:RequiredValidator />
</EditClientSideValidators>
</trirand:JQGridColumn>
<trirand:JQGridColumn HeaderText=" " EditActionIconsColumn="true" Width="50" EditActionIconsEditEnabled="false"
CssClass="clickable" />
</Columns>
<ClientSideEvents LoadComplete="loadComplete" ColumnSort="columnSort" RowDoubleClick="editRow">
</ClientSideEvents>
<ToolBarSettings ShowSearchToolBar="True" ToolBarPosition="TopAndBottom">
</ToolBarSettings>
<PagerSettings NoRowsMessage="No rows to display" />
<ExportSettings ExportDataRange="All" />
</trirand:JQGrid>
The callback loadError are used to process errors during filling/loading of the grid. Form editing methods like delGridRow supports errorTextFormat callback. So is you use navGrid you should define errorTextFormat callback as the method of prmDel parameter of navGrid.
Additionally I would recommend you to use [HandleJsonException] instead of [HandleError] in case of usage ASP.NET MVC (see the answer for details). In other ASP.NET applications you can define the error handler Application_Error in Global.asax.cs (see the answer). The usage of such handles will simplify you the analyse of the error server response inside of errorTextFormat callback because the error information will be returned as JSON.
Related
I'm reacquainting myself with Web Forms programming, using the ubiquitous Northwind database as a backing db for my project. I'm following a simple design pattern for displaying Customers, Products, etc., by displaying a databound gridview at the top of a page, then using the selected row of the gridview to display single item details in a DetailsView. This has been working perfectly well until, for some reason, I started working with a particular table (Suppliers). I am getting the following error:
The display of the Suppliers Gridview itself works perfectly until I add the DetailsView code. My Gridview-related code is as follows:
<asp:GridView ID="gvSuppliers" class="table table-bordered table-condensed table-responsive table-hover" runat="server" AutoGenerateColumns="False"
autogenerateselectbutton="True" AllowPaging="True" DataSourceID="dsSuppliersObjectSource" DataKeyNames="SupplierID" >
<columns>
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" />
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
<asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" />
<asp:BoundField DataField="ContactTitle" HeaderText="ContactTitle" SortExpression="ContactTitle" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="Region" HeaderText="Region" SortExpression="Region" />
<asp:BoundField DataField="PostalCode" HeaderText="PostalCode" SortExpression="PostalCode" />
<asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
<asp:BoundField DataField="Fax" HeaderText="Fax" SortExpression="Fax" />
<asp:BoundField DataField="HomePage" HeaderText="HomePage" SortExpression="HomePage" />
</columns>
</asp:GridView>
<asp:ObjectDataSource ID="dsSuppliersObjectSource" runat="server" EnablePaging="True" SelectMethod="GetSuppliers"
SelectCountMethod="GetSuppliersCount" TypeName="Unknown_Web_Forms.SupplierDS" MaximumRowsParameterName="maxRows"
StartRowIndexParameterName="startIndex">
</asp:ObjectDataSource>
Note I am using an object data source; the relevant code, a method named "GetSuppliers", is a simple LINQ query, which, again, is working just fine:
public List<Supplier> GetSuppliers(int startIndex, int maxRows)
{
using (NorthwindEntities entities = new NorthwindEntities())
{
return (from supplier in entities.Suppliers
select supplier)
.OrderBy(supplier => supplier.SupplierID)
.Skip(startIndex)
.Take(maxRows).ToList();
}
}
So far so good. But then I add my DetailsView and try to wire it to my Gridview's selectedValue as the data source:
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" AutoGenerateRows="False" DataSourceID="SuppliersSingleItemDataSource">
<Fields>
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" />
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="SuppliersSingleItemDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString2 %>"
SelectCommand="SELECT * FROM [Suppliers] WHERE ([SupplierID] = #SupplierID)">
<SelectParameters>
<asp:ControlParameter ControlID="gvSuppliers" DefaultValue="null" Name="SupplierID" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
As soon as I do this, I get the error you see in the opening of this question.
What I have tried:
Some Googling of this suggested I try limiting the columns displayed as BoundFields inside the DetailsView; that maybe there was bad data in the table. I have cut down the number of fields to a bare minimum, the SupplierID, which is an integer primary key and therefore can't be null or a non-integer value. I also kept the company name (a string).
Ensured I have an integer DataKeyName (SupplierID) specified in my gridview and it matches the datatype of the DetailViews' datasource (SupplierID, Int32).
The error message is so unhelpful and generic that I'm running out of ideas on how to solve this. Again, I am using this same technique (DetailsView picking up a Select in a Gridview) for other tables and not having this problem. I have painstakingly compared my technique on the pages that work against this one that doesn't work and cannot see a difference. It seems this should be working. Ideas, anyone?
I was able to solve this on my own. The culprit appears to be having a default value of null in the datasource for the the DetailsView. If I leave the default value out (hey,it was in the tutorial I was following!) the DetailsView won't try to display anything until it gets an actual integer from a click on the gridview. Thought I'd leave my question and answer here in case anybody else runs into this situation. Judging by Google, it is a quite common error.
<asp:SqlDataSource ID="SuppliersSingleItemDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString2 %>"
SelectCommand="SELECT * FROM [Suppliers] WHERE ([SupplierID] = #SupplierID)">
<SelectParameters>
<asp:ControlParameter ControlID="gvSuppliers" Name="SupplierID" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
I am trying to find a way to bind a data table to a tab panel (within a tabcontainer and template) without doing it on page_init or page_load. OR Binding a data table to a gridview then binding that gridview to the tab panel. I know how to bind a data table to a gridview so that's the easy part. I have to be able to - on click of a button - add or create multiple tabs in that tab container.
I want the user to be able to click a button, run some queries and then make the tab container visible and bind the data from a data table to a panel at that time (then the panel to the tab container). Do this multiple times.
Can someone provide an example or explain how I can accomplsih this? Is Update Panel my answer and where can I find some good examples?
UPDATE
I found that it was very easy to bind data to a gridview within Ajax tabs. Of course you needed you script manager ajax reference declared in the asp page and web.config file. You also need to add the ajax css style to an existing style sheet. i tried using a seperate one and it didn't work.
ASP HTML
<AjaxToolkit:TabContainer ID="TabContainer1" runat="server" ActiveTabIndex="0"
Visible="false" ScrollBars="Both"
CssClass="Tab2" Width="1326px" Height="464px" >
<AjaxToolkit:TabPanel ID="TabPanel1" runat="server" HeaderText="Empty" Enabled="true" ScrollBars="Both" CssClass="Tab2">
<ContentTemplate>
<div style="overflow:auto;width:1287px; height: 418px;">
<font color="white" size="1" face="Verdana">
<asp:GridView ID="SalesOrderView1" runat="server" BackColor="White" BorderColor="#DEDFDE"visible="False"BorderStyle="None" BorderWidth="1px"
CellPadding="4" ForeColor="Black"
GridLines="Vertical" HorizontalAlign="Center">
<AlternatingRowStyle BackColor="White" />
<FooterStyle BackColor="#CCCC99" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BackColor="#F7F7DE" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#FBFBF2" />
<SortedAscendingHeaderStyle BackColor="#848384" />
<SortedDescendingCellStyle BackColor="#EAEAD3" />
<SortedDescendingHeaderStyle BackColor="#575357" />
</asp:GridView>
</div>
</font>
</ContentTemplate>
</AjaxToolkit:TabPanel>
<AjaxToolkit:TabPanel ID="TabPanel2" runat="server" HeaderText="Empty" ScrollBars="Both" CssClass="Tab2">
<ContentTemplate >
</AjaxToolkit:TabContainer>
C# Code to bind data to the gridview on click button event.
SalesOrderView1.Visible = true;
TabPanel1.Visible = true;
TabPanel1.HeaderText = Order_List[multi_order_count];
I am trying to conditionally update my updatepanel based on changes that have been made to my gridview. I am having trouble. This is inside the BugsGridView_RowUpdated function.
if ( /*Changes have been made to gridview */)
{
ActivityUpdatePanel.Update();
}
Thanks!
Did you try assigning your GridView as a trigger of your UpdatePanel in you aspx?
<asp:UpdatePanel ID="ActivityUpdatePanel" runat="server">
<ContentTemplate>
<asp:GridView ID="BugsGridView" runat="server" AutoGenerateColumns="false">
<Columns>
...
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="BugsGridView" EventName="RowUpdated" />
</Triggers>
</asp:UpdatePanel>
I am not sure about the event name RowUpdated though.
Edit: maybe the correct event is RowUpdating
I'm using GridView and there is a dropdownlist in header cell for filtering.
<gm:GridView ID="routePlanGridView" runat="server" AutoGenerateColumns="False"
AllowPaging="true" PageSize="20" GridLines="Both" ShowFooter="true" CssClass="grid"
DataKeyNames="RoutePlanId" OnSorting="routePlanGridView_Sorting"
AllowSorting="true" OnPageIndexChanging="routePlanGridView_PageIndexChanging"
OnSelectedIndexChanging="routePlanGridView_SelectedIndexChanging"
OnRowDataBound="routePlanGridView_RowDataBound"
OnRowEditing="routePlanGridView_RowEditing"
OnRowUpdating="routePlanGridView_RowUpdating">
<HeaderStyle CssClass="gridHeaderFooter" />
<FooterStyle CssClass="gridHeaderFooter" />
<RowStyle CssClass="gridRow" />
<AlternatingRowStyle CssClass="gridRowAlternate" />
<Columns>
<asp:TemplateField SortExpression="SPName">
<HeaderTemplate>
SP Name<br />
<asp:DropDownList ID="spNameFilterDDL" runat="server" CssClass="gridControl" AutoPostBack="true" DataSourceID="SPNameSDS" DataTextField="SPName" OnDataBound="filterDDL_DataBound" OnSelectedIndexChanged="spNameFilterDDL_SelectedIndexChanged" />
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="spNameLabel" runat="server" Text='<%# Bind("SPName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<...15 more...>
</Columns>
</gm:GridView>
and there are relevant event handlers for sorting and paging.
Now the problem is if I put "SP Name" text in a link button, page crashes when link clicked, otherwise no link produced to sort.
If I remove Header Template fields (all of them) and put a text with HeaderText attribute of TemplateField it works as expected. Is there a way to put them together? I need that dropdown and also sorting.
Thanks.
sorry, forgot to insert the code correctly - here:
<asp:LinkButton runat="server" Text="SP Name" CommandName="Sort" CommandArgument="SPName" ></asp:LinkButton>
You need to use a link button for your header text. So in place of "SP Name", use . It should work if you are handling sorting.
Trying to update RadDock (open/close it) by putting it in UpdatePanel however no luck....I'm getting the following response.
189|error|500|Invalid JSON primitive: {"Top":179,"Left":583,"DockZoneID":"","Collapsed":false,"Pinned"
:false,"Resizable":false,"Closed":false,"Width":"300px","Height":null,"ExpandedHeight":0,"Index":-1}
.|
Here is the code:
<asp:UpdatePanel ID="upanelDock" runat="server">
<ContentTemplate>
<telerik:RadDock ID="RadDock1" runat="server" Width="300px">
<TitlebarTemplate>
<h2>
this is a dock</h2>
</TitlebarTemplate>
<ContentTemplate>
some content here
<br />
some content here
<br />
some content here
<br />
</ContentTemplate>
</telerik:RadDock>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="lbtnUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:LinkButton ID="lbtnUpdate" runat="server" OnClick="lbtnUpdate_Click">update</asp:LinkButton>
Code behind:
protected void lbtnUpdate_Click(object sender, EventArgs e)
{
if (this.RadDock1.Closed)
this.RadDock1.Closed = false;
else
this.RadDock1.Closed = true;
}
What am I doing wrong here?
UPDATE: You are not doing anything wrong in your code. I was able to duplicate this problem using both UpdatePanel and RadAjaxManager. According to Telerik support, this is a "limitation" in the RadDock control. More like a bug in my opinion.
Here's what it says in their Support Page Forum: Non-docked Docks cloned plus Invalid JSON primitive
The RadDock control is not a standard
control and there are some limitations
when it is updated via ajax. If you
want to update a RadDock via ajax you
should update all RadDockZones and all
RadDocks should be docked.
The error you experience is due to
that you update a floating RadDock
with AJAX. When dragging the dock you
move it outside the update panel and
this causes AJAX not working properly
as it attempts to recreate the dock at
the place it was previously located.
In this way two docks with the same id
appear on the page and this leads to
an exception. This is a common problem
for all controls which could be moved
in the DOM.
I was able to make your code work by wrapping the RadDock inside a RadDockZone and setting the DockMode property to "Docked". If however, I drag the dock out of the zone, leave it floating and click the "Update" button, the error reappears.
<asp:UpdatePanel ID="upanelDock" runat="server">
<ContentTemplate>
<telerik:RadDockZone runat="server">
<telerik:RadDock ID="RadDock1" runat="server" Width="300px"
DockMode="Docked">
<TitlebarTemplate>
<h2>
this is a dock
</h2>
</TitlebarTemplate>
<ContentTemplate>
some content here
<br />
some content here
<br />
some content here
<br />
</ContentTemplate>
</telerik:RadDock>
</telerik:RadDockZone>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="lbtnUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:LinkButton ID="lbtnUpdate" runat="server"
OnClick="lbtnUpdate_Click">update</asp:LinkButton>
I have a couple RadDocks floating inside a RadDockLayout. Ajax works if I update the RadDock, the RadDockLayout, or the main panel that wraps the RadDockLayout through the RadAjaxManager object.
Ex:
<telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="mainPanel" />
</UpdatedControls>
</telerik:AjaxSetting>