Nintex Forms: How to disable or hide option in Choice control?

  • 27 November 2015
  • 20 replies
  • 42 views

Badge +7

I have a form with a Choice control. It has a number of choices, and I need some of them to be either hidden or disabled based on some condition. In my case the condition is something like

   fn-IsMemberOfGroup("administratorgroup")

 

How can I achieve this?

 

Regards

Leif


20 replies

Userlevel 6
Badge +16

I'd do it having 2 panels of choices, 1 (visible) for administrators and the other for NonAdministrators

Badge +7

That could be a way to go, but I am implementing tabs (as per Nintex Forms - Tab like Functionality - Vadim Tabakman  ​) where each tab is reprented as an option in a Choice control. My goal is then to have the Administrator tab be either disabled or hidden (whatever is achievable) for those not member of the correct security group. Hence the need to be able to control the visibility/availability of each option.

/Leif

Badge +7

Hi Ratnesh,

I did try fooling around with JS, but was unable to get it right. COuld you supply me with the code that would do the trick?

Regards

Leif

Badge +5

Hi Leif.

Not sure if you found a solution yourself but the following are the js code required to achieve what you wanted here.

NWF$(document).ready(function()
{

   if(IsCurrentUserMemberOfGroup("administratorgroup"))

  {

    //remove options
      NWF$("#"+myOptions).find("option[value='Option 1']").remove()

  }

});

//check if member belongs to a sharepoint group

function IsCurrentUserMemberOfGroup(groupName) {

    var dfd = NWF$.Deferred(function(){
        var currentContext = new SP.ClientContext.get_current();
        var currentWeb = currentContext.get_web();

        var currentUser = currentContext.get_web().get_currentUser();
        currentContext.load(currentUser);

        var allGroups = currentWeb.get_siteGroups();
        currentContext.load(allGroups);

        var group = allGroups.getByName(groupName);
        currentContext.load(group);

        var groupUsers = group.get_users();
        currentContext.load(groupUsers);

        currentContext.executeQueryAsync(
          function(sender,args){
              var userInGroup = false;
              var groupUserEnumerator = groupUsers.getEnumerator();
              while (groupUserEnumerator.moveNext()) {
                  var groupUser = groupUserEnumerator.get_current();
                  if (groupUser.get_id() == currentUser.get_id()) {
                      userInGroup = true;
                      break;
                  }
              }
              dfd.resolve(userInGroup);
          },
            function(sender,args){
                console.log(args.get_message()+" "+groupName);
                dfd.resolve(false);
                //dfd.reject(args.get_message());
            }
        );
    });
    return dfd.promise();
}

Badge +7

Hi Thomas,

Thank you for your input - it seems to be in the right direction. However I have one problem with getting the code to work: Because of the asynchronous nature of the code, the function IsCurrentUser... is getting a return value before the code that actually contains the logic to determine the result is run. I have tried to simplify what is happening in the code here, and in the image attached.

The simplified code:

NWF$(document).ready(function()

{

  1. console.log("A");

  if(myFunc())

  {

   console.log("B - myFunc returned true");

  } else

  {

   console.log("C - myFunc returned false");

  }

});

function myFunc() {

  console.log("D - starting myFunc");

  var dfd = NWF$.Deferred(function(){

  var currentContext = new SP.ClientContext.get_current();

  currentContext.executeQueryAsync(

        function(sender,args){

          console.log("D - succes");

          dfd.resolve(false);

        },

        function(sender,args){

          console.log("E - failure");

          dfd.resolve(false);

        }

  );

});

  console.log("F - returning promise");

  return dfd.promise();

}

Console output is:

A

D - starting myFunc

F - returning promise

B - myFunc returned true

D - succes

As you can see from the console output, myFunc returns true, even though both functions given to executeQueryAsync returns false.

So to illustrate the order of events graphically:

Untitled.png

As you can see, the promise is returned before the resolve happens.

I tried to remove everything in the original code that tasted like async, but then I got an error saying "the collection has not been initialized".

Please advise, how I can change this so my "business logic" is run before the function returns the result.

Regards

Leif

Badge +5

Hi Leif.

I just checked my working solution again. The following should get the function calling order right.

Let me know if any further issues

NWF$(document).ready(function()
{

  checkIfGroupMember("Group Name");

});

function checkIfGroupMember(groupName)
{
NWF$.when(IsCurrentUserMemberOfGroup(groupName).done(function(hasPermission){
   if(hasPermission)
   {
    IsGroupMember = true;
   }
   }),
  ).then(function(){
     if(IsGroupMember)
     {
     //your logic
     }
  
  });
}

Badge +7

Thank again - did not know about the when/then contruction in jQuery...

I implemented the following, where I move the stuff that I want done into the async functions. Some would probably say that it's not pretty, butit's pretty simple ;-)

The code now looks like this:

NWF$(document).ready(function()

{

          removeTabIfNotAllowed("Administrator","WorkWear Admins");

}

)

function removeTabIfNotAllowed(tabName,groupName) {

    var dfd = NWF$.Deferred(function(){

                   var currentContext = new SP.ClientContext.get_current();

                   var currentWeb = currentContext.get_web();

                   var currentUser = currentContext.get_web().get_currentUser();

                   currentContext.load(currentUser);

                   var allGroups = currentWeb.get_siteGroups();

                   currentContext.load(allGroups);

                   var group = allGroups.getByName(groupName);

                   currentContext.load(group);

                   var groupUsers = group.get_users();

                   currentContext.load(groupUsers);

                   currentContext.executeQueryAsync(

                       function(sender,args){

                              var userInGroup = false;

                              var groupUserEnumerator = groupUsers.getEnumerator();

                              while (groupUserEnumerator.moveNext()) {

                                 var groupUser = groupUserEnumerator.get_current();

                                 if (groupUser.get_id() == currentUser.get_id()) {

                                    userInGroup = true;

                                    break;

                                 }

                              }

                                        

                              if (!userInGroup) {

                                  NWF$("#"+varTabButtons).find("option[value=" + tabName + "]").remove();

                              }

                              dfd.resolve(userInGroup);

                        },

                        function(sender,args){

                              console.log(args.get_message()+" "+groupName);

                              dfd.resolve(false);

                        }

                   );

    });

    return dfd.promise();

}

/Regards

Leif

Badge +5

Yeah when and then are very useful for these kinda asynchronous functions and you can have mutiple of them as well.

NWF$.when(

function1().done(function(result1){

  if(result1 meets some condition)

  {  }

  }),

  function2().done(function(result2)

   {  }

  }

  functionN().........

  )

  ).then(function(){

  });

I usually use them with REST service ajax calls as well to solve the same timing problem especially when you have multiple calls.

Glad to hear your own solution worked happy.png

Badge +10

Hi Thomas,

Is there a way to disable an option item

thanks,

Badge +5

Yes,

Kind Regards,

Thomas Xu | Empired.com<http://www.empired.com/> | Senior Consultant, TS – Enterprise Solutions, Productivity |

Badge +5

Yes,  NWF$("your input control")[0].disabled = true;

Badge +10

Hi Thomas,

I tried it and it did not work, forgot to tell you that is a lookup control. It fills that data from a list. I just need to disable the last two items

I have tried this also, NWF$('#' + jsvCat).find("option[value='Goods']").attr('readonly',true);

Badge +5

Try this one below. I have used it for a drop down control in the past.

I usually use CSS class instead of Control CSS class on the control settings hence why the dot (.) below instead of hash (#)

NWF$(".className option[value='DropDownValueToRemove']").remove();

Kind Regards,

Thomas Xu | Empired.com<http://www.empired.com/> | Senior Consultant, TS – Enterprise Solutions, Productivity |

Badge +10

Hi Thomas, I don't want to remove it, i need to disable it.

Badge +5

Can you share some screenshot on what you are trying to do?

I was imaging a drop down list (linked to a look up list) . I was under the impression you want to prevent user from selecting a particular value hence why

Removing/adding a drop down value conditionally would make sense. I am not sure if you can disable a “Drop down value” from a drop down list.

Kind Regards,

Thomas Xu | Empired.com<http://www.empired.com/> | Senior Consultant, TS – Enterprise Solutions, Productivity |

Badge +10

Thanks, It is a lookup list display as option button.

189265_pastedImage_0.png

I have used another option control to have them on the screen and disabled. There is alignment issue when try it on browser.

Badge +7

By the way and along the lines of hiding options:  

Regards

Leif

Badge +5

‌, I found your post and seems similar to what I am being requested to do. I can "kinda" understand your code. I have a tab control named "Issue_Type" and I named my Client ID JavaScript variable name as "TabOptionHide", where do I substitute that in your code?

Would that be in line 5 or Line 65 or Both?

Badge +5

Is there someone that can assist me. I keep reading this post and I seem to keep getting lost more and more as I read.

If I use Leif Frederiksen's code and substitute my values and tabname, I presume I put the entire code into the form custom Javascript. I have have the field settings to store the javascript ID as "vTabOptionHide". How is this calling the variable, is there something I need to know for it to call the script the variable?
THe below code is what I inserted in the form as custom javascript, the bold sections is what I changed and I presume that would be correct?

NWF$(document).ready(function()

{

          removeTabIfNotAllowed("Issue_Type","WTS Leads");

}

)

 

function removeTabIfNotAllowed(tabName,groupName) {

    var dfd = NWF$.Deferred(function(){

                   var currentContext = new SP.ClientContext.get_current();

                   var currentWeb = currentContext.get_web();

                   var currentUser = currentContext.get_web().get_currentUser();

                   currentContext.load(currentUser);

                   var allGroups = currentWeb.get_siteGroups();

                   currentContext.load(allGroups);

                   var group = allGroups.getByName(groupName);

                   currentContext.load(group);

                   var groupUsers = group.get_users();

                   currentContext.load(groupUsers);

                   currentContext.executeQueryAsync(

 

                       function(sender,args){

                              var userInGroup = false;

                              var groupUserEnumerator = groupUsers.getEnumerator();

                              while (groupUserEnumerator.moveNext()) {

                                 var groupUser = groupUserEnumerator.get_current();

                                 if (groupUser.get_id() == currentUser.get_id()) {

                                    userInGroup = true;

                                    break;

                                 }

                              }

                                        

                              if (!userInGroup) {

                                  NWF$("#"+vTabOptionHide).find("option[value=" + tabName + "]").remove();

                              }

                              dfd.resolve(userInGroup);

                        },

                        function(sender,args){

                              console.log(args.get_message()+" "+groupName);

                              dfd.resolve(false);

                        }

                   );

    });

    return dfd.promise();

}

Userlevel 2
Badge +11

It is possible to do this without any JavaScript. Just use a formula for your administrator choice in the choices list, for example:

Menu Tab 1
Menu Tab 2
Menu Tab 3
fn-If(fn-IsMemberOfGroup("administratorgroup"),'Administrator Tab','')

This works only for (saved) item property values, not on Named Controls. I'm using it in at least 2 forms hiding a Copy Metadata panel tab if not in Is New Mode and workfs like a charm.

Reply