Require Unique Answers in SharePoint Survery Ranking Scale
Posted on 13 August 2010 by Jason Grimme
Let’s pretend you want to create a SharePoint survey where you ask your audience how they would rank the three Lord of the Rings books, in order from their most to least liked.
The best solution would be to create a ranking scale, and list the three books and three choices (Most liked, Middle, Least liked). This would be realtively simple except for that you want to make sure they can only select ‘Most liked’ once. This is where SharePoint has no method of requiring unique answers between questions.
After trying many different methods, I settled on creating a custom JavaScript function on the page that validates that answers to ranking scale questions are unique.
Update:
See this validation post for an alternative way to add validation to a page.
Hooking Into SharePoints Validation Before Submitting
On any SharePoint page, if you create a JavaScript function named PreSaveAction, it will run and require a return true before submitting the page.
My custom function is named RequireUniqueRankings and accepts an array that tells it which ranking matrices you want to force unique answers on. It returns true if there were no problems and returns false if there were, which prevents the form from submitting.
I added the custom code in the survey page using Microsoft Designer.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <script type="text/javascript"> function PreSaveAction() { // Settings for matrices that require unique values // Start with zero and go by order in which they appear in the source // Default: False var matrices = new Array(); matrices[0] = true; matrices[1] = false; return RequireUniqueRankings(matrices); } |
Ugly SharePoint HTML
Microsoft spent a great deal of time making the ranking matrices extremely hard to parse. Not only are the names and IDs of the radio buttons pointless, the values are useless as well. They could have assigned values like 0, 1, 2, 3, etc, but no. They use values such as ctl00, ctl01, and ctl02. This would be tolerable except for the value names keep increasing within the same matrix. For the second option in the same matrix, the exact same three rankings will be ctl03, ctl04, and ctl05 instead of ctl00, ctl01, and ctl02. Why I don’t know, but it certainly is nonsensical.
Example HTML for one rank matrix – Three Items x Three ranks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | ] <table cellpadding="0" cellspacing="1" border="0" height="95%" summary="Rating Scale Question"> <tr> <td> </td> <td class="ms-verticaldots"> </td> <td class="ms-gridCol">First</td> <td class="ms-gridCol">Second</td> <td class="ms-gridCol">Third </td> </tr> <tr> <td> </td> <td class="ms-verticaldots"> </td> <th scope="col" class="ms-gridCol">1</th> <th scope="col" class="ms-gridCol">2</th> <th scope="col" class="ms-gridCol">3</th> </tr> <tr> <td class="ms-sectionline" colspan="100%" height="1"><img alt="" src="/_layouts/images/blank.gif" /></td> </tr> <!-- First option--> <tr> <th class="ms-gridT1" scope="row">The Lord of the Rings: Fellowship of the Ring</th> <td class="ms-verticaldots"> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl00" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl00" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl00').title='The Lord of the Rings: Fellowship of the Ring Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl01" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl01" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl01').title='The Lord of the Rings: Fellowship of the Ring Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl02" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl02" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl02').title='The Lord of the Rings: Fellowship of the Ring Value 3';</script> </td> </tr> <!-- Second option--> <tr> <th class="ms-gridT1" scope="row">The Lord of the Rings: The Two Towers</th> <td class="ms-verticaldots"> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl03" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl03" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl03').title='The Lord of the Rings: The Two Towers Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl04" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl04" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl04').title='The Lord of the Rings: The Two Towers Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl05" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl05" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl05').title='The Lord of the Rings: The Two Towers Value 3';</script> </td> </tr> <!-- Second option--> <tr> <th class="ms-gridT1" scope="row">The Lord of the Rings: The Return of the King</th> <td class="ms-verticaldots"> </td> <td align="center" <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl06" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl06" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl06').title='The Lord of the Rings: The Return of the King Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl07" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl07" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl07').title='The Lord of the Rings: The Return of the King Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl08" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl02$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl08" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl02_ctl00_ctl00_ctl04_ctl00_ctl08').title='The Lord of the Rings: The Return of the King Value 3';</script> </td> </tr> <!-- END OPTIONS --> </table> |
Example HTML – One Matrix – 5 Items x 5 Ranks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | <table cellpadding="0" cellspacing="1" border="0" height="95%" summary="Rating Scale Question"> <tr> <td> </td> <td class="ms-verticaldots"> </td> <td class="ms-gridCol">Low </td> <td class="ms-gridCol"></td> <td class="ms-gridCol">Average</td> <td class="ms-gridCol"></td> <td class="ms-gridCol"> High</td> </tr> <tr> <td> </td> <td class="ms-verticaldots"> </td> <th scope="col" class="ms-gridCol">1</th> <th scope="col" class="ms-gridCol">2</th> <th scope="col" class="ms-gridCol">3</th> <th scope="col" class="ms-gridCol">4</th> <th scope="col" class="ms-gridCol">5</th> </tr> <tr> <td class="ms-sectionline" colspan="100%" height="1"> <img alt="" src="/_layouts/images/blank.gif" /></td> </tr> <tr> <th class="ms-gridT1" scope="row">First</th> <td class="ms-verticaldots"> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl00" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl00" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl00').title='First Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl01" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl01" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl01').title='First Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl02" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl02" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl02').title='First Value 3';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl03" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl03" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl03').title='First Value 4';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl04" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:0" value="ctl04" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl04').title='First Value 5';</script> </td> </tr> <tr> <th class="ms-gridT1" scope="row">Second</th> <td class="ms-verticaldots"> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl05" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl05" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl05').title='Second Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl06" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl06" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl06').title='Second Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl07" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl07" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl07').title='Second Value 3';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl08" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl08" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl08').title='Second Value 4';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl09" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:1" value="ctl09" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl09').title='Second Value 5';</script> </td> </tr> <tr> <th class="ms-gridT1" scope="row">Third</th> <td class="ms-verticaldots"> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl10" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl10" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl10').title='Third Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl11" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl11" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl11').title='Third Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl12" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl12" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl12').title='Third Value 3';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl13" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl13" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl13').title='Third Value 4';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl14" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:2" value="ctl14" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl14').title='Third Value 5';</script> </td> </tr> <tr> <th class="ms-gridT1" scope="row">Fourth</th> <td class="ms-verticaldots"> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl15" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:3" value="ctl15" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl15').title='Fourth Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl16" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:3" value="ctl16" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl16').title='Fourth Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl17" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:3" value="ctl17" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl17').title='Fourth Value 3';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl18" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:3" value="ctl18" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl18').title='Fourth Value 4';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl19" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:3" value="ctl19" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl19').title='Fourth Value 5';</script> </td> </tr> <tr> <th class="ms-gridT1" scope="row">Fifth</th> <td class="ms-verticaldots"> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl20" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:4" value="ctl20" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl20').title='Fifth Value 1';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl21" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:4" value="ctl21" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl21').title='Fifth Value 2';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl22" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:4" value="ctl22" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl22').title='Fifth Value 3';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl23" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:4" value="ctl23" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl23').title='Fifth Value 4';</script> </td> <td align="center"> <input id="ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl24" type="radio" name="ctl00$m$g_50921f35_b2ce_4835_8087_6ebf6c0e84ec$ctl00$ctl01$ctl03$ctl00$ctl00$ctl04$ctl00$RadioButtons:4" value="ctl24" /> <script>document.getElementById('ctl00_m_g_50921f35_b2ce_4835_8087_6ebf6c0e84ec_ctl00_ctl01_ctl03_ctl00_ctl00_ctl04_ctl00_ctl24').title='Fifth Value 5';</script> </td> </tr> </table> |
Validating Ranking Answers
In essence, my script loops through all radio button input elements, and then sorts all of them based on some logic that results in them being split into the different matrices as well as grouping the answer values so that they are 0, 1, 2 instead of ctl00, ctl01, and ctl02.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | function RequireUniqueRankings(requiredMatrices) { var matrixCount = 0; var rankedMatrixes = new Array(); rankedMatrixes[matrixCount] = new Object; rankedMatrixes[matrixCount]['matrixRadioButtons'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioSPvalues'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioNames'] = new Object; rankedMatrixes[matrixCount]['matrixRadioValues'] = new Object; rankedMatrixes[matrixCount]['matrixRadioSelected'] = new Object; // Get all input radio buttons var inputsArr = document.getElementsByTagName("input"); // Loop through all inputs. Get matrix radio buttons for(var i=0; i<inputsArr.length; i++) { if(inputsArr[i].type == "radio") { // Determine if this radio button is part of a ranked matrix // Assumed pattern: name="ctl00...ctl00$RadioButtons:2" var rankMatrixRefEx = /RadioButtons\:\d+/g; var isRankMatrixRadio = rankMatrixRefEx.exec(inputsArr[i].name); if(isRankMatrixRadio) { // If we have already run into this value, then we are on a new matrix // Loop through all values for current matrix. for(m=0; m<rankedMatrixes[matrixCount]['matrixRadioSPvalues'].length; m++) { if(rankedMatrixes[matrixCount]['matrixRadioSPvalues'][m] == inputsArr[i].value) { matrixCount++; rankedMatrixes[matrixCount] = new Object; rankedMatrixes[matrixCount]['matrixRadioButtons'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioSPvalues'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioNames'] = new Object; rankedMatrixes[matrixCount]['matrixRadioValues'] = new Object; rankedMatrixes[matrixCount]['matrixRadioSelected'] = new Object; } } rankedMatrixes[matrixCount]['matrixRadioSPvalues'].push(inputsArr[i].value); // Add to list of radio buttons rankedMatrixes[matrixCount]['matrixRadioButtons'].push(inputsArr[i]); // Add to list of radio groups rankedMatrixes[matrixCount]['matrixRadioNames'][inputsArr[i].name] = inputsArr[i].value; } } } /* Good for debugging var list = ""; for(var i=0; i<rankedMatrixes.length; i++) { for(var j=0; j<rankedMatrixes[i]['matrixRadioButtons'].length; j++) { list += i + " : " + rankedMatrixes[i]['matrixRadioButtons'][j].name + "\n"; } } alert(list); */ // Loop through each of our matrixi and check for unique values for(var i=0; i<rankedMatrixes.length; i++) { // If we didn't require this to have unique values, skip it if(!requiredMatrices[i]) { continue; } //Get selected values for each ranked option // Loop through each question/group for( var radioName in rankedMatrixes[i]['matrixRadioNames']) { var buttonsWithinName = document.getElementsByName(radioName); for(var j=0; j<buttonsWithinName.length; j++) { // Assoc this unique value with the general value (0, 1, 2, etc) // ex ctl00 = 0; ctl01 = 1; ... ctl04 = 0; rankedMatrixes[i]['matrixRadioValues'][buttonsWithinName[j].value] = j; if(buttonsWithinName[j].checked == true) { // Assign this value to this name rankedMatrixes[i]['matrixRadioSelected'][radioName] = buttonsWithinName[j].value; } } } // Return false if user selected a ranking more than once // Will keep track of selected values for this group var valuesWithinGroup = new Object; // For each group for( var radioGroup in rankedMatrixes[i]['matrixRadioSelected']) { var groupName = radioGroup; var groupUniqueValue = rankedMatrixes[i]['matrixRadioSelected'][radioGroup]; var groupCommonValue = rankedMatrixes[i]['matrixRadioValues'][groupUniqueValue]; if(valuesWithinGroup[groupCommonValue]) { // Get the title for this group var groupTitle = document.getElementsByName(groupName)[groupCommonValue].title; alert("You may only select a ranking once between the items.\nPlease revise your ranking for " + groupTitle); return false; } // Register this rank as taken valuesWithinGroup[groupCommonValue] = true; } }// End each matrix // If we made it to this point, they have not selected a ranking twice. return true; } |
Final Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | <script type="text/javascript"> function PreSaveAction() { // Settings for matrices that require unique values // Start with zero, by order in which they appear in the source // Default: to false var matrices = new Array(); matrices[0] = true; matrices[1] = true; return RequireUniqueRankings(matrices); } function RequireUniqueRankings(requiredMatrices) { var matrixCount = 0; var rankedMatrixes = new Array(); rankedMatrixes[matrixCount] = new Object; rankedMatrixes[matrixCount]['matrixRadioButtons'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioSPvalues'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioNames'] = new Object; rankedMatrixes[matrixCount]['matrixRadioValues'] = new Object; rankedMatrixes[matrixCount]['matrixRadioSelected'] = new Object; // Get all input radio buttons var inputsArr = document.getElementsByTagName("input"); // Loop through all inputs. Get matrix radio buttons for(var i=0; i<inputsArr.length; i++) { if(inputsArr[i].type == "radio") { // Determine if this radio button is part of a ranked matrix // Assumed pattern: name="ctl00...ctl00$RadioButtons:2" var rankMatrixRefEx = /RadioButtons\:\d+/g; var isRankMatrixRadio = rankMatrixRefEx.exec(inputsArr[i].name); if(isRankMatrixRadio) { // If we have already run into this value, then we are on a new matrix // Loop through all values for current matrix. for(m=0; m<rankedMatrixes[matrixCount]['matrixRadioSPvalues'].length; m++) { if(rankedMatrixes[matrixCount]['matrixRadioSPvalues'][m] == inputsArr[i].value) { matrixCount++; rankedMatrixes[matrixCount] = new Object; rankedMatrixes[matrixCount]['matrixRadioButtons'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioSPvalues'] = new Array(); rankedMatrixes[matrixCount]['matrixRadioNames'] = new Object; rankedMatrixes[matrixCount]['matrixRadioValues'] = new Object; rankedMatrixes[matrixCount]['matrixRadioSelected'] = new Object; } } rankedMatrixes[matrixCount]['matrixRadioSPvalues'].push(inputsArr[i].value); // Add to list of radio buttons rankedMatrixes[matrixCount]['matrixRadioButtons'].push(inputsArr[i]); // Add to list of radio groups rankedMatrixes[matrixCount]['matrixRadioNames'][inputsArr[i].name] = inputsArr[i].value; } } } /* Good for debugging var list = ""; for(var i=0; i<rankedMatrixes.length; i++) { for(var j=0; j<rankedMatrixes[i]['matrixRadioButtons'].length; j++) { list += i + " : " + rankedMatrixes[i]['matrixRadioButtons'][j].name + "\n"; } } alert(list); */ // Loop through each of our matrixi and check for unique values for(var i=0; i<rankedMatrixes.length; i++) { // If we didn't require this to have unique values, skip it if(!requiredMatrices[i]) { continue; } //Get selected values for each ranked option // Loop through each question/group for( var radioName in rankedMatrixes[i]['matrixRadioNames']) { var buttonsWithinName = document.getElementsByName(radioName); for(var j=0; j<buttonsWithinName.length; j++) { // Assoc this unique value with the general value (0, 1, 2, etc) // ex ctl00 = 0; ctl01 = 1; ... ctl04 = 0; rankedMatrixes[i]['matrixRadioValues'][buttonsWithinName[j].value] = j; if(buttonsWithinName[j].checked == true) { // Assign this value to this name rankedMatrixes[i]['matrixRadioSelected'][radioName] = buttonsWithinName[j].value; } } } // Return false if user selected a ranking more than once // Will keep track of selected values for this group var valuesWithinGroup = new Object; // For each group for( var radioGroup in rankedMatrixes[i]['matrixRadioSelected']) { var groupName = radioGroup; var groupUniqueValue = rankedMatrixes[i]['matrixRadioSelected'][radioGroup]; var groupCommonValue = rankedMatrixes[i]['matrixRadioValues'][groupUniqueValue]; if(valuesWithinGroup[groupCommonValue]) { // Get the title for this group var groupTitle = document.getElementsByName(groupName)[groupCommonValue].title; alert("You may only select a ranking once between the items.\nPlease revise your ranking for " + groupTitle); return false; } // Register this rank as taken valuesWithinGroup[groupCommonValue] = true; } }// End each matrix // If we made it to this point, they have not selected a ranking twice. return true; } </script> |
Tags | JavaScript, SharePoint, Validation


Thank you very much, Jason. The code works for me.
If I have access to sharepoint designer how do I add this code in? I can’t actually edit anything in the server itself just the site I manage. Under the survey I just have
Allitems
DispForm
EditForm
NewForm
overview
summary
Can I add this code to any of these bits or do I need to be able to edit stuff directly on the server side?
Hi!!
Where insert this code??I have sharepoint 2007+designer 2007.
I open Survery->newForm.aspx, insert code and nothing…
Help please!!