Telerik Forums
UI for ASP.NET AJAX Forum
5 answers
376 views
Hi,

I'm trying to input schedule data into a RadScheduler that comes from a foreign system. For the purposes of this exercise let's just say it schedule data being imported into my App's SQL DB from another SQL server DB.

I have my own business object data layer and have an object called WorkSchedule which contains an instance of a class that contains multiple instances of another object called WorkScheduleTimeCollection (as an ArrayList). WorkScheduleTImeCollection in essence contains multiple instances of the class WorkScheduleTime (which is for all intents and purposes an object to represent an Appointment), this collection can thus be bound as a DataSource to RadScheduler.

When WorkScheduleTimeCollection is populated with data, an instance of a RadScheduler Recurrence Rule is created, both it and its string representation have been added as properties to the WorkScheduleTime Class. WorkScheduleTime also contains general data (like "Name" and "UniqueID"), as well as a StartTime and EndTime.

Also note I did find that formatting the RecurrenceRule string representation as discussed here: http://www.telerik.com/community/forums/aspnet-ajax/scheduler/daily-recurrence-string-is-correct.aspx to be useful.

Therefore I am attempting to bind this data to the RadScheduler as such:

With rsSchedule 
 
    Dim stcWorkSchedule As New WorkScheduleTimeCollection
    stcWorkSchedule = Database.SelectWorkScheduleTimes(ScheduleUniqueID, .VisibleRangeStart, .VisibleRangeEnd, True) 
 
    .DataSource = stcWorkSchedule 
    .DataKeyField = "UniqueID" 
    .DataSubjectField = "Name" 
    .DataStartField = "StartTime" 
    .DataEndField = "EndTime" 
    .DataRecurrenceParentKeyField = "UniqueID" 
    .DataRecurrenceField = "RecurrenceRuleValue" 
    .DataBind()                 
 
End With 

In the code the first line simply retrieves the collection of "appointment" objects in the current schedule from a database method for the current visible range, and then it is bound to the RadScheduler

Here is an example of what kind of data would be in a typical WorkScheduleTime Appointment object, including the recurrence rule:

ID: 562
UniqueID: 562.008
Name: 562.008
DateActiveFrom: 1/1/2000 12:00:00 AM
DateActiveTo: 1/1/2099 12:00:00 AM
StartTime: 1/1/2000 12:34:00 PM (UTC)
EndTime: 1/1/2000 1:10:00 PM (UTC)
DayFrequency: M,T,W,U,F
RecurrenceRuleValue: DTSTART:20000101T000000Z/r/nDTEND:20000101T003600Z/r/nRRULE:FREQ=WEEKLY;UNTIL=20990101T000000Z;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR/r/n

Here is (a simplified example of, but the same lines of code exist in the actual method of) how the recurrence rule is created, BTW:
 
Private Function CreateRecurrenceRule(wstTime As WorkScheduleTime) As WorkScheduleTime

    With wstTime 
       
        Dim rrRange As New RecurrenceRange() 
        rrRange.Start = .DateActiveFrom 
        rrRange.RecursUntil = .DateActiveTo 
        rrRange.EventDuration = .EndTime - .StartTime 
 
        'Here ".DayFrequency" is a class of boolean values representing the 7 character comma delimited day
        'frequency list I receive from the foreign schedule data, that class is "converted" to the Telerik
        'RecurrenceDay object.
        Dim rdDays As RecurrenceDay = Me.BuildScheduleDayRecurrence(.DayFrequency) 
 
        Dim wrRule As New WeeklyRecurrenceRule(1, rdDays, rrRange) 
 
        .RecurrenceRule = wrRule 
        .RecurrenceRuleValue = wrRule.ToString 
        .RecurrenceRuleValue = .RecurrenceRuleValue.Replace(vbCr, "/r") 
        .RecurrenceRuleValue = .RecurrenceRuleValue.Replace(vbLf, "/n") 
 
    End With 
 
    Return wstTime
End Sub 
 
 
 

Now my problem is, when the page loads all I get is one instance of each appointment created on the start date (DateActiveFrom) of the appointment and no others (it just so happens 1/1/2000 is a Saturday so the recurrence is truly not working correctly as these appointments almost always happen during the week as does the example). In essence the above example appointment does not recur every week day on M/W/T/U/F at 12:34p - 1:10p from 1/1/2000 - 1/1/2099. And at this point I'm not sure why.

