This was a triumph.
I'm making a note here: HUGE SUCCESS.

Search This Blog

Wednesday, October 23, 2013

How to make a contact form in SharePoint and submit the messages to a SharePoint list

I had to make a contact page for an intranet SharePoint site, and didn't like the idea of receiving dozens of e-mails every single day. First of all that would really flood my mailbox and I would have to make a folder in my mailbox just for contact messages received by the intranet site, and second of all I just don't like having to read a lot of new e-mails.

So! I decided that I wanted all the messages to be stored in a SharePoint list, and I wrote a script to handle this. The script fetches the subject, message, full name and e-mail address of the user who sends a message through the contact form. Only the subject and the message have to be filled in by the user, the full name and e-mail address are fetched automatically based on the current user. If everything is correct and validates, it saves the data as a new list item. 

Here are some screenshots of what it will look like.

The contact page with the contact form:

The contact form when you try to click send without filling in anything:

The contact form when you filled in the fields and pressed send:

So you see, it has proper validation. If one of the fields or both isn't filled in, it won't get sent as an empty message. If it is filled in properly and the user has pressed send, it will be sent to the Contact list and the input fields and send button will be disabled (to prevent the user from sending the same message again).

If the user has successfully submitted a message, he/she can follow the status of his/her message on another page (or you can put it on the same page, depends on what you like). I've put it on a second page, and this is what it looks like:

Depending on the status of the message, it can be found under either "Sent", "Received" or "Answered". These three tabs are three web parts with different views.

Let's begin. 

First of all, you will need to make a SharePoint list in which you want to store all the messages.
My list is named "Contact".
I created 7 new columns: "Date", "Name", "Email", "Title", "Message", "Status" and "Answer". The "Title" column was a default column that can't be removed, but I'll just use it instead of making a new column for the subject.

Here's an overview of all the columns your list will need:
ColumnTypeUsed for
DateDate and TimeStoring the date and time of the message
NameSingle line of textStoring the name of the user who sent the message
EmailSingle line of textStoring the e-mail address of the user who sent the message
TitleSingle line of textStoring the subject of the message
MessageMultiple lines of textStoring the message
StatusChoiceSetting the status of the message (Sent/Received/Answered)
AnswerMultiple lines of textStoring the answer of the administrator


You will also need to create views for the Contact list. Each view has a filter applied. The first view is filtered to only show items of which the Status column equals the value "Sent", the second view is filtered to only show items of which the Status column equals the value "Received", and the third view is filtered to only show items of which the Status column equals the value "Answered".
What is also very important, is that each view should have 2 filters. The first is to filter the status of the message, the second filter is to make sure only the person who sent the message can see his own message. The items in these views have to satisfy both requirements that have been set in the filters. Other people shouldn't be able to see the messages of others. To do so, set the second filter of all the views to show only items when the column "Made by" equals "[Me]". By doing so, only the person who sent the message will see his message. You as an administrator will off course always be able to see the messages since you can just make another view for yourself and skip the second filter.

When your list is set up, we can begin on preparing the contact page with a contact form. I made a content editor web part and added the following code to it (edit source of the web part first, then add the code):
<table id="ContactTable"> 
   <tbody>
      <tr> 
         <td class="contactLabel">Subject:</td>
         <td colspan="2">
            <input class="contactInput" id="Subject" name="Subject" 
                   type="text" /> 
         </td>
      </tr>
      <tr> 
         <td class="contactLabel">Message:</td>
         <td colspan="2">
            <textarea class="contactInput contactInputMessage" 
                      id="Message" name="Message"> </textarea> 
         </td>
      </tr>
      <tr>
         <td></td> 
         <td>
            <span id="FeedbackField"> </span> 
         </td>
         <td>
            <div id="ClickMeButton">Send​​​​​​​​​​​​​​</div>
         </td>
      </tr>
   </tbody> 
</table>

Put a script editor web part at the bottom of the Contact page and add the following code to it (I stored my script in the MasterPageGallery folder, but wherever you plan on making your script, just make sure that the reference is correct):
<script type="text/javascript" 
src="~sitecollection/_catalogs/masterpage/MasterPageGallery/Contact.js">
</script>

For the Contact overview page, edit the source and add the following code:
<div id="ContactTabs">
   <div id="tabs1">
      <ul>
         <li><a href="#tabs1-1">Sent</a></li>
         <li><a href="#tabs1-2">Received</a></li>
         <li><a href="#tabs1-3">Answered</a></li>
      </ul>
      <div id="tabs1-1">
        <!-- Space reserved for a content editor web part with a view for
             "Sent" -->
      </div>
      <div id="tabs1-2">
        <!-- Space reserved for a content editor web part with a view for
             "Received" -->
      </div>
      <div id="tabs1-3">
        <!-- Space reserved for a content editor web part with a view for
             "Answered" -->
      </div>
   </div>
</div>

Then put a script editor web part at the bottom of your Contact overview page and include the following code:
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
  $(function() {
    $( "#tabs1" ).tabs();
  });
</script>

This is the CSS for the above contact form and for the contact overview (best to put this in a CSS file and add a link to that file in your master page):
#ContactTable {
 margin-left: auto;
 margin-right: auto;
}

#ClickMeButton {
 padding: 5px;
 background-color: #d7d6d8;
 border: 1px solid gray;
 width: 78px !important;
 margin-top: 10px;
 font-family: 'Francois One', sans-serif;
 text-transform: uppercase;
 letter-spacing: 0.1em;
 text-align: center;
 float: right;
}

.contactLabel {
 width: 100px;
 display: table-cell;
 vertical-align: top;
 padding-top: 4px;
 text-align: right;
 padding-right: 10px;
}

.contactInput { width: 400px; }

.contactInputMessage {
 max-width: 650px !important;
 min-width: 650px !important;
 min-height: 100px;
 max-height: 200px;
}

#ContactTabs .ms-webpartzone-cell { margin-top: 10px; }

#ContactTabs {
 margin-left: auto;
 margin-right: auto;
 width: 700px;
}

All right! We have now set up the Contact page and the Contact overview page and styled them. Don't forget to add the content editor web parts to the Contact overview page.

Now all we need is functionality!

Create a JavaScript file, I created mine in SharePoint Designer 2013 and it is located in _catalogs/masterpage/MasterPageGallery/Contact.js. You can put it somewhere else if you want to, but this is just where I put it.

Here's the code of my Contact.js file, I added comments to explain to you what everything does. Please keep in mind that I might not have put comments everywhere, but I do my best!
// Load the scripts, make sure you have a script for jQuery as well.
SP.SOD.executeOrDelayUntilScriptLoaded(sharePointReady, 
"SP.UserProfiles.js", 
"~sitecollection/Style Library/Scripts/jquery.SPServices-2013.01.min.js"
);
SP.SOD.executeFunc("SP.js", "SP.ClientContext", sharePointReady);

// run the following function.
sharePointReady();

function sharePointReady() {
  // Initialize a new instance of the ClientContext object.
   var clientContext = new  SP.ClientContext.get_current();   
   this.website = clientContext.get_web();
   this.currentUser = website.get_currentUser();
  
   clientContext.load(currentUser);
   clientContext.load(website);

   // Execute the query, add functions to launch when it succeeds/fails.
   clientContext.executeQueryAsync(
      Function.createDelegate(this, this.onRequestSucceeded), 
      Function.createDelegate(this, this.onRequestFailed)
   );
}

function onRequestSucceeded() {   
   // Fetch the full name of the user that is sending the message.
   var fullUserName = $().SPServices.SPGetCurrentUser({
      fieldName: "Title",
      debug: false
   });

   // Fetch the e-mail address of the user that is sending the message.
   var emailAddress = $().SPServices.SPGetCurrentUser({
      fieldName: "Email",
      debug: false
   });
  
   // Execute the following function.
   SendEnquiry();
 
   function SendEnquiry() {
      document.getElementById('ClickMeButton').onclick = function(){   
         var NameField = fullUserName;
         var emailField = emailAddress;
         var subjectField = document.getElementById("Subject").value;
         var messageField = document.getElementById("Message").value;

         // If one of the input fields or both input fields are empty,
         // then give feedback.
         if( (subjectField == "" && messageField == "")
          || (subjectField == "") || (messageField == "") ){
            document.getElementById("FeedbackField").innerHTML =
               "Please fill in all the fields. ";
            document.getElementById('FeedbackField').style.color = "red";
         } 
         // If both fields are filled in, start the function to save
         // the values as a new list item in the Contact list.
         else {   
           SaveInContact(NameField,emailField,subjectField,messageField);
         }
      };
   }

   function SaveInContact(Name,Email,Subject,Message) {
      // Initialize a new instance of the ClientContext object for the 
      // specified SharePoint site.
      var context = new SP.ClientContext.get_current(); 
      var web = context.get_web();
      // Get the list in which you want to store the values, we use the 
      // Contact list.
      var list = web.get_lists().getByTitle("Contact");  
      var listItemCreationInfo = new SP.ListItemCreationInformation();   
      var newItem = list.addItem(listItemCreationInfo);
      // This below is to set which column will get which value, the 
      // first part is the name of the column and the second part is 
      // the value it will get.
      newItem.set_item("Title", Subject);
      newItem.set_item("Name",Name);
      newItem.set_item("Email",Email);
      newItem.set_item("Message",Message);
      newItem.set_item("Status",'Sent');
      newItem.update();

      context.executeQueryAsync(
         Function.createDelegate(this, this.onAddSucceeded), 
         Function.createDelegate(this, this.onAddFailed)
      );
  
      document.getElementById("FeedbackField").innerHTML = 
         "Thank you! Your message has been sent. ";   
      document.getElementById('FeedbackField').style.color = "green";
      // Disable the input fields and the button to prevent the user 
      // from submitting the same message again.
      document.getElementById("Subject").disabled = true;
      document.getElementById("Message").disabled = true;
      document.getElementById("ClickMeButton").disabled = true;
      document.getElementById("ClickMeButton").style.backgroundColor = 
         "#ECEBEC";
   }
}

function onRequestFailed(sender, args) {   
 console.log("Error: " + args.get_message());
 alert("Request failed: " + args.get_message() + '\n' 
   + args.get_stackTrace());
}

function onAddSucceeded() {
 document.getElementById("ClickMeButton").style.color = "green";
}

function onAddFailed(sender, args) {
 alert("Error: " + args.get_message() + "\n"+ args.get_stackTrace());
}

(function () { 
 document.getElementById("ClickMeButton").onclick = SendEnquiry();
})(); 


That's it! With this code, you should now have a functional contact form. :)

Got questions? Need extra information? Are you stuck at some part? Then do not hesitate to comment, I'll do my best to help you as soon as I can. Also, adding console logs everywhere in the code might help. That way you can see what get executed and what doesn't.


Regards,

Magali

3 comments:

  1. Hi Magali,

    i'm new in Sharepoint JS, plz help me, i have a simple contact form only 4 field i want save all field data in SharePoint list.
    how to save .


    ReplyDelete
    Replies
    1. Hi! I can't really help much more than what's said in this post, the SaveInContact function is a good example of how to save data to a SharePoint list. You just need to get the values of the fields you want to save and pass them to that function.

      Delete
    2. Create a form (Infopath / Nintex)

      Delete