If I had a div tag inside a repeater, and i want to add a jquery effect to every one of those div tags, how would that be done?
<script type="text/javascript">
$(function() {
//run the currently selected effect
function runEffect() {
//most effect types need no options passed by default
var options = {};
//check if it's scale, transfer, or size - they need options
//if (selectedEffect == 'scale') { options = { percent: 0 }; }
//run the effect
$("#effect").effect('explode', options, 500, callback);
};
//callback function to bring a hidden box back
function callback() {
setTimeout(function() {
$("#effect:hidden").removeAttr('style').hide().fadeIn();
}, 1000);
};
//set effect from select menu value
$(document).ready(function() {
$("div.effect").click(function() {
runEffect();
return false;
});
});
});
</script>
<asp:Repeater ID="repItems" runat="server">
<ItemTemplate>
<div class="toggler">
<div id="effect" class="ui-widget-content ui-corner-all">
<h3 class="ui-widget-header ui-corner-all"><%#Eval("Tag") %></h3>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
I tried the above, but only the first div works. What am i doing wrong??
try using a class for those divs like:
<div id="effect" class="effect ui-widget-content ui-corner-all">
and in jquery use ("div.effect") selector.
i "think" that using the same id for multiple things might cause the issue...
The id values on HTML elements are required to be unique across the entire document. You're using the same id value for each item that that repeater displays, in violation of that rule. Now, the web being what it is, your browser doesn't complain about that, but try running your rendered HTML through a validator. jQuery only acts on the first such element, because it expects there to be only one.
If you switch from id to class, you should have much better results.
another idea to consider is to put a div tag with an id AROUND the repeater. the repeater itself looks pretty straightforward and looking at your jquery, it doesn't appear that it matters which of the div tags in the repeater is clicked.
$(document).ready(function() {
$("#base").click(function() {
runEffect();
return false;
});
});
<div id="base">
<asp:Repeater ID="repItems" runat="server">
<ItemTemplate>
<div class="toggler">
<div id="effect" class="ui-widget-content ui-corner-all">
<h3 class="ui-widget-header ui-corner-all"><%#Eval("Tag") %></h3>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
I think what you need to change is in the 'ready' function where you attach the click event - you are using $('div.effect') as the selector, which does not look valid to me. I suggest using $('.ui-widget-content'). This selects based on the class, rather than the id (which should be unique as noted by others).
If you're not wanting to use a class on those divs nested in your repeater, you can use partial ID matching. Even though the repeater will add information to beginning of your ID for each div (to ensure it's unique), the ID will still end in "effect", or whatever name you've used.
You can use this to your advantage. In your jQuery code, where you're operating on the "effect" ID, change your code from this:
$("#effect")
to this:
$("[id$='effect']")
This will select all elements whose ID END in "effect", so when repeater renames the ID of each div to "repItems_ ctl001_ effect" or what have you, jQuery will still find it.
Also do note, toward the end of your jQuery code listed in your question, you're attempting to access a div based on the class "effect", instead of the ID. Just an FYI.
Related
I have a dynamically named DIV in a GridView which contains a user control with a dynamically assigned Parent_ID. The javascript is used to show or hide the DIV. I'll show you two examples of different rows without the ASP code.
Row 1 showing for Order # 123456:
<a href="<%#"javascript:collapseExpand('Order_Notes_Panel123456');" %>" >+</a>
<div id='Order_Notes_Panel123456' style="display:none;">
<uc:Comments_Control id="Comments_Control_ID" runat="server" Parent_ID='123456'/>
</div>
Row 2 showing for Order # 678901:
<a href="<%#"javascript:collapseExpand('Order_Notes_Panel678901');" %>" >+</a>
<div id='Order_Notes_Panel678901' style="display:none;">
<uc:Comments_Control id="Comments_Control_ID" runat="server" Parent_ID='678901'/>
</div>
The good news is that the user control binds and works perfectly. The javascript shows (sets the style to "display:block;") and hides (style set to "display:none;") the appropriate DIV each time the '+' is clicked.
Here is my problem: there is a 'Reply' link in the user control that, when clicked, does a post-back and puts the control into Edit mode. When I employ this user control on another page without a containing DIV, you won't notice a thing. However, when the 'Reply' does its post-back, the containing DIV reverts back to style="display:none;".
Can you provide a recommendation how to set the parent DIV's style to "display:block;" while a user is obviously working with it? I would imagine the appropriate code would go in the code behind of the user control when it goes into Edit mode.
Thanks,
Rob
Update: I recognize that there is no runat=server in my DIV. Since I'm trying to establish a dynamic ID for each, I get an error if I try to use the runat. That is probably the reason why I can't reach it from code behind...
I am very happy of myself... (see the YouTube video for this phrase, you'll be glad you did.)
In summary, this is what I added:
1. New Javascript function to add the name of the target DIV to a hidden field (The "collapseExpand" function is in the Site.Master. I couldn't put "load_div_to_hidden" in the Site.Master since "myhiddenField" isn't set up on every page
2. New hidden field to capture the name of the target DIV
3. New Javascript function to run on window.onload, check if we've got a post-back, and then display the value from the hidden field
4. Adding second Javascript call from the href in the link
Below are the new snippets of code:
<script type="text/javascript">
function load_div_to_hidden(obj) {
var hidden = document.getElementById('<%= myhiddenField.ClientID %>');
hidden.value = obj;
}
function windowOnLoad() {
var isPostBack = (('<%= IsPostBack %>').toLowerCase() == 'true') ? true : false;
if (isPostBack == true) {
var hid_field_value = document.getElementById('<%= myhiddenField.ClientID %>').value;
var right_div = document.getElementById(hid_field_value);
right_div.style.display = "block";
}
}
window.onload = windowOnLoad;
</script>
<input type="hidden" id="myhiddenField" runat="server" value="" />
<a href="<%#"javascript:collapseExpand('Order_Notes_Panel123456'); javascript:load_div_to_hidden('Order_Notes_Panel123456');" %>" >+</a>
<div id='Order_Notes_Panel123456' style="display:none;">
<uc:Comments_Control id="Comments_Control_ID" runat="server" Parent_ID='123456'/>
</div>
Works like a charm!
im a newbie in asp.net and i have a issue. i need to make my div section visible only on some pages. i placed attribute style:(not with " on start of course)
<div ID="id1" class="grid-box width33 grid-h" style="visibility:visible" >
<!-- Other code here //-->
</div>
and i need to make in code behind some kind of if statement that's going to check if my section picker picked that div section, and if it is picked it's going to be printed on page, else it's going to render something else.
on my page_load method i have a code such as:
if (this.CurrentContent.CentralSection.HasValue)
{
this.ucCentralSection.CentralSectionId = this.CurrentContent.CentralSection.Value;
}
else
{
this.ucCentralSection.Visible=false;
}
but it's not working properly...
Add a runat attribute to your div. Use FindControl method in your code-behind to locate the div in question and toggle the visible property there.
Use like this
<div ID="id1" class="grid-box width33 grid-h" style="visibility:visible"
runat="server" >
<!-- Other code here //-->
</div>
And in your cs page
var div = (HtmlGenericControl)Page.FindControl("id1");
div.Visibility=true;
Other wise you can use Panel server control.
I thought my question was answered over here at
How to use JQuery with Master Pages?
but after trying the things suggested there, my code is still not working. I'm trying to get a checkbox control to toggle a hidden div below. Here's the code in my external .js file;
$(document).ready(function() {
alert("hello world");
});//works
$('[id$=parking]').click(function() {
$('#parktype').slideToggle('slow');//doesn't work
});
and here is the code in my .aspx file
<td class="vanilla">
<div id="park"></div><asp:CheckBox ID="parking" runat="server" /></div>
</td>
</tr>
</table>
</div>
<div id="parktype" style="display:none;width:540px;padding:20px;margin:auto;">
<table width="75%" border="0" cellpadding="5" cellspacing="0">
<tr>
Last but not least I have linked my masterpage to the jQuery library;
<script src="../jquery-1.4.4.min.js" type="text/javascript"></script>
As far as I can tell, the slideToggle function is not being triggered, and I suspect this is because of the difficulty in grabbing the name of a control in asp.net.
I've tried changing this:
$('[id$=parking]').click(function() {
to many variations, including
$('[id$=_parking]').click(function() {
$('[id$="_parking"]').click(function() {
$('[id$=ctl00_body_parking]').click(function() {
with the last variation being the ID given in the processed file;
<td class="vanilla">
<div id="park"></div><input id="ctl00_body_parking" type="checkbox" name="ctl00$body$parking" /></div>
</td>
Not quite sure what I'm missing but thankful for any helpful hints, or whacks over the head indicating I'm just missing something really obvious...
Again, the goal is to have the div #parktype slideToggle when the asp.net control parking is clicked.
Merci!
Because your .js is external the document ready will not fire.
I'm a little rusty on my asp.net controls but i think you can set your OnClientClick Event to
<asp:CheckBox ID="parking" runat="server" OnClientClick="$('#parktype').slideToggle('slow');" />
or
you can set the OnClientClick to a function which passes in the checkbox itself
<asp:CheckBox ID="parking" runat="server" OnClientClick="toggleParkType(this);" />
Here's a sample of the function
function toggleParkType(chkbox){
$(chkbox).slideToggle();
// test if checked
if($(chkbx).is(":checked")){
// perform action for checked
}
}
try this:
$(document).ready(function() {
alert("hello world");
$('[id$="parking"]').click(function() {
$('#parktype').slideToggle('slow');
});
});
Additionally you should review the comment I left on your question about the div tags
Try to use change function.
$(document).ready(function() {
$('[id$=parking]').change(function() {
$('#parktype').slideToggle('slow');
});
});
Consider this scenario:
<asp:CheckBoxList> in a master page.
the goal is to have all checkboxes in this list to be checked on page load.
there are many checkbox lists on the page.
The markup:
<asp:CheckBoxList runat="server" ID="chkSubscriptionType"
DataSourceID="myDS"
CssClass="boxes" DataTextField="Name" DataValueField="Name" />
renders to:
<input id="ctl00_cphContent_chkSubscriptionType_0" type="checkbox" name="ctl00$cphContent$chkSubscriptionType$0" />
Question: how can you use jQuery to check all boxes in this asp:CheckBoxList on document.ready? I see samples everywhere, but naming convention used by the master page throws off the samples in other places.
Because of the naming container, the ID's will be auto-generated and messed up, as you mention. You can use an attribute filter to select all elements that contain the part that you do know, that is, "chkSubscriptionType". For example:
$("input[id*=chkSubscriptionType]").attr("checked", "checked");
The *= means "contains".
ASP.NET's naming conventions are slightly frustrating. You can side-step them by wrapping your element in a span, and giving it a class. You can then use that span.class to focus your selector:
$(function(){
// On dom-ready, all checkboxes in span.names will be checked
$("span.names :checkbox").attr("checked", "checked");
});
<span class="names">
<asp:CheckBoxList ... />
</span>
Regardless of asp/php/ruby, etc, you should be able to do something like:
$(document).ready(function(){
$("input[type=checkbox]").attr("checked", "checked");
});
In ASP.NET Gridviews generate a table which generates a parent div container. This can break CSS layouts since there is no way to attach styles to the generated div. Is there a way to prevent the div from generating or a way to apply a style to it?
This was asked and marked as resolved here but MS just said that the div is needed for the Paging and Sorting functionality. Am I to understand that if I want to use the paging and sorting functionality I can't wrap my own div around it and apply a style? Thanks
If you're stuck with an unstyled wrapper (which it appears that you are) but want to enforce a style, give it another wrapper, and apply your style to the combination. If a plain div has some padding you want to get rid of (for example), this in the aspx:
<div id="crushGvDiv">
<asp:GridView ... >
</div>
and this for CSS:
div#crushGvDiv, div#crushGvDiv div { padding: 0; margin: 0; }
UPDATE
Ians response does remove much of the hackery from this but it also requires
more effort on my part. I think we can have the best of both worlds if we
do this just a little differently...
We no longer want to add a 'table-responsive' div to our source at all. We DO want to add a 'table-responsive-table' to our GridView classes.
ASP
<asp:GridView ID=gvMain DataSourceID=dsMain RunAt=Server
CssClass='table table-responsive-table'>
Our JavaScript just needs to add the 'table-responsive' class to the parent div of those 'table-responsive-table' class tables that we've added.
JS
$( document ).ready(function() {
$(".table-responsive-table").parent().addClass('table-responsive');
});
This will generate:
HTML
<div class=table-responsive>
<table class='table table-responsive-table' .....>
This new output should be relatively free of hackery related problems due to the fact that we have exactly the same output in the end as we would've otherwise had (except for the extra class on the table), we do not need to modify this code for every table (meaning we can write it once and it'll automatically be applied to all GridViews with the 'table-responsive-table' class), and we are not moving\copying the table data at all (this is important for speed, paging, and sorting). I know everyone says they have the best answer but I really do think this is the absolute best way of handling this.
NOTE: I have not tested this new code but it will probably work just fine.
An easy solution without render modifying:
I need to apply a style to the div generated by the gridview because it breaks my layout, so I created a div with id "myContainerDiv" and moved my GridView into it, and using jQuery I apply some styles.
Example:
$("#myContainerDiv > div").css("display", "inline");
I put this javascript in $(document).ready(function({}));.
But if you use UpdatePanel, like I must use in this particular case, I execute this $().css() in every async postback. Without that the style will be lost if you execute some updatepanel where your gridview is contained. But I execute this $().css() only if a particular UpdatePanel is fired (no need to execute this javascript instruction in every every every async postback)
Example:
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
if (args.get_error() == undefined && sender._updatePanelClientIDs != null &&
sender._updatePanelClientIDs.length > 0 && sender._updatePanelClientIDs[0] == "<%= MyParticularUpdatePanel.ClientID %>") {
$("#myContainerDiv > div").css("display", "inline");
}
}
</script>
Resolved!
The entire page will look like that:
<script type="text/javascrcipt" src="jquery.js"></script>
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
if (args.get_error() == undefined && sender._updatePanelClientIDs != null &&
sender._updatePanelClientIDs.length > 0 && sender._updatePanelClientIDs[0] == "<%= MyParticularUpdatePanel.ClientID %>") {
$("#myContainerDiv > div").css("display", "inline");
}
}
</script>
<asp:UpdatePanel runat="server" ID="MyParticularUpdatePanel" UpdateMode="Conditional" RenderMode="Inline">
<Triggers>
// Your triggers here...
</Triggers>
<ContentTemplate>
<div id="myContainerDiv" style="display:inline;">
<asp:GridView runat="server" ID="MyGridView" AutoGenerateColumns="false" Height="150px" EmptyDataText="No data.">
<Columns>
<asp:BoundField DataField="ID" HeaderText="My ID" />
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
I don't know if this code will compile exactly like I wrote because I wrote it using notepad.
Sorry for my poor english, I'm from Brazil.
Christophe Trevisani Chavey.
http://www.christophetrevisani.com
Same issue here, OMG it's so annoying. Glitch in rendering in IE6/7 when butting a div to the top of a gridview - the parent DIV causes a space between the two elements.
I've dug into the GridView code using reflector and found the problem:
Private Sub Render(ByVal writer As HtmlTextWriter, ByVal renderPanel As Boolean)
If (Not Me.Page Is Nothing) Then
Me.Page.VerifyRenderingInServerForm(Me)
End If
Me.PrepareControlHierarchy
If renderPanel Then
Dim clientID As String = Me.ClientID
If Me.DetermineRenderClientScript Then
If (clientID Is Nothing) Then
Throw New HttpException(SR.GetString("GridView_MustBeParented"))
End If
Dim builder As New StringBuilder("__gv", (clientID.Length + 9))
builder.Append(clientID)
builder.Append("__div")
writer.AddAttribute(HtmlTextWriterAttribute.Id, builder.ToString, True)
End If
writer.RenderBeginTag(HtmlTextWriterTag.Div)
End If
Me.RenderContents(writer)
If renderPanel Then
writer.RenderEndTag
End If
End Sub
This is called from render:
Protected Friend Overrides Sub Render(ByVal writer As HtmlTextWriter)
Me.Render(writer, Not MyBase.DesignMode)
End Sub
So, 'renderPanel' == not DesignMode. The DIV is used for paging and sorting when then gridview isn't in an UpdatePanel. On my site, all GridViews are in a UP plus they inherit from a custom gridview class, so my solution was to override the above function with the following:
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
Me.PrepareControlHierarchy()
Me.RenderContents(writer)
End Sub
The other solution could be to copy the render method from above and changed as required.
This smells of HACK - you've been warned, but might work for you, esp if you're not using paging/sorting.
Simplest and best solution using CSS class "gridViewWrapperFix".
ASPX:
<div class="gridViewWrapperFix">
<asp:GridView>
<%--the full gridview would go here--%>
</asp:GridView>
</div>
CSS:
/* styles the div that gets auto generated around and asp.net gridview */
.gridViewWrapperFix > div {
padding: 0;
margin: 0;
border: 3px solid red;
}
You can put it inside of an asp:Panel and set the Visible property on the panel to false if the table is empty.
I've never done this, but I my first guess would be you could grab the rendered html output just before it gets to the browser, remove the outer div and then htmltextwrite out your new rendered html in the prerender event or make a user or custom control to do this.
But then you risk breaking the functionality of the gridview but if you know you won't be using the features that use the div, then you might get away with it.
You could define an explicit CssClass for your Gridviews to make use of.
<asp:GridView ... CssClass="nameOfStyleClass" ... />
Then define a css class:
.nameOfStyleClass
{
< Style stuff >
}