Avatar billede tchami Nybegynder
13. juli 2004 - 20:31 Der er 30 kommentarer og
1 løsning

Textboxe forsvinder..

Hej,

Jeg er ved at lave en formular på to sider, dvs. på den første side indtaster brugeren et nummer og trykker videre. På den næste side bliver der så genereret det antal textboxe brugeren har valgt. Disse bliver tilføjet til en placeholder. Brugeren kan så udfylde disse textboxe og når der trykkes gem vil jeg gerne have fat i indholdet af disse textboxe, men de er væk!

Her er min webform:

<code>
Antal svarmuligheder:
<asp:TextBox ID="answers" Runat="server" CssClass="content-textbox" Width="50"/><br/></br>
<asp:PlaceHolder ID="phQuestions" Runat="server" />
<asp:Button ID="btnGenQuestions" Text="  Videre >>  " cssclass="submit-button" OnClick="generateQuestions" Runat="server" />
<asp:Button ID="btnStartOver" Text="  << Tilbage  " cssclass="submit-button" OnClick="startOver" Visible="False" Runat="server" />
<asp:Button ID="btnAddPoll" Text="  Tilføj afstemning  " Visible="False" cssclass="submit-button" OnClick="addPoll" Runat="server" />
</code>

Og de bagvedliggende funktioner:

<code>
protected void startOver(object sender, System.EventArgs e)
{
    answers.ReadOnly = false;
    btnGenQuestions.Visible = true;
    btnAddPoll.Visible = false;
    btnStartOver.Visible = false;
}

protected void generateQuestions(object sender, System.EventArgs e)
{
    phQuestions.Controls.Add(new LiteralControl("Spørgsmål:<br>"));
    for(int i = 0; i<Convert.ToInt32(answers.Text); i++)
    {
        TextBox choice = new TextBox();
        choice.ID = i.ToString();
        choice.CssClass = "content-textbox";
        phQuestions.Controls.Add(new LiteralControl(i+1 + ": "));
        phQuestions.Controls.Add(choice);
        phQuestions.Controls.Add(new LiteralControl("<br>"));
    }
    phQuestions.Controls.Add(new LiteralControl("<br><br>"));
}

protected void addPoll(object sender, System.EventArgs e)
{
foreach(Control ctrl in phQuestions.Controls)
{
    if(ctrl is System.Web.UI.WebControls.TextBox)
    {
        Response.Write(ctrl + "<br>");
    }   
}
}
</code>
Avatar billede tchami Nybegynder
13. juli 2004 - 20:33 #1
Og det er jo så altså i addPoll metoden at jeg ikke kan få fat i de textboxe der blev genereret i generateQuestions.
Avatar billede snepnet Nybegynder
13. juli 2004 - 21:50 #2
Hej tchami.

Den enestå metode du har til at få lagt dine tekstbokse ind i kontroltræet er handleren af dit generateQuestions-event, så hvis den ikke kaldes i forbindelse med et roundtrip til serveren - så findes de ikke.

Når du tilføjer kontroller dynamisk på den måde bliver de der desværre ikke automatisk.

Der er flere måder du kan fikse det på, men jeg tror sådan lige umiddelbart at du vil være bedst tjent med at oprette en form til hvert trin, men hvis godt kunne tænke dig at lave det hele på én form, kan det også lade sig gøre.

For den ene model vil problemerne nok ligge i at få overført de rigtige parametre fra den ene side til den anden, og for den anden model vil det nok være lidt omkring at alt skal oprettes dynamisk udfra et slags "page-mode".

Jeg vil meget gerne komme med forslag til begge dele hvis du er interesseret, men jeg vil gerne vide om der er én af delene du allerede nu kan sige at du foretrækker.

Jeg har for øvrigt svaret udfra forestillingen om at det er sådan lidt "wizard-agtigt" det du vil lave, og at der kunne komme flere trin, så det håber jeg er tilfældet :o)

Mvh
Avatar billede tchami Nybegynder
13. juli 2004 - 22:45 #3
Jeg vil allerhelst gøre dynamisk, så hvis du kan hjælpe med det ville det være lækkert!

