Hi and thanks in advance...
I have a button that I want change the css on pageload in c# and asp.net. Right now, on pageload, I am only able to change the text. When the text contains "ADD" I need it to be green, else blue.
Inside of a gridview I have this:
ASP.NET
<asp:TemplateField HeaderText="Tower">
<ItemTemplate>
<asp:Button ID="Button_Detail" CssClass="page-btn blue" CausesValidation="false"
CommandArgument='<%#Eval("idRangeList") %> ' CommandName="Detail" runat="server"
Text='<%# getButtonText(Eval("idRangeList")) %>' OnClick="btnDetails_Click">
</asp:Button>
</ItemTemplate>
</asp:TemplateField>
c#
protected string getButtonText(object o)
{
String btnText;
int rID = Convert.ToInt32(o);
WISSModel.WISSEntities context = new WISSModel.WISSEntities();
var text = (from t in context.Towers
where t.isDeleted == false && t.fkRangeList == rID
select t);
if (text.Count() == 0)
{
btnText = "3. ADD";
}
else
btnText = "Details";
return btnText;
}
I am up for either a jquery or c# solution.
I have tried both and I am stuck. On the C# side, I am not able to access the ButtonID.
For JS I tried this, but its not doing anything:
function textCheck() {
//var buttonDetails = $("Button_Detail");
if($("Button_Detail:contains('ADD')")){
$("Button_Detail").css("green v2");
}
}
you need to try:
if($(".page-btn").val()=='ADD'){
$(this).removeClass().addClass('.page-btn green');
}
This line will not work:
$("Button_Detail").css("green v2");
It needs to be:
$("Button_Detail").addClass("green v2");
However this will still not work as your selector isn't correct. It either needs to have a # for IDs or a . for classes. Given that .NET's IDs are changable it's far easier to give your control a unique class and use that.
In your case:
$(".page-btn").addClass("green v2");
The jQuery css function is for adding specific CSS properties to an element.
http://api.jquery.com/css/
If you want to manipulate which classes an element has you should look at the class attribute documentation:
http://api.jquery.com/category/manipulation/class-attribute/
Related
I have two select lists in my ASP.NET site that are filled by the server with some elements.
// .aspx
<asp:dropdownlist id="abc" runat="server"></asp:dropdownlist>
<asp:dropdownlist id="def" runat="server"></asp:dropdownlist>
// .aspx.cs
abc.Items.Add(new ListItem("element1", "value1"));
def.Items.Add(new ListItem("element1", "value1"));
Due to too complicated reasons to explain right now, I also need to modify the options of the select lists with JavaScript, adding some values.
// In the <head> of the .aspx page
var abcList = document.getElementById("abc");
var defList = document.getElementById("def");
var newAbcElement = new Option("element2", "value2", false, false);
var newDefElement = new Option("element2", "value2", false, false);
abcList.options[abcList.length] = newAbcElement;
defList.options[defList.length] = newDefElement;
Of course, this will mess up Even Validation as soon as I send the form back to the server (be it by submitting or as a PostBack from some other form elements with AutoPostBack="true").
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Now, I don't have the resources and budget to completely overhaul the whole page design, so: What is the fastest and easiest way to change the dropdownlist that does not mean I have to rewrite the whole thing?
So that the values added via JavaScript are recognized by my CodeBehind file when submitting the form?
Ok, here is one more option for you. You can add those items to your lists using AsyncPostBackTrigger.
Some hidden fields:
<asp:TextBox ID="newItemsForAbc" runat="server" style="display:none;"></asp:TextBox>
<asp:TextBox ID="newItemsForDef" runat="server" style="display:none;"></asp:TextBox>
<asp:Button ID="addNewItems" runat="server" OnClick="addNewItems_Click"
style="display:none;" />
The Update Panel:
<asp:UpdatePanel runat="server" ID="UpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:dropdownlist id="abc" runat="server"></asp:dropdownlist>
<asp:dropdownlist id="def" runat="server"></asp:dropdownlist>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="addNewItems" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
JS Function for doing an async post back:
<script type="text/javascript"> function UpdateStuff(value1, value2)
{
var abcItems = document.getElementById("<%= newItemsForAbc.ClientID %>");
var defItems = document.getElementById("<%= newItemsForDef.ClientID %>");
abcItems.value=value1;
defItems.value=value2;
__doPostBack("<%= addNewItems.ClientID %>","");
}
</script>
Server-side function that handles button click:
protected void addNewItems_Click(object sender, EventArgs e)
{
string[] n1 = newItemsForAbc.Text.Split(';');
string[] n2 = newItemsForDef.Text.Split(';');
foreach(string i in n1)
{
abc.Items.Add(new ListItem(i, i));
}
foreach(string i in n2)
{
def.Items.Add(new ListItem(i,i));
}
}
To Update Your Lists:
var newAbcElements = "Element1;Element2;Element3";
var newDefElements = "Element4;Element5";
UpdateStuff(newAbcElements, newDefElements);
Final note:
This piece of code probably will not do the job for you as it is. You may need to change the way you store new items in a string, thus splitting/parsing would change too. You may even need different strings for displaying a list item and its actual value. But I believe you get the basic idea.
You can disable the ViewState entirely for the DropDownList.
<asp:dropdownlist id="abc" runat="server" EnableViewState="false"></asp:dropdownlist>
To your question update:
This changes the question quite a lot. The new question is answered here: Invalid postback or callback argument. Event validation is enabled using '<pages enableEventValidation="true"/>'
You have a few options.
First, you might rewrite your code so that the server side generates all possible items for the DropDownList and then in your JavaScript remove the unneeded items instead of adding new ones.
Second option is to create a custom class derived from System.Web.UI.WebControls.DropDownList. The class should contain the one method shown below. The important piece is that your custom class will not have the System.Web.UI.SupportsEventValidationAttribute added to it - so DropDownList base methods will skip the event validation automatically. Now replace the usage from <asp:dropdownlist> to your method.
In case you can't modify the .aspx code (or you have a ton of dropdownlists to replace) you might use tag mapping in your configuration.
namespace Project.MyWebControls
{
public class MyDropDownList : System.Web.UI.WebControls.DropDownList
{
protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
if (base.LoadPostData(postDataKey, postCollection))
return true;
// this means that the value selected was not present in the .Items collection
string[] values = postCollection.GetValues(postDataKey);
if (values == null || values.Length == 0)
return false;
// add the value to the Items collection so that it can be processed later on.
this.Items.Add(new ListItem("Custom value created by JavaScript", values[0]));
this.SetPostDataSelection(this.Items.Count - 1);
}
}
}
Note that depending on your code you might want to remove these custom values from the Items collection before rendering.
Sample for the .aspx file:
<%# Register TagPrefix="my" Namespace="Project.MyWebControls" Assembly="Project" %>
<my:MyDropDownList runat="server" ...></my:MyDropDownList>
I use ObjectDataSource as below.
<asp:ObjectDataSource ID="Item" runat="server"
SelectMethod="Grid_DataBind" TypeName="XXX.XXX.XXX"
DataObjectTypeName="Controller.Items" UpdateMethod="UpdateRow_Grid"
InsertMethod="InsertRow_Grid">
When InsertMethod fire, everything work fine but ...
public IList<Items> InsertRow_Grid(Items item)
{
item.ID = System.Guid.NewGuid().ToString();
bool contains = GridSource.AsEnumerable()
.Any(row => item.JobID == row.JobID);
if (!contains)
{
GridSource.Add(item);
}
else
{
lblMsg.Text= "This record has already exists.";
}
return GridSource;
}
It doesn't know my label object which is presented in my aspx file.
I had read this so that I can search proper solution.
But I still don't get how to do.
Every suggestion will be appreciated.
This is because asp:ObjectDataSource creates new instance of object you specified in "TypeName" property
To use current page object instead of creating new, you need this code:
YourObjectDataSource.ObjectCreating += (s, a) => { a.ObjectInstance = this; };
Place it in Page_Load or Page_Init
You can add this code to your page
...
<asp:Label id="lblMsg" runat="server"/>
<asp:ObjectDataSource ID="Item" runat="server"
SelectMethod="Grid_DataBind" TypeName="XXX.XXX.XXX"
DataObjectTypeName="Controller.Items" UpdateMethod="UpdateRow_Grid"
InsertMethod="InsertRow_Grid">
.....
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript or Jquery to check and uncheck all checkbox
I have 12 asp:checkboxes on a page and I would like to add one which selects/deselects all of them.
What's the best way to do that?
I've seen people use jquery but I'm not very familiar with JS.
IS there a generic jquery finction to use?
<head>...
<script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
...</head>
<body>...
<script type="text/javascript">
function Selectall() {
if ($('.JchkAll').is(':checked')) {
// .JchkGrid cssClass will be assigned to all other checkboxes in your control
$('.JchkGrid').attr('checked', 'true');
}
else {
$('.JchkGrid').removeAttr('checked', 'false');
}
}
</script>
<form>...
<asp:CheckBox runat="server" ID="cbSelectAll" Text="Select/Deselect All" CssClass="JchkAll" onchange="Selectall();"/>
<asp:CheckBox runat="server" ID="cbName" Text="Name" class="JchkGrid"/>
<asp:CheckBox runat="server" ID="cbModel" Text="Model" CssClass="JchkGrid"/>
...</form>
...</body>
Give your chckbox a css class and try this way
// .JchkAll is cssclass of your checkbox on which's click you need to check all Checkboxes
function Selectall() {
if ($('.JchkAll').is(':checked')) {
// .JchkGrid cssClass will be assigned to all other checkboxes in your control
$('.JchkGrid').attr('checked', 'true');
}
else {
$('.JchkGrid').removeAttr('checked', 'false');
}
}
Edit:
Also Don't forget to add this on checkbox's onchange attribute..
<asp:CheckBox runat="server" onchange="Selectall();" ID="cbSelectAll"
Text="Select/Deselect All" CssClass="JchkAll"/>
But this will give you a compiler warning...it would be better if you add it from code behind on Page_Load event like
cbSelectAll.Attributes.Add("onchange","Selectall");
First you find all the checkboxes, and then you change them. This you done on client via javascript. For example this is a function that if you call it is check all the chekboxes on a page.
function SwapCheck()
{
// find them
var allChecks = jQuery('input[type=checkbox]');
allChecks.each( function() {
jQuery(this).prop("checked", !this.checked);
// use this for jQuery ver 1.6 and before
// jQuery(this).attr("checked", !this.checked);
});
}
If you like to eliminate some checkboxs then warp them with a span, or div and use the
jQuery('#DivIDWithChecksToSelect input[type=checkbox]');
If you like to check them all you can use this code
jQuery(this).attr("checked", "checked");
Also you can use the jQuery(this).prop("checked", false); to uncheck them.
relative:
Setting "checked" for a checkbox with jQuery?
Check all CheckBoxes in GridView
About the .attr() and the .prop() read here : http://api.jquery.com/prop/
Give your checkboxes one CssClass name (chk_group in my example), and the give your check box that will change all of them another CssClass name (chk_select_all in my example)
then you can try this jQuery code
$(document).ready(function(){
$(".chk_select_all input[type=checkbox]").click(function(){
$(".chk_group input[type=checkbox]").attr('checked', this.checked);
});
});
Check here a working version: http://jsfiddle.net/a2XeK/
In ASP.NET WebForms, you'll have to use the selector .chk_select_all input[type=checkbox] because the rendering engine will create a with css style, and inside the span there will be the actual checkbox.
Multiple ways to do it. See which is best for you. Using JavaScript
function toggleCheckboxes(flag) {
var form = document.getElementById('groupImportForm');
var inputs = form.elements;
if(!inputs){
//console.log("no inputs found");
return;
}
if(!inputs.length){
//console.log("only one elements, forcing into an array");
inputs = new Array(inputs);
}
for (var i = 0; i < inputs.length; i++) {
//console.log("checking input");
if (inputs[i].type == "checkbox") {
inputs[i].checked = flag;
}
}
}
Hope this helps.
You can do it in the codebehind if you want. In the OnCheckedChanged event of the main checkbox, set all of the Checked variables of the checkboxes to true.
I'm currently working with a listview in which I want an htmltablecell to possess the onclick property which is driven by the codebehind rather than a javascript.. However I'm guessing that's pretty much a dream getting it to obey the C# code... Anyways this is what I want it to run:
protected void show_anm(object sender, EventArgs e)
{
Label hiddenc = (Label)listview1.FindControl("hidden");
Alert.Show(hiddenc.Text);
}
and here's the Alert class
public static class Alert
{
public static void Show(string message)
{
string cleanMessage = message.Replace("'", "\\'");
string script = "<script type=\"text/javascript\">alert('" + cleanMessage + "');</script>";
Page page = HttpContext.Current.CurrentHandler as Page;
if (page != null && !page.ClientScript.IsClientScriptBlockRegistered("alert"))
{
page.ClientScript.RegisterClientScriptBlock(typeof(Alert), "alert", script);
}
}
}
The point is creating a listview with a two conditional tablecells, one which appears only when a certain condition is met and the other appears every other time (that's alredy sorted out). Where the one demanding a condition is Clickable, and upon clicking it it'll display an Alertbox with Data from a specific DB cell...
Sorry if my language and the question seemes off, English isn't my native language and I haven't doused myself in Coffe yet.
Any help on the matter would be most appritiated
EDIT1*
<asp:Listview ................
<ItemTemplate>
<tr ......>
<td id=default .....>
<asp:label ........ Text='<%# eval("stuff") %> />
</td>
<td id=conditional onclick=alert()..........>
<asp:label ......... Text='<%# eval("stuff") %> />
</td>
<td id=hidden visible=false ...........>
<asp:label ......... Text='<%#eval("stuff i want in alert") %>' />
.....
<script tyupe="text/javascript">
function alert()
{
var msg = document.getElementById("tried with label id and tablecell id nothing seemingly worked").value;
alert(msg);
}
</script>
I recently made a workaround that shows the data I want to display in the labels tooltip but I'd still prefer the alertbox to work properly as it feels more natural to click something.
Edit2 In case anyone is wondering I used the ItemDataBound event to bind the visibility of cells default and conditional within an if clause to make sure the control exists and the conditions are met.
I am confused as to why you're doing what you're doing. Why do you want the codebehind to handle an onclick event of a htmltablecell when you are pumping out javascript to show an alert anyway?
Why not just handle the whole logic within Javascript?
A postback from a htmltablcell will also require javascript
Set your tablecell to call a javascript function which would obtain the alert text from the hidden value and display that;
function ShowAlert()
{
var message = document.getElementbyId("hidden").value;
alert.show(message);
}
I have an ASP.NET page that uses a repeater nested within another repeater to generate a listing of data. It's to the effect of the following:
<asp:Repeater>
<ItemTemplate>
<span><%#Eval("Data1") %></span>
<!-- and many more -->
<asp:Repeater DataSource='<%#Eval("Data2")%>'>
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%#Container.DataItem%></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
In the (C#) code-behind I'm basically using LINQ to pull a listing of information from an XML document and bind that information to the first repeater.
Searching for the answer to this, it seems the method is to determine whether the data for the nested repeater is empty. If it is, then you set the visibility of the repeater to false.
Unfortunately, I haven't been able to determine how to do that inline, and not in the code-behind (since it won't necessarily work for what I'm doing).
Since my pages aren't validating now, because the ul ends up being empty for any items without Data2, and because I'd like to keep using an unordered list, I seek your help.
Any ideas?
Thanks!
UPDATE:
If it helps, since it could very well be possible to do in the code-behind, the LINQ is something to this effect:
var x = from y in z
select new {
Data1 = d,
// etcetera
Data2 = (from j in k
where j.Value != String.Empty
select j.Value).ToList()
};
blah.DataSource = x;
blah.DataBind();
This won't hide the repeater completely, but you can subclass the Repeater control so that it includes a GridView-like empty data template:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class EmptyCapableRepeater : Repeater
{
public ITemplate EmptyDataTemplate { get; set; }
protected override void OnDataBinding ( EventArgs e )
{
base.OnDataBinding( e );
if ( this.Items.Count == 0 )
{
EmptyDataTemplate.InstantiateIn( this );
}
}
}
You can them use it in your .aspx like this:
<custom:EmptyCapableRepeater runat="server" ID="rptSearchResults">
<ItemTemplate>
<%# Eval( "Result" )%>
</ItemTemplate>
<SeparatorTemplate>
<br />
</SeparatorTemplate>
<EmptyDataTemplate>
<em>No results were found.</em>
</EmptyDataTemplate>
</custom:EmptyCapableRepeater>
Try something like:
<asp:Repeater runat="server" DataSource='<%#Eval("Data2")%>'
Visible='<%# ((IEnumerable)Eval("Data2")).GetEnumerator().MoveNext() %>'>
for the nested repeater
Why not use a ListView? It offers much of the same functionality including an EmptyDataTemplate.
use this:
protected void Repeater1_PreRender(object sender, EventArgs e)
{
if (Repeater1.Items.Count < 1)
{
container.Visible = false;
}
}
When you get your LINQ query executed, check its Count property (providing its a list of some sort). If its 0, then just turn the Visible property to false.
As far as I know you must do this via the codebehind, just use the ItemDataBound event to handle it, you can leave pretty much everything as is, just simply input some logic that gets the dataset and determines if it has entries, if not hide the repeater.
I don't think what you are doing is going to work I get an error when I try and set the DataSource as you are trying to do; however, in the code behind you do this:
Assuming you added a listener to your parent repeater's ItemDataBoundEvent, then you will need to change your linq query slightly to not use an anonymous type (Create a protected class that has your properties) In mjy case I am using dto as the class name.
void rep1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rep2 = (Repeater)e.Item.FindControl("rep2");
rep2.DataSource = ((dto)e.Item.DataItem).y;
rep2.DataBind();
}
I'd love to learn why you think you can't solve this in the code behind.
I know this is an old thread and the answer above is a very nice solution, but I had a similar problem and have found another vary simple solution I thought I would share also. This validates just fine and displays the same.
Just change your footer template to:
<FooterTemplate>
<li style="display:none;">This will not show.</li></ul>
</FooterTemplate>
Or if your using tables:
<FooterTemplate>
<tr> style="display:none;"><td>But something must be in here.</td></tr></table>
</FooterTemplate>
Hope that helps someone!
In the OnItemDataBound event, set visibility to false if ItemType is a Header and set visibility to true if ItemType is an Item.