AXForum  
Вернуться   AXForum > Microsoft Dynamics CRM > Dynamics CRM: Blogs
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 15.09.2014, 17:00   #1  
Blog bot is offline
Blog bot
Участник
 
21,283 / 725 (67) +++++++
Регистрация: 28.10.2006


 </p>


Mit Erschrecken musste ich feststellen, dass ich, nun bereits seit mehr als einem halben Jahr, das bloggen hier ein wenig vernachlässigt habe. Wenngleich die Umsetzung des heutigen Themas auch schon ein wenig länger her ist, so ist es meiner Meinung nach trotzdem noch aktuell. Allerdings möchte ich dazu aber noch ein wenig weiter ausholen (war ja so klar!) und einige Jahre zurück gehen:</p>


Es begab sich nämlich zu einer Zeit, vor ungefähr 7-8 Jahren, als ich noch mit der Web-Entwicklung zu tun hatte und mich mehr als regelmäßig über JavaScript ärgern musste (und auch wollte!), so dass ich mir schwor, diese Programmiersprache danach niemals wieder auch nur anzusehen… Ob es nun an meiner vielleicht in dem Punkt beschränkten Sicht auf die Dinge oder “simpel” an der fehlenden Typgebundenheit lag, möchte ich nicht weiter ergünden. Aber: Manchmal – wenn man grauer und hoffentlich auch weiser wird - muss man seine Meinung ändern, Überzeugungen überdenken oder einfach etwas besseres benutzen, ohne die gebotenen Möglichkeiten zu verlieren. </p>
<h3> </h3>
<h3>Die Schritte zur Überzeugung</h3>


Ob nun au den Gefühl heraus, immer das Neuste haben zu müssen oder der Tatsache, dass im Update 2 für Visual Studio 2013 ein Feature Namens “TypeScript” enthalten ist, soll jeder für sich selbst entscheiden. Auf mich jedenfalls passen beide Varianten.</p>


</p>


Wichtig in dem Zusammenhang ist allerdings primär TypeScript: Nutzung der Features von JavaScript, ohne die Probleme von JavaScript.</p>


</p>


Ich werde allerdings nur am Rande auf TypeScript eingehen, wo ich es für sinnvoll erachte. Eigentlich sprechen die eingebundenen Quellcodes bereits Bände. Die Vorteile überwiegen meiner Meinung nach, wenn diese auch in Teilen mit ein klein wenig mehr Arbeit einhergehen, um beispielsweise die Bibliotheken aus dem Microsoft.Dynamics.NAV Namensraum einzubinden. Diese Arbeit habe ich mir nicht gemacht, sondern beschränke mich darauf, für diesen das Typsystem außer Kraft zu setzen (cast nach any). Mehr dazu im angehängten Quellcode.</p>


Rückblickend kann ich sagen, dass die Nutzung von TypeScript in der Tat wesentlich mehr Vor- als Nachteile brachte. Die Syntax muss man sich natürlich zunächst verinnerlichen. Sicherlich ist es dazu auch notwendig, ein wenig in der Bibliothek libd.ts zu stöbern und sich auf der TypeScript Webseite umzuschauen. Aber dann geht einem alles recht schnell von der Hand und bezüglich Typfehlern gibt es keine Probleme mehr. Bevor ich aber wieder ins schwafeln komme, zurück zu Dynamics NAV.</p>
<h3> </h3>
<h3>Alle Clients bedienen</h3>


Mit den obigen Werkzeugen bewaffnet, begebe ich mich in die Welt der Dynamics NAV Control Add-Ins, welche seit Dynamics NAV 2013 R2 auf JavaScript und HTML basieren. Näheres dazu auch unter Extending Any Microsoft Dynamics NAV Client Using Control Add-ins. Wie Sie am Titel der verlinkten Webseite erkennen, können mit dem neuen Konzept sowohl der Windows- als auch der Web Client ein solches Control hosten. Ihnen stehen, unabhängig vom verwendeten Client, nun alle Möglichkeiten offen! Dazu ein Hinweis: Das alte Konzept existiert natürlich weiterhin.</p>


Add-Ins scheinen insgesamt sehr beliebt zu sein. Speziell Drag & Drop Add-Ins schossen vor einiger Zeit wie Pilze aus dem Boden. Was liegt da näher, als genau dieses “klassische Genre” in diesem Post zu bedienen? Die Inspiration holte ich mir auf folgender Webseite: http://html5demos.com/file-api. Es handelt sich dabei um eine simple Implementierung der Browser File API. Diese erlaubt es, eine Bilddatei im Browser fallen zu lassen, läd diese hoch und zeigt sie im Anschluss an. Mit dieser Basis bewaffnet machte ich mich daran, dies auch für Dynamics NAV 2013 R2 umzusetzen.</p>


 </p>
<h3>Butter bei die Fische</h3>


Das Ziel wird sein, per Drag & Drop Dateien im Browser fallenzulassen, diese automatisch auf den Dynamics NAV Server hochzuladen und in einer Tabelle in einem BLOB-Feld zu speichern. Klingt bis dahin recht einfach, ist es aber nicht Als Startpunkt dient für die Control Add-Ins eine Manifest-Datei. Bei dieser handelt es sich um eine XML-Datei, in der alle Informationen zum Add-In zusammengeführt sind. Eine Übersicht dazu finden Sie hier: Manifest Overview.</p>


 </p>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" class="csharpcode"><?xml version=<span class="str">"1.0"</span> encoding=<span class="str">"utf-8"</span>?><Manifest> <Resources> <Script>droparea.js</Script> <StyleSheet>droparea.css</StyleSheet> <Image>BackgroundImage.png</Image> </Resources> <ScriptUrls> <ScriptUrl>http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js</ScriptUrl> </ScriptUrls> <Script> <![CDATA[ $(document).ready(<span class="kwrd">function</span>() { initializeControlAddIn(<span class="str">'controlAddIn'</span>, Microsoft.Dynamics.NAV.GetImageResource(<span class="str">'BackgroundImage.png'</span>)); Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(<span class="str">'ControlAddInReady'</span>, null); }); ]]> </Script> <RequestedHeight>150</RequestedHeight> <RequestedWidth>150</RequestedWidth> <VerticalStretch>true</VerticalStretch> <HorizontalStretch>true</HorizontalStretch></Manifest></pre>
</div>


Die Manifest-Datei ist in mehrere Bereiche unterteilt. Zum einen die Ressourcen (Resources-Tag), in dem Referenzen auf JavaScript-, StyleSheet- und Bilddateien hinterlegt werden. Diese müssen in einer vorgegebenen Struktur innerhalb eines ZIP-Archivs vorliegen. Neben der Manifest.xml selbst, sollten dort die Verzeichnisse Image, Script und StyleSheet enthalten sein. In diesen liegen dann auch die referenzierten Dateien, in diesem Fall droparea.js, droparea.cs und BackgroundImage.png. Bilder müssen übrigens zwingend als PNG-Datei (Portable Network Graphics) vorliegen.</p>


 </p>


</p>


 </p>


Weiterhin enthält die Manifest.xml noch eine Referenz auf JQuery (ScriptUrl) und einen Bereich “Script”, der als Einstiegspunkt für den Aufruf fungiert und zur Initialisierung dient. Alles weitere ist in obigem Link zu finden.</p>


