2

I am trying to modify the sample application provided by meanjs The sample application has a angularsjs view which looks as follows

  <input class="form-control" type="text" name="roles" 
  ng-model="vm.user.roles" id="roles" ng-list required />

The part of the mongoose model which updates the roles is as follows.

/**
 * Module dependencies
 */
var mongoose = require('mongoose'),
  Schema = mongoose.Schema,
  crypto = require('crypto'),
  validator = require('validator'),
  generatePassword = require('generate-password'),
  owasp = require('owasp-password-strength-test'),
  path = require('path'),
  logger = require(path.resolve('./config/lib/logger'));
/**
 * A Validation function for local strategy properties
 */
var validateLocalStrategyProperty = function (property) {
  return ((this.provider !== 'local' && !this.updated) || property.length);
};

/**
 * A Validation function for local strategy email
 */
var validateLocalStrategyEmail = function (email) {
  return ((this.provider !== 'local' && !this.updated) || validator.isEmail(email, { require_tld: false }));
};

var validateRoles = function (roles) {
  console.log("validate");
  return true;
};
/**
 * User Schema
 */
var UserSchema = new Schema({
  firstName: {
    type: String,
    trim: true,
    default: '',
    validate: [validateLocalStrategyProperty, 'Please fill in your first name']
  },
  lastName: {
    type: String,
    trim: true,
    default: '',
    validate: [validateLocalStrategyProperty, 'Please fill in your last name']
  },
  displayName: {
    type: String,
    trim: true
  },
  email: {
    type: String,
    unique: true,
    lowercase: true,
    trim: true,
    default: '',
    validate: [validateLocalStrategyEmail, 'Please fill a valid email address']
  },
  username: {
    type: String,
    unique: 'Username already exists',
    required: 'Please fill in a username',
    lowercase: true,
    trim: true
  },
  password: {
    type: String,
    default: ''
  },
  salt: {
    type: String
  },
  profileImageURL: {
    type: String,
    default: 'modules/users/client/img/profile/default.png'
  },
  provider: {
    type: String,
    required: 'Provider is required'
  },
  providerData: {},
  additionalProvidersData: {},
  roles: {
    type: [{
      type: String,
      enum: ['USR', 'ADM', 'SAD']
    }],
    default: ['USR'],
    required: 'Please provide at least one role',
    validate: [validateRoles, 'Please provide at least one role']
  },
  updated: {
    type: Date
  },
  created: {
    type: Date,
    default: Date.now
  },
  /* For reset password */
  resetPasswordToken: {
    type: String
  },
  resetPasswordExpires: {
    type: Date
  }
});

Now I am trying to convert the above text input into checkbox . My modified view is a follows

  <label ng-repeat="rolename in vm.rolesnames">
  <input type="checkbox" text={{rolename}} 
  ng- checked="vm.chooserole(rolename)" ng-model="vm.user.roles">
  {{rolename}}
  </label>

My Angularjs controller which updates the roles as follows

vm.rolesnames = ['USR', 'ADM', 'SAD']; //dummy for view
vm.userused = new Set(user.roles);// this is from model

function chooserole(rolename) {
  console.log("chooserole");
  if (rolename === 'USR') {
    return vm.userused.has('USR');
  } else if (rolename === 'ADM') {
    return vm.userused.has('ADM');
  } else if (rolename === 'SAD') {
    return vm.userused.has('SAD');
  }
  return false;
}

Whenever the page is loaded the roles for the users are assigned correctly but whenever I click the check-box all the three check-box get selected. how do I bind the checkbox to enum and send it to the model?

Rengas
  • 593
  • 1
  • 6
  • 25

1 Answers1

0

What does your model look like? I would suggest using a ui-select https://github.com/angular-ui/ui-select instead of the multiple checkboxes as it is much cleaner UX and less controller code to maintain. Then you can create an enumeration of roles and that can be managed and all your code will continue to use that enumeration of roles. Much easier to manage.

angular.module('globals', [])
  .constant('Roles', ['USR', 'ADM', 'SAD']);

Here is my property in the User Model:

  roles: {
    type: Array,
    default: ['USR']
  }

In my controller scope the roles OR use dependency injection to load the global enumerations / roles as described above:

$scope.rolesNames = ['USR', 'ADM', 'SAD];

For the Front End / Angular I use a UI-select

  {{user}}
  <br/>  
           <ui-select multiple ng-model="user.roles" theme="select2" ng-disabled="disabled" style="width: 300px;">
            <ui-select-match placeholder="Select roles...">{{ $item }}</ui-select-match>
            <ui-select-choices repeat="role in rolesNames">
              {{ role }}
            </ui-select-choices>
          </ui-select>
Enkode
  • 4,515
  • 4
  • 35
  • 50
  • Thank you for the answer. I have updated the entire model. I will try out with the ui-select module to replace checkbox. – Rengas Apr 19 '16 at 08:45
  • I tried doing the checkbox method you wanted to use and it is messy. It is possible to fix your methods but it is so much extra work to sync the checkboxes and then update the user object that it is not something I would recommend. – Enkode Apr 19 '16 at 17:06
  • @Rengas How did that work out? Please mark my answer as correct if it worked for you. Thanks – Enkode Apr 20 '16 at 23:06
  • I figured the problem was because checklist is always linked with one model. Since I am very new to meanjs. I was lost along the way trying to change things in the app with your answer. At one point I wasn't even sure what I was doing. So for now I resolved it by using [checklist-model](https://vitalets.github.io/checklist-model/). Thank you for the answer. – Rengas Apr 21 '16 at 08:41