Og ja, der kunne godt komme flere trin :)
Avatar billede snepnet Nybegynder
13. juli 2004 - 23:16 #4
jamen så smider jeg en lille bitte principskitse ud her... er det ok ?
Avatar billede tchami Nybegynder
13. juli 2004 - 23:21 #5
Det ville være perfekt.

Jeg har fundet en midlertidig løsning hvor jeg bruger Request.Form istedet, men vil meget gerne ha' hjælp til en ordentlig løsning :)
Avatar billede snepnet Nybegynder
14. juli 2004 - 03:11 #6
Beklager ventetiden - jeg har lavet et lille skelet til dig.

Hovedprincipperne er, at du laver en kontrol for hvert trin i din wizard, og du angiver så pr. querystring hvilket trin du ønsker at se.

Der er desuden et navigationspanel som hjælper med at linke mellem trinene.

Du kan så for hvert trin angive opbygning og håndtere events mv.

// aspx-filen
<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="tchami._Default" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
    <HEAD>
        <title>Default</title>
        <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
        <meta name="CODE_LANGUAGE" Content="C#">
        <meta name="vs_defaultClientScript" content="JavaScript">
        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
        <LINK href="Styles.css" type="text/css" rel="stylesheet">
    </HEAD>
    <body>
        <form id="WizardForm" method="post" runat="server">
        </form>
    </body>
</HTML>

// cs-filen
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace tchami
{
    // definition af hvilke tilstande siden kan være i
    public enum PageState
    {
        Undefined        = 0,
        WizardStepOne    = 1,
        WizardStepTwo    = 2,
        WizardStepThree    = 3
    }

    public class _Default : System.Web.UI.Page
    {
        // formen på siden
        protected HtmlForm WizardForm;

        // property til at suge pagestate fra querystring
        protected PageState CurrentPageState
        {
            get
            {
                try
                {
                    return (PageState)Enum.Parse(typeof(PageState), Request.QueryString["PageState"], true);
                }
                catch
                {
                    return PageState.WizardStepOne;
                }
            }
        }

        // kan give næste trin
        protected PageState NextPageState
        {
            get
            {
                if(Enum.IsDefined(typeof(PageState), ((int)CurrentPageState)+1))
                    return (PageState)((int)CurrentPageState)+1;
                else
                    return PageState.Undefined;
            }
        }

        // kan give forrige trin
        protected PageState PreviousPageState
        {
            get
            {
                if(Enum.IsDefined(typeof(PageState), ((int)CurrentPageState)-1))
                    return (PageState)((int)CurrentPageState)-1;
                else
                    return PageState.Undefined;
            }
        }

        // sørger for at få indsat den rigtige type kontrol
        private void Page_Load(object sender, System.EventArgs e)
        {
            WizardStep step = null;

            switch(CurrentPageState)
            {
                case PageState.WizardStepOne :
                    step = new StepOne();
                    break;
                case PageState.WizardStepTwo :
                    step = new StepTwo();
                    break;
                case PageState.WizardStepThree :
                    step = new StepThree();
                    break;                   
                default :
                    break;           
            }

            if(step != null)
            {
                step.CssClass = "wizardStep";
                WizardForm.Controls.Add(step);
                InserNavigationPanel();
            }
        }

        // for opbygning af navigationspanel
        private void InserNavigationPanel()
        {
            HyperLink hl = null;

            Table table = new Table();
            table.CssClass = "navigationPanel";
            TableRow tr = new TableRow();
            table.Rows.Add(tr);
           
            TableCell tc = new TableCell();
            tc.HorizontalAlign = HorizontalAlign.Left;
           
            if(PreviousPageState != PageState.Undefined)
            {
                hl = new HyperLink();
                hl.NavigateUrl = Request.Path + "?PageState=" + PreviousPageState;
                hl.Text = "<<--";
           
                tc.Controls.Add(hl);
            }
           
            tr.Cells.Add(tc);


            tc = new TableCell();
            tc.HorizontalAlign = HorizontalAlign.Right;
           
            if(NextPageState!= PageState.Undefined)
            {
                hl = new HyperLink();
                hl.NavigateUrl = Request.Path + "?PageState=" +NextPageState;
                hl.Text = "-->>";
                tc.Controls.Add(hl);
            }
           
            tr.Cells.Add(tc);
   
            WizardForm.Controls.Add(table);
        }

        // standard
        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }
       
        // standard
        private void InitializeComponent()
        {   
            this.Load += new System.EventHandler(this.Page_Load);
        }
    }

    // base for alle trin
    public class WizardStep : WebControl, INamingContainer
    {
    }

    public class StepOne : WizardStep
    {
        // kontroller til step1
        protected Label lblText;
        protected TextBox txtText;
        protected Button btnButton;

        protected override void OnInit(EventArgs e)
        {
            lblText = new Label();
            lblText.Text = this.GetType().Name;
            txtText = new TextBox();
            btnButton = new Button();
            btnButton.Click += new EventHandler(btnButton_Click);
            base.OnInit (e);
        }

        protected override void CreateChildControls()
        {
            Controls.Add(lblText);
            Controls.Add(new LiteralControl("<br>"));
            Controls.Add(txtText);
            Controls.Add(btnButton);
            base.CreateChildControls ();
        }

        private void btnButton_Click(object sender, EventArgs e)
        {
            this.txtText.Text = "KLIK !";
        }
    }

    public class StepTwo : WizardStep
    {
        // kontroller til step2
        protected DropDownList ddList;

        protected override void OnInit(EventArgs e)
        {
            ddList = new DropDownList();
            ddList.Items.Add(new ListItem("Hej","0"));
            ddList.Items.Add(new ListItem("med","1"));
            ddList.Items.Add(new ListItem("dig","2"));
            base.OnInit (e);
        }

        protected override void CreateChildControls()
        {
            Controls.Add(ddList);
            base.CreateChildControls ();
        }
    }
   
    public class StepThree : WizardStep
    {
        // kontroller til step3
        protected Calendar calDates;

        protected override void OnInit(EventArgs e)
        {
            calDates = new Calendar();
            base.OnInit (e);
        }

        protected override void CreateChildControls()
        {
            Controls.Add(calDates);
            base.CreateChildControls ();
        }
    }
}

