jQuery ile Düzenlenebilir Table (editableTableWidget)

editable-table
Web tasarımının listeleme yükünü sırtlayan tablo yapıları günümüzde popülerliğini korumakta. Ancak kimi zaman veri çokluğundan, kimi zaman da form yoğunluklarından bu tablolardaki güncelleme işlemleri popup, modal veya yeni sekmede yapılmakta. Bu da kullanıcının ufacık bir satırı değiştirmesi için fazladan bir ekran daha gezmesi anlamına geliyor.

Bu makalemizde jQuery ile düzenlenilebilir / değiştirilebilir table yapısı oluşturacağız. Karşınızda editableTableWidget!

ÖRNEĞİ GÖRÜNTÜLE

editableTableWidget

Adından da anlaşılacağı gibi küçük dosya boyutu ve kod satırına sahip bu yapı klasik table elemanını form inputları ekleyerek düzenlenebilir hale getiriyor. Yapımcıların vurguladığı özellikler şöyle :

  • Zor olanı yapmıyoruz. Sadece HTML’in table yapısını kullanıyoruz. Yani editableTableWidget’ı kullanmak için kodlarınızda köklü bir değişiklik yapmanız gerekmiyor.
  • Change ve validate eventlerini destekliyor. Böylece form kontrollerinizi yapmaya devam ediyorsunuz.
  • Seçimler için klasik DOM focus taslağını kullanıyor.
  • Kopyala/Yapıştır desteği sunuyor.
  • Daha önceki CSS dosyanıza uygun çalışıyor, kendi tasarımını kullanmak için sizikileri bozmuyor.
  • Bootstrap ile beraber çalışabiliyor.
  • Çalışması için sadece jQuery’e ihtiyaç var.
  • Chrome 32, Firefox 26, IE 10, Safari 7, Android Chrome and iOS 7 Safari’de test edildi.

Nasıl kullanılır?

Önceden eklemediyseniz güncel jQuery versiyonunu web sitenize dahil ediniz. Kullanılabilir versiyonlara buradan göz atabilirsiniz. Örnek kod aşağıdaki gibidir.

<script src="http://code.jquery.com/jquery-xxxxxxx.min.js"></script>

Şimdi editableTableWidget’ın kodlarını ekleyebiliriz. Aşağıdaki dosyaları içeren bir JavaScript dosyası oluşturup projenize dahil edin. Tabii bu kodları jQuery’nin altına eklemiş olmanız gerekiyor.

$.fn.editableTableWidget = function (options) {
	'use strict';
	return $(this).each(function () {
		var buildDefaultOptions = function () {
				var opts = $.extend({}, $.fn.editableTableWidget.defaultOptions);
				opts.editor = opts.editor.clone();
				return opts;
			},
			activeOptions = $.extend(buildDefaultOptions(), options),
			ARROW_LEFT = 37, ARROW_UP = 38, ARROW_RIGHT = 39, ARROW_DOWN = 40, ENTER = 13, ESC = 27, TAB = 9,
			element = $(this),
			editor = activeOptions.editor.css('position', 'absolute').hide().appendTo(element.parent()),
			active,
			showEditor = function (select) {
				active = element.find('td:focus');
				if (active.length) {
					editor.val(active.text())
						.removeClass('error')
						.show()
						.offset(active.offset())
						.css(active.css(activeOptions.cloneProperties))
						.width(active.width())
						.height(active.height())
						.focus();
					if (select) {
						editor.select();
					}
				}
			},
			setActiveText = function () {
				var text = editor.val(),
					evt = $.Event('change'),
					originalContent;
				if (active.text() === text || editor.hasClass('error')) {
					return true;
				}
				originalContent = active.html();
				active.text(text).trigger(evt, text);
				if (evt.result === false) {
					active.html(originalContent);
				}
			},
			movement = function (element, keycode) {
				if (keycode === ARROW_RIGHT) {
					return element.next('td');
				} else if (keycode === ARROW_LEFT) {
					return element.prev('td');
				} else if (keycode === ARROW_UP) {
					return element.parent().prev().children().eq(element.index());
				} else if (keycode === ARROW_DOWN) {
					return element.parent().next().children().eq(element.index());
				}
				return [];
			};
		editor.blur(function () {
			setActiveText();
			editor.hide();
		}).keydown(function (e) {
			if (e.which === ENTER) {
				setActiveText();
				editor.hide();
				active.focus();
				e.preventDefault();
				e.stopPropagation();
			} else if (e.which === ESC) {
				editor.val(active.text());
				e.preventDefault();
				e.stopPropagation();
				editor.hide();
				active.focus();
			} else if (e.which === TAB) {
				active.focus();
			} else if (this.selectionEnd - this.selectionStart === this.value.length) {
				var possibleMove = movement(active, e.which);
				if (possibleMove.length > 0) {
					possibleMove.focus();
					e.preventDefault();
					e.stopPropagation();
				}
			}
		})
		.on('input paste', function () {
			var evt = $.Event('validate');
			active.trigger(evt, editor.val());
			if (evt.result === false) {
				editor.addClass('error');
			} else {
				editor.removeClass('error');
			}
		});
		element.on('click keypress dblclick', showEditor)
		.css('cursor', 'pointer')
		.keydown(function (e) {
			var prevent = true,
				possibleMove = movement($(e.target), e.which);
			if (possibleMove.length > 0) {
				possibleMove.focus();
			} else if (e.which === ENTER) {
				showEditor(false);
			} else if (e.which === 17 || e.which === 91 || e.which === 93) {
				showEditor(true);
				prevent = false;
			} else {
				prevent = false;
			}
			if (prevent) {
				e.stopPropagation();
				e.preventDefault();
			}
		});

		element.find('td').prop('tabindex', 1);

		$(window).on('resize', function () {
			if (editor.is(':visible')) {
				editor.offset(active.offset())
				.width(active.width())
				.height(active.height());
			}
		});
	});

};
$.fn.editableTableWidget.defaultOptions = {
	cloneProperties: ['padding', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right',
					  'text-align', 'font', 'font-size', 'font-family', 'font-weight',
					  'border', 'border-top', 'border-bottom', 'border-left', 'border-right'],
	editor: $('<input>')
};     

Son olarak hangi table elemanlarının bu özelliğe sahip olmasını belirliyoruz.

$('.editable').editableTableWidget();

Böylece editable classına sahip tüm table elemanları düzenlenilir hale geldiler. Bu alana sadece table diyerek tüm tabloların düzenlenebilir olmasını sağlayabilirsiniz.

Bu da ilginizi çekebilir  Fareyle Birlikte Hareket Eden Arkaplan Resmi

Kapanış

Kullanıcının işlemini hızlandırmak ve kolaylaştırmak için bu tip anlık güncelleme işlemleri büyük önem taşıyor. Kullanıcı griddeki düzenlemeyi yaptıktan sonra focusOut yapması beklenip veritabanına göndereceğiniz UPDATE sorgusu ile işlemleri kısaltabilirsiniz.

İyi çalışmalar.