How to know which checkbox has been ticked per row?
-
21-12-2019 - |
Question
Using: Coldfusion 10, JQuery 1.9, HTML5 (more HTML4)
The title is deceptively simple for this question. I have a table which displays permissions that users have on entities within an application. To create a new user I have a FORM which allows you to enter personal details and then a table on the same page which allows you to select permissions you wish to give to this user.
So here is how the webpage table looks (sort-of):
EntityName | Write | Read | Delete // Permissions
===================================
Note | □ | □ | □ // 1 row per entity
Appointment | □ | □ | □
Sale | □ | □ | □
(Imagine the square boxes are checkboxes for the sake of illustration).
The Permissions are coming from a result called rsPermissions
(with primary key PermissionID
). I'm looping over my rsPermissions
resultset and creating a new header column for each one.
The EntityNames are coming from a resultset called rsEntities
(with primary key EntityID
). I'm looping over my rsEntities
resultset and creating a new row for each one.
Here's the problem: I know which checkbox has been checked and can get the PermissionID
e.g. Write or Read or Delete. But I don't know for which EntityID
this Permission was checked. That is, I cannot seem to get the Permissions to relate to the Entities so that this combination of PermissionID
and EntityID
can be passed to my database for insertion into a EntityPermission
database table as such:
EntityID | PermissionID
=======================
1 | 1
1 | 2
1 | 3
2 | 1
2 | 3
3 | 1
3 | 2
UPDATE TO SHOW HTML: http://jsfiddle.net/2jZYB/
<table>
<thead>
<tr>
<th scope="col">EntityName</th>
<th scope="col">Write</th>
<th scope="col">Read</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td>Note</td>
<td><input name="" type="checkbox" value=""></td>
<td><input name="" type="checkbox" value=""></td>
<td><input name="" type="checkbox" value=""></td>
</tr>
<tr>
<td>Appointment</td>
<td><input name="" type="checkbox" value=""></td>
<td><input name="" type="checkbox" value=""></td>
<td><input name="" type="checkbox" value=""></td>
</tr>
<tr>
<td>Sale</td>
<td><input name="" type="checkbox" value=""></td>
<td><input name="" type="checkbox" value=""></td>
<td><input name="" type="checkbox" value=""></td>
</tr>
</tbody>
</table>
Here is the ColdFusion markup:
<cfloop query="rsEntities">
<table>
<thead>
<tr>
<th scope="col">EntityName</th>
<cfloop query="rsPermissions">
<th scope="col">#Permission#</th>
</cfloop>
</tr>
</thead>
<tbody>
<cfloop>
<tr>
<td>#Entity#</td>
<cfloop index="i" from="1" to="#rsPermissions.RecordCount#">
<td><input name="" type="checkbox" value=""></td>
</cfloop>
</tr>
</cfloop>
</tbody>
</table>
</cfloop>
La solution
Assuming the list of Permissions is very small, another option is to name each set of checkboxes by entity ID, and use the permission ID for the checkbox value
:
<cfloop query="rsEntities">
<!--- generate a list of all entity ids --->
<input type="hidden" name="EntityIDList" value="#rsEntities.EntityID#">
...
<cfloop index="i" from="1" to="#rsPermissions.RecordCount#">
<!--- Group each set of permissions by entity id --->
<input name="EntityPermissions_#rsEntities.EntityID#"
value="#rsPermissions.permissionID[i]#"
type="checkbox" >
</cfloop>
...
</cfloop>
The end result would be a list of permissions for each entity id. So say you checked "Read" and "Write" for the entities "Note" and "Sale", the result would be a list of permissions for each entity, ie:
FORM.EntityPermissions_1 = 1,2 <== Note (Write=1,Read=2)
FORM.EntityPermissions_3 = 1,2 <== Sale (Write=1,Read=2)
When the form is submitted you could loop through the entity id's, and use a simple CROSS JOIN to insert the selected permissions into your table via an INSERT/SELECT, minimizing the overall number of database calls. A nice side benefit of this method is built in validation of the id values. (Obviously the queries should be wrapped in a cftransaction to ensure data integrity).
<cfloop list="#FORM.EntityIDList#" index="EntityID">
<!--- if any permissions were assigned for this entity ....--->
<cfif structKeyExists(FORM, "EntityPermissions_"& EntityID)
AND listLen(FORM["EntityPermissions_"& EntityID])>
<!--- insert them into the db ...--->
<cfquery ...>
SELECT e.EntityID, p.PermissionID
FROM EntityTable e CROSS JOIN PermissionTable p
WHERE e.EntityID = <cfqueryparam value="#EntityID#" .... >
AND p.PermissionID IN
(
<cfqueryparam
value="#FORM['EntityPermissions_'& EntityID]#"
list="true" .... >
)
</cfquery>
</cfif>
</cfloop>
Autres conseils
You could use something like
<input type="checkbox" name="permission[note][1]" />
<input type="checkbox" name="permission[note][2]" />
<input type="checkbox" name="permission[note][3]" />
For the three checkbox of Note?
Let me know if this is applicable to your case.
It would be easier to answer if we could see the HTML, not a mockup. That said, you should be able to give each checkbox a unique name/id that you can reference in javascript or backend code.
<input type="checkbox" id="Write_1" name="Write_1" /> <!-- Write chk, entity 1 -->
<input type="checkbox" id="Read_1" name="Read_1" /> <!-- Read chk, entity 1 -->
<input type="checkbox" id="Delete_1" name="Delete_1" /> <!-- Delete chk, entity 1 -->
<input type="checkbox" id="Write_2" name="Write_2" /> <!-- Write chk, entity 2 -->
<input type="checkbox" id="Read_2" name="Read_2" /> <!-- Read chk, entity 2 -->
<input type="checkbox" id="Delete_2" name="Delete_2" /> <!-- Delete chk, entity 2 -->
Or what might be easier:
<input type="checkbox" id="Perm_1_1" name="Perm_1_1" /> <!-- perm 1, entity 1 -->
<input type="checkbox" id="Perm_2_1" name="Perm_2_1" /> <!-- perm 2, entity 1 -->
etc.
In ColdFusion, you could loop through entities and permissions to see which ones the user has checked-
<cfloop list="#entityList#" index="entityID">
<cfloop list="#permissionList#" index="permID">
<cfif IsDefined("Form.Perm_#permID#_#entityID#")>
<!--- User has checked this permission. --->
<cfelse>
<!--- User has NOT checked this permission. --->
</cfif>
</cfloop>
</cfloop>