In diesem Fall wird die JavaScript- (bzw. TypeScript-) Funktion initializeControlAddIn aufgerufen, sobald das gesamte HTML-Dokument geladen ist. Diese erhält neben der ID des eigentlichen Add-In (controlAddIn) auch eine Referenz auf ein Bild. Bild-Referenzen werden zur Laufzeit über GetImageResource ermittelt.</p>


 </p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">function</span> initializeControlAddIn(id: <span style="color: #0000ff;">string</span>, imageUrl: <span style="color: #0000ff;">string</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> controlAddIn: HTMLElement = document.getElementById(id);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> imageTag: <span style="color: #0000ff;">string</span> = <span style="color: #006080;">""</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (imageUrl != <span style="color: #006080;">""</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> imageTag = <span style="color: #006080;">'<p class="centeredImage">[img]'</span> + imageUrl + <span style=[/img]'"></p>'</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> controlAddIn.innerHTML =</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #006080;">'<section id="container">'</span> +</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #006080;">'<article>'</span> +</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #006080;">'<p id="status">Not supported</p>'</span> +</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #006080;">'<div id="droparea">'</span> + imageTag + <span style="color: #006080;">'</div>'</span> +</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #006080;">'<div id="progressbar"><div class="percent">0%</div></div>'</span> +</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #006080;">'</article>'</span> +</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #006080;">'</section>'</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> pageLoaded();</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #0000ff;">function</span> pageLoaded() {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> dropArea: HTMLElement = document.getElementById(<span style="color: #006080;">'droparea'</span>);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">typeof</span> (<any>window).FileReader === <span style="color: #006080;">'undefined'</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> updateStatus(<span style="color: #006080;">''</span>, <span style="color: #006080;">'fail'</span>);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> } <span style="color: #0000ff;">else</span> {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> updateStatus(<span style="color: #006080;">'Ready!'</span>, <span style="color: #006080;">'success'</span>);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> dropArea.ondragover = onDragOver;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> dropArea.ondragleave = onDragLeave;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> dropArea.ondragend = onDragEnd;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> dropArea.ondrop = onDrop;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #0000ff;">function</span> onDragOver(e: DragEvent) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.className = <span style="color: #006080;">'hover'</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">function</span> onDragLeave(e: DragEvent) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.className = <span style="color: #006080;">''</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #0000ff;">function</span> onDragEnd(e: DragEvent) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.className = <span style="color: #006080;">''</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">function</span> onDrop(e: DragEvent) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.className = <span style="color: #006080;">'drop'</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> e.preventDefault();</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #008000;">// Reset progress indicator on new file selection.</span></pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> updateProgress(<span style="color: #006080;">''</span>, <span style="color: #006080;">''</span>, 0);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> type: <span style="color: #0000ff;">string</span> = e.dataTransfer.types[0];</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (type === <span style="color: #006080;">"Text"</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> content: <span style="color: #0000ff;">string</span> = e.dataTransfer.getData(type);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> alert(content);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (type === <span style="color: #006080;">"Files"</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> files: FileList = e.dataTransfer.files;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i: number = 0, file: File; file = files[i]; i++) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> upload: Upload = <span style="color: #0000ff;">new</span> Upload(file.name, file);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> uploadQueue.Push(upload);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (!uploadQueue.uploadInProgress) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> uploadQueue.StartSendData();</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.className = <span style="color: #006080;">''</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>
</div>
</div>


 </p>


Demnach wird in der Methode initializeControlAddIn() das Element geholt, ein eventuell übergebenes Bild eingebettet und die DropArea gezeichnet. Gefolgt davon, wird die Methode pageLoaded() aufgerufen, die u.a. prüft, ob der Browser die File API unterstützt und abhängig davon den Status des Add-In setzt. Abschließend werden noch 4 Events registriert, die beim Überfahren mit der Maus das Add-In jeweils farblich anpassen, um dem Benutzer auch visuelles Feedback zu geben.</p>


 </p>


         </p>


Der Upload selbst startet im Event onDrop(). Auf diese Methode möchte ich nun etwas genauer eingehen, da hier alles beginnt…</p>


 </p>
<h3>Los geht’s</h3>


Im Fall, dass Datei(en) fallen gelassen werden, lautet e.dataTransfer.types[0] == “Files”. In dem Fall wird für jede der Dateien ein neues Objekt von Typ Upload() erzeugt und dieses dem definierten uploadQueue() hinzugefügt. Handelt es sich dabei um den ersten Upload bzw. ist noch kein Upload im Gange, dann wird per uploadQueue.StartSendData() die Übertragung gestartet.</p>


 </p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">StartSendData() {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.uploadQueue.length > 0) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.uploadInProgress = <span style="color: #0000ff;">true</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> upload: Upload = <span style="color: #0000ff;">this</span>.uploadQueue[0];</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> updateStatus(upload.name + <span style="color: #006080;">' ('</span> + <span style="color: #0000ff;">this</span>.uploadQueue.length + <span style="color: #006080;">')'</span>, <span style="color: #006080;">'success'</span>);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> reader: FileReader = <span style="color: #0000ff;">new</span> FileReader();</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #008000;">// Save file and upload reference for use in events</span></pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> (<any>reader).upload = upload;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> reader.onabort = <span style="color: #0000ff;">function</span> (<span style="color: #0000ff;">event</span>: any) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> alert(<span style="color: #006080;">'File read cancelled'</span>);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> };</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> reader.onloadstart = <span style="color: #0000ff;">function</span> (<span style="color: #0000ff;">event</span>: any) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> updateProgress(<span style="color: #006080;">'Loading'</span>, <span style="color: #006080;">'loading'</span>, -1);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> };</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> reader.onprogress = <span style="color: #0000ff;">function</span> (<span style="color: #0000ff;">event</span>: ProgressEvent) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">event</span>.lengthComputable) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> percentLoaded: number = Math.round((<span style="color: #0000ff;">event</span>.loaded / <span style="color: #0000ff;">event</span>.total) * 100);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (percentLoaded < 100) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> updateProgress(<span style="color: #006080;">'Loading'</span>, <span style="color: #006080;">'loading'</span>, percentLoaded);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> reader.onloadend = <span style="color: #0000ff;">function</span> (<span style="color: #0000ff;">event</span>: ProgressEvent) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> data: <span style="color: #0000ff;">string</span> = (<any><span style="color: #0000ff;">event</span>.target).result;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (data != <span style="color: #0000ff;">null</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.upload.data = data;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.upload.length = data.length;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.upload.totalLength = data.length;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #008000;">// Ensure that the progress bar displays 100% at the end.</span></pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> updateProgress(<span style="color: #006080;">''</span>, <span style="color: #006080;">''</span>, 100);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(<span style="color: #006080;">'FileDropBegin'</span>, [<span style="color: #0000ff;">this</span>.upload.name]);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> reader.onload = <span style="color: #0000ff;">function</span> (<span style="color: #0000ff;">event</span>: any) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> };</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> reader.readAsDataURL(upload.file);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">else</span> {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.uploadInProgress = <span style="color: #0000ff;">false</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> updateStatus(<span style="color: #006080;">'Ready!'</span>, <span style="color: #006080;">'success'</span>);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>
</div>
</div>


 </p>


Nach dem Start wird natürlich zunächst geprüft, ob der uploadQueue überhaupt etwas zur Übertragung enthält. Ist dies der Fall, wird dies notiert (uploadInProgress = true), das erste Upload-Objekt gelesen und der Status des Controls aktualisiert. Zum eigentlichen Lesen der Dateien fungiert der FileReader(). Für die erzeugte Instanz werden (inline) die Events onabort, onloadstart, onprogress und onload definiert, die primär zur Aktualisierung der Oberfläche dienen. Das onloadend-Event selbst kümmert sich um den eigentlichen Upload. Nachdem der FileReader per reader.readAsDataURL() ausgeführt wurde, wird nach dem vollständigen Upload das onloadend-Event ausgeführt und es werden die eigentlichen Daten und auch die Länge der Daten ermittelt. Um diese Daten dann auch an Dynamics NAV zu schicken, wird InvokeExtensibilityMethod() aufgerufen. Diese Methode ist der “direkte” Rückweg zum Aufruf von Dynamics NAV-Funktionen im C/AL auf dem Server. “Direkt” steht hier in Anführungszeichen, da alle Erweiterungsmethoden jeweils asynchron verarbeitet werden.</p>


Dazu aber später mehr. An dieser Stelle ist es notwendig, dass wir die Erläuterungen kurz unterbrechen, und klären, wie genau denn im C/AL die Erweiterungsmethoden definiert werden und wie auch die Entwicklungsumgebung davon Wind bekommt. Denn diese, wie Sie sich sicherlich denken, hat mit HTML5 und JavaScript nicht wirklich viel am Hut </p>


 </p>
