Re-order custom fields
jdarwood007

jdarwood007 commited on 2018-08-06 20:09:15
Showing 10 changed files, with 221 additions and 20 deletions.


Implants #84 to reorder custom fields.
... ...
@@ -139,6 +139,10 @@ dl.permsettings img, dl.cannedsettings dd img.icon {
139 139
 	margin: 0 10px 0 0;
140 140
 }
141 141
 
142
+dl span.custom_field_order img {
143
+	margin-right: 0;	
144
+}
145
+
142 146
 h3 a.permcollapse img {
143 147
 	margin-top:8px;
144 148
 }
... ...
@@ -97,15 +97,15 @@
97 97
 		<hook hook="integrate_SSI" function="$sourcedir/SimpleDesk-SSI.php" />
98 98
 
99 99
 		<!-- database changes -->
100
-		<database>install.php</database>
100
+		<database>install-sd.php</database>
101 101
 
102 102
 		<redirect url="?action=admin;area=helpdesk_info" />
103 103
 	</install>
104 104
 
105 105
 	<uninstall for="2.1 Beta 3, 2.1 Beta 4">
106 106
 		<!-- database changes, undone -->
107
-		<database>uninstall-optional.php</database>
108
-		<code type="file">uninstall-required.php</code>
107
+		<database>uninstall-sd-optional.php</database>
108
+		<code type="file">uninstall-sd-required.php</code>
109 109
 
110 110
 		<!-- All the hooks -->
111 111
 			<!-- SMF Core -->
... ...
@@ -124,3 +124,132 @@ function toggleItem(itemID, theme_url, txt_on, txt_off)
124 124
 	// Don't reload.
125 125
 	return false;
126 126
 }
