Show Popup before post back

16 באוקטובר 2009

אין תגובות

 


נניח שיש לנו טופס שהמשתמש ממלא בו פרטים כלשהם ובזמן לחיצה על OK לפני הריצה לשרת אנחנו רוצים להציג חלון אחר (מודלי) ובמידה והמשתמש ילחץ באותו חלון על OK נוכל לעשות ריצה לשרת בחלון הראשון .

 

המוטובצייה לעשות את זה יכולה להיות מכל מיני סיבות – אני אדגים כאן כדוגמא, בטופס הראשון משתמש אמור להעלות קובץ ולבחור משתמשים שיכולים לראות את הקובץ, בזמן לחיצה על OK נפתח לו חלון חדש שבו יש לו GRID עם השמות של המשתמשים ותיבת טקסט שבו הוא אמור להכניס את מספרי הזהות של המשתמשים שהוא בחר – ורק במידה ומספרי הזהות נכונים יוכל המשתמש לסגור את החלון המודלי על ידי לחצן OK ואז תהיה ריצה לשרת בחלון הראשון. (כמובן ויתכן פיתרונות טובים יותר מאשר חלון חדש עבור הדוגמא הזאת – המטרה של הפוסט היא להראות איך ניתן לעשות את זה כשחייבים בחלון חדש)

 

למעשה המימוש של זה מתחלק לשניים – האם יש ולידצייה כלשהי בחלון הראשון או לא – במידה ואין שום ולידצייה זה יהיה יותר פשוט אבל במידה שיש ולידצייה (לדוגמא שהמשתמש העלה קובץ) מן הסתם נרצה להפעיל את הולידצייה לפני פתיחת החלון המודלי של הכנסת מספרי הזהות.

 

בהתחלה אני אדגים את הפיתרון במצב שאין שום ולידצייה על העמוד.

ניתן להוריד את דוגמת הקוד מכאן. (הדוגמא להורדה מכילה יותר דברים – כמו styles וכו' – כאן אני מציג רק את קטעי הקוד הרלוונטיים)

 

 

החלון הראשון:

 



    1 <asp:FileUpload ID="fu" runat="server" />


    2 


    3 <asp:CheckBoxList ID="chkUsers" runat="server">


    4     <asp:ListItem Text="Shlomo" Value="Shlomo"></asp:ListItem>


    5     <asp:ListItem Text="Noam" Value="Noam"></asp:ListItem>


    6     <asp:ListItem Text="Yossi" Value="Yossi"></asp:ListItem>


    7     <asp:ListItem Text="Tom" Value="Tom"></asp:ListItem>


    8     <asp:ListItem Text="Ido" Value="Ido"></asp:ListItem>


    9 </asp:CheckBoxList>


   10 


   11 <asp:Button ID="btn" runat="server" Text="Submit"


   12     OnClientClick="return CheckIds()" OnClick="btn_OnClick" />


 

 

כמו שאנחנו רואים יש UploadFile, רשימה של משתמשים ולחצן.

בזמן לחיצה לפני הריצה לשרת אנחנו מפעילים את פונקצית CheckIds בצד בלקוח.

 



function CheckIds() {


 


    var users = GetAllSelectedUsers();


 


    return window.showModalDialog('MyPopupPage.aspx?users=' + users);


}


 

בהתחלה אנחנו מקבלים רשימה של כל המשתמשים מהפקד (אני לא מדגים את הפונקציה – אפשר להוריד את הגרסה המלאה של התוכנית, מכאן)

 

הפונקציה תחזיר true או false בהתבסס על מה שיוחזר מהחלון myPoupPage, ואנחנו שולחים לו כפרמטר את שמות המשתמשים. (כמובן יעבוד רק ב – IE)

 

 

הקוד של MyPopupPage:

 



<asp:GridView ID="grd" runat="server" AutoGenerateColumns="false">


    <Columns>


        <asp:BoundField DataField="Name" HeaderText="Name" />


        <asp:TemplateField>


            <ItemTemplate>


                <asp:TextBox ID="txtID" runat="server"></asp:TextBox>


                <asp:RequiredFieldValidator ID="rfv" runat="server"


                        ControlToValidate="txtID" ErrorMessage="*">


                </asp:RequiredFieldValidator>


            </ItemTemplate>


        </asp:TemplateField>


    </Columns>


</asp:GridView>


 


<asp:Button ID="btnOk" runat="server" Text="OK" OnClick="btnOk_OnClick" />


 


<input type="button" value="Cancel" onclick="window.returnValue = false; window.close();" />


 

זה מה יש לנו:

 

הגדרה של גריד עם עמודה אחד שמקושרת ל – Name

ועמודה שנייה שיש בה תיבת טקסט ו – RequiredValidator

 

לחצן OK שרת לשרת לבדוק האם המספרים בסדר.

ולחצן Cancel שמחזיר false וסוגר את החלון.

 

חשוב מאוד להוסיף ב – head את הדבר הבא:

 



<base target="_self" />


אחרת אחרי לחיצה על OK יפתח חלון חדש ולא מודלי – כמו שכתבתי כאן על הבעייה הידועה.

 

צד השרת (של החלון המודלי)

 



protected void Page_Load(object sender, EventArgs e)


{


    if (!IsPostBack)


    {


        DataTable table = new DataTable();


        table.Columns.Add("Name");


        table.Columns.Add("Id");


        table.PrimaryKey = new DataColumn[] { table.Columns["Id"] };


 


        if (Request["users"].Contains("Shlomo"))


            table.Rows.Add("Shlomo", "1");


        if (Request["users"].Contains("Noam"))


            table.Rows.Add("Noam", "2");


        if (Request["users"].Contains("Yossi"))


            table.Rows.Add("Yossi", "3");


        if (Request["users"].Contains("Tom"))


            table.Rows.Add("Tom", "4");


        if (Request["users"].Contains("Ido"))


            table.Rows.Add("Ido", "5");


 


        Session["table"] = table;


        grd.DataSource = table;


        grd.DataBind();


    }


}


 

בפעם הראשונה אנחנו שומרים את כל האנשים ב – Session (כמובן בדוגמא זה hard code) ומקשרים את הגריד.

 

בלחיצה על OK – קורה הדבר הבא:

 



protected void btnOk_OnClick(object sender, EventArgs e)


{


    DataTable table = (DataTable)Session["table"];


 


    for (int i = 0; i < grd.Rows.Count; i++)


    {


        string name = grd.Rows[i].Cells[0].Text;


        string id = ((TextBox)grd.Rows[i].FindControl("txtID")).Text;


 


        DataRow row = table.Rows.Find(id);


        if (row == null || row["Name"].ToString() != name)


        {


            string msg = string.Format("id {0} is not valid for {1}", id, name);


            Page.ClientScript.RegisterClientScriptBlock(GetType(), "aaa", "alert('" + msg + "')", true);


            return;


        }


    }


 


    string script = "window.returnValue = true; window.close();";


    Page.ClientScript.RegisterClientScriptBlock(GetType(), "key", script, true);


}


 

נרוץ על כל השורות בגריד, עבור כל שורה נוציא את השם והמספר.

נחפש לפי המספר האם הוא קיים בטבלה – במידה ולא מצאנו או שמצאנו אבל זה לא תואם לשם, נציג למשתמש הודעה.

 

במידה והכל בסדר נסגור את החלון ונגדיר את ה – returnValue כ – true.

 

 

היות ואין לי זמן כרגע – אפרסם את הפיתרון במידה שיש ולידצייה על הדף הראשון בפוסט הבא.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *