diff --git a/src/css/builder.css b/src/css/builder.css
index 6ee74f20..f4609c10 100644
--- a/src/css/builder.css
+++ b/src/css/builder.css
@@ -929,7 +929,7 @@ div.propertyItems > div > * {
display: table-cell;
padding-bottom: 8px;
}
-table#selectOption {
+table.selectTable {
width: 100%;
}
div.propertyItems label[for] {
diff --git a/src/js/views/property.js b/src/js/views/property.js
index 2f3eaa45..08266c49 100644
--- a/src/js/views/property.js
+++ b/src/js/views/property.js
@@ -85,35 +85,73 @@
widget.refresh(event,widget);
},
- _setProperty: function(property, value) {
- var viewId = property + '-value';
- if (typeof(value) === 'boolean') {
- this.element.find("#" + viewId).attr('checked', value);
- } else {
- this.element.find("#" + viewId).val(value);
+ _setProperty: function(property, propType, value) {
+ var element = this.element.find("#" + property + '-value');
+ switch (propType) {
+ case "boolean":
+ element.attr('checked', value);
+ break;
+ default:
+ element.val(value);
}
},
+ _redrawProperty: function(property, newElment) {
+ var element = this.element.find("#" + property + '-value');
+ element.replaceWith(newElment);
+ },
+
_modelUpdatedHandler: function(event, widget) {
- var affectedWidget, id, value;
+ var affectedWidget, id, value, propType;
widget = widget || this;
if (event && event.type === "propertyChanged") {
if (event.node.getType() !== 'Design') {
id = event.property + '-value';
affectedWidget = widget.element.find('#' + id);
- if (affectedWidget.attr('type') !== 'checkbox') {
- value = affectedWidget.val();
- } else {
- value = affectedWidget.attr('checked')?true:false;
+ propType = BWidget.getPropertyType(event.node.getType(), event.property);
+
+ // Get value to for commparation
+ switch (propType) {
+ case "boolean":
+ value = affectedWidget.attr('checked')?true:false;
+ break;
+ case "record-array":
+ value = event.oldValue; // FIXME: oldValue can't passed here.
+ break;
+ default:
+ value = affectedWidget.val();
+ break;
}
- if(event.newValue != value) {
- affectedWidget[0].scrollIntoViewIfNeeded();
- if(typeof(event.newValue) === 'boolean') {
- affectedWidget.effect('pulsate', { times:3 }, 200);
- } else {
- affectedWidget.effect('highlight', {}, 1000);
- }
- widget._setProperty(event.property, event.newValue);
+
+ // Compare the newValue is equal with value, then return directly.
+ if (event.newValue == value)
+ return
+
+ // Update ADM and apply effects.
+ switch (propType) {
+ case "boolean":
+ if (affectedWidget) {
+ affectedWidget[0].scrollIntoViewIfNeeded();
+ affectedWidget.effect('pulsate', { times:3 }, 200);
+ }
+ widget._setProperty(event.property, propType, event.newValue);
+ break;
+ case "record-array":
+ value = event.oldValue;
+ // TODO: Do something with affectedWidget
+ // affectedWidget = event.element;
+ widget._redrawProperty(
+ event.property,
+ widget._generateRecordArraryTable(widget, event.node, event.property)
+ );
+ break;
+ default:
+ if (affectedWidget) {
+ affectedWidget[0].scrollIntoViewIfNeeded();
+ affectedWidget.effect('highlight', {}, 1000);
+ }
+ widget._setProperty(event.property, propType, event.newValue);
+ break;
}
return;
} else if (event.property !== 'css') {
@@ -138,6 +176,183 @@
return;
},
+ _generateSelectMenuOption: function(node, property, child, index, props) {
+ var changeCallback = function(event) {
+ var newValue, self = $(this);
+ props[property].children[index][event.data.key] = self.val();
+ newValue = props[property];
+ node.fireEvent("modelUpdated", {
+ type: "propertyChanged",
+ node: node,
+ property: property,
+ element: self,
+ newValue: newValue,
+ index: index
+ });
+ };
+
+ if (!props)
+ props = node.getProperties();
+ return $('
').data('index', index)
+ .addClass("options")
+ .append(' | ')
+ .children().eq(0)
+ .append('')
+ .children(':first')
+ .attr('src', "src/css/images/propertiesDragIconSmall.png")
+ .end()
+ .end().end()
+ .append(' | ')
+ .children().eq(1)
+ .append('')
+ .children().eq(0)
+ .val(child.text)
+ .addClass('title optionInput')
+ .change({key: 'text'}, changeCallback)
+ .end().end()
+ .end().end()
+ .append(' | ')
+ .children().eq(2)
+ .append('')
+ .children().eq(0)
+ .val(child.value)
+ .addClass('title optionInput')
+ .change({key: 'value'}, changeCallback)
+ .end().end()
+ .end().end()
+ .append(' | ')
+ .children().eq(3)
+ .append('Delete
')
+ .children(':first')
+ // add delete option handler
+ .click(function(e) {
+ try {
+ var newValue, self = $(this);
+ // Generate ADM properties
+ index = self.parent().parent().data('index');
+ props[property].children.splice(index, 1);
+ // Instead by draw, so comment following lines.
+ /*
+ // Remove the row element after clicked delete button
+ self.parent().parent().remove();
+ */
+ newValue = props[property];
+ // Trigger the modelUpdated event.
+ node.fireEvent("modelUpdated", {
+ type: "propertyChanged",
+ node: node,
+ property: property,
+ element: self,
+ newValue: newValue,
+ index: index
+ });
+ }
+ catch (err) {
+ console.error(err.message);
+ }
+ e.stopPropagation();
+ return false;
+ })
+ .end()
+ .end().end();
+ },
+
+ _generateRecordArraryTable: function(widget, node, property, props) {
+ var child, table = $('')
+ .attr('id', property + '-value')
+ .addClass('selectTable')
+ .attr('cellspacing', '5');
+
+ if (!props)
+ props = node.getProperties();
+
+ $('
')
+ .append(' | ')
+ .append(' Text | ')
+ .children().eq(1)
+ .addClass('title')
+ .end().end()
+ .append(' Value | ')
+ .children().eq(2)
+ .addClass('title')
+ .end().end()
+ .append(' | ')
+ .appendTo(table);
+ for (var i = 0; i< props[property].children.length; i++){
+ child = props[property].children[i];
+ table.append(
+ this._generateSelectMenuOption(node, property, child, i, props)
+ );
+ }
+
+ // add add items handler
+ $('+ add item |
')
+ .children(':first')
+ .addClass('rightLabel title')
+ .attr('id', 'addOptionItem')
+ .end()
+ .click(function(e) {
+ var newValue, self = $(this);
+ try {
+ var rowElement, index = props[property].children.length,
+ optionItem = {
+ 'text': 'Option',
+ 'value': 'Value'
+ };
+ props[property].children.push(optionItem);
+ // Instead by draw, so comment following lines.
+ /*
+ rowElement = widget._generateSelectMenuOption(
+ node, property, optionItem, index, props
+ );
+ */
+ table.append(rowElement);
+ $(this).insertAfter(rowElement);
+ newValue = props[property];
+ node.fireEvent("modelUpdated", {
+ type: "propertyChanged",
+ node: node,
+ property: property,
+ element: self,
+ newValue: newValue,
+ index: index
+ });
+ } catch (err) {
+ console.error(err.message);
+ }
+ e.stopPropagation();
+ return false;
+ })
+ .appendTo(table);
+
+ // make option sortable
+ table.sortable({
+ axis: 'y',
+ items: '.options',
+ containment: table.find('tbody'),
+ start: function(event, ui) {
+ widget.origRowIndex = ui.item.index() - 1;
+ },
+ stop: function(event, ui) {
+ var optionItem, curIndex = ui.item.index() - 1,
+ origIndex = widget.origRowIndex;
+ optionItem = props[property].children.splice(origIndex,1)[0];
+
+ props[property].children.splice(curIndex, 0, optionItem);
+ node.fireEvent("modelUpdated", {
+ type: "propertyChanged",
+ node: node,
+ property: property,
+ element: table,
+ newValue: props[property],
+ index: ui.item.index()
+ });
+ }
+ });
+
+ return table;
+ },
+
_showProperties: function(node) {
var labelId, labelVal, valueId, valueVal, count,
widget = this, type, i, child, index, propType,
@@ -251,137 +466,7 @@
break;
case "record-array":
- $('')
- .attr('id', 'selectOption')
- .attr('cellspacing', '5')
- .appendTo(value);
- var selectOption = value.find('#selectOption');
- $('
')
- .append(' | ')
- .append(' Text | ')
- .children().eq(1)
- .addClass('title')
- .end().end()
- .append(' Value | ')
- .children().eq(2)
- .addClass('title')
- .end().end()
- .append(' | ')
- .appendTo(selectOption);
- for (i = 0; i< props[p].children.length; i ++){
- child = props[p].children[i];
- $('
').data('index', i)
- .addClass("options")
- .append(' | ')
- .children().eq(0)
- .append('')
- .children(':first')
- .attr('src', "src/css/images/propertiesDragIconSmall.png")
- .end()
- .end().end()
- .append(' | ')
- .children().eq(1)
- .append('')
- .children().eq(0)
- .val(child.text)
- .addClass('title optionInput')
- .change(node, function (event) {
- index = $(this).parent().parent().data('index');
- props['options'].children[index].text = $(this).val();
- node.fireEvent("modelUpdated",
- {type: "propertyChanged",
- node: node,
- property: 'options'});
- })
- .end().end()
- .end().end()
- .append(' | ')
- .children().eq(2)
- .append('')
- .children().eq(0)
- .val(child.value)
- .addClass('title optionInput')
- .change(node, function (event) {
- index = $(this).parent().parent().data('index');
- props['options'].children[index].value = $(this).val();
- node.fireEvent("modelUpdated",
- {type: "propertyChanged",
- node: node,
- property: 'options'});
- })
- .end().end()
- .end().end()
- .append(' | ')
- .children().eq(3)
- .append('Delete
')
- .children(':first')
- // add delete option handler
- .click(function(e) {
- try {
- index = $(this).parent().parent().data('index');
- props['options'].children.splice(index, 1);
- node.fireEvent("modelUpdated",
- {type: "propertyChanged",
- node: node,
- property: 'options'});
- }
- catch (err) {
- console.error(err.message);
- }
- e.stopPropagation();
- return false;
- })
- .end()
- .end().end()
- .appendTo(selectOption);
- }
-
- // add add items handler
- $('')
- .children(':first')
- .addClass('rightLabel title')
- .attr('id', 'addOptionItem')
- .end()
- .appendTo(value);
- value.find('#addOptionItem')
- .click(function(e) {
- try {
- var optionItem = {};
- optionItem.text = "Option";
- optionItem.value = "Value";
- props['options'].children.push(optionItem);
- node.fireEvent("modelUpdated",
- {type: "propertyChanged",
- node: node,
- property: 'options'});
- }
- catch (err) {
- console.error(err.message);
- }
- e.stopPropagation();
- return false;
- });
-
- // make option sortable
- value.find('#selectOption tbody').sortable({
- axis: 'y',
- items: '.options',
- containment: value.find('#selectOption tbody'),
- start: function(event, ui) {
- widget.origRowIndex = ui.item.index() - 1;
- },
- stop: function(event, ui) {
- var optionItem, curIndex = ui.item.index() - 1,
- origIndex = widget.origRowIndex;
- optionItem = props['options'].children.splice(origIndex,1)[0];
-
- props['options'].children.splice(curIndex, 0, optionItem);
- node.fireEvent("modelUpdated",
- {type: "propertyChanged",
- node: node,
- property: 'options'});
- }
- });
+ value.append(this._generateRecordArraryTable(widget, node, p, props));
break;
case "targetlist":
container = node.getParent();