127
+
128
+/* Sort Custom Fields */
129
+function shd_custom_field_order(oOptions)
130
+{
131
+	this.opt = oOptions;
132
+
133
+	if (!this.opt.sFieldsContainer)
134
+		this.opt.sFieldsContainer = 'custom_fields_list';
135
+	if (!this.opt.sOptionsOrderClass)
136
+		this.opt.sOptionsOrderClass = 'custom_field_order';
137
+	if (!this.opt.sOptionsMoveDownClass)
138
+		this.opt.sOptionsMoveDownClass = 'custom_field_move_down';
139
+	if (!this.opt.sOptionsMoveUpClass)
140
+		this.opt.sOptionsMoveUpClass = 'custom_field_move_up';
141
+	if (!this.opt.aCustHTMLFields)
142
+		this.opt.aCustHTMLFields = ['break_{KEY}', 'radio_{KEY}', 'multi_{KEY}', 'option_{KEY}', 'order_{KEY}'];
143
+
144
+	this.currentOrder = new Array();
145
+	this.newOrder = new Array();
146
+
147
+	this.init();
148
+	return false;
149
+}
150
+
151
+shd_custom_field_order.prototype.init = function ()
152
+{
153
+	var self = this;
154
+
155
+	$(document).on('click', '#' + this.opt.sFieldsContainer + ' .' + this.opt.sOptionsMoveDownClass, function(e){
156
+		e.preventDefault();
157
+		var clickedKey = $(this).data('key');
158
+		var clickedOrder = $('#order_' + clickedKey + ' input').val();
159
+		self.move(clickedKey, clickedOrder, clickedOrder + 1);
160
+		return;
161
+	});
162
+	$(document).on('click', '#' + this.opt.sFieldsContainer + ' .' + this.opt.sOptionsMoveUpClass, function(e){
163
+		e.preventDefault();
164
+		var clickedKey = $(this).data('key');
165
+		var clickedOrder = $('#order_' + clickedKey + ' input').val();
166
+		self.move(clickedKey, clickedOrder, clickedOrder - 1);
167
+		return;
168
+	});
169
+}
170
+
171
+shd_custom_field_order.prototype.cloneArray = function (arraySource)
172
+{
173
+	return arraySource.slice(0);
174
+}
175
+
176
+shd_custom_field_order.prototype.move = function (clickedKey, clickedOrder, movedOrder)
177
+{
178
+	var currentOrder = new Array();
179
+	var newOrder = new Array();
180
+
181
+	// Get our current Order items.
182
+	var self = this;
183
+	$('#' + this.opt.sFieldsContainer + ' .' + this.opt.sOptionsOrderClass + ' input').each(function() {
184
+		currentOrder[$(this).val()] = $(this).data('key');
185
+
186
+		// Capture the current input. attr is used here as data doesn't get retained.
187
+		$('#option_' + $(this).data('key')).attr('data-value-input', $('#option_' + $(this).data('key')).val());
188
+	});
189
+
190
+	// Make sure it can go that way.
191
+	if (
192
+		(clickedOrder > movedOrder && movedOrder < 0) ||
193
+		(clickedOrder < movedOrder && clickedOrder >= currentOrder.length - 1)
194
+	)
195
+		return;
196
+
197
+	// Put this into the right place.
198
+	newOrder = this.cloneArray(currentOrder);
199
+	newOrder.splice(clickedOrder, 1);
200
+	newOrder.splice(movedOrder, 0, clickedKey);
201
+
202
+	// Build up the new HTML and move it.
203
+	var newDiv = '';
204
+	$(newOrder).each(function(order, key) {
205
+		$(self.opt.aCustHTMLFields).each(function(order2, field) {
206
+			newDiv += $('#' + field.replace('{KEY}', key)).prop('outerHTML');
207
+		});
208
+	});
209
+	newDiv += '<span id="addopt"></span>';
210
+	$('#' + this.opt.sFieldsContainer).html(newDiv);
211
+
212
+	this.resort(newOrder);
213
+}
214
+
215
+shd_custom_field_order.prototype.resortNew = function ()
216
+{
217
+	var currentOrder = new Array();
218
+
219
+	$('#' + this.opt.sFieldsContainer + ' .' + this.opt.sOptionsOrderClass + ' input').each(function() {
220
+		currentOrder[$(this).val()] = $(this).data('key');
221
+
222
+		// Capture the current input. attr is used here as data doesn't get retained.
223
+		$('#option_' + $(this).data('key')).attr('data-value-input', $('#option_' + $(this).data('key')).val());
224
+	});
225
+
226
+	this.resort(currentOrder);
227
+}
228
+
229
+shd_custom_field_order.prototype.resort = function (currentOrder)
230
+{
231
+	// Find out the new orders.
232
+	var firstField = typeof currentOrder[0] === 'undefined' ? 0 : currentOrder[0];
233
+	var lastField = currentOrder[currentOrder.length - 1];
234
+
235
+	// Go through each possible option and reorder it, you can't do this first since outerHTML doesn't contain the updated information.
236
+	$(currentOrder).each(function(order, key) {
237
+		orderHTML = $('#order_' + key + '_input').val(order);
238
+
239
+		// First item, we hide the move up.
240
+		if (firstField == key)
241
+			$('#order_' + key + ' a.custom_field_move_up').hide();
242
+		else
243
+			$('#order_' + key + ' a.custom_field_move_up').show();
244
+
245
+		// Last item we hide the move down.
246
+		if (lastField == key)
247
+			$('#order_' + key + ' a.custom_field_move_down').hide();
248
+		else
249
+			$('#order_' + key + ' a.custom_field_move_down').show();
250
+
251
+		// Capture the current input.
252
+		if ($('#option_' + key).data('value-input'))
253
+			$('#option_' + key).val($('#option_' + key).attr('data-value-input'));
254
+	});
255
+}
127 256
\ No newline at end of file
... ...
@@ -125,7 +125,7 @@ function shd_admin_custom_new()
125 125
 		'placement' => CFIELD_PLACE_DETAILS,
126 126
 	));
127 127
 
128
-	$context['custom_field']['options'] = array(1 => '', '', '', 'inactive' => array());
128
+	$context['custom_field']['options'] = array(1 => '', '', '', 'inactive' => array(), 'order' => array());
129 129
 	$context['custom_field']['default_value'] = false;
130 130
 
