UNPKG

freeboard-leaflet-realtime

Version:
544 lines (454 loc) 16.6 kB
PluginEditor = function(jsEditor, valueEditor) { function _displayValidationError(settingName, errorMessage) { var errorElement = $('<div class="validation-error"></div>').html(errorMessage); $("#setting-value-container-" + settingName).append(errorElement); } function _removeSettingsRows() { if($("#setting-row-instance-name").length) { $("#setting-row-instance-name").nextAll().remove(); } else { $("#setting-row-plugin-types").nextAll().remove(); } } function _isNumerical(n) { return !isNaN(parseFloat(n)) && isFinite(n); } function _appendCalculatedSettingRow(valueCell, newSettings, settingDef, currentValue, includeRemove) { var input = $('<textarea></textarea>'); if(settingDef.multi_input) { input.change(function() { var arrayInput = []; $(valueCell).find('textarea').each(function() { var thisVal = $(this).val(); if(thisVal) { arrayInput = arrayInput.concat(thisVal); } }); newSettings.settings[settingDef.name] = arrayInput; }); } else { input.change(function() { newSettings.settings[settingDef.name] = $(this).val(); }); } if(currentValue) { input.val(currentValue); } valueEditor.createValueEditor(input); var datasourceToolbox = $('<ul class="board-toolbar datasource-input-suffix"></ul>'); var wrapperDiv = $('<div class="calculated-setting-row"></div>'); wrapperDiv.append(input).append(datasourceToolbox); var datasourceTool = $('<li><i class="icon-plus icon-white"></i><label>DATASOURCE</label></li>') .mousedown(function(e) { e.preventDefault(); $(input).val("").focus().insertAtCaret("datasources[\"").trigger("freeboard-eval"); }); datasourceToolbox.append(datasourceTool); var jsEditorTool = $('<li><i class="icon-fullscreen icon-white"></i><label>.JS EDITOR</label></li>') .mousedown(function(e) { e.preventDefault(); jsEditor.displayJSEditor(input.val(), function(result) { input.val(result); input.change(); }); }); datasourceToolbox.append(jsEditorTool); if(includeRemove) { var removeButton = $('<li class="remove-setting-row"><i class="icon-minus icon-white"></i><label></label></li>') .mousedown(function(e) { e.preventDefault(); wrapperDiv.remove(); $(valueCell).find('textarea:first').change(); }); datasourceToolbox.prepend(removeButton); } $(valueCell).append(wrapperDiv); } function createPluginEditor(title, pluginTypes, currentTypeName, currentSettingsValues, settingsSavedCallback) { var newSettings = { type : currentTypeName, settings: {} }; function createSettingRow(name, displayName) { var tr = $('<div id="setting-row-' + name + '" class="form-row"></div>').appendTo(form); tr.append('<div class="form-label"><label class="control-label">' + displayName + '</label></div>'); return $('<div id="setting-value-container-' + name + '" class="form-value"></div>').appendTo(tr); } var selectedType; var form = $('<div></div>'); var pluginDescriptionElement = $('<div id="plugin-description"></div>').hide(); form.append(pluginDescriptionElement); function createSettingsFromDefinition(settingsDefs, typeaheadSource, typeaheadDataSegment) { _.each(settingsDefs, function(settingDef) { // Set a default value if one doesn't exist if(!_.isUndefined(settingDef.default_value) && _.isUndefined(currentSettingsValues[settingDef.name])) { currentSettingsValues[settingDef.name] = settingDef.default_value; } var displayName = settingDef.name; if(!_.isUndefined(settingDef.display_name)) { displayName = settingDef.display_name; } var valueCell = createSettingRow(settingDef.name, displayName); switch (settingDef.type) { case "array": { var subTableDiv = $('<div class="form-table-value-subtable"></div>').appendTo(valueCell); var subTable = $('<table class="table table-condensed sub-table"></table>').appendTo(subTableDiv); var subTableHead = $("<thead></thead>").hide().appendTo(subTable); var subTableHeadRow = $("<tr></tr>").appendTo(subTableHead); var subTableBody = $('<tbody></tbody>').appendTo(subTable); var currentSubSettingValues = []; // Create our headers _.each(settingDef.settings, function(subSettingDef) { var subsettingDisplayName = subSettingDef.name; if(!_.isUndefined(subSettingDef.display_name)) { subsettingDisplayName = subSettingDef.display_name; } $('<th>' + subsettingDisplayName + '</th>').appendTo(subTableHeadRow); }); if(settingDef.name in currentSettingsValues) { currentSubSettingValues = currentSettingsValues[settingDef.name]; } function processHeaderVisibility() { if(newSettings.settings[settingDef.name].length > 0) { subTableHead.show(); } else { subTableHead.hide(); } } function createSubsettingRow(subsettingValue) { var subsettingRow = $('<tr></tr>').appendTo(subTableBody); var newSetting = {}; if(!_.isArray(newSettings.settings[settingDef.name])) { newSettings.settings[settingDef.name] = []; } newSettings.settings[settingDef.name].push(newSetting); _.each(settingDef.settings, function(subSettingDef) { var subsettingCol = $('<td></td>').appendTo(subsettingRow); var subsettingValueString = ""; if(!_.isUndefined(subsettingValue[subSettingDef.name])) { subsettingValueString = subsettingValue[subSettingDef.name]; } newSetting[subSettingDef.name] = subsettingValueString; $('<input class="table-row-value" type="text">').appendTo(subsettingCol).val(subsettingValueString).change(function() { newSetting[subSettingDef.name] = $(this).val(); }); }); subsettingRow.append($('<td class="table-row-operation"></td>').append($('<ul class="board-toolbar"></ul>').append($('<li></li>').append($('<i class="icon-trash icon-white"></i>').click(function() { var subSettingIndex = newSettings.settings[settingDef.name].indexOf(newSetting); if(subSettingIndex != -1) { newSettings.settings[settingDef.name].splice(subSettingIndex, 1); subsettingRow.remove(); processHeaderVisibility(); } }))))); subTableDiv.scrollTop(subTableDiv[0].scrollHeight); processHeaderVisibility(); } $('<div class="table-operation text-button">ADD</div>').appendTo(valueCell).click(function() { var newSubsettingValue = {}; _.each(settingDef.settings, function(subSettingDef) { newSubsettingValue[subSettingDef.name] = ""; }); createSubsettingRow(newSubsettingValue); }); // Create our rows _.each(currentSubSettingValues, function(currentSubSettingValue, subSettingIndex) { createSubsettingRow(currentSubSettingValue); }); break; } case "boolean": { newSettings.settings[settingDef.name] = currentSettingsValues[settingDef.name]; var onOffSwitch = $('<div class="onoffswitch"><label class="onoffswitch-label" for="' + settingDef.name + '-onoff"><div class="onoffswitch-inner"><span class="on">YES</span><span class="off">NO</span></div><div class="onoffswitch-switch"></div></label></div>').appendTo(valueCell); var input = $('<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="' + settingDef.name + '-onoff">').prependTo(onOffSwitch).change(function() { newSettings.settings[settingDef.name] = this.checked; }); if(settingDef.name in currentSettingsValues) { input.prop("checked", currentSettingsValues[settingDef.name]); } break; } case "option": { var defaultValue = currentSettingsValues[settingDef.name]; var input = $('<select></select>').appendTo($('<div class="styled-select"></div>').appendTo(valueCell)).change(function() { newSettings.settings[settingDef.name] = $(this).val(); }); _.each(settingDef.options, function(option) { var optionName; var optionValue; if(_.isObject(option)) { optionName = option.name; optionValue = option.value; } else { optionName = option; } if(_.isUndefined(optionValue)) { optionValue = optionName; } if(_.isUndefined(defaultValue)) { defaultValue = optionValue; } $("<option></option>").text(optionName).attr("value", optionValue).appendTo(input); }); newSettings.settings[settingDef.name] = defaultValue; if(settingDef.name in currentSettingsValues) { input.val(currentSettingsValues[settingDef.name]); } break; } default: { newSettings.settings[settingDef.name] = currentSettingsValues[settingDef.name]; if(settingDef.type == "calculated") { if(settingDef.name in currentSettingsValues) { var currentValue = currentSettingsValues[settingDef.name]; if(settingDef.multi_input && _.isArray(currentValue)) { var includeRemove = false; for(var i=0; i<currentValue.length; i++) { _appendCalculatedSettingRow(valueCell, newSettings, settingDef, currentValue[i], includeRemove); includeRemove = true; } } else { _appendCalculatedSettingRow(valueCell, newSettings, settingDef, currentValue, false); } } else { _appendCalculatedSettingRow(valueCell, newSettings, settingDef, null, false); } if(settingDef.multi_input) { var inputAdder = $('<ul class="board-toolbar"><li class="add-setting-row"><i class="icon-plus icon-white"></i><label>ADD</label></li></ul>') .mousedown(function(e) { e.preventDefault(); _appendCalculatedSettingRow(valueCell, newSettings, settingDef, null, true); }); $(valueCell).siblings('.form-label').append(inputAdder); } } else { var input = $('<input type="text">').appendTo(valueCell).change(function() { if(settingDef.type == "number") { newSettings.settings[settingDef.name] = Number($(this).val()); } else { newSettings.settings[settingDef.name] = $(this).val(); } }); if(settingDef.name in currentSettingsValues) { input.val(currentSettingsValues[settingDef.name]); } if(typeaheadSource && settingDef.typeahead_data_field){ input.addClass('typeahead_data_field-' + settingDef.typeahead_data_field); } if(typeaheadSource && settingDef.typeahead_field){ var typeaheadValues = []; input.keyup(function(event){ if(event.which >= 65 && event.which <= 91) { input.trigger('change'); } }); $(input).autocomplete({ source: typeaheadValues, select: function(event, ui){ input.val(ui.item.value); input.trigger('change'); } }); input.change(function(event){ var value = input.val(); var source = _.template(typeaheadSource)({input: value}); $.get(source, function(data){ if(typeaheadDataSegment){ data = data[typeaheadDataSegment]; } data = _.select(data, function(elm){ return elm[settingDef.typeahead_field][0] == value[0]; }); typeaheadValues = _.map(data, function(elm){ return elm[settingDef.typeahead_field]; }); $(input).autocomplete("option", "source", typeaheadValues); if(data.length == 1){ data = data[0]; //we found the one. let's use it to populate the other info for(var field in data){ if(data.hasOwnProperty(field)){ var otherInput = $(_.template('input.typeahead_data_field-<%= field %>')({field: field})); if(otherInput){ otherInput.val(data[field]); if(otherInput.val() != input.val()) { otherInput.trigger('change'); } } } } } }); }); } } break; } } if(!_.isUndefined(settingDef.suffix)) { valueCell.append($('<div class="input-suffix">' + settingDef.suffix + '</div>')); } if(!_.isUndefined(settingDef.description)) { valueCell.append($('<div class="setting-description">' + settingDef.description + '</div>')); } }); } new DialogBox(form, title, "Save", "Cancel", function() { $(".validation-error").remove(); // Loop through each setting and validate it for(var index = 0; index < selectedType.settings.length; index++) { var settingDef = selectedType.settings[index]; if(settingDef.required && (_.isUndefined(newSettings.settings[settingDef.name]) || newSettings.settings[settingDef.name] == "")) { _displayValidationError(settingDef.name, "This is required."); return true; } else if(settingDef.type == "integer" && (newSettings.settings[settingDef.name] % 1 !== 0)) { _displayValidationError(settingDef.name, "Must be a whole number."); return true; } else if(settingDef.type == "number" && !_isNumerical(newSettings.settings[settingDef.name])) { _displayValidationError(settingDef.name, "Must be a number."); return true; } } if(_.isFunction(settingsSavedCallback)) { settingsSavedCallback(newSettings); } }); // Create our body var pluginTypeNames = _.keys(pluginTypes); var typeSelect; if(pluginTypeNames.length > 1) { var typeRow = createSettingRow("plugin-types", "Type"); typeSelect = $('<select></select>').appendTo($('<div class="styled-select"></div>').appendTo(typeRow)); typeSelect.append($("<option>Select a type...</option>").attr("value", "undefined")); _.each(pluginTypes, function(pluginType) { typeSelect.append($("<option></option>").text(pluginType.display_name).attr("value", pluginType.type_name)); }); typeSelect.change(function() { newSettings.type = $(this).val(); newSettings.settings = {}; // Remove all the previous settings _removeSettingsRows(); selectedType = pluginTypes[typeSelect.val()]; if(_.isUndefined(selectedType)) { $("#setting-row-instance-name").hide(); $("#dialog-ok").hide(); } else { $("#setting-row-instance-name").show(); if(selectedType.description && selectedType.description.length > 0) { pluginDescriptionElement.html(selectedType.description).show(); } else { pluginDescriptionElement.hide(); } $("#dialog-ok").show(); createSettingsFromDefinition(selectedType.settings, selectedType.typeahead_source, selectedType.typeahead_data_segment); } }); } else if(pluginTypeNames.length == 1) { selectedType = pluginTypes[pluginTypeNames[0]]; newSettings.type = selectedType.type_name; newSettings.settings = {}; createSettingsFromDefinition(selectedType.settings); } if(typeSelect) { if(_.isUndefined(currentTypeName)) { $("#setting-row-instance-name").hide(); $("#dialog-ok").hide(); } else { $("#dialog-ok").show(); typeSelect.val(currentTypeName).trigger("change"); } } } // Public API return { createPluginEditor : function( title, pluginTypes, currentInstanceName, currentTypeName, currentSettingsValues, settingsSavedCallback) { createPluginEditor(title, pluginTypes, currentInstanceName, currentTypeName, currentSettingsValues, settingsSavedCallback); } } }