Telerik Forums
UI for ASP.NET AJAX Forum
1 answer
188 views
So I have a very simple RadGrid (no heirarchy) and a very simple RadTreeView. I followed the code example in one of the demos I cannot seem to find now. But here are the oddities in my situation:
  1. Everything about the RadTreeView seems to work just fine.
  2. The RadGrid Columns are created programtically whilst the rest of the radGrad is done design time.
  3. Eight of the thirteen or so columns are GridTemplateColumns.

The page keeps giving me an error after the page has rendered in the browser when it tries to seemingly instantiate this simple custom remove link. The error comes in the line here and caused by the fact that cItem.DataItem has a null value. Keep in mind the code has passed through the same code path twice already (prior to the rendering) and it is not until this third time (post-render) that the cItem.DateItem is set to nul. Another interesting note, the KeyValues remains unchanged ( KeyValues "{BuildGuid:\"7278f75e-4712-8f38-c598-b9a144c2a9fc\"}" string) in all three passes through the code path during the life cycle of the page.

Link.CommandArgument = (string)((DataRowView)cItem.DataItem)["BuildGuid"].ToString(); 

Here is the entire template object:

    public partial class BuildRemoveLinkButton : ITemplate  
    {  
        protected LinkButton Link;  
        private string ColumnName;  
 
        public BuildRemoveLinkButton(string ColumnNameInput)  
        {  
            this.ColumnName = ColumnNameInput;  
        }  
 
        public void InstantiateIn(Control container)  
        {  
            GridDataItem cItem = container.Parent as GridDataItem;  
            if (cItem != null)  
            {  
                Link = new LinkButton();  
                Link.Text = "remove";  
                Link.ToolTip = "Remove this build from the view";  
                Link.CommandArgument = (string)((DataRowView)cItem.DataItem)["BuildGuid"].ToString();  
                Link.ID = String.Format("Remove-{0}", this.ColumnName);  
                Link.CommandName = ColumnName;  
                container.Controls.Add(Link);  
            }  
        }  
    } 

Just to remind you, the page and RadGrid have already rendered in the browser. Here is the RadGrid defintion:

<telerik:RadGrid ID="CompareGrid" runat="server" AutoGenerateColumns="false" 
    ShowStatusBar="true" AllowSorting="true" OnNeedDataSource="CompareGrid_NeedDataSource" 
    OnItemCommand="CompareGrid_ItemCommand" EnableViewState="false">  
    <MasterTableView DataKeyNames="BuildGuid" Width="680" CommandItemDisplay="Top" 
        EnableColumnsViewState="false">  
        <HeaderStyle HorizontalAlign="Center"/>  
        <ItemStyle HorizontalAlign="Center" /> 
        <AlternatingItemStyle HorizontalAlign="Center" /> 
        <CommandItemTemplate> 
            <telerik:RadToolBar ID="CompareToolBar" runat="server" 
                OnButtonClick="CompareToolBar_OnButtonClick">  
                <Items> 
                    <telerik:RadToolBarButton  
                        Text="Add all builds from tree" 
                        CommandName="ShowAll" /> 
                    <telerik:RadToolBarButton IsSeparator="true" /> 
                    <telerik:RadToolBarButton  
                        Text="Remove all builds from grid" 
                        CommandName="ShowAll" /> 
                </Items> 
            </telerik:RadToolBar> 
        </CommandItemTemplate> 
    </MasterTableView> 
    <ClientSettings> 
        <Scrolling AllowScroll="true" UseStaticHeaders="true" /> 
        <ClientEvents OnColumnCreated="GridCreated" /> 
    </ClientSettings> 
</telerik:RadGrid> 

