How to build a Registration or Sign-Up Solution in SharePoint

6.58K
Views

Ever have someone ask you to build a registration form for training or sign-up sheet for an event on SharePoint?  Seems simple enough until you go to do it…  Well next time that happens give this a try!

Create the Lists

  • Calendar List – use the out of the box Calendar list and add these fields
    • Seats – Number field
    • FilledSeats – Number field
    • RemainingSeats
      • Calculated Field
      • Formula: =Seats-FilledSeats
      • Data type returned: Number
    • SeatsIncrement
      • Calculated Field
      • Formula: =FilledSeats+1
      • Data type returned: Number
    • Closed – Yes/No
      • Default Value: No
    • StaticID – Number
      • Note: This is a Hack we have to put in because we can’t use the real ID field in a calculated column. We will use a workflow to fill it in correctly later. I am open to suggestions on a better way to do this
    • Register
      • Calculated Field
      • Data type returned: Single line of text
      • Formula :

  • Attendees List – custom SharePoint list, add these fields:
    • Username
    • Single line of Text Field
    • Required
  • Meeting
    • Lookup Field
      • Get Information from – Calendar List created earlier
      • In this column – Title field
    • MeetingID – Single line of text field

Workflows

SetStaticClassID Workflow

The SetStaticClassID Workflow is really a hack because SharePoint won’t let you use the ID field in the calculated columns. All we are doing is setting a number field with the ID field every time the calendar item is created or modified. For our particular situation, this will work fine. However, don’t assume this technique will work in every situation you need to use the ID field in a calculated column.

Go to the Calendar List created earlier. Edit the Calendar List in SharePoint Designer (note: you will need SharePoint Designer 2010 to do this)

  • Choose List Workflow in the Ribbon of SharePoint Designer
  • Give the Workflow a good name – something like SetStaticClassID
  • Add an Action – “Set Field in Current Item”
  • Click the “field” link – choose StaticID
  • Click the “value” link and clickt the fx button:
    • Data source: Current Item
    • Field from source: ID

Your Workflow should look like this:

setstaticid

Save your work.

Go back to the settings page for the Workflow. Set the Start Options for “Start Workflow automatically when an item is created” and “Start workflow automatically when an item is changed”

Save and Publish your workflow.

Registration Workflow

The Registration Workflow is one of the main parts of this solution. This is the Workflow that will update the remaining seats in the calendar list when an Attendee register for the course.

Go to the Attendee List created earlier. Edit the Attendee List in SharePoint Designer.

  • Choose List Workflow in the Ribbon of SharePoint Designer
  • Give the Workflow a good name – something like Registration
  • Add an Action – “Update List Item”
  • Click the “this list” link in the action
  • Change the list ot the Calendar list created earlier
  • Click the “Add…” button
    • Choose “FilledSeats”
    • Click the fx button for the value
      • Data source: Calendar
      • Field from source: SeatIncrement
      • Field: ID
      • Value – click the fx button
        • Data source: Current Item
        • Field from source: Meeting
  • In the Find the list item section
    • Field: ID
    • Value – click the fx button
      • Data source: Current Item
      • Field from source: Meeting

Save your work.

Go back to the settings page for the Workflow. Set the Start Options for “Start Workflow automatically when an item is created”

Save and Publish your workflow. It should look like this :

registration

InfoPath Form

The end user will eventually register through the InfoPath form on the Attendees list.

  • Go to the Attendees list in SharePoint
  • Choose to Customize the Form in the Ribbon (note: you will need InfoPath Designer to do this)
  • AutoPopulate the Title Field: In the title field of the form
    • Right-click – Text Box Properties
    • Default value – click the fx button
    • Add this in for the Formula:

Note: copy and paste will not work on this formula. You will have to delete the “Meeting” string in the formula and use the “Insert Field or Group” button instead and choose the Meeting field

  • Add a formatting rule – “Hide this control” to both the Title and MeetingID fieldsNote: You should also delete the label for these fields and move them to the bottom of the form and delete the empty table rows they were in. This will make these fields invisible to the end user, but they will still be there to bind to the SharePoint list
  • In the Username field of the form
    • Right-click – Text Box Properties
    • Default value – click the fx button
    • Add this in for the Formula: userName()
  • Add a formatting rule to the Username field to “Disable this control”
  • In the Meeting field of the form
    • Click the “Default Value” button in the Control Tools – Properties tab of the ribbon
    • Default value – click the fx button
    • Add this in for the Formula using the “Insert Field or Group” button: MeetingID
  • Add a formatting rule to the Meeting field to “Disable this control”
  • Publish the form

Querystring

In order to automatically set the the meeting in the InfoPath form, we will use a query string to the MeetingID field. There are a few problems to this:

  1. You can’t send querystrings to InfoPath: Solution = use a Query String Filter Web Part on the SharePoint page
  1. The Query String Filter Web Part can’t set a lookup field. Since our Meeting column is a lookup field, this won’t work. Thus, we created a MeetingID field. This is a hidden field on the InfoPath form that is purely used to set the Meeting lookup field in the form. The end user will never see this field

Go to the Attendees list on the SharePoint site.

Right-Click on the “Add new item” link and choose to open in a new window or a new tab.

Now you will be on the edit form page – click Site Actions – Edit Page.

Add a Query String (URL) Filter field to the site.

Modify the Settings and add

  • Fiter Name – QueryString
  • Query String Parameter Name – meeting_id
Connect the Query String (URL) Filter Web Part to the InfoPath Form Web Part

Use the “MeetingID” filed as the Consumer Field Name

Now when anyone comes to the new form of your Attendees list, it will be filtered by the querystring on the MeetingID field. The InfoPath form is setup to use the MeetingID text field to populate the Meeting dropdown box. This allows us to automatically pick the dropdown of the event the attendee wishes to register from.

Javascript

The last step to this is a javascript file. The javascript does two things:

  • Creates the dialog box javascript to open our new form. The call to this javascript method is in the calculated field on the attendees list to register
  • Turns the calculated field column into html
Note: The solution below uses JQuery because it is the easiest way to loop through multiple elements on the client side. If you do not have JQuery in your solution then:
  • Download the latest version of JQuery
  • Upload the file to your SharePoint site. I usually like to use the Style Library library at the root of the site collection
  • Add a reference to JQuery on your page:

Note: consider adding this as the first line of text in a Text File and then add the rest of the Javascript below to that same Text File. Then you can upload the Text File to a library on your site (I usually use the Style Library or Site Assets Library for this) and you can reference the text file from a Content Editor WebPart on the page we are creating.

IMPORTANT: Please change the url in the javascript to point to your new form (remember, you can right click on the add new on the Attendees list and open in new tab or window). This will show you the path to the new form and the List GUID. Also, make sure you keep the meeting_id at the end as a query string parameter.

Putting it all together

SharePoint, put a Content Editor WebPart on your page and reference the text file in the options of the Content Editor Web Part. Just make sure this Content Editor WebPart is underneath the Calendar list webpart)

Edit the Calendar list webpart and choose the default view (this should be the All Events or Current Events view depending on yoru requirements). Do not use the Default Calendar view (so that you can show the new register link). Modify the view you chose. Make sure the “Register” column is visible to the end users because that is the link they will click to register.

Now the end users can add a new meeting in the Calendar (make sure they know to set the amount of seats available). I also suggest putting a nice message on the InfoPath form telling the end user to Save the form to register for the class. Otherwise, it might not be intuitive for the end user to know to hit the Save button in order to register. You could also add a Register button that just saves the form if you want.

(6583)

4.8/5 (7)

Please rate this

How to build a Registration or Sign-Up Solution in SharePoint

Profile photo of Rick Mucha
About The Author
- I am currently an Enterprise Applications Analyst for Runzheimer International. My main focus is SharePoint and Salesforce development.

102 Comments

  • Profile photo of Darrell Houghton
    Darrell Houghton
    Reply

    Hi Rick, great information. I can’t wait to try it. Under the Workflow section there is a reference to “Your Workflow should look like this:” but no illustration. Was there an image that should go there?  

  • Profile photo of Rick Mucha
    Rick Mucha
    Reply

    Check over the Javascript section, that is what turns the register field into a hyperlink.  Make sure you are updating the URLs in there.   The link to JQuery, your list, and make sure it is referenced on the page.   Given that it’s not displaying as a hyperlink the issue must be there. 

  • Profile photo of Mike Koach
    Mike Koach
    Reply

    Hi Rick.  I’m having an issue replicating what you did.  Everything is working correctly with the exception of the querystring.  It is not pulling this information from the calendar and populating the fields on the attendees list.  I have tried it several different times, but I can’t seem to get it to work right.  Any ideas as to what might be wrong?

  • keithwinnett
    Reply

    @Jacob, I have done something similar without Infopath, only using SP Designer.  Send me a message if you want some ideas.  I will say Rick’s way is probably more of a “best practices” solution than mine, but I don’t use Infopath or Javascript.

  • Profile photo of Steve Mitchell
    Steve Mitchell
    Reply

    Hi Rick, the Url in the Java script is not redirecting hyperlink to the attendee form. Any thoughts? I have changed Url to point to the form, hyperlink is showing up but is redirecting to the calendar list.

    <script type=”text/javascript” src=”/Style Library/jquery-2.1.4.min.js></script>

    <script type=”text/javascript”>
    function OpenLandLRegistration(meeting_id){
    var options = {
    url:”/Lists/Attendees/Item/newifs.aspx?List=275c66e6%edf1%4cc1%a352%cd242bea0dfe&meeting_id=” + meeting_id,
    width: 750,
    height: 600,
    dialogReturnValueCallback: DialogCallback
    };
    SP.UI.ModalDialog.showModalDialog(options);
    }
    function DialogCallback(dialogResult, returnValue){ }

    // Reformat the url in the calculated column

    reformatCalculatedColumnUrl();
    function reformatCalculatedColumnUrl(){
    $(“.ms-listviewtable td.ms-vb2:contains(‘href’)”).each(function(){
    $(this).html($(this).text());
    });
    }
    </script>

  • Profile photo of Joe
    Joe
    Reply

    I successfully implemented the calendar event registration with some minor tweaks. I originally had the same issue as Nick G., “The register link; I get this in the column instead of a hyperlink: <a href=’#’ onclick=’OpenLandLRegistration(1)’>Register</a>”. I carefully reviewed the JavaScript and corrected my missing characters. Once I matched the JavaScript, the “Register” link displayed. I clicked on the link and I was directed to the same page. I trouble shot my issue by first making sure the workflows were working. I tested my attendee list form URL and included “&meeting_id=” and also included the “StaticID” number of a known event at the end of the address. The form came up and I was able to register for the event. The “Remainingseat” number decreased on the Calendar event, so I knew the workflow was working correctly.

    I noticed the calculation field “Register” within the Event Calendar displayed a “#” sign within ,”<a href=’#’. When I replaced the “#” with ‘<my attendee list form URL>&meeting_id=”&StaticID&”‘ the “Register” link was redirected to the form (do not include < > in URL).

    Is that the correct way the calculation should be? What was the reason for the “#” sign?

    Is there any way to automatically update the “Remainingseats” field if someone deletes their item from the Attendee list? Can the “Register” field have additional if statements to make it work?

    Once someone clicks on the attendee form Register (Submit) button, is there a way the close form function can redirect to another page instead of the Attendee list? If not, how can I set the form to open in another window instead of the same window?

    Setting the “Register” field “Data type returned:” to number worked the same as “Data type returned: Single line of text”. The only difference I noticed is when viewing the properties of an event. Setting field to “Single line of text” displayed a link within the properties. Setting to number did not display a link for the “register” field when viewing the properties of an event.

    Nick G., make sure you are not adding the line numbers within the JavaScript. Example, do not type 05 or 06 within the text file. Those are simple line numbers. Also, make sure you add &meeting_id= At the end of your attendee form URL.

    05width: 750,

    06height: 600,

    I created a web part page to display the Event Calendar and attendee list. Both views were set to only display upcoming events. For the attendee view, I also included the start and end times from the Event Calendar (From “Meeting” lookup field, select start and end time fields). The attendee view only displayed  events that are scheduled and the “Meeting” field is grouped (easier to see attendees listed). For the Attendee view, I only display the User Name.

    Implemented using SharePoint 2010 & SharePoint 2010 Designer.

  • Profile photo of Joe
    Joe
    Reply

    ***Update***

    I was able to redirect the form submission by adding a “Source” command after the InfoPath form URL.

    If you are trying to redirect users who submit an InfoPath to a Web Page after they Submit and Close the form, use ‘&Source=<URL to redirect to after submission>'. Be aware that if users click submit, close, or cancel, they will be redirect to the redirect page.

    Use the Register Calculated column to add the Source command. Here is the example using the Register formula:

    =IF(Closed=TRUE,”Closed for registration”,IF(RemainingSeats>0,”<a href=’http://MySharePointSite.com/Lists/Attendees/Item/newifs.aspx?List=034d3042%2D1f03%2D43cc%2D96fc%2Dc4ef0acfa92a&meeting_id=”&StaticID&”&Source=http://MySharePointSite.com/WebPartPage’ onclick=’OpenLandLRegistration(“&StaticID&”)’>Register</a>”,”Class is Full”))

  • Profile photo of Quy T
    Quy T
    Reply

    @Michelle Hines, @Steve Mitchell you can each accomplish you task of check for duplicate registration and send emails with event details using the Attendee InfoPath form.

    Anyone figure out how to “unregister”? or how to do waiting list? Also, really big help if anyone can figure out how to make the “register” link work when you click on details of the event.

  • Profile photo of Quy T
    Quy T
    Reply

    *** update, clarify ***

    @Michelle Hines, run a rule that will check if the current user name is equal to the “username” already in the event… if the user has already registered it will have a username already in Attendee.

    @Steve Mitchell, just create another view that you can send as an email via a data connection… (or create workflow) and add fields you like to be in the email.

  • Profile photo of Michelle Hines
    Michelle Hines
    Reply

    @Quy T – I didn’t get the rule to stop the duplicate registration, but rather I created a new Site Page and put up several web parts – such as “Past Attendance” and “My Schedule”. It also had the list of pending events that were open. I’m working on almost duplicating the whole structure now for when we hold “contests” – Our office raffles off monthly tickets to a concert venue and I want to get it out of email and into SharePoint.

    This page was possible because I played a lot with the SharePoint 2013 filter that only showed the current user’s information. But it is working great now.

    I had a way to “unregister” working while I was in a trial of Nintex Workflow and Forms. We plan on purchasing it – but we let the trial expire and the purchase is in the hands of budgetary people now — I don’t know when I’ll get it finalized and ready to use – but it was working so well – it was two clicks only.

    Lastly, I had to add a lot of extra columns for things like Department holding the training, Subject Matter and the Attendance column. From there I was able to do a lot of things like create a page for supervisors to go and pull reports of their own users with simply using filters.

  • Profile photo of Quy T
    Quy T
    Reply

    @Michelle Hines — wow that sounds like you have really got this going.

    I took this a little further (user friendly) and instead of using the list view as suggested in the blog. I went ahead and got the “register” link to actually show up on the displayform for the calendar. So the events page is a calendar vs a list, so it is more user friendly. User looks at a calendar and click on the event link, it displays all the information (natively as any other normal SP calendar event), plus it shows the register link and then user can register from there. I did a similar web part as you have described and displayed all events the current user is registered for.

    On the InfoPath form, I customized it to query for User Info from SP and AD, also queried the Calendar list and Custom list, so when the form opens it auto populates all the user and event info, so all the user has to do is verify the info before registering. The form then uses the queries to do my comparison for duplicate registration for the same event and notify the user if they already registered for the event. If no duplication, the form then sends and an email with a link so user can add the registered event to Outlook Calendar.

    As for reports, I have my Admin staff sync with Excel and they can do all sort of reports, charts, graphics, sorting, etc…

    I have a working “unregister” OOTB. I created another custom list and form and compared that list with the Attendee list via a WF and deleted appropriate items matching criteria. If the user wants to register for the event that they just unregistered for the WF reverses and deletes the item out of unregister list and allows them to re-register.

  • Profile photo of SBeare
    SBeare
    Reply

    @ Quy T and @Michelle Hines. I have been trying to get this registration site working since the beginning of the year when our IT department had major problems with the migration to SP2013, where they destroyed the old registration site . I had issues with Rick’s original post and can not figure out what went wrong. Is there any possible way either of you can post screen shots of how to get this registration site going?

  • Profile photo of Quy T
    Quy T
    Reply

    someone asked how I got the hyperlink to work on the Calendar view

    What I had to do was modify the original JavaScript that was in the blog, so that it can find the proper calculated column to convert into a hyperlink. The displayform of the Calendar view is a bit different structure than the List view. So here are the steps:

    1. Open your Calendar library
    2. Go to Calendar tab at the top left
    3. Select Form Web Parts > Default Display Form
    4. Click on “Add a Web Part“, Choose Media and Content, Choose Script Editor, click Add
    5. Click on Edit Snippet, then paste the below JavaScript in the text box, click Insert
    6. Click Stop Editing

    ========== Copy all lines below, Remember replace our Site URL ==================

    <script src=”https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js” type=”text/javascript”></script>
    <script type=”text/javascript”>

    //Creates window and opens the infopath form
    function OpenLandLRegistration(meeting_id){
    var options = {
    url:” http://replace with your site url/path to the custom list (as shown in blog)&meeting_id=” + meeting_id,
    width: 750,
    height: 600,
    dialogReturnValueCallback: DialogCallback,
    dialogReturnValueCallback: RefreshOnDialogClose
    };
    SP.UI.ModalDialog.showModalDialog(options);
    }
    function DialogCallback(dialogResult, returnValue){ }

    // Reformat the url in the calculated column to hyperlink
    $(function(){
    // Format link font size and weight
    $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).css(“font-size”, “18px”);
    $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).css(“font-weight”, “bold”);

    reformatCalculatedColumnUrl();

    function reformatCalculatedColumnUrl(){
    $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).each(function(){
    $(this).html($(this).text());
    });
    };
    });

    // Hides Columns
    $(function() {

    $(“a[name$=’StaticID’]”).closest(“tr”).hide();
    $(“a[name$=’SeatsIncrement’]”).closest(“tr”).hide();

    });

    </script>

    ========== Copy all lines above ===================

    So, now when you create an event, it will show up in the Calendar view as it should normally. When a user wants to register for the event, they will click on the hyperlink to the event created and another window will open. In this window will be the hyperlink for the “Register” calculated column and it will hide the two columns in the JavaScript.

    • Profile photo of Jeff Parker
      Jeff Parker
      Reply

      Hi Quy,
      I was able to get the register link to work in the list view, but cannot get the link to work in the calendar form view. Copied/pasted your code into text file, changed the URL to match the site URL like I did with the list view, and then added the text file to content editor web part that is below the display form web part for the calendar. Any ideas?

    • Profile photo of shannon_c
      shannon_c
      Reply

      Robert Woods and Quy T
      I am also using the online version and just cannot get the register link to display correctly. The url functions but is not user friendly. I am using the code Quy T posted above. Would either of you mind taking a look at my code/config to see if something I am doing wrong jumps out at you?

      Thanks,

  • Profile photo of Robert Woods
    Robert Woods
    Reply

    Now that I have the basics working maybe you could help me figure out how to tailor it to my needs?

    I have added a field to the registration form that allows the user to request between 1 and 4 tickets to the event they are registering for. I want to change the registration workflow to update the remaining FilledSeats based on the number of tickets requested instead of a static increase of 1 as is done with the SeatIncrement field. Any suggestions?

  • Profile photo of Quy T
    Quy T
    Reply

    @Robert Woods

    I did a quick test and it seems to work (possible you can fine tune it some more). We have to change the calculation to take place within the “Registration” workflow. The following are the steps I took to edit the InfoPath form and the “Registration” workflow on the Attendee list library.

    Step 1: Edit InfoPath form for Attendee List

    1. Add “NoOfSeats” text field as a number (you could, I suppose, also do a drop down control)
    2. Publish it

    Step 2: Edit the Registration Workflow for Attendee List

    1. Add “Do Calculation
      Calculate “Calendar:FilledSeats” plus “CurrentItem:NoOfSeats” (Output to Variable:lvSeatsIncrement2) — local variable name can be whatever name you choose and as a number
        Calendar:FilledSeats
        CurrentItem:NoOfSeats
        Variable:lvSeatsIncrement2
    2. Add “Log to History List” — add whatever comment you want, this is just so you can track/troubleshoot the steps. I suggest add the local variable, so you know the result of the calculation.   
    3. Change the current Update item you implemented from the blog to reflect the new value of the local variable above (ie. lvSeatsIncrement2, in this example)
        i. Open the action
        ii. Double-click the “FilledSeats” field in the list
        iii. Click on the “fx” for To This Value
        iv. Change the look up to match the local variable
        
    4. Add “Log to History List” — add whatever comment you want, this is just so you can track/troubleshoot the steps. I suggest to add the FilledSeats variable, so you know the actual value when you look at the logs of the workflow.
        

    Your workflow should look similar to this (my calendar name is EventReg2):

    Give it a shot, let me know.

  • Profile photo of Robert Woods
    Robert Woods
    Reply

    Workflow suspended during the calculation.

    RequestorId: 80ce6fea-1a8b-179a-0000-000000000000. Details: An unhandled exception occurred during the execution of the workflow instance. Exception details: System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) at Microsoft.Activities.Expressions.ParseNumber1.Execute(CodeActivityContext context) at System.Activities.CodeActivity1.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation) Exception from activity ParseNumber<Int32> ToString DynamicActivity<Guid> DynamicActivity<Double> Microsoft.SharePoint.WorkflowServices.Activities.Calc Stage 1 Sequence Flowchart Sequence Registration.WorkflowXaml_1da0a574_549f_43f3_9b79_87a1d7436cd3

  • Profile photo of Quy T
    Quy T
    Reply

    @ Robert Woods

    Initially looking at the error, it is a conversion that went wrong. I would double check to make sure the local variable in the Do Calculation is set as a number. Also double check the data source and fields are correct.

    if it all looks correct. Try to delete all previous workflows and republish it. Then create a brand new event and test it out.

  • Profile photo of Robert Woods
    Robert Woods
    Reply

    Quy T Deleting and Republishing the workflow was the answer. Thank you Sir. Now that I have the workflow going properly I would like to validate the user has not already registered. Earlier in the thread you mentioned running a rule that will check if the current user name is equal to the “username” already in the event…

    Will I set this up as a Form Load Rule? Sorry to ask so many questions but You have been a great help and I am almost there! I see where I can add an action to query for data but am not sure of the next step.

  • Profile photo of Quy T
    Quy T
    Reply

    Robert Woods

    Checking for Duplicate

    There are actually two ways of checking to see if someone has already registered. Both methods work when SP is sync with Active Directory. The duplicate checks are based off of the userid / display name of the user and the attendees list. This works for local SP installs, I think it should work for online too.

    Now before you read on, there are some customization (submit data, email, etc) to the InfoPath form that is not mentioned step-by-step here. This post is only focused on the steps to check for duplication.

    When I implemented the original registration steps from the blog, I ended up with the List view of the calendar and I used the InfoPath form to do my duplicate check. I customized my InfoPath Registration form to include a “Register” button vs using the default toolbar from InfoPath. Since, then I have modified so that I can now use the Calendar view instead and use JavaScript to check for duplicates. I will post both solutions.

    Doing the duplicate check on the InfoPath has limitations, first off you can’t do the check in the Form Load Rule. The InfoPath form does not know what ID is being passed from the Calendar list yet, so the Form Load Rule option is out. Thus, you will need to do the check when the “Register” button is clicked based on rules and switch to another view (if true) to indicate as a message that they are already register.

    Duplicate check within InfoPath Registration form:

    1. Create another view as the message to display – mine is named Duplicate
    2. Create 3 additional Data Connections
    • Event Attendees
      1. Click Add > Receive Data > SharePoint Library or list
      2. Enter the URL to Attendees List
      3. Check – Title, UserName, MeetingTitle, MeetingID
      4. Do not store a_copy of the data in the form template
      5. Do not Automatically retrieve data when form is opened
      6. Click Finish
    • Event Registration 1
      1. Click Add > Receive Data > SharePoint Library or list
      2. Enter the URL to Event Registration calendar
      3. Check – StaticID
      4. Do not store a_copy of the data in the form template
      5. Do not Automatically retrieve data when form is opened
      6. Click Finish
    • User Information List
      1. Click Add > Receive Data > SharePoint Library or list
      2. Enter the URL to SharePoint Site
      3. Choose User Information List
      4. Check – Name, Account
      5. Do not store a_copy of the data in the form template
      6. Do not Automatically retrieve data when form is opened
      7. Click Finish

     

    1. Add Rules to the “Register” button
      1. Rule #1; Click New >Action Rule (name: Query Event Info)
      2. Condition: None
      3. Add Set a Field’s Value
        1. In the field box, click the Browse button
        2. On the top, change to Event Registration 1
        3. Click “+” sign for queryFields
        4. Click “+” sign for q:SharePointListItem_RW
        5. Select ID
        6. Click OK
        7. In the Value box, click the fx button
        8. Click on Insert Field or Group button
        9. Select MeetingTitle
        10. Click OK, click OK again, click OK again
      4. Add Query for Data
        1. Select Event Registration 1
        2. Click OK

       

      1. Rule #2; Click New > Action Rule (name: Query Attendees)
      2. Condition: None
      3. Add Set a Field’s Value
        1. In the field box, click the Browse button
        2. On the top, change to Event Attendees
        3. Click “+” sign for queryFields
        4. Click “+” sign for q:SharePointListItem_RW
        5. Select MeetingID
        6. Click OK
        7. In the Value box, click the fx button,
        8. Click on Insert Field or Group button
        9. Click on Show Advanced View
          1. On the top, change to Event Registration 1
          2. Click “+” sign for dataFields
          3. Click “+” sign for d:SharePointListItem_RW
          4. Select StaticID
          5. Click OK, click OK again, click OK again
      4. Add Query for Data
        1. Select Event Attendees
        2. Click OK

     

    1. Rule #3; Click New > Action Rule (name: Check Duplicate)
    2. Condition
      1. Left box, Select field or group
      2. On the top, change to Event Attendees
      3. Click “+” sign for dataFields
      4. Click “+” sign for d:SharePointListItem_RW
      5. Select UserName
      6. Click OK
      7. Middle box, is equal to
      8. Right box, Select field or group
      9. On the top, change to User Information List
      10. Click “+” sign for dataFields
      11. Click “+” sign for d:SharePointListItem_RW
      12. Select Name
      13. Click OK, click OK
    3. Add Switch Views
      1. Choose, Duplicate
      2. Click OK
      3. Check box for Don’t run remaining rules if the condition of this rule is met

     

    1. Add a rule to query user information when the form loads
      1. Click on Data Tab > Form Load
        1. Click New > Action Rule (name: Query User Information)
        2. Condition: None
        3. Add Set a Field’s Value
          1. In the field box, click the Browse button
          2. On the top, change to User Information List
          3. Click “+” sign for queryFields
          4. Click “+” sign for q:SharePointListItem_RW
          5. Select Account
          6. Click OK
          7. In the Value box, click the fx button
          8. Click Insert Function, choose User on left, then choose userName on right
          9. Click OK
      2. Add Query for Data
        1. Select User Information List
        2. Click OK

    So now when the user clicks on the “Register” button, it will run all the rules, it will allow them to register and submit (based on another rule) the InfoPath form to the Attendees list, if it’s the first time to register for that event. If it’s their second attempt it will display the Duplicate view.

    —————————————————————————————————————–

    Duplicate check using JavaScript:

    Now with the update that I have done with moving from a list view to a calendar view, I can now use a JavaScript to do my duplicate registration check in the displayform template, instead of in the InfoPath form and based on the results it will either display the “Register” hyperlink or the “Un-Register” hyperlink.

    In the JavaScript when it does the duplicate check of user name, the variable “UserName” is a field from the InfoPath Registration form. The “UserName” field has a default value assigned from the “User Information List” query, mentioned above earlier. After it does the query, you can set the default value. The “LoginName” is the display name from Active Directory that was extracted from SP. Thus it was mentioned in the beginning about AD sync with SP.

    The following is the JavaScript to accomplish the duplicate check.

    =============== Beginning of Script to check for duplication ====================

    <script src=”https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js” type=”text/javascript”></script>

    <script type=”text/javascript”>

     //The following script will be used to query two lists, compare the ID and UserName for duplicate registration

     $(function() {

     //Get current Calendar list item ID to be used in a function

       var vars = [], hash;

       var hashes = window.location.href.slice(window.location.href.indexOf(‘?’) + 1).split(‘&’);

       for(var i = 0; i < hashes.length; i++){    

         hash = hashes[i].split(‘=’);

         vars.push(hash[0]);

         vars[hash[0]] = hash[1];

    }

        var calendarId = vars[“ID”].toString();

     

     //***********************************************************************************

    //Global Variables used to get list items

       var listName = “Replace with your Attendees List Name“; //list name of attendees

       var url = _spPageContextInfo.webAbsoluteUrl; //grabs the current SP site

       var userid = _spPageContextInfo.userId; //grabs the current user ID

     

    //Set global variable to current user via a function call

       var myJsonObj3 = getCurrentUser(userid, url); //set variable to a return data when function is called

       var LoginName = myJsonObj3.d.Title;

     

    //Set global variable to attendees list via a function call

       var myJsonObj = getListItems(listName, url); //set variable to a return data when function is called

       var myAttendeesList = myJsonObj.d.results;

     

     //***********************************************************************************

    //Function to get the items from a list with an ID and username, then return a JSON data set

    function getListItems(listName, siteurl, success, failure) {

       return JSON.parse($.ajax({

           url: siteurl + “/_api/web/lists/getbytitle(‘” + listName + “‘)/items?$filter=(MeetingID eq ” + calendarId + “) and (UserName eq ‘” + LoginName + “‘)”,

           method: “GET”,

           global: false,

           async:false,

           headers: { “Accept”: “application/json; odata=verbose” },

           success: function (data) {

               return (data);

           },

           error: function (data) {

               failure(data);

           }

       }).responseText);

    }

     

    //***********************************************************************************

    //Function to get the current user from SP

    function getCurrentUser(userid, siteurl, success, failure) {

       return JSON.parse($.ajax({

           url: siteurl + “/_api/web/getuserbyid(” + userid + “)”,

           method: “GET”,

           global: false,

           async:false,

           headers: { “Accept”: “application/json; odata=verbose” },

           success: function (data) {

               return (data);

           },

           error: function (data) {

               failure(data);

           }

       }).responseText);

    }

     

    //***********************************************************************************

    //Checking for duplicate registration for current user

     

    if (myAttendeesList.length > 0) {

    for (var i = 0; i < myAttendeesList.length; i++) {

       if (myAttendeesList[i].UserName == LoginName) {

         alert(myAttendeesList[i].UserName + ” is already registered for this event”);

         $(“a[name$=’SPBookmark_Register’]”).closest(“tr”).hide();

       }

    }

    } else {

    // alert(LoginName + ” is NOT registered for the event.”);

    $(“a[name$=’SPBookmark_UnRegister’]”).closest(“tr”).hide();

    }

    });

    </script>

    =============== End of Script to check for duplication ========================

    Hope this helps you out in the right direction.

  • Profile photo of Chau Le
    Chau Le
    Reply

    Thank you so much for this post Rick!!  I got the codes to work and it’s exactly what we need.   I was wondering if we are able to add back the seats if someone unregistered or delete themselves?  Has anyone tried it and can give me some pointers? TIA!!

  • Profile photo of Quy T
    Quy T
    Reply

    @ Chau Le

    Yes you can !

    create another calculated column for seats decrement

    create another calculated column for Unregister link

    reverse the registration workflow

  • Profile photo of Quy T
    Quy T
    Reply

    @ Chau Le and @ Mj

    I did this quick instruction, give it try.

    Create UnRegister

    For UnRegister we will follow the same logic as if an Attendee was registering, except we will decrease the number of seats. So when someone clicks on the UnRegister link, it will start a work flow in a custom list to update the number of seats remaining.

    Create New Custom List

    1. Create a new custom UnRegister list
      1. Modify / Edit the InfoPath form to match the same as the Attendees List (use the same steps in the blog)

    Create Column in Calendar List

    1. Go to the Calendar list
    2. Create Calculated column
      1. Name: SeatsDecrement
      2. Type: Calculated
      3. Formula: =FilledSeats-1
      4. Data Type returned: Number

     

    1. Create Calculated column
      1. Name: UnRegister
      2. Type: Calculated
      3. Formula: =”<a href=’#’ style=’color:red’ onclick=’OpenLandURegistration(“&StaticID&”)’>Click Here to UnRegister</a>”
      4. Date Type return: Single line of textCreate UnRegistration Workflow

     

    Go to the UnRegister List and open the list with SPD (we will use the same steps as you did for the Attendees List, except we will reference the newly created columns above)

    1. Create a new Workflow and name is UnRegistration
      1. Add an Action – “Update List Item”
      2. Click the “this list” link in the action
      3. Change the list to the Calendar created earlier
      4. Click the “Add…” button
        1. Choose “FilledSeats
        2. Click the fx button for the value
        3. Data source: EventsCalendar
        4. Field from source: SeatsDecrement
        5. Field: ID
        6. Value – click the fx button
          1. Data source: Current Item
          2. Field from source: Meeting
          3. Click, OK, then click OK again for the next window
        7. In the Find the list item section
        8. Field: ID
        9. Value – click the fx button
          1. Data source: Current Item
          2. Field from source: Meeting
      5. Click, OK, then click OK again for the next window

     

    Create a QueryString for UnRegister List

    Use the same steps you did for Attendees list and apply the steps to the UnRegister list

     

    Copy / Add / Modify to current JavaScript

    Open your current JavaScript from the blog and copy the first function that has the OpenLandLRegistration, copy that entire function and paste it. You should now have two functions and we will make the following changes to the function you just copied:

    1. Change the function name to OpenLandURegistration
    2. Change the url to match the UnRegister custom list (just as you did in the previous steps for the Attendees list, remember to include the site url, path and list GUID as explained in the blog)

    Example: http://replace with your site url/path to the custom list/Item/newifs.aspx?List=37ab2f49%2D755e%2D473b%2Db02b%2D79080b997467&

    ==================== JavaScript Changes ===========================

    function OpenLandURegistration(meeting_id){

    var options = {

    url:” http://replace with your site url/path to the unregister custom list and GUID/&meeting_id=” + meeting_id,

    width: 750,

    height: 600,

    dialogReturnValueCallback: DialogCallback,

    dialogReturnValueCallback: RefreshOnDialogClose

    };

    SP.UI.ModalDialog.showModalDialog(options);

    }

    function DialogCallback(dialogResult, returnValue){ }

    ================== End of JavaScript Changes =================

  • Profile photo of Mj
    Mj
    Reply

    Quy T I don’t have the javascript on my SPD form because it would not work for me so what I wanted to do was when a person’s name was deleted from the Attendee list then the number would change. Is there a way to set this up?

  • Profile photo of Quy T
    Quy T
    Reply

    Mj you can trigger a workflow on a change, but the problem would be how would that workflow know which calendar ID to decrease from, so unless we can logically figure out a way to track that and pass it to the workflow, I don’t know of a way to do this, when a file is delete from the list. I will attempt to try out some scenario, but don’t hold your breath.

  • Profile photo of CoolCat
    CoolCat
    Reply

    Thank you so much for this post Rick  & Quy T. I have implemented registration using Calendar view as mentioned by Quy T.

    @ Quy T : When I am trying to implement duplicate check using JavaScript code given by you on display form for Calendar, nothing is happening. I mean I am not able to perform duplicate check. Can you please tell me if I can do this in SharePoint online . Also I copy pasted the code given by you just replaced my list name. 

    Can someone help me to achieve this duplicate check functionality on registeration

  • Profile photo of Quy T
    Quy T
    Reply

    @CoolCat

    So after working with you offline and with SP Online, I have made some changes, so that the JS works correctly when finding duplication with SP Online. So the problem is with the login account that is on SP Online: 

    i:0#.f|membership|myname@mysite.onmicrosoft.com 

    In order for the JS to work properly we need to get the values of Username in the InfoPath form and the variable LoginName in the JS to have the login account as: 

    myname@mysite.onmicrosoft.com

    Let me know if this works for you.

     

    Step1: Change the default value in your InfoPath form.

    1. Open the Registration InfoPath form from the Attendees list. Go the “Username” control properties and change the default value to have the following:

    substring-after(substring-after(userName(), “|”), “|”)  

    Step2: Copy and paste updated JS below

    1. Copy the below updated JS and replace the current one you have in the Calendar Default View web part. Make sure the “Register” column name is spelled correctly at the bottom of the JS and is the same in your Calendar list, it is case sensitive. Also remember to replace your Attendees list name in the script.

    ============= Beginning of Script ===================

    <script src=”https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js” type=”text/javascript”></script>

    <script type=”text/javascript”>

    //The following script will be used to query two lists, compare the ID and UserName for duplicate registration

    $(function() {

    //Get current Calendar list item ID to be used in a function

       var vars = [], hash;

       var hashes = window.location.href.slice(window.location.href.indexOf(‘?’) + 1).split(‘&’);

       for(var i = 0; i < hashes.length; i++){    

         hash = hashes[i].split(‘=’);

         vars.push(hash[0]);

         vars[hash[0]] = hash[1];

    }

       var calendarId = vars[“ID”].toString();

    //************************************************************************************************************

    //Global Variables used to get list items

     

       var listName = “Replace with your list name”; //list name of attendees list

       var url = _spPageContextInfo.webAbsoluteUrl; //grabs the current SP site

       var userid = _spPageContextInfo.userId; //grabs the current user ID number

     

    //Set global variable to current user via a function call

       var myJsonObj3 = getCurrentUser(userid, url); //set variable to a return data when function is called

       var LoginNameLong = myJsonObj3.d.LoginName;

       var LoginName = LoginNameLong.substring(18);

     

    //Set global variable to attendees list via a function call

       var myJsonObj = getListItems(listName, url); //set variable to a return data when function is called

       var myAttendeesList = myJsonObj.d.results;

     

    //************************************************************************************************************

    //Function to get the items from a list and return a JSON data set

    function getListItems(listName, siteurl, success, failure) {

       return JSON.parse($.ajax({

           url: siteurl + “/_api/web/lists/getbytitle(‘” + listName + “‘)/items?$filter=(MeetingID eq ” + calendarId + “) and (Username eq ‘” + LoginName + “‘)”,

           method: “GET”,

           global: false,

           async:false,

           headers: { “Accept”: “application/json; odata=verbose” },

           success: function (data) {

               return (data);

           },

           error: function (data) {

               failure(data);

           }

       }).responseText);

    }

     

    //************************************************************************************************************

    //Function to get the current user

    function getCurrentUser(userid, siteurl, success, failure) {

       return JSON.parse($.ajax({

           url: siteurl + “/_api/web/getuserbyid(” + userid + “)”,

           method: “GET”,

           global: false,

           async:false,

           headers: { “Accept”: “application/json; odata=verbose” },

           success: function (data) {

               return (data);

           },

           error: function (data) {

               failure(data);

           }

       }).responseText);

    }

     

    //************************************************************************************************************

    //Checking for duplicate registration for current user

     

    if (myAttendeesList.length > 0) {

    for (var i = 0; i < myAttendeesList.length; i++) {

       if (myAttendeesList[i].Username == LoginName) {

         alert(myAttendeesList[i].Username + ” is already registered for the event, ” + myAttendeesList[i].Title + “.”);

         $(“a[name$=’SPBookmark_Register’]”).closest(“tr”).hide();

       }

    }

    } else {

    $(“a[name$=’SPBookmark_UnRegister’]”).closest(“tr”).hide();

    }

    });

    </script>

     

    =================== End of Script ===========================

  • Profile photo of Robert Woods
    Robert Woods
    Reply

    Quy T I am trying to expand a little on the registrations to make allotments by department. What I have done is add the same fields as the example but with dept names in front, then altered the workflow to look like this 

    but the workflow does not notice the submitter is a member of the security group I set here. Any way you can think of to make this work?

  • Profile photo of Quy T
    Quy T
    Reply

    @ Robert Woods

    I was able to follow the link you posted. The information I was able to retrieve was on SP security groups, is that what you were looking for?

    Quy

  • Profile photo of Robert Woods
    Robert Woods
    Reply

    Quy T  I would like to iterate through the users AD Security Groups and if they are a member of the group specified change the allotment for only that group. So first I have built matching columns for each department, ITFilledSeats, HRFilledSeats, for example. If the submitter was a member of *IT Deparment then workflow would update ITFilledSeats and not HRFilledSeats.

  • Profile photo of Quy T
    Quy T
    Reply

    @ Robert Woods

    I don’t think there is an easy way (none that i have found) to iterate through AD Sec grps. SP does manage the groups, it just knows the pointers to the group. So you will have to duplicate the groups as SP groups (which can be a lot, depending on the number of grps you have) in order to do what you want. Then it just combo of scripts and workflows to update the columns.

  • Profile photo of Mubashshira
    Mubashshira
    Reply

    @Quy

    Thanks for the link. it seems that the link being generated is creating a calendar invite, whereas i want the recipients invitation which the registered user will be accept/deny. I want information like date, time and location to be included in the invite and as the user accepts it, their outlook calendar will be updated.

  • Profile photo of Quy T
    Quy T
    Reply

    @ Mubashshira

    Yes, that link shows how to generate the calendar invite  based on the calendar ID your registration is for. Once you can capture that URL (as in the video shows), you simply create another view in your InfoPath form to send an email that includes the URL for the calendar invite.

    Once the person that registers get the email with the URL link, they click on that URL and it will add it to their Outlook calendar.

  • Profile photo of Mubashshira
    Mubashshira
    Reply

    @Quy

    Yes, the link does generate a calendar invite but it is a three step process (click, open and save) to add it to the outlook calendar. But i guess, this the best that can happen.

    This post has been very useful in one of my recent development. I went ahead and added another step to remove the registered user from the attendee list using the UnRegistration workflow.

  • Profile photo of Quy T
    Quy T
    Reply

    @Mubashshira

    Yes, that is all that we can do for the calendar invite, there is no “automated” way.. at least that I have found … to do it. So yes, some user interaction will need to occur. For us, we added some instructions at the bottom of the email with the invite link, so user’s will know how to add it to their calendar.

    Cool, on the “unregistration”. In the comments, there is a script to check for duplicates too (caution with Office365, because the login id is different from on premises SP). You can also google search for Colorized Calendar too, this will help separate multiple events on the same day !!! Lots of potentials !!

  • Profile photo of Mubashshira
    Mubashshira
    Reply

    Hi Quy T,

    I have run into two new issues. Please let me know if you know the solution.

    1. An error is being logged in ULS for the Calendar:

    The form template failed to load. (User: **********, Form Name: Template, IP: , Request: https://********/DispForm.aspx?ID=13, Form ID: urn:schemas-microsoft-com:office:infopath:list:-AutoGen-2016-09-22T05:22:23:143Z, Type: NullReferenceException, Exception Message: Object reference not set to an instance of an object.)

    2. Emails are being sent in consistently. A user once got the email, but she is not receiving them anymore.

  • Profile photo of Quy T
    Quy T
    Reply

    @Mubashshira

    1. I’m not 100% sure of this error, but I would first try to open and verify the infopath form and then republish the infopath form. Perhaps the xsn file got corrupted or has a broken link in it.

    2. How are you sending the emails?

    infopath view? – check make sure that the email address is consistent, i always use a data connection to pull the email, so i’m not relying on a user to “type” it in. You can also do a quick form with just email field and see if it still sending out.

    using SPD? – again check the email address, variables and workflow, then test it out

    junk mail? – perhaps your mail server is categorizing them as junk emails

  • Profile photo of Robert Woods
    Robert Woods
    Reply

    @Quy T, Quy first I want to say Thank You so much for the time you spend on this blog. I have not found many as helpful as yourself. I am still working on getting groups, I understand that using AD groups is not possible and will replicate the groups I need in sharepoint, but I need some help with the rest calls. I perform the first call to get users ID, and then pass that to the second call with a variable, when I make the second call, “https://site.sharepoint.com/sites/site/_api/Web/getUserbyId(15)/Groups” I get an OK response code, and pass the response content to a variable dictionary. Now I need to pull the Title out of the variable dictionary, but for some reason d/Title does not find the info. Do you know what I should be putting for the path?

    Get d/Title from Variable: JSONResultsGroup (Output to Variable: dataset )

    is the line that I need help with

  • Profile photo of Mubashshira
    Mubashshira
    Reply

    @Quy,

    there were duplicate user accounts with same username and missing email address in one of them. once we fixed that, emails are being sent.

    I also implemented color calendars using “Calendar Overlays” OOB. indeed it adds the x-factor to the entire process.

    there is one thing I need to fix. With IE, when event page loads which has the register/unregister links, the page first scroll to the bottom where these calculated columns are and for a second I can see the complete formula. and then it scrolls back to the top. this behavior does not give a good impression as most of the users are using IE only. Hope I am able to explain my self. Let me know if you have any idea.

  • Profile photo of Quy T
    Quy T
    Reply

    @Robert,

    Your welcome. By no means, am I an expert on any of this, but I will share what I can and help out where I can.

    Can you send me the entire code you are using or the relative functions? you can send me a private msg. I’m wondering if the info you are pulling is already in a JSON data set and just needs to have the specific fields pull from the set. Give me some time to comb through it and see if I can come with anything for you.

    @Mubashshira

    two things:

    1. instead of using overlays, which adds more layers, try looking up colorize calendars with JS, example is here:  https://blog.metrostarsystems.com/2014/07/16/sharepoint-2013-any-color-coded-calendar-step-by-step/

    the above method using JS is what I use to colorize each of the events in my registration calendar without using OOB layers.

    2. With the IE issue, does the “register / unregister” link disappear, after it scrolls back up? if so, what I’m thinking is that, if you used one of the latter JS scripts, not the original one in the blog, for your events page, then the JS script that is running on that page also has a “hide” function for the links, thus it loads the JS, does the “hiding” and then refreshes. I have this function on my JS, so that it does not display two links, its either or, but not both.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    @Quy: First of all thank you for this solution. That is what I was looking for. I learned a lot, also about the calculated columns.

    The solution works with one exception…. the link is not shown as a html Hyperlink but as html text. I cannot find the Problem at all. $

    The calendar works (in my opinion)….

    I edited the script several times and after this I used your second script from comment page 3 (Comment  by Quy T on July 15, 2016 at 18:55)
    Clicking the calendar entry shows the Register link as html text (<a href=”#” onClick=”OpenLandLRegistration(1)” />Register</a>). The “meetingID” is correct (see following screenshot).

    Debugging it it is the following…

    I have no idea where the problem could be. SO I hope you have some hints or even you see the problem. 

    Thanks in advance für helping. Have a nice day.

  • Profile photo of Quy T
    Quy T
    Reply

    @Robert

    Sorry, haven’t had time to review what I sent you, but I will try as soon as I can. I believe it just a matter of the web service call and then looping through it to find the right group you want to compare.

    @Joel

    If you followed the blog then the JS script from the blog (remove the line numbers if you copied it) will need to be place in the the same page as your calendar. You can reference to the JS script with either Script Editor or Contented Editor web parts.

    If you used my JS script then you will need to add reference to the JS script with either Script Editor or Contented Editor web parts to the Calendar Default Display Form.

    The JS script from the blog is different from mine and both references different parts to convert to html, so it depends on how you implemented the JS script.

  • Profile photo of Quy T
    Quy T
    Reply

    @ Joel

    one other thing is that the blog will display the events in a “list view format” and my solution was a “calendar view”, thus the JS are different.

  • Profile photo of Robert Woods
    Robert Woods
    Reply

    [email protected]Quy T I have been playing a bit with what you sent me ,  I ended up creating another dictionary, logging the d/results to there, and from that dictionary get [%Variable: LoopCounter%])/Title output to Variable: Groups. 

    Now im working on logic, if variable:groups containts “IT Only Members”

     Calculate Signups:ITFilledSeats plus Current ITem:NoOfSeats output to variable calc2

    then update item in Signups

     

  • Profile photo of Quy T
    Quy T
    Reply

    @Robert

    That’s awesome, I would really like to see the finish SPD workflow, once you have gotten it worked out. I was more focused on JS, so I didn’t even think about SPD, so that’s great to have another option. Good job.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    @QUI T: I already have a calendar view and not a list view.
    The line numbers are removed. Those in the screenshot are only the PSPad Editors numbers 🙂

    First I had the wole script in the script Editor Webpart within and below the calender. Now I mad a JS File, uploaded it to the Server and put a reference below the calendar library.

    Is there the correct place or must it be in the *.ASPX page where also a calendar Webpart is included? That wa salso an issue I didn’t unterstand well in the blog.

    Then I have to say that this Register solution is in a normal Publishing website and not in a blog. But I think that doesn’t matter, does it?

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    @QUI T: Additional information
    You write that it depends on which view I use and which script I copied….

    I implemented as follows….

    • below there the “calendar” library itself I put a “script editor Webpart” with the reference to the script in the Style%20Library…Directory. Within the script I frist referenced to the jquery file and then follows the whole script from the “blog comment – page 3 – Comment  by Quy T on July 15, 2016 at 18:55”.
    • within a aspx page with a Webpart (calendar) I also tried a script editor Webpart with the reference to the script, I tried with the list view and also with the calendar view. Neither the listview nor the calendar view shows the Link but only the html text string <a…..>xyz</a>.
      But the link text is correct (IDs are correct and the html tag Shows good), so I don’t think there is a mistake in the library columns. 🙂
    • Now in (SP Designer) in the calendar library itself I (first made a copy of the original file) edited the DispView.apsx and put a reference to the script (as you said). But I am not sure if I did it correctly (see below “script snippet).
      Unfortunately I cannot see the reference in th sourcecode. So I guess the reference in dispForm is not working?? Is asp:Content… not the correct reference code?

    script-snippet:
    . . .

    <%@ Register Tagprefix=”SharePoint” Namespace=”Microsoft.SharePoint.WebControls” …… %>
     . . .
    <asp:Content runat=”server” ContentPlaceHolderID=”PlaceHolderAdditionalPageHead”>
    <!– Custom Scripts –>
    <script src=”/Style%20Library/scripts/jquery-2.2.4.min.js” type=”text/javascript”></script>
    <script src=”/Style%20Library/scripts/register_convertIntoHyperlinks.js” type=”text/javascript”></script>
    </asp:Content>

    <asp:Content ContentPlaceHolderId=”PlaceHolderPageTitle” runat=”server”>
     <SharePoint:ListFormPageTitle runat=”server”/>
    </asp:Content>
    . . .

    I hope this helps to understand what I did.

    Kind Regards

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    Addition:

    Here the Sourcecode snippet from the form:
    . . .
    <tr>
      <td nowrap=”true” valign=”top” width=”113px” class=”ms-formlabel”><h3 class=”ms-standardheader”><a name=”SPBookmark_Register”></a>Register</h3></td>
      <td valign=”top” class=”ms-formbody” width=”350px” id=”SPFieldCalculated”>
      <!– FieldName=”Register”
        FieldInternalName=”Register”
        FieldType=”SPFieldCalculated”
        –>
       &lt;a href=&#39;#&#39; onclick=&#39;OpenLandLRegistration(1)&#39;&gt;Register&lt;/a&gt;
       
      </td>
     </tr>
    . . .

  • Profile photo of Quy T
    Quy T
    Reply

    @Joel

    if you are using the JS from me on page 3, then option 1 & 2 that you stated will not work, because those two options are still referencing a “list” and the JS is looking for a “table”

    now the option to add the JS is in the default display view should of worked. instead of using SPD, lets try it through the user interface.

    go to your calendar, click on the calendar tab, go to “Form Webparts”, then select “Default Display View”

    you should now be able to add a web part, add the Script Editor and then edit that web part and paste the JS, save and then try it again. keep the jquery at version 2.2.2, i know there are newer ones, but this one seems to work.

    once it is working, you can add the calendar to a new page, just select the “calendar” view in the web part

    • Profile photo of shannon_c
      shannon_c
      Reply

      @Quy T
      2 important questions.
      1. When I choose the Default Display View it opens the page that displays the details of an event entered into the calendar. Is that correct?
      2. Does it matter if the script editor is displayed above or below the Default Display View Webpart?

      My Link appears to work but will not display correctly. I copied your code exactly and changed the url to the matching url of the new entry for the form page.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    Hi QUI T 

    HA!!! Finally it works  :-)))

    as you told me, I was in the “Default Display View” and put the whole script and the reference to the jquery 2.2.2. But I use your script from page 3 because I have no list view but the calendar view instead….

    Now I can go for further features (unregister etc.),

    Thank you so much, I am really happy and I appreciate it a lot. If I have more questions, I’ll try it here….

    Have a good one.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    @QUI T
    Another two questions.
    1. Why is the username a textfield instead of People picker? Generella it can be changed. I did this but I am not Aware if somewhere there could be a Problem with this.

    2. The idea would be that (also when it’s as calendar) the calender can be shown in any other site within the sitecollection. So different Teams could have a vierw in their site and see their specific category Events.

  • Profile photo of Quy T
    Quy T
    Reply

    @Joel

    1. I’m not sure of any issues using people picker vs textbox. However, in the blog on the InfoPath form, it states to assign the default value of the current user, so perhaps that would be a benefit to using text.

    2. Are you asking about putting the calendar on other pages / sites? as far as i know as long as they have permission you should be able to. For the team to see their specific events, that would invovle views of the calendar and/or filters.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    Hi
    The solution from the blog works. I use now the calendar view and the script from blog-page 3 from
    QUI T.
    Now I wanted to implement the unregister and the double check. That is what we would need too.

    I tried to Change the script which I took from the blog comments page 3 (the default view form of the calendar) and I puted in the one on page 5 which does double check and in addiation I changed the attendees form username “default value” to
    substring-after(substring-after(userName(), “|”), “|”)  

    But now I face the same Problem again. The Register link is not a link but a html text.

    My questions are,

    – if there is a step by step manual which describes where to put which scripts now and if the actual scripts have still to be there ….. I don’t understand it due to the several comments and my not so good english (sorry about that).

    – is there a script which includes both Solutions (unregister and double check AND….
        – where to put it in and what do I have to Change beside the script?

    Thank you very much in advance for your help.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    @Hi Quy T
    19 The People picker is over. I changed it back and created the whole Thing like your post (script from page 3 and calendar view) and it workls very well….

    2) I’ll try it out. For the Moment we only Need a small one for our Events (roundtable Meetings etc.). I we can reach the to other Features (unregister and double check) I would be really happy.

    Thanx in advance and a big thank you for your great work.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    The username which automatically is in the userName field Looks like the following…..
       i:0#.w|DOMAIN\loginname

    Is it possible to Change to the users real Name somehow?
    Then it would look like “Lastname Firstname” and the Title field then would look like..
       Lastname Firstname Registration for Event no. (x)
    instead of
       i:0#.w|DOMAIN\Username registration for event number 2

    Thanx and have a good one…

  • Profile photo of Quy T
    Quy T
    Reply

    @Joel

    1. There is no official step-by-step guide, i started one but it takes time with screen captures and typing, plus setting time to create one. So short answer is no, just this blog and Q&A.

    2. Yes, it is possible to do un-register, you will just have to reverse the process and add in the checks for it. There is no step-by-step for this but it can be done. I haven’t looked at what I did in a while so it will take some time to back track what I did. Same goes for duplicate registration, I will have to look at what I did, but I believe in one of the comments I added something about duplication.

    3. Yes, you can display the “Title” of the person, you will need to create a data connection to SP User Information List in your InfoPath form and then use the query action to pull the data and then assigne to the proper text field.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    @QUI T

    Thank you very much for your answer end help. Unregister works finally. SO doulbecheck is the next Thing. As far as I understood, then it woll Show the Register Link and if someone is already registered, then the Unregister Link is shown.

    The only Thing is (due to not soooo good English) I couldn’t understand where the doublecheck script have to be in and if it has to be where the registering script is, do I put it in Addition below or above OR….do I replace the script? I tried this but then I don’t get the Hyperlinks but only the html text like <a href….>.

    I think if I know how and where to put the script in, I’ll get it working.

    The script which I use now is the following and it is in the calendars Default view form:

    <script src=”/Style%20Library/scripts/jquery-2.2.2.min.js” type=”text/javascript”></script>
    <script type=”text/javascript”>
    //Creates window and opens the infopath form
    function OpenLandLRegistration(meeting_id){
    var options = {
    url:”/org/ict/Lists/Attendees/Item/newifs.aspx?List=7889bbe8%2D2461%2D41c5%2Dafe3%2D5b294b888793&meeting_id=” + meeting_id,
    width: 750,
    height: 450,
    dialogReturnValueCallback: DialogCallback,
    dialogReturnValueCallback: RefreshOnDialogClose
    };
    SP.UI.ModalDialog.showModalDialog(options);
    }
    function DialogCallback(dialogResult, returnValue){ }
      // Reformat the url in the calculated column to hyperlink
      $(function(){
        // Format link font size and weight
        $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).css(“font-size”, “18px”);
        $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).css(“background-color”, “#EFEFEF”);
        $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).css(“border”, “1px solid #AAAAAA”);
        $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).css(“padding-left”, “20px”);
        $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).css(“font-weight”, “bold”);
     
        reformatCalculatedColumnUrl();
     
        function reformatCalculatedColumnUrl(){
          $(‘td.ms-formlabel:contains(“Register”)’).siblings(“.ms-formbody”).each(function(){
            // alert($(this));
            $(this).html($(this).text());
          }
        );
        };
    });

    // Hides Columns
    $(function() {

    $(“a[name$=’StaticID’]”).closest(“tr”).hide();
    $(“a[name$=’SeatsIncrement’]”).closest(“tr”).hide();

    });

    /*
    |========================================================|
    |                                                        |
    |              UnRegister Code…..                      |
    |                                                        |
    |========================================================
    */
    function OpenLandURegistration(meeting_id){

    var options = {

    url:” /org/ict/Lists/Attendees/Item/newifs.aspx?List=1764e5e2%2Dc7f4%2D4923%2D8dc9%2D957361ece0e1&meeting_id=” + meeting_id,

    width: 750,

    height: 600,

    dialogReturnValueCallback: DialogCallback,

    dialogReturnValueCallback: RefreshOnDialogClose

    };

    SP.UI.ModalDialog.showModalDialog(options);

    }

    function DialogCallback(dialogResult, returnValue){ }

    </script>

     And one little Thing I am not sure…in the doublecheck script….there is a variable where the “list name” should be filled in.
    That is only the Name of the list, right? I my case “Attemdees”.

    script snippet:
    . . .
    var listName = “Replace with your list name”; //list name of attendees
    var url = _spPageContextInfo.webAbsoluteUrl; //grabs the current SP site
    . . .

    Thanks in advance.

    By the way, it’s is OK that there is no step by step Manual.
    Then I will do one for myself. So almost I can do it step by step when I am ready to creat it on the productive SharePoint (I am already working on a test machine).
    I am copying all the Posts from this blog together. I do it as far as I understand it.
    So if you are interested in, I could send it as far as I have all the information.

  • Profile photo of Quy T
    Quy T
    Reply

    @Joel

    Glad to hear you go the unregister to work.

    For Duplication check, you have 2 options:

    1) go to the default display view again, add another script editor web part, then paste the code for duplicate check

    or

    2) go to the default display view again, edit the current script and add all the FUNCTIONS, for example everything between the <script type> … </script> tags. Just like how you did the unregister.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    Hello QUI T,

    I did everything but the double check doesn’t work yet. 
    Do I  understand that right….

    – the script searches whether a user is already registered for the event,
    if yes the Register is hodden and the unregister button shown.
    – Else (if user is not registered) the Unregister is hidden and Register shown?

    Not in the Default view form I have the following (below the form)
    1. A Script Editor WebPart:
    the Register Unregister script (which works. I now can see both links and they work together with seatsIncrement and seatsDecrement.
    2. A Script Editor WebPart
    The doublecheck script.in which I only changed the Listname to Attendees.

    And ohh, I tried to put the doublecheck script into the other (Register/Unregister) but that didn’t work at all.

    Is there a Priority to put either the Register/Unregister or the doublecheck on top of each other or on top of the form??

    I also created completely new calender Events and deleted all others and all registerings. Still, I can do double registerings and unregister works…

    Something is not getting the values out from the list….?
    And right now I am sticking in the script mud I am lost. :-))

    Again thank you very much for this great help you always do for everyone here in the blog. I really appreciate it very much and I can learn a lot from it.

  • Profile photo of Quy T
    Quy T
    Reply

    @ Joel

    Been bz here.

    yes, the duplicate script will check to see if a person is already registered and will display a pop up window. it does not matter which order you have the 2 scripts and yes, they both need to be in the default display view, no need to put anywhere else.

    where is your SP site hosted, online or on premise? this makes a difference as how the login id is presented, so it will be different for login name for SP online vs on premise… for example:

    online it will be some like

    i:0#.f|membership|myname@mysite.onmicrosoft.com

    where as on premise

    domainname\username

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    @Quy T:
    Our Intranet (SP) is on premise. We have a testserver (virtual) and a productive server (virtual) here in our company.
    We made the migration from SP2010 to SP2013 this year and since then we have such things like i:0#.w|domain\Username instead of the name and login name only.
    In addition here as Username we use 3 digits. First two digits from lastname and 1 digit from the first name.
    Example: Smith John. Username smj. so this would be i:0#.w|domain\smj
    This is probably the problem due to the script doesn’t go successfully through the doublecheck (see next lines).

    The doublecheck script didn’t work at all. it didn’t start. 
    Searching in google, I found a command which should start the script onLoad……

        _spBodyOnLoadFunctionNames.push(‘doublecheckUserAndEvent’);

    So I changed the $(function(){…. }  to

    function doublecheckUserAndEvent(){
    . . .
    }

    Now the script starts but…. there are two other Problems:
     
    1. (spBodyOnLoadFunctionNames.push problem)
    When I want to make a change in the doublecheck script web part….(after create and close/save it)
    when I go again into the defaultdisplayform, all Ribbon Buttons are deactivated and the edit button Image is invisible.

    Workaround: I have to delete the whole doublecheck web part and make a new one again. That works until I newly want to change something in it.
    And that has been the case since I did this one line (see above).

    2. (Username problem)
    the script starts but says only that the user hasn’t been registered yet and shows the “Register” link (the unregister link hides successfully).
    This is also the case when I am already registered for a meeting.

    I guess this has to do with the LoginName and/or the UserName.
    Firebug shows…..
    http://intranettest.domain/org/ict/_api/web/lists/getbytitle(‘Attendees’)/items?$filter=(MeetingID%20eq%203)%20and%20(Username%20eq%20%27LastName%20FirstName%27)

    but in the Attendees list there are no LoginName…they have the following items:
    Title:               i:0#.w|domain\Username registration for event no. x
    Username:      i:0#.w|domain\Username
    Meeting:         Name of the meeting
    MeetingID:     x
    Registration:  status

    I think that loginname/Username is the Problem, isn’t it?
    In firebug in the url they validate Username eq Lastname Firstname which doesn’tmatch with  i:0#.w|domain\Username.

    Questions:
    1. how to change this loginname/username problem (if else works correctly)? I am not so familiar with this stuff.
    2. what could I do to change the “Username” column to Lastname Firstname and ….
       also the title field which should include Lastname Firstname
        instead of i:0#.w|domain\Username….(the entry then would be: lastname firstname registration for event number x)
        Its also much easier for the event owner.
    3. What could be an alternative to the SP command “_spBodyOnLoadFunctionNames.push” to avoid the ribbon problem?  

  • Profile photo of Quy T
    Quy T
    Reply

    @ Joel

    Ah ok, I go it. The script compares the display name of the logged in user (ie. Doe, John) and not (ie domain\johndoe), so you have a couple of choices to make.:

    1) edit the duplicate script so that it compares the current login id and the Username in your attendees list and not the title, look at the script and see the line that is Var LoginName = myJsonObj3.d.Title and change that to the appropriate Json object.

    or

    2) add a data connection to your InfoPath form, query it and then assign a new variable the display name and keep the script as it is.

  • Profile photo of Joel Eymard
    Joel Eymard
    Reply

    Hi Quy T

    Thanks a lot. The most Things work now. But we had to change something within the script see below in “Doublecheck script”).

    We didn’t get the real Name into a new column, so we chosed another approach (almost for now).
    The following steps are to have a real Name. That is easier for People who organize the Events (who is registered) since we have ony shortkeys as  username/Login (3 characters).

    • in Attendees and Unregistration:
    • created a people columnin 
         …in Attendees list named “registered Person”
         …in UnRegistration list named  “unregistered Person”

    In the Attendees and the Unregistration Workflows:

    • added a Action “Set Field in actual element” or something like that
    • clicked “Field” and putted the Registered Person / UnRegistered Person
    • clicked “value” and fx
      • and putted currentItem and “Created by” in there.

    Then published the WF

    Now in a page I can create a “view” for the Event organizers which Shows, who is registered and how many seats are left etc.

    The Doublecheck script:

    Because of the first characters in username  (for example “i:0#.w|…“) especially the “#“,
    the script never returned the correct “user” it always stopped after the “#”.
    Now we did the following…

    in the doublecheck script within the function “getListItems” we changed the line “url:” to…
    url: siteurl + “/_api/web/lists/getbytitle(‘” + listName + “‘)/items?$filter=(MeetingID eq ” + calendarId + “) and (Username eq ‘” + encodeURIComponent(LoginName) + “‘)”,

    Probably the last issue …. :-))
    Now the only thing I have left, is that…

    on UnRegistering, the user stays still within the Attendees list after Unregistering. The UnRegister does add the unregistered entry but it still also remains in the Attendees list.
    Then the check for a new Register always tell that you are still registered and shows the UnRegister  and hides the Register link..   🙁

    Question: What is going wrong here? I think it should be deleted in Attendees when unregistering, shouldn’t it?

  • Profile photo of Quy T
    Quy T
    Reply

    @ Joel

    Glad you were able to figure out a “comparison” that works for you for the “double check”.

    Now, for you to delete entries in the Attendees list, you will have to create a workflow that is opposite of the register workflow. So when someone “unregister” the workflow will kick off and look in the attendees list and delete that user’s entry, you will have to decided on what parameters to use in order to delete that one entry. I would suggest the StaticID and the User Login as your parameters.

  • Sonia
    Reply

    Hi, I’ve just about gotten this – in the comments you talk about a unregister and check feature??? Where is that exactly? Also, in the calculated field for “register” in the HREF # – which URL goes in there? To the Calendar list? Any help would be appreciated. I was using the SP 2010 free Microsoft template but they wanted a way to put the classes on their personal calendar and although I got it to work via .ics files – the client can’t use .ics files so I’m starting from scratch.

  • Talita Feuerstein
    Reply

    I am encountering a snag not listed. When setting up a workflow (mine looks exactly like the image posted) I get the following message when trying to publish it:
    “(Transition section cannot be empty . Insert a go-to action.)”
    My options if I click on action-go to stage are Go to Stage 1 or End the Workflow.
    Any advice which to choose?

  • Talita Feuerstein
    Reply

    Also, for my JQuery text, my URL is:
    /Lists/Class%20Attendees%20List/Item/newifs.aspx?List=e65a459f%2D6315%2D479a%2D9e8a%2D29eda103c654&RootFolder=&Web=afaaea1d%2D624e%2D4296%2D94d5%2D363eeaf35347

    I have tried adding &class_id= to the end of that URL I copied and pasted, and also tried replacing the text after &RootFolder for &class_id=

    I am still getting the following text instead of link itself Register

    Please help!
    Frustrated Talita
    🙁

    • Talita Feuerstein
      Reply

      I mean I am still getting the text a href=’#’ onclick=’OpenLandLRegistration(1)’ (with proper ) instead of link itself

  • Talita Feuerstein
    Reply

    Alright, I was able to get some help with some of the stuff I was having issues with. Currently the only thing that is not working is the Registration Workflow. I followed the steps exactly, and even re-did it a couple of times. It seems nothing is calling for the workflow. I even tried just telling it to change the number of filled seats to ‘5’ to see if workflow was working at all. Anyone else ran into the workflow not working? I am new to workflow, not sure how to even debug it. Help!

  • Steven C
    Reply

    Does anyone know how to set this up so department supervisors can register their team members? (assumption is that reporting structure is set up in AD correctly)

  • Dan
    Reply

    How can you do this without using InfoPath? I have about pulled my hair out trying to figure out how to get everything working by just using the SharePoint Designer.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">