I am using datatable JQuery plugin found on this site. http://datatables.net/
This is how I generated my table, which include three columns, checkbox column, program name and company name.
<script>
$(document).ready(function () {
var table = $('#tablePrograms').DataTable();
});
</script>
<div id="selectedProgramIds" runat="server"></div>
<asp:Repeater ID="RpPrograms" runat="server">
<HeaderTemplate>
<table id="tablePrograms" class="display">
<thead>
<tr>
<th></th>
<th>Program</th>
<th>Company Name</th>
</tr>
</thead>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:checkbox runat="server" ID="cbxProgram"/>
<asp:HiddenField ID="hdnProgramID" runat="server" Value='<%# Eval("ProgramID")%>' />
</td>
<td><asp:label runat="server" id="ProgramName" Text='<%#Eval("Program")%>'></asp:label></td>
<td><%#Eval("CompanyName")%></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
My question is, now that this is a 10 pages table with pagination, what is the best way to save the data so that checkboxes selected on 10 different pages can all be saved. Currently, the DOM only shows the elements of the pages that I am on. For example, if I am on page 1, DOM doesn't display the elements on page 2-10. What is the best way to perform saving is this case? Does datatable plugin has some kind of build-in saving feature? Thanks for your help.
Found the answer on their website. http://datatables.net/release-datatables/examples/api/form.html
A handy jQuery serialize() function can be used to string together the data.
Related
I recently did a nested repeater according to this tutorial. The same thing
http://www.codeproject.com/Articles/6140/A-quick-guide-to-using-nested-repeaters-in-ASP-NET
But I added a jQuery accordion just like this example:
http://www.snyderplace.com/demos/accordion.html
Everything is good, but I realized some UI issues. I mean for example if one of my nested repeaters has 100 records and another has just 1 record, for this second with just 1 record, it has a blank space reserved as it had 100 records also. Someone knows how to fit the height each nested repeater to its elements?
<div id="accordion">
<asp:Repeater ID="summary" runat="server" OnItemDataBound="summary_ItemDataBound">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<div>
Id:<asp:Literal ID="litCategory" runat="server" />
</div>
<div>
<asp:Repeater ID="detail" runat="server" OnItemDataBound="detail_ItemDataBound">
<HeaderTemplate>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:Literal ID="litID" runat="server" /></td>
<td><asp:Literal ID="litName" runat="server" /></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
</div>
I got it! I found this solution!
$(function () {
$("#accordion").accordion({
collapsible: true,
heightStyle: "content"
});
});
I need to specify that to attributes and that's it!
I have a Repeater like this
<asp:Repeater runat="server" DataSourceID="HeaderFooterSqlDataSource">
<HeaderTemplate>
<table border="0" width="100%">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<input runat="server" id="SelectRadio" type="radio"
name="HeaderFooter" onclick='SelectAndSetHeaderFooter(this);" %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Now here when this Repeater is rendered the name attribute of my input radio "SelectRadio" gets auto generated but name attribute for all the radiobuttons in my repeater should be same so that they can work like a group & get checked / unchecked automatically according to other elements in that group, So how can I overcome this situation ??
Edit
I got the solution my self, Actually I have defined my input radio control as runat="server" because I thought otherwise Eval() binding wouldn't work but I was wrong Eval() binding does work without runat="server" , So when I remove that attribute name doesn't generated automatically and everything is fine now, But thanx to all for sparing time for my question.
Instead of hacking this you should use the built-in RaidoButtonList control.
<asp:RadioButtonList id="RadioButtonList1" runat="server">
<asp:ListItem>Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
<asp:ListItem>Item 3</asp:ListItem>
<asp:ListItem>Item 4</asp:ListItem>
<asp:ListItem>Item 5</asp:ListItem>
<asp:ListItem>Item 6</asp:ListItem>
</asp:RadioButtonList>
You want to look into the asp:RadioButton control (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.radiobutton.aspx).
In particular the GroupName property on this control can be used to "specify a grouping of radio buttons to create a mutually exclusive set of controls"
So roughly speaking:
<asp:RadioButton runat="server" id="SelectRadio"
GroupName="HeaderFooter" %>' />
Edit: It seems that in this particular situation GroupName doesn't do what it is designed for. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.radiobutton.groupname.aspx discusses it in the community content at the end but it boils down to the fact that it uses its current NamingContainer still as part of its name rather than just using the groupname you have given it. Thanks to the mysterious user1429080 for bringing that to my attention in comments.
The reason your radio buttons are not acting as a group is because you have runat="server" which will cause the name and id attributes to be prepended with parents' ids. The following will cause the radio buttons to behave as a cohesive group (note the lack of runat="server"):
ascx code:
<asp:Repeater ID="uxRadioSelections" runat="server">
<HeaderTemplate>
<table border="0" width="300px">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<input type="radio" value='<%# Eval("Name") %>' name="HeaderFooter" onclick="alert(this.value);"><%# Eval("Name") %></input>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
code behind:
protected void Page_Load(object sender, EventArgs e)
{
string[] names = new string[] {"Alvin", "Simon", "Theodore"};
uxRadioSelections.DataSource = names.Select(x => new { Name = x });
uxRadioSelections.DataBind();
}
However, the following will NOT perform as a cohesive group:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
Test
<asp:Repeater ID="uxRadioSelections" runat="server">
<HeaderTemplate>
<table border="0" width="300px">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:RadioButton Text='<%#Eval("Name") %>' runat="server" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</asp:Content>
Due to the naming conventions you alluded to, these individual radio buttons will not find each other. ASP.NET uses RadioButtonLists to overcome this:
ascx code:
<asp:RadioButtonList ID="uxRadioButtons" runat="server">
</asp:RadioButtonList>
code behind:
protected void Page_Load(object sender, EventArgs e)
{
string[] names = new string[] {"Alvin", "Simon", "Theodore"};
uxRadioButtons.DataTextField = "Name";
uxRadioButtons.DataValueField = "Name";
uxRadioButtons.DataSource = names.Select(x => new { Name = x });
uxRadioButtons.DataBind();
}
This does not give you as granular control, but will provide easy server-side access to the selections. If all you need is javascript-related functionality and increased formatting flexibility, the first format may (which is nearly identical to what you provided) is your best bet. Good luck!
Another option is to set the ClientIDMode as 'static' which will set its value to that of the ID specified. Since it is a repeater control, all the items generated will thus have the same generated ID. So you simply set:
<asp:RadioButton runat="server" id="SelectRadio" GroupName="HeaderFooter" ClientIDMode="static">' />
This means that all generated controls will have the same ID specified i.e. "SelectRadio". This may or may not be problematic and you should be careful that this is exactly what you want.
Just a note, ClientIDMode is a feature of ASP.Net 4.0. More info here: ClientIDMode in ASP.NET 4.0 and here: MSDN. I hope this helps.
Update 1:
You can get more insights from this question asked before on StackOverflow. (It's jQuery though).
I have 2 tables in my database where one table is called "Generic Questions" and the other "Job Questions" both have a column name "Questiontext" So, the idea is they both makeup a job application.
Right now, i only have 3 questions per "Questiontext" but will be adding more later.
I have a data layer where i am accessing this database. The idea is to make something like an application. So, i would like to bind those data sets to labels because they are a series of questions. Then, i could have text boxes next to them or checkboxes.
Is there a way to add textboxes to some questions and add maybe a checkbox to another?
JobPositionSystemDAL jps = new JobPositionSystemDAL();
DataSet ds = jps.OpenJobOpeningByID(1);
DataSet ds2 = jps.GetGenericQuestions();
ListView1.DataSource = ds;
ListView1.DataBind();
ListView2.DataSource = ds2;
ListView2.DataBind();
here is the code for the listview. which works good.
<asp:ListView ID="ListView1" runat="server"
style="margin-right: 42px; margin-top: 28px; margin-left: 35px;">
<LayoutTemplate>
<table>
<thead>
<tr>
</tr>
</thead>
<tbody>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</tbody>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("QUESTIONTEXT")%></td>
</tr>
</ItemTemplate>
</asp:ListView>
</table>
<div>
<asp:ListView ID="ListView2" runat="server">
<LayoutTemplate>
<table>
<thead>
<tr>
</tr>
</thead>
<tbody>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</tbody>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("QUESTIONTEXT")%></td>
</tr>
</ItemTemplate>
</asp:ListView>
There must be a column in your query which would contain the questions (Using a Select * from database table is a bad idea, please specify table columns name in your queries)
Just place a boundfield/template field inside a gridview & databind as you are doing right now
if using template field use it like this
<asp:label ID="yourLabel" runat="server" Text='<%#Bind YourQuestionColumnName%>' ></asp:TextBox>
You can then place a checkbox list/radio button list inside a template field & bind that with your answers dataset.
In my aspx page, I have two radio buttons and a table.. if one of the radio buttons is checked it should make the table visible if the other one is checked invisible.. but this line is giving me a "JS Object Required". I am firing this from code behind .cs.. it fires fine but then i get that error.
document.getElementById('tblnewpackinglogo').style.display = '';
See code below
JAVASCRIPT
<script language="javascript" type="text/javascript">
function ShowImage() {
var rdoImg = document.getElementById("<%=radImage.ClientID%>");
if (rdoCurrImage2.checked == true) {
document.getElementById('tblnewpackinglogo').style.display = 'none';
}
else {
document.getElementById('tblnewpackinglogo').style.display = '';
}
}
</script>
TABLES
<table id="tblImage" border="0" cellpadding="0" cellspacing="10" runat="server"
visible="true">
<tr>
<td>
<asp:Image ID="imgLogo" runat="server" />
</td>
<td>
<div class="FieldStyle">
Select an Option</div>
<asp:RadioButton ID="radImage"
Text="Keep Current Image"
runat="server"
GroupName="LogoImage"
OnCheckedChanged="radImage_CheckedChanged"
Checked="True" />
<asp:RadioButton ID="radNewImage"
Text="Upload New Image" runat="server"
GroupName="LogoImage"
OnCheckedChanged="radNewImage_CheckedChanged" />
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
<table id="tblnewpackinglogo" border="0" cellpadding="0" cellspacing="0" width="100%"
runat="server" style="display:none;">
<tr>
<td style="height: 41px">
<div class="Style">
Select a Logo Image</div>
<div class="ValueStyle">
<asp:FileUpload ID="UploadImage"
runat="server"
Width="300px" />
</div>
</td>
</tr>
</table>
It's probably that you need to get the name-mangled ClientID of the table:
document.getElementById('<%= tblnewpackinglogo.ClientID %>').style.display = '';
You're already doing it with the radio button above.
Also, if you're injecting the script from the code-behind file, then you'll still need to use the ClientID, as the JavaScript will run on client-side.
That error means that something of the form (null or undefined expression).someproperty is occurring. Naturally there is no someproperty on null/undefined. For the line:
document.getElementById('tblnewpackinglogo').style.display = '';
It is most likely that the problem is getElementById is returning undefined which would be caused if there was no element with the id tblnewpackinglogo at the time it was invoked.
Since there is a tblnewpackinglogo then -- unless FishBasketGordo's answer is correct -- I suspect the issue may be that ShowImage is invoked before the DOM has been loaded. Either that or there is another trivial error that does not align with the above post.
Inspect the actual HTML to see what is generated and use a tool like FireBug to try getElementById manually. Both FireBug and MS Script Debugger also offer more detailed debugging support to inspect the state at the time of the exception.
Happy coding.
I have a set textboxes where the user enters something and I use them when they click Submit. I need to add a button that lets them add another identical set of textboxes on the fly, enter data into those and then when the submit button is pressed I need to grab the value from both sets. The amount of added sets of items can be unlimited.
What's the best way to handle something like this in ASP.NET/C#?
I've looked around and have basically only gotten that you can try to use JQuery on the front end which leaves the backend a mess or you can try to use a GridView and rebind it every time with new items which can get messy.
Any better/easier way to do this?
Thanks for the help.
Use a Repeater control for the first set of text boxes, and have it repeat for each extra listing.
Here's my comment control repeater. It's a little arcane, as it was the first control I ever made in asp.net, but it should get you going.
<asp:Repeater runat="server" ID="repeater"
onitemdatabound="repeater_ItemDataBound"
>
<HeaderTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
</HeaderTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
<ItemTemplate>
<tr id="trContents" runat="server"><td>
<table id="tableComment" runat="server"
width="100%" style="border-color:Black; border-width:1px; border-style:solid;background-color:#EEEE99">
<tr><td id="tdHeader" runat="server"
style="border-color:Black; border-width:1px; border-style:solid;padding: 5px">
<table width="100%" id="tableHeader" runat="server">
<tr>
<td>
<asp:Label ID="headerText" runat="server"
Text="<%# GetHeader((CommentRecord)Container.DataItem) %>" />
</td>
<td style="text-align:right"> <%-- OnClientClick="aspnetForm.target ='_blank';" --%>
<asp:Button ID="btnEdit" runat="server" Text="Edit"
PostBackUrl="<%$ AppSettings:TextEditor %>"
/>
<asp:Button ID="btnReply" runat="server" Text="Reply"
PostBackUrl="<%$ AppSettings:TextEditor %>"
/>
</td>
</tr>
</table>
</td></tr>
<tr><td style="border-color:Black; border-width:1px; border-style:solid;background-color:#FFFFF0;padding: 10px">
<%# ((CommentRecord)Container.DataItem).Text %>
</td></tr>
<tr><td>
<table width="100%"><tr>
<td style="text-align:left">
<asp:Button ID="btnDelete" runat="server" Text="Delete"
CausesValidation="False" />
</td>
<td style="text-align:right">
<asp:Label ID="footer" runat="server" Text="<%# GetFooter((CommentRecord)Container.DataItem) %>" />
</td>
</tr></table>
</td></tr>
</table>
<asp:PlaceHolder ID="placeHolder" runat="server" />
</td></tr>
</ItemTemplate>
</asp:Repeater>
What I usually do in these cases is have Javascript that handles the client-side dynamic creation of additional textboxes, then before I submit the values, have all the data collected into a JSON object and save the JSON string into a <asp:HiddenField> control that ASP.NET can read and parse. This isn't a perfectly clean approach, but it is the best thing I have found so far.
I would create the textboxes using jQuery (assigning them a unique id) and then get the values on the server from the Request.Form key/value collection. This would be a rather simple solution.
I would recommend going the GridView way, and bind it to a DataSource object, e.g. ObjectDataSource. Clicking the add button should add an empty row to the data source, and this empty row will automatically be drawn by the GridView. When everything works you can wrap in an UpdatePanel to achieve smooth refresh when adding rows.