131 131
 	// Get the list of departments, and whether a field is required in each department.
... ...
@@ -139,6 +139,8 @@ function shd_admin_custom_new()
139 139
 	while ($row = $smcFunc['db_fetch_assoc']($query))
140 140
 		$context['dept_fields'][$row['id_dept']] = $row;
141 141
 	$smcFunc['db_free_result']($query);
142
+
143
+	loadLanguage('ManageSettings');
142 144
 }
143 145
 
144 146
 /**
... ...
@@ -154,7 +156,8 @@ function shd_admin_custom_edit()
154 156
 
155 157
 	$query = shd_db_query('', '
156 158
 		SELECT id_field, active, field_order, field_name, field_desc, field_loc, icon, field_type,
157
-		field_length, field_options, bbc, default_value, can_see, can_edit, display_empty, placement
159
+		field_length, field_options, bbc, default_value, can_see, can_edit,
160
+		display_empty, placement
158 161
 		FROM {db_prefix}helpdesk_custom_fields
159 162
 		WHERE id_field = {int:field}',
160 163
 		array(
... ...
@@ -174,6 +178,23 @@ function shd_admin_custom_edit()
174 178
 		if (empty($context['custom_field']['options']['inactive']))
175 179
 			$context['custom_field']['options']['inactive'] = array();
176 180
 
181
+		if (!isset($context['custom_field']['options']['order']))
182
+			$context['custom_field']['options']['order'] = array();
183
+
184
+		// If this option isn't in the order, make it so!
185
+		foreach ($context['custom_field']['options'] as $key => $val)
186
+			if (!in_array($key, array('inactive', 'order')) && !in_array($key, $context['custom_field']['options']['order']))
187
+				$context['custom_field']['options']['order'][] = $key;
188
+
189
+		// Make sure it exists in the order.
190
+		foreach ($context['custom_field']['options']['order'] as $key => $val)
191
+			if (!isset($context['custom_field']['options'][$val]))
192
+				unset($context['custom_field']['options']['order'][$val]);
193
+
194
+		// first and last order.
195
+		$context['custom_field']['order_first'] = current($context['custom_field']['options']['order']);
196
+		$context['custom_field']['order_last'] = end($context['custom_field']['options']['order']);
197
+
177 198
 		// If this is a textarea, we need to get its dimensions too.
178 199
 		if ($context['custom_field']['field_type'] == CFIELD_TYPE_LARGETEXT)
179 200
 			$context['custom_field']['dimensions'] = explode(',', $context['custom_field']['default_value']);
... ...
@@ -216,6 +237,8 @@ function shd_admin_custom_edit()
216 237
 		$smcFunc['db_free_result']($query);
217 238
 		fatal_lang_error('shd_admin_cannot_edit_custom_field', false);
218 239
 	}
240
+
241
+	loadLanguage('ManageSettings');
219 242
 }
220 243
 
221 244
 /**
... ...
@@ -373,6 +396,7 @@ function shd_admin_custom_save()
373 396
 	$defaultOptions = array();
374 397
 	if (!empty($_POST['select_option']) && ($_POST['field_type'] == CFIELD_TYPE_SELECT || $_POST['field_type'] == CFIELD_TYPE_RADIO || $_POST['field_type'] == CFIELD_TYPE_MULTI))
375 398
 	{
399
+		$optionsOrder = array();
376 400
 		foreach ($_POST['select_option'] as $k => $v)
377 401
 		{
378 402
 			// Clean, clean, clean...
... ...
@@ -391,7 +415,12 @@ function shd_admin_custom_save()
391 415
 			// Is it default?
392 416
 			if (isset($_POST['default_select']) && $_POST['default_select'] == $k)
393 417
 				$_POST['default_check'] = $k;
418
+
419
+			// Our order.
420
+			$optionsOrder[$_POST['order'][$k]] = $k;
394 421
 		}
422
+
423
+		$newOptions['order'] = $optionsOrder;
395 424
 		$options = json_encode($newOptions);
396 425
 	}
397 426
 
... ...
@@ -511,7 +540,7 @@ function shd_admin_custom_save()
511 540
 			// First, figure out what fields we had before.
512 541
 			foreach ($row['field_options'] as $k => $v)
513 542
 			{
514
-				if ($k == 'inactive')
543
+				if ($k == 'inactive' || $k == 'order')
515 544
 					continue;
516 545
 				if (!isset($newOptions[$k]))
517 546
 					$inactive[] = $k;
... ...
@@ -521,6 +550,7 @@ function shd_admin_custom_save()
521 550
 			foreach ($newOptions as $k => $v)
522 551
 				$new_fields[$k] = $v;
523 552
 			$new_fields['inactive'] = $inactive;
553
+			$new_fields['order'] = $optionsOrder;
524 554
 			$options = json_encode($new_fields);
525 555
 		}
526 556
 
... ...
@@ -833,7 +833,7 @@ function shd_load_custom_fields($is_ticket = true, $ticketContext = 0, $dept = 0
833 833
 			{
834 834
 				foreach ($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options'] as $k => $v)
835 835
 				{
836
-					if ($k != 'inactive')
836
+					if ($k != 'inactive' && $k != 'order')
837 837
 						$context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options'][$k] = (strpos($v, '[') !== false) ? trim(strip_tags(parse_bbc($v))) : trim($v);
838 838
 				}
839 839
 			}
... ...
@@ -842,6 +842,21 @@ function shd_load_custom_fields($is_ticket = true, $ticketContext = 0, $dept = 0
842 842
 		if (!empty($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']) && empty($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['inactive']))
843 843
 			$context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['inactive'] = array();
844 844
 
845
+		if (!empty($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']) && !isset($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['order']))
846
+			$context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['order'] = array();
847
+
848
+		// If this option isn't in the order, make it so!
849
+		if (!empty($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']))
850
+			foreach ($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options'] as $key => $val)
851
+				if (!in_array($key, array('inactive', 'order')) && !in_array($key, $context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['order']))
852
+					$context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['order'][] = $key;
853
+
854
+		// Make sure it exists in the order.
855
+		if (!empty($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']))
856
+			foreach ($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['order'] as $key => $val)
857
+				if (!isset($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options'][$val]))
858
+					unset($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['options']['order'][$val]);
859
+
845 860
 		if (isset($field_values[$row['id_field']]))
846 861
 		{
847 862
 			if ($context['ticket_form']['custom_fields'][$loc][$row['id_field']]['type'] == CFIELD_TYPE_MULTI)
... ...
@@ -157,22 +157,29 @@ function template_shd_custom_field_edit()
157 157
 					document.getElementById("required_dept" + id).disabled = state;
158 158
 					document.getElementById("required_dept_multi_" + id).disabled = state;
159 159
 				}
160
-				var startOptID = ', count($context['custom_field']['options']), ';
160
+				var startOptID = ', !empty($context['custom_field']['options']['order']) ? count($context['custom_field']['options']['order']) + 1 : 1, ';
161 161
 				function add_option()
162 162
 				{
163 163
 					var ftype = document.getElementById("cf_fieldtype").value;
164
-					var newHTML = \'<br><input type="radio" id="radio_\' + startOptID + \'" name="default_select" value="\' + startOptID + \'" id="\' + startOptID + \'"\';
164
+					var newHTML = \'<br id="break_\' + startOptID + \'"><input type="radio" id="radio_\' + startOptID + \'" name="default_select" value="\' + startOptID + \'" id="\' + startOptID + \'"\';
165 165
 					if (ftype == ', CFIELD_TYPE_MULTI, ')
166 166
 						newHTML += \' style="display:none;"\';
167 167
 					newHTML += \' >\' + "\n";
168 168
 					newHTML += \'<input type="checkbox" id="multi_\' + startOptID + \'" name="default_select_multi[\' + startOptID + \']" value="\' + startOptID + \'"\';
169 169
 					if (ftype != ', CFIELD_TYPE_MULTI, ')
170 170
 						newHTML += \' style="display:none;"\';
171
-					newHTML += \' >\' + "\n";
172
-					newHTML += \'<input type="text" name="select_option[\' + startOptID + \']" value="" ><span id="addopt"></span>\';
171
+					newHTML += \' ><input type="text" id="option_\' + startOptID + \'" name="select_option[\' + startOptID + \']" value="" >\' + "\n";
172
+					newHTML += \'<span id="order_\' + startOptID + \'" class="custom_field_order"><input id="order_\' + startOptID + \'_input" type="hidden" name="order[\' + startOptID + \']" value="\' + (startOptID - 1) + \'" data-key="\' + startOptID + \'">\' + "\n";
173
+					newHTML += \'<a href="#" class="custom_field_move_up" data-key="\' + startOptID + \'"><img src="', $settings['default_images_url'], '/simpledesk/move_up.png" class="icon" alt="', $txt['custom_edit_order_up'], '" title="', $txt['custom_edit_order_up'], '"/></a>\';
174
+					newHTML += \'<a href="#" class="custom_field_move_down" data-key="\' + startOptID + \'"><img src="', $settings['default_images_url'], '/simpledesk/move_down.png" class="icon" alt="', $txt['custom_edit_order_down'], '" title="', $txt['custom_edit_order_down'], '"/></a>\';
175
+					newHTML += \'</span>\' + "\n";
176
+
177
+					newHTML += \'<span id="addopt"></span>\';
173 178
 
174 179
 					setOuterHTML(document.getElementById("addopt"), newHTML);
175 180
 					startOptID++;
181
+
182
+					optionsOrder.resortNew();
176 183
 				}
177 184
 				function update_default_label(defstate)
178 185
 				{
... ...
@@ -324,27 +331,38 @@ function template_shd_custom_field_edit()
324 331
 								</div>
325 332
 							</dt>
326 333
 							<dd id="options_dd"', in_array($context['field_type_value'], array(CFIELD_TYPE_SELECT, CFIELD_TYPE_RADIO, CFIELD_TYPE_MULTI)) ? '' : ' style="display: none;"','>								
327
-								<input type="radio" id="radio_0" name="default_select" value="0"', $context['custom_field']['default_value'] == 0 ? ' checked="checked"' : '', $context['field_type_value'] != CFIELD_TYPE_MULTI ? '' : ' style="display:none;"', ' > <span id="radio_text_0"', $context['field_type_value'] != CFIELD_TYPE_MULTI ? '' : ' style="display:none;"', '>', $txt['shd_admin_custom_field_no_selected_default'], '</span>';
334
+								<input type="radio" id="radio_0" name="default_select" value="0"', $context['custom_field']['default_value'] == 0 ? ' checked="checked"' : '', $context['field_type_value'] != CFIELD_TYPE_MULTI ? '' : ' style="display:none;"', ' >
335
+								<span id="radio_text_0"', $context['field_type_value'] != CFIELD_TYPE_MULTI ? '' : ' style="display:none;"', '>', $txt['shd_admin_custom_field_no_selected_default'], '</span>
336
+								<div id="custom_fields_list">';
328 337
 
329 338
 	// Convert it to an array for displaying the main doodah
330 339
 	if ($context['field_type_value'] == CFIELD_TYPE_MULTI)
331 340
 		$context['custom_field']['default_value'] = explode(',', $context['custom_field']['default_value']);
332 341
 
333
-	foreach ($context['custom_field']['options'] as $k => $option)
342
+	foreach ($context['custom_field']['options']['order'] as $order => $k)
334 343
 	{
335
-		if ($k == 'inactive' || in_array($k, $context['custom_field']['options']['inactive']))
344
+		if ($k == 'order' || $k == 'inactive' || in_array($k, $context['custom_field']['options']['inactive']))
336 345
 			continue;
346
+		$option = $context['custom_field']['options'][$k];
337 347
 
338 348
 		echo '
339
-								<br>
349
+									<br id="break_', $k, '">
340 350
 									<input type="radio" id="radio_', $k, '" name="default_select" value="', $k, '"', $context['field_type_value'] != CFIELD_TYPE_MULTI && $context['custom_field']['default_value'] == $k ? ' checked="checked"' : '', $context['field_type_value'] != CFIELD_TYPE_MULTI ? '' : ' style="display:none;"', ' >
341 351
 									<input type="checkbox" id="multi_', $k, '" name="default_select_multi[', $k, ']" value="', $k, '"', $context['field_type_value'] == CFIELD_TYPE_MULTI && in_array($k, $context['custom_field']['default_value']) ? ' checked="checked"' : '', $context['field_type_value'] == CFIELD_TYPE_MULTI ? '' : ' style="display:none;"', ' >
342
-								<input type="text" name="select_option[', $k, ']" value="', $option, '" >';
352
+									<input type="text" id="option_', $k, '" name="select_option[', $k, ']" value="', $option, '">
353
+									<span id="order_', $k, '" class="custom_field_order"><input id="order_', $k, '_input" type="hidden" name="order[', $k, ']" value="', $order, '" data-key="', $k, '">';
354
+
355
+			echo '<a href="#" class="custom_field_move_up" data-key="', $k, '"', $context['custom_field']['order_first'] == $k ? ' style="display:none;"' : '', '><img src="', $settings['default_images_url'], '/simpledesk/move_up.png" class="icon" alt="', $txt['custom_edit_order_up'], '" title="', $txt['custom_edit_order_up'], '"/></a>';
356
+			echo '<a href="#" class="custom_field_move_down" data-key="', $k, '"', $context['custom_field']['order_last'] == $k ? ' style="display:none;"' : '', '><img src="', $settings['default_images_url'], '/simpledesk/move_down.png" class="icon" alt="', $txt['custom_edit_order_down'], '" title="', $txt['custom_edit_order_down'], '"/></a>';
357
+
358
+		echo '</span>';
359
+
343 360
 	}
344 361
 
345 362
 	echo '
346 363
 								<span id="addopt"></span>
347
-								[<a href="" onclick="add_option(); return false;">', $txt['more'], '</a>]
364
+								</div>
365
+								<span id="addopt_link">[<a href="" onclick="add_option(); return false;">', $txt['more'], '</a>]</span>
348 366
 							</dd>
349 367
 							<dt id="default_dt"', $context['field_type_value'] == CFIELD_TYPE_CHECKBOX ? '' : ' style="display: none;"','>
350 368
 								<strong>', $txt['shd_admin_custom_field_default_state'], ':</strong>
... ...
@@ -394,5 +412,9 @@ function template_shd_custom_field_edit()
394 412
 					<input type="submit" value="', $txt['shd_admin_cancel_custom_field'], '" name="cancel" class="button">
395 413
 					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
396 414
 					<input type="hidden" name="field" value="', empty($context['custom_field']['id_field']) ? 0 : $context['custom_field']['id_field'], '">
397
-				</form>';
415
+				</form>
416
+
417
+	<script type="text/javascript">
418
+		var optionsOrder = new shd_custom_field_order({});
419
+	</script>';
398 420
 }
399 421
\ No newline at end of file
... ...
@@ -229,11 +229,13 @@ function template_ticket_custom_fields()
229 229
 								<select name="field-', $field['id'], '">
230 230
 									<option value="0"', $field['value'] == 0 ? ' selected="selected"' : '', !empty($field['is_required']) ? ' disabled="disabled"' : '', '>', $txt['shd_choose_one'], '&nbsp;</option>';
231 231
 
232
-					foreach ($field['options'] as $key => $option)
232
+					foreach ($field['options']['order'] as $order => $key)
233 233
 					{
234
-						if ($key == 'inactive' || in_array($key, $field['options']['inactive']))
234
+						if ($key == 'order' || $key == 'inactive' || in_array($key, $field['options']['inactive']))
235 235
 							continue;
236 236
 
237
+						$option = $field['options'][$key];
238
+
237 239
 						echo '
238 240
 									<option value="', $key, '"', $field['value'] == $key ? ' selected="selected"' : '', '>', $option, '&nbsp;</option>';
239 241
 					}