2013-09-06 3 views
0

У меня есть Javascript на стороне клиента, который я использую на странице ASP.NET, чтобы установить видимость нескольких элементов в datalist. В принципе, когда элемент 1 виден, элемент 2 должен быть скрыт и наоборот. Этот код также позволяет/отключает некоторые обязательные проверки валидатора ASP.NET в зависимости от видимости полей вокруг них на стороне клиента.Ошибка проверки ASP.NET - отображаемые элементы меняют видимость

Код работает нормально , если у меня нет ошибки проверки ASP.NET. Когда проверка не удалась, поля сбрасываются до видимости по умолчанию (скрыты).

Я исключал это, так как мои контрольные точки на стороне сервера не попадают, когда возникает проблема. Это похоже на скрипт на стороне клиента.

Исправления на стороне сервера отсутствуют, поскольку страница никогда не отправляет сообщения назад. Мне интересно, как я могу это сделать с точки зрения Javascript? Есть ли способ запускать пользовательский код при запуске сценариев проверки подлинности?

Я думал об использовании файла cookie, но я не думаю, что это поможет мне, если я не могу подключиться к событию проверки.

код следует ...

function handleDropDown(e, a, b, c, v1, v2, h1, h2) { 
    var i = parseInt(c) + 2; 
    var x = parseInt(c) + 3; 

    if (e.value == "Yes") { 
     document.getElementById(i).style.display = "inline"; 
     document.getElementById(i).style.visibility = "visible"; 

     document.getElementById(x).style.display = "none"; 
     document.getElementById(x).style.visibility = "hidden"; 

     document.getElementById(a).focus(); 

     //Enable validator if needed 
     var oVal1 = document.getElementById(v1); 
     var oVal2 = document.getElementById(v2); 

     var oVis1 = document.getElementById(h1); 
     var oVis2 = document.getElementById(h2); 

     ValidatorEnable(oVal1, true); 
     if (oVis1 != null) { 
      oVis1.value = "true"; 
     } 
     ValidatorEnable(oVal2, false); 
     if (oVis2 != null) { 
      oVis2.value = "false"; 
     } 
     } 
    else if (e.value == "No") { 
     document.getElementById(x).style.display = "inline"; 
     document.getElementById(x).style.visibility = "visible"; 

     document.getElementById(i).style.display = "none"; 
     document.getElementById(i).style.visibility = "hidden"; 

     document.getElementById(b).focus(); 

     //Enable validator if needed 
     var oVal1 = document.getElementById(v1); 
     var oVal2 = document.getElementById(v2); 

     var oVis1 = document.getElementById(h1); 
     var oVis2 = document.getElementById(h2); 

     ValidatorEnable(oVal1, false); 
     if (oVis1 != null) { 
      oVis1.value = "false"; 

     } 
     ValidatorEnable(oVal2, true); 
     if (oVis2 != null) { 
      oVis2.value = "true"; 
     } 
    } 
} 

ASPX Markup сниппет: **

   <span id="spTxtAnswer" class="required" visible="false" runat="server">*</span> 
         <asp:TextBox ID="txtAnswer" Text='<%# Bind("Answer") %>' runat="server" 
            TextMode="MultiLine" Height="76px" MaxLength="2000" Width="370px" Visible="false" > 
         </asp:TextBox> 
         <asp:RequiredFieldValidator ID="valTextBox" ErrorMessage="This question is required." Enabled="false" 
         Display="Static" ControlToValidate="txtAnswer" runat="server" ValidationGroup="Request" /> 
         <asp:RequiredFieldValidator ID="valAnswer" ControlToValidate="txtAnswer" ErrorMessage="<br />Other description is required." 
         Display="Static" enabled="false" runat="server" ValidationGroup="Request" /> 
         <span id="spDdlAnswer" class="required" visible="false" runat="server">*</span> 
         <asp:DropDownList ID="ddlAnswer" Visible="false" runat="server" /> 
         <asp:RequiredFieldValidator ID="valDropDown" ControlToValidate="ddlAnswer" Enabled="false" 
         ErrorMessage="This field is required." Display="Static" runat="server" 
         InitialValue="(Select)" ValidationGroup="Request" /> 
         <asp:HiddenField ID="hfQuestionID" Value='<%# Bind("QuestionID") %>' runat="server" /> 
         <asp:HiddenField ID="hfAnswer" Value='<%# Bind("Answer") %>' runat="server" /> 
         <asp:HiddenField ID="hfRequired" Value='<%# Bind("Required") %>' runat="server" /> 
         <asp:HiddenField ID="hfVisible" Value="false" runat="server" /> 

CodeBehind сниппет:

TextBox tb1 = (TextBox)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("txtAnswer"); 
      TextBox tb2 = (TextBox)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("txtAnswer"); 
      RequiredFieldValidator rfv1 = (RequiredFieldValidator)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("valTextBox"); 
      RequiredFieldValidator rfv2 = (RequiredFieldValidator)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("valTextBox"); 
      HiddenField hf1 = (HiddenField)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 1].FindControl("hfVisible"); 
      HiddenField hf2 = (HiddenField)gridUserSupplierTypeQuestionsAndAnswers.Rows[rowIndex + 2].FindControl("hfVisible"); 

      ddl.Attributes.Add("onchange", "handleDropDown(this,'" + tb1.ClientID + "','" + tb2.ClientID + "','" + questionID + "','" + rfv1.ClientID + "','" + rfv2.ClientID + "'," + 
       "'" + hf1.ClientID + "','" + hf2.ClientID + "');"); 

      //When selected and viewing in edit mode, set the visibility during page load 
      string script = "<script language='javascript'>"; 
      script += System.Environment.NewLine + "var el = document.getElementById('" + ddl.ClientID + "');"; 
      script += System.Environment.NewLine + "handleDropDown(el,'" + tb1.ClientID + "','" + tb2.ClientID + "','" + questionID + "','" + rfv1.ClientID + "','" + rfv2.ClientID + "');</script>"; 
      ClientScript.RegisterStartupScript(Page.GetType(),"startScript", script); 

