views:

251

answers:

3

I am creating a private message system to allow users to communicate between one another within the context of the website (ie, not emails).

I have created this function to handle all my form submissions. I would like to achieve a solution without modifying this function (ideally).

$("form.reload").submit(function(){
    alert($(this).serialize()); /* Debugging */
    $.post($(this).attr("action"),
        $(this).serialize()
    ,function(data){
        if(data){
            $("#error").html(data);
        }else{
            location.reload();
        };
    });
    return false;
});

Within my form I am using JQuery Autocomplete to find usernames. This function works perfectly. My first solution was to add buttons within the form with the necessary values.

select: function(event, ui) {
    $("#message_to").append("<input type=\"button\" class=\"recipient\" name=\"recipients[]\" value=\"" + ui.item.label + "\" onclick=\"$(this).remove()\" />");
}

<form method="post" action="/messages-create" class="reload">
<div id="message_to"></div>
</form>

For some reason the values of recipients are not getting posted.

My second solution was to add to a post array that already existed in the form

select: function(event, ui) {
    $("input[name=recipients[]").val = ui.item.label; /* Need to add to array, not replace! */

    $("#message_to").append("<input type=\"button\" class=\"recipient\" name=\"recipient\" value=\"" + ui.item.label + "\" onclick=\"$(this).remove(); /* Remove from recipients */\" />");
}

<form method="post" action="/messages-create" class="reload">
<input type="hidden" name="recipients[]" value="" />
<div id="message_to"></div>
</form>

This works ok, but I have been unable to work out how to append to the recipients[] array only replace with the new label. Moving on from this, I also need to know how to then remove this value from the array.

Thanks in advance!

A: 

That needed some quotes. Don't know if it will do what you want, though... Also, the val

$("input[name=recipients[]]").val(ui.item.label);

And recipients, not receipients...

Victor
Original Code did have the quotes, typo on my behalf. As for the val(ui.item.lable), this is just replacing the value and not ammending.
bigstylee
A: 

I think that the simplest way to do this would be to save all of the recipient information to a javascript object or array and then in your submit function, just run a function that checks if this object exists, and if it does, write out a series of hidden inputs with the recipients' identifying information in them before serializing the form and starting your post call.

Create an object variable in an accessible location (I'm using the global scope for convenience, but a utility object would be better)

recipients_dict = {}; // We could also use an array if we have a find function handy.

In your :select function alter your onclick event and add:

select: function(event, ui) {
    $("#message_to").append("<input type=\"button\" class=\"recipient\" name=\"recipients[]\" value=\"" + ui.item.label + "\" onclick=\"remove_recipients(this)\" />");
    recipients_dict[ui.item.label] = ui.item.label;
}

Then create two functions, one to remove people from the array, and one to create the form elements before submission.

function remove_recipients(btn) {
    btn = $(btn);
    name = btn.value;
    if (typeof recipients_dict[name] !== 'undefined') {
        delete recipients_dict[name];
    }
    btn.remove();
}

function add_recipients(frm) {
    if (typeof recipients_dict === 'object') {
        _recipient_inputs = "";
        for (var name in recipients_dict) {
            _recipients_inputs += '<input type="hidden" name="recipients[]" value="' + name + '" />';
        }
        $(frm).append(_recipients_inputs);
    }
}

Then, inside of your submit function, just pass:

$("form.reload").submit(function(){
    add_recipients(this);
    alert($(this).serialize()); /* Debugging */
    // ... snip ...
}

The advantage of this is that you do not have to worry about removing the right recipients from the form. Once you build the form you know you are only submitting the correct recipients.

Sean Vieira
Thank you for your input, a good solution. Although I wanted to achieve the solution without modification to my submit function.
bigstylee
+1  A: 

it's a bit of a kludge, but in your first example it doesn't serialize because it's a button. Try using a hidden field and don't give the button a name, just in case it decides to work in the future..

select: function(event, ui) {
  $("#message_to").append("<span onclick=\"$(this).remove()\"><input type=\"hidden\" class=\"recipient\" name=\"recipients[]\" value=\"" + ui.item.label + "\"  />" +
    "<input type=\"button\" value=\"" + ui.item.label + "\" /></span>");
}
Lee
worked perfectly, thank you!
bigstylee
+1. Much cleaner than my massive enterprise-y script solution!
Sean Vieira