Jeg håber du kan bruge idéen til noget...
Hvis der er noget omkring det du er i tvivl siger du bare til.

Jeg er klar over at der i eksemplet IKKE er vist noget med hvordan du samler værdier op i forbindelse med navigering osv, men der er ikke nogle problemer i at lægge ind, og jeg gør det gerne, hvis du gerne vil arbejde videre med ovenstående model.
Desuden gemmes bruges eventuelle indtastninger heller ikke ved navigering, men det er der heller ikke noget problem i at udvide med.
(men så skal vi nok have lidt på banen omkring hvad der skal ske med det :o)

Mvh
Avatar billede tchami Nybegynder
22. juli 2004 - 19:52 #7
hej Snepnet,

jeg beklager meget at jeg ikke har svaret før nu. Jeg kom pludselig fra det og siden har jeg glemt alt om det :(

Det ligner helt sikkert noget jeg kan bruge til noget, og uanset hvad skal du have dine point, så smid et svar :)
Avatar billede snepnet Nybegynder
22. juli 2004 - 19:53 #8
Det er bare ok... Jeg håber du får det til at virke, ellers spørger du bare :o)
Avatar billede tchami Nybegynder
27. juli 2004 - 22:29 #9
Det virker jo helt perfekt, og helt som jeg havde tænkt mig :)

Jeg ved sidde og lege lidt med det og prøve og se om jeg ikke selv kan finde ud at samle værdierne op og gemme de forskellige indtastninger, ellers vender jeg frygteligt tilbage ;)
Avatar billede snepnet Nybegynder
27. juli 2004 - 22:33 #10
Du siger bare til... der var en plan for den slags også :o)
Avatar billede tchami Nybegynder
27. juli 2004 - 22:46 #11
Du må da gerne afsløre planen så :)

Jeg har brug for tre trin:

Trin et: To texboxe, i den ene indtaster man et nummer
Trin to: Et antal (Det antal man indtastede i trin et) textboxe genereres
Trin tre: To kalendere