<h3>Wie sag ich’s meiner Entwicklungsumgebung – Schnittstellendefinition</h3>


Die Antwort: Wie damals. Wobei “damals” dann hier Dynamics NAV 2013 meint. Es wird ein Interface definiert, in dem alle im eigentlichen JavaScript-Add-In definierten Methoden und Events beschrieben sind. Die Implementierung finden Sie im Projekt in der Datei ControlAddIn.cs.</p>


 </p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #008000;">// Name: DropAreaControl</span></pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #008000;">// Token: b33780e0a1cf8256</span></pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">using</span> System;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #0000ff;">using</span> System.Collections.Generic;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">using</span> System.Linq;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #0000ff;">using</span> System.Text;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">using</span> Microsoft.Dynamics.Framework.UI.Extensibility;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"><span style="color: #0000ff;">namespace</span> DropAreaControlAddIn</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">{</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">delegate</span> <span style="color: #0000ff;">void</span> FileDropBeginEventHandler(<span style="color: #0000ff;">string</span> filename);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">delegate</span> <span style="color: #0000ff;">void</span> FileDropEventHandler(<span style="color: #0000ff;">string</span> data);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">delegate</span> <span style="color: #0000ff;">void</span> FileDropEndEventHandler();</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> [ControlAddInExport(<span style="color: #006080;">"DropAreaControl"</span>)]</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">interface</span> IDropAreaControlAddIn</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> [ApplicationVisible]</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">event</span> ApplicationEventHandler ControlAddInReady;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> [ApplicationVisible]</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">event</span> FileDropBeginEventHandler FileDropBegin;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> [ApplicationVisible]</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">event</span> FileDropEventHandler FileDrop;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> [ApplicationVisible]</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">event</span> FileDropEndEventHandler FileDropEnd;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> [ApplicationVisible]</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">string</span> ReadyForData(<span style="color: #0000ff;">string</span> filename);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>
</div>
</div>


 </p>


Das Interface beschreibt die in JavaScript implementierten Methoden (ReadyForData()) und alle im C/AL zu nutzenden Events. Und genau diese Events sind es, die Sie bei Nutzung der Methode InvokeExtensibilityMethod() dann aus dem Web auf dem Dynamics NAV Server aufrufen.</p>


 </p>


</p>


 </p>
<h3>Weiter geht’s</h3>


Und hier ist es wichtig sich bewusst zu sein, dass die Events im Dynamics NAV (also FileDropBegin(), FileDrop() und FileDropEnd()) asynchron aufgerufen werden! Und genau hier, und jetzt fahre ich mit meiner Erläuterung zu InvokeExtensibilityMethod('FileDropBegin', [this.upload.name]) fort, kann es spannend werden, wenn die Datei, welche Sie fallengelassen haben, etwas größer als sehr wenige KB ist. Gehen wir davon aus, dass die Datei 5 MB groß ist und Sie alle Daten, gerne schön in kleineren Häppchen, auf den Server übertragen. Senden, senden, senden, senden…</p>


Und dabei kommt es zum Problem, da dann zu viele Daten vom Browser, über den Web Client (auf dem Internet Information Server) an den Dynamics NAV Server übertragen werden sollen. Es ist aufgrund der Asynchronität aber nicht zwingend so, dass diese Daten auch in Echtzeit verarbeitet und gesendet werden. Dabei kann es dann passieren, dass es letztendlich an einer Stelle einfach “überläuft”.</p>


Dabei fällt mir eine meiner Lieblingsszenen aus “Das Boot” ein: “Irgendwann is’ natürlich Schluss. Das is’ klar. Hält der Druckkörper nich’ mehr. Dann wird das Boot - vom Wasserdruck - zerquetscht.”. Nicht so bildlich vielleicht, aber genau das passiert in den Fall. Es gilt also sicherzustellen, dass wir die folgende Daten erst senden, sobald die vorhergehenden Daten vom Dynamics NAV Server erfolgreich verarbeitet wurden.</p>


