Skip to content

Instantly share code, notes, and snippets.

@JogoShugh
Last active December 12, 2015 00:48
Show Gist options
  • Save JogoShugh/4685990 to your computer and use it in GitHub Desktop.
Save JogoShugh/4685990 to your computer and use it in GitHub Desktop.
VersionOne MetaMorformzr
{
"Story.Name": {
"_type": "AttributeDefinition",
"Name": "Name",
"Token": "Story.Name",
"DisplayName": "AttributeDefinition'Name'Story",
"AttributeType": "Text",
"IsReadOnly": false,
"IsRequired": true,
"IsMultivalue": false,
"IsCanned": true,
"IsCustom": false,
"Base": {
"href": "/versionone.web/meta.v1/BaseAsset/Name",
"tokenref": "BaseAsset.Name"
},
"OrderByAttribute": {
"href": "/versionone.web/meta.v1/Story/Name",
"tokenref": "Story.Name"
}
},
"Story.Description": {
"_type": "AttributeDefinition",
"Name": "Description",
"Token": "Story.Description",
"DisplayName": "AttributeDefinition'Description'Story",
"AttributeType": "LongText",
"IsReadOnly": false,
"IsRequired": false,
"IsMultivalue": false,
"IsCanned": true,
"IsCustom": false,
"Base": {
"href": "/versionone.web/meta.v1/BaseAsset/Description",
"tokenref": "BaseAsset.Description"
},
"OrderByAttribute": {
"href": "/versionone.web/meta.v1/Story/Description",
"tokenref": "Story.Description"
}
},
"Story.Estimate": {
"_type": "AttributeDefinition",
"Name": "Estimate",
"Token": "Story.Estimate",
"DisplayName": "AttributeDefinition'Estimate'Story",
"AttributeType": "Numeric",
"IsReadOnly": false,
"IsRequired": false,
"IsMultivalue": false,
"IsCanned": true,
"IsCustom": false,
"Base": {
"href": "/versionone.web/meta.v1/PrimaryWorkitem/Estimate",
"tokenref": "PrimaryWorkitem.Estimate"
},
"OrderByAttribute": {
"href": "/versionone.web/meta.v1/Story/Estimate",
"tokenref": "Story.Estimate"
}
}
}
javascript:alert('RequestedByAndEvenMore'.replace(/([A-Z])/g, ' $1').substring(1) == 'Requested By And Even More')
<html>
<head>
<title>VersionOne MetaMorformizr User Story Editor</title>
</head>
<body>
<h1>VersionOne MetaMorformizr User Story Editor</h1>
An intermediate / advanced example of using the VersionOne HTTP API with
the open source jQuery, Backbone, and Backbone Forms libraries.
<br/>
<br/>This example uses all three core VersionOne APIs: Meta, Localization,
and Data.
<a href="http://community.versionone.com/sdk/documentation/coreapi.aspx"
target="_blank">Learn more here about the APIs</a>.
<br/>
<br/>
<div style='border: 1px solid darkgray;padding:5px;background:linen'>
<h3>Instructions</h3>
<ol>
<li>1: Click <code>Load Story</code>
<br/>
<blockquote><i><span>Result</span>: Story details should load with values for the attributes selected in the <code>Which attributes?</code> list</i>
</blockquote>
</li>
<li>2: Modify the story and click <code>Save Story</code>
<br/>
<blockquote><i><span>Result</span>: Story will be saved back to VersionOne</i>
</blockquote>
</li>
<li>3: Select some different fields from the <code>Which attributes?</code> list
and repeat from step 1</li>
</ol>
</div>
<div class='editorDiv'>
<div id="editor">
<form id="editorForm">
<fieldset>
<legend>VersionOne MetaMorformizr User Story Editor</legend>
<div id="editorFields"></div>
</fieldset>
</form>
<input type="button" id="save" value="Save Story" />&nbsp;<span id="message"></span>
<img id='saveSpinner' height='20' width='20'
src="https://www12.v1host.com/s/12.3.5.45/css/images/loaders/ajax-loader.gif"
/>
</div>
<label for="StoryId"><b>Which Story do you want to edit?</b>
</label>
<input type="text" id="StoryId" value='1154' />
<br />
<label for="Fields"><b>Which attributes?</b>
</label>
<select id='attributes' multiple='true'>
<option value='Name'>Name</option>
<option value='Description'>Description</option>
<option value='Estimate'>Estimate</option>
<option value='RequestedBy'>Requested By</option>
<option value='Benefits'>Benefits</option>
<option value='ToDo'>To Do</option>
</select>
<br />
<input type="button" id="storyGet" value="Load Story" class='bbf-load'
/>
<img id='spinner' class='bbf-load' height='20' width='20' src="https://www12.v1host.com/s/12.3.5.45/css/images/loaders/ajax-loader.gif"
/>
</div>
</body>
</html>
function readQueryString(key) {
return "Name,Description,Estimate";
}
Backbone.emulateHTTP = true;
var siteRoot = "http://eval.versionone.net/platformtest/";
var urlRoot = siteRoot + "rest-1.v1/Data/Story/";
var metaUrl = siteRoot + "meta.v1/Story?accept=application/json";
var l10nUrl = siteRoot + "loc.v1";
var v1AtttributeTypeToBackboneFormsFieldMap = {
LongText: { type: "TextArea" },
Text: { type: "Text" },
Numeric: { type: "Number" }
};
var headers = { Authorization: "Basic " + btoa("admin:admin"), Accept: "haljson" };
var formSchema = {};
var form = null;
var storyModel = Backbone.Model.extend({
urlRoot: urlRoot,
url: function() {
if (!this.isNew()) return this.urlRoot + this.id;
return this.urlRoot + this.id + "?sel=" + _.keys(formSchema).join(",");
},
save: function(attributes, options) {
options || (options = {contentType: "haljson", patch: true, headers: headers});
return Backbone.Model.prototype.save.call(this, attributes, options);
},
fetch: function(options) {
options || (options = {dataType: "json", headers: headers});
return Backbone.Model.prototype.fetch.call(this, options);
}
});
var model = new storyModel;
function loadMeta(callback) {
formSchema = {};
var attributes = getSelectedAttributesNames();
$.ajax(metaUrl).done(function(data) {
var titleRequests = [];
var attributeNames = _.map(attributes, function(fieldName) {
return "Story." + fieldName;
});
attribs = _.pick(data.Attributes, attributeNames);
_.each(attribs, function(item, index) {
var field = {};
var mixThemInProps = v1AtttributeTypeToBackboneFormsFieldMap[item.AttributeType];
_.extend(field, mixThemInProps);
var isRequired = item.IsRequired;
if (isRequired) {
if (!field.validators) {
field.validators = [];
}
field.validators.push("required");
}
formSchema[item.Name] = field;
var titleRequest = function() {
var formField = field;
return $.ajax(l10nUrl + "?" + item.DisplayName).done(function(data) {
formField.title = data;
});
};
titleRequests.push(titleRequest);
});
$.when.apply(null, titleRequests).done(function() {
callback();
});
});
}
function createForm(model) {
var settings = { schema: formSchema };
function finish() {
form = new Backbone.Form(settings);
$("#editorFields").empty();
$("#editorFields").append(form.render().el);
$("#editor").fadeIn();
}
if (model) {
model.fetch().done(function() {
settings.model = model;
finish();
});
} else finish();
}
function storyGet() {
$("#storyGet").attr("disabled", "disabled");
$("#editor").fadeOut();
$("#spinner").fadeIn();
loadMeta(function() {
model.id = $("#StoryId").val();
if (model.id == "") {
return;
}
createForm(model);
$("#editor").delay(1e3).fadeIn();
$("#spinner").fadeOut(function() {
$("#storyGet").removeAttr("disabled");
});
});
}
function storySave() {
if (form.validate() !== null) return;
form.commit();
$("#save").attr("disabled", true);
$("#message").hide();
$("#saveSpinner").fadeIn();
var xhr = model.save(form.getValue()).done(function(data) {
$("#saveSpinner").fadeOut(function() {
$("#save").attr("disabled", false);
$("#message").text("Save successful!").fadeIn().delay(1500).fadeOut(1500);
});
});
}
function getSelectedAttributesNames() {
var attributes = [];
$("#attributes option:selected").each(function() {
attributes.push($(this).attr("value"));
});
return attributes;
}
$(function() {
var initialFields = readQueryString("sel").split(",");
_.each(initialFields, function(field) {
var option = $('option[value="' + field + '"]');
option.attr("selected", "selected");
});
$("#save").click(storySave);
$("#storyGet").click(storyGet);
});
body {
padding: 5px;
font-family: sans-serif;
}
#editor {
padding: 10px;
border: 1px solid darkblue;
background: whitesmoke;
display: none;
margin-bottom: 15px;
}
label { color: darkblue }
textarea { height: 100px }
#message {
font-weight: bold;
color: darkgreen;
}
/* From Backbone Forms github site */
/* Date */
.bbf-date .bbf-date { width: 4em }
.bbf-date .bbf-month { width: 9em }
.bbf-date .bbf-year { width: 5em }
/* DateTime */
.bbf-datetime select { width: 4em }
/* List */
.bbf-list .bbf-add,
.bbf-load { margin-top: -10px }
.bbf-list li { margin-bottom: 5px }
.bbf-list .bbf-del { margin-left: 4px }
/* List.Modal */
.bbf-list-modal {
cursor: pointer;
border: 1px solid #ccc;
width: 208px;
border-radius: 3px;
padding: 4px;
color: #555;
}
/* Custom */
#spinner,
#saveSpinner { display: none }
blockquote {
font-size: 75%;
font-weight: bold;
}
blockquote code {
font-size: 75%;
background: beige;
}
blockquote span { color: darkgreen }
.editorDiv {
margin-top: 10px;
padding: 10px;
border: 2px solid darkgray;
}
{
"Story.Name": {
"_type": "AttributeDefinition",
"Name": "Name",
"Token": "Story.Name",
"DisplayName": "AttributeDefinition'Name'Story",
"AttributeType": "Text",
"IsReadOnly": false,
"IsRequired": true,
"IsMultivalue": false,
"IsCanned": true,
"IsCustom": false,
"Base": {
"href": "/versionone.web/meta.v1/BaseAsset/Name",
"tokenref": "BaseAsset.Name"
},
"OrderByAttribute": {
"href": "/versionone.web/meta.v1/Story/Name",
"tokenref": "Story.Name"
}
},
"Story.Description": {
"_type": "AttributeDefinition",
"Name": "Description",
"Token": "Story.Description",
"DisplayName": "AttributeDefinition'Description'Story",
"AttributeType": "LongText",
"IsReadOnly": false,
"IsRequired": false,
"IsMultivalue": false,
"IsCanned": true,
"IsCustom": false,
"Base": {
"href": "/versionone.web/meta.v1/BaseAsset/Description",
"tokenref": "BaseAsset.Description"
},
"OrderByAttribute": {
"href": "/versionone.web/meta.v1/Story/Description",
"tokenref": "Story.Description"
}
},
"Story.Estimate": {
"_type": "AttributeDefinition",
"Name": "Estimate",
"Token": "Story.Estimate",
"DisplayName": "AttributeDefinition'Estimate'Story",
"AttributeType": "Numeric",
"IsReadOnly": false,
"IsRequired": false,
"IsMultivalue": false,
"IsCanned": true,
"IsCustom": false,
"Base": {
"href": "/versionone.web/meta.v1/PrimaryWorkitem/Estimate",
"tokenref": "PrimaryWorkitem.Estimate"
},
"OrderByAttribute": {
"href": "/versionone.web/meta.v1/Story/Estimate",
"tokenref": "Story.Estimate"
}
}
}
readQueryString = (key) ->
"Name,Description,Estimate"
Backbone.emulateHTTP = true
siteRoot = "http://eval.versionone.net/platformtest/"
urlRoot = siteRoot + "rest-1.v1/Data/Story/"
metaUrl = siteRoot + "meta.v1/Story?accept=application/json"
l10nUrl = siteRoot + "loc.v1"
v1AtttributeTypeToBackboneFormsFieldMap =
LongText:
type: "TextArea"
Text:
type: "Text"
Numeric:
type: "Number"
headers =
Authorization: "Basic " + btoa("admin:admin")
Accept: "haljson"
formSchema = {}
form = null
storyModel = Backbone.Model.extend(
urlRoot: urlRoot
url: ->
return @urlRoot + @id unless @isNew()
@urlRoot + @id + "?sel=" + _.keys(formSchema).join(",")
save: (attributes, options) ->
options or (options =
contentType: "haljson"
patch: true
headers: headers
)
Backbone.Model::save.call this, attributes, options
fetch: (options) ->
options or (options =
dataType: "json"
headers: headers
)
Backbone.Model::fetch.call this, options
)
model = new storyModel
loadMeta = (callback) ->
formSchema = {}
attributes = getSelectedAttributesNames()
$.ajax(metaUrl).done (data) ->
titleRequests = []
attributeNames = _.map(attributes, (fieldName) ->
"Story." + fieldName
)
attribs = _.pick(data.Attributes, attributeNames)
_.each attribs, (item, index) ->
field = {}
mixThemInProps = v1AtttributeTypeToBackboneFormsFieldMap[item.AttributeType]
_.extend field, mixThemInProps
isRequired = item.IsRequired
if isRequired
field.validators = [] unless field.validators
field.validators.push "required"
formSchema[item.Name] = field
titleRequest = ->
formField = field
$.ajax(l10nUrl + "?" + item.DisplayName).done (data) ->
formField.title = data
titleRequests.push titleRequest
$.when.apply(null, titleRequests).done ->
callback()
createForm = (model) ->
settings = schema: formSchema
finish = ->
form = new Backbone.Form(settings)
$("#editorFields").empty()
html = form.render().el
$("#editorFields").append html
$("#editor").fadeIn()
if model
model.fetch().done ->
settings.model = model
finish()
else
finish()
storyGet = ->
$("#storyGet").attr "disabled", "disabled"
$("#editor").fadeOut()
$("#spinner").fadeIn()
loadMeta ->
model.id = $("#StoryId").val()
return if model.id is ""
createForm model
$("#editor").delay(1e3).fadeIn()
$("#spinner").fadeOut ->
$("#storyGet").removeAttr "disabled"
storySave = ->
return if form.validate() isnt null
form.commit()
$("#save").attr "disabled", true
$("#message").hide()
$("#saveSpinner").fadeIn()
xhr = model.save(form.getValue()).done((data) ->
$("#saveSpinner").fadeOut ->
$("#save").attr "disabled", false
$("#message").text("Save successful!").fadeIn().delay(1500).fadeOut 1500
)
getSelectedAttributesNames = ->
attributes = []
$("#attributes option:selected").each ->
attributes.push $(this).attr("value")
attributes
$ ->
initialFields = readQueryString("sel").split(",")
_.each initialFields, (field) ->
option = $("option[value=\"" + field + "\"]")
option.attr "selected", "selected"
$("#save").click storySave
$("#storyGet").click storyGet
readQueryString = (key) ->
"Name,Description,Estimate"
loadMeta = (callback) ->
formSchema = {}
attributes = getSelectedAttributesNames()
$.ajax(metaUrl).done (data) ->
titleRequests = []
attributeNames = _.map(attributes, (fieldName) ->
"Story." + fieldName
)
attribs = _.pick(data.Attributes, attributeNames)
_.each attribs, (item, index) ->
field = {}
mixThemInProps = v1AtttributeTypeToBackboneFormsFieldMap[item.AttributeType]
_.extend field, mixThemInProps
isRequired = item.IsRequired
if isRequired
field.validators = [] unless field.validators
field.validators.push "required"
formSchema[item.Name] = field
titleRequest = ->
formField = field
$.ajax(l10nUrl + "?" + item.DisplayName).done (data) ->
formField.title = data
titleRequests.push titleRequest
$.when.apply(null, titleRequests).done ->
callback()
createForm = (model) ->
finish = ->
form = new Backbone.Form(settings)
$("#editorFields").empty()
$("#editorFields").append form.render().el
$("#editor").fadeIn()
settings = schema: formSchema
if model
model.fetch().done ->
settings.model = model
finish()
else
finish()
storyGet = ->
$("#storyGet").attr "disabled", "disabled"
$("#editor").fadeOut()
$("#spinner").fadeIn()
loadMeta ->
model.id = $("#StoryId").val()
return if model.id is ""
createForm model
$("#editor").delay(1e3).fadeIn()
$("#spinner").fadeOut ->
$("#storyGet").removeAttr "disabled"
storySave = ->
return if form.validate() isnt null
form.commit()
$("#save").attr "disabled", true
$("#message").hide()
$("#saveSpinner").fadeIn()
xhr = model.save(form.getValue()).done((data) ->
$("#saveSpinner").fadeOut ->
$("#save").attr "disabled", false
$("#message").text("Save successful!").fadeIn().delay(1500).fadeOut 1500
)
getSelectedAttributesNames = ->
attributes = []
$("#attributes option:selected").each ->
attributes.push $(this).attr("value")
attributes
Backbone.emulateHTTP = true
siteRoot = "http://eval.versionone.net/platformtest/"
urlRoot = siteRoot + "rest-1.v1/Data/Story/"
metaUrl = siteRoot + "meta.v1/Story?accept=application/json"
l10nUrl = siteRoot + "loc.v1"
v1AtttributeTypeToBackboneFormsFieldMap =
LongText:
type: "TextArea"
Text:
type: "Text"
Numeric:
type: "Number"
headers =
Authorization: "Basic " + btoa("admin:admin")
Accept: "haljson"
formSchema = {}
form = null
storyModel = Backbone.Model.extend(
urlRoot: urlRoot
url: ->
return @urlRoot + @id unless @isNew()
@urlRoot + @id + "?sel=" + _.keys(formSchema).join(",")
save: (attributes, options) ->
options or (options =
contentType: "haljson"
patch: true
headers: headers
)
Backbone.Model::save.call this, attributes, options
fetch: (options) ->
options or (options =
dataType: "json"
headers: headers
)
Backbone.Model::fetch.call this, options
)
model = new storyModel
$ ->
initialFields = readQueryString("sel").split(",")
_.each initialFields, (field) ->
option = $("option[value=\"" + field + "\"]")
option.attr "selected", "selected"
$("#save").click storySave
$("#storyGet").click storyGet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment