Telerik Forums
UI for ASP.NET AJAX Forum
1 answer
87 views
I am trying to use radmenu to create a custom looking menu that will have 2nd and 3rd level dropdowns.

I've attached an image of what the menu should look like.

My question is, what direction should I go with trying to do this?

I believe I could
1) go with no skin, and just try to override things with CSS declarations.
2) go with a custom skin, and try to build everything I want in terms of appearance into the custom skin
3) use all item templates and define the elements in there.

With my really limited knowledge of these topics I'm leaning toward using item templates, where I think I should be able to control the look of these things pretty well, but I may be wrong.

Can anyone give me some advice?
Cori
Top achievements
Rank 2
 answered on 08 Feb 2011
1 answer
72 views
I have what on the surface looks like a fairly simple scenario. I have a textbox validated by a radinputmanager via a webservice. This allows the user to enter a produce code. If the code is valid then I want to populate some values with the textboxes textchanged event.

Heres what I have:

<asp:TextBox ID="ProductReferenceTextBox" runat="server" Text='<%#Bind("ProductReference") %>' MaxLength="8"
                            AutoPostBack="true" OnTextChanged="ProductReferenceTextBox_TextChanged" />
 
<t:RadInputManager ID="MainInputManager" runat="server">
        <t:TextBoxSetting BehaviorID="ProductReferenceBehavior" Validation-Method="ValidateProductCode"
            Validation-Location="ValidationServices/ProductService.asmx" Validation-ValidateOnEvent="All" Validation-IsRequired="true" />
protected void ProductReferenceTextBox_TextChanged(object Sender, EventArgs E)
{
TextBox oSender = (TextBox)Sender;
 
if (IocContainer.ProductDao.Exists(oSender.Text))
{
  Product eProduct = IocContainer.ProductDao.GetProduct(oSender.Text);
 
    GridDataInsertItem oContainer = (GridDataInsertItem)oSender.NamingContainer;
 
  Label oLabel = (Label)oContainer.Controls[5].Controls[0];
 
  oLabel.Text = eProduct.StockUnit;
  }
  }

This is fine if the code entered is valid, but if the code is invalid (i.e. the webservice validation fails) I don't want to postback to the textchanged event.

Is there any way to do this?

Thanks
Martin
Telerik team
 answered on 08 Feb 2011
