Edit data using ListBox in ListView - c#

I am currently using the ListView grid format to display data from the db using a SqlDataSource. Is there a way when I click edit that only that specific row becomes a listbox
and each column becomes editable, all other rows stays the same.
For example,
Row1
Col1 Edit(Maybe using a dropdown)
Col2 Edit
Col3 Edit
Row 2 Col1 Col2 Col3
Row 3 Col1 Col2 Col3
Here is my code thus far:(This edits everything using a dropdownlist for each field)
<EditItemTemplate>
<tr style="background-color: #999999;">
<td>
<asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="Update" />
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Cancel" />
</td>
<td>
<div style="overflow:auto; width:300px;">
<asp:DropDownList ID="formtitle" runat="server" DataSourceID="SqlDataSource1" DataTextField="FormTitle" DataValueField="FormTitle" Width="300px" AppendDataBoundItems="True" SelectedValue ='<%# Bind("FormTitle") %>'>
</asp:DropDownList>
</div>
</td>
<td>
<div style="overflow:auto; width:300px;">
<asp:DropDownList ID="formsection" runat="server" DataSourceID="SqlDataSource1" DataTextField="FormSection" DataValueField="FormSection" Width="300px" AppendDataBoundItems="True" SelectedValue ='<%# Bind("FormSection") %>'>
</asp:DropDownList>
</div>
</td>
<td>
<div style="overflow:auto; width:300px;">
<asp:DropDownList ID="subsection" runat="server" DataSourceID="SqlDataSource1" DataTextField="SubSection" DataValueField="SubSection" Width="300px" AppendDataBoundItems="True" SelectedValue ='<%# Bind("SubSection") %>'>
</asp:DropDownList>
</div>
<asp:TextBox ID="SubSectionTextBox" runat="server" Text='<%# Bind("SubSection") %>' />
</td>
<td>
<div style="overflow:auto; width:300px;">
<asp:DropDownList ID="sectionitem" runat="server" DataSourceID="SqlDataSource1" DataTextField="SectionItem" DataValueField="SectionItem" Width="300px" AppendDataBoundItems="True" SelectedValue ='<%# Bind("SectionItem") %>'>
</asp:DropDownList>
</div>
<asp:TextBox ID="SectionItemTextBox" runat="server" Text='<%# Bind("SectionItem") %>' />
</td>
</tr>
</EditItemTemplate>

In order to use a ListBox in the edit row, just replace whatever DropDownList you want with a ListBox. A ListBox will instead show all of the items without the drop-down functionality and it will also allow for multiple selections. It is not however, used as a container for other controls. For example:
<asp:ListBox ID="listbox1" runat="server" DataSourceID="SqlDataSource1" DataTextField="FormTitle" DataValueField="FormTitle"></asp:ListBox>
After clearing up a few things, it sounds like you may want to check out this article titled: In-place editing of ListView subitems. Out of the box, a ListView only allows the editing of an entire row at once, not individual cells. The article I linked explains how that could be done.

Related

Trying to insert new item into a dropdownlist?

Currently, I'm trying to insert a new item into a drop-down list. It seems like nothing is working. Nothing is added to the dropdown list. It finds the control find I belive but does not insert a new item. Is my syntax off or something?
protected void livFact_ItemEditing(object sender, ListViewEditEventArgs e)
{
ListViewItem item = livFact.Items[e.NewEditIndex];
DropDownList ddl = (DropDownList)item.FindControl("ddlLocation");
ddl.Items.Insert(0, new ListItem("--Location--", "0"));
}
<%--Edit Item Template--%>
<EditItemTemplate>
<tr>
<td>
<asp:Button runat="server" ID="btnModifySave" SkinID="btnListView" class="btn btn-success btn-sm" CausesValidation="true" CommandName="Update" Text="Save" ValidationGroup="ModifySave" />
<asp:Button runat="server" ID="btnModifyCancel" SkinID="btnListView" class="btn btn-danger btn-sm" CausesValidation="false" CommandName="Cancel" Text="Cancel" />
</td>
<%--Copy Area Start Set Enabled="true" --%>
<td>
<asp:DropDownList runat="server" ID="ddlLocation" class="form-control" Enabled="true" DataSourceID="sdsDropDownListLocation" DataTextField="Location" DataValueField="LocationID" AppendDataBoundItems="true" />
<asp:Label runat="server" ID="lblLocationID" Visible="false" Text='<%# Bind("LocationID") %>' />
<br />
<div class="alert alert-warning rounded">
<asp:Label runat="server" Text="Current Location editing: " />
<asp:Label runat="server" CssClass="text-primary font-weight-bold" ID="lblLocation" Text='<%# Bind("Location") %>' />
</div>
</td>
<td class="text-center">
<asp:TextBox runat="server" ID="txtFact" class="form-control" Enabled="true" Text='<%# Bind("Fact") %>' TextMode="MultiLine" Rows="5" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtFact" Enabled="true" Display="Dynamic" ErrorMessage="A Fact is required." Text="*" ForeColor="Red" SetFocusOnError="true" ValidationGroup="ModifySave" />
</td>
<%-- Copy Area End--%>
</tr>
</EditItemTemplate>
I found a simpler approach to solve my problem. Instead of using the code behind and c#, you can solve the problem on the aspx page itself. You can simply add a ListItem and put anything you want into the drop-down list on top of any data your binding to the drop-down list from a database. I would then suggest creating a Required Field Validator with an Initial Value to stop it from saving to the database if the user clicks save with the default option selected.
<asp:DropDownList runat="server" ID="ddlLocation" class="form-control" Enabled="true" DataSourceID="sdsDropDownListLocation" DataTextField="Location" DataValueField="LocationID" AppendDataBoundItems="true">
<asp:ListItem Text="--Location--" Value="-1" Selected="True" />
</asp:DropDownList>
Found my answers here.

