WymaganiaPrzesyłanie pliku na serwer automatycznie wewnątrz panelu aktualizacji nie działa po raz pierwszy
Próbuję przesłać plik, tak szybko, jak użytkownik wybierze ją. Muszę spełnić następujące wymagania:
- Przycisk wygląda jak inne przyciski w aplikacji.
- Plik zostanie przesłany, gdy tylko użytkownik go wybierze.
- Potrzebuję go w UpdatePanel, ponieważ muszę wprowadzić warunkowe aktualizacje strony. I CAN zrobić pełny odświeżenie na wybranym pliku (a.k.a
onchange
) wydarzenie.
Aktualny kod
obserwuję to, jak wygląda mój plik widok:
<asp:UpdatePanel ID="upData" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<div style="width: auto; float: right;">
<asp:Button ID="btnFileImportSkin" CssClass="ButtonSkin AddButton" Text="Import" Style="position: absolute; z-index: 2;" runat="server" OnClientClick="Javascript:onImport(); return false;" />
<asp:FileUpload ID="fileImport" Visible="false" Style="position:relative; opacity:0;" runat="server" onchange="Javascript:onFileSelected();" />
<%-- onchange="Javascript:this.form.submit();" /> --%>
<%-- <asp:Button ID="btnUpload" runat="server" OnClientClick="Javascript:alert('Uploading...'); __doPostBack('<%= btnUpload.ID %>', ''); return false;" /> --%>
<asp:Button ID="btnUpload" OnClick="btnUpload_Click" runat="server" />
</div>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnUpload" />
</Triggers>
</asp:UpdatePanel>
Stosowna Javascript:
<script type="text/javascript">
function onImport() {
var fileImportClientId = '<%= fileImport.ClientID %>';
document.getElementById(fileImportClientId).click();
}
function onFileSelected() {
alert("File Selected");
// I have tried calling the function directly and with a timeout
setTimeout(onUpload, 20);
}
function onUpload() {
var btnUploadClientId = '<%= btnUpload.ClientID %>';
document.getElementById(btnUploadClientId).click();
}
</script>
Kod za:
protected void btnUpload_Click(object sender, EventArgs e)
{
// PostedFile is null first time code gets here on user selecting a file
if (fileImport.PostedFile != null)
{
if (fileImport.PostedFile.FileName.Length > 0)
{
ImportFromFile();
}
}
}
Wyjaśnienie/Przepływ
- Użytkownik klika
btnFileImportSkin
przycisku. - Wywoływana jest funkcja
onImport
, która programowo klika przyciskfileimport
. - Użytkownik wybiera plik i naciska Otwórz.
onFileSelected
jest wywołana.onUpload
nazywa się pomyślnie.btnUpload_Click
nazywa się pomyślnie za każdym razem.
JednakProblem że
fileImport.PostedFile jest null pierwszy użytkownik czas wybiera plik. Wszystko działa dobrze po raz drugi i od tego momentu.
pokrewne
This question jest ściśle związane z moim problemem, ale PO prawdopodobnie chciał rozwiązanie wysyłania Async jak w Gmailu. Próbowałem już w następujący sposób, jak w odpowiedzi na to pytanie:
- __doPostBack() w OnClientClick przypadku
btnUpload
- this.form.submit() onChange przypadku mojego
FileUpload
kontrolą. - Ustawianie onchange atrybutu
FileUpload
kontroli w Page_PreRender
uwagi dodatkowe
- To coś działało idealnie, kiedy nie mają panele aktualizacji. Robiłem this.form.submit() bezpośrednio w zdarzeniu onchange o wartości
FileUpload
. - ramy docelowa jest .NET 4,0
UWAGA: Dodano Visible = "false" w FileUpload
kontroli powyżej. To był problem, ale zignorowałem go, zadając pytanie.
Zarówno html, jak i javascript znajdują się w formancie użytkownika. –
Czy jesteś pewien, że działa po raz pierwszy? Działa to również dla mnie, gdy po raz drugi klikam 'btnFileImportSkin'. –
Tak, jestem, 110%. :) Klikam przycisk tylko raz, a kod trafia w punkt przerwania za pierwszym razem, za każdym razem. – BeeTee2