1 answer
45 views
Hi.
I'm developing an ASP.NET app using the Q1 2010 version.
The app is deployed in a testing server in the local network. I've a page with 2 raddatepicker. When I test in Firefox I've no problem, but when I work in I.E. 8 (with proxy with exceptions for local URL's) the second raddatepicker doesn't work (the popup button is like "disabled"). Curiously when I disable the proxy option in I.E. 8, the compatibility view is active (I can use it with proxy) and both raddatepicker works fine.
I try to use the microsoft support solution including several ways to use emulation in I.E 7 (using headers in IIS or metatags in aspx files) but nothing works with proxy on.
Any suggestion?

Arseni
Top achievements
Rank 1
 answered on 08 Feb 2011
1 answer
300 views
hello everyone,
I have stuck on the issue of changing the background color of rad-scheduler appointments, based on a value. My scenario is as,
I have a class named as <appointments> which contains the following properties StartDate,EndDate,TaskId,TaskName and Status.
The appointments class is the data source of scheduler.
I want to change the background -color of appointments compairing the values in status field, but at the same time status should not be shown.
advance thnx.

scheuler.ascx
<telerik:RadScheduler ID="calTaskDisplay" runat="server" DataEndField="EndDate" DataKeyField="TaskId"
                    DataStartField="EndDate" DataSubjectField="TaskName" OnAppointmentCreated="calTaskDisplay_AppointmentCreated"
                    OnDataBound="calTaskDisplay_DataBound" AllowDelete="False" AllowEdit="False" SelectedView="MonthView"
                    DayStartTime="09:00:00" DisplayDeleteConfirmation="False" EditFormDateFormat="d/M/yyyy"
                    EnableAdvancedForm="False" EnableViewState="False" FirstDayOfWeek="Monday" LastDayOfWeek="Friday"
                    WorkDayEndTime="17:00:00" EnableCustomAttributeEditing="true" CustomAttributeNames="status"
                    WorkDayStartTime="09:00:00" OnAppointmentDataBound="calTaskDisplay_AppointmentDataBound">
                    <DayView DayStartTime="09:00:00" ShowHoursColumn="False" WorkDayEndTime="17:00:00" />
                    <WeekView DayStartTime="09:00:00" WorkDayStartTime="09:00:00" WorkDayEndTime="17:00:00" />
                    <AppointmentTemplate>
                        <%#Eval("Subject")%>
                        <input type="text" id="lblStatus" visible="false" title='<%# Eval("Status") %>' />
                    </AppointmentTemplate>
                </telerik:RadScheduler>

codebehind as,
scheduler.ascx.cs
Page_Load()
{
List<ScheduledTasks> loOtherTasks = loClient.GetScheduledTasks(Session["UserId"].ToString());
                calTaskDisplay.DataSource = loOtherTasks;
                calTaskDisplay.DataBind();
}
calTaskDisplay_AppointmentDataBound(object sender, SchedulerEventArgs e)
{
 switch (e.Appointment.Attributes["Status"])
            {
                case "Pending": e.Appointment.BackColor = System.Drawing.Color.Red;
                    break;
                case "pending": e.Appointment.BackColor = System.Drawing.Color.Red;
                    break;
                case "Complete": e.Appointment.BackColor = System.Drawing.Color.Green;
                    break;
                case "complete": e.Appointment.BackColor = System.Drawing.Color.Green;
                    break;
                case "Over due": e.Appointment.BackColor = System.Drawing.Color.Red;
                    break;
                case "over due": e.Appointment.BackColor = System.Drawing.Color.Red;
                    break;
                case "Started": e.Appointment.BackColor = System.Drawing.Color.Blue;
                    break;
                case "started": e.Appointment.BackColor = System.Drawing.Color.Blue;
                    break;
                default:
                    break;
}
 
calTaskDisplay_DataBound(object sender, EventArgs e)
{
foreach (ResourceType resType in calTaskDisplay.ResourceTypes)
            {
                resType.AllowMultipleValues = false;
            }
}
Princy
Top achievements
Rank 2
 answered on 08 Feb 2011
1 answer
236 views
Hi,

I have two questions regarding opening a rad window.  Please note in both scenario's I don't want to use the radalert or radconfirm dialog boxes, I want to be able to display my own message box.

First question, I have a page with a radgrid and am using linkbuttons in the CommandItemTemplate to perform add/updates/deletes and everything works great. When a user adds a new record, I perform validation that checks for a duplicate value against the database or a null value.  If a duplicate'null value is found then I open a radwindow that displays a message to the user that a duplicate/null value has been found and again this works great. The problem is that when the radwindow opens a postback occurs.  I don't want this to happen.

I have read the article Calling radalert from codebehind (all versions of RadWindow) and cannot figure out how top apply this to my code.  The scenario where I am calling the radwindow is a little different.  The code that opens the the rad window is in another module.

Here is the code that calls the radwindow;
<CommandItemTemplate >
                   <div style="padding: 5px 5px;">
                       <asp:LinkButton ID="lbtAdd"          runat="server" CommandName="InitInsert"     Visible='<%# Not rgvSecurityGroups.MasterTableView.IsItemInserted %>'><asp:Image ID="imgAdd" runat="server" CssClass="css_GFS01_Image_Align" ImageURL="<%$ Resources:Images,AddGreen16%>" /> Add </asp:LinkButton>  
                       <asp:LinkButton ID="btnEditSelected" runat="server" CommandName="EditSelected"   Visible='<%# rgvSecurityGroups.EditIndexes.Count = 0 and Not rgvSecurityGroups.MasterTableView.IsItemInserted %>'>          <asp:Image runat="server" CssClass="css_GFS01_Image_Align" ImageURL="<%$ Resources:Images, EditGreen16%>"/> Edit </asp:LinkButton>  
                       <asp:LinkButton ID="btnCancel"       runat="server" CommandName="CancelAll"      Visible='<%# rgvSecurityGroups.EditIndexes.Count > 0 Or rgvSecurityGroups.MasterTableView.IsItemInserted %>'><asp:Image ID="imgCancel" runat="server" CssClass="css_GFS01_Image_Align" ImageURL="<%$ Resources:Images,CancelGreen16%>" /> Cancel </asp:LinkButton>  
                       <asp:LinkButton ID="lbtSaveNew"      runat="server" CommandName="PerformInsert"  Visible='<%# rgvSecurityGroups.MasterTableView.IsItemInserted%>'><asp:Image ID="imgSaveNew" runat="server" CssClass="css_GFS01_Image_Align" ImageURL="<%$ Resources:Images,SaveButton18%>" /> Save New</asp:LinkButton>  
                       <asp:LinkButton ID="lbtDelete"       runat="server" CommandName="DeleteSelected" Visible='<%# rgvSecurityGroups.EditIndexes.Count = 0 and Not rgvSecurityGroups.MasterTableView.IsItemInserted %>'><asp:Image ID="imgDelete"       runat="server" CssClass="css_GFS01_Image_Align" ImageURL="<%$ Resources:Images,DeleteRed16%>" />Delete </asp:LinkButton>  
                       <asp:LinkButton ID="lbtSave"         runat="server" CommandName="UpdateEdited"   Visible='<%# rgvSecurityGroups.EditIndexes.Count > 0 or rgvSecurityGroups.MasterTableView.IsItemInserted%>'><asp:Image runat="server" CssClass="css_GFS01_Image_Align" ImageURL="<%$ Resources:Images,SaveBlue16%>" />  Update </asp:LinkButton>  
                       <asp:LinkButton ID="lbtRefresh"      runat="server" CommandName="RebindGrid"     ><asp:Image id="imgRefresh" runat="server" CssClass="css_GFS01_Image_Align" ImageURL="<%$Resources:Images, ReloadBlue16 %>" AlternateText ="Refresh Grid" /></asp:LinkButton>                     
                   </div>
               </CommandItemTemplate>


Private Sub rgvSecurityGroups_InsertCommand(ByVal sender As Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs) Handles rgvSecurityGroups.InsertCommand
    Dim InsertedItem As GridDataInsertItem = DirectCast(e.Item.OwnerTableView.GetInsertItem(), GridDataInsertItem)
    Dim strSecurityGroup As String = DirectCast(InsertedItem("SecurityGroup").Controls(0), TextBox).Text
    Dim aryParameters(2) As String
    Dim strMessageType As String = Nothing
    Dim strMessage As String = Nothing
    Dim strMessageHeading As String = Nothing
    If strSecurityGroup Is Nothing Or IsDBNull(strSecurityGroup) Or Len(strSecurityGroup) = 0 Then
        strMessageType = "Error"
        strMessageHeading = "Null Value"
        aryParameters(0) = "Security Group"
        aryParameters(1) = strSecurityGroup
        strMessage = UDF_GetErrorMessage("Null Value", aryParameters)
        USB_DisplayMessage(strMessageType, strMessageHeading, strMessage, "Medium", "Black", Me.rwmMessageBox)
    Else
        If pUDF_DuplicateValueCheck(0, strSecurityGroup) = True Then
            strMessageType = "Error"
            strMessageHeading = "Duplicate Value"
            aryParameters(0) = "Security Group"
            aryParameters(1) = strSecurityGroup
            strMessage = UDF_GetErrorMessage("Duplicate Value", aryParameters)
            USB_DisplayMessage(strMessageType, strMessageHeading, strMessage, "Medium", "Black", Me.rwmMessageBox)
        Else
            Me.SQLDS_SecurityGroups.InsertCommandType = SqlDataSourceCommandType.Text
            Me.SQLDS_SecurityGroups.InsertCommand = "EXEC [Security].[DSP_SEL-INS-UPD-DEL-SecurityGroups] 'Insert', DEFAULT, " & strSecurityGroup
        End If
    End If

Here's is the code that opens the rad window, notice that I am sending the radwindow control that is used on the page that is calling the procedure.
Public Shared Sub USB_DisplayMessage(ByVal strMessageType As String, ByVal strMessageHeading As String, ByVal strMessage As String, ByVal strMessageSize As String, ByVal strSkin As String, ByVal rwmMessageBox As RadWindowManager)
       Dim rwdMessage As New RadWindow
       Dim strNavigation As String = "~/Modules/Central/WBF CTL Message Box.aspx?MessageType=" + strMessageType + "&MessageHeading=" + strMessageHeading + "&Message=" + strMessage
       rwdMessage.ID = "rwdMessageDetail"
       rwdMessage.Skin = strSkin
       Select Case strMessageSize
           Case "Small"
               rwdMessage.Height = "250"
               rwdMessage.Width = "400"
           Case "Medium"
               rwdMessage.Height = "300"
               rwdMessage.Width = "400"
       End Select
       rwdMessage.NavigateUrl = strNavigation
       rwmMessageBox.Windows.Add(rwdMessage)
   End Sub

So my question is how do I prevent the radwidow from causing a postback?

My second question is regarding the cancelling of the delete event.  As in the above scenario I am using the CommandItemTemplate with LinkButtons to perform all the record functions.  When the user clicks the delete button I open a radwindow prompting  (yes/no buttons)  them to confirm the deletion and again this works fine.  What I want to be able to do is Cancel the deletion if the user clicks the No button on the rad window.  But I can't figure out how to cancel the DeleteCommand if the user clicks the No button to cancel the deletion.

Here is the code that calls the rad window. The code for opening the rad window is the same as listed above.

Private Sub rgvSecurityGroups_DeleteCommand(ByVal sender As Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs) Handles rgvSecurityGroups.DeleteCommand
    Dim GridItem As GridDataItem = DirectCast(e.Item, GridDataItem)
    Dim intSecurityId As Int16 = GridItem.GetDataKeyValue("SecurityID")
    Dim strSecurityGroup As String = GridItem("SecurityGroup").Text
    Dim strMessageType As String = Nothing
    Dim strMessage As String = Nothing
    Dim strMessageHeading As String = Nothing
    strMessageType = "Warning"
    strMessageHeading = "Deleting " + strSecurityGroup
    strMessage = "You have selected to delete security group " + strSecurityGroup & ".  This action will cause this group to be deleted from all Users.<br><br>Do you want to continue?"
    USB_DisplayMessage(strMessageType, strMessageHeading, strMessage, "Medium", "Black", Me.rwmMessageBox)
    Me.SQLDS_SecurityGroups.DeleteCommandType = SqlDataSourceCommandType.Text
    Me.SQLDS_SecurityGroups.DeleteCommand = "EXEC [Security].[DSP_SEL-INS-UPD-DEL-SecurityGroups] 'Delete', " & intSecurityId & ", DEFAULT"
End Sub

Thank you for your help.

Georgi Tunev
Telerik team
 answered on 08 Feb 2011
4 answers
530 views
Hi,

I have a little question,

In my application i have a RadDatePicker declared so :

<telerik:RadDatePicker id="myDate" runat="server" Skin="Default">
                <DateInput DateFormat="dd/MM/yyyy"></DateInput>
            </telerik:RadDatePicker>

And i want to make it nullable : for the moment the user can write the date in the inputControl manually , but if he wants to set the Date to Null it's not possible.

In my CodeBehind i have a button which update the date in a database, it takes the code the selectedDate to make this update.

        protected void lnkUpdateDate_Click(object sender, EventArgs e)
        {
              if(myDate.DateInput.SelectedValue != null)
                  Update((DateTime)myDate.DateInput.SelectedValue);
        }

I can't make the difference between an emtpy inputextbox.text value and wrong date in input textbox.text

How can I test if the User has enter an empty string in order to make the update with a null Date ?
Ric
Top achievements
Rank 1
 answered on 08 Feb 2011
2 answers
89 views
Hi,

I need to stop the context menu from displaying in certain situations (client-side of course). I tried using OnContextMenu, but I'm not sure if telerik's context menu supports being stopped.

function OnClientContextMenu(sender, args) {
    var appointment = args.get_appointment();
    if (appointment)
    {
        if(appointment.get_attributes().getAttribute("Status") != 2 || appointment.get_attributes().getAttribute("Status") != 3) {
            //Stop context menu from showing.
            return;
        }
        else
        {
            //Show context menu.
            menu.show(args.get_domEvent());
        }
    }
}

Thank you for your help.

Daryl

Edit: Method is attached to this event:

OnClientAppointmentContextMenu="OnClientContextMenu"
Alan
Top achievements
Rank 1
 answered on 08 Feb 2011
3 answers
119 views
Hello,

I need a solution to completly rebind the items of the context menu on runtime at server side when user right-clicks.

Items are currently bound with following code. Now I like to bind the items not in page_load, but when user right-clicks, because items are generated in future in a separate business logic on another server and they can change between page_loads.
 
I have tried a server callback event on client event "OnClientShowing"; it works but unfortunately no changes can be done here. The context menu will not change.

Does anybody find a solution for that?

Thanks in advance

René 

<telerik:RadContextMenu ID="RadContextMenu1" runat="server">
    <Targets>
      <telerik:ContextMenuControlTarget ControlID="TextBox1" />
      <telerik:ContextMenuControlTarget ControlID="Label1" />
      <telerik:ContextMenuControlTarget ControlID="Image1" />
    </Targets>                
    <Items>
    </Items>
</telerik:RadContextMenu>


    Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            RadContextMenu1.DataTextField = "Text"
            RadContextMenu1.DataNavigateUrlField = "Url"
            RadContextMenu1.DataFieldID = "ID"
            RadContextMenu1.DataFieldParentID = "ParentID"
            RadContextMenu1.DataSource = GenerateSiteData()
            RadContextMenu1.DataBind()
        End If
    End Sub
  
    Private Function GenerateSiteData() As ArrayList
        Dim siteData As New ArrayList()
        siteData.Add(New SiteDataItem(1, Nothing, "All Sites", ""))
        siteData.Add(New SiteDataItem(2, 1, "Search Engines", ""))
        siteData.Add(New SiteDataItem(3, 1, "News Sites", ""))
        siteData.Add(New SiteDataItem(4, 2, "Yahoo", "http://www.yahoo.com"))
        siteData.Add(New SiteDataItem(5, 2, "MSN", "http://www.msn.com"))
        siteData.Add(New SiteDataItem(6, 2, "Google", "http://www.google.com"))
        siteData.Add(New SiteDataItem(7, 3, "CNN", "http://www.cnn.com"))
        siteData.Add(New SiteDataItem(8, 3, "BBC", "http://www.bbc.co.uk"))
        siteData.Add(New SiteDataItem(9, 3, "FOX", "http://www.foxnews.com"))
        Return siteData
    End Function
  
Public Class SiteDataItem
    Private _text As String
    Private _url As String
    Private _id As Integer
    Private _parentId As Integer
    Public Property Text() As String
        Get
            Return _text
        End Get
        Set(ByVal value As String)
            _text = value
        End Set
    End Property
    Public Property Url() As String
        Get
            Return _url
        End Get
        Set(ByVal value As String)
            _url = value
        End Set
    End Property
    Public Property ID() As Integer
        Get
            Return _id
        End Get
        Set(ByVal value As Integer)
            _id = value
        End Set
    End Property
    Public Property ParentID() As Integer
        Get
            Return _parentId
        End Get
        Set(ByVal value As Integer)
            _parentId = value
        End Set
    End Property
    Public Sub New(ByVal id As Integer, ByVal parentId As Integer, ByVal text As String, ByVal url As String)
        _id = id
        _parentId = parentId
        _text = text
        _url = url
    End Sub
End Class
Kate
Telerik team
 answered on 08 Feb 2011
7 answers
110 views
We were using RadEditor Lite 4.4.1 and worked fine beside getting the error 'RadEditor 7.2.1 trial version. Copyright Telerik © 2002-2007. To remove this message, please  purchase a developer version.'

I'm being told that to get rid of that message I need to upgrade to 4.5.6. I followed the guide and upgraded to 4.5.6; however, I received the following error message:

Exception information:
    Exception type: MethodAccessException
    Exception message: Telerik.SharePoint.MOSSRadEditor..ctor()
 
Request information:
    Request URL:
    Request path: /r/event.aspx
    User host address:
    User: 
    Is authenticated: True
    Authentication Type: Negotiate
    Thread account name:
 
Thread information:
    Thread ID: 9
    Thread account name:
    Is impersonating: False
    Stack trace:    at Rapid.Wcm.Web.UI.FieldControls.Html..ctor()
   at T_1bac81ac_4a77_4224_8229_b52ee8813542.CreateInstance()
   at System.Web.HttpRuntime.FastCreatePublicInstance(Type type)
   at System.Web.UI.ControlBuilder.BuildObjectInternal()
   at System.Web.UI.ControlBuilder.BuildObject()
   at System.Web.UI.ControlBuilder.BuildChildren(Object parentObj)
   at System.Web.UI.TemplateBuilder.InstantiateIn(Control container)
   at System.Web.UI.WebControls.ContentBuilderInternal.InstantiateIn(Control container)
   at System.Web.UI.WebControls.ContentPlaceHolderBuilder.BuildObject()
   at System.Web.UI.ControlBuilder.BuildChildren(Object parentObj)
   at System.Web.UI.TemplateBuilder.InstantiateIn(Control container)
   at System.Web.UI.WebControls.ContentBuilderInternal.InstantiateIn(Control container)
   at System.Web.UI.WebControls.ContentPlaceHolderBuilder.BuildObject()
   at System.Web.UI.ControlBuilder.BuildChildren(Object parentObj)
   at System.Web.UI.TemplateBuilder.InstantiateIn(Control container)
   at System.Web.UI.WebControls.ContentBuilderInternal.InstantiateIn(Control container)
   at System.Web.UI.WebControls.ContentPlaceHolderBuilder.BuildObject()
   at System.Web.UI.ControlBuilder.BuildChildren(Object parentObj)
   at System.Web.UI.ControlBuilder.InitObject(Object obj)
   at System.Web.UI.ControlBuilder.BuildObjectInternal()
   at System.Web.UI.ControlBuilder.BuildObject()
   at System.Web.UI.ControlBuilder.BuildChildren(Object parentObj)
   at System.Web.UI.ControlBuilder.InitObject(Object obj)
   at System.Web.UI.ControlBuilder.BuildObjectInternal()
   at System.Web.UI.ControlBuilder.BuildObject()
   at System.Web.UI.ControlBuilder.BuildChildren(Object parentObj)
   at System.Web.UI.ControlBuilder.InitObject(Object obj)
   at System.Web.UI.FileLevelPageControlBuilder.InitObject(Object obj)
   at System.Web.Compilation.BuildResultNoCompileTemplateControl.FrameworkInitialize(TemplateControl templateControl)
   at System.Web.UI.TemplateControl.FrameworkInitialize()
   at System.Web.UI.UserControl.InitializeAsUserControlInternal()
   at System.Web.UI.MasterPage.CreateMaster(TemplateControl owner, HttpContext context, VirtualPath masterPageFile, IDictionary contentTemplateCollection)
   at System.Web.UI.MasterPage.get_Master()
   at System.Web.UI.MasterPage.ApplyMasterRecursive(MasterPage master, IList appliedMasterFilePaths)
   at System.Web.UI.MasterPage.ApplyMasterRecursive(MasterPage master, IList appliedMasterFilePaths)
   at System.Web.UI.Page.ApplyMasterPage()
   at System.Web.UI.Page.PerformPreInit()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Stanimir
Telerik team
 answered on 08 Feb 2011
2 answers
325 views
Hi,

I am using radgrid in my page. i have asp:button. when i click the button i want to show error message below the button. but i have 5 grid in my page. so i am passing error message to label. but i want set focus the label. how to set this one?


Thanks in advance,
Dhamu.
Dhamodharan
Top achievements
Rank 1
 answered on 08 Feb 2011
Narrow your results
Selected tags
Tags
+? more
Top users last month
Jay
Top achievements
Rank 3
Iron
Iron
Iron
Benjamin
Top achievements
Rank 3
Bronze
Iron
Veteran
Radek
Top achievements
Rank 2
Iron
Iron
Iron
Bohdan
Top achievements
Rank 2
Iron
Iron
Richard
Top achievements
Rank 4
Bronze
Bronze
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Jay
Top achievements
Rank 3
Iron
Iron
Iron
Benjamin
Top achievements
Rank 3
Bronze
Iron
Veteran
Radek
Top achievements
Rank 2
Iron
Iron
Iron
Bohdan
Top achievements
Rank 2
Iron
Iron
Richard
Top achievements
Rank 4
Bronze
Bronze
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?