Det skulle gerne være muligt at gå frem og tilbage i de forskellige trin, og når man er tilfreds og er nået til trin tre skal al indtastet data være tilgængeligt så det kan gemmes i en db eller lign. Håber det er nogenlunde klart hvad jeg mener?
Avatar billede snepnet Nybegynder
27. juli 2004 - 23:02 #12
Det er fuldstændig klart :o)

Jeg vil gerne gå lidt videre med det, men jeg har ikke tid i aften desværre... Jeg får måske tid til det imorgen.

Har du en database at gemme det i, eller er det en du skal lave på et tidspunkt ?
Avatar billede tchami Nybegynder
27. juli 2004 - 23:13 #13
Det lyder fremragende :)

Jeg har en database ja, og det er heller ikke noget problem at gemme data i den. Mit eneste problem er at lave de tre trin og så stadig have al data tilgængelig :)
Avatar billede snepnet Nybegynder
27. juli 2004 - 23:15 #14
Super... kan du ikke smide noget herud der viser den/de tabeller du ville gemme sagerne i ?
(du kan eventuelt bare dumpe et create-script af det el.l)
Avatar billede tchami Nybegynder
27. juli 2004 - 23:16 #15
Jo da :)

Det er en MySQL db, passer det dig?
Avatar billede snepnet Nybegynder
27. juli 2004 - 23:18 #16
Ja det er fint... jeg har både MySql og MS Sql kørende.
Avatar billede tchami Nybegynder
27. juli 2004 - 23:23 #17
Oki doki, her er den:

CREATE TABLE poll (
  id int(6) unsigned NOT NULL auto_increment,
  question varchar(255) default NULL,
  startdate date default NULL,
  enddate date default NULL,
  PRIMARY KEY  (id),
  UNIQUE KEY id (id)
) TYPE=MyISAM;

CREATE TABLE poll_choices (
  id int(6) unsigned NOT NULL auto_increment,
  fk_pollid int(6) unsigned default NULL,
  choice_number tinyint(3) unsigned default '0',
  choice varchar(255) default NULL,
  votes int(6) unsigned default '0',
  PRIMARY KEY  (id),
  UNIQUE KEY id (id)
) TYPE=MyISAM;

Indholdet af de textboxe der generes i trin to skal gemmes i poll_choices og værdien af den ene textbox i trin et samt de to kalendere skal gemmes i poll (question, startdate og enddate).

Det er til en afstemning som du jo nok allerede har regnet ud :)
Avatar billede snepnet Nybegynder
27. juli 2004 - 23:24 #18
Super duper.... jeg kigger på det imorgen.
Hold dig munter så længe :o)
Avatar billede tchami Nybegynder
27. juli 2004 - 23:32 #19
Mange tak og i lige måde :)
Avatar billede snepnet Nybegynder
28. juli 2004 - 23:00 #20
Hej tchami... er du kommet videre med det selv ?
Avatar billede tchami Nybegynder
29. juli 2004 - 20:13 #21
Ikke just, jeg blev pludselig grebet af noget andet :)
Avatar billede snepnet Nybegynder
29. juli 2004 - 22:46 #22
Det kender jeg godt :o)
Du kan bare sige til når du kommer tilbage til det.
Mvh
Avatar billede tchami Nybegynder
30. juli 2004 - 15:28 #23
Jeg har siddet og kigget på det siden i går, men jeg kan ikke helt hitte ud af hvordan jeg skal få fat i værdierne imellem de to trin.. Kan du hjælpe?
Avatar billede snepnet Nybegynder
30. juli 2004 - 15:57 #24
Jeps... men jeg har ikke tid nu... Kan du vente et par timer.
Avatar billede tchami Nybegynder
30. juli 2004 - 17:13 #25
Sagtens :)
Avatar billede snepnet Nybegynder
30. juli 2004 - 19:13 #26
Hej tchami... har du arbejdet med datasets og den slags ?
Avatar billede snepnet Nybegynder
30. juli 2004 - 20:29 #27
Jeg har lavet noget her der forudsætter at du har lidt kendskab til det...
Avatar billede tchami Nybegynder
30. juli 2004 - 20:52 #28
Det har jeg ja :)
Avatar billede snepnet Nybegynder
30. juli 2004 - 20:55 #29
Perfekt.... så er vi på banen :o)

