2016-05-04 24 views
0

Meine Form verhält sich seltsam. Andere Formen in unserem System verhalten sich gut, aber meins macht einige seltsame Dinge in IE11. Es scheint zu sein, weil einige der Komponenten nicht gut zusammenleben.Platzhaltertext ist editierbar

Meine Frage ist: Wie kann ich aufhören, diese seltsamen Dinge zu tun und warum passieren diese seltsamen Dinge?

Mein Formular zeigt eine Liste der Immobilienverkäufe in einem <table> an. Jeder Verkauf hat seine eigene <tbody> mit ein paar <tr> s drin. Eine der Zellen enthält eine Dateieingabe, die einen Tooltip (von Bootstrap) hat. Ich muss einige der Verkäufe verstecken, wenn das Formular zuerst angezeigt wird, was ich mit display: none oder JQuery .hide() mache. Das Formular verwendet auch Platzhalter und einige "obligatorische Eingabe-Dekoration" (automatisch ein Sternchen neben obligatorischen Eingaben) basierend auf Code aus here.

Durch einen Prozess der Beseitigung, habe ich zwei Dinge gefunden, die die seltsamen Dinge verhindern können: keine der <tr> s mit den Dateieingaben verstecken, und keine obligatorische Eingabe Dekoration verwenden. Leider muss ich beides tun.

Sonderbare Dinge

  1. Initial caret Platzierung: in dem zunächst fokussierte Textfeld (das Adressfeld, die vorgefüllt ist), wird das Caret manchmal zu Beginn des Textes, manchmal am Ende
  2. Editierbare Platzhalter: siehe unten
  3. Tab Titel: der Browser-Tab Text in „Waiting fo klemmt r ...“
  4. Weird-Muster von seltsamen Verhalten: siehe unten

Editierbare Platzhalter

Wenn ich ein Textfeld mit einem Platzhalter klicken, ein normales Verhalten für die caret bei erscheinen die linke Seite des Textfelds mit (in Chrome) dem Platzhaltertext rechts neben dem Einfügemarke oder (in IE11) dem Platzhaltertext. Aber wenn meine Seite wird weirdly in IE11 verhalten, erscheint der Cursor nach dem Platzhalter:

comment box with caret after placeholder

... und kann bearbeitet werden ...

comment box with modified placeholder

Wenn das Formular abgeschickt wird, Jeder aktualisierte Platzhalterinhalt wird nicht übermittelt. Daher besteht die Möglichkeit, dass Nutzer Text eingeben können, von dem sie meinen, dass er gespeichert wird. Dies ist jedoch nicht der Fall.

Der Platzhalter Seltsamkeit ist auch empfindlich: es passiert nur für den ersten Mausklick auf die Seite; Dinge verhalten sich normal mit nachfolgenden Klicks oder Tastatur Tabbing zwischen den Feldern.

Weird-Muster von seltsamen Verhalten

Dinge funktionieren unterschiedlich, je nachdem, was passiert ist, bevor die Seite angezeigt wurde.

Auf der ersten Anzeige können Platzhalter bearbeitet werden. Wenn ich in einen Platzhalter klicke (d. H., Dass die Einfügemarke irgendwo in oder hinter dem Platzhaltertext erscheint), verhält sich die Seite nach der Aktualisierung anders als wenn ich nicht in einen Platzhalter geklickt hätte.

Wenn ich zuerst in einen der Textfelder mit einem Platzhalter klicke und der Platzhalter editierbar ist, dann wird nach F5 das anfänglich fokussierte Textfeld am Anfang mit der Einfügemarke angezeigt. Oder, wenn das anfänglich fokussierte Textfeld das Caret am Anfang hatte und ich nichts mit dem Formular mache, geht das Caret nach F5 wieder zum Start. Wenn das anfänglich fokussierte Textfeld am Ende die Einfügemarke enthält, kann ich den Platzhaltertext meines Kommentarfelds bearbeiten ... Es ist ein wenig verwirrend.

