I am trying to use the Slider control from AjaxControlTookit and my problem is that I cannot find a way to display non-numeric values inside the label bound to the slider. My code is like below..
Code:
<asp:TextBox ID="txtSlider" runat="server" style="display:none;/>
<ajaxToolkit:SliderExtender ID="slider1" runat="server" TargetControlID="txtSlider" Steps="3" BoundControlID="lblSliderValue" Minimum="1" Maximum="3" Orientation="Vertical"></ajaxToolkit:SliderExtender>
<asp:Label ID="lblSliderValue" runat="server" />
The lblSliderValue only shows me the values of 0,1 and 2, however I would need low, medium and high. So far I haven't found any way to specify these. I tried adding the textbox's OnTextChanged="txtSlider_textChanged" AutoPostBack="true" and set the lblSliderValue in code behind, with no succes. Any ideas on how to achieve this?
Such functionality doesn't implemented in slider. So let's customize it a bit.
At the first, you need to download toolkit sources. We will modify two files (I'll provide a links to codeplex for these files so you'll easy locate them in solution): SliderExtender.cs and SliderBehavior_resource.pre.js
Mark the SliderExtender class with this attribute: [ParseChildren(typeof(ListItem), ChildrenAsProperties = true)]
private List<ListItem> items = new List<ListItem>();
[PersistenceMode(PersistenceMode.InnerProperty)]
[ExtenderControlProperty]
[ClientPropertyName("items")]
public List<ListItem> Items
{
get { return items; }
}
static SliderExtender()
{
if (!ScriptObjectBuilder.CustomConverters.ContainsKey(typeof(ListItem)))
{
ScriptObjectBuilder.CustomConverters.Add(typeof(List<ListItem>), SerializeItemsToJson);
}
}
private static string SerializeItemsToJson(object itemsParam)
{
var items = itemsParam as List<ListItem>;
if (items == null)
return null;
return "{" + string.Join(",", items.Select(item => string.Format("{0}: '{1}'", item.Value, item.Text))) + "}";
}
That's all with server code so let's tweak client side code of extender.
Let's start with JavaScript code. Add to body of Sys.Extended.UI.SliderBehavior function this item: this._items = null;
And add to prototype of Sys.Extended.UI.SliderBehavior function code below:
get_items: function () {
return this._items;
},
set_items: function (value) {
if (Sys.Serialization.JavaScriptSerializer.serialize(this._items) != value) {
this._items = Sys.Serialization.JavaScriptSerializer.deserialize(value);
this.raisePropertyChanged('items');
}
}
Then, modify the _calcValue function as following:
_calcValue: function (value, mouseOffset) {
var val;
if (value != null) {
if (!Number.isInstanceOfType(value)) {
if (this._items) {
for (var prop in this._items) {
if (this._items.hasOwnProperty(prop) && this._items[prop] === value) {
value = prop;
break;
}
}
}
//rest of function's code stays as it is
And the last step - fix the _ensureBinding function:
_ensureBinding: function () {
if (this._boundControl) {
var value = this._value;
var displayItem = this._items && this._items.hasOwnProperty(value) ? this._items[value] : null;
if (value >= this._minimum || value <= this._maximum) {
var isInputElement = this._boundControl.nodeName == 'INPUT';
if (isInputElement) {
this._boundControl.value = displayItem || value;
}
else if (this._boundControl) {
this._boundControl.innerHTML = displayItem || value;
}
}
}
}
After all changes above, rebuild solution and add reference on toolkit dll to your project. Sample of usage of modified slider here. And it still support two-way binding (i.e. from extender to label but not from bounded textbox to extender).
<asp:TextBox ID="Slider1" runat="server" />
<br />
<ajaxToolkit:SliderExtender ID="SliderExtender1" runat="server" BehaviorID="Slider1"
TargetControlID="Slider1" Minimum="1" Maximum="3" BoundControlID="Slider1_BoundControl"
Steps="5">
<Items>
<asp:ListItem Value="1" Text="Low" />
<asp:ListItem Value="2" Text="Medium" />
<asp:ListItem Value="3" Text="High" />
</Items>
</ajaxToolkit:SliderExtender>
<asp:TextBox runat="server" ID="Slider1_BoundControl" />
<%--<asp:Label ID="Slider1_BoundControl" runat="server" Style="text-align: right" />--%>
Related
I have a ASPxMenu that I have named "mnuCategoryOptions" and it has 4 items and I also have ASPxPopupControl that I have named "popupAddProductCategory". When I click one of the items in the ASPxMenu I want it to bring up the ASPxPopupControl. I have written my code in the following way and it does not work:
<dx:ASPxMenu ID="mnuCategoryOptions" runat="server" OnItemClick="mnuCategoryOptions_ItemClick">
<ClientSideEvents ItemClick="function(s, e)
{
e.processOnServer = false;
if (e.item.name == 'mnuAddCategory') { popupAddProductCategory.Show = true; }
else if (e.item.name == 'mnuEditCategory') { alert('Edit Category'); }
else if (e.item.name == 'mnuDeleteCategory') { alert('Del Category'); }
else if (e.item.name == 'mnuAddProducts') { alert('Add Products'); }
else { e.processOnServer = true; }
}" />
<Items>
<dx:MenuItem Name="mnuAddCategory" Text="Add Category"><Image Url="~/images/GridIcons/add.png"/></dx:MenuItem>
<dx:MenuItem Name="mnuEditCategory" Text="Edit Category"><Image Url="~/images/GridIcons/page_edit.png"/></dx:MenuItem>
<dx:MenuItem Name="mnuDeleteCategory" Text="Delete Category"><Image Url="~/images/GridIcons/delete.png"/></dx:MenuItem>
<dx:MenuItem Name="mnuAddProducts" Text="Add Products"><Image Url="~/images/GridIcons/page_add.png" /></dx:MenuItem>
</Items>
</dx:ASPxMenu>
Please look at the line "if (e.item.name == 'mnuAddCategory') { popupAddProductCategory.Show = true; }". This is the line that is not working. Please help.
Kind Regards
Siyabonga Kubeka
Suppose you have ASPxPopupControl server control like this:
<dx:ASPxPopupControl ID="popupAddProductCategory" runat="server" ClientInstanceName="popupAddProductCategory" ... />
Then you should use Show() method to show that popup with client-side code:
if (e.item.name == 'mnuAddCategory') {
popupAddProductCategory.Show();
}
According to ASPxClientPopupControlBase member list, Show is name of a method, not a property. Also ClientInstanceName property from popup control must be used if you want to use same client-side name as control name.
Reference:
ASPxClientPopupControlBase.Show() function
I am trying to show an error by changing the color of the border of a text box. I have found a lot of posts on how to do it, but I have never done anything with 'Validators' so I am confused where to start, or where to put the code.
Similar posts:
Post One
Post Two
My main question(s) are, where do I put the JS code? And secondly, how do I call the code?
Current Code
If TicketNumber.Text = String.Empty = True Then
NotificationLabel.Text = "Ticket Number must be filled out"
Exit Sub
End If
A RequiredFieldValidator could do it with some tricks explained here, and here. Another way is to use a CustomValidator like the following.
aspx mark-up
<asp:TextBox runat="server" ID="tbText" />
<asp:CustomValidator ID="cvCustom" ErrorMessage="Ticket Number must be filled out"
ControlToValidate="tbText" runat="server" OnServerValidate="ValidateInput"
ClientValidationFunction="ValidateInput" ValidateEmptyText="True" />
<asp:Button Text="My Button" runat="server" />
Javascript
<script type="text/javascript">
function ValidateInput(sender, args) {
if (args.Value == '') {
args.IsValid = false;
document.getElementById('<%= tbText.ClientID %>').style.borderColor = "red";
return false;
}
return true;
}
</script>
Code Behind (C#)
protected void ValidateInput(object source, ServerValidateEventArgs args)
{
if(string.IsNullOrWhiteSpace(args.Value))
{
args.IsValid = false;
tbText.Style["border-color"] = "red";
}
else
{
args.IsValid = true;
}
}
I use a performCallback to add a new item to my ASPxCombo on serverside, and want to change my index to that new item on the client side. I use DevExpress onEndCallback to do this and it is working great if my index is <= 99. Above that the index is not changed.
Do anybody no if DevExpress's SetSelectedIndex() method works with index greater than this, seems a little strange to me.
<dx:ASPxComboBox runat="server"
ID="CmbManufacturer"
ClientInstanceName="cmbManufacturer"
CssClass="dxeButtonEdit_LWDisplayEdit_CustomDropDown"
DropDownStyle="DropDownList"
EnableCallbackMode="True"
OnCallback="CmbManufacturer_Callback"
ValueType="System.String"
FieldName="ID"
TextFormatString="{0}"
FilterBy="Name"
TextField="Name"
ValueField="ID"
EnableSynchronization="False"
AllowEdit="false"
ValidationSettings-Display="None"
AutoPostBack="False"
Visible="False"
Width="400" >
<ClientSideEvents SelectedIndexChanged="function(s,e) {OnManufacturerChanged(s,e); }"
Init="function(s,e) {LwValidating2(s,e);}"
EndCallback="function(s,e) { OnEndCallbackCmbManufacturer(s,e); }"/>
</dx:ASPxComboBox>
function OnEndCallbackCmbManufacturer(s, e) {
var index = s.cpSelectedIndex;
s.SetSelectedIndex(index);
OnManufacturerChanged(s, e);
}
I have solved the problem by moving my new Item in dropdownItemList up in front of list below CallbackpageSize. Then i can change index on combo to the Items new index.
protected void CmbManufacturer_Callback(object source, CallbackEventArgsBase e)
{
var manufacturerName = e.Parameter.Trim();
// need to move item to top of list because it must be lower than CallbackPagesize to work
int indexforNewItem = 1;
try
{
int newManufacturerId = SoftwareManufacturer.Update(-1, manufacturerName, "");
LoadDropDownBoxManufacturer(null);
int newManufacturerIndex = CmbManufacturer.Items.IndexOfText(manufacturerName);
CmbManufacturer.Items.Move(newManufacturerIndex, indexforNewItem);
CmbManufacturer.JSProperties["cpSelectedIndex"] = indexforNewItem;
}
catch ()
{
}
}
What property do I use on the required field validator control to make the textbox red if there is a validation error?
Here is my code:
<asp:Label ID="lblFirstName" runat="server" AssociatedControlID="txtFirstName" Text="First Name:" CssClass="reg-labels" />
<br />
<asp:TextBox ID="txtFirstName" runat="server" CausesValidation="true" MaxLength="60" CssClass="standard_width"/>
<asp:RequiredFieldValidator ControlToValidate="txtFirstName" runat="server" ID="valFirstName" ValidationGroup="grpRegistration" ErrorMessage="First Name is required." Text="*" />
ASP.Net web forms internally uses a Javascript frameworka located at aspnet_client\{0}\{1} folder to handle the validation, etc. They are basically determined from the property ClientScriptsLocation
Try overriding the default framework function by keeping it in your page includes additional line to set the control_to_validate color
document.getElmentById(val.controltovalidate).style.border='1px solid red';
<asp:TextBox ID="txtFirstName" runat="server" CausesValidation="true" MaxLength="60"
CssClass="standard_width" />
<asp:RequiredFieldValidator ControlToValidate="txtFirstName" runat="server" ID="valFirstName" ValidationGroup="grpRegistration" ErrorMessage="First Name is required." Text="*" />
<asp:Button Text="Super" ID="btnSubmit" CausesValidation="true" runat="server" />
JS
<script type="text/javascript">
function ValidatorUpdateDisplay(val) {
if (typeof (val.display) == "string") {
if (val.display == "None") {
return;
}
if (val.display == "Dynamic") {
val.style.display = val.isvalid ? "none" : "inline";
return;
}
}
val.style.visibility = val.isvalid ? "hidden" : "visible";
if (val.isvalid) {
document.getElementById(val.controltovalidate).style.border = '1px solid #333';
}
else {
document.getElementById(val.controltovalidate).style.border = '1px solid red';
}
}
</script>
Without overloading anything, give your <asp:*Validator tags a CssClass="garbage" attribute.
In your style sheet, create
.garbage {
display: none;
}
.garbage[style*=visible] + input,
.garbage[style*=visible] + select,
.garbage[style*=visible] + textarea {
background-color: #ffcccc;
border: 1px solid #ff0000;
}
and any form control immediately preceded by a validator will be highlighted on invalid data.
EDIT:
I've seen a few methods for forcing a redraw in Chrome, including a pure css solution: transform: translateZ(0);
Murali's answer works great, but I rolled a jQuery version for myself if anyone's interested.
Based on the official documentation (https://msdn.microsoft.com/en-us/library/yb52a4x0.aspx), I was able to get each validator and check to see if it isvalid, and if not, use the errormessage property to populate my own notification system (setStatusMessage() is a function I wrote, feel free to use any other type of status message prompt, like alert() or roll your own).
/*
* Validation Catcher - Sean D Kendle - 9/24/2015
* Catch validation events and add to status messages system
*/
$(document).on("submit", function () {
$.each(Page_Validators, function (i, v) {
var strControlToValidateID = v.controltovalidate;
var $controlToValidate = $("#" + strControlToValidateID);
var arrInvalidControls = new Array(); //collection of all invalid field ids for later
if (!v.isvalid) {
$controlToValidate.addClass("error"); //custom error class, optional
$controlToValidate.css("border-color", "#D00"); //manually set border-color per OP's question
$(".error").eq(0).focus(); /*set focus to top-most invalid field on error, or you can use the v.focusOnError property to check if validator has this set (string "t" if true), but I don't want to have to set this every time*/
arrInvalidControls.push(strControlToValidateID); //collect all invalid field ids for later
$(v).addClass("redtext"); //custom class - allows me to make all errors red without having to add a ForeColor property to every validator
setStatusMessage(v.errormessage, "red", -1); // setStatusMessage is a function I wrote, replace with another alert system if desired, or delete this line
} else {
/*the following prevents control being seen as valid if there are two or more validators for the control - example: required field validator, then custom or regex validator (first would be invalid, second would be valid for empty field)*/
if (!$.inArray(strControlToValidateID, arrInvalidControls)) {
$controlToValidate.removeClass("error");
$controlToValidate.css("border-color", "");
} else {
//console.log(strControlToValidateID + " is already invalid.");
}
}
});
});
I hope this helps someone!
Well, to your disappointment there isn't a direct way (cf https://stackoverflow.com/a/5249021/145682)
However, you can make use of a CustomValidator. Here is one way to define it:
<asp:TextBox ID="txtbx" runat="server"></asp:TextBox>
<asp:CustomValidator ID="customValidator"
runat="server" ValidationGroup="submit" ControlToValidate="txtbx"
ClientValidationFunction="foo" ErrorMessage="*"></asp:CustomValidator>
Make note of the ClientValidationFunction. It has to be written as follows:
function foo(sender, e) {
var value = e.Value;
console.log('Value: ', e.Value);
var ctrlid = sender.controltovalidate;
var targetControl = document.getElementById(ctrlid);
if (vowels.indexOf(value[0].toLowerCase()) == -1) {
console.log('true-executed');
e.isValid = false;
targetControl.style.borderColor = 'red';
}
else {
console.log('else-executed');
e.isValid = true;
targetControl.style.borderColor = '';
}
}
The controltovalidate property of sender will give you the id of the control you are looking for; in other words, your ControlToValidate. And, Value property of e should give you the target control's value.
The other option, is you can write your own server control to do the job: http://msdn.microsoft.com/en-us/library/aa719624(v=vs.71).aspx
Murali's answer worked for me as data changes, but on postback all the fields rendered as though there were no validation errors. I found that ASP.NET lazy-loads ValidatorUpdateDisplay, so the client-side override doesn't take effect until after it's already passed its onload validation. I'm guessing there's either a version or an implementation difference that blocked me here, but other solutions (including a few with CSS) weren't working either.
Eventually, I came upon a solution that combines Murali's answer with Dillie-O's solution from here: Change Text Box Color using Required Field Validator. No Extender Controls Please
<div class="pad-left">
<asp:CompareValidator ID="comvIncTaxable" runat="server" ControlToValidate="tbIncTaxable" Display="Dynamic" Operator="DataTypeCheck" Type="Currency" CssClass="red-border"
ErrorMessage="Please enter a currency value.">
<span></span>
</asp:CompareValidator>
<asp:TextBox runat="server" ID="tbIncTaxable"></asp:TextBox>
</div>
<script type="text/javascript">
$(function () {
setValidatedBordersOnLoad();
});
function ValidatorUpdateDisplay(val) {
if (typeof (val.display) == "string") {
if (val.display == "None") {
return;
}
if (val.display == "Dynamic") {
val.style.display = val.isvalid ? "none" : "inline";
if (val.className == 'red-border' && val.controltovalidate) {
if (val.isvalid) {
document.getElementById(val.controltovalidate).style.border = '1px solid #ccc';
}
else {
document.getElementById(val.controltovalidate).style.border = '1px solid red';
}
}
return;
}
}
val.style.visibility = val.isvalid ? "hidden" : "visible";
}
function setValidatedBordersOnLoad()
{
for (var i = 0; i < Page_Validators.length; i++)
{
var val = Page_Validators[i];
if (val.className == 'red-border' && val.controltovalidate) {
var ctrl = document.getElementById(val.controltovalidate);
if (ctrl != null && ctrl.style != null) {
if (!val.isvalid)
ctrl.style.border = '1px solid red';
else
ctrl.style.border = '1px solid #ccc';
}
}
}
}
</script>
The nice thing about this solution is it lets you cherry-pick which validators get this special handling simply by adding CssClass='red-border' to the validator. In my case, I only wanted this behavior on fields within a specific grid where cell positioning shouldn't change, but still wanted to use out-of-box functionality elsewhere on the form.
I am using Ajax toolkit with a combobox functionality, the items being displayed are around 40,000, so I want to apply a filter on the same, so that a user types an alphabet in the combobox and corresponding entries with starting alphabet "a" will be displayed in the combobox.
Can I have an idea, I am not using Radcombobox, it is a simplest combobox.
<asp:ComboBox ID="AppComCombx" runat="server"
CssClass="dropdownpersonal textfont"
onselectedindexchanged="AppComCombx_SelectedIndexChanged" AutoPostBack="true">
</asp:ComboBox>
Try this : AutoCompleteMode = "SuggestAppend"
Like this
<ajaxToolkit:ComboBox ID="ComboBox1" runat="server"
AutoPostBack="False"
DropDownStyle="DropDownList"
AutoCompleteMode="SuggestAppend"
CaseSensitive="False"
CssClass=""
ItemInsertLocation="Append" />
For more info go here
Add to the ScriptManager reference on js file with script below and use Suggest or None mode for combo
Sys.Application.add_load(function () {
Sys.Extended.UI.ComboBox.prototype._ensureHighlightedIndex = function () {
// highlight an index according to textbox value
var textBoxValue = this.get_textBoxControl().value;
// first, check the current highlighted index
if (this._highlightedIndex != null && this._highlightedIndex >= 0
&& this._isExactMatch(this._optionListItems[this._highlightedIndex].text, textBoxValue)) {
return;
}
// need to find the correct index
var firstMatch = -1;
var ensured = false;
var children = this.get_optionListControl().childNodes;
for (var i = 0; i < this._optionListItems.length; i++) {
var itemText = this._optionListItems[i].text;
children[i].style.display = this._isPrefixMatch(itemText, textBoxValue) ? "list-item" : "none";
if (!ensured && this._isExactMatch(itemText, textBoxValue)) {
this._highlightListItem(i, true);
ensured = true;
}
// if in DropDownList mode, save first match.
else if (!ensured && firstMatch < 0 && this._highlightSuggestedItem) {
if (this._isPrefixMatch(itemText, textBoxValue)) {
firstMatch = i;
}
}
}
if (!ensured) {
this._highlightListItem(firstMatch, true);
}
};
});
AutoCompleteExtender is better choice in this case as all the way ComboBox will render all items on a page