Aligning checkboxes in nested repeater - c#

I have a nested repeater control and I am trying to list out the items underneath that nested repeater over a few spaces including the check box associated with it. But it seems like every other line is a checkbox without a label, can someone shed a little light?
<asp:Repeater ID="parentRepeater" runat="server">
<ItemTemplate>
<br />
<b>
<input type="checkbox" id="chk_ParentProgram" name="chk_ParentProgram" runat="server"
value='<%# ((programsRepeat)Container.DataItem).Level == 1 ? ((programsRepeat)Container.DataItem).ProgramID.ToString() : "" %> '
/>
<label for="chk_ParentProgram">
<%# ((programsRepeat)Container.DataItem).Level == 1 ? ((programsRepeat)Container.DataItem).ProgramName : "" %>
</label>
</b>
<asp:Repeater>
<ItemTemplate>
<br/>
<input type="checkbox" id="chk_ChildProgram" name="chk_Child" runat="server"
value='<%# ((programsRepeat)Container.DataItem).Level == 2 ? ((programsRepeat)Container.DataItem).ProgramID.ToString() + " from the child repeater" : "" %>'
/>
<label for="chk_ChildProgram">
<%# ((programsRepeat)Container.DataItem).Level == 2 ? ((programsRepeat)Container.DataItem).ProgramName : "" %>
</label>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>

The problem is whether you have a valid value or empty sting for (programsRepeat)Container.DataItem).ProgramID.ToString() you still rendering the checkbox like below
<input type="checkbox" value="" />
This will render the empty checkbox.
Better check the value and render the checkbox like
<% if((programsRepeat)Container.DataItem).Level == 2 &&
((programsRepeat)Container.DataItem).ProgramID!="")
{
//not sure about the inline syntax here.
//add checkbox code
}
%>
Inline Syntax Reference or check this

Related

How to enable href to appear with certain condition. ASP.NET C#

I'm trying to enable users to edit their respective comments they have made on my project. What I would like to do is match the current user in session with the eval value of the user that has made the respective comment. Below is what I have done so far:
<% if (Session["user"] != null && Session["user"] == Eval("first_name"))
{
%>
Edit
<%
}
else
{
}
%>
However, it gives an error:
'Databinding methods such as Eval(), XPath(), and Bind() can only be
used in the context of a databound control.'
Here's the full code:
<asp:Repeater ID="r2" runat="server" OnItemCommand="r2_ItemCommand">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<% if (Session["user"] != null)
{
%>
<br />
<asp:Hyperlink runat="server" ID="myLink" Text="Edit" Visible="false"></asp:Hyperlink>
<%
}
else
{
}
%>
<br /> <%#Eval("title") %><br />
By <%#Eval("first_name") %> <%#Eval("last_name") %> on <%#Eval("date") %><br />
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater><br />
Any ideas on how to fix this or any better solutions that can be done?
Eval only works when you're setting a bindable property on a server control.
To do something like this, you could either have a server control container, or make an asp Hyperlink control.
HTML
<asp:Hyperlink runat="server" ID="myLink" Text="edit" Visible="false"></asp:Hyperlink>
C#
if (Session["user"] != null && Session["user"] == myObject.first_name))
myLink.Visible = true;

Trying to apply bootstrap styles in ASP.net webform

I have a text box which has an asp:RegularExpressionValidator attached to it as so
<div class="form-group col-sm-6 <%= (revAlertValue.IsValid == false ? "has-error" : "") %>">
<label for="AlertValue" class="control-label col-sm-4">Alert Value</label>
<div class="col-sm-4 input-group">
<span class="input-group-btn">
<asp:Button ID="btnMediumValue" CssClass="btn btn-warning" runat="server" Text="Low" OnClientClick="btnMediumValue_Click" OnClick="btnMediumValue_Click" />
</span>
<asp:TextBox CssClass="form-control text-center" CausesValidation="true" ID="tbAlertValue" runat="server" MaxLength="4" />
<asp:RegularExpressionValidator ID="revAlertValue" runat="server"
ControlToValidate="tbAlertValue" ErrorMessage=""
ValidationExpression="^[1-9]\d*$" />
<asp:RequiredFieldValidator ID="rfvAlertValue" runat="server" ControlToValidate="tbAlertValue" />
<span class="input-group-btn">
<asp:Button ID="btnHighValue" CssClass="btn btn-danger" runat="server" Text="High" OnClientClick="btnHighValue_Click" OnClick="btnHighValue_Click" />
</span>
</div>
I'm basically trying to apply the has-error class to my form-group if the regular expression validator is not valid. However, when I go to test and input text that would fail the regex validator the class is not applied.
I've tried writing the expression in other ways:
<%= (revResendEvery.IsValid == false) ? "has-error" : "" %>
<%= (revAlertValue.IsValid == false ? "has-error" : "") %>
I've thought maybe it has to be triggered when the submit button is pressed, or more code has to be added to the .aspx.cs handling the class addition after submit is pressed but that doesn't do the trick either.
In order to do this client side you need to tap into the client side code rendered by ASP.NET. Here is an example of some script you might include on your page to do so.
(function () {
var originalRegularExpressionValidator = RegularExpressionValidatorEvaluateIsValid;
RegularExpressionValidatorEvaluateIsValid = function (val) {
var originalValidationResult = originalRegularExpressionValidator(val);
if (!originalValidationResult) {
var formGroup = $("#" + val.controltovalidate).closest(".form-group");
formGroup.addClass("has-error");
}
return originalValidationResult;
}
})();
This, of course, assumes you have jQuery on the page (for the closest and addClass methods), but you can replace that with whatever you want.
Additionally, you may want to look into overriding the Page_ClientValidate function ASP.NET renders. There are many questions on StackOverflow that address how to do that.

