RK.
RK.

Reputation: 981

Automatically check checkboxes that relate to that id in database

Currently, I am working on the project using Codeigniter and facing a challenge that I am unable to resolve.

Following is the view:

enter image description here

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

Answers (9)

Du D.
Du D.

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:

  1. Get all the permission for all roles seleted, merge them
  2. Loop through the list of all permissions and check the appropriate boxes

Upvotes: 0

Jeroen
Jeroen

Reputation: 567

I would give every premission a value the following way

  • premission 1 = 1
  • premission 2 = 2
  • premission 3 = 4
  • premission 4 = 8

The roles would have a value that is the sum of the premission they have

so

  • role 1 (premission 1,2,4) = 11
  • role 2 (premission 2,3) 6

Then take the highest premission value (8 in this case) and check with the checked roles.

  1. so 11-8 = 3 is not smaller then 0, so premission 4.
  2. Take half of the current premission value (4) with the result of last check (11-8)
  3. 3 - 4 = -1 is smaller then 0. NOT premission 3.
  4. Take half of current premission value (2), but keep the result of 3
  5. 3 - 2 = 1 is not smaller then 0, so premission 2.
  6. again the same
  7. 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

Pankaj Dubey
Pankaj Dubey

Reputation: 824

assuming your html to be something like --

<div id="role_container">
    <input id="{ROLE_ID of Master here}" type="checkbox" />&nbsp;<label>Master</label>
    ----- Other Roles here -----
    ----- Other Roles here -----
    <input id="{ROLE_ID Guard here}" type="checkbox" />&nbsp;<label>Guard</label>
</div><br />
<div id="permission_container" >
    <input id="{Permission_ID of Company here}" type="checkbox" />&nbsp;<label>Company</label>
    ----- Other Permission here -----
    ----- Other Permission here -----
    <input id="{Permission_ID Roster here}" type="checkbox" />&nbsp;<label>Roster</label>
    ----- Other Permission here -----
    ----- Other Permission here -----
    <input id="{Permission_ID Form here}" type="checkbox" />&nbsp;<label>Form</label>
    ----- Other Permission here -----
    ----- Other Permission here -----
    <input id="{Permission_ID TimeSheet here}" type="checkbox" />&nbsp;<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}" />&nbsp;<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}"/>&nbsp;<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

Rudrakshya Barman
Rudrakshya Barman

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

Lauri Orgla
Lauri Orgla

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

Marshall
Marshall

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

Phelan Leroux
Phelan Leroux

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&nbsp;
<input type="checkbox" name="acl_group[]" value="2" /> Mod&nbsp;
<input type="checkbox" name="acl_group[]" value="12" /> User&nbsp;
<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&nbsp;
    <input type="checkbox" name="acl_rule[]" value="2" data-in-acl-group=";1;;2;" />Perm 2&nbsp;
    <input type="checkbox" name="acl_rule[]" value="3" data-in-acl-group=";2;" />Perm 3&nbsp;
    <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&nbsp;
    <input type="checkbox" name="acl_rule[]" value="6" data-in-acl-group=";1;;2;" />Perm 6&nbsp;
    <input type="checkbox" name="acl_rule[]" value="7" data-in-acl-group=";1;;12;" />Perm 7&nbsp;
    <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

Jadran Josimovic
Jadran Josimovic

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

Carlos
Carlos

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

Related Questions