Last week I posted a question on the "Ruby on Rails: Spinoffs" group - generally a place for ProtoType/Scriptaculous discussions. My
post was wondering how to do the InPlaceEditor of Scriptaculous using checkboxes for the form controls. This seems like it could be a derivative of the InPlaceCollectionEditor, after all I have a defined set of choices - some of which may be selected - only I don't want a drop-down for selecting. But as you can see from the post, only one person responded and while I didn't read his response in detail - it sure looks like a lot of code. There is also a Rails plugin, oh - this is for a Rails app - of course, "
SuperInPlaceControls" but it's targeted to Rails 2.0, I'm on 1.2 still, and it employs classic Rails javascript helpers - and I'm not such a big fan of those. I prefer to manage, as much as possible, my on-page controls via
LowPro behaviors in a standard application.js file.
Last week I posted a question on the "Ruby on Rails: Spinoffs" group - generally a place for ProtoType/Scriptaculous discussions. My
post was wondering how to do the InPlaceEditor of Scriptaculous using checkboxes for the form controls. This seems like it could be a derivative of the InPlaceCollectionEditor, after all I have a defined set of choices - some of which may be selected - only I don't want a drop-down for selecting. But as you can see from the post, only one person responded and while I didn't read his response in detail - it sure looks like a lot of code. There is also a Rails plugin, oh - this is for a Rails app - of course, "
SuperInPlaceControls" but it's targeted to Rails 2.0, I'm on 1.2 still, and it employs classic Rails javascript helpers - and I'm not such a big fan of those. I prefer to manage, as much as possible, my on-page controls via
LowPro behaviors in a standard application.js file.
That said, I'm posting my solution to the problem for all the world to see. Basically what I did was to use the onFormCustomization callback, which is not documented in the "
Bungee book" - although you can always read the code, right? Without getting too verbose; my code is posted below. I've removed some non-relevant bits. The main function is declare_in_place_check_boxer which I call from a LowPro behavior definition, something like...
'span.ipe_check_box':function(){
FormControls.declare_in_place_check_boxer('my_controller_name', 'this_param_name', this, element_id);
}
... where the "element_id" is an integer for the record being updated. Usually I place hidden fields in the page and use Proto DOM functions to find it from where ever I happen to be - which is maybe an idea for another post.
Now the text is linked to this IPE, which after it is clicked and loaded the onFormCustomization triggers. As you can see I create a table using Proto DOM functions to dynamically build up the html. The select_list variable is an array of the string values already selected for this attribute. I'll let the code speak for me now, except for the last bit "ipeForm.removeChild(ipe._controls.editor);" where I'm removing the default form control (ie. text field) create by IPE.
I'd be happy to hear of a better method.
declare_in_place_check_boxer:function(controller, parameter_name, element, id){
new Ajax.InPlaceEditor(element,
'/' + controller + '/' + id,
method: 'put',
{paramName: parameter_name,
onFormCustomization:function(ipe, ipeForm){
var select_list = ipe.element.innerHTML.split(',');
var t = $table();
var tr = $tr();
t.appendChild(tr);
for(var i=0;i<products.size(); i++){
if((i)%4 == 0){
var tr = $tr();
t.appendChild(tr);
}
FormActions.add_product_cell(products[i], tr, parameter_name, select_list);
}
ipeForm.appendChild(t);
ipeForm.removeChild(ipe._controls.editor);
}
} );
},
add_product_cell:function(product, tr, parameter_name, selected_values){
// where product[0] is the id and product[1] is the name
var td = $td();
var lbl = $label({'style':"white-space: nowrap;"})
var chk = $input({type:"checkbox",
value:product[0],
name:parameter_name})
if(selected_values.include(product[1])){
chk.checked = true;
}
lbl.appendChild(chk);
lbl.appendChild(document.createTextNode(product[1]));
td.appendChild(lbl);
tr.appendChild(td);
}