Here also is the column creation code which is called during Page_Init:

    private void CompareGrid_DefineGrid()  
    {  
        // Create the columns for the Grid.  
 
        // Add LinkButton column.  
        GridTemplateColumn removeColumn = new GridTemplateColumn();  
        removeColumn.ItemTemplate = new BuildRemoveLinkButton("BuildRowRemove");  
        removeColumn.UniqueName = "BuildRowRemove";  
        removeColumn.DataField = "BuildRowRemove";  
        CompareGrid.MasterTableView.Columns.Add(removeColumn);  
 
        // Add columns programtically.  
        GridBoundColumn boundColumn = new GridBoundColumn();  
        boundColumn.UniqueName = "BuildName";  
        boundColumn.DataField = "BuildName";  
        boundColumn.HeaderText = "Build Name";  
        CompareGrid.MasterTableView.Columns.Add(boundColumn);  
 
        // Add checkbox column.  
        GridTemplateColumn checkColumn = new GridTemplateColumn();  
        checkColumn.HeaderTemplate = new HeaderCheckBox();  
        checkColumn.ItemTemplate = new BuildSelectCheckBox("BuildSelect");  
        checkColumn.UniqueName = "BuildSelect";  
        checkColumn.HeaderText = "Build Select";  
        checkColumn.DataField = "BuildSelect";  
        CompareGrid.MasterTableView.Columns.Add(checkColumn);  
 
        // Add build guid hidden column.  
        boundColumn = new GridBoundColumn();  
        boundColumn.UniqueName = "BuildGuid";  
        boundColumn.DataField = "BuildGuid";  
        boundColumn.Display = false;  
        boundColumn.HeaderText = "Build Guid";  
        CompareGrid.MasterTableView.Columns.Add(boundColumn);  
 
        // Add columns for each gate.  
        GridTemplateColumn buttonColumn;  
        foreach (GateDefinition definition in RIGates.Gates)  
        {  
            buttonColumn = new GridTemplateColumn();  
            buttonColumn.ItemTemplate = new GateResultImageButton(definition.DataName);  
            buttonColumn.HeaderTemplate = new GateCompareLinkButton(definition.DataName, definition.Name);  
            buttonColumn.UniqueName = definition.DataName;  
            buttonColumn.DataField = definition.DataName;  
            buttonColumn.Reorderable = true;  
            CompareGrid.MasterTableView.Columns.Add(buttonColumn);  
        }  
    } 

