I have a custom validator on a page:
<asp:CustomValidator ID="CustomValidator2" runat="server"
ControlToValidate="ddlProposer" ErrorMessage="Please select some values."
Display="Dynamic" onservervalidate="CustomValidator2_ServerValidate"
ClientValidationFunction="CustomValidator2_ClientValidate">
</asp:CustomValidator>
It must be valid, when a server-side list is not empty (or: the ListCount variable > 0). This list may change after the page has been loaded (via buttons on update panel):
public partial class Pages_Application_Application : System.Web.UI.Page
{
protected List<IdValue> ProposersList
{
get
{
if (ViewState["proposersList"] == null)
ViewState["proposersList"] = new List<IdValue>();
return ViewState["proposersList"] as List<IdValue>;
}
set
{
ViewState["proposersList"] = value;
}
}
public int ListCount
{
get
{
return this.ProposersList.Count;
}
}
...
There is no problem with server-side validation:
protected void CustomValidator2_ServerValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = this.ProposersList.Count > 0;
}
The problem is with client-side part. I've been trying something like this:
<script type="text/javascript">
function CustomValidator2_ClientValidate(source, arguments) {
var serverVariable = <%= ListCount %>;
alert(serverVariable);
arguments.IsValid = serverVariable > 0;
}
</script>
however, it fires only on first page load, and the ListCount variable is always 0 (so does the serverVariable).
The question is: is there an easy-way to make it working? So the Javascript gets the current value of some server-side variable?
you can use hidden variable on the page level and by setting its value from server side and validate on client side.
<input type="hidden" id="ListCount" runat="server" value="0" />
public partial class Pages_Application_Application : System.Web.UI.Page
{
protected List<IdValue> ProposersList
{
get
{
if (ViewState["proposersList"] == null)
ViewState["proposersList"] = new List<IdValue>();
return ViewState["proposersList"] as List<IdValue>;
}
set
{
ViewState["proposersList"] = value;
ListCount=value;
}
}
public int ListCount
{
get
{
return this.ProposersList.Count;
}
}
<script type="text/javascript">
function CustomValidator2_ClientValidate(source, arguments) {
var count= document.getElementById("ListCount").value;
alert(count);
arguments.IsValid = count > 0;
}
You'll have to do it in plain javascript, and there is no sens of getting the server side variable since it won't be up to date at the moment client validation will be done.
What you need is pass your ddl html element to your CustomValidator2_ClientValidate function and check if it contains option html elements, that should do the trick.
Related
I am not able to read the Checked status of my custom checkbox control.
I created this control so that it would rendor correctly for easy use with bootstrap.
The control renders perfectly, and I have all the function that I want/need EXCEPT being able to read the checked status of the input when the user clicks 'submit'.
Custom Server Control Code (C#):
public class InlineBootstrapCheckBox : CheckBox, IPostBackDataHandler, ICheckBoxControl
{
private string value;
private string labelCSS;
private string labelID;
public string LabelID
{
get
{
if (!string.IsNullOrEmpty(this.labelID))
{
return this.labelID;
}
else
{
return null;
}
}
set
{
this.labelID = value;
}
}
public string LabelCSS
{
get
{
if (!string.IsNullOrEmpty(this.labelCSS))
{
return this.labelCSS;
}
else
{
return null;
}
}
set
{
this.labelCSS = value;
}
}
public string Value
{
get
{
if (!string.IsNullOrEmpty(this.value))
{
return this.value;
}
else
{
throw new NotImplementedException("You must set a 'Value' for InlineBootstrapCheckBox Controls");
}
}
set
{
this.value = value;
}
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
writer.WriteLine(string.Format("<label id=\"{0}\" class=\"{1}\" for=\"{2}\">", (this.LabelID != null) ? this.LabelID : string.Concat(this.ID, "_Label"), (this.LabelCSS != null) ? string.Concat(this.LabelCSS, " checkbox-inline") : "checkbox-inline", this.ID));
writer.WriteLine(string.Format("<input type=\"checkbox\" id=\"{0}\" value=\"{1}\">", this.ID, this.Value));
writer.WriteLine(this.Text);
writer.WriteLine("</label>");
}
}
Markup Code (.ASPX):
<div class="form-group">
<label id="lblCategories" class="col-sm-3 control-label">Categories</label>
<div class="col-sm-9">
<cookout:InlineBootstrapCheckBox runat="server" ID="chkRibs" Text="Ribs" Value="1" />
<cookout:InlineBootstrapCheckBox runat="server" ID="chkChicken" Text="Chicken" Value="2" />
<cookout:InlineBootstrapCheckBox runat="server" ID="chkBrisket" Text="Beef Brisket" Value="3" />
<cookout:InlineBootstrapCheckBox runat="server" ID="chkPork" Text="Pork" Value="4" />
<cookout:InlineBootstrapCheckBox runat="server" ID="chkAnythingBut" Text="Anything But" Value="5" />
</div>
</div>
Code Behind (C#):
This is where I think my problem is?
protected void btnSubmit_Click(object sender, EventArgs e)
{
ProRegistration regInfo = new ProRegistration();
regInfo.TeamName = this.txtTeamName.Text.ToString();
regInfo.ContactName = this.txtContactName.Text.ToString();
regInfo.StreetAddress = this.txtContactAddress.Text.ToString();
regInfo.City = this.txtContactCity.Text.ToString();
regInfo.State = this.txtContactState.Text.ToString();
regInfo.ZipCode = this.txtContactZip.Text.ToString();
regInfo.Email = this.txtContactEmail.Text.ToString();
regInfo.Phone = this.txtContactPhone.Text.ToString();
regInfo.IsRibs = this.chkRibs.Checked;
regInfo.IsChicken = this.chkChicken.Checked;
regInfo.IsBrisket = this.chkBrisket.Checked;
regInfo.IsPork = this.chkPork.Checked;
regInfo.IsAnythingBut = this.chkAnythingBut.Checked;
regInfo.Created = DateTime.Now;
DataManager.InsertProfessionalRegistration(regInfo);
}
...So basically what I need is to be able to get a positive response when I try to submit this object to my database. Currently, no matter the click status, I get a false result.
I have been trying to research an answer to this for about 3 hours now to no avail.
Thank you!
I don't know bootstrap but it looks like you are injecting an html checkbox into the output. If this is the case it will not be recognized as a server control on postback, however you can get its value by using the request.form object.
string result=Request.Form["thecheckboxid"];
I'm trying to make my first ASP.NET web site and am unable to get searching and paging to work in ASP.NET Web Forms without using an invisible button. I can't use my search button's click event because it needs to reset my page to 0 when clicked, so it only has a client-click event. I have to make it call a JavaScript function, which calls the invisible button's click event handler after doing so. The only way I can figure out around it is to make the page post back to itself and pass the index in from the bottom paging table. Hopefully, someone here might have some suggestions for an easier way to do it. Thanks in advance for any suggestions. If it wasn't for paging, it would be one line of code inside my button click event handler.
Here is the relevant markup for my page.
<script language="javascript">
function page(index)
{
document.getElementById('PageIndex').value = index;
document.getElementById('btnInvisible').click();
}
</script>
<uc1:ucWidgetSearch runat="server" id="ctl" />
<p id="pHTML" runat="server"/>
<asp:Button ID="btnInvisible" runat="server" BackColor="White"
BorderStyle="None" BorderWidth="0px" OnClick="btnInvisible_Click" />
<asp:HiddenField ID="PageIndex" runat="server" /
Here is the markup for the UserControl on the page.
<label>Last Name:</label>
<asp:TextBox ID="txtLastName" runat="server" MaxLength="50" Enabled="false"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" Text="Search" OnClientClick="page('0')" />
Here is the C# code behind for the .aspx page. The .aspx page uses no using statements.
namespace Widgets.WebUI
{ public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, System.EventArgs e)
{ ScreenHelper.LoadScreen(ctl.Search(), pHTML, PageIndex);}
protected void btnInvisible_Click(object sender, System.EventArgs e)
{ }
}
}
Here is the code behind for the UserControl. It also uses no using statements.
public partial class ucWidgetSearch : System.Web.UI.UserControl
{
internal Widgets.BLL.WidgetSearch Search()
{
if (!txtLastName.Enabled)
{
txtLastName.Enabled = true;
txtLastName.Focus();
return null;
}
return new Widgets.BLL.WidgetSearch(txtLastName.Text);
}
}
Finally, there is a ScreenHelper class that calls into the BLL layer, which calls into the DAL layer and constructs an HTML document and passes it into the p element on the main page.
internal class ScreenHelper
{
internal static void LoadScreen(WidgetSearch search,
System.Web.UI.HtmlControls.HtmlGenericControl p, HiddenField page)
{
if (search != null)
{
try
{
p.InnerHtml = WidgetsLogic.GetHTMLTable(search.LastName, int.Parse(page.Value), 20);
}
catch (System.Exception ex)
{
p.InnerHtml = "<label style=\"color: #FF0000\">Error loading screen: " + ex.Message + "</label>";
}
}
}
}
namespace Widgets.BLL
{
public class WidgetsLogic
{
public static string GetHTMLTable(string name, int pageIndex, int? pageSize)
{
StringBuilder strBuilder = new StringBuilder("<table border=\"1\">");
List<Widget> list = WidgetsDataAccess.GetByName(name);
int minDex = 0, maxDex = list.Count;
if (pageSize == null)
{
pageIndex = 0;
}
else
{
pageIndex = HTMLHelper.GetPageIndex(pageIndex, pageSize.Value, list.Count);
minDex = pageIndex * pageSize.Value;
maxDex = minDex + pageSize.Value;
if (maxDex > list.Count)
maxDex = list.Count;
}
for (int i = minDex; i < maxDex; i++)
{
strBuilder.Append("<tr");
// Set Light Gray Color for alterating rows in table
if (i%2 != 0)
strBuilder.Append(" style=\"background-color: #EBEBEB\"");
strBuilder.Append("><td>" + list[i].ID.ToString() + "</td>");
strBuilder.Append("<td>" + list[i].Name + "</td></tr>");
}
strBuilder.Append("</table>");
// Add Paging if appropriate
if (pageSize != null && pageSize.Value < list.Count)
{
strBuilder.Append(HTMLHelper.GetPagingFooter(pageIndex, pageSize.Value,
list.Count, "javascript:page('#pageIndex')"));
}
string str = strBuilder.ToString();
return str;
}
}
you should never try to do paging manually. Rather use GridView and an ObjectDataSource
to bind data to your page. This way ASP.NET handles the pageIndex exc via viewstate and the ObjectDatasource handles paging for you.Check this link for a good example of how to do just that.
Use ClientID to refer to the actual ID of an HTML control
document.getElementById('<%= PageIndex.ClientID %>').value = index;
I am using Client script for confirm message box as follows
string script = "fadeScript";
ScriptManager.RegisterClientScriptBlock(this.Page, script.GetType(), "Script", "Closewindow();", true);
java script function:
<script type="text/javascript">
function Closewindow() {
var Result = confirm("Are you sure want to delete?");
alert(Result);
if (Result == true) {
document.getElementById('txtConfirmresult').value = Result;//assigning to hidden text box
alert(txtConfirmresult.value);
return true;
}
else
{
document.getElementById('txtConfirmresult').value = Result;//assigning to hidden text box
alert('BYE');
return false;
}
}
</script>
I want to use the script return value in .cs file to excite procedure if it returns true. if it return false i have to stay on that particular page only. plz kindly help me on this
You can use __doPostBack(target, argument) to post back to the server. You can then evaluate __EVENTTARGET and __EVENTARGUMENT in the post data to see what you sent back and perform logic appropriately. Here is a link that provides a little more in depth information.
A quick example:
Script/Client side:
<script type="text/javascript">
function Closewindow() {
var Result = confirm("Are you sure want to delete?");
alert(Result);
if (Result == true) {
var txtConfirmResult = document.getElementById('txtConfirmresult');
txtConfirmResult.value = Result;//assigning to hidden text box
alert(txtConfirmresult.value); //displaying for debug purposes
__doPostBack( 'txtConfirmresult', Result ); //sending back to server.
return true;
}
else
{
document.getElementById('txtConfirmresult').value = Result;//assigning to hidden text box
alert('BYE');
return false;
}
}
C#
protected void Page_Load(object sender, EventArgs e)
{
string target = Request["__EVENTTARGET"];
string argument = Request["__EVENTARGUMENT"];
if (target != null && target.Equals( "txtConfirmresult" ) )
{
this.DoSomeGreatServerSideProcessing(argument);
}
}
Updated to add slightly more correct variable names, but should work with your existing codebase assuming your script was working. I would be very careful using txtConfirmresult as your ID as that will only work if runat="server" is not set on the textbox. If that is the case, the ID will be prepended to denote container hierarchy.
I would suggest naming your "callbacks" very well, such as:
Script/Client side:
<script type="text/javascript">
function Closewindow() {
var Result = confirm("Are you sure want to delete?");
document.getElementById('txtConfirmresult').value = Result;//assigning to hidden text box
if (Result) {
__doPostBack( 'UserConfirmedFormSubmission', "CloseWindow" ); //sending back to server.
return true;
}
else
{
return false;
}
}
C#
protected void Page_Load(object sender, EventArgs e)
{
string target = Request["__EVENTTARGET"];
string argument = Request["__EVENTARGUMENT"];
if (!string.IsNullOrEmpty(target) && target.Equals("UserConfirmedFormSubmission"))
{
if ( !string.IsNullOrEmpty(argument) && argument.equals("CloseWindow"))
{
this.HandleUserRequestedCloseWinow();
}
}
}
I'm trying to make a generic Search UserControl that can be given some values, based on those values the search results will display. However I'm currently trying to display the results of my values, and they always show up as my default values.
my UserControl code:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ProductSearch.ascx.cs" Inherits="..." %>
<asp:Label ID="lblSearchWord" runat="server" />
<asp:Label ID="lblSearch" runat="server" />
Code Behind:
private string _searchWord = string.Empty;
private int _search = -1;
public string SearchWord
{
get { return _searchWord; }
set { _searchWord = value; }
}
public int Search
{
get { return _search; }
set { _search = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
lblGroupId.Text = LevelId.ToString();
lblSearchWord.Text = SearchWord;
}
When I press the search button on the main aspx.cs page I do the following:
protected void btnSearch_Click(object sender, EventArgs e)
{
ucPS.SearchWord = txtProductSearch.Text;
ucPS.Search = 1
}
My aspx page contains the following
<%# Register src="UserControls/ProductSearch.ascx" tagname="ProductSearch" tagprefix="ps" %>
<ps:ProductSearch id="ucPS" runat="server" />
My problem is that I can't use Query strings as the user might have selected some other things on this page that I need to keep the state of, however I did test that one and foudn it working.
Where am I going wrong? or is there an better alternative (except for query strings).
All variables in a page are disposed at the end of the page-lifecycle. Hence SearchWord will always be initialized with the default value on every postback.
You need to persist it somewehere else, for example in a ViewState variable.
public string SearchWord
{
get
{
if (ViewState["SearchWord"] == null)
return "";
else
return (String)ViewState["SearchWord"];
}
set { ViewState["SearchWord"] = value; }
}
Nine Options for Managing Persistent User State in Your ASP.NET Application
public string SearchWord
{
get
{
if (ViewState["SearchWord"] == null)
ViewState["SearchWord"] = string.Empty;
return ViewState["SearchWord"];
}
set
{
ViewState["SearchWord"] = value;
}
}
and I use databind not pageload, this way your usercontrol doesn't load unless you call it.
protected override DataBind()
{
//you can add a condition here if you like
if(SearchWord != string.Empty)
lblSearchWord.Text = SearchWord;
}
to call this from aspx:
usercontrol.SearchWord = "my word";
usercontrol.DataBind();
and thats it..
The treeview has leaf node checkboxes.I need to validate the treeview
if atleast one of the node is checked and not more than a specfic(say 3 nodes) number of nodes a user can select.
Note:The Treeview is a asp.net treeview(not an ajax treeview)
Alright, since you didn't mentioned what type of validation you want, I'll do both client side and server side. My TreeView is named tvTest
First, add a CustomValidator to you Asp.Net page:
<asp:CustomValidator ID="CustomValidator1" runat="server" ClientValidationFunction="ClientValidate"
ErrorMessage="CustomValidator" Display="Dynamic" OnServerValidate="CustomValidator1_ServerValidate">*</asp:CustomValidator>
Note: don't set the ControlToValidate property.
Next, add this script (also to your Asp.Net page) for client side validation:
<script type="text/javascript">
function ClientValidate(source, arguments) {
var treeView = document.getElementById("<%= tvTest.ClientID %>");
var checkBoxes = treeView.getElementsByTagName("input");
var checkedCount = 0;
for (var i = 0; i < checkBoxes.length; i++) {
if (checkBoxes[i].checked) {
checkedCount++;
}
}
if (checkedCount > 0 && checkedCount < 4) {
arguments.IsValid = true;
} else {
arguments.IsValid = false;
}
}
</script>
And last, add this to your code-behind for server side validation:
protected void CustomValidator1_ServerValidate(object source, System.Web.UI.WebControls.ServerValidateEventArgs args) {
if (tvTest.CheckedNodes.Count > 0 && tvTest.CheckedNodes.Count < 4) {
args.IsValid = true;
} else {
args.IsValid = false;
}
}
Of course, you'll want to change the limits for the minimum and maximum number of nodes the user can check.