Reputation: 981
Currently, I am working on the project using Codeigniter and facing a challenge that I am unable to resolve.
Following is the view:
As shown in above figure, there are multiple roles and permissions available. Each role has different permissions stored in the database. Also, user can have more than one role at a time.
Currently, I am able to select multiple roles and permissions of the user and it can successfully add in to the database. But the problem is that each role already have its permissions stored in the database. So, i would like to make it more user friendly and sensible that when I check any User Role
checkbox then using Jquery/Javascript it should automatically check all the relevant permissions
checkboxes in order to make a sense that which role has what permissions.
Any help ?
Upvotes: 1
Views: 5406
Reputation: 5310
I think this problem needs a two steps process.
First you must generate a javascript object which contains all the permission for earch row.
var rolePermissions = {
master: [ 'dashboard', 'guard', 'sites'],
manager: ['sites', 'timesheet'],
operation: ['etc.' ]
};
now when the page load or the user checked the role checkbox:
Upvotes: 0
Reputation: 567
I would give every premission a value the following way
The roles would have a value that is the sum of the premission they have
so
Then take the highest premission value (8 in this case) and check with the checked roles.
1 - 1 = 0 is not smaller then 0, so premission 1.
$(".role").on("click", function(){
$(".perm").prop("checked", false);
$(".role:checked").each(function() {
var reduceBy = maxFromDatabase;
var roleRight = $(this).data("rights");
while(reduceBy != 0) {
if(!(roleRight - reduceBy < 0)) {
$("input[data-right-val='"+reduceBy+"']").prop("checked", true);
roleRight = roleRight-reduceBy;
}
reduceBy = Math.floor(reduceBy/2);
}
});
});
You can check this fiddle for the html (I use data attributes) implementation http://jsfiddle.net/8dcp4Lvk/3/
I placed the values in a data attribute in html. I like this system because it is easy to maintain. You do not need an extra table in the database between the roles and premissions and adding a premission or removing one is as easy as adding or removing it's value from the role value.
In the fiddle all you would have to do is add a new premission, with a value of 64, as 64 to the first role (71) and maxFromDatabase to 64 (this value you would normally get with a query offcourse, same with all the data values). Added benifit is that you can also use these values in your PHP code in the same way.
You could extend this. Give roles a value like premission (1, 2, 4, etc) and you can use those for the user. Give him two columns (roles and premissions) in roles you give him the roles he has and in premission you assigned the total number of premissions. This way all you need is some extra colums, not extra tables.
Upvotes: 7
Reputation: 824
assuming your html to be something like --
<div id="role_container">
<input id="{ROLE_ID of Master here}" type="checkbox" /> <label>Master</label>
----- Other Roles here -----
----- Other Roles here -----
<input id="{ROLE_ID Guard here}" type="checkbox" /> <label>Guard</label>
</div><br />
<div id="permission_container" >
<input id="{Permission_ID of Company here}" type="checkbox" /> <label>Company</label>
----- Other Permission here -----
----- Other Permission here -----
<input id="{Permission_ID Roster here}" type="checkbox" /> <label>Roster</label>
----- Other Permission here -----
----- Other Permission here -----
<input id="{Permission_ID Form here}" type="checkbox" /> <label>Form</label>
----- Other Permission here -----
----- Other Permission here -----
<input id="{Permission_ID TimeSheet here}" type="checkbox" /> <label>TimeSheet</label>
</div>
Now, I would suggest you to add a data attribute on checkbox for each Role. Then populate this data attribute with Premission_Ids (comma seperated) like --
<input id="{R_ID_Master here}" type="checkbox" data-permissions="{P_Id_Company}, {P_Id_Form}, {P_Id_Roster}" /> <label>Master</label>
----- Other Roles here -----
----- Other Roles here -----
<input id="{R_ID_TimeSheet here}" type="checkbox" data-permissions="{P_Id_TimeSheet}, {P_Id_Sites}"/> <label>TimeSheet</label>
When you have this setup ready, call this javascript function onchange event--
function OnRoleCheckedChange(sender) {
if (sender.checked) {
var prrmissions = $(sender).attr("data-permissions").split(",");
permissions.each(function () {
$("div#permission_container input[type='checkbox'][id='" + this.trim() + "']").prop('checked', true);
});
}
}
If you have conditions then they can be applied in the function before checking or unchecking
Upvotes: 0
Reputation: 134
Dont know about codeignitor. But if it was my problem I would first create the view dynamically from the database. (label, checkbox etc).
As you say "Each role has different permissions stored in the database";
First I assume the DB like
[ name | id ] : master | 1; manager | 2; operation | 3; translink | 4; guard = 5;
AND child table like:
[parentPermissionId | permissionName | permissionId] : 1|dashboard|1; 1|guard|2; 1|rosterSite|3; 1|report|4;
and so on .....
Now in PHP create the controller
<?php
// i assume that you already done db conn and have a model
$obj = new permission_model();
$masterPermissions = $obj->masterPermission();
// assuming that you fetch distinct child permission name and id from DB
$childPermissions = $obj->childPermission();
?>
for view
<?php
if(isset($masterPermissions)) {
foreach($masterPermisssions as $masterPermission) {
echo '<input type="checkbox" id="'.$masterPermission['id'].'"> '.$masterPermission['name'];
}
}
if(isset($childPermissions)) {
foreach($childPermisssions as $childPermission) {
echo '<input type="checkbox" id="'.$childPermission['id'].'"> '.$childPermission['name'];
}
}
?>
now from client side
in jQuery
$('input[type="checkbox"]').click(function () {
id = thid.id;
// get permission from db in JSON format;
$.getJSON('jsonPermission.php', { id : id }, function (data) {
$.each(data.results, function() {
if(this.id === 1) {
$('#'+thid.id).prop('checked', true);
}
});
});
});
create JSON from PHP for jQuery
<?php
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest' ) {
require 'models/permission_model.php';
$id = trim(htmlentities($_GET['id']));
$obj = new permission_model();
$infos = $obj->permissionChildIdFromParent($id);
foreach($infos as $info) {
array_push($results,array(
'id' => $info['id']
));
}
echo json_encode(array('results' => $results));
}
?>
may be I am not more specific. but it will be if you show your DB table and code structure.
Upvotes: 0
Reputation: 561
You should create a permissions system which allows you to do that. For example:
You create tables: user, permissions, user_permissions, permission_groups In that way you could have all possible permissions defined in "permissions" table, have a table where you could assign user-specific permissions, a table which would assign a permission-group to permissions. Then after that you could just simply request the permissions of a group via ajax.
The ui part is easy to solve.You assign every checkbox a id with the permission name from database. So when u make ajax call i.e: getManagerGroupPermissions -> returns [perm1, perm2, perm3, perm4] so you would parse json and check all the checkboxes with these id-s.
Upvotes: 0
Reputation: 329
Not sure what you want to do...
If your problem is just to dynamicaly select the permissions associated to a role, here is an implementation using jQuery: http://jsfiddle.net/hkaqLfr
// List which permissions come with the role
// You can populate it during page creation
var roleHasPerm = {
0:[2,3,4],
1:[1,3,4],
2:[3,5,9,6],
3:[8,4,5,3],
4:[1,4]
};
// when a role is checked or unchecked
$('.check_role').change(function(){
// get the role id
var roleId = $(this).attr('data-id-role');
// get the permissions associated to this role
var permissions = roleHasPerm[roleId];
if (!$(this).prop('checked'))
return; // here you can chose what to do when user unchecks a role...
// check every associated permissions
permissions.forEach(function(permission){
$('#perm_'+permission).prop('checked', true);
});
});
If your problem is somewhere else, I didn't get it...
WARNING: check forEach
compatibility at https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/forEach
Upvotes: 0
Reputation: 1
Maybe this helps: http://jsfiddle.net/2mbwas6r/1/
HTML
<!-- Value could be the id of this group from your database //-->
<input type="checkbox" name="acl_group[]" value="1" /> Admin
<input type="checkbox" name="acl_group[]" value="2" /> Mod
<input type="checkbox" name="acl_group[]" value="12" /> User
<p>
<!-- In data-in-acl-group add any group id from above surrounded by ; (semicolon) //-->
<input type="checkbox" name="acl_rule[]" value="1" data-in-acl-group=";1;" />Perm 1
<input type="checkbox" name="acl_rule[]" value="2" data-in-acl-group=";1;;2;" />Perm 2
<input type="checkbox" name="acl_rule[]" value="3" data-in-acl-group=";2;" />Perm 3
<input type="checkbox" name="acl_rule[]" value="4" data-in-acl-group=";1;;2;;12;" />Perm 4
<br />
<input type="checkbox" name="acl_rule[]" value="5" data-in-acl-group=";1;" />Perm 5
<input type="checkbox" name="acl_rule[]" value="6" data-in-acl-group=";1;;2;" />Perm 6
<input type="checkbox" name="acl_rule[]" value="7" data-in-acl-group=";1;;12;" />Perm 7
<input type="checkbox" name="acl_rule[]" value="8" data-in-acl-group=";2;;1;" />Perm 8
</p>
JS
var aclGroupsSelected = [];
$('body').on('change', 'input[name^=acl_group]', function() {
aclGroupsSelected = [];
$.when(
$('input[name^=acl_group]:checked').each(function() {
aclGroupsSelected.push($(this).val());
})
).then(function(){
$('input[data-in-acl-group]').removeAttr('checked');
$(aclGroupsSelected).each(function(aclGroupIdIndex){
$('input[data-in-acl-group*=";' + aclGroupsSelected[aclGroupIdIndex] + ';"]').each(function(){
this.checked = "checked";
});
});
});
});
Upvotes: 0
Reputation: 86
When serving page make sure to serve a certain JavaScript structure which describes which role brings which permission. After that it is a simple click event tracking and filling in the permission boxes.
I guess you know how to read roles and permissions from the DB and how to serve the following JavaScript inside the page.
Take a look at this jsFiddle DEMO!
var roles = {
master: {
dashboard: true,
companies: true,
contractor: true
},
manager: {
contractor: true,
sites: true,
guard: true
},
operation: {
roster: true
}
};
$('.role').click(function() {
var result = {};
$('.role').each(function() {
if (!$(this).prop('checked')) return;
var role = $(this).attr('id');
$.extend(result, roles[role]);
});
$('.perm').each(function() {
var perm = $(this).attr('id');
var chk = (perm in result);
$(this).prop('checked', chk);
});
});
Note that you can also combine this with user specific permissions (outside the roles, if it is allowed). Let me know if you want this option as well, I can try to update the source.
The objects server are a bit more than your case needs since they have boolean values, but it would make later easier to expand the usage. For instance prevent certain permission if the role is selected.
Upvotes: 1
Reputation: 57
A quick thought, I will edit this as I go: I would make a jquery/javascript function that checks the permissions of the role sending a form with ajax.
function checkRoles() {
if($('#check_id1').is(":checked") or $('#check_id2').is(":checked") ){ //Check for the roles
$.ajax({
url: '<?php echo base_url(); ?>index.php/yourcheckingphp/yourcheckinmethod/',
type: 'POST', //Here you send the form with the role
data: $('#yourform').serialize(),
success: function(data) { //If php returns data this function does this in a sucessful response or on error
document.getElementById("Permission1").checked = true; //Enable as much permissions as you want, check them.
document.getElementById("Permission2").checked = true;
//ADD PERMISSIONS HERE!
},
error: function(error) {
alert('Check your connection!');
quitImageLoading();
}
});
}
}
In php:
public function yourcheckinmethod() {
//Get the checked roles (This may vary depending on your needs)
$check_id1 = $this->input->post('check_id1');
$check_id2 = $this->input->post('check_id2');
$check_id3 = $this->input->post('check_id3');
$check_id4 = $this->input->post('check_id4');
//Call a php model with a connection to the database
$result = $this->yourmodel->yourcheckinmethodMODEL($check_id1,$check_id2,$check_id3,$check_id4);
echo $result;
}
//In your DB model
//With your db connection
function yourcheckinmethodMODEL($check_id1,$check_id2,$check_id3,$check_id4) {
if($check_id1 != NULL){
$query = $this->db->query("SELECT * FROM Permissions WHERE ROLE = $check_id1");
}
//This may vary depending on your needs
return $query->result();
}
Upvotes: 1