Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

New event handler #296

Open
wants to merge 1 commit into from

3 participants

@xuqingkuang

Refined the the event handler to be a standalone View, and added a icon to indicate existence of event handlers in outline View.

@zhizhangchen

Please merge the two commits into one as the first commit can't exist by itself

@zhizhangchen

There's a problem: When creating a new event handler, the editor doesn't have a cursor

@zhizhangchen

Then icon is a little big and I think two branches lightning is better than three branches lightning.

src/js/main.js
@@ -330,6 +334,21 @@
$(this).propertyView('option', 'model', ADM);
});
+ $('.eventHandler').each( function() {
+ $(this).eventHandlerView();
+ $(this).eventHandlerView('option', 'model', ADM)
+ .dialog({
@zhizhangchen Owner

Why do you create an dialog here instead of doing it in _create method of eventHandlerView?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/js/main.js
@@ -369,6 +388,14 @@
.append('<p class="centerImage"><img src="src/css/images/projectExportDivider.png"/></p>')
.append('<a id="about">About</a>')
.appendTo(this.ui.extras);
+
+ // Bindding the Done button clicked behavior.
+ this.ui.eventHandlerView
@zhizhangchen Owner

Can this binding be done in event handler's _create method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/js/views/eventHandler.js
((8 lines not shown))
+ *
+ */
+"use strict";
+// Event Handler view widget
+
+(function($, undefined) {
+ $.widget('rib.eventHandlerView', $.rib.baseView, {
+ _create: function() {
+ var o = this.options,
+ e = this.element;
+
+ // Chain up to base class _create()
+ $.rib.baseView.prototype._create.call(this);
+
+ // Create event handler dialog;
+ this._construct(this);
@zhizhangchen Owner

_construct function is not necessary as it's used only once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/js/views/eventHandler.js
((222 lines not shown))
+ this.formElement = formElement;
+ this.eventElement = eventElement;
+ this.eventSelectElement = eventSelectElement;
+ this.eventHandlersList = eventHandlersList;
+ this.eventEditor = eventEditor;
+ this.element
+ .append(formElement);
+ return this;
+ },
+
+ /*
+ * Elements construction functions.
+ */
+
+ // Generate the event property select options.
+ generateEventSelectElement: function(widget, eventSelectElement, node, matchedProps) {
@zhizhangchen Owner

Will this function be called outside? If not, define it as private function is better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/js/views/eventHandler.js
((41 lines not shown))
+
+ refresh: function(event, widget) {
+ widget = widget || this;
+ var matchedProps,
+ eventElement = widget.element.find('input[name="currentEvent"]'),
+ eventSelectElement = widget.element.find('select'),
+ eventHandlersList = widget.element.find('fieldset'),
+ node = ADM.getSelectedNode();
+
+ // Initial event handler if it's selected another event.
+ if (event && event.name === 'selectionChanged') {
+ eventElement.val('');
+ eventSelectElement.val('');
+ /*
+ * FIXME: setValue doesn't working here.
+ * widget.eventEditor.setValue('');
@zhizhangchen Owner

Maybe you should remove these lines?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/js/main.js
@@ -501,6 +529,14 @@
},
_selectionChanged: function(event, widget) {
+ // Update event handler dialog title after selection changed.
@zhizhangchen Owner

Why don't you do it in event handler's _selectionChanged method or refresh method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/js/views/eventHandler.js
((44 lines not shown))
+ var matchedProps,
+ eventElement = widget.element.find('input[name="currentEvent"]'),
+ eventSelectElement = widget.element.find('select'),
+ eventHandlersList = widget.element.find('fieldset'),
+ node = ADM.getSelectedNode();
+
+ // Initial event handler if it's selected another event.
+ if (event && event.name === 'selectionChanged') {
+ eventElement.val('');
+ eventSelectElement.val('');
+ /*
+ * FIXME: setValue doesn't working here.
+ * widget.eventEditor.setValue('');
+ */
+ widget.element.find('pre').empty();
+ widget.eventEditor.setOption('readOnly', 'nocursor');
@zhizhangchen Owner

Why do you set it to readOnly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@xuqingkuang

@zhizhangchen The code updated by your comments, please review.

There's only a issue is CodeMirror editor contents can't erase in some situation, so the editor re-initial code is exist in 'dialogopen' event handler and the 'refresh' function, it could make sure the editor is blank after selectionChanged.

Xuqing Kuang [Event handler] Refined the whole code to be a standalone View.
Refined the the event handler to be a standalone View,
and added a icon to indicate existence of event handlers in outline View.
d2491b9
@sbryan sbryan commented on the diff
src/css/builder.css
@@ -1563,17 +1563,19 @@ input.screenCoordinate::-webkit-inner-spin-button {
margin: 0 0.6em;
}
-#eventHandlerDialog {
+.eventHandler {
+ width: 980px !important; /* Override computed style */
@sbryan Owner
sbryan added a note

This is generally a bad idea, hardcoding sizes. If my screen or window is small enough, it's impossible to access the bottom of the dialog as it does not scroll it's contents.

I'd prefer we set max, min widths and heights in hard pixels only if necessary, then use percentages for the default width and heights. Also make sure the contents of the dialog can be scrolled if the dialog it's self is too small.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@sbryan sbryan commented on the diff
src/js/views/eventHandler.js
((50 lines not shown))
+ formElement.trigger('submit');
+ })
+ .select()
+ .appendTo(leftPanelContainer);
+
+ // Add a hidden input to store current event name
+ eventElement = $(
+ '<input name="currentEvent" type="hidden" value="" />'
+ ).appendTo(leftPanelContainer);
+
+ // Initial the event handlers list
+ eventHandlersList = $('<fieldset>')
+ .append($('<legend>Event handlers</legend>'))
+ .appendTo(leftPanelContainer);
+
+ // Create the DONE button
@sbryan Owner
sbryan added a note

I think we ought to also have a "Cancel" button, or some way for the user to revert their changes to the last saved value, in case they accidentally cut and paste the wrong code, or change their minds and want to restore the last script code that was in the editor before they started making changes.

Maybe there is another way to do this (short cut keybinding?) that I'm not aware of, but if not, we need it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@sbryan
Owner

The eventHandlerIcon.png does not really seem to fit or match the existing color scheme of the UX. I won't hold the PR becuase of this, but I suggest if we are going to try and be creative, we should follow existing color schemes. Normally, we would request new visual assets from our creative team, but, since we don't have one... ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 13, 2012
  1. [Event handler] Refined the whole code to be a standalone View.

    Xuqing Kuang authored
    Refined the the event handler to be a standalone View,
    and added a icon to indicate existence of event handlers in outline View.
This page is out of date. Refresh to see the latest.
View
1  index.html
@@ -47,6 +47,7 @@
<script src="src/js/views/outline.js"></script>
<script src="src/js/views/property.js"></script>
<script src="src/js/views/palette.js"></script>
+ <script src="src/js/views/eventHandler.js"></script>
<script src="src/js/views/widget.js"></script>
<script src="src/js/panel.js"></script>
<script src="src/js/main.js"></script>
View
61 src/css/builder.css
@@ -1563,17 +1563,19 @@ input.screenCoordinate::-webkit-inner-spin-button {
margin: 0 0.6em;
}
-#eventHandlerDialog {
+.eventHandler {
+ width: 980px !important; /* Override computed style */
@sbryan Owner
sbryan added a note

This is generally a bad idea, hardcoding sizes. If my screen or window is small enough, it's impossible to access the bottom of the dialog as it does not scroll it's contents.

I'd prefer we set max, min widths and heights in hard pixels only if necessary, then use percentages for the default width and heights. Also make sure the contents of the dialog can be scrolled if the dialog it's self is too small.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ height: 560px !important; /* Override computed style */
overflow: hidden;
}
-#eventHandlerDialog .title {
+.eventHandler .title {
position: relative;
height: 52px;
background-color: #E4E5DF;
}
-#eventHandlerDialog .title > label {
+.eventHandler .title > label {
position: absolute;
left: 10px;
top: 16px;
@@ -1583,32 +1585,31 @@ input.screenCoordinate::-webkit-inner-spin-button {
font-weight: 600; /* semi-bold */
}
-
-#eventHandlerDialog .wrap_left {
+.eventHandler .wrap_left {
position: relative;
width: 230px;
border-right: 1px solid #dededc;
}
-#eventHandlerDialog .wrap_left .container {
+.eventHandler .wrap_left .container {
position: absolute;
width: 100%;
margin: 10px;
}
-#eventHandlerDialog .wrap_left .container * {
+.eventHandler .wrap_left .container * {
display: inline-block;
}
-#eventHandlerDialog .wrap_left .container select {
+.eventHandler .wrap_left .container select {
position: absolute;
top: 10px;
left: 0px;
width: 270px;
}
-#eventHandlerDialog .wrap_left .container fieldset {
+.eventHandler .wrap_left .container fieldset {
position: absolute;
top: 40px;
width: 244px;
@@ -1616,11 +1617,11 @@ input.screenCoordinate::-webkit-inner-spin-button {
overflow: auto;
}
-#eventHandlerDialog .wrap_left .container fieldset ul {
+.eventHandler .wrap_left .container fieldset ul {
margin: 0px;
}
-#eventHandlerDialog .wrap_left .container fieldset li {
+.eventHandler .wrap_left .container fieldset li {
display: block;
padding: 8px 8px 8px 8px;
margin-left: -36px;
@@ -1630,36 +1631,40 @@ input.screenCoordinate::-webkit-inner-spin-button {
border-bottom: 1px solid #CCC;
}
-#eventHandlerDialog .wrap_left .container fieldset li.ui-selected {
+.eventHandler .wrap_left .container fieldset li.ui-selected {
background-color: #4AE57B;
}
-#eventHandlerDialog .wrap_left .container fieldset li > a.link {
+.eventHandler .wrap_left .container fieldset li > a.link {
padding-top: 8px;
width: 160px;
height: 34px;
}
-#eventHandlerDialog .wrap_left .container button.doneButton {
+.eventHandler .wrap_left .container fieldset a.ui-button {
+ margin-top: 0px;
+ float: right;
+}
+
+.eventHandler .wrap_left .container button.doneButton {
position: absolute;
top: 440px;
left: 46px;
width: 180px;
}
-#eventHandlerDialog .wrap_right {
+.eventHandler .wrap_right {
width: 630px;
}
-#eventHandlerDialog .wrap_right .container {
+.eventHandler .wrap_right .container {
overflow: auto;
resize: none;
- height: 600px;
width: 98%;
margin: 6px;
}
-#eventHandlerDialog .wrap_right .container .CodeMirror {
+.eventHandler .wrap_right .container .CodeMirror {
margin: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
@@ -1669,6 +1674,24 @@ input.screenCoordinate::-webkit-inner-spin-button {
height: 470px;
}
-#eventHandlerDialog .wrap_right .container .CodeMirror .CodeMirror-scroll {
+.eventHandler .wrap_right .container .CodeMirror .CodeMirror-scroll {
height: 464px;
}
+
+.eventHandlerIcon {
+ display: inline-block;
+ position: relative;
+ top: 4px;
+ left: 4px;
+ margin-right: 1px;
+ text-indent: -3000px;
+ height: 20px;
+ width: 20px;
+ background-repeat: no-repeat;
+ background-position: left top;
+ background-image: url('images/eventHandlerIcon.png');
+}
+
+.eventHandlerIcon:hover {
+ opacity: 0.8;
+}
View
BIN  src/css/images/eventHandlerIcon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
10 src/js/main.js
@@ -315,6 +315,10 @@
.addClass('view live flex1');
this.ui.liveView.append('<div class="stage flex1 vbox">');
+ this.ui.eventHandlerView = $('<div/>').appendTo(container)
+ .attr('id', 'eventHandlerView')
+ .addClass('view eventHandler');
+
$('.pageView').each( function () {
$(this).pageView();
$(this).pageView('option', 'model', ADM);
@@ -330,6 +334,11 @@
$(this).propertyView('option', 'model', ADM);
});
+ $('.eventHandler').each( function() {
+ $(this).eventHandlerView();
+ $(this).eventHandlerView('option', 'model', ADM);
+ })
+
$('.paletteView').each( function () {
$(this).paletteView();
widget._bindResizeEvent(this, 'paletteView');
@@ -431,6 +440,7 @@
this.ui.layoutView = $('.view.layout').eq(0);
this.ui.codeView = $('.view.code').eq(0);
this.ui.liveView = $('.view.live').eq(0);
+ this.ui.eventHandlerView = $('.view.eventHandler').eq(0);
this.ui.tools = $('.tools-primary').eq(0);
this.ui.extras = $('.tools-secondary').eq(0);
},
View
367 src/js/views/eventHandler.js
@@ -0,0 +1,367 @@
+/*
+ * Rapid Interface Builder (RIB) - A simple WYSIWYG HTML5 app creator
+ * Copyright (c) 2011-2012, Intel Corporation.
+ *
+ * This program is licensed under the terms and conditions of the
+ * Apache License, version 2.0. The full text of the Apache License is at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+"use strict";
+// Event Handler view widget
+
+(function($, undefined) {
+ $.widget('rib.eventHandlerView', $.rib.baseView, {
+ _create: function() {
+ var formContainer, leftPanel, leftPanelContainer,
+ rightPanel, eventElement, eventSelectElement,
+ eventEditorContainer, eventEditor, formElement,
+ jsCode, eventHandlersList,
+ o = this.options, e = this.element, self = this,
+ uniqueIdName = 'id';
+
+ // Chain up to base class _create()
+ $.rib.baseView.prototype._create.call(this);
+
+ /*
+ * Construct the page layout
+ */
+ // Page layout initial
+ formContainer = $('<div class="hbox" />');
+ leftPanel = $('<div class="flex1 vbox wrap_left" />')
+ .appendTo(formContainer)
+ rightPanel =$('<div class="flex1 wrap_right" />')
+ .appendTo(formContainer)
+
+ /*** Left panel contents ***/
+
+ $('<div class="title"><label>Event</label></div>')
+ .appendTo(leftPanel);
+
+ leftPanelContainer = $('<div>')
+ .addClass('container propertyItems')
+ .appendTo(leftPanel);
+
+ // Construct event options elements
+ eventSelectElement = $('<select>')
+ .attr({'name': 'selectedEvent'})
+ .addClass('center')
+ .change(function(e) {
+ formElement.trigger('submit');
+ })
+ .select()
+ .appendTo(leftPanelContainer);
+
+ // Add a hidden input to store current event name
+ eventElement = $(
+ '<input name="currentEvent" type="hidden" value="" />'
+ ).appendTo(leftPanelContainer);
+
+ // Initial the event handlers list
+ eventHandlersList = $('<fieldset>')
+ .append($('<legend>Event handlers</legend>'))
+ .appendTo(leftPanelContainer);
+
+ // Create the DONE button
@sbryan Owner
sbryan added a note

I think we ought to also have a "Cancel" button, or some way for the user to revert their changes to the last saved value, in case they accidentally cut and paste the wrong code, or change their minds and want to restore the last script code that was in the editor before they started making changes.

Maybe there is another way to do this (short cut keybinding?) that I'm not aware of, but if not, we need it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $('<button>Done</button>')
+ .addClass('buttonStyle doneButton')
+ .click( function (e) {
+ self.element.dialog('close');
+ })
+ .button()
+ .appendTo(leftPanelContainer);
+
+ /*** Right panel contents ***/
+
+ $('<div class="title"><label>Javascript Code</label></div>')
+ .appendTo(rightPanel);
+
+ // Construct code editor element
+ eventEditorContainer = $('<div/>')
+ .addClass('container')
+ .appendTo(rightPanel);
+ eventEditor = CodeMirror(
+ eventEditorContainer[0],
+ {
+ mode: "javascript",
+ readOnly: 'nocursor',
+ }
+ );
+ eventEditorContainer.show();
+
+ /*** Dialog contents ***/
+ formElement = $('<form>')
+ .append(formContainer)
+ .bind('submit', function(e) {
+ e.preventDefault();
+ var node = ADM.getSelectedNode(),
+ formData = $(this).serializeJSON();
+
+ formData['jsCode'] = eventEditor.getValue();
+
+ // If ID is blank, generate a unique one.
+ if(node.getProperty(uniqueIdName) == '') {
+ node.generateUniqueProperty(
+ uniqueIdName, true
+ );
+ }
+
+ // Save editor content to ADM property.
+ if (formData.currentEvent) {
+ node.setProperty(
+ formData.currentEvent,
+ formData.jsCode
+ );
+ // Refresh event handlers list.
+ self.refresh(e, self);
+ }
+
+ // Load the jsCode
+ //
+ // Checking the event select element changed
+ //
+ // If old event is not equal to current event in
+ // select, it's meaning the select changed not
+ // the window close, so we need to load the JS
+ // code from new selected property and change the
+ // editor content.
+ if (formData.currentEvent != formData.selectedEvent) {
+ if (formData.selectedEvent) {
+ // Load the event property content and set
+ // the editor content.
+ jsCode = node.getProperty(
+ formData.selectedEvent
+ );
+ if (typeof(jsCode) != 'string')
+ jsCode = '';
+ eventEditor.setOption('readOnly', false);
+ eventEditor.setValue(jsCode);
+ } else {
+ // Check the selection of event, if
+ // selected blank will clean up the editor
+ // content and set editor to be read only.
+ eventEditor.setValue('');
+ eventEditor.setOption(
+ 'readOnly', 'nocursor'
+ );
+ }
+
+ // Set currentEvent element to selctedEvent.
+ eventElement.val(formData.selectedEvent);
+ };
+ });
+
+ this.formElement = formElement;
+ this.eventElement = eventElement;
+ this.eventSelectElement = eventSelectElement;
+ this.eventHandlersList = eventHandlersList;
+ this.eventEditor = eventEditor;
+ this.element.append(formElement);
+ this.element.dialog({
+ modal: true,
+ width: 980,
+ height: 560,
+ resizable: false,
+ autoOpen: false
+ })
+ .bind('dialogopen', function(e) {
+ if (eventSelectElement.val() == '')
+ self._initialEditorContent(self);
+ })
+ .bind('dialogclose', function(e) {
+ self.formElement.trigger('submit');
+ });
+
+ return this;
+ },
+
+ _setOption: function(key, value) {
+ // Chain up to base class _setOptions()
+ // FIXME: In jquery UI 1.9 and above, instead use
+ // this._super('_setOption', key, value)
+ $.rib.baseView.prototype._setOption.apply(this, arguments);
+
+ switch (key) {
+ case 'model':
+ this.refresh(null, this);
+ break;
+ default:
+ break;
+ }
+ },
+
+ refresh: function(event, widget) {
+ widget = widget || this;
+ var matchedProps,
+ eventElement = widget.element.find('input[name="currentEvent"]'),
+ eventSelectElement = widget.element.find('select'),
+ eventHandlersList = widget.element.find('fieldset'),
+ node = ADM.getSelectedNode(), id = node.getProperty('id');
+
+ // Restore the select element to be blank
+ if (event && event.name == 'selectionChanged')
+ widget._initialEditorContent(widget);
+
+ // Update dialog title.
+ widget.element.dialog({
+ title: "Event Handlers - "
+ + BWidget.getDisplayLabel(node.getType())
+ + (id ? ' (' + id + ')' : '' ),
+ })
+
+ // Regenerate event select options/list.
+ matchedProps = node.getMatchingProperties({'type': 'event'});
+ widget._generateEventSelectElement(
+ widget, eventSelectElement, node, matchedProps
+ );
+ widget._generateEventHandlersList(
+ widget, eventSelectElement, node, matchedProps
+ ).replaceAll(eventHandlersList);
+ },
+
+ // Private functions
+ _createPrimaryTools: function() {
+ return $(null);
+ },
+
+ _createSecondaryTools: function() {
+ return $(null);
+ },
+
+ _selectionChangedHandler: function(event, widget) {
+ widget = widget || this;
+ widget.refresh(event, widget);
+ },
+
+ _initialEditorContent: function(widget) {
+ widget = widget || this;
+ widget.eventSelectElement.val('');
+ widget.eventElement.val('');
+ // Clean up the editor contents and restore it to be read only.
+ widget.eventEditor.setValue('');
+ widget.eventEditor.setOption('readOnly', 'nocursor');
+ },
+
+ /*
+ * Elements construction functions.
+ */
+
+ // Generate the event property select options.
+ _generateEventSelectElement: function(widget, eventSelectElement, node, matchedProps) {
+ var selected, newSelectElement, result,
+ optionElement, eventName, optionsGroup;
+
+ // If eventSelectElement is not exist then create one, otherwise
+ // restore it to initial.
+ if (eventSelectElement.length == 0) {
+ eventSelectElement = $('<select name="selectedEvent" class="center"></select>');
+ } else {
+ selected = eventSelectElement.val();
+ eventSelectElement.empty();
+ }
+
+ // Added a initial blank option;
+ $('<option value="">[Select an event handler]</option>')
+ .addClass('cm-inactive')
+ .appendTo(eventSelectElement);
+
+ // TODO: Classify the events and use optgroup to
+ // genereate it.
+ /*
+ optionsGroup = $(
+ '<optgroup label="[Select an event handler]"></optgroup>'
+ )
+ .appendTo(eventSelectElement);
+ */
+
+ // Generate event select options.
+ for (eventName in matchedProps) {
+ optionElement = $('<option>')
+ .attr('value', eventName)
+ .html(eventName)
+ .appendTo(eventSelectElement);
+
+ // If the event is selcted, then check it to be
+ // selected again.
+ if (eventName === selected)
+ optionElement.attr('selected', 'selected');
+
+ // If the event have codes, then highlight it.
+ if (typeof(matchedProps[eventName]) !== 'string')
+ continue;
+ if (matchedProps[eventName].trim() === '')
+ continue;
+ optionElement.addClass('cm-active');
+ optionElement.html(optionElement.html() + ' *');
+ }
+ return eventSelectElement;
+ },
+
+ // Generate the event event handler that had codes list area.
+ _generateEventHandlersList: function(widget, eventSelectElement, node, matchedProps) {
+ var selected, ulElement, liElement, aElement,
+ removeElement, result, eventName, eventHandlersList,
+ self = this;
+ var switchEventHandler = function(e) {
+ e.preventDefault();
+ var self = $(this), parent = self.parent(),
+ eventName = self.parent().attr('rel');
+ // Highlight current line.
+ parent.parent().find('.ui-selected').removeClass('ui-selected');
+ parent.addClass('ui-selected');
+ // Set the event handler editor.
+ widget.eventSelectElement.val(eventName);
+ widget.eventSelectElement.trigger('change');
+ },
+ removeEventHandler = function(e) {
+ e.preventDefault();
+ var eventName = $(this).parent().attr('rel');
+ $.rib.confirm(
+ 'Are you sure you want to delete the '
+ + eventName
+ + ' event handler?',
+ function() {
+ node.setProperty(eventName, '');
+ if (widget.eventElement.val() == eventName) {
+ widget.eventSelectElement.val('');
+ widget.eventEditor.setValue('');
+ }
+ widget.formElement.trigger('submit');
+ }
+ );
+ };
+ // Store the old selected event.
+ selected = eventSelectElement.val();
+
+ // Generate event handlers list.
+ eventHandlersList = $('<fieldset>')
+ .append($('<legend>Event handlers</legend>'))
+
+ ulElement = $('<ul>').appendTo(eventHandlersList);
+ for (eventName in matchedProps) {
+ if (typeof(matchedProps[eventName]) !== 'string')
+ continue;
+ if (matchedProps[eventName].trim() === '')
+ continue;
+ aElement = $('<a>')
+ .addClass('link')
+ .html(eventName)
+ .click(switchEventHandler);
+ liElement = $('<li>')
+ .attr('rel', eventName)
+ // FIXME: Strange behavior here
+ // removeElement only appended to
+ // last liElement
+ // .append(removeElement);
+ .append(aElement)
+ .appendTo(ulElement);
+ if (selected == eventName)
+ liElement.addClass('ui-selected');
+ }
+ removeElement = $('<div class="delete button">Delete</div>')
+ .click(removeEventHandler);
+ ulElement.find('li').append(removeElement);
+ return eventHandlersList;
+ }
+ })
+})(jQuery);
View
17 src/js/views/outline.js
@@ -160,7 +160,10 @@
return null;
return model.getSelectedNode() || model.getActivePage();
},
- _renderPageNode: function (domNode, node) {
+ _renderSpecialNode: function (domNode, node) {
+ var id, titleNode, element, icon;
+
+ // Display ID when type is Page.
if (node.getType() === "Page") {
//set page id
var id = node.getProperty('id'),
@@ -170,6 +173,16 @@
.appendTo(domNode.find("> a"));
titleNode.text(' (' + id + ')');
}
+
+ // Add event handler icon to outline view.
+ if (node.hasEventHandlers()) {
+ element = domNode.find('a');
+ icon = $('<a class="eventHandlerIcon" title="Open event handler.">Event Handler</a>')
+ .click(function(e) {
+ $(':rib-eventHandlerView').dialog('open');
+ });
+ element.append(icon);
+ }
},
_render: function (domNode, data) {
var labelFunc, parentNode = data.getParent(), newTopLevelNode;
@@ -187,7 +200,7 @@
$('<li class="label">' + label + '</li>')
.insertBefore(domNode).data('adm-node', parentNode);
}
- this._renderPageNode(domNode, data);
+ this._renderSpecialNode(domNode, data);
},
_nodeSelected: function (treeModelNode, data) {
this.options.model.setSelected(data.getUid());
View
320 src/js/views/property.js
@@ -622,325 +622,7 @@
.attr('id', "eventHandlerElement")
.appendTo(buttonsContainer)
.bind('click', function(e) {
- var generateEventSelectElement, generateEventHandlersList,
- removeEventHandler, eventLinkClicked;
- var formContainer, leftPanel, leftPanelContainer,
- rightPanel, eventElement, eventSelectElement,
- eventEditorContainer, eventEditor, formElement,
- jsCode, eventHandlersList, id,
- uniqueIdName = 'id';
-
- // If node have no ID property, then return directly.
- if(typeof(BWidget.propertyExists(node.getType(), uniqueIdName)) == 'undefined') {
- alert('Event handler must be using with the element have ID property.');
- return false;
- };
-
- /*
- * Call back functions.
- */
-
- // Remove event handler
- removeEventHandler = function(e) {
- e.preventDefault();
- var eventName = $(this).parent().attr('rel');
- $.rib.confirm(
- 'Are you sure you want to delete the '
- + eventName
- + ' event handler?',
- function() {
- node.setProperty(eventName, '');
- if (eventElement.val() == eventName) {
- eventEditor.setValue('');
- formElement.trigger('submit');
- } else {
- formElement.trigger('refresh');
- }
- }
- );
- }
-
- // Event link clicked callback
- eventLinkClicked = function(e) {
- e.preventDefault();
- var eventName = $(this).parent().attr('rel');
- eventSelectElement.val(eventName);
- formElement.trigger('submit');
- }
-
- /*
- * Elements generation functions.
- */
-
- // Generate the event property select options.
- generateEventSelectElement = function(selectElement, matchedProps) {
- var selected, newSelectElement, result, matchedProps,
- optionElement, eventName, optionsGroup;
-
- // Store the old selected event.
- selected = selectElement.val();
-
- // Clean up the origin options.
- selectElement.find('option').remove();
-
- // Search event properties
- if (!matchedProps)
- matchedProps = node.getMatchingProperties(
- {'type': 'event'}
- );
-
- // Added a initial blank option;
- $('<option value="">[Select an event handler]</option>')
- .addClass('cm-inactive')
- .appendTo(selectElement);
-
- // TODO: Classify the events and use optgroup to
- // genereate it.
- /*
- optionsGroup = $(
- '<optgroup label="[Select an event handler]"></optgroup>'
- )
- .appendTo(selectElement);
- */
-
- // Generate event select options.
- for (eventName in matchedProps) {
- optionElement = $('<option>')
- .attr('value', eventName)
- .html(node.getPropertyDisplayName(eventName))
- .appendTo(selectElement);
-
- // If the event is selcted, then check it to be
- // selected again.
- if (eventName == selected)
- optionElement.attr('selected', 'selected');
-
- // If the event have codes, then highlight it.
- if (typeof(matchedProps[eventName]) != 'string')
- continue;
- if (matchedProps[eventName].trim() == '')
- continue;
- optionElement.addClass('cm-active');
- optionElement.html(optionElement.html() + ' *');
- }
- }
-
- // Generate the event event handler that had codes list area.
- generateEventHandlersList = function(selectElement, matchedProps) {
- var selected, ulElement, liElement, aElement,
- removeElement, result, matchedProps, eventName;
-
- // Store the old selected event.
- selected = selectElement.val();
-
- // Search event properties
- if (!matchedProps)
- matchedProps = node.getMatchingProperties(
- {'type': 'event'}
- );
-
- // Generate event handlers list.
- eventHandlersList = $('<fieldset>')
- .append($('<legend>Event handlers</legend>'))
-
- ulElement = $('<ul>').appendTo(eventHandlersList);
- removeElement = $('<div class="delete button">Delete</div>')
- .click(removeEventHandler);
-
- for (eventName in matchedProps) {
- if (typeof(matchedProps[eventName]) != 'string')
- continue;
- if (matchedProps[eventName].trim() == '')
- continue;
- aElement = $('<a>')
- .addClass('link')
- .html(eventName)
- .click(eventLinkClicked);
- liElement = $('<li>')
- .attr('rel', eventName)
- // FIXME: Strange behavior here
- // removeElement only appended to
- // last liElement
- // .append(removeElement);
- .append(aElement)
- .appendTo(ulElement);
- }
- ulElement.find('li').append(removeElement);
- return eventHandlersList;
- }
-
- /*
- * Construct the page layout
- */
-
- // Page layout initial
- formContainer = $('<div class="hbox" />');
- leftPanel = $('<div class="flex1 vbox wrap_left" />')
- .appendTo(formContainer)
- rightPanel =$('<div class="flex1 wrap_right" />')
- .appendTo(formContainer)
-
- /*** Left panel contents ***/
-
- $('<div class="title"><label>Event</label></div>')
- .appendTo(leftPanel);
-
- leftPanelContainer = $('<div>')
- .addClass('container propertyItems')
- .appendTo(leftPanel);
-
- // Construct event options elements
- eventSelectElement = $('<select>')
- .attr({'name': 'selectedEvent'})
- .addClass('center')
- .change(function(e) {
- formElement.trigger('submit');
- })
- .select()
- .appendTo(leftPanelContainer);
-
- // Add a hidden input to store current event name
- eventElement = $(
- '<input name="currentEvent" type="hidden" value="" />'
- ).appendTo(leftPanelContainer);
-
- // Initial the event handlers list
- eventHandlersList = $('<fieldset>')
- .append($('<legend>Event handlers</legend>'))
- .appendTo(leftPanelContainer);
-
- // Create the DONE button
- $('<button>Done</button>')
- .addClass('buttonStyle doneButton')
- .click( function (e) {
- formElement.dialog('close');
- })
- .button()
- .appendTo(leftPanelContainer);
-
- /*** Right panel contents ***/
-
- $('<div class="title"><label>Javascript Code</label></div>')
- .appendTo(rightPanel);
-
- // Construct code editor element
- eventEditorContainer = $('<div/>')
- .addClass('container')
- .appendTo(rightPanel);
- eventEditor = CodeMirror(
- eventEditorContainer[0],
- {
- mode: "javascript",
- readOnly: 'nocursor',
- }
- );
- eventEditorContainer.show();
-
- /*** Dialog contents ***/
- id = node.getProperty('id');
- formElement = $('<form>')
- .attr('id', 'eventHandlerDialog')
- .append(formContainer)
- .dialog({
- title: "Event Handlers - "
- + BWidget.getDisplayLabel(type)
- + (id ? ' (' + id + ')' : '' ),
- modal: true,
- width: 980,
- height: 600,
- resizable: false
- })
- .bind('refresh', function(e, matchedProps) {
- if (!matchedProps)
- matchedProps = node.getMatchingProperties(
- {'type': 'event'}
- );
-
- // Regenerate event select options.
- generateEventSelectElement(
- eventSelectElement, matchedProps
- );
-
- // Regenerate the event handlers list.
- eventHandlersList.replaceWith(
- generateEventHandlersList(
- eventSelectElement,matchedProps
- )
- );
- })
- .bind('dialogclose', function(e) {
- $(this).trigger('submit');
- })
- .bind('submit', function(e) {
- e.preventDefault();
-
- // Serialize the form data to JSON.
- var formData = $(this).serializeJSON();
- formData['jsCode'] = eventEditor.getValue();
-
- // If ID is blank, generate a unique one.
- if(node.getProperty(uniqueIdName) == '') {
- node.generateUniqueProperty(
- uniqueIdName, true
- );
- }
-
- // Save editor content to ADM property.
- if (formData.currentEvent) {
- node.setProperty(
- formData.currentEvent,
- formData.jsCode
- );
- // Refresh event handlers list.
- $(this).trigger('refresh');
- }
-
- // Load the jsCode
- //
- // Checking the event select element changed
- //
- // If old event is not equal to current event in
- // select, it's meaning the select changed not
- // the window close, so we need to load the JS
- // code from new selected property and change the
- // editor content.
- if (formData.currentEvent != formData.selectedEvent) {
- if (formData.selectedEvent) {
- // Load the event property content and set
- // the editor content.
- jsCode = node.getProperty(
- formData.selectedEvent
- );
- if (typeof(jsCode) != 'string')
- jsCode = '';
- eventEditor.setOption('readOnly', false);
- eventEditor.setValue(jsCode);
-
- // Hightlight current event in event
- // handlers
- eventHandlersList
- .find('li.ui-selected')
- .removeClass('ui-selected');
- eventHandlersList
- .find('li[rel="' + formData.selectedEvent + '"]')
- .addClass('ui-selected');
- } else {
- // Check the selection of event, if
- // selected blank will clean up the editor
- // content and set editor to be read only.
- eventEditor.setValue('');
- eventEditor.setOption(
- 'readOnly', 'nocursor'
- );
- }
-
- // Set currentEvent element to selctedEvent.
- eventElement.val(formData.selectedEvent);
- };
- });
-
- // Initial event handlers list.
- formElement.trigger('refresh');
+ $(':rib-eventHandlerView').dialog('open');
});
// add delete element button
Something went wrong with that request. Please try again.