Deshalb wird das C/AL-Event DropArea::FileDropBegin(filename : Text) nur einmalig aufgerufen und an dieser Stelle auch nur der Dateiname gespeichert. Daraufhin wird in den Client (JavaScript) per ReadyForData() zurückgerufen, um zu Signalisieren, dass der Server für weitere Datenpakete bereit ist. Der Name wird im JavaScript verwendet, um den korrekten Upload zu ermitteln.</p>


 </p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">ReadyForData(name: <span style="color: #0000ff;">string</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> upload: Upload = <span style="color: #0000ff;">this</span>.FindUpload(name);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (upload != <span style="color: #0000ff;">null</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (upload.length > 0) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> currentLength: number = (upload.length > 16384) ? 16384 : upload.length;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.currentData = upload.data.substr(0, currentLength);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> upload.data = (upload.length > currentLength) ? upload.data.substr(currentLength) : <span style="color: #006080;">""</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> upload.length -= currentLength;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">var</span> percentUploaded: number = Math.round(((upload.totalLength - upload.length) / upload.totalLength) * 100);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> updateProgress(<span style="color: #006080;">'Uploading'</span>, <span style="color: #006080;">'loading'</span>, percentUploaded);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> setTimeout(<span style="color: #006080;">"uploadQueue.SendData();"</span>, 10);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">return</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.currentData = <span style="color: #0000ff;">null</span>;</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.RemoveUpload(name);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> updateProgress(<span style="color: #006080;">''</span>, <span style="color: #006080;">''</span>, 0);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> </pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> setTimeout(<span style="color: #006080;">"uploadQueue.SendData();"</span>, 10);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>
</div>
</div>


 </p>


Wird dieser gefunden (FindUpload()), dann werden die nächsten 16 KB der zum Upload anstehenden Datei ermittelt und uploadQueue.SendData() erneut aufgerufen. Allerdings nicht direkt, sondern indirekt über setTimeout(), also mit einer Verzögerung von 10 Millisekunden. Aber warum? Wir müssen den Aufruf entkoppeln, damit ReadyForData() Gelegenheit hat, wieder zum Aufrufer Dynamics NAV zurückzukehren. Ansonsten könnte es (bzw. wird es) eine Aufrufkette geben, FileDropBegin() (NAV) –> ReadyForData() (JS) –> SendData() (JS) –> FileDrop() (NAV), die wiederum unerwünschte Effekte auslösen kann. Durch setTimeout() wird also entkoppelt, ReadyForData() kehrt zurück und beendet sich und einige Millisekunden später wird, ausgelöst/getriggert vom JavaScript, SendData() aufgerufen, welches wiederum das aktuelle Datenpaket von max. 16 KB Größe an Dynamics NAV sendet.</p>


 </p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">
<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">SendData() {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.currentData != <span style="color: #0000ff;">null</span>) {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(<span style="color: #006080;">'FileDrop'</span>, [<span style="color: #0000ff;">this</span>.currentData]);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">else</span> {</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(<span style="color: #006080;">'FileDropEnd'</span>, <span style="color: #0000ff;">null</span>);</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;"> <span style="color: #0000ff;">this</span>.StartSendData();</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> }</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;">}</pre>

<pre style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"> </pre>
</div>
</div>


 </p>


Das geschieht so lange, wie noch Daten vorhanden sind, also currentData != null ist. Eine 160 KB große Datei führt demnach zu 10 Aufrufen von SendData(), bis letztendlich die Methode bzw. das Dynamics NAV Event FileDropEnd() aufgerufen wird, welches die Dekodierung der empfangenen Daten und die weitere Verarbeitung durchführt. Während der Übertragung werden die ankommenden Daten in eine DotNet Variable vom Typ MemoryStream (FromMemoryStream) geschrieben. Dieser wurde beim Aufruf von FileDropBegin() geöffnet und bekommt bei jedem Aufruf die gesendeten Textdaten, gewandelt in ein Byte[]-Array angehängt. Die gesendeten Daten enthalten am Anfang einen kurzen Header der mit “data:” beginnt, welcher in der Funktion FileDrop() geprüft und eventuell herausgefiltert wird.</p>


 </p>


</p>