Finally, here is the call stack causeing the error after the page has rendered...
>   BuildQuality.DLL!BuildQuality.Templates.BuildRemoveLinkButton.InstantiateIn(System.Web.UI.Control container = {Telerik.Web.UI.GridTableCell}) Line 53   C#  
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridTemplateColumn.InitializeCell(System.Web.UI.WebControls.TableCell cell = {Telerik.Web.UI.GridTableCell}, int columnIndex = 2, Telerik.Web.UI.GridItem inItem = {Telerik.Web.UI.GridDataItem}) + 0x23d bytes     
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridItem.Initialize(Telerik.Web.UI.GridColumn[] columns = {Telerik.Web.UI.GridColumn[16]}) + 0x91 bytes     
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridItem.SetupItem(bool dataBind = false, object dataItem = null, Telerik.Web.UI.GridColumn[] columns = {Telerik.Web.UI.GridColumn[16]}, System.Web.UI.ControlCollection rows = {System.Web.UI.WebControls.Table.RowControlCollection}) + 0xdb bytes    
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridItemBuilder.InitializeItem(int dataSourceIndex = 0, out string nextItemHierarchicalIndex = "0", out bool itemIsInEditMode = false) + 0xfc bytes     
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridItemBuilder.CreateItems(Telerik.Web.UI.GridGroupingContext group = {Telerik.Web.UI.GridGroupingContext}) + 0x243 bytes      
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridTableView.CreateItems(System.Collections.IEnumerator enumerator = {Telerik.Web.UI.GridDummyDataSource.GridDummyDataSourceEnumerator}, Telerik.Web.UI.GridColumn[] columns = {Telerik.Web.UI.GridColumn[16]}, System.Web.UI.ControlCollection controls = {System.Web.UI.WebControls.Table.RowControlCollection}) + 0xc2 bytes    
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridTableView.CreateControlHierarchy(bool useDataSource = false) + 0x647 bytes      
    Telerik.Web.UI.DLL!Telerik.Web.UI.GridTableView.CreateChildControls(System.Collections.IEnumerable dataSource = {System.Web.UI.WebControls.DummyDataSource}, bool useDataSource = false) + 0x33a bytes    
    System.Web.dll!System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls() + 0xa2 bytes     
    System.Web.dll!System.Web.UI.Control.EnsureChildControls() + 0x67 bytes   
    System.Web.dll!System.Web.UI.Control.FindControl(string id = "CompareGrid$ctl00$ctl02$ctl00$CompareToolBar", int pathOffset = 18) + 0x15 bytes    
    System.Web.dll!System.Web.UI.Control.FindControl(string id, int pathOffset) + 0x16e bytes     
    System.Web.dll!System.Web.UI.Control.FindControl(string id, int pathOffset) + 0x16e bytes     
    System.Web.dll!System.Web.UI.Page.FindControl(string id) + 0x27 bytes     
    System.Web.dll!System.Web.UI.Page.ProcessPostData(System.Collections.Specialized.NameValueCollection postData, bool fBeforeLoad = true) + 0x2c6 bytes     
    System.Web.dll!System.Web.UI.Page.ProcessRequestMain(bool includeStagesBeforeAsyncPoint = true, bool includeStagesAfterAsyncPoint = true) + 0x36f bytes   
    System.Web.dll!System.Web.UI.Page.ProcessRequest(bool includeStagesBeforeAsyncPoint, bool includeStagesAfterAsyncPoint = true) + 0x8d bytes   
    System.Web.dll!System.Web.UI.Page.ProcessRequest() + 0x4f bytes   
    System.Web.dll!System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext context) + 0x16 bytes     
    System.Web.dll!System.Web.UI.Page.ProcessRequest(System.Web.HttpContext context) + 0x32 bytes     
    App_Web_dsf31s5x.dll!ASP.default_aspx.ProcessRequest(System.Web.HttpContext context = {System.Web.HttpContext}) + 0x33 bytes    C#  
    System.Web.dll!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x65 bytes   
    System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {System.Web.HttpApplication.CallHandlerExecutionStep}, ref bool completedSynchronously = true) + 0x4c bytes    
    System.Web.dll!System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(System.Exception error) + 0x13e bytes    
    System.Web.dll!System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object extraData) + 0xad bytes    
    System.Web.dll!System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x1a2 bytes    
    System.Web.dll!System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest wr) + 0x7d bytes    
    System.Web.dll!System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest wr) + 0x47 bytes    
    WebDev.WebHost40.dll!Microsoft.VisualStudio.WebHost.Request.Process() + 0x17b bytes   
    WebDev.WebHost40.dll!Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Microsoft.VisualStudio.WebHost.Connection conn = {System.Runtime.Remoting.Proxies.__TransparentProxy}) + 0x6c bytes   
    [Appdomain Transition]    
    WebDev.WebHost40.dll!Microsoft.VisualStudio.WebHost.Server.OnSocketAccept(object acceptedSocket) + 0x83 bytes     
    mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) + 0x2d bytes   
    mscorlib.dll!System.Threading.ExecutionContext.runTryCode(object userData) + 0x51 bytes   
    [Native to Managed Transition]    
    [Managed to Native Transition]    
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6a bytes      
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0x7e bytes      
    mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() + 0x5a bytes   
    mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x147 bytes    
    mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x2d bytes      
    [Native to Managed Transition]    
 

 Any help/insights someone may have will be greatly appreciated.
Yavor
Telerik team
 answered on 03 Jun 2010