The scheduler does see the appointment as a recurring appointment and will attempt to edit the individual occurence but If I try to "edit" the whole series the control breaks citing "not an instance of an object".

Any help would be appreciated, a trouble ticket can be submitted if that becomes necessary.

Thanks!

T. Tsonev
Telerik team
 answered on 24 Mar 2010
7 answers
163 views
Hi,

I am trying to figure out how to disable the "active row" functionality.  I have no need for an active row, but i want to do keyboard up down selection.  I want it to be selected, not activated.  I want no distinction between an active row and a selected row.  I have tried javascript functions like

set_activeRow

and

grid.MasterTableView.SetActiveRow

Each of these does nothing.  Can i just disable the active row concept all together?
Mira
Telerik team
 answered on 24 Mar 2010
4 answers
337 views
I really like how the RegEx Text Boxes behave when their validation is required.  If I load my page and just click submit right away every RegEx box I have on the form that is required pops up the little exclaimation point, displays my error message, and won't let them use submit until they put something into each required field that satisfies the Regular Expression.

I would like my various date boxes to do the same... right now the user can fill in all required RegEx text boxes and click submit and the page will let them, despite having blank required date fields.  I know I could write some little Javascript function, or use the ASP.Net field validators, but I'd rather keep everything consistent and use the Telerik-style validations if possible.

So is there a way I can make the DatePicker require some input and if the user leaves the filed blank and clicks away, or tries to submit the form with nothing in the required Date Picker field, then have it display the exclaimation icon inside the DatePicker field and stop the submission?
T. Tsonev
Telerik team
 answered on 24 Mar 2010
2 answers
88 views
I want to not only style the row being edited when using InPlace edition (using <EditItemStyle/>) but I also need to change the placement and add some additional text to the "Update Cancel" link buttons.

What I need to do is make that: "Cancel | Save" instead. Basically reversing the position and adding a pipe character between. So, I'm guessing that I need some sort of EditItemTemplate but there doesn't seem to be one available.

Do you have any samples that come close to the modifications I need to do to the link buttons?

Thanks.
Charles
Top achievements
Rank 2
 answered on 24 Mar 2010
1 answer
157 views
Hi ,

I am making a UserControl having Nested RadGrid, Everything is made dynamically in codebehind. I am adding Edit button to ParentTable in ItemDatabound. When i expand parentrow my ParentRow Edit button binding is gone.