Nachdem die Datei komplett übertragen ist und von JavaScript aus, im Dynamics NAV dann das Event FileDropEnd() aufgerufen wird, werden alle bisher im FromMemoryStream gespeicherten Daten Base64-Dekodiert in eine neue MemoryStream-Variable namens ToMemoryStream geschrieben. Die eigentliche Dekodierung geschieht dabei in der C/AL-Funktion Base64Decode(). FileDropEnd() letztendlich, speichert den dekodierten binären Datenstrom in einem BLOB-Feld der Tabelle Drop Area File und räumt danach ein wenig auf.</p>


Voila! Von der lokalen Festplatte, über den Browser, gesendet an den Internet Information Server (Web Client), weitergeleitet an den Dynamics NAV Server, landet die übertragene Datei letztendlich in den Untiefen einer SQL Server Datenbank. Beinahe wie von Geisterhand </p>


 </p>
<h3>Ich will selber ran</h3>


Den kompletten Quellcode inkl. Dynamics NAV-Objekten und dem Visual Studio 2013-Solution habe ich an diesen Beitrag angehängt.</p>


</p>


Die Solution besteht aus zwei Teilen. Zum Einen das Projekt "ControlAddIn", welche auch die TypeScript-Datei (.ts) enthält. Diese wird beim kompilieren in eine JavaScript-Datei (.js) umgewandelt. Weiterhin der C#-Teil (DropAreaControlAddIn), aus welchem die DLL hervorgeht, die dann das Interface für die Entwicklungsumgebung enthält.</p>


 </p>


Um alles zu testen, entpacken Sie bitte das Archiv in ein Verzeichnis Ihrer Wahl. Zur simplen Installation, gehen Sie dann bitte wie in den folgenden Punkten beschrieben vor:</p>
<ul>[*]Kopieren Sie die Datei DropAreaControlAddInbinDebugDropAreaControlAddIn.dll in das Verzeichnis C:Program Files (x86)Microsoft Dynamics NAV71RoleTailored ClientAdd-ins oder alternativ in ein dort angelegtes neues Unterverzeichnis. Diese DLL enthält das oben beschriebene Interface, um die Funktionen und Events in der Dynamics NAV Entwicklungsumgebung verfügbar zu machen. Danach muss die finsql.exe neu gestartet werden.[*]Markieren Sie alle Verzeichnisse und die Datei Manifest.xml in Verzeichnis ControlAddInAddIn. Erstellen Sie dann (beispielsweise über “Senden an”) ein neues ZIP-Archiv.[*]Öffnen Sie Dynamics NAV 2013 R2, suchen Sie nach “Steuerelement-Add-Ins” und tragen Sie die folgenden Daten ein:
<ul>[*]Name: DropAreaControl[*]Token: b33780e0a1cf8256[*]Klicken Sie auf die Action “Importieren”, um die erstellte Archivdatei mit dem Add-in zu importieren.[/list][*]In der neu gestarteten Entwicklungsumgebung, öffnen Sie den Object Designer und importieren die Datei DropAreaControlAddInObjects.fob oder DropAreaControlAddInObjects.txt.[*]Kompilieren Sie danach alle Objekte mit der Version “DropArea”.[/list]

Aus dem Object Designer der Entwicklungsumgebung, starten Sie nun die Page 50001 “Drop Area Files”. Alternativ öffnen Sie den Web Client: http://serverort/DynamicsNAV71/WebClient/List.aspx?company=CRONUS%20AG&mode=View&page=50001</p>


Ich wünsche Ihnen viel Spaß mit der Implementierung und hoffe auf interessante Weiterentwicklungen!</p>


 </p>


Carsten Scholling </p>


Microsoft Dynamics Germany Microsoft Global Business Support (GBS) EMEA</p>


Microsoft Connect: http://connect.microsoft.com Online Support: http://www.microsoft.com/support Sicherheitsupdates: http://www.microsoft.de/sicherheit</p>


Microsoft Deutschland GmbH Konrad-Zuse-Straße 1 D-85716 Unterschleißheim http://www.microsoft.de</p><div style="clear:both;"></div>Далее
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 00:26.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.