Populating DropDown List in Alfresco Share - javascript

I need help populating dropdown list in Alfresco Share. I've created a WebScript API which I read the content of a folder in the repository. As a service in Alfresco (repository) it works. However, I need that DropDown in Share.
Here is what I did in Alfresco:
var folder = roothome.childByNamePath(url.extension);
if (folder == undefined || !folder.isContainer)
{
status.code = 404;
status.message = "Folder " + url.extension + " not found.";
status.redirect = true;
}
model.folder = folder;
<webscript>
<shortname>Folder Listing Sample</shortname>
<description>Sample demonstrating the listing of folder contents</description>
<url>/folder/{path}</url>
<format default="html">argument</format>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>
<html>
<head>
<title>${folder.displayPath}/${folder.name}</title>
</head>
<body>
Folder: ${folder.displayPath}/${folder.name}
<br>
<select id='selectItems' name='selectItems' onchange='dropdown2()'>
<#list folder.children as child>
<option value='${child.nodeRef}'>${child.properties.name}</option>
</#list>
</select>
</body>
</html>
<#macro encodepath node><#if node.parent?exists><#encodepath node=node.parent/>/${node.name?url}</#if></#macro>
I need this dropdown in Share. Since variables like: userhome, companyhome and such aren't accessible from Share WebScripts, I don't know how to get info from Alfresco and display it in Share. Any help would be appreciated.

From javascript controller of alfresco share, you can call webscript of alfresco and retrieve details from alfresco webscript in json format. Below is one example which is calling alfresco side webscript from share javascript controller.
try
{
var url = "/slingshot/webscript/from/alfresco/url";
logger.log("url: " + url);
// Request the current user's preferences
var result = remote.call(url);
if (result.status == 200 && result != "{}")
{
logger.log(result);
var nodeInfo = eval('(' + result + ')');
nodeRef = nodeInfo.parent.nodeRef;
}
}
catch (e)
{ }
In above url, is of alfresco webscript url which will return data in json format.you can also return data in another format depends on your requirement.

Related

Use of localStorage and IndexedDB in New Google Sites <Embed HTML> doesn't work

