Link to home
Start Free TrialLog in
Avatar of manu009
manu009

asked on

Checkbox control inside a repeater control.. how to collect data?? help!

Hello experts;
I am using ASP.net, C#.

On a webpage I list some records in a repeater control (from database).
   One of the columns is a checkbox control (On or Off depending on the relevant value pulled from database)
      NOW, I need the user to be able to change the state of the checkbox
          When he clicks SUBMIT, I want to update all selected records in the database.

NOW how do I find out....
 which checkboxes the user selected????
 which id they are associated with???????????

I believe in ASP.net there should be a simple solution....
---> I also noticed that, ASP.net changes my checkbox ids to something like repeaterElements_ctl00_CheckBox1, repeaterElements_ctl01_CheckBox1 etc...

Any help will be appreciated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Thanks a in advance...
Avatar of jonorossi
jonorossi

You can loop through all the items in the repeater and then use code like this to retrieve the value of the checkbox. There should be a nicer way but that is how it has to be done:

if (((CheckBox)Repeater1.Items[0].FindControl("CheckBox1")).Checked)

Then you get the ID from item you use the DataItem and cast it to either a business object or a DataRow or whatever you are binding to the repeater:

Repeater1.Items[0].DataItem

Hope that helps, Jono
Avatar of manu009

ASKER

Could you please post the code (preferably in C#... or even VB) for that..
Here is what I use

<asp:repeater  id="repeater1" runat="server">
  <ITEMTEMPLATE>
    <asp:CheckBox id="chk" runat="server" />
  </ITEMTEMPLATE>
</asp:repeater>

Much appreciated....
I am new to this ASP.net :-) cheers
Are you using the SqlDataSource control? I still haven't found a way to get the ID because i found out the DataItem of a repeater is set to null other than a few events of the repeater (http://www.netnewsgroups.net/group/microsoft.public.dotnet.framework.aspnet/topic4049.aspx).

[code]
        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item)
            {
                bool isChecked = ((item.FindControl("chk") as CheckBox).Checked);

                // --> this needs fixing:
                //int id = item.DataItem;
            }
        }
[/code]
From what i have looked at i cannot see a way to get the bound data from the repeater. I haven't yet had a need to use a repeater so i didn't relise it was so basic,

The best solution i can think of is to make a hidden field and then use findcontrol to get the id out of it. Add a hidden field to your ItemTemplate:
<asp:HiddenField ID="HiddenField1" runat="server" />

Jono
Avatar of manu009

ASKER

Well I just included a hidden field with its value set to record id.

However, the record_ids returned are the ones that were already in the database.
Whatever the user selectes/deselects is ignored...

Any ideas???

Thanks for your help...
please explain?
However, the record_ids returned are the ones that were already in the database.

where else do they come from?
Avatar of manu009

ASKER

Say, I get 3 records listed
and say, the first checkbox is selected, while other two are not (obviously which checkbox is selected depends upon the relevant value in database).

Now the user deselects the first checkbox
 and selects third checkbox instead.
And clicks on the Submit button, so that the ON/OFF values in the db will be changed.

BUT after the submit is clicked, the array that holds values returned from above action
 still has record_id 1 as ON and other two as OFF.

Pl let me know if I should explain in more detail...

Cheers for your help buddy. :-)

do you use an sql command or statement to update the database base on what check box is checked?
The easiest way to conserve updating the database with the checked state it has is to make another hiddenfield with the checked state at the beginning. Use findcontrol again and then if the value is different to the checkbox then update it in the database.
Avatar of manu009

ASKER

[deanvanrooyen ]
Yes I am using an SQL statement, to update the db, based on what checkbox is selected!

[jonorossi ]
The hidden field will give me existing values in the database.
The same thing, I am getting in the array that holds what is returned from the form (checkboxes) after submit button is clicked.
On comparision, I will always get YES.

Any ideas???

Thanks a lot for your help. :-)

I don't understand what the problem is. What array are you referring to?
Avatar of manu009

ASKER

Pl see below

User visits the page
Original Selections (pulled  from database) When page loads
 checkbox1 ON
 checkbox2 OFF
 checkbox3 OFF

-> now the user changes them to
 checkbox1 OFF
 checkbox2 ON
 checkbox3 ON

and hits the submit button.

NOW I, ofcourse, need the new values so that I can change the database as per user's new selections.

Whatever user submits, I store in an array.
That array should contain new values selected by user

BUT it does not

it still contains, the old original values that were already in the database, which are useless.

I hope this explanation makes more sense.

Thanks guys....

:-)
Are you rebinding the repeater on the postback? Basically do you have a if(!IsPostBack) around the binding code? Ignore if that if you do, it is just that this is the most common reason for this type of thing.
Avatar of manu009

ASKER

No buddy... there is no if(!IsPostBack).... in the script...

  @ @
    £
   ~~

scratching my head...
ASKER CERTIFIED SOLUTION
Avatar of jonorossi
jonorossi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
this is how I do it, I used a update button next to every row, but you could use one update button and search through every row to repeat update command...
I am using sql express.

        <asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand" >
        <ItemTemplate>
             <asp:Label ID="label1" Text='<%# Eval("ProductID") %>' runat="server" Width="50"></asp:Label>
 
             <asp:CheckBox id="chk" runat="server" Text="Discontinued?" Checked='<%# System.Convert.ToBoolean(Eval("Discontinued")) %>' Width="50"/>
     
             <asp:Button id="btnUpdate" Runat="server" Text="Update" CommandName="Update" Font-Size="12px" Width="50"></asp:Button>
             <br />
             <br />
         </ItemTemplate>
        </asp:Repeater>

    public void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        Int32 id = System.Convert.ToInt32(((Label)e.Item.FindControl("label1")).Text); //record id key
        Int16 check = System.Convert.ToInt16(((CheckBox)e.Item.FindControl("chk")).Checked);
        //update the db
        string strcon = SqlDataSource1.ConnectionString;
        System.Data.SqlClient.SqlConnection sqlCon = new System.Data.SqlClient.SqlConnection(strcon);
        System.Data.SqlClient.SqlCommand sqlCmd = new System.Data.SqlClient.SqlCommand("update products set discontinued = @check where productid = @id", sqlCon);
        sqlCmd.Parameters.Add("@id", SqlDbType.Int).Value = id;
        sqlCmd.Parameters.Add("@check", SqlDbType.Int).Value = check;
       
        try
        {
            sqlCon.Open();
            sqlCmd.ExecuteNonQuery();
            sqlCon.Close();
            //rebind the repeater here to reflect updated record - this might not be required though as the checkbox should remain checked with view state
        }
        catch(Exception me)
        {

        }  
    }

hope this helps
Avatar of manu009

ASKER

[jonorossi]
I tried both, with IsPostBack and with !IsPostBack... nothing works...

[deanvanrooyen]
Thanks for the code, but it is far away from what I am looking for.

Any other suggestions??

Thanks to all efforts!
Can you post your code from the aspx and cs files that are applicable to this issue.
you say you store the checked option in an array?

why? and can you post the code.
Avatar of manu009

ASKER

// Here is the code for aspx.cs file (only relevent section)
//////////////////////////////////////////////////////////////////
                <asp:Repeater ID="repeaterElements" runat="server">
                <ItemTemplate>

                <tr>
                    <td>
                    <%# DataBinder.Eval(Container, "DataItem.label_name") %>
                    </td>

                    <td>
                    <%# DataBinder.Eval(Container, "DataItem.element_name") %>
                    </td>

                    <td>
                    <asp:CheckBox ID="CheckBox1" runat="server" Checked=<%# DataBinder.Eval(Container, "DataItem.default_on_off") %> />
                    </td>

                    <td>
                    <asp:HiddenField ID="HiddenField1" value=<%# DataBinder.Eval(Container, "DataItem.label_id") %> runat="server" />
                   
                    <A href=labels.aspx?action=edit&element_id=<%# DataBinder.Eval(Container, "DataItem.element_id") %>&label_name=<%# DataBinder.Eval(Container, "DataItem.label_name") %>>Edit</A>
                    /
                    <A href=labels.aspx?action=delete&label_id=<%# DataBinder.Eval(Container, "DataItem.label_id") %>>Delete</A>
                    </td>
                </tr>
                </ItemTemplate>
               
                <FooterTemplate>
                <asp:Button ID="Button_Save2" runat="server" Text="Save" OnClick="Button_Save2_Click" />
                </FooterTemplate>
                </asp:Repeater>

// Here is the code for aspx.cs file (only relevent section)
//////////////////////////////////////////////////////////////////////////////////////////
    protected void Button_Save2_Click (object sender, System.EventArgs e)
    {

        ArrayList arrList = new ArrayList();
       
            foreach (RepeaterItem item in repeaterElements.Items)
            {
                CheckBox cb = (CheckBox)item.FindControl("CheckBox1");

                if (cb.Checked)
                {
                    HiddenField label_id = (HiddenField)item.FindControl("HiddenField1");
                    arrList.Add(label_id.Value);
                    arrList.TrimToSize();
                }

            }
  }

I cannot see any problems with that code at the moment; can you show the code in your Page_Load that binds the repeater.
Whay do you store it in an array instead of writting the update to the database and rebind the repeater?
I think he is just doing that for now while testing, he probably has a breakpoint set and he checks the values in the array.

aha - that why the values are always the same in the array

check this out :

<asp:HiddenField ID="HiddenField1" value=<%# DataBinder.Eval(Container, "DataItem.label_id")

then

        HiddenField label_id = (HiddenField)item.FindControl("HiddenField1");
        arrList.Add(label_id.Value);

nothing is actually been updated it is always the value from the database that is stored....
does this make sense?

I am still confused though

User visits the page
Original Selections (pulled  from database) When page loads
 checkbox1 ON                             (database field = true)
 checkbox2 OFF                           (database field = false)
 checkbox3 OFF                           (database field = false)

-> now the user changes them to
 checkbox1 OFF                           (database field still = true)
 checkbox2 ON                             (database field still = false)
 checkbox3 ON                             (database field still = false)

and hits the submit button.

he adds the hidden field to array which still contains the original db field value

so array = ( false,false)  although
but he thinks it should be  (true,true) because the check boxes are now checked .....

see what i mean kindof? am I on the right track here - I feel that I am answering what he has put in writing but the issue is somthing else ... anyway....



I think you miss read it:

                CheckBox cb = (CheckBox)item.FindControl("CheckBox1");
                if (cb.Checked)
                {
                    HiddenField label_id = (HiddenField)item.FindControl("HiddenField1");
                    arrList.Add(label_id.Value);
                    arrList.TrimToSize();
                }

You will see that it gets the checkbox, then if it is checked it inserts the value into into the list. So you will end up with a list (the ID) of the checked items. This is not what you want to execute something in the database but if you check something that wasn't previously checked then it should be in the list. manu009 was however saying that it was always the same.

What manu009 needs is something like this:

Add another hidden field like this:
<asp:HiddenField ID="HiddenField2" value=<%# DataBinder.Eval(Container, "DataItem.default_on_off") %> runat="server" />

Then code like this:
                CheckBox cb = (CheckBox)item.FindControl("CheckBox1");
                bool originalCheckedValue = (HiddenField)item.FindControl("HiddenField2").Checked;
                if (cb.Checked != originalCheckedValue)
                {
                    HiddenField label_id = (HiddenField)item.FindControl("HiddenField1");
                    // execute your database code to update the row with 'label_id' with the value of cb.Checked
                }
that looks better