NeedDataSource of ParentGrid is not firing. These are my Grid Event
#region Grid Events  
 
        protected void RadGridNestedControl_DetailTableDataBind(object source, Telerik.Web.UI.GridDetailTableDataBindEventArgs e)  
        {     
            GridDataItem dataItem = (GridDataItem)e.DetailTableView.ParentItem;  
            string strParentRelationID = dataItem.GetDataKeyValue(this.ParentRelationColumn).ToString();  
            e.DetailTableView.DataSource = Source.Tables[1].Select(ChildRelationColumn + "=" + strParentRelationID);  
            RadGrid obj = (RadGrid)source ;  
            //obj.Rebind();  
        }  
          
        protected void RadGridNestedControl_ItemDataBound(object source, Telerik.Web.UI.GridItemEventArgs e)  
        {  
            if (this.PageType == (int)PageName.HeaderFooterListing)  
            {  
                if (e.Item is GridDataItem && e.Item.OwnerTableView.Name == "ParentView")  
                {  
                    GridDataItem dataItem = e.Item as GridDataItem;  
                    GridTableCell wgColEdit = (GridTableCell)dataItem["Edit"];  
 
                    if (wgColEdit != null)  
                    {  
                        //Creating QueryString  
                        string[] editParam = this.NavigationEditParameters;  
                        string strQueryString = string.Empty;  
                        foreach (string str in editParam)  
                        {  
                            if (dataItem[str] != null)  
                            {  
                                if (dataItem[str].Text != "&nbsp;")  
                                    strQueryString += str + "=" + dataItem[str].Text + "&";  
                                else  
                                    strQueryString += str + "=" + ServiceNet.BLL.Global.NullInteger.ToString() + "&";  
                            }  
                        }  
                        strQueryString += "PKSourceClientID=" + intClientID;  
 
                        wgColEdit.HorizontalAlign = HorizontalAlign.Center;  
                        (wgColEdit.Controls[0] as ImageButton).Style.Add("Cursor", "Pointer");  
                        wgColEdit.ToolTip = ResourceLang.GetString("C_Edit");  
                        string url = ((ServiceNet.Web.BasePage)Page).ImagesLocation + "btn_edit_small" + ((ServiceNet.Web.BasePage)Page).ImageExtension;  
                        wgColEdit.Text = "<a href='" + this.NavigationEditURL + "?" + strQueryString + "' ><img src='" + url + "'  OnMouseOver=ChangeImage(this,'btn_edit_small',1) OnMouseOut=ChangeImage(this,'btn_edit_small',2) OnMouseDown=ChangeImage(this,'btn_edit_small',3) OnMouseUp=ChangeImage(this,'btn_edit_small',4) onKeyDown=ChangeImage(this,'btn_edit_small',5)   OnKeyUp=ChangeImage(this,'btn_edit_small',6)></a>";  
                    }  
 
                }  
 
                if (e.Item is GridDataItem && e.Item.OwnerTableView.Name == "ChildView")  
                {  
                    GridDataItem dataItem = e.Item as GridDataItem;  
                    GridTableCell wgColPreview = (GridTableCell)dataItem["Add"];  
 
                    if (wgColPreview != null)  
                    {  
                        int intPKID = Convert.ToInt32(dataItem.GetDataKeyValue(this.ChildRelationColumn).ToString());  
                        int intTypeValueID = ServiceNet.BLL.Global.NullInteger;  
                        int intPKUserSourceID = ServiceNet.BLL.Global.NullInteger;  
                        int intPopUpHeight = ServiceNet.BLL.Global.NullInteger;  
                        int intPopUpWidth = ServiceNet.BLL.Global.NullInteger;  
 
                        string strDisplayText = dataItem["DisplayText"].Text;  
 
                        //Getting ParentRow Data  
                        DataRow[] drParent = Source.Tables[0].Select("PKID =" + intPKID);  
                        if (drParent != null && drParent.Length > 0)  
                        {  
                            intTypeValueID = DatabaseHelper.GetNullableInt32(drParent[0], "TypeValueID");  
                            intPKUserSourceID = DatabaseHelper.GetNullableInt32(drParent[0], "PKUserSourceID");  
                            intPopUpHeight = DatabaseHelper.GetNullableInt32(drParent[0], "PopUpHeight");  
                            intPopUpWidth = DatabaseHelper.GetNullableInt32(drParent[0], "PopUpWidth");  
                        }  
 
 
                        wgColPreview.HorizontalAlign = HorizontalAlign.Center;  
                        wgColPreview.ToolTip = ResourceLang.GetString("C_Preview");  
                        string url = ((ServiceNet.Web.BasePage)Page).ImagesLocation + "btn_ViewSchedules" + ((ServiceNet.Web.BasePage)Page).ImageExtension;  
                        wgColPreview.Text = "<a href='# style=cursor:hand;'><img onclick=\"javascript:ShowDataPopUp('" + this.ControlSessionData.LoggedUserPreferences.LanguageID + "','" + intTypeValueID + "','" + strDisplayText + "','" + intPKUserSourceID + "','" + intPopUpHeight + "','" + intPopUpWidth + "');\" src='" + url + "'  OnMouseOver=ChangeImage(this,'btn_ViewSchedules',1) OnMouseOut=ChangeImage(this,'btn_ViewSchedules',2) OnMouseDown=ChangeImage(this,'btn_ViewSchedules',3) OnMouseUp=ChangeImage(this,'btn_ViewSchedules',4) onKeyDown=ChangeImage(this,'btn_ViewSchedules',5)   OnKeyUp=ChangeImage(this,'btn_ViewSchedules',6)></a>";  
                    }  
                }  
            }  
        }  
                
        protected void RadGridNestedControl_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)  
        {  
            //if (!e.IsFromDetailTable)  
            //{     
            //    LoadData(this.Source);                  
            //}  
        }  
 
        #endregion 



This is my LoadGrid Event which is fired from Page_Load()