Was ich versucht habe

Wir normalerweise this verwenden, um Platzhalter in älteren Browsern funktionieren. Ich habe versucht, es zu entfernen, aber das macht keinen Unterschied.

Ich habe versucht this script, aber es macht nur das Problem etwas anders: die Caret bewegt sich an den Anfang des Platzhalters, aber es ist noch editierbar.

Ich habe versucht, nicefileinput zu entfernen, aber das machte keinen Unterschied.

Hier ist meine gesamte Form. Das Feld „Kommentar“ erscheint etwa auf halbem Weg nach unten Form

@model OurCompany.Web.ViewModels.OurProductCompleteDesktopSalesComparisonViewModel 
@{ 
    ViewBag.Title = "CompleteDesktopSalesComparison"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
<link rel="stylesheet" href="~/content/css/typeahead.js-bootstrap.css"> 
<script type="text/javascript" src="~/Content/Scripts/DICurrencyInputFormatter.js"></script> 

<section class="container-wrap"> 
<div class="container"> 
    @Html.Partial("~/Views/OurProduct/_CompleteHeaderPartial.cshtml") 
    @using (Html.BeginForm("CompleteDesktopSalesComparison", "OurProduct", FormMethod.Post, new { enctype = "multipart/form-data" })) 
    { 
     @Html.ValidationSummary(false) 
     @Html.AntiForgeryToken() 
     @Html.HiddenFor(m => m.Valuation.OrderNumber) 
     @Html.HiddenFor(m => m.Property.DIPID) 
     @Html.HiddenFor(m => m.Property.FullAddress) 
     @Html.HiddenFor(m => m.Valuation.CategoryCode) 
     @Html.HiddenFor(m => m.Valuation.ValuationTypeCode) 

     @Html.Partial("~/Views/OurProduct/_CompleteNavigationTabsPartial.cshtml") 

     <div class="col-md-10 col-md-offset-1"> 
      <div class="row">&nbsp;</div> 
      <div> 
       @*Sales comparisons==============================================================================*@ 
       @Html.Hidden("saleCount", Model.ComparableSales.Count) 
       <table class="table table-default"> 
        @foreach (var sale in Model.ComparableSales) 
        { 
         var saleIndex = Model.ComparableSales.IndexOf(sale); 
         var isVisible = sale.Visible; 

         var shadedClass = saleIndex % 2 == 0 ? string.Empty : "shaded-rows"; 
         var visibleStyle = isVisible ? string.Empty : "display: none;"; 
         var saleTbodyId = string.Format("saleTbody{0}", saleIndex); 
         var selectedId = string.Format("selected{0}", saleIndex); 
         var visibleId = string.Format("visible{0}", saleIndex); 

         <tbody id="@saleTbodyId" class="@shadedClass" style="@visibleStyle"> 
         @*Address, selected*@ 
         <tr> 
          <td> 
           @Html.HiddenFor(m => m.ComparableSales[saleIndex].Sequence) 
           @Html.HiddenFor(m => m.ComparableSales[saleIndex].Visible, new{ id = visibleId}) 
           Address 
          </td> 
          <td colspan="3"> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].FullAddress, new {@class = "form-control tt-query", style = "width: 100%;", placeholder = "Full address of sale"}) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].FullAddress) 
           @Html.HiddenFor(m => m.ComparableSales[saleIndex].Dipid) 
           <script> 
            $("#[email protected](saleIndex)__FullAddress").on("typeahead:selected typeahead:autocompleted", function(e, datum) { 
             $("#[email protected](saleIndex)__Dipid").val(datum.SearchKey); 
            }) 
           </script> 
          </td> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].Selected)</td> 
          <td> 
           @Html.CheckBoxFor(m => m.ComparableSales[saleIndex].Selected, new { id = selectedId }) 
          </td> 
         </tr> 
         @*Date, Price*@ 
         <tr> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].Date)</td> 
          <td> 
           <span class="di-mandatory-field-container di-mandatory-field-text" style="position: relative;"> 
            @Html.DropDownListFor(m => m.ComparableSales[saleIndex].Date, 
             Model.GetSalesDateListInstance(Model.ComparableSales[saleIndex].Date), 
             new { @class = "form-control" }) 
           </span> 
          </td> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].PriceString)</td> 
          <td> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].PriceString, 
            new { @class = "form-control currency-0-decimals", placeholder = "Sale price" }) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].PriceString) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].Price) 
          </td> 
          <td></td> 
          <td></td> 
         </tr> 
         @*Floor Area, Bedrooms*@ 
         <tr> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].FloorArea)</td> 
          <td> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].FloorArea, 
            new { @class = "form-control", placeholder = "Floor Area" }) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].FloorArea) 
          </td> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].Bedrooms)</td> 
          <td> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].Bedrooms, 
            new { @class = "form-control", placeholder = "Bedrooms" }) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].Bedrooms) 
          </td> 
          <td></td> 
          <td></td> 
         </tr> 
         @*Land Area, Bathrooms*@ 
         <tr> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].LandArea)</td> 
          <td> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].LandArea, 
            new { @class = "form-control", placeholder = "Land Area" }) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].LandArea) 
          </td> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].Bathrooms)</td> 
          <td> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].Bathrooms, 
            new { @class = "form-control", placeholder = "Bathrooms" }) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].Bathrooms) 
          </td> 
          <td></td> 
          <td></td> 
         </tr> 
         @*Comment*@ 
         <tr> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].Comment)</td> 
          <td colspan="5"> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].Comment, 
            new { @class = "form-control", placeholder = "Comments" }) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].Comment) 
          </td> 
         </tr> 
         @*Image*@ 
         <tr> 
          <td> 
           <p>Image</p> 
           <p>(@Html.DisplayFor(m => m.FileExtensionConstraintMessages["VALUATION_REPORT_SALE_IMAGE"]))</p> 
          </td> 
          <td colspan="5"> 
           @if (Model.ComparableSales[saleIndex].Images != null) 
           { 
            foreach (var file in Model.ComparableSales[saleIndex].Images) 
            { 
             <span>@Html.DisplayFor(f => file.FileName) (Created: @Html.DisplayFor(f => file.CreateDate))</span> 
             <a href="@Url.Action("PropertyFile", "Files", new { orderNumber = Model.Valuation.OrderNumber, fileTypeCode = file.FileTypeCode, userFileId = file.Id })"><i class="fa fa-file fa-lg"></i></a> 
             <br/> 
            } 
           } 
           <span data-toggle="tooltip" data-placement="top" title="@Html.DisplayFor(m => m.FileUploadConstraintMessages["VALUATION_REPORT_SALE_IMAGE"])"> 
            <input type="file" name="[email protected](saleIndex)Image"/> 
           </span> 
           @{ var validationMessageKey = String.Format("SaleComparisonImage{0}", saleIndex); } 
           @Html.ValidationMessage(validationMessageKey) 
          </td> 
         </tr> 
         @*Comparability*@ 
         <tr> 
          <td>@Html.DisplayNameFor(m => m.ComparableSales[saleIndex].Comparability)</td> 
          <td colspan="5"> 
           @Html.TextBoxFor(m => m.ComparableSales[saleIndex].Comparability, 
            new { @class = "form-control", placeholder = "Comparability - e.g. Inferior, Comparable, Superior" }) 
           @Html.ValidationMessageFor(m => m.ComparableSales[saleIndex].Comparability) 
          </td> 
         </tr> 
         </tbody> 
        } 
       </table> 

      </div> 
      <div><input id="addSaleButton" type="button" value="Add a sale" class="btn btn-light" /></div> 
     </div> 

     @Html.Partial("~/Views/OurProduct/_CompleteNavigationButtonsPartial.cshtml") 
    } 
    <div class="row">&nbsp;</div> 
