Depending on the result of a checkbox, I want to hide/reveal a hidden table (hidden from page load), asking for more information.
The JQuery and ASP is below, can someone point me in the right direction and let me know what I'm doing wrong with this approach.
ASP
<h3>Table Heading</h3>
<asp:Table ID="tbl1" runat="server">
<asp:TableHeaderRow>
<asp:TableHeaderCell>
<h4>One</h4>
</asp:TableHeaderCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell>
<asp:CheckBox ID=""Yes" runat="server" Checked="false" Text="Yes" />
<asp:CheckBox ID="No" Text="No" runat="server" Checked="false" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<asp:Table ID="tbl2" runat="server" Visible="false">
<asp:TableHeaderRow>
<asp:TableHeaderCell>
<h4>Additional information</h4>
</asp:TableHeaderCell>
</asp:TableHeaderRow>
<asp:TableRow>
<asp:TableCell><asp:TextBox ID="AddInfo" runat="server" TextMode="MultiLine"></asp:TextBox></asp:TableCell>
</asp:TableRow>
</asp:Table>
JQuery
<script type="text/javascript">
function toggleTable()
{
$(function () {
$("#Yes").click(function () {
$("#tbl2").show();
})
$("#No").click(function () {
$("#tbl2").hide();
})
}
</script>
Update 1
As suggested I removed the wrapping function, this still didn't work.
<script type="text/javascript">
$(function ()
{
$("#Yes").click(function () {
$("#tbl2").show();
})
$("No").click(function () {
$("#tbl2").hide();
})
})
</script>
Raw HTML
<h3></h3>
<table id="MainContent_tbl1">
<tr>
<th>
<h4></h4>
</th>
</tr><tr>
<td><input id="MainContent_Yes" type="radio" name="ctl00$MainContent$Yes" value="Yes" />
<label for="MainContent_Yes">Yes</label><input id="MainContent_No" type="radio" name="ctl00$MainContent$No" value="No" />
<label for="MainContent_No">No</label></td>
</tr>
When you had used visible=false in server control, that had done this - It removed that control entirely from page when rendered.
More about Visible property - If this property is false, the server
control is not rendered. You should take this into account when
organizing the layout of your page. If a container control is not
rendered, any controls that it contains will not be rendered even if
you set the Visible property of an individual control to true. - http://msdn.microsoft.com/en-us/library/system.web.ui.control.visible(v=vs.100).aspx
So i would suggest, if you are doing show/hide from server side code, then set attribute (CSS) style= display none . If you directly use visible property and set it to false, it will remove control from page, there will be no way to show in page.
E.g. tbl1.Attributes.Add("style", "display:none");
In client-side hide it using style=display:none" instead of visible=false.
Also, ,use .ClientID to get exact render ID for jquery selector. Like
$("#<%=tbl1.ClientID%>").show();
Take away the toggleTable() wrapping function and it should work as you've suggested.
The $(function () { runs when the document is ready and should turn on the click listeners at that point.
I'd also point out that the logic is flawed. Checkboxes can all be turned on so you might want to use radio buttons instead so only one can be checked.
In your jquery get everthing by ClientID as it is asp it will rename it(as you can see it has added MainContent_ to your control ids) so do this :
$("<%=tbl2.ClientID %>").click{....
Or add ClientIDMode = "Static" to your controls e.g.:
<asp:Table ID="tbl1" runat="server" ClientIDMode = "Static">
Related
Hi I have a problem with my javascript within an ASP SharePoint web part page. The page is built the same as any other ASP page so the fact that its hosted within SharePoint shouldn't make any difference.
The problem is with my javascript within the page. I have Html Table made up of 8 cells. For each of these cells I am displaying a different div with different data within it onmouseover.
The problem comes with the ID for the Divs that I am trying to display. The Divs ID is changed at runtime but also changes daily so cant be inputted manually.
HTML:
<div id="Main" style="display: none;
<div id="hover1" runat="server" style="display: none">
Test
</div>
</div>
<table id="Table3" runat="server" >
<tr id="Tr8" runat="server" >
<td id="status1" runat="server" onmouseover="getDataXML('hover1')" onmouseout="hideDiv('hover1')">
Received
</td>
</tr>
</table>
The id 'hover1' at runtime is replaced with something like 'ctl00_m_g_6ddac285_ceb9_4b5a_9095_c4b216cf7dfd_ctl00_hover1'
Javascript:
function getDataXML(getID) {
document.getElementById('Main').style.display = "block";
document.getElementById(getID).style.display = "block";
};
The javascript works if I take the ID which is generated and hard code it but the ID changes daily meaning it becomes a problem. Any help I would greatly appreciate
Regards,
Set clientIdMode = static to the element
<div id="hover1" clientIdMode="static" runat="server" style="display: none">
you have to pass clientId like this:
onmouseover="getDataXML('<%=hover1.ClientID %>')"
or alternatively set ClientIDMode to Static, but in that case if you change div id in aspx, you have to explicitly change where you have used Id and it will be difficult to catch becuse there will be no compile time error.
I have two dropdown menus and a linkbutton:
<form name="OptionForm" method="post">
<p>
<label for="ddlLocJobPhOpt" class="ui-accessible">Location Job Phase</label>
<asp:DropDownList runat="server" ID="ddlLocJobPhOpt" data-mini="true"></asp:DropDownList>
</p>
<p>
<label for="ddlFrmnOpt" class="ui-accessible">Foreman</label>
<asp:DropDownList runat="server" ID="ddlFrmnOpt" data-mini="true"></asp:DropDownList>
</p>
<asp:LinkButton ID="lnkSelectOptions" data-icon="arrow-r" data-iconpos="right" runat="server" data-role="button" Class="custom-btn" data-inline="true" data-theme="c" data-transition="pop" UseSubmitBahavior="false" href="#" data-mini="true" OnClientClick="SelectOptions()">GO</asp:LinkButton>
</form>
When I click the linkbutton this function fires: SelectOptions()
I am trying to empty the second dropdown list when the button is clicked. But when I add:
var frmnDDL = $('#ddlFrmnOpt');
frmnDDL.html("");
or
var frmnDDL = $('#ddlFrmnOpt');
frmnDDL.empty();
and then renavigate to the OptionForm above the dropdown is still populated.
What am I doing wrong?
I can almost guarantee that frmnDDL.length is 0.
.Net renames controls to something like ctl00_MainContent_ddlFrmnOpt
You have two options
you can change your jquery selector to the actual generated name (inspect the rendered html)
you can change your selector to do a partial match with something like $("[id$=ddlFrmnOpt]") or $("select[id$=ddlFrmnOpt]")
After that there are many ways to empty the select
frmnDDL.empty();
frmnDDL.children().remove();
frmnDDL.find('option').remove();
//etc, etc
Secondly, I'm confused by what you mean when you say "and then renavigate to the OptionForm above the dropdown is still populated." If you are performing a postback, .net will reload the dropdown with it's data during it's page lifecycle. What you changed in the DOM was client side, and with the web being stateless, those changes aren't remembered between postbacks.
As #CaffGeek pointed out, your issue is the fact that ASP.NET uses the control's parent hierarchy to determine the rendered ID. You can continue using the Javascript and jQuery code you already have by using static IDs for your controls.
Try
<asp:DropDownList runat="server" ClientIDMode="Static" ID="ddlLocJobPhOpt" data-mini="true"></asp:DropDownList>
and
<asp:DropDownList runat="server" ClientIDMode="Static" ID="ddlFrmnOpt" data-mini="true"></asp:DropDownList>
As of .NET 4, adding
ClientIdMode="Static"
to any server side control tells ASP.NET to render the exact ID that you specified in your markup instead of rendering it based on its legacy rules.
See http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode(v=vs.110).aspx
Check this Fiddle
$('button').click(function(){
$('#mySelect option').each(function(){
$(this).remove();
});
});
I would like to know how to read the value from the TextBox and assign to another TextBox on button click. This TextBox is attached to the AJAX CalendarExtender. So far I have this. I need this on ShowDate() function in Javascript.
<asp:TextBox ID="txtStartDate" runat="server" ReadOnly="false" Height="28px" Width="283px"></asp:TextBox>
<asp:CalendarExtender ID="ClendarExtender" BehaviorID="CE1" TargetControlID="txtStartDate" runat="server">
</asp:CalendarExtender>
<br />
<asp:TextBox ID="txtShowMessage" runat="server" Height="76px"
style="margin-left: 336px" Width="306px"></asp:TextBox>
<br />
<br />
<asp:Button ID="btnCreateNote" runat="server" OnClientClick="showDate()" style="margin-left: 456px"
Text="Button" onclick="btnCreateNote_Click" />
<br />
then my js is
function showDate() {
var txtDate = document.getElementById('<%=txtStartDate.ClientID %>');
document.getElementById("txtShowMessage").value = txtDate;
}
Dont know what's wrong and no value is there in the textDate.
Try to change your Javascript showDate() method like
<script type="text/javascript" >
function showDate() {
var txtDate = document.getElementById('txtStartDate').value;
document.getElementById('txtShowMessage').value = txtDate;
}
</script>
I checked this function and it works fine, Hope it works for you.
This is because when you write runat="server" then ASP engine prepends some string from its side.
ASP.NET has a built in mechanism (INamingContainer) to ensure than you don't have multiple controls named the same. It does this by adding container prefixes.
So
<asp:TextBox ID="txtShowMessage" runat="server"></asp:TextBox>
will change to something like
<input type="text" id="ctl00_ctl00_txtShowMessage" runat="server" />
So just document.getElementById('txtShowMessage') won't work. You need to get the complete ID. So you can use document.queryselector('[id$=txtShowMessage]'). This means get the element whose ID is ending with txtShowMessage.
Otherwise you can do like this
document.getElementById('<%=txtShowMessage.ClientID %>');
Note
1. The second approach I mentioned is better (Using the ClientID).
2. If you want to know the complete ID, then go to the webpage and view it's source, locate that TextField and check the ID (It won't change everytime, thats fixed)
3. For more information Refer here
I have Googled this to death and found lots of 'answers', but none of them will work for me, so maybe you clever people could give me a 'definitive' answer?
I have a Javascript function:
function enableSaveLink() {
document.getElementById('<%= btnSaveLink.ClientID %>').removeAttribute('disabled');
}
This works fine, but obviously it is hard-coded to enable a particular control on my page. What I'd like is to be able to call this function from any control on the page, passing the name of the control I'd like to enable as a variable. So, in an ideal world, my Javascript function would look like this:
function enableControl(ctl) {
document.getElementById(ctl).removeAttribute('disabled');
}
And I'd call it like this:
<asp:button id="btnTestButton" runat="server" Text="Click Me" onclientclick="enableControl('txtTestTextbox') />
<asp:button id="txtTestTextbox" runat="server" enabled="false />
I know the way I've passed the control name would never work, but I've tried passing it in all different ways and none work, so this is just for the purposes of illustration. Can anyone tell me how to actually make this work?
You need to use the ClientID property of the control.
This will help:
<asp:button id="btnTest" runat="server" Text="Click Me"
onclientclick="enableControl('<%= lblTest.ClientID %>') />
Use the this reference (more info here):
<asp:button id="btnTest" runat="server" Text="Click Me" onclientclick="enableControl(this);" />
Then in your script:
function enableSaveLink(elem) {
elem.removeAttribute('disabled');
}
Here you are passing a reference to the object calling the function to the function, you can then just set the attribute on the element rather than finding it in the DOM.
EDIT - Just realised what your intended usage is. If you're looking to fire an event from a disabled element when clicked, then you can't do this from the element. It would need to be handled from some other enabled element. The above method works fine if you intend to disable the element when clicked - but not enable the element when clicked.
EDIT - Just to accompany my comment, if you have a uniform structure like this (i.e. where all inputs have a corresponding label - or even button) then:
<div>
<label onclick="activateSibling(this);">Input One:</label>
<input type="text" />
</div>
You could try this:
function activateSibling(label) {
label.nextSibling.removeAttribute("disabled");
}
I've made a jsFiddle demonstrating my concept in jQuery which seems to work fine.
EDIT - OK, last idea. What about custom attributes. You could add a target attribute to your clickable element which contains the Id you're going to enable, like so:
<label target="active_me" onclick="activate(this);">Click to activate</label>
<input type="text" id="active_me" disabled="disabled" />
And your script:
function activate(label) {
var inputId = this.getAttribute("target");
var input = document.getElementById(inputId);
input.removeAttribute("disabled");
}
Although, it's starting to feel like we're fighting against the technology a little and we're not too far removed from ctrlInput.ClientID. But I suppose this makes your markup a little cleaner and gives you a function that's bindable en masse.
Ok, I've cracked it. There are probably more ways than one to do this, but this is fairly elegant.
My Javascript function:
function enableControl(ctl) {
document.getElementById(ctl).removeAttribute('disabled');
}
My ASP.NET markup:
<asp:Button ID="btnTestButton" runat="server" Text="Click to enable" OnClientClick="enableControl('txtTestTextbox');" />
<asp:TextBox ID="txtTestTextBox" runat="server" enabled="false" ClientIDMode="Static" />
The key is the ClientIDMode property, which, when set to static, means that the control's client-side ID when it is rendered will match the ID you give it in markup. If it's within a naming container you may need to include that in the variable passed in the function call. See here for more info about ClientIDMode.
Anyway, this works for me! Thanks for your input, everyone.
ClientID is used for getting server side control on javascript.
var element=document.getElementById('<%=lblTest.ClientID%>');
I'm using an asp:Repeater server side control that contains a table as it's repeatable item. One of the td tags in the table contains a checkbox. In the header of the repeater I have a checkbox with id="selectAllCheck".
I have the following javascript code
var checkBox = document.getElementById('selectAllCheck');
function changeAll() {
if (checkBox.checked == 1) {
$('input:checkbox').attr('checked', "checked");
}
else {
$('input:checkbox').attr('checked', "");
}
}
checkBox.onchange = changeAll;
This works just fine in firefox, instantly all the checkboxes are either checked or unchecked when necessary. However, in chrome it takes about 10 seconds. I do have about 250 checkboxes on the page by the way, but even putting that number down to only 15, I can see that it is still not instant with chrome, but much faster.
If anyone has encountered this problem before, seen any articles related to this problem, or knows how to solve this problem I would be very thankful.
EDIT: Posted the page
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentMain" Runat="Server">
<form id="webForm" runat="server">
<asp:Label ID="sourceLabel" runat="server" AssociatedControlID="sourceList" Text="Source"></asp:Label>
<asp:DropDownList ID="sourceList" runat="server" />
<asp:Button ID="showButton" runat="server" Text="View" />
<asp:Repeater ID="Repeater_DIBS" runat="server">
<HeaderTemplate>
<table>
<tr><th><input type="checkbox" id="selectAllCheck" /> (un)check All</th> <th>SourceID</th><th>FieldID</th><th>Source Indicator</th><th>Date Data Updated</th> <th>Message</th></tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td style='width:1%;white-space:nowrap;'><input type='checkbox' class='checkBoxes' /></td>
<td style='width:1%;white-space:nowrap;'><%# Eval("SourceID") %></td>
<td style='width:1%;white-space:nowrap;'><%# Eval("FieldID") %></td>
<td class='indicator' style='width:1%;white-space:nowrap;'><%# Eval("SourceIndicator") %></td>
<td style='width:1%;white-space:nowrap;'><%# Eval("DateDataUpdated") %></td>
<td style='width:1%;white-space:nowrap;' class='status'></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</form>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentJS" Runat="Server">
<script type="text/javascript">
$("#selectAllCheck").change(function () {
if (this.checked) {
$("input:checkbox.checkBoxes").attr("checked", "checked");
}
else {
$("input:checkbox.checkBoxes").removeAttr("checked");
}
});
</script>
</asp:Content>
I think it's a bug in Chrome. The more checkboxes you have on a page, the slower the process gets. When you have around 500, the speed is ok. The problem is that when you get over 1000, the process to check all the boxes exponentially gets larger. In IE9 and FF4, this process does not matter. Even if you did not use jQuery and try to use straight js, you end up with Chrome getting slower the more checkboxes you use on a page.
Try limiting the number of checkboxes if possible.
You are selecting all the checkboxes in the page. Instead of this assign a class to all the child checkboxes and toggle the checked property of those textboxes. Also specify a parent element so that the search will be more specific. Something like
$("#chkAll").change(function(){
if (this.checked) {
$("#containerid input:checkbox.yourclass").attr("checked", "checked");
}
else {
$("#containerid input:checkbox.yourclass").removeAttr("checked");
}
});
try this refactoring and it should speed things up:
$(function() {
$("#selectAllCheck").click(function(){
$("input:checkbox:not(#selectAllCheck)").attr("checked", $(this).is(":checked"));
});
});
binds the event to #selectAllCheck and checks all remaining checkboxes.
example here: http://jsfiddle.net/mDGzW/1/
works instant in Chrome....
Do not look up all of the checkboxes all of the time. If they are not dynamic, there is no reason to do it. It takes the browser a good amount of time to always look through the DOM to find the elements. Do it once and keep the reference.
Also the best selector you can use is just a classname in this case. The "input:checkbox" look up is a lot slower than just looking at the class.
Basic idea:
(function(){
var cbs = $(".cb");
$("#checkall").click(
function(){
var state = this.checked;
cbs.attr("checked", state);
}
)
})();
I'd use a attr / removeAttr:
$(document).ready(function(){
$('#selectAllCheck').click(function(){
if($(this).is(':checked')) {
$('input:checkbox').attr('checked', 'checked');
}
else {
$('input:checkbox').removeAttr('checked');
}
});
});
A few minor performance tweaks:
http://jsfiddle.net/H9kK9/2/
Cache your list of checkboxes upfront, so the expensive DOM query is already finished when a user triggers onChange
Use the native "checked = true/false" instead of jQuery's prop/attr wrapper, to save on overhead. Checked is a very stable, old DOM property, and you should feel comfortable setting it on a DOM element without jQuery's help.