public void LoadData(DataSet dsSource)  
        {  
 
            this.RadGridNestedControl = new RadGrid();  
 
            this.RadGridNestedControl.ID = "RadGrid1";  
            this.RadGridNestedControl.NeedDataSource += new GridNeedDataSourceEventHandler(this.RadGridNestedControl_NeedDataSource);  
            this.RadGridNestedControl.DetailTableDataBind += new GridDetailTableDataBindEventHandler(this.RadGridNestedControl_DetailTableDataBind);  
            this.RadGridNestedControl.ItemDataBound += new GridItemEventHandler(this.RadGridNestedControl_ItemDataBound);  
 
            this.RadGridNestedControl.EnableEmbeddedScripts = true;  
 
            this.RadGridNestedControl.Width = Unit.Percentage(100);  
            thisthis.RadGridNestedControl.PageSize = this.ParentNumberofRecords;  
            this.RadGridNestedControl.AllowPaging = true;  
            this.RadGridNestedControl.AllowSorting = true;  
            this.RadGridNestedControl.AutoGenerateColumns = false;  
 
            if (this.Source != null)  
            {  
 
                RadGridNestedControl.DataSource = dsSource.Tables[0];  
                RadGridNestedControl.MasterTableView.DataKeyNames = new string[] { this.ParentRelationColumn };  
                RadGridNestedControl.MasterTableView.Name = "ParentView";  
 
                //Creating Columns  
                foreach (DataColumn dcol in dsSource.Tables[0].Columns)  
                {  
                    if (this.ParentExcludedFields != ServiceNet.BLL.Global.NullString)  
                    {  
                        if (this.ParentExcludedFields.IndexOf("," + dcol.ColumnName.ToUpper() + ",") < 0)  
                        {  
                            if (this.ResourceLangPrefix != null && this.ResourceLangPrefix != "")  
                                dcol.Caption = ResourceLang.GetString(this.ResourceLangPrefix + "_" + dcol.ColumnName);  
                            else  
                                dcol.Caption = ResourceLang.GetString(dcol.ColumnName);  
                            if (dcol.Caption == string.Empty)  
                                dcoldcol.Caption = dcol.ColumnName;  
                            GridBoundColumn wgCol = new GridBoundColumn();  
                            RadGridNestedControl.MasterTableView.Columns.Add(wgCol);  
                            wgCol.DataField = dcol.ColumnName;  
                            wgCol.HeaderText = dcol.Caption;  
                            wgCol.UniqueName = dcol.ColumnName;  
                            wgCol.AllowSorting = true;  
                        }  
                        else  
                        {  
                            GridBoundColumn wgCol = new GridBoundColumn();  
                            RadGridNestedControl.MasterTableView.Columns.Add(wgCol);  
                            wgCol.DataField = dcol.ColumnName;  
                            wgCol.Display = false;  
                        }  
                    }  
                    else  
                    {  
                        dcol.Caption = ResourceLang.GetString(this.ResourceLangPrefix + "_" + dcol.ColumnName);  
                        if (dcol.Caption == string.Empty)  
                            dcoldcol.Caption = dcol.ColumnName;  
                        GridBoundColumn wgCol = new GridBoundColumn();  
                        RadGridNestedControl.MasterTableView.Columns.Add(wgCol);  
                        wgCol.DataField = dcol.ColumnName;  
                        wgCol.HeaderText = dcol.Caption;  
                        wgCol.UniqueName = dcol.ColumnName;  
                        wgCol.AllowSorting = true;  
                    }  
 
                }  
 
                  
                //Adding Buttons to ParentGrid  
                if (this.IsParentRecordEditButton)  
                    AddButtonColumnsToGrid("Edit", ResourceLang.GetString("C_Edit"));  
 
 
                if (this.IsParentRecordAddButton)  
                    AddButtonColumnsToGrid("Add", ResourceLang.GetString("C_Add"));  
 
                if (this.IsParentRecordDeleteButton)  
                    AddButtonColumnsToGrid("Delete", ResourceLang.GetString("C_Delete"));  
                  
 
                //Detail Table  
                GridTableView tableDetailView = new GridTableView(RadGridNestedControl);  
                tableDetailView.Width = Unit.Percentage(100);  
                tableDetailView.DataSource = dsSource.Tables[1];  
                tableDetailView.DataKeyNames = new string[] { this.ChildRelationColumn };  
                tableDetailView.PageSize = this.ChildNumberofRecords;  
                tableDetailView.Name = "ChildView";  
 
                GridRelationFields relationFields = new GridRelationFields();  
                relationFields.MasterKeyField = this.ParentRelationColumn;  
                relationFields.DetailKeyField = this.ChildRelationColumn;  
                tableDetailView.ParentTableRelation.Add(relationFields);  
 
                //Creating Child Columns  
                foreach (DataColumn dcol in dsSource.Tables[1].Columns)  
                {  
                    if (this.ChildExcludedFields != ServiceNet.BLL.Global.NullString)  
                    {  
                        if (this.ChildExcludedFields.IndexOf("," + dcol.ColumnName.ToUpper() + ",") < 0)  
                        {  
                            if (this.ResourceLangPrefix != null && this.ResourceLangPrefix != "")  
                                dcol.Caption = ResourceLang.GetString(this.ResourceLangPrefix + "_" + dcol.ColumnName);  
                            else  
                                dcol.Caption = ResourceLang.GetString(dcol.ColumnName);  
                            if (dcol.Caption == string.Empty)  
                                dcoldcol.Caption = dcol.ColumnName;  
                            GridBoundColumn wgCol = new GridBoundColumn();  
                            wgCol.DataField = dcol.ColumnName;  
                            wgCol.HeaderText = dcol.Caption;  
                            wgCol.UniqueName = dcol.ColumnName;  
                            wgCol.AllowSorting = true;  
                            tableDetailView.Columns.Add(wgCol);  
 
                        }  
                        else  
                        {  
                            GridBoundColumn wgCol = new GridBoundColumn();  
                            tableDetailView.Columns.Add(wgCol);  
                            wgCol.DataField = dcol.ColumnName;  
                            wgCol.Display = false;  
                        }  
                    }  
                    else  
                    {  
                        dcol.Caption = ResourceLang.GetString(this.ResourceLangPrefix + "_" + dcol.ColumnName);  
                        if (dcol.Caption == string.Empty)  
                            dcoldcol.Caption = dcol.ColumnName;  
                        GridBoundColumn wgCol = new GridBoundColumn();  
                        wgCol.DataField = dcol.ColumnName;  
                        wgCol.HeaderText = dcol.Caption;  
                        wgCol.UniqueName = dcol.ColumnName;  
                        wgCol.AllowSorting = true;  
                        tableDetailView.Columns.Add(wgCol);  
                    }  
                }  
 
                //Adding Buttons to ChildGrid  
                if (this.IsChildRecordAddButton)  
                    AddButtonColumnsToChildGrid("Add", ResourceLang.GetString("C_Add"), tableDetailView);  
 
                if (this.IsChildRecordEditButton)  
                    AddButtonColumnsToChildGrid("Edit", ResourceLang.GetString("C_Edit"), tableDetailView);  
 
                if (this.IsChildRecordDeleteButton)  
                    AddButtonColumnsToChildGrid("Delete", ResourceLang.GetString("C_Delete"), tableDetailView);  
 
                RadGridNestedControl.MasterTableView.DetailTables.Add(tableDetailView);  
                this.PlaceHolder1.Controls.Add(RadGridNestedControl);  
            }  
        } 