Adding a checkbox to the list of checkbox and label

<table style="width: 98%; height: 100%; text-align: left">
<tr>
<td valign="top">
<asp:CheckBoxList ID="c1" runat="server" DataTextField="Title" DataValueField="Id" RepeatDirection="Horizontal"
OnDataBound="cblAvailableWidgetSelector_DataBound">
</asp:CheckBoxList>
<asp:CheckBox ID="CheckBox1" runat="server" />
<label runat="server" id="lblMessage" style="padding: 3px;" />
</td>
</tr>
</table>
Here, I get the out as list of checkbox and label attached to it.
Example: I get,
Checkbox Item1
Checkbox Item2
Checkbox Item3
But I want,
Checkbox Checkbox Item1
Checkbox Checkbox Item2
Checkbox Checkbox Item3
I am using a checkbox listitem, but How can I get the output as desired.
In the code file,
DataTable dt = //datatable, which I get
c1.DataSource = dt;
c1.DataBind();
So, I get the checkbox list and a label with values, but I want to add 1 more checkbox to this list. How can I do that ?
Update
Trying to use this,
<asp:Repeater runat="server" ID="CheckBoxRepeater">
<ItemTemplate>
<asp:CheckBox ID="c1" OnDataBinding="c1_DataBound" runat="server" Checked="<%# Convert.ToBoolean(Eval("Id")) %>" />
<asp:CheckBox ID="CheckBox2" runat="server" />
<asp:Label ID="lblMessage" runat="server" style="padding: 3px;" Text="<%# Eval("Title") %>" />
</ItemTemplate>
</asp:Repeater>
But still it is not working.
Error: The server tag is not well formed.
CheckBoxList does not allow you custom templating, so it is too limited to achieve what you are trying to do. But this should be very easy to imitate with repeater:
<asp:Repeater runat="server" ID="CheckBoxRepeater">
<ItemTemplate>
<asp:CheckBox runat="server" Checked="<%# Eval("BoolProperty1") %>" />
<asp:CheckBox runat="server" Checked="<%# Eval("BoolProperty2") %>" />
<asp:Label runat="server" Text="<%# Eval("TextProperty") %>" />
</ItemTemplate>
</asp:Repeater>
Make sure to use Bind instead of Eval if you need two-way binding.
Instead of this:
Checked="<%# Convert.ToBoolean(Eval("Id")) %>"
Try this:
Checked="<%# Convert.ToBoolean(Eval('Id')) %>"
ASP.NET gets picky with the quotation marks in a render block. You need to alternate - one set is double, one set is single quotes.

ASP.NET, Multiple Val Summary not working; required field val not firing

I have a repeater with editable rows on the aspx page. The row has a textbox and a required field validator associated to it. On 'save' button click on that row, the required field valiator fires, It is tied to a validationsummary at the top of the page.
Now I have this panel below the repeater with a text box and a save button. This panel is 'opened' using the jquery show method on the click on a linkbutton at the top of this panel.
The required field validator is not firing for this texbox. I have a different validation summary for this textbox; as I need to trigger the validations on click on its save button only.
So I have the code like this,
<asp:ValidationSummary ID="validationSummary" ValidationGroup="ValidationGroup1" EnableClientScript="true" runat="server" />
<asp:ValidationSummary ID="validationSummary1" ValidationGroup="ValidationGroup2" EnableClientScript="true" runat="server" />
<asp:Repeater ID="Teams" runat="server" OnItemCommand="ItemCommand" OnItemDataBound="ItemDataBound">
<HeaderTemplate>
<table >
<tr>
<th>
<asp:Label ID="lbTeamNameHeader" runat="server" Text="TeamNameHeader"></asp:Label></th>
<th></th> </tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:TextBox ID="txtTeamName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "txtTeamName")%>' />
<asp:RequiredFieldValidator ID="reqdFieldValTeamName" ErrorMessage="Field cannot be blank" ValidationGroup="ValidationGroup1" runat="server" Display="None" ControlToValidate="txtTeamName"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regularExprTeamName" ErrorMessage="Invalid input for the team name" ValidationGroup="ValidationGroup1" Display="None" ControlToValidate="txtTeamName" runat="server" ValidationExpression="^[a-zA-Z0-9]+$"></asp:RegularExpressionValidator>
</td>
<td>
<asp:Panel ID="panelSave" runat="server" Visible="false">
<asp:LinkButton ID="linkbuttonSave" runat="server" CommandName="Save" ValidationGroup="ValidationGroup1" Text="SAVE" />
<asp:LinkButton ID="linkbuttonCancel" runat="server" CommandName="Cancel" Text="CANCEL" />
</asp:Panel>
</td>
</tr>
</ItemTemplate>
<FooterTemplate></table></FooterTemplate>
</asp:Repeater>
<asp:LinkButton ID="linkbuttonAddTeam" runat="server" Text="Add New Team" />
<div id="AddPanelDiv" style="display:none;">
<asp:TextBox ID="txtAddTeam" runat="server" />
<asp:RequiredFieldValidator ID="reqdFieldValAddTeam" ErrorMessage="Field cannot be blank" ValidationGroup="ValidationGroup2" runat="server" Display="None" ControlToValidate="txtAddTeam"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regularExprValAddTeam" ErrorMessage="Invalid format" ValidationGroup="ValidationGroup2" Display="None" ControlToValidate="txtAddTeam" runat="server" ValidationExpression="^[a-zA-Z0-9]+$"></asp:RegularExpressionValidator>
<asp:LinkButton ID="linkbuttonCancel" runat="server" Text="CANCEL"></asp:LinkButton>
<asp:LinkButton ID="linkbuttonSaveNewTeam" runat="server" OnClick="linkbuttonSaveNewTeam_OnClick" Text="SAVE" CausesValidation="true" />
</div>
Why on earth the validators for the bottom panel fire? On click of that save button, it straightaway goes to the page method onclick.
If I remove the validation group and click on the save in the repeater, it fires! But thats not what I want..
You are missing ValidationGroup="ValidationGroup2" on your second button it looks like.
<asp:LinkButton ID="linkbuttonSaveNewTeam" runat="server" OnClick="linkbuttonSaveNewTeam_OnClick"
Text="SAVE" CausesValidation="true" ValidationGroup="ValidationGroup2" />

Getting database ID of objects in ListView and updating ListView from user control ListView

I am creating a website and am facing the following problem. I have 2 ListViews.
The first ListView is inside a user control called Sidebar.ascx:
<asp:ListView ID="sidebarListView" runat="server" DataKeyNames="Id" DataSourceID="SqlDataSourceSidebar">
<ItemTemplate>
<div class="sidebarItem" runat="server">
<div>
<asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' />
</div>
</div>
</ItemTemplate>
<LayoutTemplate>
<div class="sidebarMain">
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
</div>
</LayoutTemplate>
</asp:ListView>
<asp:SqlDataSource ID="SqlDataSourceSidebar" runat="server" ConnectionString="<%$ ConnectionStrings:TudengiDBConnectionString %>" SelectCommand="SELECT [Id], [Name] FROM [Faculties] ORDER BY [Name]"></asp:SqlDataSource>
It has to display only the name.
The second listview is inside my Default.aspx
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:ListView ID="RecentItemsListView" runat="server" DataSourceID="SqlDataSource1"
GroupItemCount="3">
<LayoutTemplate>
<div class="recentItemsMain">
<asp:PlaceHolder runat="server" ID="groupPlaceHolder" />
</div>
<asp:DataPager ClientIDMode="Static" ID="DataPager1" runat="server" PageSize="9">
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
</LayoutTemplate>
<GroupTemplate>
<div class="recentItems">
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
</div>
</GroupTemplate>
<ItemTemplate>
<div class="recentItem" runat="server">
<div>
<asp:Image ID="PictureThumb" runat="server" ImageUrl='<%#CreateThumbnail((string)Eval("Picture"),130,130) %>' />
</div>
<asp:Label ID="AuthorLabel" runat="server" Text='<%# Eval("Author") %>' />
<div>
<asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' />
</div>
</div>
</ItemTemplate>
<GroupSeparatorTemplate>
<div class="groupSeparator">
</div>
</GroupSeparatorTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TudengiDBConnectionString %>" SelectCommand="SELECT [Id], [Name], [Faculty_Id], [User_Id], [Author], [Picture], [Location] FROM [Books] ORDER BY [DateAdded] DESC">
What I need is for the ListView in Default.aspx to display the data without a WHERE clause, but when an item is clicked in the Sidebar user control I need to update the Default.aspx ListView to display only the data where the [Faculty_Id] = the ID of the ListView item in the user control.
How can I get the database ID of the ListView object when I can only display the NAME field? Do I have to display the ID as well and then hide the column from users?
What is the correct way to solve a situation like this?
Thanks for helping
<asp:ListView ID="sidebarListView" runat="server" DataKeyNames="Id" DataSourceID="SqlDataSourceSidebar" OnItemCommand="sidebarListView_ItemCommand">
<ItemTemplate>
<div class="sidebarItem" runat="server">
<div>
<asp:LinkButton ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' CommandName="Select" CommandArgument='<%# Eval("Id") %>' />
</div>
</div>
</ItemTemplate>
This is what I ended up with.
Add a hidden-field to your item-template to hold the database ID.
<ItemTemplate>
<asp:HiddenField ID="hdnFacultyID" runat="server" Value='<%# Eval("FacultyID") %>' />
<div class="recentItem" runat="server">
...
</div>
</ItemTemplate>
In the appropriate ListView handlers, you can access the database ID something like this.
((HiddenField)e.item.FindControl("hdnFacultyID")).Value
What you can do is to add an attribute to the NameLabel control.
Call it for example myID:
<asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' myID='<%# Eval("ID") %>'/>
then access that attribute from your code to get your ID:
string ID = NameLabel.Attributes["myID"];

Handling repeater events aynchronously