Highlight (bold font) row in asp:Repeater with timer

I have a list of activities that is displayed with a Repeater. I already use Timers to display these, so the Timer isn't the problem. It's the code that i have to put into the Timer_tick method.
The "highlight-Timer" is supposed to highlight the items/rows one at a time, and then I want to display some info related to the highlighted row.
If it's easier with another control that's no problem. I doesn't have to be a Repeater. I just use it because of the styling-possibilities (it isn't displayed in just one line, but with several line-breaks etc.)
As requested:
(Repeater)
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div id="divActivity" runat="server">
<span style="font-size:30px;">
<%# DataBinder.Eval(Container.DataItem, "act_headline") %>
</span>
<br />
<img alt="mapIcon" src="../img/mapIcon.gif" height="15px" width="15px" style="position:absolute;" />
<span style="font-size:12px; font-style:italic; margin-left:23px;">
<%# DataBinder.Eval(Container.DataItem, "act_place") %>
</span>
<img alt="watchIcon" src="../img/watchIcon.png" height="15px" width="15px" style="position:absolute;" />
<span style="font-size:12px; font-style:italic; margin-left:23px;">
<%# DataBinder.Eval(Container.DataItem, "act_start") %> - <%# DataBinder.Eval(Container.DataItem, "act_end") %>
</span>
<br />
<div style="word-wrap: break-word; width:1000px; margin-top:20px; padding:0;">
<%# DataBinder.Eval(Container.DataItem, "act_text") %>
</div>
<br />
<img alt="infoIcon" src="../img/infoIcon.png" height="15px" width="15px" style="position:absolute;" />
<span style="font-size:12px; margin-left:23px;"><a target="_blank" href="http://<%# DataBinder.Eval(Container.DataItem, "act_info") %>"><%# DataBinder.Eval(Container.DataItem, "act_info") %></a>
</span>
</div>
</ItemTemplate>
</asp:Repeater>
I don't have anything in the the Timer_tick-event, as i've tried several things and the deleted it after it failed. Hope it's enough.
I would set a special CSS class to the highlighted item by using something like this in the tick event handler by looping over the Repeater.Items collection.
Something like this (untested):
int currentHighlight = -1;
int nextHighlight = -1;
for (int i = 0; i < Repeater1.Items.Count; i++)
{
HtmlControl htmlDiv = (HtmlControl)Repeater1.Controls[i].Controls[1];
if (htmlDiv.Attributes["class"] != null)
{
if (htmlDiv.Attributes["class"].Contains("highlighted")) // this is the currently highlighted item
{
// record currently highlighted item index
currentHighlight = i;
// remove highlight
htmlDiv.Attributes["class"].Replace("highlighted", "");
htmlDiv.Attributes["class"].Trim();
}
}
}
if ((currentHighlight == -1) || (currentHighlight == Repeater1.Items.Count))
{
// handle first Item highlighting
nextHighlight = 1;
}
else
{
// handle standard case
nextHighlight = currentHighlight + 1;
}
// highlight next item
((HtmlControl)Repeater1.Controls[nextHighlight].Controls[1]).Attributes["class"] += " highlighted";
Then you can use the highlighted CSS class to handle styling (the bold font you mention) as well as some special behavior in JavaScript or jQuery for example.
BTW, you can do any other operation on the RepeaterItem object once you get which one is currently highlighted.

Prevent full postback for UserControl with ValidationProperty attribute

