Create Request On Behalf Of - Radio Buttons and Text Change

Nicholas_VelichNicholas_Velich Cireson Consultant Ninja IT Monkey ✭✭✭✭
Original thread here: https://community.cireson.com/discussion/comment/5767

Summary of customization:

(1) Rather than allowing the analyst to immediately type in the user picker, they must first choose that they want to create on behalf of:



(2) Once they pick Yes, the picker appears as usual; however, notice the "placeholder text" now reads "Search for User" instead of the default "Choose One..."



The code used to accomplish this is attached. It would need to be copied into your custom.js file (ideally using getScript or the loadScript method). If you don't want the feature in (1) above, you can comment out or delete lines 6-21. If you want to change the placeholder text, that can be done on line 24.

Two other tidbits outside of the attached code:

(3) The actual "Create Request On Behalf Of" text can be changed in the localization section of the portal. The key you would override is "CreateRequestonbehalfof." Note that the "Choose One..." change could also be done from the localization section using the "ChooseOne' key; however, changes to localizations are Portal-wide, which might not be desirable.

(4) Changing what results appear once you start typing can be configured in the Admin Settings portion of the Portal. The keys you would modify in this case are "UserQuery" and "GroupQuery." If there is a particular attribute unique to all your Distribution Groups, you can add them to these search filter settings to omit them.

Comments

  • john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭
    edited March 2017
    One thing that should be added to the code above is a check to see that the user has the right to create tickets on behalf of other users. If they don't, then the control which the code is looking for will not be present on the form, and the page will not load.

    This code should be added near the start of the function:
    $(window).load(function () {
           if (!session.user.Security.CreateOnBehalf) return;

  • Brian_WiestBrian_Wiest Customer Super IT Monkey ✭✭✭✭✭
    The original script did make sure you were on a URL that checked for URL location. However to meet the request added both clauses to the if statement. 

    $(window).load(function () {
        if ((document.URL.indexOf("ServiceCatalog/RequestOffering") === -1) || (!session.user.Security.CreateOnBehalf)) { //Only worry about request offering forms
            return; 
        }

  • john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭
    Hi Brian,

    I didn't mean to replace the RequestOffering condition, but you can combine the two statements as you have done.
  • Tim_ShackletonTim_Shackleton Customer IT Monkey ✭
    I'm having issues with this script, in that I don't see any of the changes to the field.  I've tried placing the script directly in custom.js as well as in a separate file that is called via $.getScript.

    What could I be doing wrong?

  • john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭
    The most likely explanation is that there is a syntax error in the custom.js file which is stopping the code from executing. Open developer tools in the browser and check for errors on the console tab.
  • Tim_ShackletonTim_Shackleton Customer IT Monkey ✭
    edited April 2017
    The most likely explanation is that there is a syntax error in the custom.js file which is stopping the code from executing. Open developer tools in the browser and check for errors on the console tab.

    There is a syntax error in the original upload at the top of the page.  Line 24 is missing a semicolon.
  • Brad_HayesBrad_Hayes Member IT Monkey ✭

    I made some changes to the script and changed the radio buttons to a toggle.

    /*************************************/
    /*** Request on Behalf of Toggle ***/
    /*************************************/

    // Only load code on Request Offering page
    $(window).load(function() {
     if (document.URL.indexOf("ServiceCatalog/RequestOffering") === -1) {
      if (!session.user.Security.CreateOnBehalf) return;
     }
     
     // Hide create request on behalf of picker by default
     $('.control-label:contains("' + localization.CreateRequestonbehalfof + '")').parent().find('.two-action-input-group').hide();  
     
     // Create toggle and append after the picker
     var toggler_CBR = $('<button class="toggler">Switch...</button>');
     toggler_CBR.appendTo('label.control-label:contains("' + localization.CreateRequestonbehalfof + '")');

     // Set toggle function (Show Hide)
     $("#button_CRB").button()
     $("button.toggler").click(function() {
      $Switch = $(this);
      $Switch.toggleClass('off');
      if ($Switch.is(".off")) {
       $('.control-label:contains("' + localization.CreateRequestonbehalfof + '")').parent().find('.two-action-input-group').show();
      }
      else {
       $('.control-label:contains("' + localization.CreateRequestonbehalfof + '")').parent().find('.two-action-input-group').hide();
      }
     });
      
     // Change the placeholder text in the picker
     $('.control-label:contains("' + localization.CreateRequestonbehalfof + '")').parent().find('.k-input.search-combo').attr("placeholder", "Search for User")
    });

  • Joshua_WalkerJoshua_Walker Customer IT Monkey ✭
    Will the "Yes" and "No" text follow the localization if we switch languages? i figured the answer is no since it seems to be hardcoded into the script. We use the portal in english and french so any customization i want to apply, i have to make sure i can support it in both languages.
  • Nicholas_VelichNicholas_Velich Cireson Consultant Ninja IT Monkey ✭✭✭✭
    Hi @Joshua_Walker

    The script as provided above is only partially localized, but it would be a fairly simple update to localize it the rest of the way. Note in the code that the text for "Create on behalf of" is referenced via localization key, not hard-coded text, i.e. - localization.CreateRequestonbehalfof. The same concept would need to be applied for "Yes," "No," and any other hard-coded text within the code.

    You can view all Portal localizations, override localizations or add new localizations by clicking your name in the top-right, then selecting "Localizations." Either way, localizations are all referenced in code via localization.localizationkey.
  • Mark_GearyMark_Geary Customer IT Monkey ✭
    Is there any way that we can show this for the end users?
  • damon_mulligandamon_mulligan Cireson Consultant Advanced IT Monkey ✭✭✭
    If you place "Domain Users" in the Admin Settings > Setting Items > CreateOnBehalfGroup
    You have to make sure the "Domain Users" AD Group is in your SCSM Users CI, then make sure it is populated in the Cache for the Portal.
  • Steve_ClarkeSteve_Clarke Customer Adept IT Monkey ✭✭
    Hi @Nicholas_Velich

    The rendering is a little messed up in the latest version of the portal. Is it possible to get an updated version? Great modification btw :)

    Thanks
  • Nick_FlintNick_Flint Customer Advanced IT Monkey ✭✭✭
    @Steve_Clarke

    Try adding this to your custom.css:

    /*Fix Create on Behalf of Button Rendering*/
    input#behalfdisabled, input#behalfenabled
    {
        width: 3%;
    }

  • Brian_WiestBrian_Wiest Customer Super IT Monkey ✭✭✭✭✭
    @Nick_Flint
    That did the trick for my environment, Thanks
  • Steve_ClarkeSteve_Clarke Customer Adept IT Monkey ✭✭
    Awesome, thank you @Nick_Flint.
  • Stefan_BarrettStefan_Barrett Customer IT Monkey ✭
    Greetings @Nicholas_Velich @Adrian_Paech @Brad_Hayes and anyone else that can sound off on this.

    We've been using this custom function here for a couple years now (love it!).  Specifically, it looks like our code is a direct copy of the Adrian Paech version.  We upgraded from SCSM 2012 to SCSM 2016/1801 in June, and continued to use it on Cireson Portal v8.4.2.2016.

    Here's our issue - we just built out our Dev environment, and all our custom stuff (including this) was working fine (also on v8.4.2.2016).

    We are NOW attempting to test upgrade our portal (on Dev) to v8.12.6.2016, and all of our custom add-ons are working EXCEPT THIS ONE.  :-(

    I've tried modifying the relevant .js file referenced in custom.js for this (in our case, it is titled 'custom_OnBehalfOf.js').  I've tried copying back in original code from each of the individuals listed above.  I've tried remarking out different lines and adding stuff in.

    I even tried replacing it with code for a completely different function (Convert IR to SR) temporarily, just to make sure I didn't have a syntax error in my custom.js $.getScript line (indeed, when placed here the code for Convert IR to SR worked just fine).

    I'm at a logger-heads.  Anyone have any thoughts or ideas that might help us out?  (For now, my manager has authorized going ahead with the upgrade without this functionality, but I'm loathe to ask our business users to take a step back on this feature.)

    Thanks all!  Cheers!
  • Adrian_PaechAdrian_Paech Customer Advanced IT Monkey ✭✭✭
    Hi Stefan,
    We recently updated our version too, and had to make some changes. I cant remember what exactly :-/

    Either way, here is our current code. (below)
    This version also allows "Multiple users" to be selected, instead of just a single user.
    By default you will not be able to pick multiple users, only yourself, or a user on behalf of...
    However, to enable the "Multiple users" option on a specific form (after putting in this code below), ensure the first field in any RO is labelled "##Multiple Affected User Picker##". This field must be a query results picker, filtered to the appropriate user's (all users in our case).

    Hopefully this helps.
    --
    $(document).ready(function () {
        if (document.URL.indexOf("ServiceCatalog/RequestOffering") === -1) { //Only worry about request offering forms
            return;
        }  //1. "Request On Behalf Of:" (ROBO) to "Requested For:", Add Radio Boxes   //Get Request on Behalf Of Object  var dom_ROBO = $('.control-label:contains("' + localization.CreateRequestonbehalfof + '")');  var dom_MUP = null;
     var dom_MUPbr = null;
     
     //If "DL Membership" form, or "New Staff Member"form, or "Third Party User Request" or "Exit Staff Member" form or "Privileged access" or "Generic User" form, Hide 'Request on Behalf Of' fields all together.
     if (document.URL.indexOf("34287363-7053-e97c-e315-d3b0f794c241") != -1 || document.URL.indexOf("6eb75065-50c4-2a66-d842-0adabd0d599d") != -1 || document.URL.indexOf("1201dd35-c347-7086-a6d0-ce9c6cef4964") != -1 || document.URL.indexOf("00a4e752-9c58-f32b-3a16-d981877036dc") != -1 || document.URL.indexOf("13611be5-a0dc-f6c2-5469-6b45b1795d93") != -1) {
      dom_ROBO.parent().hide();
     }  
     //Else Rename "Request On Behalf Of:" to "Requested For:", Add Radio Boxes
     else {
      try {
       //If Change Form Found.               
       if (document.URL.indexOf("ac31564a-0256-2f95-0300-c8fdb3aa2d06") != -1) {
        dom_ROBO[0].innerHTML = "<div style='padding-top: 5px; padding-bottom: 10px;'><strong>Who will be implementing this change?</strong></div>";        
        localization.CreateRequestonbehalfof = "Change Implementer: ";
        
        //Move Selection of Implementer within Change Implementer Section.
        var dom_ChangeImplementerSection = $("h3:contains(Change Implementer)")[0];    
        dom_ROBO.parent().insertAfter(dom_ChangeImplementerSection);    
       }   
       //If External Change Form
       else if (document.URL.indexOf("a99811a1-4b0a-88dc-8b50-7d4e7ca97a8b") != -1) {
        dom_ROBO[0].innerHTML = "<div style='padding-top: 25px; padding-bottom: 10px;'><strong>Who will be implementing this change?</strong></div>";        
        localization.CreateRequestonbehalfof = "Change Implementer: ";
        
        var dom_FirstPage = $('[ng-show="(currentIndex==0)"]');
        dom_FirstPage.prepend(dom_ROBO.parent());
       }
       //If Exit User Form
       else if (document.URL.indexOf("0dc69c53-9a09-c5d3-4329-5e2046935740") != -1) {
        dom_ROBO[0].innerHTML = "<h4>Who is exiting the department?</h4>";
        localization.CreateRequestonbehalfof = "Who is exiting the department?";
        
        var dom_FirstPage = $('[ng-show="(currentIndex==0)"]');
        dom_FirstPage.prepend(dom_ROBO.parent());
       }
       //If Incident Form Found.
       else if (document.URL.indexOf("RequestOffering/c6590bf5-3fd2-99a0-18b4-f3588ff39d0f,0bc35644-30dc-8d12-4cc9-8248b9d4ed5c") != -1) {
        dom_ROBO[0].innerHTML = "<h4>Who is experiencing this fault / incident?</h4>";
        localization.CreateRequestonbehalfof = "Who is experiencing this fault / incident?";
        
        var dom_FirstPage = $('[ng-show="(currentIndex==0)"]');
        dom_FirstPage.prepend(dom_ROBO.parent());
       }
       //If Request Form Found.
       else {
        dom_ROBO[0].innerHTML = "<h4>Who is this request for?</h4>";
        localization.CreateRequestonbehalfof = "Who is this request for?";
        
        var dom_FirstPage = $('[ng-show="(currentIndex==0)"]');
        dom_FirstPage.prepend(dom_ROBO.parent());
       }
       
       dom_ROBO.parent().find('.two-action-input-group')[0].style.width = "50%";
       dom_ROBO.parent().find('.two-action-input-group')[0].style.maxWidth = "300px";
       $('.two-action-input-group__primary-action')[0].style.marginTop = "-32px";
       $('.two-action-input-group__primary-action')[0].style.marginRight = "-52px";
       $('.two-action-input-group__primary-action')[0].style.marginBottom = "30px";
       $('.two-action-input-group__primary-action')[0].style.styleFloat = "right";
       
       // v6 - Change interactions with create on behalf of picker; user must select "Another Staff Member" before being able to enter a username
       dom_ROBO.parent().find('.two-action-input-group').show();  // Find our div with the On Behalf Of Picker
       
       // Create some radio buttons, and append them just after the picker
       // External Change Form (Add Specify Vendor as an option)
       if (document.URL.indexOf("a99811a1-4b0a-88dc-8b50-7d4e7ca97a8b") != -1) {
        var radioBtn = $('<div style="padding-bottom:10px;"><div style="display:inline-block;"><input id="behalfdisabled" type="radio" name="rbtnCount" /></div><div style="display:inline-block;">&nbsp;&nbsp;&nbsp;Myself</div> <br><div style="display:inline-block;"><input id="behalfenabled" type="radio" name="rbtnCount" checked/></div><div style="display:inline-block;">&nbsp;&nbsp;&nbsp;Specify Vendor</div></div>');
       }
       // All other Forms
       else {
        dom_MUP = $('.control-label:contains("##Multiple Affected User Picker##")');
        
        // Hide h3 label for f
        $('.page-panel').prev()[0].style.display = "none";
        
        if (dom_MUP.length == 1) {      
         dom_MUPbr = $('<br>');
         dom_MUP[0].innerHTML = "<div>Search for staff in the <i>Filter</i> field below and then <b>select all affected users</b> by clicking on each staff member in the list below.<br><br></div>";
         dom_MUP[0].style.textTransform = "none";            
         dom_MUP.next().append(dom_MUPbr);
         
         dom_MUP.hide();
         dom_MUP.next().hide();
         dom_MUP.next().next().hide();
         var radioBtn = $('<div style="padding-bottom:10px;"><div style="display:inline-block;"><input id="behalfdisabled" type="radio" name="rbtnCount"/></div><div style="display:inline-block;">&nbsp;&nbsp;&nbsp;Myself</div><br><div style="display:inline-block;"><input id="behalfenabled" type="radio" name="rbtnCount" checked /></div><div style="display:inline-block;">&nbsp;&nbsp;&nbsp;Another Staff Member</div><br><div style="display:inline-block;"><input id="behalfmultienabled" type="radio" name="rbtnCount" /></div><div style="display:inline-block;">&nbsp;&nbsp;&nbsp;Multiple Staff</div></div>');
        }
        else {
         var radioBtn = $('<div style="padding-bottom:10px;"><div style="display:inline-block;"><input id="behalfdisabled" type="radio" name="rbtnCount"/></div><div style="display:inline-block;">&nbsp;&nbsp;&nbsp;Myself</div><br><div style="display:inline-block;"><input id="behalfenabled" type="radio" name="rbtnCount" checked /></div><div style="display:inline-block;">&nbsp;&nbsp;&nbsp;Another Staff Member</div></div>');
        }
       }
       radioBtn.appendTo(dom_ROBO);
       
       // When the radio buttons change, we might want to hide or show the search box.
       radioBtn.change(function(){
        if(document.getElementById('behalfenabled').checked){
         dom_ROBO.parent().find('.two-action-input-group').show();
         if (dom_MUP != null && dom_MUP.length == 1) {
          dom_MUP.hide();
          dom_MUP.next().hide();
          dom_MUP.next().next().hide();
         }
        }
        else if(document.getElementById('behalfmultienabled') != null && document.getElementById('behalfmultienabled').checked){
         dom_ROBO.parent().find('.two-action-input-group').hide();
         
         if (dom_MUP != null && dom_MUP.length == 1) {
          dom_MUP.show();
          dom_MUP.next().show();
          dom_MUP.next().next().show();
         }
        }
        else{
         dom_ROBO.parent().find('.two-action-input-group').hide();
         
         if (dom_MUP != null && dom_MUP.length == 1) {
          dom_MUP.hide();
          dom_MUP.next().hide();
          dom_MUP.next().next().hide();
         }
        }
       });
      }
      catch (err) {
       // Continue on error if "Request on Behalf Of" Does not Exist.
      }
     }
     // Change the placeholder text in the picker
     dom_ROBO.find('.k-input.search-combo').attr("placeholder", "Search for User")
    }



  • Stefan_BarrettStefan_Barrett Customer IT Monkey ✭
    Hey @Adrian_Paech - thank you so much!

    So the overall code here was a bit overkill for our own environment (looks like you've done substantial customization for your org), however, it was enough to prove out that I could get it to work. :-)  (I did add a paren and semi-colon at the very end ");" and then it worked.)

    I tried commenting stuff out (like the explicit ROs you mention, and the CR stuff) and again, it continued to work on the whole.  SO...here's what I came up with.

    The difference seems to be this:
    Your new code starts with
    $(document).ready(function () {
        if (document.URL.indexOf("ServiceCatalog/RequestOffering") === -1) { //Only worry about request offering forms
            return;
        }
    Whereas the old version starts with
    $(window).load(function () {
        if ((document.URL.indexOf("ServiceCatalog/RequestOffering") === -1) || (!session.user.Security.CreateOnBehalf)) { //Only worry about request offering forms
            return;
        }
    The clincher seems to be with stating $(document).ready instead of $(window).load.  I don't understand the code well enough to know why; I just recognized that this seemed a significant difference in the call.

    Anyway, I updated your original code (that we've been using) with that new first statement and it works great!

    I did find as with @Steve_Clarke that the formatting was goofed up (the radio buttons were way out to the right of the text labels), but the correction provided by @Nick_Flint ; for the 'custom.css' made all the difference.

    Thank you so much for responding so quickly, and hats off to all of you for your various contributions.  Great stuff!  Cheers!
    Stefan
  • Adrian_PaechAdrian_Paech Customer Advanced IT Monkey ✭✭✭
    Glad it helped :)
    Adrian
Sign In or Register to comment.