1 answer
151 views
My page :

 <telerik:RadFormDecorator ID="RadFormDecorator1" runat="server" DecoratedControls="Textbox, Textarea,Buttons,Scrollbars" /> 
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">    
    <telerik:AjaxSetting AjaxControlID="toolbar">  
                <UpdatedControls> 
                   <telerik:AjaxUpdatedControl ControlID="pnlDetail" LoadingPanelID="rlpDefault" /> 
                </UpdatedControls> 
            </telerik:AjaxSetting> 
        </AjaxSettings> 
    </telerik:RadAjaxManager> 
    <telerik:RadAjaxLoadingPanel ID="rlpDefault" runat="server" /> 
 
 <telerik:RadToolBar ID="toolbar" runat="server" Width="100%" > 
   <%--- toolbar content   ----%> 
 </telerik:RadToolBar> 
 
<telerik:RadWindow  ID="rwDetail" ...> 
  <ContentTemplate> 
  <asp:Panel id="pnlDetail" runat="server">
   <asp:TextBox ID="tbxGridId" runat="server" Width="250px"></asp:TextBox> 
   <%--- other Content ---%> 
   </asp:Panel>
</ContentTemplate> 
<telerik:RadWindow>   
       
 
 
Click toolbar button , I use client script to  open the window first.  The button's postback is true, then on server side ,get data from database to update the detail panel.  The Code works well.
But the FormDecorator can  not apply to the textbox correctly. (see the attached file)

if I open the window by sending the  javascript to client after update the detail panel on server side, the textbox display correctly.
but this is not I want , because I want the user can see the loading procedure.

any suggestion?
Bozhidar
Telerik team
 answered on 03 Jun 2010
3 answers
179 views
Hi

Changing the width of the Hyperlink Manager / LinkManager.ascx, has no effect.

radEditor.DialogOpener.Width = new Unit(450, UnitType.Pixel);

or

radEditor.DialogOpener.Window.Width = new Unit(450, UnitType.Pixel);

The LinkManager.ascx is customized

Is it possible to change the width ?

/Erik K
Rumen
Telerik team
 answered on 03 Jun 2010
2 answers
148 views
Hi All

I am using Radeditor for one of my applications. I have added toolbar item to radeditor. But the issue is the realfontsize shows only font size in pixels. Is there a way around to get the font size in points.

Any help will be much appreciated.

Thanks
Ricky
Ricky
Top achievements
Rank 2
 answered on 03 Jun 2010
3 answers
95 views
I have a radgrid which gets bound to a dataset returned by a stored procedure. I have 3 hyperlink 'options' that gets generated dynamically from the DB. Instead of creating 3 columns with links, I just wanted a dropdownlist that users can select from and a button that will trigger the redirect to a page referenced by the links.

Also, I added the button on the template column but can't get it to display , I'll just create an image button then on another template column. But on the on-click event, when I do a findcontrol, I can't seem to see the radcombobox so I can reference the selected value and redirect the user to the link. Please advise. Code samples would help. Thanks!

I have code similar to below:

 

 

<telerik:GridTemplateColumn HeaderText="Options" UniqueName="Options">

 

 

 

<ItemTemplate>

 

 

 

<telerik:RadComboBox ID="rcbOptions" runat="server" AllowCustomText="True"

 

 

 

HighlightTemplatedItems="True" EmptyMessage="(Select)">

 

 

 

<Items>

 

 

 

<telerik:RadComboBoxItem Text="Option1" Value='<%#Eval("URL1") %>' />

 

 

 

<telerik:RadComboBoxItem Text="Option2" Value='<%#Eval("URL2") %>' />

 

 

 

<telerik:RadComboBoxItem Text="Option3" Value='<%#Eval("URL3") %>' />

 

 

 

</Items>

 

 

 

</telerik:RadComboBox>

 

 

 

</ItemTemplate>

 

 

 

</telerik:GridTemplateColumn>


 

Radoslav
Telerik team
 answered on 03 Jun 2010