</div> 
<div class="push"></div> 
</section> 
<script src="~/Content/scripts/moment.js"></script> 
<script src="~/Content/scripts/bootstrap.min.js"></script> 
<script src="~/content/scripts/jquery.nicefileinput.min.js"></script> 
<script src="~/content/scripts/jquery.placeholder.js"></script> 
<script src="~/content/scripts/typeahead.js"></script> 
<script> 

    $("#addSaleButton").click(function() { 
     var saleCount = $("#saleCount").val(); 
     for (var i = 0; i < saleCount; i++) { 
      var saleTbodyId = "saleTbody" + i; 
      if ($("#" + saleTbodyId + ":hidden").length > 0) { 

       // make the sale visible 
       $("#" + saleTbodyId).show(); 

       // check the Selected checkbox 
       var selectedId = "selected" + i; 
       $("#" + selectedId).prop("checked", true); 

       // set the hidden value to ensure it shows after validation errors 
       var visibleId = "visible" + i; 
       $("#" + visibleId).val("True"); 

       // done one, don't do any more 
       break; 
      } 
     } 
    }); 

    $(".tt-query").typeahead({ 
     name: 'SearchValue', 
     valueKey: 'SearchValue', 
     limit: 20, 
     remote: { 
      url: '/properties/GetAddressSearchValues?partSearchValue=%QUERY' 
     } 
    }); 

    $(document).ready(function() { 
     // tooltips 
     $("span").tooltip({ placement: 'top' }); 

     // custom styling for file input 
     $("input[type=file]").nicefileinput(); 

     // placeholder attribute for old browsers 
     $('input, textarea').placeholder(); 

     $("#ComparableSales_0__FullAddress").focus(); 
    }); 

