عنوان:

‫غیر فعال کردن یک دکمه در حین انجام پردازش های سمت سرور


نویسنده: پژمان پارسائی
تاریخ: ۱۳۹۱/۰۹/۱۲ ۵:۴۹
آدرس: www.dntips.ir
بعضی مواقع بهتر است یک دکمه در حال انجام پردازش‌های سمت سرور غیر فعال شود و وقتی عملیات سمت سرور به پایان رسید این دکمه دوباره فعال شود. غیر فعال کردن یک دکمه به این دلیل انجام می‌شود که از postback‌های مجدد در حین postback شدن صفحه جلوگیری شود.
 فرض کنید در رویداد کلیک یک دکمه کدی نوشته اید که اطلاعات یک دانشجو را ذخیره کند. کاربر نرم افزار بعد از یک بار کلیک روی دکمه، درخواستی به سرور می‌فرستد و این باعث می‌شود کدهای درون رویداد کلیک دکمه اجرا شوند، به دلیل این که کاملا این کدها اجرا نشده اند، صفحه هم postback نشده است. کاربر به هر دلیل صبر نمی‌کند تا این پردازش تمام شود (شاید او نمی‌داند عملیاتی در سمت سرور در حال اجرا شدن هست چون پیغامی به او نشان داده نشده است)، در نتیجه باز هم روی همین دکمه کلیک می‌کند و باعث می‌شود در حین پردازش کدهای درون دکمه توسط سرور، دوباره درخواستی به سمت سرور فرستاده شود و باز هم کدهای درون همین دکمه به اجرا در آیند. به عبارت بهتر در حین postback شدن صفحه دوباره درخواست postback کردن صفحه را می‌دهد و سرور هم در حین انجام کدهای درون دکمه با درخواست قبلی، دوباره کدهای درون رویداد کلیک را اجرا می‌کند. در این مثال این کار باعث می‌شود کدهای رویداد کلیک دکمه، به تعداد کلیک‌های انجام شده اجرا شوند. در نتیجه به همین تعداد می‌تواند یک دانشجوی مستقل در دیتابیس ذخیره شود. این می‌تواند مشکلات بسیاری را همراه داشته باشد.

به همین دلیل بهتر است با کلیک روی این دکمه این کارها اتفاق بیفتند:
الف) غیرفعال کردن دکمه در حین انجام پردازش‌های سمت سرور
ب) نشان دادن یک پیغام به کاربر در حین انجام پردازش‌های سمت سرور
ج) فعال کردن دکمه بعد از انجام پردازش‌های سمت سرور

برای غیرفعال کردن دکمه در حین انجام پردازش‌های سمت سرور نمی‌توان از کدهای سمت سرور استفاده کرد. چون تا کاملا صفحه postback نشود نمی‌توان این کدها را به صفحه اعمال کرد. پس این گزینه کنار می‌رود.
راه حل بسیار خوب استفاده از جاوا اسکریپت است. مثال زیر را ببینید:
<asp:Button runat="server" 
            ID="btnProcess" 
            Text="پردازش" 
            onclick="btnProcess_Click"
            OnClientClick="this.disabled = true; this.value = 'در حال پردازش اطلاعات ...';" 
            UseSubmitBehavior="false"
             />
<asp:Label runat="server" ID="lblMessage" Text=""></asp:Label>
در رویداد OnClientClick کارهای (الف) و (ب) انجام می‌شوند و با false کردن مقدار رویداد UseSubmitBehavior کار (ج) انجام می‌شود.

و در رویداد کلیک دکمه کد زیر را بنویسید:
protected void btnProcess_Click(object sender, EventArgs e)
{
    // insert student in database
    System.Threading.Thread.Sleep(2000);
    lblMessage.Text = "پردازش اطلاعات به پایان رسید";
}
در این رویداد باید یک دانشجو اضافه شود. برای ایجاد یک پردازش سمت سروری دو ثانیه ای از متد Sleep استفاده شده است.

کد برگرفته شده از : dotnetforum.lk


 

نظرات

  • مجتبی صحرائی در ۱۳۹۱/۰۹/۱۲ ۶:۹
    به نظر میاد وقتی تو صفحه validator داشته باشیم و validator جلوی postback شدن صفحه رو تحت شرایطی میگیره؛ دکمه در حالت غیر فعال باقی خواهد موند
    • پژمان پارسائی در ۱۳۹۱/۰۹/۱۲ ۷:۳۱
      در صورتی که بتونیم با بررسی‌های سمت سروری جلوی postback‌های همزمان رو بگیریم امنیت بالاتری خواهیم داشت. (منظورم استفاده از custom validator هست که در سمت سرور و بسته به شرایطی که گفتید validate می‌شود)
    • وحید نصیری در ۱۳۹۱/۰۹/۱۲ ۸:۳۸
      برای رفع این مشکل (غیرفعال کردن سازگار با اعتبار سنجی سمت کاربر) باید به نحو زیر عمل کرد:
      UseSubmitBehavior="false"
      OnClientClick="if ((typeof(Page_ClientValidate) == 'function') && (Page_ClientValidate()==false)) { return false;} this.disabled=true;"
      

  • صابر فتح الهی در ۱۳۹۱/۰۹/۲۴ ۲۰:۳۶
    ممنون از کار شما
    من این روش تست کردم اما زمانی که با یک تاییده همراه باشه کد تقریبا از کار می‌افته، صفحه به سرور پست میشه اما عملیاتی صورت نمی‌گیره.
    کدی که نوشتم:
    $("input[type=submit]").click(function () {
                    if ((typeof (Page_ClientValidate) == 'function') && (Page_ClientValidate() == false)) {
                         return false;
                    }
                    if (!confirm("آیا مطمئن هستید؟"))
                        return false;
                    this.disabled = true;
                    this.value = 'در حال پردازش اطلاعات ...';
                    return true;
                });

    • وحید نصیری در ۱۳۹۱/۰۹/۲۴ ۲۱:۱
      در jQuery برای لغو ارسال به سرور، بهتر است بجای return false از e.preventDefault استفاده شود:
      ....click(function(e) {
              e.preventDefault() // stop the automatic form submission
      • صابر فتح الهی در ۱۳۹۱/۰۹/۲۵ ۸:۳۰
        سلام این روش استفاده کردم (با return و بدون return)
        اما جواب نمی‌ده و فرم ارسال میشه، عملیات هم انجام میشه چه کاربر تایید کنه یا نکنه
        • وحید نصیری در ۱۳۹۱/۰۹/۲۵ ۹:۴۱
          <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
              CodeBehind="Default.aspx.cs" Inherits="WebAppSingleSubmit._Default" %>
          
          <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
              <script type="text/javascript">
                  $(document).ready(function () {
                      $("input[type=submit]").click(function (e) {
                          if ((typeof (Page_ClientValidate) == 'function') && (Page_ClientValidate() == false)) {
                              return false;
                          }
                          if (!confirm("آیا مطمئن هستید؟")) {
                              return false;
                          }
                          this.disabled = true;
                          this.value = 'در حال پردازش اطلاعات ...';
          
                          __doPostBack($(this).attr('name'), '');
                      });
                  });
              </script>
          </asp:Content>
          <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
              <p>
                  <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                  <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBox1"
                      ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
                  <br />
                  <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
              </p>
          </asp:Content>
          • مهمان در ۱۳۹۲/۱۱/۱۷ ۱۹:۴۴
            سلام
            آیا روشی هست که بشه جلوی کلیک کاربر روی  دکمه‌ی refresh  مرورگر (IE) را گرفت؟
            امکانش هست که این دکمه را غیرفعال کرد؟
            • وحید نصیری در ۱۳۹۲/۱۱/۱۷ ۱۹:۵۴
              • مهمان در ۱۳۹۲/۱۱/۱۹ ۱۳:۵
                ممنون. ولی من  از MVC استفاده نمی‌کنم. پروژه در قالب SharePoint 2007 است. Redirect به 303 در asp.net وجود دارد؟
                • وحید نصیری در ۱۳۹۲/۱۱/۱۹ ۱۳:۲۸
                  - مهم داشتن یک ایده اولیه برای شروع و جستجو هست.
                  - معادل return RedirectToAction در آن کدها Response.Redirect است در وب فرم‌ها. مابقی اصول الگوی PRG تفاوتی نمی‌کند. البته Redirect در اینجا از status code=302 استفاده می‌کند؛ ولی اکثر مرورگرها آن‌را همانند 303 پردازش خواهند کرد.
  • امیر نوروزیان در ۱۳۹۳/۱۰/۱۹ ۱۳:۳۲
     با سلام
    در mvc چطوری این روش استفاده کنیم.