DataSource is passed from Page to the Control through properties of UserControl. So it is not available on Page_Init for the UserControl.

Attached are the screenshots : Beforeexpand - all looks fine. But AfterExpand, the ParentTableRow is not binded. So the images for the added buttons as well as click events are gone.

Please tell me what is missing and how to get it running.

Thanks a lot.

Best Regards,
Veenu Munjal


Radoslav
Telerik team
 answered on 24 Mar 2010
4 answers
103 views
We did some tests, as our site is leaking a lot of memory.
Took code from your documentation for example, nothing else

<

 

telerik:RadMenu ID="RadMenu1" runat="server" Flow="Horizontal">

 

 

<Items>

 

 

<telerik:RadMenuItem runat="server" Text="Root Item 1">

 

 

<Items>

 

 

<telerik:RadMenuItem runat="server" Text="Child Item 1">

 

 

<Items>

 

 

<telerik:RadMenuItem runat="server" Text="Child Item 1.1" />

 

 

<telerik:RadMenuItem runat="server" Text="Child Item 1.2" />

 

 

</Items>

 

 

</telerik:RadMenuItem>

 

 

<telerik:RadMenuItem runat="server" Text="Child Item 2" />

 

 

</Items>

 

 

</telerik:RadMenuItem>

 

 

<telerik:RadMenuItem runat="server" Text="Root Item 2">

 

 

