Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#85 2012-06-30 15:19:34

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: New sections tab, multi-edit control block

Bloke wrote:

True. Or what about a Constraint? Or is this not an appropriate place for it?

Could be cool to have, but I’m not sure if it’s really needed. As pages and styles go, you can’t actually change public-facing template or style loading, making extending of those two rather pointless. Maybe Articles panel can benefit from constraints, but I don’t think much else can.

And how did the case statements ever work with semicolons instead of colons?!

That’s PHP and its inconsistent alternative syntax structures for you.

Last edited by Gocom (2012-06-30 15:27:41)

Offline

#86 2012-07-01 02:20:17

phiw13
Plugin Author
From: Japan
Registered: 2004-02-27
Posts: 3,189
Website

Re: New sections tab, multi-edit control block

Gocom wrote:

Ah, it’s the input name, page. The multi-edit select for Uses Page option is named page, but it is reserved/used by pagination too, and the edited section gets a page number instead of page template. The multi-edit option’s name needs to be changed. Might not be a bad idea also to verify the values.

Right, thanks for debugging! Following r3877, this now works correctly.

And fwiw, I haven’t found any more issues :-).


Where is that emoji for a solar powered submarine when you need it ?
Sand space – admin theme for Textpattern

Offline

#87 2012-07-01 11:16:18

philwareham
Core designer
From: Haslemere, Surrey, UK
Registered: 2009-06-11
Posts: 3,564
Website GitHub Mastodon

Re: New sections tab, multi-edit control block

Hi.

Back home now and sifting through all the work that’s been done.

The categories page potentially has multiple instances of id="multi-option-changeparent" which needs to be addressed.

Offline

#88 2012-07-01 19:52:54

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,446
Website GitHub

Re: New sections tab, multi-edit control block

philwareham wrote:

The categories page potentially has multiple instances of id="multi-option-changeparent"

Best I can do is add a static numeric counter to the end of the ID in the multi_edit function. It’ll seem a bit weird to have multi-edit-changeblah-1 on pages that only have one control, but does that cause any problems? Or is there a better solution I’m not seeing?

EDIT: or add an optional select_id attribute to the args in multi_edit() which is mixed into the default ID somewhere. e.g. multi-option-changeparent-article (if function supplied with article as the select_id parameter).

EDIT2: OK, that last one works better. I’ll stick with that for now.

Last edited by Bloke (2012-07-01 20:26:24)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#89 2012-07-01 20:55:18

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: New sections tab, multi-edit control block

Bloke wrote:

EDIT2: OK, that last one works better. I’ll stick with that for now.

I would have gone with the first one personally. Please note that the IDs are temporary and nothing outside the multi-edit controller can use those (not w/ event based hacks). If you check the page with a DOM inspector you will see that the .multi-option blocks and IDs aren’t actually even present in the document. They are not stored as hidden blocks in the page, but in memory by JavaScript.

The best option might actually be use randomized IDs altogether. The $methods are in order, and indexes could be used the IDs. Appending an static instance number to IDs would avoid collisions.

Last edited by Gocom (2012-07-01 20:58:36)

Offline

#90 2012-07-01 21:03:38

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,446
Website GitHub

Re: New sections tab, multi-edit control block

Gocom wrote:

IDs are temporary and nothing outside the multi-edit controller can use those

Ah, good point. In which case, how about…

Index: textpattern/lib/txplib_html.php
===================================================================
--- textpattern/lib/txplib_html.php	(revision 3885)
+++ textpattern/lib/txplib_html.php	(working copy)
@@ -876,12 +876,13 @@
  * @param  string  $dir Sorting direction
  * @param  string  $crit Search criterion
  * @param  string  $search_method Search method
- * @param  string  $id_suffix Added to the HTML id attribute; useful if more than one similar control placed per page
  * @return string  HTML
  */