I'm trying to make use of the New Google Sites for a web page that I've developed, however, I'm having trouble storing local data. Local files work fine in windows and apple safari/chrome. Try it from Google Sites, and no joy! Additionally, in safari, an error is thrown, "IDBFactory.open() called in an invalid security context".
I really would like to host my site via google sites without linking to another server. I specifically need locally persistent data for just a few small items. I can't seem to make cookies work either.
Any suggestions?
I have tried this on a Windows 10 Surface Pro 2017, Apple iPad running 12.2 of Safari, Apple Mac Mini running macOs Mojave 10.14. I use SimpleHTTPServer from Windows 10 command line to share the files as a web server. I also email the files and open directly on the specified systems. Finally, I have created a New Google Sites website at https://sites.google.com/view/gerrymap It's very simple, just an Embed HTML element with the below text copied into the source code edit box. All are welcome to hit that page if they desire. Otherwise, use the short posted file below.
Instructions are in the HTML page itself.
All code works fine from a local instance of the html file. Can enter new values for the lat, long, rad, and key, save them, and read them. I can also refresh the page, then read them without storing first, and there is no problem. This proves that the values aren't just session persistent.
From Google Sites is a different matter. I set up a site that uses the html file in this question. When I enter new values and press the save button, IndexedDB fails, but localStorage succeeds in returning the values saved. If I press the refresh button, however, and then read the values without attempting to store first, IndexedDB again fails, but localStorage also fails in that it doesn't retrieve any values.
I believe I've correctly implemented the code (although some out there may take exception, I'm sure. No pride here, critics are welcome).
I've done a bunch of google searches, particularly about google sites and indexeddb/localstorage, and also posted on the google community help forum. Still no success.
Currently, I have no fallback methods, but need something relatively simple. Can anyone throw a little joy my way? Thanks in advance!
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Test Local Storage</title>
<style>
</style>
</head>
<body onload="initializeValues()">
Instructions: <br />
1. Save this sample code in an html file locally and open in a browser.<br />
2. Enter different values into the lat, long, rad, and key edit boxes.<br />
3. Press TrySave to store the values in indexedDB and localStorage.<br />
4. Refresh the webpage from the browser address line<br />
5. Press the individual Try IndexedDB and Try LocalStorage buttons to attempt<br />
6. Try inserting this code into a New Google Site, or access https://sites.google.com/view/gerrymap/home <br />
<br>
<input id="latitude" /> Latitude<br><br>
<input id="longitude" /> Longitude<br><br>
<input id="radius" /> Radius<br><br>
<input id="key" /> Key<br><br>
<button onclick="TryIndexedDB()" title="This tries to load via IndexedDB">Try IndexedDB</button><br><br>
<button onclick="TryLocalStorage()" title="This tries to load via localStorage">Try localStorage</button><br><br>
<button onclick="trySave()" title="This tries to save the data in both methods (IndexedDB, localStorage)">Try Save</button><br><br>
<button onclick="clearAll()" title="Clear the log space at the bottom of this example page">Clear Log</button><br><br>
<div id="hello">
</div>
<script>
"use strict";
function clearAll() {
document.getElementById("hello").innerHTML = "";
}
// tagBeginDefaultsReplace
var navLatitude = 39;
var navLongitude = -76.7;
var navMaxDist = 200;
var navKey = "PleaseAddYourKey";
function initializeValues() {
document.getElementById("latitude").value = navLatitude;
document.getElementById("longitude").value = navLongitude;
document.getElementById("radius").value = navMaxDist;
document.getElementById("key").value = navKey;
}
function trySave() {
navLatitude = document.getElementById("latitude").value;
navLongitude = document.getElementById("longitude").value;
navMaxDist = document.getElementById("radius").value;
navKey = document.getElementById("key").value;
// Save using indexeddb
getLocationDB(true, FinishIndexedDB);
// Save using localStorage
localStorage.setItem('latitude', navLatitude.toString());
localStorage.setItem('longitude', navLongitude.toString());
localStorage.setItem('radius', navMaxDist.toString());
localStorage.setItem('key', navKey.toString());
mylog("Done saving localStorage");
}
function getLocationDB(bSave, callbackf) {
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
var openDB;
try {
var myitem;
openDB = indexedDB.open("SampleDatabase", 1);
openDB.onupgradeneeded = function () {
var db = openDB.result;
var store = db.createObjectStore("SampleStore", { keyPath: "id" });
var index = store.createIndex("PosIndex", ["pos.latitude", "pos.longitude", "pos.radius", "pos.navkey"]);
};
openDB.onsuccess = function () {
// Start a new transaction var db = openDB.result;
callbackf("Successfully opened openDB");
var db = openDB.result;
var tx = db.transaction("SampleStore", "readwrite");
var store = tx.objectStore("SampleStore");
if (bSave) {
if (navLatitude != undefined && navLongitude != undefined && navMaxDist != undefined)
store.put({ id: 0, pos: { latitude: navLatitude, longitude: navLongitude, radius: navMaxDist, navkey: navKey } });
else
store.put({ id: 0, pos: { latitude: "38", longitude: "-75.7", radius: "100", navkey: "Please Enter Mapbox Key" } });
callbackf("Save indexeddb finished");
}
else {
var getNavLoc = store.get(0);
getNavLoc.onsuccess = function () {
if (getNavLoc != undefined
&& getNavLoc.result != undefined) {
callbackf("Succeeded reading from store. Result=" + JSON.stringify(getNavLoc.result));
navLatitude = parseFloat(getNavLoc.result.pos.latitude);
navLongitude = parseFloat(getNavLoc.result.pos.longitude);
navMaxDist = parseFloat(getNavLoc.result.pos.radius);
navKey = getNavLoc.result.pos.navkey;
}
else {
callbackf("Succeeded reading from store. Result=undefined");
navLatitude = navLongitude = navMaxDist = navKey = "undef";
}
initializeValues();
}
getNavLoc.onerror = function () {
callbackf("An error occurred getting indexeddb");
}
}
}
openDB.onerror = function () {
callbackf("An error occurred opening openDB");
}
}
catch (e) {
callbackf("Caught error in try block of indexeddb: " + e.Message);
}
}
function TryIndexedDB() {
getLocationDB(false, FinishIndexedDB);
}
function TryLocalStorage() {
mylog("localStorage read");
navLatitude = localStorage.getItem('latitude');
mylog("latitude=" + navLatitude);
navLongitude = localStorage.getItem('longitude');
mylog("longitude=" + navLongitude);
navMaxDist = localStorage.getItem('radius');
mylog("radius=" + navMaxDist);
navKey = localStorage.getItem('key');
mylog("key=" + navKey);
if (navLatitude == undefined)
navLatitude = "undef";
if (navLongitude == undefined)
navLongitude = "undef";
if (navMaxDist == undefined)
navMaxDist = "undef";
if (navKey == undefined)
navKey = "undef";
initializeValues();
}
function FinishIndexedDB(nSucceeded) {
mylog(nSucceeded);
}
function mylog(logstr) {
document.getElementById("hello").innerHTML += "<br>" + logstr.toString();
}
</script>
</body>
</html >
The problem is the way Google Sites is serving the iframe content. I'm not sure of the exact details behind the scenes, but it seems to have a randomly generated domain every time the page loads. Since localStorage and IndexedDB are associated with a specific domain, this causes the saved data to be "lost" when the page reloads.
As an example, here is the iframe's data from when I first loaded the page:
And here is the iframe's data after refreshing the page:
As you can see, the domain is completely different after refreshing, which means it has a brand new empty database.

