![]() | ![]() Products ![]() ![]() ![]() ![]() |
Home » Technical Support » Elevate Web Builder Technical Support » Support Forums » Elevate Web Builder 2 Preview » View Thread |
Messages 1 to 9 of 9 total |
![]() |
Wed, Jun 17 2015 11:58 PM | Permanent Link |
Doug B | I'm trying to integrate the DropZone component (http://www.dropzonejs.com/#create-dropzones-programmatically) into EWB, but I'm having trouble figuring out how to create the external interface correctly.
For example, to match the constructor of the component, do I create the constructor like this? JavaScript: function Dropzone(element, options) { ... } EWB: external Dropzone = class public constructor Create(const element, options: string); end; Also, after I get it instantiated, what element id can I specify in the constructor parameter to match the corresponding EWB element? Do I use the component name property? JS example: // Dropzone class: var myDropzone = new Dropzone("div#myId", { url: "/file/post"}); Finally, how would I implement events to match the component events, so I could create an event handler in my EWB form that matches e.g. the "addedfile" event? JS Example: var myDropzone = new Dropzone("#my-dropzone"); myDropzone.on("addedfile", function(file) { /* Maybe display some more file information on your page */ }); I'm sure if I can get this working, I'll be able to integrate more components like this into EWB, which would be fantastic. Any help with this would be greatly appreciated! Thanks, Doug |
Thu, Jun 18 2015 1:00 PM | Permanent Link |
Doug B | If I have to write this in 100% JavaScript, I will need to know how to get the element type/class selector and id so I can use it to associate the component with my THTMLPage component.
For example: var myDropzone = new Dropzone("div#myId" <---------- HERE , { url: "/file/post"}); How do I do that? Thanks, Doug |
Fri, Jun 19 2015 4:56 AM | Permanent Link |
Matthew Jones | Doug B wrote:
> var myDropzone = new Dropzone("div#myId" <---------- HERE , { url: > "/file/post"}); > > How do I do that? I can't help in the detail, but you have two resources that should answer the question: the framework source, and the browser "inspect element" tool. I managed to work out how to add new form fields using these, and I figure you'd be able to work out what was needed. Tim may have insight, but I suspect he is in the bunker peddling hard to get the product shipped right now. 8-) |
Fri, Jun 19 2015 9:07 AM | Permanent Link |
Raul ![]() | On 6/17/2015 11:58 PM, Doug B wrote:
> I'm trying to integrate the DropZone component (http://www.dropzonejs.com/#create-dropzones-programmatically) into EWB, but I'm having trouble figuring out how to create the external interface correctly. > For example, to match the constructor of the component, do I create the constructor like this? > Also, after I get it instantiated, what element id can I specify in the constructor parameter to match the corresponding EWB element? Do I use the component name property? EWB does not attach any elements ID to any of the components - i'm guessing external javascript library is trying to use getElementById and then attach an eventlistener. This might mess things up in EWB but if you want to try then i can recommend a quick (and very horrible hack) just to see if this would work in principle (i'm sure there is a better way but until we get full docs this is pain to trace down). The DOM element that file picker uses is defined in WebUI.wbs so copy this file (from C:\Program Files (x86)\Elevate Web Builder 2\library) to your project folder. Go find a function "function TFileInputElement.CreateDOMElement: THTMLElement;" and add to the end of it Result.setAttribute(HTML_ATTR_ID,'whatevercustomidyouwant'); Note that this affects all instances of TFileComboBox so need better long term solution. Anyways, you can now call your dropzone and use id "whatevercustomidyouwant". >Finally, how would I implement events to match the component events, so I could create an event handler in my EWB form that matches e.g. the "addedfile" event? > JS Example: > var myDropzone = new Dropzone("#my-dropzone"); > myDropzone.on("addedfile", function(file) { > /* Maybe display some more file information on your page */ > }); > > I'm sure if I can get this working, I'll be able to integrate more components like this into EWB, which would be fantastic. > > Any help with this would be greatly appreciated! In theory it looks like you just need a callback function so i would try just sending that in - basically figure out what the file parameter in function(file) is and then do an EWB function with same signature and use that to register the callback. As i look at this since your goal here is to simply upload the file(s) it might be easier in short term to just use external code for the whole thing - create an external web page (html+js) that does the whole thing and just include a form in EWB app that basically hosts a TBrowser. You would need to do the file upload from external JS as well but it's relatively easy - TServerRequest is a thin wrapper around XMLHttpRequest. I think the file upload area is one Tim can then revise once the EWB2 is out in and expose more of the functionality natively. Raul |
Fri, Jun 19 2015 9:48 AM | Permanent Link |
Raul ![]() | On 6/19/2015 9:07 AM, Raul wrote:
> This might mess things up in EWB but if you want to try then i can > recommend a quick (and very horrible hack) just to see if this would > work in principle (i'm sure there is a better way but until we get full > docs this is pain to trace down). > And here is a a really basic example with a callback function to read a file as text and send it back to ewb (in this case it shows it in multilineedit). Requiers the hack to webui at this time (my element id is called "mycustomfilepicker") : ////////////// ewb code - the whole thing unit main; interface uses WebCore, WebUI, WebForms, WebCtrls, WebEdits; type TForm1 = class(TForm) FileComboBox1: TFileComboBox; MultiLineEdit1: TMultiLineEdit; procedure Form1Create(Sender: TObject); private { Private declarations } procedure FileReadCallback(fileData:String); public { Public declarations } end; //callback function and external file reader listener TFileCallBack = procedure (FileData:string) of object; external procedure AttachFileHandler(s:string); external procedure AttachCallback( f:TFileCallBack); var Form1: TForm1; implementation procedure TForm1.Form1Create(Sender: TObject); begin AttachFileHandler('mycustomfilepicker'); AttachCallback(FileReadCallback); end; procedure TForm1.FileReadCallback(fileData:String); begin MultiLineEdit1.Lines.Add('==== FILE START ===='); MultiLineEdit1.Lines.Add(fileData); MultiLineEdit1.Lines.Add('==== FILE END ===='); end; end. ////////////// ewb code - end and then you also need the external JS file that you add to project as external file. Mine looks like this : ////////////// js code var customCallback = null; function doFileRead(evt) { var files = evt.target.files; for (var i = 0, f; f = files[i]; i++) { var reader = new FileReader(); reader.onload = function(e) { customCallback( reader.result); } reader.readAsText(f); //read as text in this case } } function AttachFileHandler(elemid ) { document.getElementById(elemid).addEventListener('change', doFileRead, false); } function AttachCallback( f ) { customCallback = f; } ////////////// js code end |
Sat, Jun 20 2015 7:05 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. ![]() | Raul,
<< EWB does not attach any elements ID to any of the components >> Correct. The issue is that it is often the case that dynamically-created components in EWB *don't* have a name. Since it isn't possible to establish a unique ID in all cases and EWB doesn't need them/they just take up space, EWB just leaves them out. You can still set them, if you need to, but it requires creating a new (or descendant) component to get access to the DOM element via its TElement wrapper. Tim Young Elevate Software www.elevatesoft.com |
Sat, Jun 20 2015 7:07 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. ![]() | Raul,
<< In theory it looks like you just need a callback function so i would try just sending that in - basically figure out what the file parameter in function(file) is and then do an EWB function with same signature and use that to register the callback. >> Almost forgot: EWB's method creation results in a simple function reference, so EWB methods can always be used wherever a function callback is required. The only difference is the current instance scope used with the function, which is enforced by EWB to be the instance of the method being passed as the callback. Tim Young Elevate Software www.elevatesoft.com |
Sat, Jun 20 2015 7:22 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. ![]() | Doug,
<< I'm sure if I can get this working, I'll be able to integrate more components like this into EWB, which would be fantastic. >> Please keep in mind that using external JS components can sometimes be a problem because: 1) They can cause issues with EWB at runtime if duplicate global variable/object/property identifiers are used. 2) EWB has no knowledge of any DOM elements created by such external JS code, so they can interfere with the operation of EWB at runtime if such elements are inserted into the DOM tree *above* any EWB elements. So, the first choice should always be to use the native APIs directly in EWB, preferably wrapped in a component/control. Tim Young Elevate Software www.elevatesoft.com |
Sun, Jun 21 2015 3:37 PM | Permanent Link |
Raul ![]() | On 6/20/2015 7:05 AM, Tim Young [Elevate Software] wrote:
> You can still set them, if you need to, but it requires creating a new > (or descendant) component to get access to the DOM element via its > TElement wrapper. Thanks. I took another look and there is another small challenge in that the file input (TFileInputElement for which i'd like to set the attribute) is actually a protected member of the TFileComboBox and TFileInputElement itself has TElement as a protected member so i'd need to create 2 descendant classes to do it "properly". Anyways, i cheated and added another public property to the base TElement class (PubDOMElement: THTMLElement read FDOMElement) and now i can just derive a custom TFileComboBox with this : TCustomFileComboBox = class(TFileComboBox) public public procedure setCustomID(newID:string); end; and implementation of : procedure TCustomFileComboBox.setCustomID(newID:string); begin TFileInputElement(GetInputElement).PubDOMElement.setAttribute(HTML_ATTR_ID,newID); end; and the whole setup phase is now : myFileCombo := TCustomFileComboBox.Create(self); //position it as you wish - top/left and layout myFileCombo.setCustomID('CustomFilePickID'); AttachFileHandler('CustomFilePickID'); AttachCallback(FileReadCallback); so a lot cleaner and universal solution. I do think it would be nice to get TElement FDOMElement published as a public property. I guess i could have overwritten the TFileComboBox FInputElement with a custom implementation of TFileInputElement but on surface this looks like a lot more work (to ensure TFileComboBox still properly registers all the FInputElement events and sets its config). Raul |
This web page was last updated on Tuesday, November 28, 2023 at 10:08 AM | Privacy Policy![]() © 2023 Elevate Software, Inc. All Rights Reserved Questions or comments ? ![]() |