I have an ASP.NET usercontrol that implements the ValidationProperty attribute. This attribute successfully makes it possible for me to use a RequiredFieldValidator for my custom control, however on validation it causes a full postback rather than using client side javascript based validation.
Is there a way to prevent this and enable client side validation without using a custom validator?
This is the what my UserControl looks like.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ucBooleanRadio.ascx.cs" Inherits="MyCompany.Web.UserControls.ucBooleanRadio" %>
<div class="BooleanRadio">
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>
[ValidationProperty("Checked")]
public partial class ucBooleanRadio : System.Web.UI.UserControl
{
public Nullable<bool> Checked
{
get
{
if (radTrue.Checked || radFalse.Checked)
return radTrue.Checked;
else
return null;
}
set
{
radTrue.Checked = value != null ? value.Value : false;
radFalse.Checked = value != null ? !value.Value : false;
}
}
}
And this is how it is being used
<uc1:ucBooleanRadio ID="ucAgree" runat="server" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" runat="server" CssClass="Validator" Display="Dynamic" ControlToValidate="ucAgree" InitialValue="" ErrorMessage="You must agree to continue."></asp:RequiredFieldValidator>
Page.Validate();
if (Page.IsValid)
{
//Do stuff
}
Turns out, ASP.NET don't event care about element tag.
I've just looked through validation code and found this
function ValidatorGetValue(id) {
var control;
control = document.getElementById(id);
if (typeof(control.value) == "string") {
return control.value;
}
return ValidatorGetValueRecursive(control);
}
So
<div class="BooleanRadio" id="<%= ClientID %>" value="<%= radTrue.Checked? "true" : radFalse.Checked? "false" : "" %>">
<% radTrue.Attributes["onclick"] = "document.getElementById('" + ClientID + "').value='true'"; %>
<% radFalse.Attributes["onclick"] = "document.getElementById('" + ClientID + "').value='false'"; %>
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>
actually works :\, as does
<div class="BooleanRadio" id="<%= ClientID %>">
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>
And there is events autohooking - validated element (one with ClientID) and its children are wired to cause validation automatically (look ValidatorHookupControl).
That may result in:
1. user does something
2. validation is performed
3. value to validate is updated (after validation!)
First example with value on div behaves this way.
For a simple client-side validation there should be an input element with corresponding name which value is to be validated. Example of how it could be done in your case:
<div class="BooleanRadio">
<% radTrue.Attributes["onclick"] = "document.getElementsByName('" + UniqueID + "')[0].value='+'"; %>
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<% radFalse.Attributes["onclick"] = "document.getElementsByName('" + UniqueID + "')[0].value='-'"; %>
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
<input name="<%= UniqueID %>" type="hidden" value="<%= radTrue.Checked? "+" : radFalse.Checked? "-" : "" %>" />
</div>
OK, So after significant digging around in the architecture of the ASP.NET field validators and some guidance from the poster above I have finally found the solution.
Basically the answer above is correct barring a couple of changes.
Firstly the id that is set for the hidden text should not be in the Name field but rather the ID field. Further the ID that is populated inside of the Hidden field should not be the Page.UniqueID but rather the Page.ClientID for the UserControl in question.
The reason for this is that when a page that contains validators is loaded the following function is called by the ASP.NET framework.
function ValidatorHookupControlID(controlID, val) {
if (typeof (controlID) != "string") {
return;
}
var ctrl = document.getElementById(controlID); //NOTE THIS LINE
if ((typeof (ctrl) != "undefined") && (ctrl != null)) {
ValidatorHookupControl(ctrl, val);
}
else {
val.isvalid = true;
val.enabled = false;
}
}
What the framework attempts to do is retrieve a control that has the same ID as the ControlToValidate property as set in the required field validator (which is actually Page.ClientID). It then uses this control in its validation functions (whether they be RequiredField, Compare, Regex and so on). If it finds such a control it enables the validator and performs validation against its value, if it doesn't it simply sets the validator to disabled.
In the end my code looks like this.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ucBooleanRadio.ascx.cs" Inherits="MyCompany.Web.UserControls.ucBooleanRadio" %>
<input id="<% =this.ClientID %>" type="hidden" value="" />
<asp:RadioButton runat="server" ID="radTrue" Text="Yes" GroupName="radio" />
<asp:RadioButton runat="server" ID="radFalse" Text="No" GroupName="radio" />
<script language="javascript" type="text/javascript">
$(function (e) {
$("#<% =radTrue.ClientID %>").click(function (e) {
$("#<% =this.ClientID %>").val("true");
});
$("#<% =radFalse.ClientID %>").click(function (e) {
$("#<% =this.ClientID %>").val("false");
});
});
</script>
And the code behind remains unchanged. Hopefully this explains some of the mystery of whats going on to anyone who runs into the same problem.
Maxim, I've just been working on a similar problem.
I've found that you don't need the JavaScript the Validators will automatically iterate through the controls looking for a "value" that is set.
You must be using server side RadioButtons rather than HTML
If you're using CompositeControls then it will work automatically
If you're using Web User Controls (ascx files) it doesn't wrap the control with an ID so you need to add the following code to your control.
<div id='<%=ClientID %>'>
Your radio button controls here...
</div>
Edit: I've just uploaded some quick sample code. Hope this helps!
Sample Code

Using Directives

If I have a repeater going through a list of data to retieve the values I use
<%# Eval("current_item") %>
And with a bit of luck it outputs the information for "current_item"
However if I want to check if "current_item" equals 1 for instance, this will tell me whether to print the next lot of information. So how do I use that information to determine the output, effectivily I want to put that information into an variable.
<%# myInt = int.Parse(Eval("current_item")) %>
The above code is what I want to do really.
Then I will do something like this:
<% if (myInt == 1) { %>
<p>Information to display if myInt = 1</p>
<% } else { %>
<p>Other Information</p>
<% } %>
Any Ideas?
I have used something similar to the following in a GridView:
<p>
<asp:Label Visible='<%# ((int)Eval("current_item") == 1) %>' Text="This is the first item" runat="server" />
<asp:Label Visible='<%# ((int)Eval("current_item") != 1) %>' Text="This is not the first item" runat="server" />
</p>
Give that a shot and see if it works for a Repeater too.

Categories