Button Action to retrieve data from spreadsheet using google app script

How to retrieve a complete row from a spreadsheet based on a filter on an action such as a click of a button.
I read that GAS is server-side scripting and it is complex to gain access to a spreadsheet.
Is that so. Please guide me.
I have done till this:
$("#form-action")
.button()
.click(function() {
var ss = SpreadsheetApp.openById("");
var sheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sheet.getSheetByName('Test'));
SpreadsheetApp.getActiveSheet().getRange("D1").setFormula('Query(A:C,"SELECT A,B,C WHERE B="' + "mydata'" + ',1)');
SpreadsheetApp.getActiveSheet().getRange("E:J").getValues();
});
Gaining access to the spreadsheet is not difficult at all. You have to remember that while Google Apps Script runs on Google servers, the client-side code (e.g. HTML and JavaScript code you use in your UI templates) will be sent to your browser for rendering, so you can't really mix the two and write jQuery code in GAS(.gs) files or vice versa.
To clarify, commands like
var ss = SpreadsheetApp.openById("");
must be kept in .gs files. To use client-side HTML and JavaScript, you must create separate HTML files in your project (go to File - New - HTML file). Here's more information on serving HTML in GAS https://developers.google.com/apps-script/guides/html/
Luckily, Google provides the API that allows you to communicate between client and server sides by calling 'google.script.run.' followed by the name of the function in '.gs' file.
Example function in '.gs' file
function addRow() {
var sheet = SpreadsheetApp.getActive()
.getSheets()[0];
sheet.appendRow(['Calling', 'server', 'function']);
}
In your HTML template file, here's how you would call this function
<script>
google.script.run.addRow();
</script>
Consider the example that is more relevant to your situation. In my spreadsheet, the QUERY formula changes dynamically based on the value entered by the user. The form with input field is displayed in the sidebar.
Project structure
Code for 'sidebar.html' is below. Note that using the 'name' attribute of the <input> element is mandatory. On form submit, the value of the attribute ('filterBy') will be transformed into propetry of the form object that we can reference in our server function to get user input.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
</head>
<body>
<form id="myForm">
<input type="text" name="filterBy">
<input type="submit" value="submit">
</form>
<table id="myTable"></table>
<script>
$('document').ready(function(){
var form = $('#myForm');
var table = $('#myTable');
var runner = google.script.run;
form.on('submit', function(event){
event.preventDefault(); //prevents <form> redirecting to another page on submit
table.empty(); // clear the table
runner.withSuccessHandler(function(array){ //this callback function will be invoked after the 'retriveValues()' function below
for (var i = 0; i < array.length; i++) {
var item = '<tr><td>' + array[i] +'</td></tr>';
table.append(item);
}
})
.retrieveValues(this); //the function that will be called first. Here, 'this' refers to the form element
});
});
</script>
</body>
</html>
Code in '.gs' file:
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheets()[0];
function onOpen() {
var ui = SpreadsheetApp.getUi();
var htmlOutput = HtmlService.createTemplateFromFile('sidebar')
.evaluate();
ui.showSidebar(htmlOutput);
}
function retrieveValues(req) {
var res = [];
var filterBy = req.filterBy; //getting the value of the input field.
sheet.getRange(1, 2, 1, 1)
.setFormula("QUERY(A1:A, \"SELECT A WHERE A > " + filterBy + "\")");
sheet.getRange(1, 2, sheet.getLastRow(), 1)
.getValues()
.map(function(value){
if (value[0] != "") res = res.concat(value[0]); // get only the values that are not empty strings.
});
return res;
}
Here's the result of entering the value and submitting the form. The server-side function returns the array of values greater than 5. The callback function that we passed as parameter to 'withSuccessHandler' then receives this array and populates the table in the sidebar.
Finally, I'm not sure why you are using the QUERY formula. Instead of modifying 'SELECT' statement, you could simply take the values from the target range an filter them in GAS.

How to import Clipboard.js library into Google App Script?

Since manipulating clipboard is forbidden in Google App, I want to find a workaround by using Clipboard.js library.
My questions are:
1. How should I import a Clipboard.js library to Google App Script?
2. And how to call the functions in other pages (eg. trying to call the function calculateWeight() from BMI.gs in index.html?
What I've tried:
I've tried to paste the source code of the Clipboard.js into a file called Clipboard.js.html and put everything inside the tag.
What I want achieve:
Copy a text string with a click on the "COPY" button.
>>what I want to achieve
I've spent a few hours looking for solutions but still can't find related info. Any help would be greatly appreciated. Thank you!
Your script can have more than one html file, and per the HTML Services: Best Practices, you should have your HTML, CSS and (client side) Javascript in separate files. So in your case your index.html file will be all the HTML code and will have a couple lines added. It could start as shown below:
<!DOCTYPE html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.4.0/clipboard.min.js"></script>
<?!= include('myCSS'); ?>
<title>Give it a Title</title>
</head>
<body>
...
All the Body stuff
...
</body>
<?!= include('myScript'); ?>
</html>
At the top of this is a line to include clipboard JS from a hosted location. I found that via a web search for clipboard.js. This is where I get access to the clipboard.js library There is a line right underneath this:
<?!= include('myCSS'); ?>
In a server side file (.gs file) I have the following so that I can include other HTML files from the one I load in my doGet() function:
function include(filename) {
return HtmlService.createTemplateFromFile(filename).evaluate()
.getContent();
}
I am loading the HTML in my doGet using this code to use Templated HTML:
function doGet(passed) {
if(passed.parameter.festival && passed.parameter.year){
passedParameter = passed.parameter.festival + ' ' + passed.parameter.year;
}
var result=HtmlService.createTemplateFromFile('index').evaluate()
.setTitle('My Title')
.setWidth(1285)
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return result;
}
Under the File pull-down you create a new HTML file called myCSS and add your CSS there:
<style>
h1 {
color: #0F6B5E;
font-size: 300%;
text-align:center;
vertical-align: middle;
font-family: 'Raleway', sans-serif;
font-weight:bold;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
</style>
Create a new HTML file called myScript and add the screipt you want used in your HTML page here. This is the Client Side script as opposed to SErver Side script, which is all in the Script files. (HTML files will show the .html extension in the list of files while server side Script files will have .gs) If your calculateWeight() function is used to calculate and display items in the HTML page, then place it in this file:
<script>
//Script to load after the page has loaded
$(function() {
google.script.run.withSuccessHandler(showMenuYear).withFailureHandler(loadFailed).getDropDownContent();
});
calculateWeight() {
//code goes here
}
function showMenuYear(menuItems) {
var list = $('#optionListYear');
var desiredValue = '<?!= passedParameter ?>';
list.find('option').remove(); // remove existing contents
list.append('<option value="-1">Select a Festival and Year</option>');
for (var i = 0; i < menuItems.length ; i++) {
list.append('<option value=' + menuItems[i].sheetrow + '>' + menuItems[i].fullFestival + '</option>');
if (menuItems[i].fullFestival === desiredValue){
list.val(menuItems[i].sheetrow);
}
}
setFormList();
}
function setFormList() {
// alert('In setFormList ');
// alert($('#optionListYear').val());
var replacement = document.getElementById("OverallGrid");
replacement.innerHTML = "Retrieving Registrations...";
if ($('#optionListYear').val() === "-1") {
// if(passedData.year && passedData.festival){replacement.innerHTML = passedData.festival & " " & passedData.year;};
replacement.innerHTML = "Select a Festival/Year above.";
return;
}
google.script.run.withSuccessHandler(showRegistrationsTable).withFailureHandler(loadFailed).getValidRegistrations($('#optionListYear').val());
}
function loadFailed(error){
var replacement = document.getElementById("OverallGrid");
var displayMessage = "Error loading data: " + error.name + ' ' + error.message;
if (error.message.includes("is missing (perhaps it was deleted?)") ) {
displayMessage = "You do not have access to these registrations."
}
replacement.innerHTML = displayMessage;
}
</script>
In this code, the lines starting with google.script.run will run a Server Side function, passing a variable to the function if needed. If Successful, the Client side function defined in withSuccessHandler(successFunction) will be used with any returned data being passed. So in my example the showMenuYear(menuItems) function is run on the Client side with menuItems being set to the returned value from the Server side function getDropDownContent(). If the Server side returns an error, the loadFailed(error) function is executed. This all comes from the line:
google.script.run.withSuccessHandler(showMenuYear).withFailureHandler(loadFailed).getDropDownContent();

Google App Script Bounded to Spreadsheet

what I' trying to accomplish is a Google Spreadsheet for a project management. I've got lots of cells in a grid where a user should select either the item was completed or not. Now this spreadsheet would be available only to a Project Manager. The way I imagined the process would work was that Project Manager selects particular cells and assigns them to a technician's email address. Script would then generate mobile friendly html UI and send it to the technician (I thought of Google forms but I want to create more customized UI). Technician would then select a checkbox after completing a task which would at the same time update the spreadsheet. Next time technician would open the UI it would populate all the checkboxes that previously were selected.
The only way I've found that I could make it work was a google script web app bounded to a spreadsheet. I've created a test HTML file and .gs file:
.html file
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<h1> Web App Test </h1>
<input type="button" value="Click Me" id="buttonclicked" onclick="getSomeData()"/>
<div id="output" class="current">output</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
function getSomeData()
{
google.script.run
.withSuccessHandler(onSuccess)
.withFailureHandler(showError)
.testForWebApp();
myLog("in WebAppTest.html getSomeData()");
}
function onSuccess(testParam)
{
var div = document.getElementById('output');
if (sectionName == null)
div.innerHTML = "<p style='color:red;'>You didn't hit the script</p>";
else
div.innerHTML = "<p style='color:white;'>" + testParam + "</p>";
}
function showError()
{
var div = document.getElementById('output');
div.innerHTML = "<p style='color:red;'>You didn't hit the script</p>";
}
</script>
</body>
and .gs file:
function doGet()
{
return HtmlService.createHtmlOutputFromFile('WebAppTest')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function testForWebApp()
{
myLog("In testForWebApp()");
var msg = "Yep you hit the script!";
return msg;
}
function myLog(log)
{
//log = 'test';
Logger.log(log);
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('log');
var lastRow = sheet.getLastRow();
sheet.insertRowBefore(1);
var newLogDateRange = sheet.getRange(1, 1);
var newLogTextRange = sheet.getRange(1, 2);
var now = new Date();
newLogDateRange.setValue(now);
newLogTextRange.setValue(log)
}
When I published the app and followed the generated link I saw my html page with a Click Me button. The click event ran the getSomeData() function which called google.script.run function. The server side .testForWebApp() gotten executed because I've gotten a log entry from myLog() but the .withSuccessHandler or .withFailureHandler were never called. At the same time the myLog() that should be executed after google.script.run never run either.
I definitely don't understand how it works and suspect that if I publish a script as a web app the HTML is not bounded to the script anymore, but I couldn't find any information about it online.
Thanks for your help.
Firstly, you cannot call server-side myLog() function from your client side javascript unless you call it using google.script.run.myLog() Therefore
myLog("in WebAppTest.html getSomeData()");
in your getSomeData() doesnt log anything in your google sheet
Secondly, this code in function onSuccess(testParam)
if (sectionName == null)
is causing your function to terminate prematurely, since there is no variable called sectionName defined.
Note: You can monitor all these errors in the console of your web browser.
Below is the modified code that should work as you intend it to
Final code:
Web App Test
output
function getSomeData()
{
google.script.run
.withSuccessHandler(onSuccess)
.withFailureHandler(showError)
.testForWebApp();
console.log("in WebAppTest.html getSomeData()"); //Log it on the browser console
}
function onSuccess(testParam)
{
var div = document.getElementById('output');
if (testParam == null) // Changed it to testParam from sectionName, to check the value returned from testWebApp()
div.innerHTML = "<p style='color:red;'>You didn't hit the script</p>";
else
div.innerHTML = "<p style='color:black;'>Success:" + testParam + "</p>";
}
function showError()
{
var div = document.getElementById('output');
div.innerHTML = "<p style='color:red;'>You didn't hit the script</p>";
}
Edit
One last note, the below code would make the return text invisible as the text and background color would be the same color (white):
div.innerHTML = "<p style='color:white;'>Success:" + testParam + "</p>";
hence changed the text color to black in the final code
Hope that helps!
Try redeploying the web app, but under a new project version.

onPreCreate with Owner pulled from external source

I am in the process of trying to create a custom HTML app in Rally to have a User Story created through the Add New component and drawing on data from an external source using JQuery with YQL JSON query.
This process works a wonder for pre-filled name, description and notes. However, the only way at the moment Owner works pre-filled is using an Object Dropdown to manually select the user. I want to be able to pull the Owner from the same external source.
Presently this is dummy code to test the theory:
var statement = "select * from html where url='" + value + "' and xpath='//h1'";
document.getElementById('statement').innerHTML = statement;
$.queryYQL(statement, "json", function (data) {
var item = data.query.results.h1;
for(var i=0;i<item.length;i++){
title = item[i].content;
style = item[i].style;
output += "<h3>"+title +"<br />"+ style +"</h3>";
}
document.getElementById('results').innerHTML = output;
});
function onAddNewPreCreate(addNew, eventArgs) {
eventArgs.item["Name"] = title;
eventArgs.item["Description"] = output;
eventArgs.item["Notes"] = style;
eventArgs.item["Owner"] = user;
}
The 'value' variable is set via a textbox where the user can input the URL of where they want to grab the external data from.
The user variable is set via the dropdown. I have tried replacing the user variable with the exact same display name as the user in Rally such as eventArgs.item["Owner"] = "User Name"; but this results in a blank for the Owner of the User Story when created.
Any ideas on how this may be achieved?
Since Users are objects in Rally, you cannot set an Artifact's Owner attribute to be the string of a Rally username, rather, you must set the Owner to be a Reference to a valid Rally User, in the form of a ref: /user/12345678910 where the long integer is the Object ID of the User of interest. You can use the rallyDataSource and AppSDK to do a query on the string value of the Rally User Name, and obtain the needed ref.
I've included a basic example that illustrates the idea of taking an e-mail formatted User Name, and querying Rally for the reference to the needed User object. The example uses a simple DOM <select> component to simulate an "external" source of username data (in your case populated via JQuery with YQL JSON). The examples does this in lieu of the AppSDK ObjectDropdown, which although the simplest way to accomplish this, as you note doesn't suit your needs since you are polling an external source as the source of your user-selector.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Copyright (c) 2011 Rally Software Development Corp. All rights reserved -->
<html>
<head>
<title>Component Example: Add New User Story, &quotExternal&quot User Chooser</title>
<meta name="Name" content="Component Example: Add New User Story, 'External' User Chooser" />
<meta name="Version" content="2012.1" />
<meta name="Vendor" content="Rally Labs" />
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.26/sdk.js"></script>
<script type="text/javascript">
// Global variables to store Reference to selected User
var userRef = null;
var rallyDataSource;
var getUserRef = function(results) {
var user = results.users[0];
userRef = user._ref;
};
function userSelectChanged() {
var userChooser = document.getElementById("userChooser");
var strUser = userChooser.options[userChooser.selectedIndex].value;
queryString = '(UserName = "' + strUser + '")';
var userQueryConfig = {
type : 'user',
key : 'users',
fetch: 'UserName,DisplayName,Role',
query: queryString
};
rallyDataSource.findAll(userQueryConfig, getUserRef);
}
function onAddNewAdd(addNew, eventArgs){
var createdItem = eventArgs.item;
var createdFormattedId = createdItem.FormattedID;
alert("Created new User Story with Formatted ID: " + createdFormattedId);
}
function onAddNewPreCreate(addNew, eventArgs)
{
// Grab Rally ref of User selected in HTML dropdown
// set it as Owner attribute of created User Story
eventArgs.item["Owner"] = userRef;
}
function onLoad() {
rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
var addNewConfig = {
types : ["HierarchicalRequirement"]
};
// Populate userRef from Rally for default selected user:
userSelectChanged();
var addNew = new rally.sdk.ui.AddNewArtifact(addNewConfig, rallyDataSource);
addNew.addEventListener("onAdd",onAddNewAdd);
addNew.addEventListener('onPreCreate', onAddNewPreCreate);
addNew.display("addNewDiv");
}
rally.addOnLoad(onLoad);
</script>
</head>
<body>
<div id="addNewDiv"></div>
<div id="userChooserDiv">
Select a Rally User as Story Owner:
<select id="userChooser" onChange="userSelectChanged()">
<option selected value="user1#company.com">user1#company.com</option>
<option value="user2#company.com">user2#company.com</option>
<option value="user3#company.com">user3#company.com</option>
</select>
</body>
</html>

Categories

Resources