Jump to content


Photo

Support for drag & drop, multiple file selects and instant uploads in file field


  • Please log in to reply
132 replies to this topic

#1 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 27 August 2011 - 05:13 PM

I am working on few nice html5 features (see topic). I started these as a separate module, but soon realized that these are something that are probably always welcome. Or that is what I think at least, how about you guys? It would be easier and probably cleaner result if I just modify the core files in this (with keeping it 100% backwards compatible).

I am going with html5 way here, so good support is in Firefox 6+. latest Chrome and upcoming IE10. HTML5 File API looks wonderful and this shouldn't require too much code. Actually there is one liner which makes file fields so much faster to use:

$this->setAttribute('multiple', 'multiple');
If you add that to line 32 in your InputfieldFile.module then supported browsers will allow you to choose multiple files at once. It works without any other changes to anywhere. And shouldn't cause any problems for older browsers, since it is just a new attribute in file input field.

I'm on very early steps on this, but if Ryan gives a green light and there is no good reason to keep these features out of the core, I will do these right into core InputfieldFile instead of extending that.

#2 Soma

Soma

    Hero Member

  • Moderators
  • 3,404 posts
  • 1935

  • LocationSH, Switzerland

Posted 27 August 2011 - 05:21 PM

Recently thought about similar things that could be done with new html5 and the like :)

Now that we have the file api, wouldn't it then be possible to see a preview thumb of a selected file in the page edit before saving the page?

@somartist | modules created | support me, flattr my work flattr.com


#3 Pete

Pete

    Administrator

  • Administrators
  • 1,802 posts
  • 727

  • LocationChester, England

Posted 27 August 2011 - 05:39 PM

Nice ideas, especially since it sounds like it just degrades gracefully on older browsers.

#4 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 27 August 2011 - 05:48 PM

Now that we have the file api, wouldn't it then be possible to see a preview thumb of a selected file in the page edit before saving the page?


Yep. Also possible to disallow uploading too big files right there and add cropping to images etc.

#5 Pete

Pete

    Administrator

  • Administrators
  • 1,802 posts
  • 727

  • LocationChester, England

Posted 28 August 2011 - 03:14 AM

Wow!

And it's taken them this long to roll HTML5 out because...?

Seriously, if we'd had the file API about 5 years ago so many of my projects would have been so much simpler ;)

#6 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 28 August 2011 - 04:24 AM

Yep. There isn't cropping in file api, but because you can read chosen files with javascript, you can display them, add cropping and do resizing etc before uploading the files.

#7 Pete

Pete

    Administrator

  • Administrators
  • 1,802 posts
  • 727

  • LocationChester, England

Posted 28 August 2011 - 05:01 AM

Wow. There's the majority of the need for Flash/Java uploaders gone for good :)

On sites where I'd be creating forms for other admins to use on one of my sites I would probably speciify that they have to update their browsers to use the CMS. It will obviously be a few years before the majority of folks have updated to a HTML5-compatible browser however I'm looking forward to using some of these features down the line to make life easier.

In fact, I'm sure I saw a jQuery-based upload script a few weeks back (before my laptop died :() that used HTML5, fell back to Flash if your browser didn't support it and fell back to doing things the old-fashioned way if you didn't have either. That one was just for uploads, but one that was just HTML5 that might be good for getting ideas from is mentioned previously here: http://processwire.c...opic,351.0.html

#8 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 28 August 2011 - 09:09 AM

Definitely green light, as you say. Any improvements in this area are certainly welcome. If it's something that is pretty universal then of course makes sense in the core. I am excited about the possibilities here.

#9 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 28 August 2011 - 02:12 PM

I started working on this and got pretty good start. Multiple selections and drag & drop already works (first thought that as "nice demo" feature, but it feels very nice in use). Next I want to add instant uploads. But that requires some url where js can post those files. What would be best solution here? Probably something like: /processwire/page/upload/?id=5839 (that would only manage ajax file uploads).

Ryan, any tips on this?

EDIT: I ProcessPageUpload looks like a good and simple solution here, will try that.

#10 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 29 August 2011 - 07:35 AM

Started developing own ProcessPageEditAjaxUpload, but it is so closely what InputfieldFile does, so started to thinking about better method. There is great way to create formdata on the fly with html5, so I could recreate the post with just the one new image and post that to regular page edit page. So far no luck with that. That would still be the best way, since it would allow all the features like the regular page save, so ajax uploads couldn't mess things up.

What stuff the page save form expects to be posted? All the fields or only few + submit_save? How it checks that it is valid post?

#11 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 29 August 2011 - 08:15 AM

Hmm.. getting closer. There is post fields that very simple page edit posts:

------WebKitFormBoundaryttJCZBXTR2dQmoZt
Content-Disposition: form-data; name="name"

grillipaikka
------WebKitFormBoundaryttJCZBXTR2dQmoZt
Content-Disposition: form-data; name="parent_id"

5817
------WebKitFormBoundaryttJCZBXTR2dQmoZt
Content-Disposition: form-data; name="template"

50
------WebKitFormBoundaryttJCZBXTR2dQmoZt
Content-Disposition: form-data; name="sortfield"

sort
------WebKitFormBoundaryttJCZBXTR2dQmoZt
Content-Disposition: form-data; name="title"

