Tactical Advice: Many rows, one checkbox per row

69 views
Skip to first unread message

Phil Petree

unread,
Apr 25, 2012, 11:39:21 AM4/25/12
to prototype-s...@googlegroups.com
Hey All,
 
My need is to create a easy approval process for what could be a handful of "subscribers" up to 1000's of "subscribers".
 
The idea thus far is to create a table that has (and needs) only a few columns of information:
RecordID (hidden)  |  Approved [checkbox]  |  Subscriber Name (read_only text)  |  Subscriber City/State (read_only text)
 
<refrain ad nausem 'x' times>
 
What I want to do is to allow the user to CHECK/UNCHECK the check box and that event will call an ajax function that will submit the RecordID and Approved box[checked/unchecked]
 
I don't want to submit ALL rows, only the row that was just clicked.
I'm pretty sure the FormObserver is the wrong way to go
I'm pretty sure the $('approved').observe('change', xxx); isn't right either as that could create 1000's of observers
 
I could do an onchange event for each checkbox... but if I do that, how do I serialize two fields of data?
 
Advice please....
 
Pete
 

 
 
 

Brian Marquis

unread,
Apr 25, 2012, 12:18:38 PM4/25/12
to prototype-s...@googlegroups.com

Why not get rid of the hidden field and assign the record id as the value of the checkboxes. When you submit the form (or serialize it) only the checked items will be passed to the server.

For example:

 

<input name="ApprovedSubscribers" value="123" type="checkbox" checked="checked"/> Joe Cool

<input name="ApprovedSubscribers" value="456" type="checkbox" /> Fred Flintstone

<input name="ApprovedSubscribers" value="789" type="checkbox" checked="checked" /> Barney Rubble

 

Becomes ApprovedSubscribers="123, 789" when submitted.

 

You can then observe the form for changes and submit via ajax with a normal form submit for graceful degradation.

Brian Marquis | Quotepro® | Senior Developer | bm@quotepro.com | Phone: 312.654.8045 x122 / Fax: 312.654.1285

image001

The information in this e-mail is confidential and may be legally privileged.  It is intended solely for the addressee.   Access to this e-mail by anyone else is unauthorized.

--
You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group.
To post to this group, send email to prototype-s...@googlegroups.com.
To unsubscribe from this group, send email to prototype-scripta...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.

image002.png

Phil Petree

unread,
Apr 25, 2012, 3:00:39 PM4/25/12
to prototype-s...@googlegroups.com
Funny, I had just figured out what you had suggested for getting rid of the hidden field and making the record id the value.
 
The problem is that ONLY the checked items get passed... if someone is "unchecked" their approval is revoked so I need to update the table for that as well.

image002.png

Brian Marquis

unread,
Apr 25, 2012, 4:05:26 PM4/25/12
to prototype-s...@googlegroups.com

Yes, that's the nature of checkboxes and radio buttons.  If you need the value submitted in all circumstances, then you're back to the hidden field implementation. Problem with that approach is that it won't work if the user has javascript disabled.

 

A few options for event listeners (untested):

 

$('tableid').observe('click',function(event) {

  var element = Event.element(event);

  if ( element.name == " ApprovedSubscribers" ) {

       new Ajax.Request( url, $H({ RecordId: element.value, Checked: element.checked }));

}

});

 

Or

 

$$("input[type='checkbox']").invoke("observe","click",function(event) {

  var element = Event.element(event);

  if ( element.name == " ApprovedSubscribers" ) {

       new Ajax.Request( url, $H({ RecordId: element.value, Checked: element.checked }));

}

});

image004.png
image003.png

Phil Petree

unread,
Apr 25, 2012, 4:23:44 PM4/25/12
to prototype-s...@googlegroups.com
I'm now wondering if the onchange event will allow me to set the value of the hidden field BEFORE the form.observer fires the ajax call.... I'll test that tomorrow... My thinking is that I'll set the value of a hidden field to on/off and the name of the field to the record #.
image003.png
image004.png

Brian Marquis

unread,
Apr 25, 2012, 6:02:16 PM4/25/12
to prototype-s...@googlegroups.com
image001.png
image002.png

Wojtek Zadora

unread,
Apr 26, 2012, 5:23:45 AM4/26/12
to prototype-s...@googlegroups.com
Hello

The idea out of the head without code.
What about creating a map of checked checkboxes on window load event or document:dom. Something this way:

