I have an asp.net listbox that I'm using javascrript to let the client reorder elements. When the user presses a save button (not pictured below), how can I capture the new order of the items in the listbox? myList always contains the original order.
<script>
function MoveUp() {
....
}
</script>
<asp:ListBox ID="myList" runat="server" Height="112px" AutoPostBack="True"/>
<asp:Button ID="Button1" runat="server" Text="Up" OnClientClick="MoveUp();return" false;" />
<asp:Button ID="Button2" runat="server" Text="Down" OnClientClick="MoveDown();return false;" />
Put the values in a hidden form field as the client reorders them. When the client hits the save button, grab that hidden field which you can use to identify the new order.
Using something like the jquery sortable plugin could make your life easier, as you won't need the up and down buttons.
Having said that, since your buttons will probably only be used for client side functionality, they really don't need to be (and shouldn't be asp.net buttons)
Related
I am running into an issue when converting an ASPX page to a controller (ASCX). My JavaScript isn't finding a textbox in a hidden div and its not firing an onclick event either. However it works perfectly fine in the ASPX page.
My JavaScript is..
function FireEditClickButton() {
document.getElementById("btnFireEdit").click();
}
Its supposed to fire this button that is in a hidden div along with the next piece)
<asp:Button ID="btnFireEdit" runat="server" OnClick="btnFireEdit_Click" />
Then with this JavaScript
function GetSelection() {
var c = document.getElementById("tbRA");
c.innerText = checkListBox.GetSelectedValues();
UpdateText();
}
gets called everytime the checklistbox has values.
Both errors are saying that they are null but they are right here in a hidden div
<div style="visibility: hidden">
<asp:TextBox ID="tbRA" runat="server"></asp:TextBox>
<asp:Button ID="btnFireEdit" runat="server" OnClick="btnFireEdit_Click" />
</div>
So why would this be happening since it works completely fine in the ASPX page? would it have to do with the WebUserControl not using a form tag?
Thanks
Your javascript cannot find the button because in the rendered HTML it no longer has id="btnFireEdit" but instead an id based on the name of the usercontrol (e.g. id="myctrlname_btnFireEdit").
You have two choices... either update the javascript to include the name of the usercontrol...
document.getElementById("myctrlname_btnFireEdit").click();
document.getElementById("<%=btnFireEdit.ClientID%>").click();
(Note, the 2nd of these two lines will only work if the javascript is part of the usercontrol itself. It will not work if the javascript is in an external .js file or the parent page)
Or use the ClientIDMode attribute of the <asp:Button> and set the value to Static. This will make the rendered HTML use id="btnFireEdit"...
<asp:Button ID="btnFireEdit" runat="server" OnClick="btnFireEdit_Click"
ClientIDMode="Static" />
When using nested controls (or pages nested in a master page), by default the ID on the client side will be different than on the server. ASP.NET does this by default to help ensure that all ID's on the client are unique. However, you can prevent this using one of two ways.
The first option is to change the ClientIDMode to static. You can do this at the control, page, web.config, or machine.config levels. The web.config technique is shown below. The ID on the client will then match the ID on the server.
<configuration>
<system.web>
<pages clientIDMode="static" />
</system.Web>
</configuration>
The second option is to use inline C# code to embed the ID into your JavaScript, but this only works if the JavaScript is embedded on an ASP.NET page or control and not in a separate script file. The C# expression will be evaluated and therefore the ID on the client will be embedded into the JavaScript.
document.getElementById('<%= btnFireEdit.ClientId %>');
There is a third option, and that is to figure out what the ID will be on the client and then manually put that in the JavaScript, like this:
document.getElementById("myctrlname_btnFireEdit").click();
However, that is a bad idea. If you ever rename either myctrlname or btnFireEdit then your client side code will fail at runtime. And it's always better to fail at compile time than runtime.
So what I want to do is click on a button which will cause JS code to run which will cause another button to click and button #2 will be runat="server" and cause a C# function to run onClick.
But using the below does not cause the C# function to run even though simply clicking the button2 does cause it to run.
function button1_click() {
document.getElementById('button2').click();
__doPostBack('#button2', 'onclick');
$('#button2').trigger('click');
// neither worked (tried them seperately)
}
<asp:Button runat="server" Visible="true" text="you should not see this" ClientIDMode="Static" ID="button2" onclick="button2_Click" formnovalidate />
Useful knowledge:
- button one is in a client form
- button two is in a runat="server" form
This code
$('#button2').trigger('click');
should work.
Have you checked that the ID 'button2' is not changed during runtime?
Sometimes, when using master pages or user controls, the client ID of an element with runat="server" attribute will get a prefix at run time.
Use a debug console (depends on your browser, try pressing F12) to check the effective client ID.
Also, have you checked that button1_click() function is actually called?
I'm using ASP.NET to pass a value to a JavaScript function and, for some reason I haven't been able to determine, it isn't working when I try to pass in a value from another control. Instead, it acts like there is a syntax error and it just submits back to the main form.
Does anyone know why?
Example:
<asp:TextBox ID="txtToSay" runat="server" Text="Something"></asp:TextBox>
<asp:Button runat="server" ID="btnSaySomething1" Text="Say Something"
OnClientClick="saySomething(<%=txtToSay.Text%>);" /> <!-- doesn't work -->
<asp:Button runat="server" ID="btnSaySomething1" Text="Say Something"
OnClientClick="saySomething('<%=txtToSay.Text%>');" /> <!-- doesn't work -->
<asp:Button runat="server" ID="btnSaySomething2" Text="Say Something"
OnClientClick="saySomething('Something');" /> <!-- works -->
<script type="text/javascript">
function saySomething(txt){
alert(txt);
};
</script>
Additional Information:
Web Application running on .NET 4.0
Language: C#
Update:
After working with this a while, I've determined that you can't use <%%> tags in ASP controls. Additionally, if you're looking for dynamic evaluation of control values AVOID AVOID AVOID using <%=someControl.Text%> or similar constructs since they are only evaluated once a request is submitted to the server. If you need a static value from another control at runtime, simply set that value in the page load event or handle it another way in the code behind.
Javacript will search for variable name = txtToSay.Text in saySomething function call, Put quotes around it to make it string value
Change
OnClientClick="saySomething(<%=txtToSay.Text%>);"
To
OnClientClick="saySomething('<%=txtToSay.Text%>');"
You can get the txtToSay.Text without passing it this way
<script type="text/javascript">
function saySomething(txt){
alert(document.getElementById('<%=txtToSay.Text%>').value);
};
</script>
you need to put ' around your text in the saySomething() call.
Like this:
<asp:Button runat="server" ID="btnSaySomething1" Text="Say Something" OnClientClick="saySomething('<%=txtToSay.Text%>');" />
UPDATE
<%= %> won't work inside an asp.net control. Can you set it from the code-behind?
I.E
btnSaySomething1.OnClientClick = "Text to say"
I have code like this
<table>
<tr>
<td>
<div>
<asp:Label runat="server" ID="lblBookmarksIds" Style="visibility: hidden;" Text="test"/>
</div>
</td>
<td>
<asp:UpdatePanel runat="server" ID="buttonPanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button runat="server" ID="btnInvokeImageRead" CausesValidation="false" UseSubmitBehavior="false"
OnClick="btnInvokeImageRead_Click" Style="visibility: hidden;" />
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
</table>
in javascript i'm trying to set value of label and call codebehind function so that i will have desired value passed to codebehind like that :
alert(document.getElementById('<%= lblBookmarksIds.ClientID%>').firstChild.nodeValue);
document.getElementById('<%= lblBookmarksIds.ClientID%>').innerText = str;
alert(document.getElementById('<%= lblBookmarksIds.ClientID%>').firstChild.nodeValue);
//alert('1');
if (str != "") {
document.getElementById('<%= btnInvokeImageRead.ClientID%>').click();
}
when second alert gets displayed the value of lblBookmarksIds has changed value, but when i debug in codebehind function btnInvokeImageRead_Click the value of lblBookmarksIds has its old value.
Anybody knows Why ?
Regards
Wojciech
Labels are not passed to code behind. You will have to use an input(TextBox) for that purpose.
You can style an input to look like a label using CSS.
Alternatively, you can keep the value in a hidden field, and use javascript to show the value in a label and pass it back in the hidden field.
The reason ASP.NET is able to "see" the values entered into a TextBox and similar controls is because the values of these controls are sent in the POST body when the page posts back. You can see this through any number of tools, including the Developer Tools your browser likely includes or an intercepting proxy like Fiddler. When the postback occurs, each of those controls has a LoadPostData function that processes the POST data and updates the Text properties (or whatever properties) of the control.
The contents of a Label are not submitted in the POST data, so .NET has no way to see any changes made to it from JavaScript.
The controls that do process post data all implement IPostBackDataHandler.
I am having so much trouble with this. I have looked everywhere so I hope someone can either explain to me how to do this or show me. Here's my problem:
I have a DataGrid filled with DataBound Items (ItemTemplate) which was created using ASP.Net.
My reason for the ItemTemplates over a regular DataBound field is to enable the Edit Mode of the DataGrid. In my ItemTemplates, I have labels to display the data and two option buttons (Edit/Delete). I've got the buttons working in the code behind (C#).
Edit places the DataGrid in Edit Mode. In the EditItemTemplates I've got DropDownLists, TextBoxes, and a Save button in place of the Edit button.
The Save button also works with the code I've written for it. All-in-all, the DataGrid works beautifully and displays everything neatly. However, there is one final job I want the Save button to do: I want it to check the TextBoxes and validate that the values entered match the criteria I have set (keep in mind that these are in EditItemTemplates).
I have Javascript already written that will check for validation. I want a modal window (that I have already set up) to display and I want the CSS of the TextBoxes in question to change.
I want to do this using Javascript but my problem is that I can't check for the Save button to create the Click event and I can't 'locate' the TextBoxes to validate them. Is there a way I can 'find' those elements while the DataGrid is in Edit Mode?
Here's a small bit of the code used to create the DataGrid if it helps:
<asp:DataGrid ID="dgCamsizer" CssClass="data" runat="server" AutoGenerateColumns="False"
GridLines="None" OnItemCommand="dgCamsizer_ItemCommand" ShowHeader="true">
<Columns>
<asp:TemplateColumn HeaderStyle-CssClass="infoHeaderDG">
<HeaderTemplate>
Operator</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="Operator" Text='<%# DataBinder.Eval(Container.DataItem, "Operator") %>'
runat="server" /></ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="EditOper" Width="40px" Text='<%# DataBinder.Eval(Container.DataItem, "Operator") %>'
runat="server"></asp:TextBox></EditItemTemplate>
<HeaderStyle CssClass="infoHeaderDG"></HeaderStyle>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderStyle-CssClass="infoHeaderDG">
<ItemTemplate>
<asp:Button ID="Edit" Text="Edit" CommandName="Edit" runat="server" /></ItemTemplate>
<EditItemTemplate>
<asp:Button ID="Save" Text="Save" CommandName="Save" runat="server" /></EditItemTemplate>
<HeaderStyle CssClass="infoHeaderDG"></HeaderStyle>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Perhaps I should re-phase my question: I managed to 'find' the TextBoxes thanks to Zetlen. I've also managed to get the values. Now... How do I use those values to test for validation?
Here is the code I used to get the values:
$("#<%=dgCamsizer.ClientID %> :text").each(function () {
alert($(this).val());
});
ASP.NET webforms are hard to work with in JavaScript, because the IDs of your HTML elements change during the page lifecycle! The input you're calling "EditOper" will get an HTML ID of something like "dgCamSizer_ctl102_EditOper". One thing you can do is collect these elements on pageload in a cache of DOM element references. I recommend using jQuery or a similar DOM querying library.
<script type="text/javascript">
$(document).ready(function() {
var $editorElms = {},
idSeparator = "_"; // the underscore is ASP.NET's default ID separator, but this can be changed if you wish with the IDSeparator property.
$('#dgCamSizer input').each(function() {
$editorElms[this.id.split('_').pop()] = $(this);
});
// now you can access every input using the $editorElms hash.
// e.g.
function someValidationRoutine() {
if (!$editorElms.EditOper.val()) {
someErrorDisplayer("EditOper must not be blank.");
return false;
}
}
})
</script>
And, again using jQuery, the Save button shouldn't be too tough to find.
var $saveButton = $('#dgCamSizer :submit[value=Save]');
So you can bind the event that way:
$saveButton.click(function(e) {
if (!someValidationRoutine()) {
e.preventDefault();
}
});
This is not the most high-performance solution--selectors of that complexity are always a bit slower. But it gets the job done without messing too much with the DataGrid.
So I managed to solve my own problems and answer my own question. I was able to get the id's of all of the TextBoxes and I even placed them into an array to be used for my validations. Here's what I used to do all of this:
var i = 0;
var data = [];
$("#<%=dgCamsizer.ClientID %> :text").each(function () {
data[i] = $(this).attr("id");
i++;
});