I've updated the Telerik library to 2026 Q1 (2026.1.211.462) and noticed a JavaScript error "ReferenceError: kendo is not defined." is thrown on the page where the RadSpreadsheet is located.
Hi Axel,
Thank you very much for reporting this bug, Axel!
We were able to reproduce the issue and have already implemented a fix. The correction is scheduled for the next official release, which is expected within approximately 1-4 weeks (the exact date is still to be finalized). As a small token of appreciation for reporting the issue, I have updated your Telerik points.
In the meantime, please apply the following workaround:
1) Create a Class e.g. KendoGlobalization.cs
namespace MyNamespace
{
public static class KendoGlobalization
{
static string[] numberNegativePatterns = new string[] { "(n)", "-n", "- n", "n-", "n -" };
static string[] currencyPositivePatterns = new string[] { "$n", "n$", "$ n", "n $" };
static string[] currencyNegativePatterns = new string[] { "($n)", "-$n", "$-n", "$n-", "(n$)", "-n$", "n-$", "n$-", "-n $", "-$ n", "n $-", "$ n-", "$ -n", "n- $", "($ n)", "(n $)" };
static string[] percentPositivePatterns = new string[] { "n %", "n%", "%n", "% n" };
static string[] percentNegativePatterns = new string[] { "-n %", "-n%", "-%n", "%-n", "%n-", "n-%", "n%-", "-% n", "n %-", "% n-", "% -n", "n- %" };
static readonly string culturePattern =
@"(function( window, undefined ) {
var kendo = $telerik._kendo;
kendo.cultures[""{{Name}}""] = {
name: ""{{Name}}"",
numberFormat: {
pattern: {{NumberPattern}},
decimals: {{NumberDecimalDigits}},
"","": ""{{NumberGroupSeparator}}"",
""."": ""{{NumberDecimalSeparator}}"",
groupSize: {{NumberGroupSizes}},
percent: {
pattern: {{PercentPattern}},
decimals: {{PercentDecimalDigits}},
"","": ""{{PercentGroupSeparator}}"",
""."": ""{{PercentDecimalSeparator}}"",
groupSize: {{PercentGroupSizes}},
symbol: ""{{PercentSymbol}}""
},
currency: {
pattern: {{CurrencyPattern}},
decimals: {{CurrencyDecimalDigits}},
"","": ""{{CurrencyGroupSeparator}}"",
""."": ""{{CurrencyDecimalSeparator}}"",
groupSize: {{CurrencyGroupSizes}},
symbol: ""{{CurrencySymbol}}""
}
},
calendars: {
standard: {
days: {
names: {{DayNames}},
namesAbbr: {{AbbreviatedDayNames}},
namesShort: {{ShortestDayNames}}
},
months: {
names: {{MonthNames}},
namesAbbr: {{AbbreviatedMonthNames}}
},
AM: {{AM}},
PM: {{PM}},
patterns: {
d: ""{{d}}"",
D: ""{{D}}"",
F: ""{{F}}"",
g: ""{{g}}"",
G: ""{{G}}"",
m: ""{{m}}"",
M: ""{{M}}"",
s: ""{{s}}"",
t: ""{{t}}"",
T: ""{{T}}"",
u: ""{{u}}"",
y: ""{{y}}"",
Y: ""{{Y}}""
},
""/"": ""{{DateSeparator}}"",
"":"": ""{{TimeSeparator}}"",
firstDay: {{FirstDayOfWeek}}
}
}
};
kendo.culture(""{{Name}}"");
})(this);";
private static IDictionary<string, object> BuildFlatDictionary(CultureInfo cultureInfo)
{
NumberFormatInfo numberFormats = cultureInfo.NumberFormat;
DateTimeFormatInfo dateTimeFormats = cultureInfo.DateTimeFormat;
IDictionary<string, object> globalization = new Dictionary<string, object>();
globalization["Name"] = cultureInfo.Name;
//number info
globalization["NumberPattern"] = new string[] { numberNegativePatterns[cultureInfo.NumberFormat.NumberNegativePattern] };
globalization["NumberDecimalDigits"] = cultureInfo.NumberFormat.NumberDecimalDigits;
globalization["NumberGroupSeparator"] = numberFormats.NumberGroupSeparator;
globalization["NumberDecimalSeparator"] = numberFormats.NumberDecimalSeparator;
globalization["NumberGroupSizes"] = numberFormats.NumberGroupSizes;
//percent info
globalization["PercentPattern"] = new string[] { percentNegativePatterns[cultureInfo.NumberFormat.PercentNegativePattern], percentPositivePatterns[cultureInfo.NumberFormat.PercentPositivePattern] };
globalization["PercentDecimalDigits"] = cultureInfo.NumberFormat.PercentDecimalDigits;
globalization["PercentGroupSeparator"] = numberFormats.PercentGroupSeparator;
globalization["PercentDecimalSeparator"] = numberFormats.PercentDecimalSeparator;
globalization["PercentGroupSizes"] = numberFormats.PercentGroupSizes;
globalization["PercentSymbol"] = numberFormats.PercentSymbol;
//currency info
globalization["CurrencyPattern"] = new string[] { currencyNegativePatterns[cultureInfo.NumberFormat.CurrencyNegativePattern], currencyPositivePatterns[cultureInfo.NumberFormat.CurrencyPositivePattern] };
globalization["CurrencyDecimalDigits"] = cultureInfo.NumberFormat.CurrencyDecimalDigits;
globalization["CurrencyGroupSeparator"] = numberFormats.CurrencyGroupSeparator;
globalization["CurrencyDecimalSeparator"] = numberFormats.CurrencyDecimalSeparator;
globalization["CurrencyGroupSizes"] = numberFormats.CurrencyGroupSizes;
globalization["CurrencySymbol"] = numberFormats.CurrencySymbol;
//standard calendar info
globalization["DayNames"] = dateTimeFormats.DayNames;
globalization["AbbreviatedDayNames"] = dateTimeFormats.AbbreviatedDayNames;
globalization["ShortestDayNames"] = dateTimeFormats.ShortestDayNames;
globalization["MonthNames"] = dateTimeFormats.MonthNames;
globalization["AbbreviatedMonthNames"] = dateTimeFormats.AbbreviatedMonthNames;
globalization["d"] = dateTimeFormats.ShortDatePattern;
globalization["D"] = dateTimeFormats.LongDatePattern;
globalization["F"] = dateTimeFormats.FullDateTimePattern;
globalization["g"] = dateTimeFormats.ShortDatePattern + " " + dateTimeFormats.ShortTimePattern;
globalization["G"] = dateTimeFormats.ShortDatePattern + " " + dateTimeFormats.LongTimePattern;
globalization["m"] = dateTimeFormats.MonthDayPattern;
globalization["M"] = dateTimeFormats.MonthDayPattern;
globalization["s"] = dateTimeFormats.SortableDateTimePattern;
globalization["t"] = dateTimeFormats.ShortTimePattern;
globalization["T"] = dateTimeFormats.LongTimePattern;
globalization["u"] = dateTimeFormats.UniversalSortableDateTimePattern;
globalization["y"] = dateTimeFormats.YearMonthPattern;
globalization["Y"] = dateTimeFormats.YearMonthPattern;
var am = dateTimeFormats.AMDesignator;
var pm = dateTimeFormats.PMDesignator;
globalization["AM"] = string.IsNullOrEmpty(am) ? new string[] { am } : new string[] { am, am.ToLower(cultureInfo), am.ToUpper(cultureInfo) };
globalization["PM"] = string.IsNullOrEmpty(pm) ? new string[] { am } : new string[] { pm, pm.ToLower(cultureInfo), pm.ToUpper(cultureInfo) };
globalization["DateSeparator"] = dateTimeFormats.DateSeparator;
globalization["TimeSeparator"] = dateTimeFormats.TimeSeparator;
globalization["FirstDayOfWeek"] = (int)dateTimeFormats.FirstDayOfWeek;
return globalization;
}
public static string Format(this CultureInfo cultureInfo)
{
var serializer = new JavaScriptSerializer();
var cultureDictionary = BuildFlatDictionary(cultureInfo);
var pattern = culturePattern;
foreach (KeyValuePair<string, object> pair in cultureDictionary)
{
var key = pair.Key;
var value = pair.Value;
pattern = pattern.Replace("{{" + key + "}}", value is System.Array ? serializer.Serialize(value) : System.Convert.ToString(value, cultureInfo));
}
Regex rgx = new Regex(" *\r\n\\ *");
pattern = rgx.Replace(pattern, "");
return pattern;
}
}
}On the Page where the Spreadsheet and/or Gantt are located, override the OnPreRender event and override the registered script with the new one:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
var spreadSheetCulture = RadSpreadsheet1.Culture; //specify the RadSpreadsheet ID as a value
if (spreadSheetCulture.Name != "en-US")
{
string cultureScript = MyNamespace.KendoGlobalization.Format(spreadSheetCulture);
ScriptManager.RegisterStartupScript(Page, typeof(RadSpreadsheet), "SpreadsheetCultureScript", cultureScript, true);
}
var ganttCulture = RadGantt1.Culture; //specify the RadGantt ID as a value
if (ganttCulture.Name != "en-US")
{
string cultureScript = MyNamespace.KendoGlobalization.Format(ganttCulture);
ScriptManager.RegisterStartupScript(Page, typeof(RadGantt), "GanttCultureScript", cultureScript, true);
}
}
Regards,
Rumen
Progress Telerik