views:

78

answers:

4

I cant seem to do this in an elegant way, and I don't understand some of the behaviour I'm seeing.

I have my array stored in html like so:
<input type="hidden" id="myField" value="1,2,3,5,8,13">

To add a value I must do this, is this really the cleanest way to do this?

$('#myField').val($('#myField').val() + ',' + 21);

And to remove I value I have to do something like this:

newValues=$.grep($('#myField').val(), function(value) {  
        return value != 3;  
     });  
      $('#myField').val(newValues);

Apart from this does not work.....as I get the same behaviour as illustrated here:

If i do this:

$.grep('1,2,3',function(value){return value!=3;})

It returns this, why do I get these extra blank elements? How do I remove 3 from the hidden input?:

["1", ",", "2", ","]
+1  A: 

The value of the hidden field is a string, not an array. The grep function treats that string as an array of characters where the , character doesn't have any special meaning, it's just another element in the array.

To treat the string as a comma-separated array of values you'll need to split it before processing, using JavaScript's split function. Once you're done with the array you can convert it back to a string using join before writing the string back to the hidden field.

var newValues = $.grep($('#myField').val().split(','), function(val) {  
    return val != 3;
});  
$('#myField').val(newValues.join(','));
LukeH
+2  A: 

You can treat it as an array using .split() and .join(), for example adding the value:

$("#myField").val(function(i, v) {
  var arr = v.split(',');
  arr.push('21');
  return arr.join(',');
});

Or removing one:

$("#myField").val(function(i, v) {
  return $.grep(v.split(','), function(value) {  
           return value != 3;  
         }).join(',');
});

You can test it out here, in each case we're converting the string value into an array, manipulating the array, then converting it back to a string. Another alternative is to always deal with the array, then convert it to a string when needed, for example in $("form").submit(...) just before submitting the form.


In case you're doing this all over the place, you could re-write it as a plugin, something like this:

jQuery.fn.extend({
    addToArray: function(value) {
        return this.filter(":input").val(function(i, v) {
           var arr = v.split(',');
           arr.push(value);
           return arr.join(',');
        }).end();
    },
    removeFromArray: function(value) {
        return this.filter(":input").val(function(i, v) {
           return $.grep(v.split(','), function(val) {  
                    return val != value;
                  }).join(',');
        }).end();
    }
});

The your calls would look like this (chainable if needed):

$("#myField").addToArray('21');
$("#myField").removeFromArray('3');

You can test that version here

Nick Craver
+1 for showing a running example using a nice tool like http://jsfiddle.net
Amr ElGarhy
A: 

This method might be able to help you. Try the following function to remove the value and get the result

function removeVal(list, value) {
  list = list.split(',');
  list.splice(list.indexOf(value), 1);
  return list.join(',');
}

removeVal('1,2,3', '2'); 
//result "1,2"

To add a value, first send the use the following function

function addVal(list, value){
 list = list + value;
return list;
}

addVal("1,2,3",",4"); //result 1,2,3,4
Raf
A: 

Keeping the same value setup as you currently have, you can add/remove values as follows:

To add a value:

$input = $("input");

var array = $input.val().split(",");
array.push(7,8,9);
$input.val(array);

To remove a value:

$input = $("input");

var array = $input.val().split(",");
array = $.grep(array, function(n, i) { return n !== "13"; });//"13" can be any value or variable you choose.
$input.val(array);

Short demo here.

​However, if you are able to change the format of the hidden field value, you can make use of the data() method in jQuery or the metadata() plugin if you choose:

//Using metadata() with html5 attributes

//Markup

<input type="hidden" id="myField" data-value="[1,2,3,5,8,13]">

//JS

var $input = $("input");

$.metadata.setType("html5");
$input.metadata().value.push(7,8,9);

The metadata section is untested, but you can interact with an element as an object instead of a string. No splits required ;)

Alexis Abril