javascript - Förhindra att jQuery UI-dialog sätter fokus på den första textrutan
Jag har ställt in en jQuery UI-modaldialog som visas när en användare klickar på en länk. Det finns två textrutor (jag visar bara koden för en av dem för korthetens skull) i den dialogdiv-taggen och den ändras till en jQuery UI DatePicker-textruta som reagerar vid fokus.
Problemet är att jQuery UI-dialogen ('open') på något sätt gör att den första textrutan får fokus, vilket sedan gör att datumväljarkalendern öppnas omedelbart.
Så jag letar efter ett sätt att förhindra att fokus sker automatiskt.
<div><a id="lnkAddReservation" href="#">Add reservation</a></div>
<div id="divNewReservation" style="display:none" title="Add reservation">
<table>
<tr>
<th><asp:Label AssociatedControlID="txtStartDate" runat="server" Text="Start date" /></th>
<td>
<asp:TextBox ID="txtStartDate" runat="server" CssClass="datepicker" />
</td>
</tr>
</table>
<div>
<asp:Button ID="btnAddReservation" runat="server" OnClick="btnAddReservation_Click" Text="Add reservation" />
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var dlg = $('#divNewReservation');
$('.datepicker').datepicker({ duration: '' });
dlg.dialog({ autoOpen:false, modal: true, width:400 });
$('#lnkAddReservation').click(function() { dlg.dialog('open'); return false; });
dlg.parent().appendTo(jQuery("form:first"));
});
</script>
Svar #1
Lägg till ett dolt span ovanför det, använd ui-helper-hidden-accessible för att göra det dolt med absolut positionering. Jag vet att du har den klassen eftersom du använder dialog från jquery-ui och det finns i jquery-ui.
<span class="ui-helper-hidden-accessible"><input type="text"/></span>
Svar #2
jQuery UI 1.10.0 ändringslogg listar ärende 4731 som åtgärdat.
Det verkar som att focusSelector inte implementerades, men en kaskadsökning efter olika element användes istället. Från ärendet:
Förläng autofokus, börja med [autofokus], sedan :tabbable innehåll, sedan knappanel, sedan stängningsknapp, sedan dialog
Så, markera ett element med attributet autofocus och det är det elementet som ska få fokus:
<input autofocus>
I dokumentationen förklaras fokuslogiken (precis under innehållsförteckningen, under titeln 'Fokus'):
När en dialog öppnas flyttas fokus automatiskt till det första objektet som matchar följande:
- Det första elementet i dialogen med attributet
autofocus- Det första
:tabbable-elementet inom dialogens innehåll- Det första
:tabbable-elementet inom dialogrutans knappfält- Dialogrutans stängningsknapp
- Själva dialogen
Svar #3
I jQuery UI >= 1.10.2 kan du ersätta _focusTabbable-prototypmetoden med en placebofunktion:
$.ui.dialog.prototype._focusTabbable = $.noop;
Fiol
Detta kommer att påverka alla dialog-rutor på sidan utan att du behöver redigera varje enskild manuellt.
Den ursprungliga funktionen gör inget annat än att sätta fokus på det första elementet med autofocus-attribut/tabbable-element/eller som en återfallslösning på själva dialogen. Eftersom dess användning bara är att sätta fokus på ett element, bör det inte vara något problem att ersätta det med en noop.
Svar #4
Från och med jQuery UI 1.10.0 kan du välja vilket inmatningselement som ska fokuseras på genom att använda HTML5-attributet autofocus.
Allt du behöver göra är att skapa ett dummyelement som din första inmatning i dialogrutan. Det kommer att ta upp fokus åt dig.
<input type="hidden" autofocus="autofocus" />
Detta har testats i Chrome, Firefox och Internet Explorer (alla senaste versioner) den 7 februari 2013.
http://jqueryui.com/upgrade-guide/1.10/#added-ability-to-specify-which-element-to-focus-on-open
Svar #5
Jag hittade följande kod för jQuery UI-dialogfunktionen för att öppna.
c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();
Du kan antingen kringgå jQuery-beteendet eller ändra beteendet.
tabindex -1 fungerar som en lösning.
Svar #6
Jag kom just på det här medan jag lekte omkring.
Jag upptäckte att med dessa lösningar för att ta bort fokus slutade ESC-tangenten att fungera (dvs stänga dialogrutan) när man först gick in i dialogrutan.
Om dialogrutan öppnas och du omedelbart trycker på ESC, kommer den inte att stänga dialogrutan (om du har det aktiverat), eftersom fokus ligger på något gömt fält eller liknande, och den får inga tangenttryckningshändelser.
Sättet jag fixade det på var att lägga till detta i öppna-händelsen för att ta bort fokus från det första fältet istället:
$('#myDialog').dialog({
open: function(event,ui) {
$(this).parent().focus();
}
});
Detta sätter fokus på dialogrutan, som inte är synlig, och sedan fungerar ESC-tangenten.
Svar #7
Ställ in tabbindex för inmatningen till -1, och sedan ställ in dialog.open för att återställa tabbindex om du behöver det senare:
$(function() {
$( "#dialog-message" ).dialog({
modal: true,
width: 500,
autoOpen: false,
resizable: false,
open: function()
{
$( "#datepicker1" ).attr("tabindex","1");
$( "#datepicker2" ).attr("tabindex","2");
}
});
});
Svar #8
Min tillfälliga lösning:
open: function(){
jQuery('input:first').blur();
jQuery('#ui-datepicker-div').hide();
},
