I'm trying to implement a UI that would let the end user upload multiple file sot a server, on a custom UI - pretty much the same way GMail or Outlook.net is doing it.
Few things to node:
The <input type="file"> is ugly - and not standard (IE shows a button named 'Browse' to the left of the file name. Chrome shows a button named 'Choose' to the right of the file name).
Most suggestions how to do the UI suggests hiding a input file element with opacity=0, but on top of by custom UI. The 'click' event will open the dialog box, and upon return the file name (without the path) will be available as a $('#file').val(). See this question, as well as the sample on jsfiddle.
I'm also aware HTML5 has a multiple="multiple" attribute now, which will let the user select multiple files.
However, I'm looking for a multiple file solution, which will work on IE8 and above (as well as WebKit, Mozila).
Some people suggested Google is using Flash. This is not true. Their multi file upload is working when flash is disabled.
Now, here is my biggest surprise: Using the developer tools (F12) on both IE and Chrome, looking at both GMail and Outlook.NET - both implementations do not have a <input type='file'> element in the tree (as far as I can tell). Moreover, both implementations are working with IE8 (flash disabled).
What is going on? How do they do it?
EDIT: Why do I think they don't use file input element? Open the developer tools (F12), switch to Console, type: document.getElementsByTagName('input'). There are 24 input elements, 19 of which are type=hidden, none is type=file.
EDIT 2:Thank you all responders and commentators. Indeed - the "there is no other way" argument (in comment) below was valid. As it turns out, both Outlook.NET and GMail will have a <input type='file'> element, which they will add dynamically, only when the user clicks the 'Attach a file' button. Then, they will send a 'click' event to the element, which will trigger the select file dialog.
The witness this, use the F12 development tool (either in Chrome, or in IE), and in the interactive console type: document.querySelectorAll('input[type=file]'). Note that in both implementations, the element is a direct child of body (with display=none).
They do not use iframe for the upload (unlike the only answer below), but simple XHR code to upload, which is now, in HTML5 is available.
The best resource on the Web for how to do it is: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications. I've went through the steps of #Jay below (which are great), but the Mozilla page is simpler, which is my recommendation. Also, take a quick look at the jsfiddle sample on #Niranjan comment.
I recently implemented a multi file upload UI for an old asp.net website, but the concepts should be the same.
I'm not very good at writing (summarizing code) but here goes.
Create a number of IFrames. I had problems trying to write IFrames after the document loaded due to security restrictions, so had the server render as many as I though the user would use at once.
Add an 'upload' button and handler which first adds a load handler to one of the iframes.
var frame = $('iframe:first');
in the frame load handler ---
frame.load(function () { /* all the code below* /});
2.a. Write the input tag for file and what ever other elements you like into the frame like this
frame.contents().find('body').html("html goes here");
2.b. Now add a handler to the file input in your frame and submit that form:
frame.contents().find('#fileUpload').change( /*submit the form */)
2.c. Now invoke the file upload dialog
frame.contents().find('#fileUpload').click();
2.d. Now that line will block until the dialog returns. When it does you have to check the value of the file upload control for null in case they canceled. This is where i marked the iframe as not in use.
2.e. Ether way you'll need to unbind from the load of the iframe and rebind to a different method that will handle the return (upload complete)
frame.unbind('load');
frame.load(function () { /* handle file uploaded */})
2.e.1. This is where I reported success to the user and released the frame so it could be reused.
2.e.2. Finally unbind from load again from the upload complete method
All of that is in your frame load handler
3.Now cause the frame to load
frame.load();
At least thats how I did it. I uploaded all the files to a handler which reported file % and a loop inside the parent page fired off ajax getting and displaying the progress of each file.
The main idea is if you want multi file upload in an 'ajaxy' style but not using flash or Html 5 you'll need to use a collection of iframes and some fancy script.
Hope this helps.
Related
When you navigate to: blockchain.info
You will notice that if you click view-source on the page, it will show HTML context different than that when you inspect-element. My question is, how are they doing this?
I understand they are using .pug templates from AngularJS framework. But how does my browser know where to read them from if they are not loaded from the client-(browser)-side?
Also, if I was to insert jQuery onto the page, would the jQuery know when the events are triggered on('click', 'submit', 'whatever') etc ...?
When you click View Source, you see what the server sends back. Many pages do not send back a full HTML page, instead some skeleton HTML and add the rest of the functionality via JavaScript
When you Inspect Element, you're viewing the browser's representation of the DOM, which includes any manipulations done via JavaScript. For a visual explanation, see this article on css-tricks: https://css-tricks.com/dom/
Any framework that is rendering HTML client-side (React, Angular, Vue) will do that. The actual source code could literally just be some basic html boilerplate and a div that then gets loaded with an application through something like Javascript. Thus, when you view the source of the page, you're seeing this basic templating. But when inspecting an element, Chrome Dev tools (and others) are inspecting the element that is being rendered client side. Your browser has placed those elements on the DOM, they didn't exist in the source code till the code executed. Hope that helps clear things up.
I'm building a Chrome Extension.
The extension injects some CSS and JavaScript when .html files on the users local drive are loaded in the browser (file:///).
My extension adds an extensive UI to the page that allows the user to modify and manipulate the original source code from their .html file.
The primary purpose of the extension is debugging and QAing HTML email newsletters. Here's just a few things that it does:
Checking links for the appropriate parameters.
Toggling images off and on to simulate popular email clients.
Displaying the source code side-by-side to show a desktop view and multiple mobile sized views.
A function that takes the original HTML and generates a plain text version.
A function that toggles <style> blocks off and on to simulate popular email clients ignoring them.
Email files are backed up via Dropbox and the Dropbox API is integrated to allow for quick sharing right from the email newsletter.
Until now I've been using javascript in my injected content script like this to create all of my menu items.
var debugOrb = document.createElement("div");
debugOrb.id = "borders-orb";
debugOrb.className = "borders-orb orb glyph";
debugOrb.addEventListener("click", toggleBorders, false);
orbsBottom.appendChild(debugOrb);
Here's an extended view of the code I've written to create all of these toggles/menu items: http://pastebin.com/LQTkNhpP
My problem is that now I'm going to be adding a LOT more clickable menu items like this. And it feels like if I do, it's going to get out of hand really quick. Especially since I'll be nesting a lot of divs to make the whole thing look organized and using JavaScript to create lots of text nodes too.
My first thought was what if I could just create my entire menu in regular HTML, then just inject that file into the page with the javascript in my content script. I'm barely intermediate level with JavaScript though. And as I understand it, if I did this, I'd lose my ability to use onclick handlers for all of these divs I'm creating.
Is there an efficient way to handle my goal that I'm not aware of?
Notes:
I'm not using any framework/plugins like React, Angular, or jQuery.
Once the html is added you can always get the element by id and then add an event listener to that element. You can have functions relate to the divs and then onload create the event listeners. element.addEventListener ('click', function);
I have a page with a lots of javascript. However, the page once rendered remains static, there are no moving things or special effects, etc... It should be possible to render the same HTML without any javascript at all using only the plain HTML and CSS. This is exactly what I want - I would like to get a no javascript version of the particular page. Surely, I do not expect any dynamic behavior, so I am OK if buttons are dead, for example. I just want them rendered.
Now, I do not want an image. It needs to be an HTML with CSS, may be embedded with the HTML, which is fine too.
How can I do it?
EDIT
I am sorry, but I must have not been clear. My web site works with javascript and will not work without it. I do not want to check if it works without, I know it will not and I really do not care about it. This is not what I am asking. I am asking about a specific page, which I want to grab as pure HTML + CSS. The fact that its dynamic nature is lost is of no importance.
EDIT2
There is a suggestion to gram the HTML from the DOM inspector. This is what I did the first thing - in Chrome development utils copied as HTML the root html element and saved it to a file. Of course, this does not work, because it continues to reference the CSS files on the web. I guess I should have mentioned that I want it to work from the file system.
Next was to save the page as complete with all the environment using some kind of the Save menu (browser dependent). It saves the page and all the related files forming a closure, which can be open from the file system. But the html has to be manually cleaned up of all the javascript - tedious and error prone.
EDIT3
I seem to keep forgetting things. Images should be preserved, of course.
I have to do a similar task on a semi-regular basis. As yet I haven't found an automated method, but here's my workflow:
Open the page in Google Chrome (I imagine FireFox also has the relevant tools);
"Save Page As" (complete page), rename the html page to something nicer, delete any .js scripts which got downloaded, move everything into a single folder;
On the original page, open the Elements tab (DOM inspector), find and delete any tags which I know cause problems (Facebook "like" buttons for example) (I also try to delete script tags at this stage because it's easier) and copy as HTML (right-click the <html> tag. Paste this into (replace) the downloaded HTML file (remember to keep the DOCTYPE which doesn't get copied;
Search all HTML files for any remaining script sections and delete (also delete any noscript content), and search for on (that's with a space at the start but StackOverflow won't render it) to remove handlers (onload, onclick, etc);
Search for images (src=, url(), find common patterns in image filenames and use regular expressions to replace them globally. So for example src="/images/myimage.png" => |/images/||. This needs to be applied to all HTML and CSS files. Also make sure the CSS files have the correct path (href). While doing this I usually replace all href (links) with #;
Finally open the converted page in a browser (actually I tend to do this early on so that I can see if any change I make causes it to break), use the Console tab to check for 404 errors (images that didn't get downloaded or had a different name) and the Network tab to check if anything is still being loaded from the online version;
For any files which didn't get downloaded I go back to the original page and use the Resources tab to find them and download manually;
(Optional) Cull any content which isn't needed (tracker images/iframes, unused CSS, etc).
It's a big job. I'd love a tool which automated all that, but so far I haven't found one. The pages I download are quite badly made (shops) which have a lot of unusual code, so that's why there are so many steps. You might not need to follow every step.
I am not a coder but, i am able to get my way around code most of the time. However, i found that this is the best place to ask questions relating to code stuff.
I have been working on a website for a client and i am at 95% - the only problem i have is facebook like-box. i have found several tutorials on the web to modify the like box css, and i have implemented most of the recommendations but, i have no favorable results.
Please - stackoverflow help!
I know jquery/javascript is a very powerful language. And facebook like uses javascript iframe/xfbml.
what code would you use, if you were to modify the like box css elements before loading them .
I say load cos i am loading my like box via ".load" ajax. So, when a user clicks the facebook button jquery loads it.
In short: how would i edit a css file on the fly, and then load the edited version afterwards.
thanks
The key problem that you'll have here is that FB's Like button is loaded inside an iframe - a self-contained HTML document within your page (if you use firebug or webkit inspector to inspect the like button, you'll see it's within <body>, <html>, then <iframe>).
The thing about these self-contained pages is that you can't access or manipulate them from the surrounding document (your page). You can change the 'src' attribute (telling the iframe to load a new page), but you can't apply or change styles on the elements inside the page. This is a security limitation that browsers have.
I know that it is possible to have a custom-styled like button, but I don't think it's done with the iframe method.
I am using TinYMce WYSIWYG editor, It is working fine. I am using OpenSource product without MCFileManager, instead files/images are uploaded via TinyBrowser which is included.
Now I need to trigger this pop-up window where I can browse files to upload from element.
Is there any way to do that via upload files?
P.S Maybe there is a way to get that MCFileManager for free or some kind of license?
You can find the available licences and prices here, you won't get it for free (at least not leagaly).
I never used TinyBrowser, but i am sure you could write your own Tinymce plugin and include your own button to trigger the TinyBrowser.