tags:

views:

84

answers:

5

I have a list of allowed file extensions that can be uploaded to my site.

I check them with jQuery Validation plugin.

I'm displaying an error message if they choose a non supported extension.

It looks like

var msg = 'You may only upload files of type ' + allowedExt.join(', ');

Obviously the list doesn't look too flash. I'd like it to look more human readable.

Any way to do this?

+2  A: 

Hello!

Yes you can!

var niceList = function(array, join, finalJoin) {       
    join = join || ', ';
    finalJoin = finalJoin || ' and ';       
    var length = array.length;      
    return array.slice(0, length - 1).join(join) + finalJoin + array[length - 1];    
};

alert(niceList([a, b, c])); // 'a, b and c'
alex
+6  A: 

A simpler way to do the answer posted by alex is by using .pop() to get the last element off:

var niceList = function(array, join, finalJoin) {
    var arr = array.slice(0), last = arr.pop();
    join = join || ', ';
    finalJoin = finalJoin || ' and ';
    return arr.join(join) + finalJoin + last;    
};
Nick Craver
Ah yep! Of course. I forgot about `pop()`. +1 to you Nick!
alex
This is very nice. Plenty of user options and a readable array all in basically 4 lines.
Peter Ajtai
Do you mean when you say it changes the array, it only changes it within the function's scope right? It is passed by value right?
alex
I vote to remove first half of this answer. I highly doubt @Alex wants to modify an array used elsewhere for validation.
Josh Stodola
@alex - nope it'll change the original array, here's a test of the first version: http://jsfiddle.net/nick_craver/NKYTP/1/ and the second, which doesn't mutate: http://jsfiddle.net/nick_craver/NKYTP/2/
Nick Craver
@Josh - fair point, the extra cost is almost *always* worth the safety, removed the first non-copy option.
Nick Craver
@Nick I always thought calling methods on an array returned a new one, but then I remembered how `pop()` works.
alex
+1 Cheers! Congrats on getting married, btw :)
Josh Stodola
Congrats too Nick! Now get off here and spend some time with the wife! :D
alex
@Josh, @alex - thanks :)
Nick Craver
Should this do a `if (array.length == 1) return array[0]` ?
alex
+1  A: 

I took you literally and made it into an actual HTML list.

var extensions = ['html', 'txt', 'png', 'jpg'];
var extension_list = '<ul>';

for(i=0; i<extensions.length; i++)
{
    extension_list += '<li>'+extensions[i]+'</li>';
}

extension_list += '<ul>';

var msg = '<p>Sorry, you can only upload the following extensions:</p>'+extension_list;
pmckenna
+1  A: 

Since we're apparently providing different versions of alex's answer, here's one without join:

function niceList(array, join, final) {
   return array.reduce(function (pv, cv, i, a) { 
      return pv + (i == a.length - 1 ? final : join) + cv; 
   });
}; 

Doesn't work with old browsers, etc.

CD Sanchez
+1 good looking solution!
alex
A: 

The accepted answer does not handle a one item list very well.

function niceList(array) {
  if (!array || array.length == 0) return "";
  var clone = array.slice(0);

  return function build() {
    if (clone.length == 1) return clone[0];
    if (clone.length == 2) return clone[0] + ' and ' + clone[1];
    return clone.shift() + ", " + build();
  }();  
}
Nick