Create a simple property grid to display and edit an object properties. Currently supports text/number/color/checkbox
Created
September 28, 2014 22:07
-
-
Save ValYouW/911d50324585876fafbd to your computer and use it in GitHub Desktop.
A Pen by ValYouW.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="pgWrapper"> | |
<table id="pgTable" class="pgTable" cellspacing="0" cellpadding="5"> | |
<tr class="pgGroupRow"> | |
<td colspan="2">Group 1</td> | |
</tr> | |
<tr class="pgRow"> | |
<td class="pgCell">Filter</td><td class="pgCell">On</td> | |
</tr> | |
<tr class="pgRow"> | |
<td class="pgCell">Filter Size</td><td class="pgCell">200</td> | |
</tr> | |
</table> | |
<div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var OTHER_GROUP_NAME = 'Other'; | |
// This is our settings object | |
var setObj = { | |
accumulateTicks: true, | |
filter: false, | |
filterSize: 200, | |
buyColor: '#00ff00', | |
sellColor: '#ff0000', | |
noGroup: 'I have no group' | |
}; | |
// This is our settings object metadata | |
var metaObj = { | |
filter: {group: 'Behavior', name: 'Filter', type: 'boolean'}, | |
filterSize: {group: 'Behavior', name: 'Filter size', type: 'number', min: 0, max: 500, step: 10}, | |
accumulateTicks: {group: 'Behavior', name: 'Accumulate ticks', type: 'boolean'}, | |
buyColor: {group: 'Appearance', name: 'Buy color', type: 'color'}, | |
sellColor: {group: 'Appearance', name: 'Sell color', type: 'color'} | |
}; | |
/** | |
* Generates the property grid | |
* @param {object} obj - The object whose properties we want to display | |
* @param {object} meta - A metadata object describing the obj properties | |
*/ | |
function generatePropertyGrid(obj, meta) { | |
meta = meta && typeof meta === 'object' ? meta : {}; | |
var groupsCellsHTML = { Other: '' }; | |
var groupsRowHTML = { }; | |
var theTable = $('#pgTable'); | |
var postInitFuncs = []; | |
var currGroup; | |
for (var prop in obj) { | |
// Check what is the group of the current property or use the default 'Other' group | |
currGroup = (meta[prop] && meta[prop].group) || OTHER_GROUP_NAME; | |
// If this is the first time we run into this group create the group row | |
if (currGroup !== OTHER_GROUP_NAME && !groupsRowHTML[currGroup]) { | |
groupsRowHTML[currGroup] = getGroupRowHtml(currGroup); | |
} | |
// Initialize the group cells html | |
groupsCellsHTML[currGroup] = groupsCellsHTML[currGroup] || ''; | |
// Append the current cell html into the group html | |
groupsCellsHTML[currGroup] += getPropertyRowHtml(prop, obj[prop], meta[prop], postInitFuncs); | |
} | |
// Now we have all the html we need, just assemble it | |
var innerHTML = ''; | |
for (var group in groupsRowHTML) { | |
// Add the group row | |
innerHTML += groupsRowHTML[group]; | |
// Add the group cells | |
innerHTML += groupsCellsHTML[group]; | |
} | |
// Finally we add the 'Other' group | |
innerHTML += getGroupRowHtml(OTHER_GROUP_NAME); | |
innerHTML += groupsCellsHTML[OTHER_GROUP_NAME]; | |
// Set the innerHTML to the table | |
theTable.html(innerHTML); | |
// Call the post init functions | |
for (var i = 0; i < postInitFuncs.length; ++i) { | |
if (typeof postInitFuncs[i] === 'function') { | |
postInitFuncs[i](); | |
} | |
} | |
// just in case make sure we are not holding any reference to the functions | |
postInitFuncs = null; | |
} | |
/** | |
* Gets the html of a group header row | |
* @param {string} displayName - The group display name | |
*/ | |
function getGroupRowHtml(displayName) { | |
return '<tr class="pgGroupRow"><td colspan="2">' + displayName + '</td></tr>'; | |
} | |
/** | |
* Gets the html of a specific property row | |
* @param {string} name - The property name | |
* @param {*} value - The current property value | |
* @param {object} meta - A metadata object describing this property | |
* @param {function[]} [postCreateInitFuncs] - An array to fill with functions to run after the grid was created | |
*/ | |
function getPropertyRowHtml(name, value, meta, postCreateInitFuncs) { | |
meta = meta || {}; | |
// We use the name in the meta if available | |
var displayName = meta.name || name; | |
var type = meta.type || ''; | |
var valueHTML; | |
switch(type) { | |
case 'number': | |
valueHTML = '<input type="text" id="' + name + '" value="' + value + '" style="width:50px" />'; | |
postCreateInitFuncs && postCreateInitFuncs.push(initSpinner(name, meta.min, meta.max, meta.step)); | |
break; | |
case 'boolean': | |
valueHTML = '<input type="checkbox" id="' + name + '" value="' + name + '" ' + (value ? 'checked' : '') + ' />'; | |
break; | |
case 'color': | |
valueHTML = '<input type="text" id="' + name + '" />'; | |
postCreateInitFuncs && postCreateInitFuncs.push(initColorPicker(name, value)); | |
break; | |
default: | |
valueHTML = '<input type="text" id="' + name + '" value="' + value + '"</input>'; | |
} | |
return '<tr class="pgRow"><td class="pgCell">' + displayName + '</td><td class="pgCell">' + valueHTML + '</td></tr>'; | |
} | |
/** | |
* Gets an init function to a number textbox | |
* @param {string} id - The number textbox id | |
* @param {number} [min] - The min number allowed | |
* @param {number} [max] - The max number allowed | |
* @param {number} [step] - The increment step | |
* @returns {function} | |
*/ | |
function initSpinner(id, min, max, step) { | |
if (!id) {return null;} | |
var options = {}; | |
if (typeof min === 'number') {options.min = min;} | |
if (typeof max === 'number') {options.max = max;} | |
if (typeof step === 'number') {options.step = step;} | |
return function() { | |
$('#' + id).spinner(options); | |
}; | |
} | |
/** | |
* Gets an init function to a color textbox | |
* @param {string} id - The color textbox id | |
* @param {string} color - The current selected color (e.g #000000) | |
* @returns {function} | |
*/ | |
function initColorPicker(id, color) { | |
if (!id) {return null;} | |
var options = { preferredFormat: "hex", showInput: true, showInitial: true }; | |
if (typeof color === 'string') {options.color = color;} | |
return function() { | |
$('#' + id).spectrum(options); | |
}; | |
} | |
// Lets create the grid | |
generatePropertyGrid(setObj, metaObj); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font-family: 'verdana'; | |
font-size: 12px; | |
} | |
.pgTable { | |
border: solid 1px #95B8E7; | |
} | |
.pgGroupRow { | |
background-color: #E0ECFF; | |
font-weight: bold; | |
} | |
.pgRow{} | |
.pgCell { | |
border: dotted 1px #ccc | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment