Visual Studio: Slow to Remove / Delete Files From Solution

At work I have been noticing an increase in time it takes to remove a file from a solution. Several weeks ago it took about ten seconds, but recently it has been taking a few minutes.
The other day while waiting for a file to be deleted I decided to figure out what was causing the problem. I was able to do some research, find the problem, and fix the problem while Visual Studio was trying to remove a file Once I fixed the problem the file finished deleting.

The Fix

It’s a simple fix, really. Empty your recycle bin. I had about two gigabytes of files and after removing them, the deletion process took less than a second. It’s unusual to be happy when you get what should have received in the first place. Then again, it’s a Microsoft product. Maybe I should be happy it works most of the time :P .

Computers, Programming Comments (0)

Custom Validation and Content on SharePoint Survey

Today my script that I wrote for Require Unique Answers in SharePoint Survery Ranking Scale was rejected because it used designer which is frowned upon for ghosting pages. I was left to quickly find a way to include a content editor web part on the survey page that contained the JavaScript.

Luckily, I found out that you can trick SharePoint into displaying the survey page in edit mode, which allows you to add web parts.

Trixie Little Hobbitses

  • Let’s say the link to your survey is http://mySite/documents/survey/newform.aspx.
  • Add the parameter/value toolpaneview=2 to the URL
  • Resulting in: http://mySite/documents/survey/newform.aspx?toolpaneview=2
  • Let’s say the link to your survey is http://mySite/documents/survey/newform.aspx?source=http://mySite.
  • Add the parameter/value toolpaneview=2 to the URL
  • Resulting in: http://mySite/documents/survey/newform.aspx?source=http://mySite&toolpaneview=2

Of course, you don’t really need to keep the source parameter on the URL.

You can then add your web part, most likely a content editor web part.

To add custom validation, add JavaScript using the PreSaveAction() method like the following and in the referenced post at the beginning of this article.

1
2
3
4
5
6
7
<script type="text/javascript">
    function PreSaveAction()
    {
        // Put your custom validation here
        return true;
    }
</script>

Update: Adding validation on Survey Edit page

After some user testing, I discovered that users could edit survey submissions (if enabled) without my Javascript validation. I took a shot at trying to add a content editor web part to the edit.aspx page and it worked as well. Simply add the same toolpaneview=2 bit onto the end of the aspx page and the add web part interface will be displayed.

Programming Comments (0)

Require Unique Answers in SharePoint Survery Ranking Scale

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.

SharePoint Ranking Scale Problem

Using This Script Forces Unique Values

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>&nbsp;</td>
        <td class="ms-verticaldots">&nbsp;</td>
        <td class="ms-gridCol">First</td>
        <td class="ms-gridCol">Second</td>
        <td class="ms-gridCol">Third&nbsp;</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td class="ms-verticaldots">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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>&nbsp;</td>
        <td class="ms-verticaldots">&nbsp;</td>
        <td class="ms-gridCol">Low&nbsp;</td>
        <td class="ms-gridCol"></td>
        <td class="ms-gridCol">Average</td>
        <td class="ms-gridCol"></td>
        <td class="ms-gridCol">&nbsp;High</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td class="ms-verticaldots">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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>

Programming Comments (1)

KitchenAid Stand Mixer Comparison: Part Three – Colors


Article Parts

KitchenAid Stand Mixer Colors

Much like iPods, clothes, laptops, and houses, the color of your KitchenAid stand mixer matters. KitchenAid offers more than thirty different colors for the Artisan series and a handful for the other model types.

Because people have different tastes; and, because certain colors have limited availability, this has created a difference in value between mixers of the exact same model. This is extremely evident when buying a mixer online through Amazon or eBay where the consumer truly is king.

List / Images of All KitchenAid Mixer Colors

Here are all the color varieties that I have found thus far. I have attempted to put them in order by color :) . For now this list only contains colors for the Artisin and does not have the colors for the Pro 600 – but it will in the future.

[more...]

Food, Personal Comments (0)

KitchenAid Stand Mixer Comparison: Part Two – Prices


Article Parts

KitchenAid Stand Mixer Pricing

Much to my dismay, there was not a lot of price variance for the same mixer model between retailers. It is possible that since KitchenAid has their "Authentic Retailer", they are able to mandate prices like Apple and their iPods.

Because of this, I won’t spend a lot of time supplying prices for individual retailers (Though I did do a lot of research on this). On a similar note, I didn’t visit every online store and check their price. I checked the main ones, including Amazon and eBay.

Pricing Summary

How do you like that? A summary before any of the data. I figured that many people won’t care about my research data.

Buying In The Store (Stubborn)

If you insist on buying in a local retailer, it doesn’t really matter which store you buy it from. The Classic model will be about $200, the Artisan will be $300, and the Pro 600 will be $400. If this isn’t the price at your store, try a different one.

Buying Online (Wise)

If you are up for buying online, I tip my hat to you. Not only are the prices cheaper, but you have greater selection of the many colors that KitchenAid offers. I bet your local retailer doesn’t carry thirty different colors, do they? I would recommend Amazon.com for buying online, they seem to be about 15% less than local stores. eBay is another great place to look for these, even new.

Buying Used or Refurbished (Practical)

With the stand mixers, you don’t always have to buy them new. These last for decades and thus there is nothing wrong with buying one that is used or refurbished.eBay has an enormous amount of auctions for KitchenAid stand mixers for sale in used and new-in-box. A used mixer can be consistently found for half the price of the new item in stores. This is absolutely the best deal that you can count on finding.
KitchenAid has a massive refurbished program and sells through their website in addition to eBay (Their account is KitchenAid). Their eBay listings ended up being about 5% cheaper than through their website. They all come with warranties.

Supporting Data

As mentioned earlier, I won’t really cover buying these magnificent machines in your local retail store. The prices are pretty much all the same and the only way you will find a deal is if it is on some special sale, which I can’t of course predict. I’m covering consistent data.

KitchenAid Mixers Pricing - eBay vs Retail

KitchenAid Mixers Pricing - eBay vs Retail. Prices include shipping.

Table: Contains price averages for specific KitchenAid Stand Mixer models.

Model Average Price
(Including Shipping)
Classic eBay Used $110
Classic eBay Refurb $120
Classic eBay New $147
Classic Retail $214
Artisan eBay Used $147
Artisan eBay Refurb $183
Artisan eBay New $217
Aresian Retail $298
Pro 500 eBay Used $170
Pro 500 eBay Refurb $198
Pro 500 eBay New $223
Pro 500 Retail $285
Pro 600 eBay Used $247
Pro 600 eBay Refurb $272
Pro 600 eBay New $304
Pro 600 Retail $415

All prices above and below include the price of shipping, so as to make it easier to compare the cost with buying locally.

Table: Documents the price difference between used, new, and retail mixers as a percentage. This is perhaps the most important information I have here!

Model eBay Used vs New eBay New vs Retail eBay Used vs Retail Refurb vs Retail
KitchenAid Classic 25% 31% 49% 44%
KitchenAid Artisan 32% 27% 51% 39%
KitchenAid Pro 500 24% 22% 40% 31%
KitchenAid Pro 600 19% 27% 40% 34%
Averages 25% 27% 45% 37%

You can see that even buying the mixers new on eBay is a fabulous deal. Some interesting statistics to highlight are that:

  • Buying a new mixer on eBay is about 27% cheaper than buying in a store.
  • A used mixer in good condition is about 25% cheaper than buying it new on eBay.
  • Therefore, a used mixer on eBay is about half the cost of a new one from the store.
  • Refurbished mixers (which are practically new) are about 37% less than the cost of a new item from a retailer.

Article Parts

Food, Personal Comments (1)

KitchenAid Stand Mixer Comparison: Part One – Models


Article Parts

Intro to the KitchenAid Mixer

If you ever watch television, on cooking shows you always see a KitchenAid stand mixer. If you watch a movie where the character has a nice kitchen, you will always see a KitchenAid stand mixer. If your friend likes to cook, chances are he/she has a KitchenAid stand mixer. These beasts of a tool are a symbol that you enjoy cooking, and that you have value buying tools that will last you a lifetime. I have wanted to buy one of these for many years, but being that they cost a few hundred dollars, you can bet your bottom Dollar that I am going to do a lot of research. Especially if I plan on using it for several decades.

This post will be part of a series of articles that I will post in the next few days. I will link to all of them here.

Models

The first thing to decide has been which model I want. There are three main models of the stand mixer, but there are also several other models, special editions, and varieties made special for different stores.
The three most common models are Classic, Artisan, and Pro 600. The Pro 500 model is a small upgrade from the artisan and the Pro 5 Plus seems to be a model that is sold to stores like CostCo, Sams Club, and Kohls, and then given a different model name. Here is a summary on the seven models that I came across most frequently.

Visual Comparison

Feature Comparison

  Classic Classic Plus Artisan 90th Anniv. Pro 500 Pro 5 Plus Pro 600
Wattage 250 Watts 275 Watts 325 Watts 325 Watts 325 Watts 450 Watts 575 Watts
Speeds 10 10 10 10 10 10 10
Bowl Size 4.5 Quarts 4.5 Quarts 5 Quarts 5 Quarts 5 Quarts 5 Quarts 6 Quarts
Head Tilt Yes Yes Yes Yes No No No
Bowl Lift No No No No Yes Yes Yes
Height 14 inches 14 inches 14 inches 14 inches 1.65 inches 16.5 inches 16.5 inches
Soft Start No No No No Yes Yes Yes
Speed Sensor No No No No ? Yes Yes
Auto Shutoff No No No No Yes Yes yes
Bowl Steel Steel Steel Glass Steel Steel Steel
Opposite
Spinning
? ? Yes Yes Yes Yes Yes

Feature Explanations

Wattage:
Many people will dispute the importance of the wattage, but it should be considered. Typically, the more wattage, the greater the ability of the mixer to power through more tough mixtures and doughs.

Head Tilt / Bowl Lift:
Head tilts make it easier to add ingredients to the bowl but the mixer must be turned off. It is also easier to clean the head since it flips out towards you. With the bowl lift system, you can lower the bowl while it is running, but may be more difficult to clean.

Bowl:
The 90th anniversary model is currently the only way to get a glass bowl. It is rumored however that KitchenAid will sell glass bowls for the tilt-head models in the near future.

Soft Start:
Using this feature, the mixer will start with a low speed and increase to the speed of your choice. This reduces the initial splatter effect caused by starting at high speeds.

Speed Sensor:
Mixers with this feature will adjust based on how easy/difficult it is to spin through your substance.

Auto Shutoff:
As a safety precaution, the mixer will turn off if it is really struggling in order to prevent the motor from dying out.

Opposite Spinning:
I wasn’t sure what this feature is called, but it is where the beater spins in one direction while the shaft spins the opposite direction. This moves the beater to 67 different points around the bowl.

Analysis

All KitchenAid Stand Mixers are made with absolute quality in mind. It used to be that some models were made with a plastic shell but that is no longer the case. If purchased from a normal retailer (or from KitchenAid), all models come with a one year warranty. If you are really strapped for cash then the Classic model is the cheapest, but it if you are going to spend over two hundred dollars on a premium product you might as well spend a little more and get the upgrade (Artisan).

The Artisan seems to be the happy medium and also has the tilt head which is a feature I am very interested in. It is missing the smart features such as soft start and auto shutoff which I see could be very useful. The Pro 600 model is obviously the most advance, with almost 600 watts, a larger bowl size, and all the remaining features. The Pro 5 Plus however has all of the same features as the Pro 600, but less wattage.

As this point the most important things to consider in a product like this are what you need it to do and which product fits those needs best. I am currently leaning towards the Artisan because it is slightly smaller and has the tilt head, but the smart features of the Pro 5 Plus are very appetizing. Pricing will be very important in the decision of which model to buy and is also a very huge subject! For this reason, it will be covered in a future article.

Article Parts

Food, Personal Comments (0)

Using Regular Expressions, Captured Groups in Notepad++ Find and Replace

The past few days I have been doing research on …something that interests me very much, which I will save for another post. I have been entering this data into Excel, and today came upon a situation where doing some regex find / replace would be very helpful. I have used regular expressions in Notepad++ before, but I hadn’t done it with captured groups.
What I had was HTML code for a select box full of several colors. I wanted a quick way to extract the colors and get rid of the rest.

Notepad++ Find Replace with RegEx

The HTML

1
2
3
4
5
6
7
<select>
<option value="0" title="White" style="color: rgb(0, 102, 153);">White</option>
<option value="1" title="Cobalt Blue" style="color: rgb(0, 102, 153);">Cobalt Blue</option>
<option value="2" title="Almond" style="color: rgb(0, 102, 153);">Almond</option>
<option value="3" title="Empire Red" style="color: rgb(0, 102, 153);">Empire Red</option>
[....]
</select>

The Regular Expression

Regular expressions are easy, but I wanted to have a heading for the next section so I felt like this needed one as well. Rather than extracting the text from the actual label of the select option, I am grabbing the contents of the title attribute. Captured groups are created by surrounding with parenthesis.

1
.*title="([\w\s]+).*

Captured Groups

In Dreamweaver I remember referencing captured groups in find and replace with a dollar sign and then the number. This did not work in notepad++. Instead, I figured out you use a forward slash (/). So, for the first captured group, you do \1. For the second, \2, etc.

1
\1

Make sure that you check the “Use Regular Expressions” checkbox, otherwise NotePad++ will think you are crazy.

Programming Comments (0)

Find more articles in the Archives...

-->