Use Grid Of Checkboxes Ajax And Webpy To Manage Related Records

Context:

  • Building WebApp with WebPy and a SQL db
  • Have sparse-matrix of records in many-to-many table - generically this is like a typical person/group/membership set of relationships, with a group.owner field
  • Want to give group owner a grid of his (multiple) groups and all the persons that are members to at least 1 group, so he can turn various memberships on/off for consistency check.
  • Want to provide AJAX interface (using JQuery) so each checkbox change makes immediate change, rather than requiring a Submit button.

Solution:

  • The GET method for the display page generates a Cross Tab of the data
    • Python has a crosstab library, but I just did it myself
    • key line is member_dict[member_row.user_id][member_row.group_id] = 1
  • display template turns crosstab member_dict into grid of checkboxes (note it gives each checkbox a unique ID by concatenating the 2 associated component IDs (user and group)
$for group in groups:
	<td align="center">
	$ check_id = str(group.id) + '_' + str(person.user_id)
	$if group.id in member_dict[person.user_id].keys():
		<input type="checkbox" name="crew" id="$check_id" checked>
	$else:
		<input type="checkbox" name="crew" id="$check_id">
	</td>
  • display template form also has CSRF hidden input <input type="hidden" name="csrf_token" id="csrf_token" value="$csrf_token()"/>
  • a piece of JavaScript in the page passed the checkbox params plus the CSRF value to a handler via AJAX
<script>
  $$(document).ready(function(){
    $$(':checkbox').change(function() { 
        var isChecked = $$(this).is(":checked") ? 1:0; 
        $$.ajax({
                url: '/group_member_toggle',
                type: 'POST',
                data: { strID:$$(this).attr("id"), strState:isChecked, csrf_token:$$('#csrf_token').val() }
        }); 
    })       
  });
</script>
  • POST method in a WebPy class receives the params and calls appropriate db functions (that part's pretty obvious)

Edited:    |       |    Search Twitter for discussion

No twinpages!