</script> 

Hier ist die Pflichteingabe Dekoration Js

Datei
// Add a CSS class to mandatory text input fields. 

// see http://www.robertgray.net.au/posts/2012/11/indicating-required-fields-with-twitter-bootstrap-and-aspnet-mvc-4#.VMqY0miUfeo 
function markRequired() { 
    // look at every mandatory field 
    $('input[data-val-required]').each(function() { 

     // not all should be treated 
     if (!$(this).parent().hasClass("input-append") && !(this).hasAttribute("readonly")) { 
      if ($(this).is("input:text")) { 
       $(this).wrap("<div class='di-mandatory-field-container di-mandatory-field-text'>"); 

       //$(this).wrap("<div class='input-group'>"); 
       //$(this).after("<span class='input-group-addon'><i class='fa fa-asterisk required-asterisk'></i></span>"); 
       //$(this).addClass("di-mandatory-field-container"); 
       //$(this).addClass("di-mandatory-field-text"); 
       //$(this).wrap("<span>"); 
      } 
     } 
    }); 
} 

function addFootnote() { 
    var parentForm; 

    // check the form for mandatory class (may be manually- or automatically-added) 
    var firstMandatory = $('.di-mandatory-field-container').first(); 

    // find the form containing that element 
    if (firstMandatory != null) { 
     var parentFinder = firstMandatory[0]; 
     while (parentForm == null && parentFinder != null) { 
      if (parentFinder.tagName.toLowerCase() == "form") { 
       parentForm = parentFinder; 
      } 
      parentFinder = parentFinder.parentNode; 
     } 
    } 

    // add the footnote 
    if (parentForm != null) { 
     var rubric = $('<span>', { text: "denotes a mandatory field", style: "position: absolute;" }) 
      .addClass("di-mandatory-field-footnote"); 
     rubric.appendTo($(parentForm).parent()); 
    } 
} 

$(document).ready(function() { 
    markRequired(); 
    addFootnote(); 
}); 

Antwort

0

Dies ist nur eine halbe Antwort (noch keine Ahnung, warum die Seltsamkeit geschieht), aber jemand finden könnte, das hilft ...

$(document).ready(function() { 
    $("#ComparableSales_0__FullAddress").focus(); 
    $("#selected0").focus(); 
}); 

Aufgrund der genannten „empfindlichen“ Art des Fehlers kann es einfach durch die Fokussierung zweimal getötet werden.