I'm evaluating whether I can use a listbox in my web app, which needs to meet 508 accessibility standards for screen reader users. While the demo site says that the control is 508 compliant from an evaluation standpoint, i'm curious as to how I can get it to actually be usable to blind users. I tried running jaws against the keyboard support demo, and while I can use the arrows to navigate the list and select an item with the spacebar, the keystrokes to move the selected option into the right box do not work. Essentially none of the keyboard keys listed in the legend work because Jaws is trapping the key events before it gets to the control.
That being said, I then tried wrapping the demo in a div with a role="application" attribute, and jaws now allows the keyboard events to pass through to the control. However, it now doesn't actually read the items in the list as you are scrolling through them.
So my question is, how can this control be set up to be usable for screen reader users? Meaning it will read the options to the user, and also allow them to navigate within the control with the keyboard.
Thanks,
Mike
*** Update from 6 June 2018 ***
The problem discussed below has been fixed in R2 2018 (2018.2.516).
*** End of update ***
Chrome 61 introduced a breaking change that breaks the positioning of the context menu and the tooltip. The issue manifests only when the page is scrolled down.
The wrong position (placement) of the context menu affects:
Details and Resolution:
The positioning problem is due to the following breaking change in Chrome 61 (see full release notes):
To align with the spec and preserve browser consistency, the scrollingElement is now the documentElement in standards mode.
Chrome 61 has changed the behavior of document.scrollingElement to return document.documentElement instead of document.body to match the CSSOM View specification and this broke the positioning of the tooltip and context menu (when the EnableScreenBoundaryDetection is enabled).
The problems with the incorrect positioning of the tooltip and context menu are logged with Critical priority here and here and will be fixed in the next official release.
If you experience it, try the solutions proposed below in all browsers and share your feedback with us.
*** Update from 22 Dec 2017 ***
Since this issue can affect many controls (tooltip, window, loading panel, menu, etc.), a common solution may be to avoid the breaking change in Chrome by changing the scrolling container to a <div> of your own inside the <form and ensuring the higher-level elements do not scroll.
You can find an example at the end of the following KB article: https://www.telerik.com/support/kb/aspnet-ajax/details/incorrect-positioning-of-controls.
*** End of update ***
Solution 1 (for RadContextMenu)
Place the following override above (before) the RadTreeView or standalone RadContextMenu declaration in your project. This works also for a standalone context menu (for example outside of RadTreeView).
*** Updated on 10.5.2017 ***
New override that works for RadCalendar's Popup, RadTooltip, RadGrid's Column resizing and context menus, RadMenu and RadContextMenu:
<script>
$telerik.getViewPortSize =
function
() {
var
width = 0;
var
height = 0;
var
canvas = document.body;
if
((!$telerik.quirksMode && !$telerik.isSafari) ||
(Telerik.Web.Browser.chrome && Telerik.Web.Browser.version >= 61)) {
canvas = document.documentElement;
}
if
(window.innerWidth) {
// Seems there's no completely reliable way to get the viewport size in Gecko, this should be the best one
width = Math.max(document.documentElement.clientWidth, document.body.clientWidth);
height = Math.max(document.documentElement.clientHeight, document.body.clientHeight);
if
(width > window.innerWidth)
width = document.documentElement.clientWidth;
if
(height > window.innerHeight)
height = document.documentElement.clientHeight;
}
else
{
width = canvas.clientWidth;
height = canvas.clientHeight;
}
width += canvas.scrollLeft;
height += canvas.scrollTop;
if
($telerik.isMobileSafari) {
width += window.pageXOffset;
height += window.pageYOffset;
}
return
{ width: width - 6, height: height - 6 };
}
</script>
<script>
Telerik.Web.UI.RadMenu._getViewPortSize =
function
() {
var
viewPortSize = $telerik.getViewPortSize();
// The document scroll is not included in the viewport size
// calculation under FF/quirks and Edge.
var
quirksMode = document.compatMode !=
"CSS1Compat"
;
if
(($telerik.isFirefox && quirksMode) || Telerik.Web.Browser.edge) {
viewPortSize.height += document.body.scrollTop;
viewPortSize.width += document.body.scrollLeft;
}
else
if
(Telerik.Web.Browser.chrome) {
viewPortSize.height += Math.max(document.body.scrollTop, document.scrollingElement.scrollTop);
viewPortSize.width += Math.max(document.body.scrollLeft, document.scrollingElement.scrollLeft);
}
return
viewPortSize;
};
</script>
<telerik:RadTreeView RenderMode=
"Lightweight"
ID=
"RadTreeView2"
runat=
"server"
>
<ContextMenus>
<telerik:RadTreeViewContextMenu ID=
"RadTreeViewContextMenu1"
runat=
"server"
RenderMode=
"Lightweight"
>
<Items>
...
<telerik:RadToolTipManager ID=
"RadToolTipManager1"
AutoTooltipify=
"true"
runat=
"server"
>
</telerik:RadToolTipManager>
<script>
Telerik.Web.UI.RadToolTip.prototype._getPosRelativeToMouse =
function
(targetBounds) {
var
elemX = targetBounds.x;
var
elemY = targetBounds.y;
//Get last recorded mouse position
var
pos =
this
._getMousePosition();
var
mouseX = pos.clientX;
var
mouseY = pos.clientY;
//Take into consideration the offsetScroll!
var
standard = $telerik.standardsMode;
//$telerik.standardsMode does not do a good job! Extra check is needed for FF!!
//And yet another check needed for Safari! It should always be set to false in order to get the calculations right
if
(!$telerik.isIE && document.compatMode !=
"CSS1Compat"
) standard =
false
;
else
if
($telerik.isSafari && !(Telerik.Web.Browser.chrome && Telerik.Web.Browser.version >= 61)) standard =
false
;
if
(standard) {
elemX -= $telerik.getCorrectScrollLeft(document.documentElement);
elemY -= document.documentElement.scrollTop;
}
else
//NEW: Add support for quircksmode
{
elemX -= $telerik.getCorrectScrollLeft(document.body);
elemY -= document.body.scrollTop;
}
//Calculate the position of the mouse, relative to the targetcontrol
var
deltaX = mouseX - elemX;
var
deltaY = mouseY - elemY;
return
{ x: deltaX, y: deltaY };
}
</script>
I have a RadGrid where the data is from our SQL Database using a NeedDataSource and works just fine. What I would like to do is append 5 additional records that are not found in our database and will remain static. How can I add these additional records to the grid?
Hello
I would like to know if there is a way to determine the range of the X and Y axis on a "zoomed" graph. Particularly when we draw a box on a chart, is there a way to figure out the X and Y ranges of the zoomed/boxed section on Javascript ?
Thanks !
<
telerik:RadHtmlChart
ID
=
"RadHtmlChartSerie"
runat
=
"server"
Transitions
=
"true"
Skin
=
"Office2007"
>
<
Appearance
>
<
FillStyle
BackgroundColor
=
"White"
></
FillStyle
>
</
Appearance
>
<
ChartTitle
>
<
Appearance
Align
=
"Center"
BackgroundColor
=
"White"
Position
=
"Top"
></
Appearance
>
</
ChartTitle
>
<
Legend
>
<
Appearance
BackgroundColor
=
"White"
Position
=
"Bottom"
></
Appearance
>
</
Legend
>
<
PlotArea
>
<
Appearance
>
<
FillStyle
BackgroundColor
=
"White"
></
FillStyle
>
</
Appearance
>
<
XAxis
DataLabelsField
=
"Dia"
>
<
LabelsAppearance
RotationAngle
=
"90"
/>
<
TitleAppearance
Text
=
"Fecha"
/>
<
MajorGridLines
Color
=
"#EFEFEF"
Width
=
"1"
></
MajorGridLines
>
<
MinorGridLines
Color
=
"#F7F7F7"
Width
=
"1"
></
MinorGridLines
>
<
TitleAppearance
Position
=
"Center"
RotationAngle
=
"0"
Text
=
"Día"
></
TitleAppearance
>
</
XAxis
>
<
YAxis
>
<
LabelsAppearance
/>
<
TitleAppearance
Text
=
"Valor"
/>
<
MajorGridLines
Color
=
"#EFEFEF"
Width
=
"1"
></
MajorGridLines
>
<
MinorGridLines
Color
=
"#F7F7F7"
Width
=
"1"
></
MinorGridLines
>
</
YAxis
>
</
PlotArea
>
<
ChartTitle
Text
=
"Serie Analizada"
>
</
ChartTitle
>
</
telerik:RadHtmlChart
>
//Declare a ScatterSeries
ScatterSeries pointMinimos =
new
ScatterSeries();
pointMinimos.Name =
"Mínimo"
;
pointMinimos.Appearance.FillStyle.BackgroundColor = Color.Green;
pointMinimos.LabelsAppearance.Visible =
false
;
pointMinimos.TooltipsAppearance.DataFormatString =
"{1}"
;
pointMinimos.TooltipsAppearance.Color = Color.White;
//Fills The ScatterSeries
foreach
(DataRow dr
in
dsMaxMin.Tables[
"dtMinimos"
].Rows)
{
ScatterSeriesItem itemCierre =
new
ScatterSeriesItem(Convert.ToDecimal(dr[
"X"
].ToString()), Convert.ToDecimal(dr[
"Y"
].ToString()));
pointMinimos.SeriesItems.Add(itemCierre);
}
//Add The series to the Chart with XAxis numerical values
RadHtmlChartSerie.PlotArea.Series.Add(pointMinimos);
//Clear the XAxis Items
RadHtmlChartSerie.PlotArea.XAxis.Items.Clear();
//Here the column "Dia" have a date string
foreach
(DataRow row
in
dsMaxMin.Tables[
"dtMinimos"
].Rows)
{
string
formattedLabelText =
string
.Format(
"{0:MMMM}"
, row[
"Dia"
].ToString());
AxisItem newAxisItem =
new
AxisItem(formattedLabelText);
RadHtmlChartSerie.PlotArea.XAxis.Items.Add(newAxisItem);
}
Hi, I'm trying to display the scheduler control in YearView mode and I am getting an error.
Cannot create an object of type 'Telerik.Web.UI.SchedulerViewType' from its string representation 'YearView' for the 'SelectedView' property.
at System.Web.UI.TemplateParser.ProcessException(Exception ex)
at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding)
at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding)
I get the same error even if I use the sample from the Telerik site. Here is the ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EventCalendarDisplay.ascx.cs" Inherits="###.Web.iParts.Events.EventCalendar.EventCalendarDisplay" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%--Get around a z-index bug where event calendar header is drawn over top of fold down menus 'rsHeader' class only appears in this telerik calendar widget.--%>
<telerik:RadAjaxPanel ID="ContentPanel" runat="server" Visible="true" EnableAJAX="true" EnableViewState="true" LoadingPanelID="LoadingPanel">
<asp:Panel runat="server" Translate="Yes">
<telerik:RadScheduler runat="server" ID="Calendar" Height="600px"
DayStartTime="08:00:00" DayEndTime="21:00:00"
FirstDayOfWeek="Sunday" LastDayOfWeek="Saturday"
SelectedView="MonthView"
EnableDescriptionField="true"
AppointmentStyleMode="Default"
OnNavigationComplete="SchedulerNavigationComplete"
OnAppointmentDataBound="SchedulerAppointmentDataBound"
OnAppointmentClick="SchedulerAppointmentClick"
DataKeyField="Id" DataSubjectField="Subject" DataDescriptionField="Description"
AllowDelete="false"
ReadOnly="true"
DataStartField="Start" DataEndField="End"
DataRecurrenceField="RecurrenceRule" DataRecurrenceParentKeyField="RecurrenceParentId"
DataReminderField="Reminder"
CustomAttributeNames="StartText,EndText">
<AdvancedForm Modal="true" />
<AdvancedEditTemplate>
<%--Certain set of CSS classes should be set when the Form is modal.--%>
<div class="rsAdvancedEdit rsAdvancedModal rsEventCalendar" style="position: relative">
<div class="rsModalBgTopLeft">
</div>
<div class="rsModalBgTopRight">
</div>
<div class="rsModalBgBottomLeft">
</div>
<div class="rsModalBgBottomRight">
</div>
<div class="rsAdvTitle">
<h1 class="rsAdvInnerTitle">
<%# Container.Appointment.Subject %>
</h1>
<asp:LinkButton runat="server" ID="LinkButton1" CssClass="rsAdvEditClose" CommandName="Cancel"
CausesValidation="false" ToolTip='<%# Container.Appointment.Owner.Localization.AdvancedClose %>'>
<%# Container.Appointment.Owner.Localization.AdvancedClose%>
</asp:LinkButton>
</div>
<div class="rsAdvContentWrapper">
<div class="PanelFieldLeft">
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Description") %>'></asp:Label>
</div>
<div class="PanelFieldLeft">
<asp:Label ID="StartInput" Text='<%# Bind("StartText") %>' runat="server">
</asp:Label><br />
</div>
<div class="PanelFieldLeft">
<asp:Label ID="EndInput" Text='<%# Bind("EndText") %>' runat="server">
</asp:Label><br />
</div>
</div>
</div>
</AdvancedEditTemplate>
</telerik:RadScheduler>
</asp:Panel>
</telerik:RadAjaxPanel>
<telerik:RadAjaxLoadingPanel runat="server" ID="LoadingPanel" Transparency="50" IsSticky="false"
BackColor="LightGray" BackgroundPosition="Center">
</telerik:RadAjaxLoadingPanel>
<telerik:RadAjaxManagerProxy ID="RadAjaxManagerProxy1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="save">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="AjaxPanel1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManagerProxy>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
></
telerik:RadScriptManager
>
<
telerik:RadCodeBlock
ID
=
"RadCodeBlock1"
runat
=
"server"
>
<
script
type
=
"text/javascript"
>
var currentLoadingPanel = null;
var currentUpdatedControl = null;
function RequestStart(sender, args) {
args.set_enableAjax(false);
currentLoadingPanel = $find("<%= RadAjaxLoadingPanel1.ClientID%>");
currentUpdatedControl = "<%= RadGrid1.ClientID%>";
currentLoadingPanel.show(currentUpdatedControl);
}
function ResponseEnd(sender, args) {
//hide the loading panel and clean up the global variables
if (currentLoadingPanel != null) {
currentLoadingPanel.hide(currentUpdatedControl);
}
currentUpdatedControl = null;
currentLoadingPanel = null;
}
</
script
>
</
telerik:RadCodeBlock
>
<
telerik:RadAjaxManager
ID
=
"RadAjaxManager1"
runat
=
"server"
>
<
AjaxSettings
>
<
telerik:AjaxSetting
AjaxControlID
=
"RadGrid1"
>
<
UpdatedControls
>
<
telerik:AjaxUpdatedControl
ControlID
=
"RadGrid1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
/>
</
UpdatedControls
>
</
telerik:AjaxSetting
>
</
AjaxSettings
>
<
ClientEvents
OnRequestStart
=
"RequestStart"
OnResponseEnd
=
"ResponseEnd"
></
ClientEvents
>
</
telerik:RadAjaxManager
>
<
telerik:RadAjaxLoadingPanel
ID
=
"RadAjaxLoadingPanel1"
runat
=
"server"
Skin
=
"Glow"
>
</
telerik:RadAjaxLoadingPanel
>
<
telerik:RadGrid
ID
=
"RadGrid1"
runat
=
"server"
CellSpacing
=
"0"
Culture
=
"zh-TW"
DataSourceID
=
"SqlDataSource1"
GridLines
=
"None"
OnItemCommand
=
"RadGrid1_ItemCommand"
>
<
MasterTableView
AllowNaturalSort
=
"False"
AutoGenerateColumns
=
"False"
CommandItemDisplay
=
"Top"
DataKeyNames
=
"applylist_no"
AllowPaging
=
"true"
PageSize
=
"15"
DataSourceID
=
"SqlDataSource1"
NoMasterRecordsText
=
"無資料"
HierarchyLoadMode
=
"Client"
EnableHierarchyExpandAll
=
"true"
>
<
DetailTables
>
<
telerik:GridTableView
runat
=
"server"
DataSourceID
=
"SqlDataSource2"
AutoGenerateColumns
=
"False"
HierarchyLoadMode
=
"Client"
>
<
ParentTableRelation
>
<
telerik:GridRelationFields
DetailKeyField
=
"applylist_no"
MasterKeyField
=
"applylist_no"
/>
</
ParentTableRelation
>
<
CommandItemSettings
ShowAddNewRecordButton
=
"False"
ShowRefreshButton
=
"False"
/>
<
Columns
>
<
telerik:GridBoundColumn
DataField
=
"data_type"
FilterControlAltText
=
"Filter type column"
HeaderText
=
"類別"
SortExpression
=
"data_type"
UniqueName
=
"data_type"
>
</
telerik:GridBoundColumn
>
<
telerik:GridCalculatedColumn
UniqueName
=
"year"
SortExpression
=
"year_history"
HeaderText
=
"年份"
DataFields
=
"year_history,year_ipccar4,year_wrf"
Expression
=
'{0} + "" + {1}+ "" + {2}'
FooterText
=
"CalculatedColumn footer"
>
</
telerik:GridCalculatedColumn
>
<
telerik:GridCalculatedColumn
DataFields
=
"parameter_history,parameter_ipccar4,parameter_tri"
Expression
=
'{0} + "" + {1}+ "" + {2}'
FilterControlAltText
=
"Filter parameter column"
HeaderText
=
"參數"
UniqueName
=
"parameter"
>
</
telerik:GridCalculatedColumn
>
<
telerik:GridBoundColumn
DataField
=
"theme"
FilterControlAltText
=
"Filter theme column"
HeaderText
=
"情境"
SortExpression
=
"theme"
UniqueName
=
"theme"
>
</
telerik:GridBoundColumn
>
<
telerik:GridCalculatedColumn
DataFields
=
"area_history,area_ipccar4,area_wrf"
Expression
=
'{0} + "" + {1}+ "" + {2}'
FilterControlAltText
=
"Filter area column"
HeaderText
=
"地區"
UniqueName
=
"area"
>
</
telerik:GridCalculatedColumn
>
<
telerik:GridTemplateColumn
HeaderText
=
"審核是否通過"
SortExpression
=
"reject"
UniqueName
=
"reject"
>
<
ItemTemplate
>
<
asp:Label
ID
=
"Label2"
runat
=
"server"
Text='<%# WrapText(Eval("reject"))%>'></
asp:Label
>
</
ItemTemplate
>
</
telerik:GridTemplateColumn
>
</
Columns
>
<
ItemStyle
HorizontalAlign
=
"Center"
/>
<
AlternatingItemStyle
HorizontalAlign
=
"Center"
/>
<
HeaderStyle
HorizontalAlign
=
"Center"
/>
<
CommandItemStyle
HorizontalAlign
=
"Center"
/>
</
telerik:GridTableView
>
</
DetailTables
>
<
CommandItemSettings
ShowAddNewRecordButton
=
"False"
ShowRefreshButton
=
"false"
/>
<
Columns
>
<
telerik:GridBoundColumn
DataField
=
"applylist_no"
FilterControlAltText
=
"Filter applylist_no column"
HeaderText
=
"申請單號"
ReadOnly
=
"True"
SortExpression
=
"applylist_no"
UniqueName
=
"applylist_no"
>
</
telerik:GridBoundColumn
>
<
telerik:GridBoundColumn
DataField
=
"date_apply"
DataType
=
"System.DateTime"
FilterControlAltText
=
"Filter date_apply column"
HeaderText
=
"送審日期"
SortExpression
=
"date_apply"
UniqueName
=
"date_apply"
>
</
telerik:GridBoundColumn
>
<
telerik:GridBoundColumn
DataField
=
"deadline_download"
DataType
=
"System.DateTime"
FilterControlAltText
=
"Filter deadline_download column"
HeaderText
=
"下載有效期限"
SortExpression
=
"deadline_download"
UniqueName
=
"deadline_download"
DataFormatString
=
"{0:yyyy/MM/dd}"
>
</
telerik:GridBoundColumn
>
<
telerik:GridButtonColumn
ButtonType
=
"PushButton"
CommandName
=
"Download"
FilterControlAltText
=
"Filter download column"
HeaderText
=
"下載"
Text
=
"下載檔案"
UniqueName
=
"download"
>
</
telerik:GridButtonColumn
>
</
Columns
>
<
ItemStyle
HorizontalAlign
=
"Center"
/>
<
AlternatingItemStyle
HorizontalAlign
=
"Center"
/>
<
HeaderStyle
HorizontalAlign
=
"Center"
/>
<
CommandItemStyle
HorizontalAlign
=
"Center"
/>
</
MasterTableView
>
</
telerik:RadGrid
>