2009-09-30 2 views
23

имеет небольшую проблему с моей страницей ASP.net. Если пользователь дважды щелкнул по кнопке «отправить», он дважды будет записывать в базу данных (т. Е. Дважды использовать метод «onclick» на изображении)ASP.Net проблема с двойным щелчком

Как я могу сделать так, чтобы, если пользователь нажимает кнопка изображения, только кнопка изображения отключена?

Я пробовал:

<asp:ImageButton 
    runat="server" 
    ID="VerifyStepContinue" 
    ImageUrl=image src 
    ToolTip="Go" 
    TabIndex="98" 
    CausesValidation="true" 
    OnClick="methodName" 
    OnClientClick="this.disabled = true;" /> 

Но это OnClientClick свойство полностью останавливает страницу от их представления! Любая помощь?

Извините, да, у меня есть элементы управления валидации ... отсюда и неприятная проблема.


Работая над этим до сих пор, до этого момента сейчас:

ASP код:

<asp:TextBox ID="hidToken" runat="server" Visible="False" Enabled="False"></asp:TextBox> 
... 
<asp:ImageButton runat="server" ID="InputStepContinue" Name="InputStepContinue" ImageUrl="imagesrc" ToolTip="Go" TabIndex="98" CausesValidation="true" OnClick="SubmitMethod" OnClientClick="document.getElementById('InputStepContinue').style.visibility='hidden';" /> 

C# код:

  private Random 
    random = new Random(); 


    protected void Page_Load(object sender, EventArgs e) 
    { 
     //Use a Token to make sure it has only been clicked once. 
     if (Page.IsPostBack) 
     { 
      if (double.Parse(hidToken.Text) == ((double)Session["NextToken"])) 
      { 
       InputMethod(); 
      } 
      else 
      { 
       // double click 
      } 
     } 

     double next = random.Next(); 

     hidToken.Text = next + ""; 
     Session["NextToken"] = next; 

... На самом деле это почти работает. Проблема двойного щелчка в значительной степени фиксирована (yay!) Изображение все еще не скрыто.

ответ

21

Общий подход двоякий.

Serverside:

  1. При загрузке страницы, сгенерировать маркер (используя System.Random), сохранить его в сессии, и записать его в скрытом поле формы
  2. На размещаете, убедитесь, что скрытая форма поле равно переменный сеанс (перед тем установить его снова)
  3. работает

Clientside

Как и у вас есть, но, вероятно, просто спрячьте кнопку и замените ее на какой-то текст, например «отправка».

Важно отметить, что клиент может отменить сообщение, нажав «escape», поэтому вам следует подумать, что делать здесь (в зависимости от того, насколько далеко они будут использоваться, токен не будет использоваться , поэтому вам нужно будет отключить/отключить кнопку).

Полный пример следующим образом:

C# (включает в себя код, чтобы увидеть его в действии):

<html> 
<head runat="server"> 
    <title>double-click test</title> 
    <script language="c#" runat="server"> 
    private Random 
     random = new Random(); 

    private static int 
     TEST = 0; 

    public void Page_Load (object sender, EventArgs ea) 
    { 
     SetToken(); 
    } 

    private void btnTest_Click (object sender, EventArgs ea) 
    { 
     if(IsTokenValid()){ 
      DoWork(); 
     } else { 
      // double click 
      ltlResult.Text = "double click!"; 
     } 
    } 

    private bool IsTokenValid() 
    { 
     bool result = double.Parse(hidToken.Value) == ((double) Session["NextToken"]); 
     SetToken(); 
     return result; 
    } 

    private void SetToken() 
    { 
     double next = random.Next(); 

     hidToken.Value  = next + ""; 
     Session["NextToken"] = next; 
    } 


    private void DoWork() 
    { 
     TEST++; 
     ltlResult.Text = "DoWork(): " + TEST + "."; 
    } 
    </script> 
</head> 
<body> 
    <script language="javascript"> 
     var last = null; 
     function f (obj) 
     { 
      obj.src = "http://www.gravatar.com/avatar/4659883ec420f39723c3df6ed99971b9?s=32&d=identicon&r=PG"; 
      // Note: Disabling it here produced strange results. More investigation required. 
      last = obj; 
      setTimeout("reset()", 1 * 1000); 
      return true; 
     } 

     function reset() 
     { 
      last.src = "http://www.gravatar.com/avatar/495ce8981a5127a9fd24bd72e7e3664a?s=32&d=identicon&r=PG"; 
      last.disabled = "false"; 
     } 
    </script> 
    <form id="form1" runat="server"> 
     <asp:HiddenField runat="server" ID="hidToken" /> 
     <asp:ImageButton runat="server" ID="btnTest" 
      OnClientClick="return f(this);" 
      ImageUrl="http://www.gravatar.com/avatar/495ce8981a5127a9fd24bd72e7e3664a?s=32&d=identicon&r=PG" OnClick="btnTest_Click" /> 
     <pre>Result: <asp:Literal runat="server" ID="ltlResult" /></pre> 
    </form> 
</body> 
</html> 
+0

+1. nice ....... –

+2

Нет встроенного, простого способа справиться с этой проблемой в ASP.Net? – MusiGenesis

+0

MusiGenesis: Все, что я знаю, у меня теперь есть 7777 репутации, и я больше не хочу никого больше (http://www.ffonline.com/media/guides/ff7/ffvii_faq_lucky7.txt) (И нет). –

3

Я решил эту проблему, установив скрытое поле на клиенте нажмите до попадания на сервер.

Затем на сервере я проверяю скрытое поле и, если это значение, например, что-то «FALSE», что может означать, что я могу или не могу этого сделать.

6

Если у вас есть проверка на странице, отключение клиентской стороны кнопки становится немного сложнее. Если проверка не удалась, вы не хотите отключать эту кнопку. Вот фрагмент кода, который добавляет клиентский обработчик события сторона:

private void BuildClickOnceButton(WebControl ctl) 

{ 

System.Text.StringBuilder sbValid = new System.Text.StringBuilder(); 

sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { "); 

sbValid.Append("if (Page_ClientValidate() == false) { return false; }} "); 

sbValid.Append(ctl.ClientID + ".value = 'Please wait...';"); 

sbValid.Append(ctl.ClientID + ".disabled = true;"); 

// GetPostBackEventReference obtains a reference to a client-side script 
// function that causes the server to post back to the page. 

sbValid.Append(ClientScript.GetPostBackEventReference(ctl, "")); 

sbValid.Append(";"); 

ctl.Attributes.Add("onclick", sbValid.ToString()); 

} 

Смотрите эту asp.net thread для получения дополнительной информации.

Обновление: приведенный выше код будет использоваться для добавления обработчика OnClientClick в код позади. Вы также можете написать JavaScript в вашем ASPX разметкой следующим образом:

<script type="text/javascript"> 
function disableButton(button) 
{ 
    // if there are client validators on the page 
    if (typeof(Page_ClientValidate) == 'function') 
    { 
     // if validation failed return false 
     // this will cancel the click event 
     if (Page_ClientValidate() == false) 
     { 
      return false; 
     } 
    } 

    // change the button text (does not apply to an ImageButton) 
    //button.value = "Please wait ..."; 
    // disable the button 
    button.disabled = true; 

    // fire postback 
    __doPostBack(button.id, ''); 
} 
</script> 

<asp:ImageButton runat="server" ID="VerifyStepContinue" ImageUrl="button.png" 
    ToolTip="Go" TabIndex="98" CausesValidation="true" OnClick="methodName" 
    OnClientClick="return disableButton(this);" /> 
+0

Это похоже на то, что мне нужно, но не совсем уверен, как работать с этим ... какие переменные мне нужно изменить для моего? Я посмотрел сообщение на форуме, и это кажется правильным, но я не могу это понять. –

+0

Я обновил свой ответ на примере. Надеюсь это поможет! – jrummell

+0

Опять же, не работает ... когда я пытаюсь использовать это, он все еще отключает все. –

0

Подобно стороне клиента ответ шелковистой, я обычно делают две кнопки, которые похожи друг на друга, за исключением, что вторая кнопка неактивна и скрыта. OnClientClick обычной кнопки меняет стили отображения двух кнопок, чтобы нормальная кнопка была скрыта, и отображается отключенная кнопка.

0

Функция двойного щелчка представляет собой реализацию на стороне сервера, чтобы предотвратить обработку того же запроса, который может быть реализован на стороне клиента через JavaScript. Основной целью этой функции является предотвращение обработки одного и того же запроса дважды. Эта реализация на стороне сервера делает это путем идентификации повторного запроса; однако идеальным решением является предотвращение этого на стороне клиента.

В HTML-контенте, отправленном клиенту, который позволяет им отправлять запросы, для проверки того, был ли запрос отправлен, может быть использован небольшой JavaScript проверки, и если это так, не разрешайте онлайн-покупателю повторно отправлять запрос. Эта функция проверки JavaScript проверит глобальный флаг, чтобы увидеть, был ли отправлен запрос, и если да; не повторяет запрос. Если функция двойного щелчка отключена на сервере, настоятельно рекомендуется, чтобы страницы JSP и HTML реализовали это предупреждение JavaScript.

Следующий пример предотвращает форму от представляется более чем один раз с помощью действия onSubmit() объекта формы:

... 
<script> 
var requestSubmitted = false; 
     function submitRequest() { 
       if (!requestSubmitted) { 
        requestSubmitted = true; 
        return true; 
       } 
       return false; 
     } 
</script> 
... 

     <FORM method="POST" action="Logon" onSubmit="javascript:submitRequest()"> 
       ...... 
     </FORM> 
+0

Код onsubmit должен выглядеть следующим образом: onsubmit = "return submitRequest()". –

0

для тех, кто просто хочет сделать быстро исправить, просто скрыть его и показать еще одну кнопку, у которой нет событий

<asp:Button ID="RedeemSubmitButton" runat="server" Text="Submit to Redeem" OnClick="RedeemSubmitButton_Click" OnClientClick="hideit();" /> 
<asp:Button ID="RedeemSubmitButtonDisabled" style="display:none;" runat="server" Text="please wait" OnClientClick="javascript:alert('please wait, processing');" /> 
<script> 
function hideit() { 



     var btn = $get('<%= this.RedeemSubmitButton.ClientID %>'); 
     var btn2 = $get('<%= this.RedeemSubmitButtonDisabled.ClientID %>'); 
     if (btn != null) 
     { 

      btn.style.display = 'none'; 
      btn2.style.display = 'block' 
     } 
} 
    </script>