2

I am making an application with ASP.net. I have a button, that when clicked generates some html, some asp textboxes and an asp button (second button). This works fine as far as I can tell. Now what I want, is when I click that second, newly created button I want it to create some html + asp.net textboxes.

This seems confusing to me, is there an easier way to do it? I can't seem to figure it out, I create on onclick event for button two, but it doesnt exist yet.

Thanks a lot.

Thought it might be a bit easier to see the code, just in case you would like to see what is going on.

namespace ConnorMackayWebForm
{
public partial class InspectionCreate : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //Set the initial amount of areas and hazards
        int areaCount = 0;
        int hazardCount = 0;

        //Check if the viewstate with the area count already exists
        if (ViewState["areaCount"] != null)
        {
            //Convert the view state back to an int
            areaCount = Convert.ToInt32(ViewState["areaCount"]);
        }
        else
        {
            ViewState["areaCount"] = areaCount;
        }

        //Check if the viewstate with the hazard count already exists
        if (ViewState["hazardCount"] != null)
        {
            //Convert the view state back to an int
            hazardCount = Convert.ToInt32(ViewState["hazardCount"]);
        }
        else
        {
            ViewState["hazardCount"] = hazardCount;
        }

        //Create the required number of areas
        for (int i = 1; i <= areaCount; i++)
        {
            createArea(i);
        }

        //Create the required number of hazards
        for (int i = 1; i <= hazardCount; i++)
        {
            createHazard(i);
        }
    }

    protected void btnCreateArea_Click(object sender, EventArgs e)
    {
        //Get the current number of areas
        int areaCount = Convert.ToInt32(ViewState["areaCount"]) + 1;

        //Create the area
        createArea(areaCount);

        //Set the new area into the viewstate
        ViewState["areaCount"] = areaCount;
    }

    protected void btnCreateHazard_Click(object sender, CommandEventArgs areaCount)
    {
        //Get the current number of areas
        int hazardCount = Convert.ToInt32(ViewState["hazardCount"]) + 1;

        //Get the argument from the button
        int placeholderID = Convert.ToInt32(areaCount.CommandArgument);

        //Create the hazard
        createHazard(hazardCount, placeholderID);

        //Set the new hazard into the viewstate
        ViewState["hazardCount"] = hazardCount;
    }

    private void createArea(int areaCount)
    {   
        //Start generating the HTML
        pnlArea.Controls.Add(new LiteralControl("<div class='box'>"));
        pnlArea.Controls.Add(new LiteralControl("<div class='box-header with-border'>"));
        pnlArea.Controls.Add(new LiteralControl("<h2 class='box-title'>Area / Equipment Inspected 1: "));

        //Create the title dropdown
        DropDownList ddArea = new DropDownList();
        ddArea.ID = "ddArea" + areaCount;

        pnlArea.Controls.Add(ddArea);

        //Create the Other textbox in the title
        pnlArea.Controls.Add(new LiteralControl(" Other: "));

        TextBox txtOther = new TextBox();
        txtOther.ID = "txtOther" + areaCount;

        pnlArea.Controls.Add(txtOther);

        //Generate HTML for the box body and begining of first column
        pnlArea.Controls.Add(new LiteralControl("<div class='box-tools pull-right'>"));
        pnlArea.Controls.Add(new LiteralControl("</div>"));
        pnlArea.Controls.Add(new LiteralControl("</div>"));
        pnlArea.Controls.Add(new LiteralControl("<div class='box-body'>"));

        //Placeholder to put future hazards into
        PlaceHolder phHazard = new PlaceHolder();
        phHazard.ID = "phHazard" + areaCount;

        pnlArea.Controls.Add(phHazard);

        //Create hazard button
        pnlArea.Controls.Add(new LiteralControl("<br>"));

        Button btnCreateHazard = new Button();
        //btnCreateHazard.Click += btnCreateHazard_Click;
        btnCreateHazard.ID = "btnCreateHazard" + areaCount;
        btnCreateHazard.Text = "Create Hazard";
        btnCreateHazard.CssClass = "form-control";

        //Pass along the current area count, allowing the onclick to pick it up, pass it to 
        //the create hazard method.  That method will then take the argument and search for a place
        //holder with matching ID and assign the controls to that placeholder.
        btnCreateHazard.Command += btnCreateHazard_Click;
        btnCreateHazard.CommandArgument = areaCount.ToString();

        pnlArea.Controls.Add(btnCreateHazard);

        pnlArea.Controls.Add(new LiteralControl("</div>"));
        pnlArea.Controls.Add(new LiteralControl("</div>"));
    }

    private void createHazard (int hazardCount, int placeholderID)
    {
        //The starting of the HTML rows, etc
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("<div class='row'>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("<div class='col-lg-3'>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("Hazard: "));

        //Create the Hazard Dropdown
        DropDownList ddHazard = new DropDownList();
        ddHazard.ID = "ddHazard" + hazardCount;

        FindControl("phHazard" + placeholderID).Controls.Add(ddHazard);

        //HTML ending the first column, starting second
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("</div>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("<div class='col-lg-3'>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("Hazard Description: "));

        //Create the hazard description textbox
        TextBox txtHazardDesc = new TextBox();
        txtHazardDesc.ID = "txtHazardDesc" + hazardCount;

        FindControl("phHazard" + placeholderID).Controls.Add(txtHazardDesc);

        //HTML ending second column, starting third
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("</div>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("<div class='col-lg-3'>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("Corrective Action Due Date: "));

        //Create the due date textbox
        TextBox txtDueDate = new TextBox();
        txtDueDate.ID = "txtDueDate" + hazardCount;

        FindControl("phHazard" + placeholderID).Controls.Add(txtDueDate);

        //HTML ending the third column, starting fourth
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("</div>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("<div class='col-lg-3'>"));
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("Corrective Action Description: "));

        //Create the corrective action description text box
        TextBox txtActionDesc = new TextBox();
        txtActionDesc.ID = "txtActionDesc" + hazardCount;

        FindControl("phHazard" + placeholderID).Controls.Add(txtActionDesc);

        //End the row
        FindControl("phHazard" + placeholderID).Controls.Add(new LiteralControl("<br>"));
    }
}

}

1
  • 1
    Please read How to Ask and share your code. Commented Mar 2, 2017 at 18:45

1 Answer 1

3

Here is an example for continuously adding buttons to the page. Every newly created button can also add another button to the page. This can be used with all types of Controls. Also you will have to recreate dynamic controls on every PostBack, otherwise they and their contents will be lost.

protected void Page_Load(object sender, EventArgs e)
{
    //set the initial number of buttons
    int buttonCount = 1;

    //check if the viewstate with the buttoncount already exists (= postback)
    if (ViewState["buttonCount"] != null)
    {
        //convert the viewstate back to an integer
        buttonCount = Convert.ToInt32(ViewState["buttonCount"]);
    }
    else
    {
        ViewState["buttonCount"] = buttonCount;
    }

    //create the required number of buttons
    for (int i = 1; i <= buttonCount; i++)
    {
        createButton(i);
    }
}

private void createButton(int cnt)
{
    //create a new button control
    Button button = new Button();
    button.Text = "Add another Button (" + cnt + ")";

    //add the correct method to the button
    button.Click += DynamicButton_Click;

    //another control, in this case a literal
    Literal literal = new Literal();
    literal.Text = "<br>";

    //add the button and literal to the placeholder
    PlaceHolder1.Controls.Add(button);
    PlaceHolder1.Controls.Add(literal);
}

protected void DynamicButton_Click(object sender, EventArgs e)
{
    //get the current number of buttons
    int buttonCount = Convert.ToInt32(ViewState["buttonCount"]) + 1;

    //create another button
    createButton(buttonCount);

    //set the new button count into the viewstate
    ViewState["buttonCount"] = buttonCount;
}

UPDATE

You can also delegate a Command to a button instead of a Click, and with this you can send a variable along with the button as a CommandArgument. You will have to change the creation of the button a bit.

//add the correct method to the button
button.Command += DynamicButton_Command;

//now you can also add an argument to the button
button.CommandArgument = "Create Hazard";

You will also need a different method to handle the button clicks.

protected void DynamicButton_Command(object sender, CommandEventArgs e)
{
    //get the current number of buttons
    int buttonCount = Convert.ToInt32(ViewState["buttonCount"]) + 1;

    //create another button
    createButton(buttonCount);

    //set the new button count into the viewstate
    ViewState["buttonCount"] = buttonCount;

    //get the commandargument from the button
    string buttonArgument = e.CommandArgument.ToString();
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks a lot, Ill give it a shot.
Hey, I've been playing around with the code you gave me and its going pretty good. I was wondering though, is it possible to make it so when I click on the 'Create Hazard' button in 'Are/Equipment Inpected' Box 3 or 4 that the Hazard row appears in the respective textbox it was clicked? I will add an image to hopefully explain better. Thanks a lot for your guidance. i.gyazo.com/a63c828956415de1d83b1828a07c740f.png
Yes it's possible. See my update. You can switch from Click to Command to send a variable along with the button.
Hey, again thanks for all the help. My only issue now is getting this all working with the viewstate. I pass the command argument onto the createbutton method for example. Now in the viewstate where I have it creating those buttons on reload it would like that same command argument passed in, as it runs the same method for creating buttons on reload. Now is there a way I can have it place those buttons in the right places on reload? Thanks a ton.
I'm not entirely sure that I know what you mean, but if you want fixed places for the button maybe a grid layout with PlaceHolders? Then send the ID of the PlaceHolder in the CommandName/CommandArgument? If you need more than one variable in the CommandArgument, combine them in one string that you can split on a specific delimiter.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.