1 answer
130 views
I need to select the date from RadDatepicker in single click. But now I need to double click to select the date. Could you please help me to fix this issue ?

Thanks
Ragupathi
Shinu
Top achievements
Rank 2
 answered on 03 Jun 2010
1 answer
112 views

Dears,

I am using RadTree in my web page, I want to ask a user before moving from selected node to another
"Do you want to save changes?"  and give hime the following button options: Yes, No, and Cancel. Becuase javascript confirm has only Ok and cancel button, I used radconfirm and change the template as the following:

 

<ConfirmTemplate>

 

 

<div style="text-align: center">

 

{1}

 

<br />

 

 

<br />

 

 

<input id="btnYes" type="button" value="Yes" onclick="$find('{0}').close(true);" />

 

 

<input id="btnNo" type="button" value="No" onclick="$find('{0}').close(false);" />

 

 

<input id="btnCancel" type="button" value="Cancel" onclick="$find('{0}').close(null);" />

 

 

</div>

 

 

</ConfirmTemplate>

the radconfirm is ok, and it returns null when user click on "Cancel" button. but the problem is I have to call the radconfirm inside the treeview ClientNodeClicking event, and radconfirm has CallBackFunction, and in CallBackFunction I can not execute:

 

eventArgs.set_cancel(true);

becuase eventArgs is avilable only in ClientNodeClicking.
So, could you please help me in that.
Yana
Telerik team
 answered on 03 Jun 2010
1 answer
61 views

I am trying to inherit GridBoundColumn.

where i override preparecell method.

I am putting an ImageButton  in GridDataItem.

now i need to fire owner grid ItemCommand event on this ImageButton's  Click event.

How can i do that?

check out this code.

[ToolboxData("<{0}:ActiveDeactiveColumn runat=server></{0}:ActiveDeactiveColumn>")]
    public class ActiveDeactiveColumn : GridBoundColumn
    {
        public override void PrepareCell(TableCell cell, GridItem item)
        {
          
            if (item is GridHeaderItem)
            {
                Literal lt = new Literal();

                lt.Text = this.HeaderText;

                cell.Controls.Add(lt);
            }

            if (item is GridDataItem)
            {

                ImageButton imgBtn = new ImageButton();

                bool value = (Boolean)DataBinder.Eval(item.DataItem, this.DataField);

                String url = value ? "OSS.Resources.tick.gif" : "OSS.Resources.cross.gif";

                imgBtn.ImageUrl = this.Owner.OwnerGrid.Page.ClientScript.GetWebResourceUrl(this.GetType(), url);

                imgBtn.OnClientClick = "return confirm('Are you sure want to " + (value ? "deactivate" : "activate") + " this record?')";

                imgBtn.CommandName = value ? "deactivate" : "activate";

                //What should be written Here?
                //imgBtn.Click += ""???
               // how can i bind this.owner.ownerGrid.ItemCommand (RadGrid.ItemCommand) event to this ImageButton event?
               
                cell.Controls.Add(imgBtn);
 
            }   

        }
    }




Mira
Telerik team
 answered on 03 Jun 2010
3 answers
515 views

While I'm at it . . .

I have an edit form template which is nested in a panel bar.  I'm having trouble accessing the form objects in the template from the code behind.  Here is the panel bar/grid/template:

 

<telerik:RadPanelBar runat="server" ID="panelDisputeHistory" Skin="Web20" Width="98%">  
                <CollapseAnimation Type="None"></CollapseAnimation> 
                    <Items> 
                        <telerik:RadPanelItem Text="Dispute History" Expanded="False">  
                            <Items> 