Grillipaikka
------WebKitFormBoundaryttJCZBXTR2dQmoZt
Content-Disposition: form-data; name="submit_save"

Save Page
------WebKitFormBoundaryttJCZBXTR2dQmoZt
Content-Disposition: form-data; name="id"

5819
------WebKitFormBoundaryttJCZBXTR2dQmoZt--

***

So it must be that I don't have parent_id, template etc? Didn't find the place where to check which of those (if all?) are required? Or are those just the same than when working from api?

(I'll work at the same time and throw questions when those occur, more like brainstorming here - not actual or important questions)

#12 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 29 August 2011 - 08:26 AM

Posted this on other page, but still no luck:

------WebKitFormBoundary4pYRGbMxtMXW4kdE
Content-Disposition: form-data; name="parent_id"

5812
------WebKitFormBoundary4pYRGbMxtMXW4kdE
Content-Disposition: form-data; name="template"

41
------WebKitFormBoundary4pYRGbMxtMXW4kdE
Content-Disposition: form-data; name="name"

linnanmaki
------WebKitFormBoundary4pYRGbMxtMXW4kdE
Content-Disposition: form-data; name="sortfield"

sort
------WebKitFormBoundary4pYRGbMxtMXW4kdE
Content-Disposition: form-data; name="title"

Testing testing
------WebKitFormBoundary4pYRGbMxtMXW4kdE
Content-Disposition: form-data; name="submit_save"

Save page
------WebKitFormBoundary4pYRGbMxtMXW4kdE
Content-Disposition: form-data; name="id"

5815
------WebKitFormBoundary4pYRGbMxtMXW4kdE--


Respond headers say 200 ok and it seems to render the page normally (I can see that from Chrome dev tools, network tab). So it posts ok and to right page. But when you do regular save, then it does 301 redirect (to avoid back button problems). So somehow saving fails somewhere before that.

#13 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 29 August 2011 - 08:26 AM

I think that the only thing PageEdit needs to save a page is the actual 'id' as a POST var. But it's not specifically designed for saving one field at a time, so I'm thinking that in this scenario ProcessPageEdit be inefficient at best, or unpredictable at worst. So I think we probably need something more designed for this (within ProcessPageEdit), or at least I need to update ProcessPageEdit to know to expect it. I'm going to finish replying to messages here and then going to experiment in the code to see if there is a simple solution (I think there is).

#14 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 29 August 2011 - 08:37 AM

Ok, sounds good. Good solution might be something like if post comes through XMLHttpRequest, then it saves only the fields that are posted.

#15 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 29 August 2011 - 08:49 AM

That sounds like a perfect solution. I'm working with it now...

#16 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 29 August 2011 - 09:03 AM

If it is simpler to implement, I think that it is also fine to save just one field at the time (at least on this occasion, not sure about the future)

#17 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 29 August 2011 - 10:30 AM

I think I've got this ready to go if you want to give it a try. Replace your /wire/modules/process/ProcessPageEdit.module with the attached version. Then, when you want to save a field via ajax, POST it to the ./fields/ URL, i.e. /processwire/page/edit/fields/. For example:

var page_id = $("#Inputfield_id").val(); 

var postData = {
    id: page_id, 
    title: 'This is a test of changing the page title', 
}; 

$.post('./fields/', postData, function(jsonResult) {
    console.log(jsonResult); 
});

You can specify as many fields as you want in postData, but they have to be ones that are attached to the page's template in Setup > Templates > Fields. Currently you can't change fields that are built-in to pages, like: id, name, template, parent, etc.

I opted to do this with a "./fields/" URL off the page edit because I didn't want to use the same save code. Ajax stuff needs to react quickly and I thought it would just be faster if the code that saves ajax results didn't have to build and process the entire form. So instead, it just deals with the fields that are posted.

Once we've got it all working, I'll commit the ProcessPageEdit updates to the 2.1 source.

Edit:
Somewhat unrelated, but also wanted to add: whenever you are posting files, the form that posts them needs to have an 'enctype' attribute of 'multipart/form-data'. I mention this only because I always forget it and finally realize it after pulling some hair out. :)

Edit #2:
Wanted to clarify that you don't need to add a /fields/ page in your admin. ProcessPageEdit knows to handle that URL segment, so you don't need to do anything other than replace your existing ProcessPageEdit.module file and set your JS to post to the same URL as you were before, but with "/fields/" url segment appended to it.

Edit #3: found minor error in my code example above, as well as in the .module file, fixed both.

Attached Files



#18 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 29 August 2011 - 11:19 AM

Thanks Ryan, will test this right after our lego games end and kids are a sleep.

#19 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,586 posts
  • 905

  • LocationVihti, Finland

Posted 29 August 2011 - 02:34 PM

This works nicely with text only fields. But we cannot send multipart/form-data posts with jquery/js. So it needs some adjustments on the backend to support this. But this got me leaps forward and I should be able to fork from this. Looking better all the time!

#20 ryan

ryan

    Hero Member

  • Administrators
  • 5,980 posts
  • 3382

  • LocationAtlanta, GA

Posted 29 August 2011 - 02:59 PM

I'm not sure what needs to be done to support the multipart/form-data on PW module side? PW's forms are multipart/form-data already, but I think you are referring to something else. I don't know how the HTML5 upload script works exactly.  :)  But if there is anything I can add, just let me know and I'll do it.






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users