I'm trying to design a template that generates a document based on the following Diagram.
For each System (1 or 2) there is a Chapter, which will be further populated with subchapters for every "Element type C".
Example of chapter structure
The template I'm using is this one:
And it calls a table:
While scripting the fragment of this, for each element type C, I'm checking the connection type ( connection Y) to see if the element is related and can be added to the bottom half of the table. If so, the ID of element Type B is added to an XML structure.
The code I'm using is the following:
function arrange_data_in_xml(objectid) {
//Get the repository type
var repotype = Repository.RepositoryType();
//Create the xml structure
var xmlDOM = new COMObject("MSXML2.DOMDocument.6.0");
xmlDOM.validateOnParse = false;
xmlDOM.async = false;
var node = xmlDOM.createProcessingInstruction("xml", "version='1.0' encoding='ISO-8859-1'");
xmlDOM.appendChild(node);
var xmlRoot = xmlDOM.createElement("EADATA");
xmlDOM.appendChild(xmlRoot);
var xmlDataSet = xmlDOM.createElement("Dataset_0");
xmlRoot.appendChild(xmlDataSet);
var xmlData = xmlDOM.createElement("Data");
xmlDataSet.appendChild(xmlData);
var part1A = Repository.GetElementSet(sqlquery, 2);
//Session.Output(part1A.Count)
//This cycle will iterate over each Element Type B
for (var i = 0; i < part1A.Count; i++) {
var ElementTypeBrow = ""
var countElementTypeB = 0;
Session.Output("DEBUG 0 " + part1A.GetAt(i).ElementID + " -- " + part1A.GetAt(i).Name + " -- " + objectid)
var xmlRow = xmlDOM.createElement("Row");
xmlData.appendChild(xmlRow);
var xmlName = xmlDOM.createElement("Object_ID");
xmlName.text = part1A.GetAt(i).ElementID;
xmlRow.appendChild(xmlName);
var xmlName = xmlDOM.createElement("ElementTypeCName");
xmlName.text = part1A.GetAt(i).Name;
xmlRow.appendChild(xmlName);
for (var k = 0; k < part1A.GetAt(i).TaggedValues.Count; k++) {
var tv = part1A.GetAt(i).TaggedValues.GetAt(k);
if (tv.Name == 'Proprety X') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue1");
xmlName.text = tv.Value;
xmlRow.appendChild(xmlName);
} else if (tv.Name == 'Proprety Y') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue2");
xmlName.text = tv.Value;
xmlRow.appendChild(xmlName);
}
}
for (var j = 0; j < part1A.GetAt(i).Connectors.Count; j++) {
var connector = part1A.GetAt(i).Connectors.GetAt(j);
if (connector.Stereotype == 'Connection type Z') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue3");
xmlName.text = Repository.GetElementByID(connector.SupplierID).Name;
xmlRow.appendChild(xmlName);
} else if (connector.Stereotype == 'Connection type Y') {
var xmlName = xmlDOM.createElement("ElementTypeC.TagValue4");
xmlName.text = Repository.GetElementByID(connector.ClientID).Name;
xmlRow.appendChild(xmlName);
} else if (connector.Stereotype == 'Connection type X'') {
var ElementTypeB = Repository.GetElementByID(connector.SupplierID)
//Check if the ElementTypeB is connected to the current interface
if (check_interface(ElementTypeB.ElementID) == objectid) {
//Session.Output("DEBUG 1 " + part1A.GetAt(i).Name + " - " + ElementTypeB.Name)
var ElementTypeBalias = ""
if (ElementTypeB.Alias != "") {ElementTypeBalias = " (" + ElementTypeB.Alias + ")"}
ElementTypeBrow = ElementTypeB.Name + ElementTypeBalias + " \n" + ElementTypeBrow
countElementTypeB = countElementTypeB + 1
}
}
}
//Session.Output("DEBUG 1 " +ElementTypeBrow + " - " + countElementTypeBs + " - " + ElementTypeB.Name)
var xmlName = xmlDOM.createElement("ApplicableElementTypeB-Hyperlink");
if (countElementTypeBs > 1) {
xmlName.text = ElementTypeBrow.trimStart();
} else {
xmlName.text = ElementTypeB.ElementGUID+ElementTypeBrow;
}
xmlRow.appendChild(xmlName);
}
return xmlDOM.xml;
}
The problem that I'm having now is the result list of elements is taken as one, ie all of the elements of the bottom half of the table are as one.
Is there a way to manipulate each element individually (for example create a hyperlink for each entry)?
I've tried to rearrange the XML stucture. But the problem remains.
Fragments like this expect there contents in the form of a table, with rows and columns.
Currently you are only returning a single row, but somehow you would like to split the different values for ElementTypeBName-Hyperlink into different rows.
I think you have two possibilities here:
Return each ElementTypeBName-Hyperlink element with a different name e.g. ElementTypeBName-Hyperlink1, ElementTypeBName-Hyperlink2,... and then use each of those in your table template.
Downside of this approach is that it isn't flexible at all, and only useful if you have more or less the same number of ElementB names.
Split your template into two templates. One template for the upper part, and one for the lower part.
Another observation is that you are taking the complicated (and slow) route. For requirements like this, it's much easier to create an SQL template instead of a script template.
Related
I need to take data from a basic excel form and paste it on a data table as many times as one of the cells form the form says.
This is the form:
Form
I've tried this:
function COPIARPEGAR() {
var Libro = SpreadsheetApp.getActiveSpreadsheet();
var Form = Libro.getSheetByName("Form")
var CON = Form.getRange('J18').getValue();
var Disciplina = Form.getRange('J20').getValue();
var Masculino = Form.getRange('L22').getValue();
var TituloMasculino = Form.getRange('L20').getValue();
var Femenino = Form.getRange('N22').getValue();
var TituloFemenino = Form.getRange('N20').getValue();
var BBDD = Libro.getSheetByName("BBDD2");
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length
for(var filamasc=UltimaFila+1;filamasc<=Masculino+1;filamasc++) {
BBDD.getRange(filamasc,1).setValue(Disciplina)
BBDD.getRange(filamasc,2).setValue(CON)
BBDD.getRange(filamasc,3).setValue(TituloMasculino)
for(var filafem=UltimaFila+1;filafem<=Femenino+1;filafem++) {
BBDD.getRange(filafem,1).setValue(Disciplina)
BBDD.getRange(filafem,2).setValue(CON)
BBDD.getRange(filafem,3).setValue(TituloFemenino)
}
Logger.log(UltimaFila);
Logger.log(CON);
Logger.log(Disciplina)
}
And as result I always get the smaller number overwrited by the largest number like this:
result
Thanks for yur help!
Your loops are the issue in that you aren't starting at the same rows. Consider running your code in debug mode so you can see your variables value on the right hand part of the screen (such as UltimaFila = 1). I looked at your code, and I think this would work with modifications, but again look at your variables on the right side of your code, and run in debug mode.
function COPIARPEGAR() {
var Libro = SpreadsheetApp.getActiveSpreadsheet();
var Form = Libro.getSheetByName("Form")
var CON = Form.getRange('J18').getValue();
var Disciplina = Form.getRange('J20').getValue();
var Masculino = Form.getRange('L22').getValue();
var TituloMasculino = Form.getRange('L20').getValue();
var Femenino = Form.getRange('N22').getValue();
var TituloFemenino = Form.getRange('N20').getValue();
var BBDD = Libro.getSheetByName("BBDD2");
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length;
//Updated the ending point
for (var filamasc = UltimaFila + 1; filamasc <= Masculino + 1 + UltimaFila; filamasc++) {
BBDD.getRange(filamasc, 1).setValue(Disciplina)
BBDD.getRange(filamasc, 2).setValue(CON)
BBDD.getRange(filamasc, 3).setValue(TituloMasculino)
}
//See the starting points change
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length
//Updated the ending point
for (var filafem = UltimaFila + 1; filafem <= Femenino + 1 + UltimaFila; filafem++) {
BBDD.getRange(filafem, 1).setValue(Disciplina)
BBDD.getRange(filafem, 2).setValue(CON)
BBDD.getRange(filafem, 3).setValue(TituloFemenino)
}
Logger.log(UltimaFila);
Logger.log(CON);
Logger.log(Disciplina)
}
How To Debug Your Code
I have an import task that parses a huge .dat file as an Aspose Workbook.
This was the original code:
public static List<QueryResult> GetAsposeExcelDocumentWithSheetIndex(string filename, string propertyNames, int sheetIndex = 0, int skipRows = 0, int columnToScanForValidEntries = 0, Stream stream = null)
{
Sitecore.Diagnostics.Log.Info("Begin GetAsposeExcelDocumentWithSheetIndex: Filename: " + filename, typeof(UploadHelper));
var loadOptions = new Aspose.Cells.LoadOptions(LoadFormat.Excel97To2003);
if (filename.EndsWith(".xlsx"))
{
loadOptions = new Aspose.Cells.LoadOptions(LoadFormat.Xlsx);
}
else if (filename.EndsWith(".dat") || filename.EndsWith(".csv"))
{
loadOptions = new Aspose.Cells.LoadOptions(LoadFormat.CSV);
}
//var fsStats = new StreamWriter(HttpContext.Current.Server.MapPath("/_uploads/ftp/import.txt"), false);
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Opening file: " + filename);
//fsStats.Flush();
loadOptions.ParsingFormulaOnOpen = false;
try
{
var workbook = stream != null ? new Workbook(stream: stream, loadOptions: loadOptions) : new Aspose.Cells.Workbook(filename, loadOptions);
Worksheet worksheet = workbook.Worksheets[sheetIndex];
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Opened sheet");
//fsStats.Flush();
var list = new List<QueryResult>();
for (int i = skipRows, loopTo = worksheet.Cells.Rows.Count + skipRows - 1; i <= loopTo; i++)
{
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Reading row: " + i);
//fsStats.Flush();
if (worksheet.Cells.GetCell(i, columnToScanForValidEntries) != null &&
worksheet.Cells.GetCell(i, columnToScanForValidEntries).Value != null)
{
NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;
var obj = new QueryResult();
var propNames = propertyNames.Split(',');
for (int j = 0, loopTo1 = propNames.Length - 1; j <= loopTo1; j++)
{
Cell cellInfo = worksheet.Cells.GetCell(i, j);
if (cellInfo != null)
{
// specific excluded properties
var propName = propNames[j];
var parseAsString = PropNameShouldNeverBeParsedAsDate(propName);
if ((cellInfo.Type == CellValueType.IsDateTime) && !parseAsString && cellInfo.DateTimeValue.Year > 2010 && !cellInfo.Name.StartsWith("X") && !cellInfo.Name.StartsWith("Y") && !cellInfo.Name.StartsWith("AC")) // this second check is bc some dates weren't return as a DateTime type in the Iplot file
{
// Colmun X and Y should NEVER be a date time
obj.Properties.Add(propNames[j], cellInfo.DateTimeValue);
}
else
{
obj.Properties.Add(propNames[j], cellInfo.StringValue);
}
}
else
{
obj.Properties.Add(propNames[j], null);
}
}
list.Add(obj);
}
}
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Done reading");
//fsStats.Flush();
//fsStats.Close();
return list;
}
catch (Exception ex)
{
Sitecore.Diagnostics.Error.LogError("Error GetAsposeExcelDocumentWithSheetIndex:" + ex.ToString() + ex.StackTrace);
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Error: " + ex.ToString());
//fsStats.Flush();
//fsStats.Close();
}
return null;
}
This worked as expected on my local, however the production website is hosted in Germany. The code runs correctly when manually triggered from the admin page (which requires being logged into Sitecore), but when run automatically as a scheduled task, it fails because it's not parsing numbers correctly
public static List<QueryResult> GetAsposeExcelDocumentWithSheetIndex(string filename, string propertyNames, int sheetIndex = 0, int skipRows = 0, int columnToScanForValidEntries = 0, Stream stream = null)
{
//var fsStats = new StreamWriter(HttpContext.Current.Server.MapPath("/_uploads/ftp/import.txt"), false);
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Opening file: " + filename);
//fsStats.Flush();
loadOptions.ParsingFormulaOnOpen = false;
try
{
var workbook = stream != null ? new Workbook(stream: stream, loadOptions: loadOptions) : new Aspose.Cells.Workbook(filename, loadOptions);
Worksheet worksheet = workbook.Worksheets[sheetIndex];
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Opened sheet");
//fsStats.Flush();
var list = new List<QueryResult>();
for (int i = skipRows, loopTo = worksheet.Cells.Rows.Count + skipRows - 1; i <= loopTo; i++)
{
//fsStats.WriteLine(DateTime.Now.ToString("h:mm:ss") + " - Reading row: " + i);
//fsStats.Flush();
if (worksheet.Cells.GetCell(i, columnToScanForValidEntries) != null &&
worksheet.Cells.GetCell(i, columnToScanForValidEntries).Value != null)
{
NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;
var obj = new QueryResult();
var propNames = propertyNames.Split(',');
for (int j = 0, loopTo1 = propNames.Length - 1; j <= loopTo1; j++)
{
Cell cellInfo = worksheet.Cells.GetCell(i, j);
if (cellInfo != null)
{
// specific excluded properties
var propName = propNames[j];
var parseAsString = PropNameShouldNeverBeParsedAsDate(propName);
if ((cellInfo.Type == CellValueType.IsDateTime) && !parseAsString && cellInfo.DateTimeValue.Year > 2010 && !cellInfo.Name.StartsWith("X") && !cellInfo.Name.StartsWith("Y") && !cellInfo.Name.StartsWith("AC")) // this second check is bc some dates weren't return as a DateTime type in the Iplot file
{
// Colmun X and Y should NEVER be a date time
obj.Properties.Add(propNames[j], cellInfo.DateTimeValue);
}
else
{
var value = cellInfo.StringValue;
if (cellInfo.Type == CellValueType.IsNumeric || propName.Contains("NUM_VALUE"))
{
try
{
if (cellInfo.StringValue == "2.074.927" || cellInfo.DoubleValue == 2074927 || cellInfo.DoubleValue == 2074.927)
{
Sitecore.Diagnostics.Log.Info("Value: " + cellInfo.Value.ToString() + " StringValue: " + cellInfo.StringValue + " DoubleValue: " + cellInfo.DoubleValue.ToString(nfi), typeof(UploadHelper));
Sitecore.Diagnostics.Log.Info("Convert.ToDouble Value: " + Convert.ToDouble(cellInfo.Value) + ", " + Convert.ToDouble(cellInfo.Value).ToString(nfi), typeof(UploadHelper));
Sitecore.Diagnostics.Log.Info("DoubleValue: " + (cellInfo.DoubleValue) + ", " + (cellInfo.DoubleValue).ToString(nfi), typeof(UploadHelper));
Sitecore.Diagnostics.Log.Info("StringValue: " + (cellInfo.StringValue), typeof(UploadHelper));
Sitecore.Diagnostics.Log.Info("FloatValue: " + (cellInfo.FloatValue) + ", " + (cellInfo.FloatValue).ToString(nfi), typeof(UploadHelper));
Sitecore.Diagnostics.Log.Info("StringValueWithoutFormat: " + (cellInfo.StringValueWithoutFormat), typeof(UploadHelper));
Sitecore.Diagnostics.Log.Info("IntValue: " + (cellInfo.IntValue), typeof(UploadHelper));
}
if (Convert.ToDouble(cellInfo.Value).ToString() != value)
{
Double val;
if (Double.TryParse(value, System.Globalization.NumberStyles.Any, nfi, out val))
{
Sitecore.Diagnostics.Log.Info("Using value " + val, typeof(UploadHelper));
obj.Properties.Add(propNames[j], val);
}
else
{
Sitecore.Diagnostics.Log.Info("Failed to parse as decimal, using stringValue " + value, typeof(UploadHelper));
obj.Properties.Add(propNames[j], value);
}
}
else
{
Sitecore.Diagnostics.Log.Info("Value as double matches StringValue", typeof(UploadHelper));
obj.Properties.Add(propNames[j], Convert.ToDouble(cellInfo.Value));
}
}catch(Exception ex)
{
Sitecore.Diagnostics.Log.Info(ex.Message, typeof(UploadHelper));
obj.Properties.Add(propNames[j], cellInfo.StringValue);
}
}
else
{
obj.Properties.Add(propNames[j], cellInfo.StringValue);
}
}
}
else
{
obj.Properties.Add(propNames[j], null);
}
}
list.Add(obj);
}
}
The reason why I added all the additional code for numeric values is because on the German server, cellInfo.StringValue returns an improperly formatted number as a string - it uses periods instead of commas, so large decimal values end up being returned like 12.703.1005 instead of 12,703.1005.
So, I tried to return cellInfo.DoubleValue instead when the cell is numeric, but that ALSO returns wrong. Some decimals like 12.7 are being interpreted as dates, so cellInfo.DoubleValue is entirely wrong, but cellInfo.StringValue gives me the correct number (as a string). But the one thing that's still not working either as strings or decimals is large numbers that have a comma and a decimal.
In the second block of code you can see all the logging I added in. Here is the output on my local, for parsing a value of 2074.927
27908 10:47:59 INFO Value: 2074.927 StringValue: 2074.927 DoubleValue: 2074.927
27908 10:48:02 INFO Convert.ToDouble Value: 2074.927, 2074.927
27908 10:48:04 INFO DoubleValue: 2074.927, 2074.927
27908 10:48:07 INFO StringValue: 2074.927
27908 10:48:10 INFO FloatValue: 2074.927, 2074.927
27908 10:48:21 INFO StringValueWithoutFormat: 2074.9270000000001
27908 10:48:24 INFO IntValue: 2074
and here is the output on the German server:
ManagedPoolThread #12 15:36:04 INFO Value: 2074927 StringValue: 2.074.927 DoubleValue: 2074927
ManagedPoolThread #12 15:36:04 INFO Convert.ToDouble Value: 2074927, 2074927
ManagedPoolThread #12 15:36:04 INFO DoubleValue: 2074927, 2074927
ManagedPoolThread #12 15:36:04 INFO StringValue: 2.074.927
ManagedPoolThread #12 15:36:04 INFO FloatValue: 2074927, 2074927
ManagedPoolThread #12 15:36:04 INFO StringValueWithoutFormat: 2074927
ManagedPoolThread #12 15:36:04 INFO IntValue: 2074927
On the German server, I don't have a single instance of the correct number. It early strips the decimal place (returning the number several orders of magnitude larger than it should be), or it gives me a string value that has a period instead of a comma, which I cannot parse as a decimal.
Why is the German server messing this up? How can I change my code to parse correctly on the German server? As you can see in the code I'm already trying to use NumberFormatInfo to give me the correct delimiters but it doesn't matter since the DoubleValue is returning with no delimeter to begin with.
#Anshul Samaiyar,
If you could specify your custom formatting, i.e., "## ###.##%" for the given value to the cell in MS Excel manually, you will also get this result ("1231123.%"). So, Aspose.Cells works the same way as MS Excel does. Your custom formatting is not right. Please see the following sample code with (updated) custom formatting and give it a try, it will give you expected results.
e.g.
Sample code:
//Create a new (empty) workbook
Workbook workbook = new Workbook();
//Get the first (default) worksheet
Worksheet worksheet = workbook.getWorksheets().get(0);
//Get A1 cell
Cell cell = worksheet.getCells().get("A1");
//Specify double value
Double dataValue = 12311.23;
dataValue = Double.parseDouble(dataValue.toString());
cell.putValue(dataValue);
//Create a style and set the custom formattings
Style cellStyle = workbook.createStyle();
cellStyle.setCustom("## ###.##\\%");
//Apply the style to the cell
cell.setStyle(cellStyle);
//Autofit column to show all values
worksheet.autoFitColumn(0);
//Save the Excel file
workbook.save("f:\\files\\out1.xlsx");
//Save to PDF file
workbook.save("f:\\files\\out12.pdf");
Hope this helps, you may also post queries in the dedicated forums.
Facing similar issue where
dataValue = 12311.23;
dataValue = Double.parseDouble(dataValue.toString());
cellStyle.setCustom("## ###.##%");
is not getting change to 12 311.23 but getting g converted to 1231123.% any solution for the issue is welcome.
I have a function that stores the coordinates and the name of that chunk, but the problem is that this function gets called everytime new chunks get generated, but the old ones keep being loaded if they are not far. So the result is that in the textfile, the function writes the chunks sometimes 2 times.
I don't want this to happen and have the function only write every chunk once.
The main problem is that I can't use StreamwWriter and StreamReader at the same time.
This is my code:
function saveLoadedChunk() {
var loadedChunks : GameObject[] = FindObjectsOfType(GameObject) as GameObject[];
var fileName = "C:/Reactor Games/chunks.txt";
var sw : System.IO.StreamWriter = new System.IO.StreamWriter(fileName, true);
for (var i = 0; i < loadedChunks.length ; i++) {
if(loadedChunks[i].name.Substring(0,5) == "Chunk" || loadedChunks[i].name.Substring(0,5) == "_TERR") {
if(loadedChunks[i].tag != "Player") {
var xco = loadedChunks[i].transform.position.x;
var yco = loadedChunks[i].transform.position.y;
var zco = loadedChunks[i].transform.position.z;
var stringToWrite = "Chunk (" + xco + ", " + yco + ", " + zco + ")";
sw.WriteLine(stringToWrite);
}
}
}
sw.Flush();
sw.Close();
}
Preamble
I mostly work with C#, so there could be some mistakes in syntax.
Solution
You can store all your chunks in memory set. Inside saveLoadedChunk you are going to update this set and then write it's contents to file:
var chunks: HashSet<Vector3> = new HashSet<Vector3>();
function saveLoadedChunk() {
var loadedChunks : GameObject[] = FindObjectsOfType(GameObject) as GameObject[];
for (var i = 0; i < loadedChunks.length ; i++)
if(loadedChunks[i].name.Substring(0,5) == "Chunk" || loadedChunks[i].name.Substring(0,5) == "_TERR")
if(loadedChunks[i].tag != "Player")
chunks.Add(loadedChunks[i].transform.position);
var fileName = "C:/Reactor Games/chunks.txt";
var sw : System.IO.StreamWriter = new System.IO.StreamWriter(fileName, false);
for (var chunk: Vector3 in chunks) {
var stringToWrite = "Chunk (" + chunk.x + ", " + chunk.y + ", " + chunk.z + ")";
sw.WriteLine(stringToWrite);
}
}
The drawback here is:
That you start with blank chunks set every time app is launched.
You store all the chunks' coords in memory. But I wouldn't say that this is drawback until you have really-really lot of chunks.
In order to solve first problem you need to fill chunks with corrds stored in C:/Reactor Games/chunks.txt once the app is started.
i couldnt do aautocopmlete edit box. i want to take names from another database. i wrote my code to typeahead's value list. but it dont work. i am using same server but different database.anybody help me ? here is my code:
//Getting the view containing a document for each of the employees
var searchView:NotesView = session.getDatabase("servername","test/application name.nsf")
.getView("viewname");
// Creating a Lotus Notes search query. Notice the reference to lupkey!
var query = "(FIELD Ad Soyad CONTAINS *" + lupkey +"*)";
// Creating an array to store hits in
var searchOutput:Array = ["å","åå"];
// Doing the actual search
var hits = searchView.FTSearch(query);
var entries = searchView.getAllEntries();
var entry = entries.getFirstEntry();
//Sort the array manually, since Notes doesn't want to sort them alphabetically
for (i=0; i<hits; i++) {
searchOutput.push(entry.getColumnValues()[0]);
entry = entries.getNextEntry();
}
searchOutput.sort();
// Build the resulting output HTML code
var result = "<ul><li><span class='informal'>Suggestions:</span></li></ul>";
var limit = Math.min(hits,20);
for (j=0; j<limit; j++) {
var name = searchOutput[j].toString();
var start = name.indexOfIgnoreCase(lupkey)
var stop = start + lupkey.length;
//Make the matching part of the name bold
name = name.insert("</b>",stop).insert("<b>",start);
result += "<li>" + name + "</li>";
}
result += "</ul>";
return result;
There are plenty of issues with your code:
the query can't return any result since your field has a space in it
Do you really need an FTSearch to return values and not a sorted view?
the typeahead -as the name suggest- presents values that match left to right and not somewhere substring. If you need that you need to roll your own typeahead function using Ajax
The typeahead function doesn't take a parameter, so your lupkey doesn't go anywhere. The function needs to return all values and XPages will do the matching
Instead of copying one by one into an array for sorting, copy the returning Vector() into a TreeSet(). This is one line, sorts it and removes duplicates
To get it working check this example based on dojo, previously asked here. You will need the REST control
i do it like that
var directoryTypeahead = function (searchValue:string) {
// update the following line to point to your real directory
//var directory:NotesDatabase = session.getDatabase(database.getServer(), "names.nsf");
var directory:NotesDatabase = session.getDatabase(database.getServer(), "org/test.nsf");
var allUsers:NotesView = directory.getView("SVFHP2");
var matches = {};
var includeForm = {
Person: true,
Group: true
}
searchValue = searchValue.replace("I","i")
var matchingEntries:NotesViewEntryCollection = allUsers.getAllEntriesByKey(searchValue, false);
var entry:NotesViewEntry = matchingEntries.getFirstEntry();
var resultCount:int = 0;
while (entry != null) {
var matchDoc:NotesDocument = entry.getDocument();
var matchType:string = matchDoc.getItemValueString("Form");
//if (includeForm[matchType]) { // ignore if not person or group
var fullName:string = matchDoc.getItemValue("Name").elementAt(0) + " " + matchDoc.getItemValue("Title").elementAt(0);
if (!(matches[fullName])) { // skip if already stored
resultCount++;
var matchName:NotesName = session.createName(fullName);
matches[fullName] = {
cn: matchName.getCommon(),
photo: matchDoc.getItemValueString("Photo"),
job: matchDoc.getItemValueString("sum"),
email: matchDoc.getItemValueString("email"),
}
}
// }
/*if (resultCount > 15) {
entry = null; // limit the results to first 10 found
}
else {*/
entry = matchingEntries.getNextEntry(entry);
//}
};
}
I have a WCF RESTful service that returns a complex object with the following format:
{"GetMatterSearchRESTResult":{"BreakDownBypracticeGroups":[],"BreakDownByCountry":[],"TotalMatterCount":0}}.
When I have this value return, I try to access it using the following code below:
if (executor.get_responseAvailable) {
var serviceResults = executor.get_responseData();
var prasevalues = eval('(' + serviceResults + ')');
var mattersResults = prasevalues.GetMatterSearchRESTResult;
for (var a = 0; a < mattersResults.length; a++) {
alert(mattersResults[a].TotalMatterCount);
var pgBreakDown = mattersResults[a].BreakDownBypracticeGroups;
for (var b = 0; b < pgBreakDown.length; b++) {
alert(pgBreakDown[b].DepartmentName + " " + pgBreakDown[b].Count);
}
}
}
return false;
After the eval function called, i get an undefined value. Please help.
GetMatterSearchRESTResult isn't an array, it's an object, so matterResults won't have a length method. Make GetMatterSearchRESTResult an array of objects:
{"GetMatterSearchRESTResult":[{"BreakDownBypracticeGroups":[],"BreakDownByCountry":[],"TotalMatterCount":0}]}
Edit: Or, if that's not possible, you don't need to loop through the object