<telerik:RadPanelItem Text="" Value="pnlItemDisputeHistory">  
                                    <ItemTemplate> 
                                        <div> 
                                            <!-- Begin dispute history section -->         
                                            <telerik:RadGrid ID="grdDisputes" runat="server" DataSourceID="sqlDisputes" Skin="Default" 
                                            AllowPaging="false" AllowSorting="True" 
                                            FilterItemStyle-HorizontalAlign="center" Width="700px" Height="400px"   
                                            ShowStatusBar="false" GridLines="Both" 
                                            AutoGenerateColumns="False" HeaderStyle-Font-Size="X-Small" HorizontalAlign="NotSet"   
                                            OnUpdateCommand="grdDisputes_UpdateCommand" CommandItemDisplay="Top"   
                                            OnInsertCommand="grdDisputes_InsertCommand" OnDeleteCommand="grdDisputes_DeleteCommand" OnItemDataBound="grdDisputes_ItemDataBound">    
<MasterTableView DataSourceID="sqlDisputes" PageSize="50" 
                                                    Width="700px" DataKeyNames="ID" ItemStyle-Font-Size="X-Small">    
                                                    <Columns> 
</Columns> 
<EditFormSettings EditFormType="Template">  
                                                         <EditColumn uniquename="EditCommandColumn1"></EditColumn> 
                                                         <FormTemplate> 
                                                              
                                                            <table width="100%" cellpadding="2" cellspacing="2" border="0" class="standard_table_no_border">  
                                                                <tbody>                                                              
                                                                    <tr> 
                                                                        <td style="" colspan="3">Invoice Amount  
                                                                            <asp:TextBox ID="txtInvoiceAmt" runat="server" width="50" Font-Size="X-Small"  Text='<%#Eval("INVOICE_AMT", "{0:n2}") %>'></asp:TextBox>&nbsp;  
</td> 
                                                                    </tr>   
 </tbody> 
                                                            </table> 
</FormTemplate> 
                                                         <PopUpSettings ScrollBars="None" /> 
                                                    </EditFormSettings>   
                                                      
                                                </MasterTableView> 
                                            </telerik:RadGrid> 
                                            <!-- End dispute section -->                                      
                                        </div> 
                                    </ItemTemplate> 
                                </telerik:RadPanelItem> 
                            </Items> 
                        </telerik:RadPanelItem>                  
                    </Items> 
                <ExpandAnimation Type="None"></ExpandAnimation> 
            </telerik:RadPanelBar>             

I've tried a dozen different ways of accessing txtInvoiceAmt, none with success.  The basis of my attempts is some form of:

TextBox txtInvoiceAmt = (TextBox)panelDisputeHistory.FindItemByValue("pnlItemDisputeHistory").FindControl("grdDisputes").FindControl("txtInvoiceAmt");  
 

 

Nothing seems to work.  Any ideas?

 

Thanks again.

 

Rich

PV
Top achievements
Rank 1
 answered on 03 Jun 2010
1 answer
78 views

I have developed a webpart in SharePoint Foundation 2010, and use RadGrid control in it. I have following codes:
Panel pnl = new Panel();

 

pnl.ID =

"Panel1";

 

pnl.Attributes.Add(

"style", "Overflow-x:auto");

 

pnl.Width = System.Web.UI.WebControls.Unit.Percentage(100);
pnl.Controls.Add(radGridInstance);
It runs well first. But after scrolling, UI RadGrid appears  a vertical line and no border in header.
I have no set skin of RadGrid.
I have a attached screenshot.
Thanks in advance.
Tuan

 

Mira
Telerik team
 answered on 03 Jun 2010
Narrow your results
Selected tags
Tags
+? more
Top users last month
Jake
Top achievements
Rank 1
RBarnes
Top achievements
Rank 1
Iron
Iron
Rami
Top achievements
Rank 1
Iron
Veteran
Nathan
Top achievements
Rank 1
Kumeri
Top achievements
Rank 1
Iron
Veteran
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Jake
Top achievements
Rank 1
RBarnes
Top achievements
Rank 1
Iron
Iron
Rami
Top achievements
Rank 1
Iron
Veteran
Nathan
Top achievements
Rank 1
Kumeri
Top achievements
Rank 1
Iron
Veteran
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?