-	function multi_edit($options, $event=null, $step=null, $page='', $sort='', $dir='', $crit='', $search_method='', $id_suffix='')
+	function multi_edit($options, $event=null, $step=null, $page='', $sort='', $dir='', $crit='', $search_method='')
 	{
+		static $me_counter = 1;
+
 		$html = $methods = array();
 		$methods[''] = gTxt('with_selected_option');

@@ -906,7 +907,7 @@
 				if (isset($option['html']))
 				{
 					$html[$value] = '<div class="multi-option" id="multi-option-'.
-						txpspecialchars($value).($id_suffix ? '-'.txpspecialchars($id_suffix) : '').'">'.$option['html'].'</div>';
+						txpspecialchars($value).$me_counter++.'">'.$option['html'].'</div>';
 				}
 			}
 			else
Index: textpattern/include/txp_category.php
===================================================================
--- textpattern/include/txp_category.php	(revision 3885)
+++ textpattern/include/txp_category.php	(working copy)
@@ -184,7 +184,7 @@
 				form(
 					join('',$array).
 					hInput('type',$area).
-					n.multi_edit($methods, 'category', 'cat_category_multiedit', '', '', '', '', '', $area)
+					n.multi_edit($methods, 'category', 'cat_category_multiedit')
 					,'', '', 'post', 'category-tree', '', 'category_'.$area.'_form'
 				);
 		}

The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#91 2012-07-01 21:16:36

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: New sections tab, multi-edit control block

Btw, the categories panel is broken.

The IDs are used to link the .multi-option blocks to the edit_method options. The IDs are named after the values. Since they don’t match, the categories panel doesn’t work.

These changes would require that the scripts functionality is changed too in some form. Which is why I was suggesting the random ID thing. Since you have an random ID consistently present, the ID can be broken apart correctly.

Offline

#92 2012-07-01 21:18:17

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,446
Website GitHub

Re: New sections tab, multi-edit control block

Gocom wrote:

Btw, the categories panel is broken.

Yikes. OK than. Code suggestions?


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#93 2012-07-01 21:29:51

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: New sections tab, multi-edit control block

I will send a patch soon. It will contain some other optimizations too to the multi-edit jQuery plugin. Wait for half an hour or so.

Offline

#94 2012-07-01 21:30:46

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,446
Website GitHub

Re: New sections tab, multi-edit control block

Gocom wrote:

I will send a patch soon. It will contain some other optimizations too to the multi-edit jQuery plugin. Wait for half an hour or so.

Legend, thanks.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#95 2012-07-01 22:48:20

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: New sections tab, multi-edit control block

Stef, please take a look:

Index: textpattern.js
===================================================================
--- textpattern.js	(revision 3886)
+++ textpattern.js	(working copy)
@@ -143,13 +143,13 @@
 /**
  * Multi-edit functions
  * @param string|obj method
- * @param obj options
+ * @param obj opt
  * @since 4.5.0
  */

-jQuery.fn.txpMultiEditForm = function(method, options)
+jQuery.fn.txpMultiEditForm = function(method, opt)
 {
-	var args = {}, opt;
+	var args = {};

 	var defaults = {
 		'checkbox' : 'input[name="selected[]"][type=checkbox]',
@@ -166,26 +166,23 @@

 	if ($.type(method) !== 'string')
 	{
-		options = method;
+		opt = method;
 		method = null;
 	}
 	else
 	{
-		args = options;
+		args = opt;
 	}

-	opt = options;
-
 	this.closest('form').each(function() {

 		var $this = $(this), form = {}, public = {}, private = {};
-		
+
 		if ($this.data('_txpMultiEdit'))
 		{
 			form = $this.data('_txpMultiEdit');
 			opt = $.extend(form.opt, opt);
 		}
-		
 		else
 		{
 			opt = $.extend(defaults, opt);
@@ -212,6 +209,11 @@
 				'value' : null,
 				'html' : null
 			}, options);
+			
+			if (!settings.value)
+			{
+				return public;
+			}

 			var option = form.editMethod.find('option').filter(function() {
 				return $(this).attr('value') === settings.value;
@@ -247,7 +249,7 @@

 			return public;
 		};
-		
+
 		/**
 		 * Selects rows based on supplied arguments. Only one of the filters applies at time.
 		 * @param array index Select based on row's index.
@@ -255,7 +257,7 @@
 		 * @param array value [value1, value2, value3, ...]
 		 * @param bool checked Set matched checked or unchecked. FALSE to uncheck.
 		 */
-		
+
 		public.select = function(options)
 		{
 			var settings = $.extend({
@@ -264,58 +266,58 @@
 				'value' : null,
 				'checked' : true
 			}, options);
-			
+
 			var obj = $this.find(form.pattern);
-			
+
 			if (settings.value !== null)
 			{
 				obj = obj.filter(function() {
 					return $.inArray($(this).attr('value'), settings.value) !== -1;
 				});
 			}
-			
+
 			else if (settings.index !== null)
 			{
 				obj = obj.filter(function(index) {
 					return $.inArray(index, settings.index) !== -1;
 				});
 			}
-			
+
 			else if (settings.range !== null)
 			{
 				obj = obj.slice(settings.range[0], settings.range[1]);
 			}
-		
+
 			obj.prop('checked', settings.checked).change();
 			return public;
 		};
-		
+
 		/**
 		 * Binds checkboxes
 		 */
-		
+
 		private.bindRows = function()
 		{
 			form.rows = $this.find(opt.row);
 			form.boxes = $this.find(form.pattern);
 			return private;
 		};
-		
+
 		/**
 		 * Highlights selected rows
 		 */
-		
+
 		private.highlight = function()
 		{
 			form.boxes.filter(':checked').closest(opt.highlighted).addClass(opt.selectedClass);
 			form.boxes.filter(':not(:checked)').closest(opt.highlighted).removeClass(opt.selectedClass);
 			return private;
 		};
-		
+
 		/**
 		 * Extends click region to whole row
 		 */
-		
+
 		private.extendedClick = function()
 		{
 			if (opt.rowClick)
@@ -328,9 +330,9 @@
 			}

 			obj.live('click', function(e) {
-			
+
 				var self = ($(e.target).is(form.pattern) || $(this).is(form.pattern));
-	
+
 				if (!self && (e.target != this || $(this).is('a, :input') || $(e.target).is('a, :input')))
 				{
 					return;
@@ -347,72 +349,53 @@
 				{
 					return;
 				}
-				
+
 				private.bindRows();
-				
+
 				var checked = box.prop('checked');
-					
+
 				if (self)
 				{
 					checked = !checked;
 				}
-					
-				if (form.lastCheck)
+
+				if (e.shiftKey && form.lastCheck)
 				{
+					var start = form.boxes.index(box);
 					var end = form.boxes.index(form.lastCheck);
+
+					public.select({
+						'range' : [Math.min(start, end), Math.max(start, end)+1],
+						'checked' : !checked
+					});
 				}
-					
+				else if (!self)
+				{
+					box.prop('checked', !checked).change();
+				}
+
 				if (checked === false)
 				{
-					if (e.shiftKey && form.lastCheck)
-					{
-						var start = form.boxes.index(box);
-						
-						public.select({
-							'range' : [Math.min(start, end), Math.max(start, end)+1]
-						});
-					}
-					
-					else if (!self)
-					{
-						box.prop('checked', true).change();
-					}
-					
 					form.lastCheck = box;
 				}
-				
 				else
 				{
-					if (e.shiftKey && form.lastCheck)
-					{
-						var start = form.boxes.index(box);
-						
-						public.select({
-							'range' : [Math.min(start, end), Math.max(start, end)+1],
-							'checked' : false
-						});
-					}
-					else if (!self)
-					{
-						box.prop('checked', false).change();
-					}
-				
 					form.lastCheck = null;
 				}
 			});
-			
+
 			return private;
 		};
-		
+
 		/**
 		 * Tracks row checks
 		 */
-		
+
 		private.checked = function()
 		{
 			form.boxes.live('change', function(e) {
 				var box = $(this);
-				
+
 				if (box.prop('checked'))
 				{
 					$(this).closest(opt.highlighted).addClass(opt.selectedClass);
@@ -424,14 +407,14 @@
 					form.selectAll.prop('checked', false);
 				}
 			});
-			
+
 			return private;
 		};
-		
+
 		/**
 		 * Handles edit method selecting
 		 */
-		
+
 		private.changeMethod = function()
 		{
 			form.button.hide();
@@ -482,14 +465,29 @@
 		{
 			private.bindRows().highlight().extendedClick().checked().changeMethod().sendForm();

-			$this.find('.multi-option:not(.multi-step)').each(function() {
-				public.addOption({
-					'label' : null,
-					'html' : $(this).contents(),
-					'value' : $(this).attr('id').substring(13)
+			(function() {
+				var multiOptions = $this.find('.multi-option:not(.multi-step)');
+
+				form.editMethod.find('option[value!=""]').each(function() {
+					var value = $(this).val();
+
+					var option = multiOptions.filter(function() {
+						return $(this).hasClass('multi-option-'+value);
+					});
+
+					if (option.length > 0)
+					{
+						public.addOption({
+							'label' : null,
+							'html' : option.eq(0).contents(),
+							'value' : $(this).val()
+						});
+					}
 				});
-			}).remove();

+				multiOptions.remove();
+			})();
+
 			form.selectAll.live('change', function(e) {
 				public.select({
 					'checked' : $(this).prop('checked')
Index: lib/txplib_html.php
===================================================================
--- lib/txplib_html.php	(revision 3886)
+++ lib/txplib_html.php	(working copy)
@@ -876,11 +876,10 @@
  * @param  string  $dir Sorting direction
  * @param  string  $crit Search criterion
  * @param  string  $search_method Search method
- * @param  string  $id_suffix Added to the HTML id attribute; useful if more than one similar control placed per page
  * @return string  HTML
  */

-	function multi_edit($options, $event=null, $step=null, $page='', $sort='', $dir='', $crit='', $search_method='', $id_suffix='')
+	function multi_edit($options, $event=null, $step=null, $page='', $sort='', $dir='', $crit='', $search_method='')
 	{
 		$html = $methods = array();
 		$methods[''] = gTxt('with_selected_option');
@@ -905,8 +904,7 @@

 				if (isset($option['html']))
 				{
-					$html[$value] = '<div class="multi-option" id="multi-option-'.
-						txpspecialchars($value).($id_suffix ? '-'.txpspecialchars($id_suffix) : '').'">'.$option['html'].'</div>';
+					$html[$value] = '<div class="multi-option multi-option-'.txpspecialchars($value).'">'.$option['html'].'</div>';
 				}
 			}
 			else

It basically changes the thing to work with classes instead of IDs. This solves all the collisions issues. Instead of the JavaScript picking .multi-options it uses the actual <option> elements to trace the steps from markup. When 4.6 and HTML5 lands, those classes could be changed to data- attributes even simplifying the logic even more.

Other changes are some basic cleanup and small fixes. Main thing is that it now prevents hooking with addOption() method to the default empty option (by accident) as that would just cause a loop of confirmation dialogs if anything. It also merges two almost identical condition blocks used for shift+click. Just reverses the booleans in props and likes, leading to much shorter code in that scenario.

Last edited by Gocom (2012-07-01 22:49:23)

Offline

#96 2012-07-01 22:55:47

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: New sections tab, multi-edit control block

If you are wondering why the diff is as big as it is, is because I removed my auto-indents. In Textpattern’s source empty lines aren’t leveled, so I decided to remove those extra indentations to match the general styling.

Last edited by Gocom (2012-07-01 22:57:23)

Offline

Board footer

Powered by FluxBB