I have a custom search control on my page (asp.net) which contains a textbox and a repeater for displaying results.
The repeater is populated with a callback as the user types ... nice and simple callback.
...
When a search result is selected the repeater fires off a postback and the itemcommand event is raised (as expected) ... and this event adds a child repeater to itself and binds a child list to the current item.
My problem is that I don't want my parent repeater to fire off a full postback because the page is quite time consuming to render.
I tried putting the control / just the outer repeater in to an ajax update panel control but it appears to still fire a ful postback.
Can anyone shed any light on how I might tell a repeater to fire its item command event in a callback instead of a postback?
I'm guessing this involves a load of manual wiring for my repeater item controls but i'm hoping theres a control somewhere that handles all that for me :)
EDIT : Sample of my situation ....
<asp:UpdatePanel ... >
<asp:Repeater ...>
<itemTemplate> <asp:LinkButton ... CommandArg='<%= Eval("ID") %>' CommandName="select" /> </itemTemplate>
</asp:Repeater>
</asp:UpdatePanel>
So my question is ...
How do i tell the repeater "fire this link buttons onclick as a callback instead of a postback"
the process of wrapping up the repeater in an update panel doesn't help because the ID of the link button is dynamic and therefore I cannot (not inline anyway) add a trigger for the link button.
If i manually add a trigger to the panel in the repeaters onitembound event i get an exception from .Net sayingt he callback reference is invalid ... i guess this is because im trying to attach a callback trigger to a control that is already handling a postback event or something setup by the repeater ...
EDIT 2 : Sample of the scenario faced here
essentially because this control X number of times on the page virtually everything has to be dynamic.
The control implements ICallbackHandler and the search bx code (not included below) fires off an ajax call onkeyup when the user types in company names (so it works a bit like google).
I was hoping that when a user clicked on a company name from the list it would ajax call back / partial postback to recover the sub list of branches thus preventing the full page flicker you get with a full postback.
Then a user would select a branch and it would do a full postback which would result in several server actions taking place.
This works fine as is ... its just not the cleanest user experience.
<div id='<%= this.UniqueID + "Results" %>' class="results">
<asp:Repeater ID="ui_lstCompanies" runat="server" onitemcommand="ui_lstCompanies_ItemCommand">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<asp:Panel ID="item" runat="server">
<li>
<asp:LinkButton ID="ui_btnSelectCompany" runat="server" CommandName="Select" Text='<%# Eval("Name") %>' />
</li>
</asp:Panel>
<asp:Panel ID="selectedItem" runat="server" Visible="false">
<li>
<hr /><h4><%# Eval("Name") %></h4>
<asp:Repeater ID="ui_lstBranches" runat="server" onitemcommand="ui_lstBranches_ItemCommand" >
<HeaderTemplate>
<table style="border-collapse:collapse;">
<tr><th> </th><th>Branch Name</th><th>Branch Address</th><th>Tel</th><th>Fax</th><th>Email</th></tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td> </td>
<td><asp:LinkButton ID="ui_btnSelectBranch1" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Select" Text='<%# Eval("Name") %>' /></td>
<td><asp:LinkButton ID="ui_btnSelectBranch2" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Select" Text='<%# Eval("Address") %>' /></td></td>
<td><asp:LinkButton ID="ui_btnSelectBranch3" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Select" Text='<%# Eval("Telephone1") %>' /></td></td>
<td><asp:LinkButton ID="ui_btnSelectBranch4" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Select" Text='<%# Eval("Fax") %>' /></td></td>
<td><asp:LinkButton ID="ui_btnSelectBranch5" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Select" Text='<%# Eval("Email") %>' /></td></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<hr />
</li>
</asp:Panel>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</div>
I had a similar problem as you did. If you replace the linkbuttons with regular asp:button and continue to use the repeater's itemcommand event as you were, it will work. Why? I don't know. However, it works. It may not look good with your design, but it triggers the asynch postback that you desired.
<asp:Repeater runat="server" ID="rpt1">
</asp:Repeater>
<asp:UpdatePanel runat="server" ID="up1">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="rpt1"/>
</Triggers>
<ContentTemplate>
<asp:Repeater runat="server" ID="rpt2">
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
This should then perform an async call to all commands from rpt1.
Just Replace these repeater control's with yours
EDIT:
I've basically created a mockup of your code with different fields etc. I assume the code below is what you tried and it was not working? If so then I've got no idea why it's not working on your side as it is on myne, there must be some slight difference somewhere that we're not picking up.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="UpdatePanel1">
<ContentTemplate>
<div id='<%= this.UniqueID + "Results" %>' class="results">
<asp:Repeater ID="ui_lstCompanies" runat="server" OnItemCommand="ui_lstCompanies_ItemCommand">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<asp:Panel ID="item" runat="server">
<li>
<asp:LinkButton ID="ui_btnSelectCompany" runat="server" CommandName="Select" Text='<%# Eval("Name") %>' />
</li>
</asp:Panel>
<asp:Panel ID="selectedItem" runat="server" Visible="false">
<li>
<hr />
<h4>
<%# Eval("Name") %></h4>
<asp:Repeater ID="ui_lstBranches" runat="server" OnItemCommand="ui_lstBranches_ItemCommand">
<HeaderTemplate>
<table style="border-collapse: collapse;">
<tr>
<th>
</th>
<th>
Branch Name
</th>
<th>
Branch Address
</th>
<th>
Tel
</th>
<th>
Fax
</th>
<th>
Email
</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
</td>
<td>
<asp:LinkButton ID="ui_btnSelectBranch1" runat="server" CommandArgument='<%# Eval("ID") %>'
CommandName="Select" Text='<%# Eval("Name") %>' />
</td>
<td>
<asp:LinkButton ID="ui_btnSelectBranch2" runat="server" CommandArgument='<%# Eval("ID") %>'
CommandName="Select" Text='<%# Eval("Address") %>' />
</td>
</td>
<td>
<asp:LinkButton ID="ui_btnSelectBranch3" runat="server" CommandArgument='<%# Eval("ID") %>'
CommandName="Select" Text='<%# Eval("Telephone1") %>' />
</td>
</td>
<td>
<asp:LinkButton ID="ui_btnSelectBranch4" runat="server" CommandArgument='<%# Eval("ID") %>'
CommandName="Select" Text='<%# Eval("Fax") %>' />
</td>
</td>
<td>
<asp:LinkButton ID="ui_btnSelectBranch5" runat="server" CommandArgument='<%# Eval("ID") %>'
CommandName="Select" Text='<%# Eval("Email") %>' />
</td>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<hr />
</li>
</asp:Panel>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</div>
</ContentTemplate>
</asp:UpdatePanel>

Categories

Resources