<Items>

 

 

<telerik:RadMenuItem runat="server" Text="Child Item 2.1" />

 

 

</Items>

 

 

</telerik:RadMenuItem>

 

 

</Items>

 

</

 

telerik:RadMenu>

 


and added a submit button, every time you submit you have huge spike of memory that never gets released, before you know it it is gearing up to 1GB. Please advise.
T. Tsonev
Telerik team
 answered on 24 Mar 2010
1 answer
103 views
Hello All:
I have a context-menu on a grid.  I have a non data-key (the 'lblStatus'), that I would like to cancel or continue the context menu.  So during the standard 'RowContextMenu' javascript function, I need to a reference to 'lblStatus'.  I believe that the following gets the data grid row.
var dataItem = Sender.get_masterTableView().get_dataItems()[index]; 

How do i obtain a reference to the status value?
Thanks.
Phil
Princy
Top achievements
Rank 2
 answered on 24 Mar 2010
1 answer
146 views
Hi there,

I am using telerik:RadEditor in my page, in which i have facilitate with
<telerik:EditorTool Name="imagemanager" Enabled="true" /> 
. By using image manager i can able to upload the image, and it's displaying in the page perfectely, while trying to send to mail id, in the mail it's showing empty space instead of what image i have send. But text format is displaying correctly.

Can anybody help me on this.
Regards,
Vimal Kumar Srivastava
Madhepura, Bihar
Rumen
Telerik team
 answered on 24 Mar 2010
5 answers
190 views
I have a rad tab and in each tab has some radeditors inside. I've set each radeditor to be autoresizeheight = true.

When I go to print the webpage, I have it set with css so that all the tabs print (set div's to display). However say I don't select a tab before I print, the tabs that I don't select will print the editors with scrollbars. The tabs that I have chosen will print with their heights set properly.

Is there anything I can do to force the autoresizeheight to run even if the editors are hidden?

Thanks

-Matt
Dobromir
Telerik team
 answered on 24 Mar 2010
4 answers
154 views
Hello,

I have a problem with the click around empty message in the RadListBox.

When i do click around empty message, the control throw an exception.

How i can disable the event selectedIndexChanged when there are not elements in
the RadListBox?

This is the error when i click on RadListBox (Empty):

Microsoft JScript runtime error: 'undefined' is null or not an object

The error is occurred at second line:
 
this._activeItem=e; 
d(e.get_element()).addClass("rlbActive"); 
e.ensureVisible(); 

Code:

                                <telerik:RadListBox ID="mailToSend" runat="server"  
                                     EmptyMessage="Emailsssssss" Height="150px" Width="200px" 
                                     SelectionMode="Multiple" AllowTransfer="True" TransferToID="mailToRemove"  
                                     AutoPostBackOnTransfer="True" AllowReorder="True" AutoPostBackOnReorder="True" 
                                     EnableDragAndDrop="True" Visible="false"
                                     <EmptyMessageTemplate> 
                                         Emailsssssss 
                                     </EmptyMessageTemplate> 
                                 </telerik:RadListBox> 
Schlurk
Top achievements
Rank 2
 answered on 24 Mar 2010
Narrow your results
Selected tags
Tags
+? more
Top users last month
Hiba
Top achievements
Rank 1
Iron
Iron
Rob
Top achievements
Rank 3
Bronze
Bronze
Iron
Max
Top achievements
Rank 1
Veteran
Iron
Alina
Top achievements
Rank 1
Rakhee
Top achievements
Rank 1
Iron
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Hiba
Top achievements
Rank 1
Iron
Iron
Rob
Top achievements
Rank 3
Bronze
Bronze
Iron
Max
Top achievements
Rank 1
Veteran
Iron
Alina
Top achievements
Rank 1
Rakhee
Top achievements
Rank 1
Iron
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?