var checked = $('formId').select('input[checked]').pluck('value');

Then on submit form you select again all checked checkboxes and compare (do other logic) with start map.

-wz

Phil Petree

unread,
Apr 26, 2012, 10:51:46 AM4/26/12
to prototype-s...@googlegroups.com
I got it working... here's where I am so far:
 
1) at the top of the form I created a hidden input called 'active_record' which holds the $('id') of the row in progress
2) each row has <input type=hidden name=$record_num value=''> <input type=checkbox value=$record_num checked='checked/unchecked' onchange='updateRow(this.id, this.value);' >
3) updateRow(cbID, cbValue) {} wherein I set the value of the hidden $record_num with "checked" || "unchecked" and active_record with the cbValue and then call my ajax function which serializes the form and makes the call.
4) oncomplete: I clear the two hidden inputs.
 
In my php code I can check my $_POST:
$record = $_POST['active_record'];
$value = $_POST[$record];
error_log("record num is: $record and is set to $value");
Problem:
I'm still sending all the rows where the type=checkbox has checked=checked but I'm not processing those. Has no real impact on performance right now but with 1000's of users and frequent approval/disapprovals, it will unnecesssarily suck up bandwidth and time.
 
Any idea how to serialize just one field? Afterall, all I really need to do is send the checked/unchecked from the active_records hidden input...
 
 
 
 

 

Phil Petree

unread,
Apr 26, 2012, 12:26:50 PM4/26/12
to prototype-s...@googlegroups.com
I just drastically shortened this down...
 
I'm now serializing the data manually with:   strSerialize = "active_record=" +cbValue +"&state=" +strState;
Which produces: active_record=5&state="checked"
 
On the server side I can easily get the two values with $_POST... so far perfect...
 
I've deleted all the hidden fields...  
 
Now when you click on the checkbox, onchange does all the work and since I enable/disable the form, only one submission happens at a time...  exactly as we want it... Working perfectly...
 
Thanks for the help!

Wojtek Zadora

unread,
Apr 27, 2012, 2:11:10 AM4/27/12
to prototype-s...@googlegroups.com, Phil Petree
Hi

I wrote a routine (not sure if it fits exactly what you need), yet it presents the logic and maybe you will be able to fit in your code.
Notice it is not tested and uses prototype 1.7. It is wrote as clousure yet you may transfer it easly into Object Literal or class or something. Ah - and there is only one observer - on form:


Here you are:

(function()
{
    var _checked = undefined;
   
    document.observe("dom:loaded", function()
    {
        // select all checked ckeckboxes
        _checked = $('formId').select('input[checked]').pluck('value');

    //register observer on form click
        $('formId').on('click', _onClick);
    });
   
    function _onClick(event, element)
    {
        var isUnchecked = undefined;
   
        //if clicked element is input
        if (element.tagName.toLowerCase() == 'input') {

        // here we find out if our checkbox was checked or not at time of page loaded (isUnchecked == true shows it was checked and now is not)
            isUnchecked = _checked.indexOf(element.value) > -1 ? true : false;
           
            // send Ajax request
            _sendAjaxRequest(element, isUnchecked);
        }
    }
   
    function _sendAjaxRequest(element, isUnchecked)
    {
   
        new Ajax.Request('url', {
            method: 'post',
            parameters: { here you serialize your checkbox (element) manually},

            onSuccess: function(transport) {
                var response = transport.responseText.evalJSON();
                ......
            },

            onComplete: function() {
                ....
            }
        });
    }
})();


Hope it helps

-wz

Wojtek Zadora

unread,
Apr 27, 2012, 2:22:01 AM4/27/12
to prototype-s...@googlegroups.com, Phil Petree
Well, writing code out of a haed produces bugs: notice that after Ajax Request one needs update _checked array . Probably during ajax request functionality of form should be locked to prevent subsequent clicks till operation is done and checked is updated  Easily adding var _isLocked = false to closure and changing state to true on onCreate in AjaxRequest, back to false on onComplete) and using it to lock activity.

-wz

Wojtek Zadora

unread,
Apr 27, 2012, 3:13:53 AM4/27/12
to prototype-s...@googlegroups.com
Sorry for the mess I produced. Of course all this stuff with _checked array is not necessery if you want send AjaxRequest immediatly after checkbox click - just extract the clicked item and send all needed data including checkbox state as you do.

-wz
Reply all
Reply to author
Forward
0 new messages