**

+1

Вы можете показать фрагмент разметки aspx с помощью валидаторов на месте? я подозреваю, что ваша проверка действительно происходит на стороне сервера. Вы поставили точку останова в первой строке в обработчике событий Page_Load? – woohoo

ответ

0

Мне пришлось использовать скрипт на стороне клиента и файл cookie, чтобы установить видимость. Мне нужно сохранить значения после обратной передачи, но прочитать их на стороне клиента, поэтому в этом случае viewstate не был действительно вариантом.

Еще одна связанная с этим проблема заключалась в том, что когда я попытался вызвать скрипт для определения видимости поля в IE10, он всегда будет выполняться до того, как тело закончит загрузку. Я установил вызов в теге body на главной странице, и теперь он работает нормально.

+0

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

0

С другой стек проблема переполнения (https://stackoverflow.com/a/11723794/704879):

«Это проблема: когда на страницу загружен валидатор, он создает немного javascript для поддержки проверки клиентов. Когда вы помещаете валидатор внутри пользовательского контроля, который по умолчанию не отображается, и этот пользовательский контроль находится в панели обновления, он не создает этот javascript правильно. Это решение: За пределы UpdatePanel, я сделал выше, создать фиктивную валидатор с фиктивным текстовым полем с помощью фиктивного ValidationGroup так:.»

Кредитов идут на оригинальный плакат решения (Антон Белев)

+0

Хороший ресурс, но моя страница не использует обновления. – Tim

0

Я знаю, что это старый, но на всякий случай кто-то сталкивается с этим, как я это делал, я хотел бы предоставить альтернативу ответам Тима на использование файлов cookie для отслеживания состояния между клиентской стороной и сервером.

Если у вас есть javascript, который должен быть способен считывать значение, например, был ли конкретный элемент управления видимым/скрытым на стороне клиента, а не использовать файл cookie, я рекомендую создать собственное состояние просмотра таким же образом .NET делает.

Я видел, как многие коллеги на протяжении многих лет пытались перекрыть скрытый контроль поля в свою разметку страницы, но это не всегда надежно, потому что .NET может перезаписать значение на стороне клиента при перезагрузке viewstate. Решение, которое я использую, похоже, работает очень надежно, и его не сложно настроить. Это работает точно так же для веб-пользователей и даже элементов управления сервером. Это дает серверный и клиентский доступ к значениям по обратной передаче и учитывает любые изменения на стороне клиента до значений, которые могут произойти.

В моем примере ниже показано логическое целое число и строка, но тот же метод может использоваться с любым типом данных, который может быть сериализован и десериализован в значение «строка».

public partial class MyPage : System.Web.UI.Page 
{ 
    const string 
     hdnFld1Nm = "hdnFld1", 
     hdnFld2Nm = "hdnFld2", 
     hdnFld3Nm = "hdnFld3"; 

    protected bool HiddenFieldValue1 
    { 
     get 
     { 
      object vsVal = this.ViewState["HiddenFieldValue1"]; 
      if (vsVal == null) 
       return false; // Whatever you want the 'default' value to be. 
      else return (bool)vsVal; 
     } 
     set { this.ViewState["HiddenFieldValue1"] = value; } 
    } 
    protected int HiddenFieldValue2 
    { 
     get 
     { 
      object vsVal = this.ViewState["HiddenFieldValue2"]; 
      if (vsVal == null) 
       return -1; // Again, default value. 
      else 
       return (int)vsVal; 
     } 
     set { this.ViewState["HiddenFieldValue2"] = value; } 
    } 
    protected string HiddenFieldValue3 
    { 
     get { return (string)this.ViewState["HiddenFieldValue3"]; } 
     set { this.ViewState["HiddenFieldValue3"] = value; } 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     // For the boolean state, we'll consider any value other than "0" or NULL to be "true". 
     this.HiddenFieldValue1 = (!string.IsNullOrEmpty(this.Request[hdnFld1Nm]) && this.Request.Form[hdnFld1Nm] != "0"); 

     // For the integer, we have to parse from the string value we get from the Form collection, and deal with the potential for "null" if no value was returned. 
     string sHdnVal2 = this.Request.Form[hdnFld2Nm]; 
     int iHdnVal2; 
     if (!string.IsNullOrEmpty(sHdnVal2) && !int.TryParse(sHdnVal2, out iHdnVal2)) 
      this.HiddenFieldValue2 = iHdnVal2; 

     // Getting a string value back is easy. 
     this.HiddenFieldValue3 = this.Request[hdnFld3Nm]; 
    } 
    protected void Page_PreRender(object sender, EventArgs e) 
    { 
     // Before the page actually renders, we want to let the .NET page renderer know that we want these three hidden field values written to the output page. 
     this.Page.ClientScript.RegisterHiddenField(hdnFld1Nm, this.HiddenFieldValue1 ? "1" : "0"); // Make sure you keep your boolean logic the same. 
     this.Page.ClientScript.RegisterHiddenField(hdnFld2Nm, this.HiddenFieldValue2.ToString()); // Hidden fields can only store "string" values, so we have to "ToString" our int. 
     this.Page.ClientScript.RegisterHiddenField(hdnFld3Nm, this.HiddenFieldValue3); 
    } 
} 
Смежные вопросы