Hvis du laver et dataset baseret på de to tabeller du har sendt - dvs noget i den her stil :

public class PollDataSet : DataSet
{
    public PollDataSet() : base()
    {
        InitClass();
    }

    public void InitClass()
    {
        this.DataSetName = "WizardDataSet";
        this.Tables.Add(new PollTable());
        this.Tables.Add(new PollChoices());
        // relation mellem tabellerne kan angive med
        this.Relations.Add(...);
    }
}

En tabel kan du så lave sådan her :

public class PollTable : DataTable
{
    public const string TableName = "PollTable ";
   
    public const string id            = "id";
    public const string question        = "question";
    public const string startdate        = "startdate";
    public const string enddate        = "enddate";
   
    public SampleTable() : base(TableName)
    {
        InitClass();
    }

    private void InitClass()
    {
        DataColumn c = this.Columns.Add(id, typeof(int));
        c.AllowDBNull = false;
        c.AutoIncrement = true;
        c.AutoIncrementSeed = 0;
        c.AutoIncrementStep = -1;

        DataColumn[] pKeys = {c};
        this.PrimaryKey = pKeys;       
   
        c = this.Columns.Add(question, typeof(string));
        c.AllowDBNull = true;
        c.DefaultValue = "SampleString";

        c = this.Columns.Add(startdate, typeof(DateTime));
        c.DefaultValue = DateTime.Now;
        c.AllowDBNull = true;

        c = this.Columns.Add(enddate, typeof(DateTime));
        c.DefaultValue = DateTime.Now;
        c.AllowDBNull = true;
    }
}

public class PollChoiceTable : DataTable
{
    // samme fremgangsmåde som med den anden
}


Du kan så - når wizarden startes - gøre noget ala nedenstående :

PollDataSet pollData = new PollDataSet();

//
DataRow newPollRow = pollData.Tables[PollTable.TableName].NewRow();
newPollRow[PollTable.question] = "hvor du så end har spørgsmålet fra";
newPollRow[..] = ...
...
osv

Derefter :
pollData.Tables[PollTable.TableName].Rows.Add(newPollRow);

Nu har du så et dataset, med to tabeller, hvor du har oprettet en Poll række i den ene tabel.

Derefter kan du så - efterhånde som wizarden skrider frem - tilføje de nødvendige PollChoices-rækker på samme måde.
Dvs... du får noget :
DataRow pollChoiceRow = pollData.Tables[PollChoiceTable.TableName].NewRow();

Du kan så sørge for at holde datasættet i session, og gemme det når du har lyst (når folk trykker gem til allersidst, eller for hvert trin, eller hvad du nu synes).

...

Nå - men fidusen er så (hvis du gør det som ovenstående) - at du kan komme ret let over det ved at være lidt fræk, og lade dine wizard trin få adgang til data, hvilken du kan gøre ved simpelthen at have en property på wizard-trin base. Desuden bør du så nok sikre, at det enkelte trin altid skal have en reference til et dataset (altså... du sørger for at et trin skal have et dataset i constructoren).

Du kan så faktisk implementere i hvert trin hvad der skal oprettes af choice-rækker mv, og da du har en reference direkte til det dataset der ligger og hygger sig i session - bliver det bare gemt der.

Du går på den måde en smule på kompromis med det generelle i wizarden, men til gengæld er det meget enkelt at få til at virke på den måde.

Mvh
(der er for øvrigt ikke noget af koden der er forsøgt kompileret eller noget, så det kan godt være at det ikke lige virker... men det er også mere ideen du skulle se).
Avatar billede tchami Nybegynder
04. august 2004 - 21:02 #30
Hej igen,

Endnu en gang beklager jeg at jeg ikke har svaret før nu. Umiddelbart virker det til at finde ud af så tak for hjælpen :)
Avatar billede snepnet Nybegynder
04. august 2004 - 21:14 #31
det var så lidt :o)
mvh
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester