I am working on an application that loads in "Apps" from a file on the server. At the moment i have to load the apps in a specific order otherwise they will have the wrong positions in the array of positions.
Here is the code to help explain what i mean.
function getFacebook() {
var appname = "facebooka1thd";
$.get("apps/"+appname+"/"+appname+".html", function(data){
$('.AppList').append(data);
$.cookie(appname, 1, { expires : 365 });
checkpositions();
});
};
function checkpositions() {
if ($.cookie('PosApps')){
var Poscookie = $.cookie('PosApps');
var Pos = JSON.parse(Poscookie);
$("#User").css({top:Pos[0].top, left:Pos[0].left});
$("#facebooka1thd").css({top:Pos[1].top, left:Pos[1].left});
$("#youtubea2thd").css({top:Pos[2].top, left:Pos[2].left});
};
};
function getAppPositions() {
var apps = $(".App"),
positions = [];
$.each(apps, function (index, app) {
var positionInfo = $(app).position();
positions.push(positionInfo);
console.log(positionInfo);
});
var setPositions = JSON.stringify(positions);
$.cookie("PosApps", setPositions, { expires : 365 });
};
I would like the code to adapt to the number off apps present and the order in which they are added or removed.
basically i dont have a clue how to get around this -_- I think that most of my code would have to change in-order for this to be possible because at the moment the positions are saved in the order in which the apps are added but that wont help when the user removes one of the apps and also the positions are being set relative to the order of the apps being added.
Any help with this would be great!
I managed to work it out for my self...
function checkpositions() {
if ($.cookie('PosApps')){
var Poscookie = $.cookie('PosApps');
var Pos = JSON.parse(Poscookie);
for (var i = 0; i < Pos.length; i++) {
$("#"+Pos[i][0]).css({top:Pos[i][1].top, left:Pos[i][1].left});
};
};
};
function getAppPositions() {
var apps = $(".App"),
positions = [];
$.each(apps, function (index, app) {
var id = $(app).attr('id');
var positionInfo = [id,$(app).position()];
positions.push(positionInfo);
console.log(positionInfo);
});
var setPositions = JSON.stringify(positions);
$.cookie("PosApps", setPositions, { expires : 365 });
};
All i had to do was make a 2D array with the id of the element before its position and set the CSS using Pos[i][0] for the id and Posi.top/left for the positions. Hope this helps anyone who gets stuck with something like this. Also if you do get stuck with a problem i would recommend going to this site. Their tutorials are really good and are what helped me figure this problem out.
Related
So, Google recently updated Google App Script API and added lots of nice features, however, in the process, they also depreciated LOTS of API. I have been working on a Library Database user interface for the place I work on my college campus, and when I wanted to update my app to the new API, a lot of things broke, and I can't figure out how to make them work again.
What I am trying to do is get a value from a Google Sheets file, and simply put that value in a text box on the web app. Currently I cannot get that work work. In addition, I discovered something that was troublesome, and that is, the debugger seems to not be correct. I know, bold accusation. Let me try to show you.
Code.gs
function doGet(e) {
var html = HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
return html;
}
function searchBooks(searchItem, searchType){
var sI = searchItem;
Logger.log(sI);
var sT = searchType;
Logger.log(sT);
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var ss = sheets[0];
var itemDataRange = ss.getRangeByName("itemInformation");
var selectedItem = null; //the item that will be returned
//var selectedSearch = searchItem;
var titles = sheet.getRange("K2:K9507").getValues(); //get the titles of the items
var authors = sheet.getRange("J2:J9507").getValues(); //get the authors in the sheet
var barcodes = sheet.getRange("B2:B9507").getValues(); //get the barcodes in the sheet
var itemsArray = new Array();
if (sT == '')
{
return null;
}
else if (sT.value == 'Please select type...')
{
var test = "this works";
Logger.log(test);
return selectedItem;
}
else if(sT == 'Barcode')
{
var selectedBarcode = sI;
for(var i = 0; i < barcodes.length; i++) //search for the barcode
{
if(barcodes[i] == selectedBarcode)
{
selectedItem = titles[i];
break; //break immediately because barcodes are not duplicated
}
}
if(selectedItem != null)
{
return selectedItem;
}
else
{
selectedItem = "No book(s) found";
return selectedItem;
}
return selectedItem;
}
}
...
index.html
<script>
function bookSearch()
{
var searchItem = String(document.getElementById('searchItem').value.toLowerCase());
var searchType = String(document.getElementById('searchType').value.toLowerCase());
google.script.run.withSuccessHandler(bookFound).searchBooks(searchItem, searchType);
}
...
function bookFound(selectedItem)
{
document.getElementById("bookResultBox").innHTML = selectedItem;
alert(selectedItem);
}
</script>
When I test this code, and put a search value with the category "Barcodes" selected, I successfully get console logs of the data being brought into the function searchBooks, however the debug console says that the variables sI, sT, searchItems, and searchType are all undefined.
I've also been having trouble trying to figure out the proper API calls to use to search through the spreadsheet (when dealing with stuff like getRangeByName). I think there might be a slightly different way to do this since the big update. I may have had it working before I changed some of the code, although I started changing a lot of it when I was trying to figure out WHY nothing was displaying. When I saw at the "undefined" debug console logs, it scared me a bit. I can't tell if I'm messing up, or the API is messing up.
Any help is much appreciated in advance :)
There's probably an error in your code. It's probably coming from line:
var itemDataRange = ss.getRangeByName("itemInformation");
Your variable ss is not a spreadsheet class, it's a sheet class. You can't get a RangeByName of a sheet class. There is no getRangeByName() method of the Sheet class.
I'd change your code to this:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var itemDataRange = ss.getRangeByName("itemInformation");
If you need to get the first sheet:
var theFirstSheet = ss.getSheets()[0];
I have an interactive UI of elements, and I was encouraged to use divs and spans exclusively, and avoid checkboxes. I have converted the site over to the same functionality, but don't know much about persistence to begin with, but with checkboxes, it seemed approachable given the idea of being 'checked' or 'not checked'. How would I begin to use this approach with tracking each element's visibility?
Here is the page I am trying to implement persistence on.
Previous implementation (not my code, as I am new to JS and persistence) used the following:
// Persistence
//¿¿??
var formvals = {};
var keyval = location.search.replace('?', '').split('&');
$.each(keyval, function () {
var splitval = this.split('=');
formvals[splitval[0]] = splitval[1];
});
$.each($('form')[0].elements, function () {
var key = $(this).attr('name');
if (key && formvals[key]) {
$('#' + key).val(formvals[key]);
} else {
if ($(this).attr('type') == 'checkbox') {
$('#'+key)[0].checked = false;
}
}
});
I would like to know how to use the visibility of the elements to help develop different templates.
I can't find any intros into URL persistence, and Im not quite sure what the previous code does, so any explanation or guidance is greatly appreciated.
If you need more information, please ask, and hopefully you can help send me down the right path.
If URL will be like http://site.com/page.html?id_block_to_click1=1&id_block_to_click2=1 it should work
$(function(){
var formvals = {};
var keyval = location.search.replace('?', '').split('&');
$.each(keyval, function () {
var splitval = this.split('=');
formvals[splitval[0]] = splitval[1];
});
$.each(formvals, function(key,val){
if (val == 1) {
$('#'+key).click();
}
})
});
i need a script that copies all my selected list items to an other (custom) list. I found nice solution for documents:
var context = SP.ClientContext.get_current();
var web = context.get_web();
context.load(web);
var _destinationlib = web.get_lists().getByTitle('DestinationLibrary');
context.load(_destinationlib);
var notifyId;
var currentlibid = SP.ListOperation.Selection.getSelectedList();
var currentLib = web.get_lists().getById(currentlibid);
var selectedItems = SP.ListOperation.Selection.getSelectedItems(context);
var count = CountDictionary(selectedItems);
for(var i in selectedItems)
{
alert('Now copying ' + i);
var currentItem = currentLib.getItemById(selectedItems[i].id);
context.load(currentItem);
var File = currentItem.get_file();
context.load(File);
//Excecuting executeQueryAsync to get the loaded values
context.executeQueryAsync
(
function (sender, args) {
if(File != null) {
var _destinationlibUrl = web.get_serverRelativeUrl() + _destinationlib.get_title() + '/' + File.get_name();
File.copyTo(_destinationlibUrl, true);
notifyId = SP.UI.Notify.addNotification('Moving file…' + File.get_serverRelativeUrl() + 'to' + _destinationlibUrl, true);
//Excecuting executeQueryAsync to copy the file
context.executeQueryAsync(
function (sender, args) {
SP.UI.Notify.removeNotification(notifyId);
SP.UI.Notify.addNotification('File copied successfully', false);
},
function (sender, args) {
SP.UI.Notify.addNotification('Error copying file', false);
SP.UI.Notify.removeNotification(notifyId);
showError(args.get_message());
});
}
},
function (sender, args) {
alert('Error occured' + args.get_message());
}
);
}
I dont know what i have to change to get it working for normal list items. I tried to exchange
var File = currentItem.get_file();
context.load(File);
with
var title = currentItem.get_Title();
context.load(title);
var number = currentItem.get_item('number');
context.load(number);
but it dosnt work. It would be great if somebody can give me a hint what i have to do.
many thx
Fabulus
It looks like that you took code above from here.
Try to be attentively. This code copies selected files (not list items!) to another document library!
For your needs better try to code your own solution. See SharePoint JavaScript Class Library for details. You can have two possible architectures:
Make all work from JavaScript. And the first your step will be addItem method of SP.List.
Make processing of selection on client in JavaScript and call your custom server-side component (may be an application page) for items copying (creating copies in new list of already existed items from initial list.). See this for example.
Also be careful with context.load. It's recommended to write all next code in context.executeQueryAsync. Use Firebug in FF and developer tools in Chrome for debugging your code and to find what is wrong.
I need realtime plotting in javascript, and I came across this:
http://nme.pl/en/2011/01/real-time-graph-using-javascript
This is close to what i want. Now that my javascript understanding is limited, can any guru point me where from this canvas is getting data? Is it taking from any online url? What is that google analytics url about?
The post is old but came up when googling so I thought I'd post some links to more modern solutions.
Rickshaw is getting some good reviews - https://github.com/shutterstock/rickshaw
Smoothie is also getting some good reviews and I've seen it in action - https://github.com/joewalnes/smoothie
HTH
That particular example is getting data from a JavaScript function that generates "random" data. Code is:
// rotating across pseudo-random values array
var Rotator = function() {
var self = this;
self.data = [
16,23,41,38,45,31,29,22,27,22,25,29,32,45,88,30,
26,22,45,23,36,48,99,22,32,26,22,27,5,0,0,3,15
];
self.index = 0;
self.single = function() {
self.index += 1;
if (self.index > self.data.length) {
self.index = 1;
}
return self.data[self.index-1];
};
self.many = function(length) {
var results = [];
for (var i=0;i<length;i++) {
results.push(self.single());
}
return results;
};
};
As mentioned in comments, you can look at Flor or Ext-JS (Sencha).
I'm initiating an email create, by calling the code below, and adding an attachment to it.
I want the user to be able to type in the receipient, and modify the contents of the message, so I'm not sending it immediately.
Why do I get a RangeError the 2nd time the method is called?
(The first time it works correctly.)
function NewMailItem(p_recipient, p_subject, p_body, p_file, p_attachmentname)
{
try
{
var objO = new ActiveXObject('Outlook.Application');
var objNS = objO.GetNameSpace('MAPI');
var mItm = objO.CreateItem(0);
mItm.Display();
if (p_recipient.length > 0)
{
mItm.To = p_recipient;
}
mItm.Subject = p_subject;
if (p_file.length > 0)
{
var mAts = mItm.Attachments;
mAts.add(p_file, 1, p_body.length + 1, p_attachmentname);
}
mItm.Body = p_body;
mItm.GetInspector.WindowState = 2;
} catch(e)
{
alert('unable to create new mail item');
}
}
The error is occuring on the mAts.add line. So when it tries to attach the document, it fails.
Also the file name (p_file) is a http address to a image.
Won't work outside of IE, the user needs to have Outlook on the machine and an account configured on it. Are you sure you want to send an email this way?
I'm trying it with this little snippet, and it works flawlessly:
var objO = new ActiveXObject('Outlook.Application');
var mItm = objO.CreateItem(0);
var mAts = mItm.Attachments;
var p_file = [
"http://stackoverflow.com/content/img/vote-arrow-up.png",
"http://stackoverflow.com/content/img/vote-arrow-down.png"
];
for (var i = 0; i < p_file.length; i++) {
mAts.add(p_file[i]);
}
Note that I left off all optional arguments to Attachments.Add(). The method defaults to adding the attachments at the end, which is what you seem to want anyway.
Can you try this standalone snippet? If it works for you, please do a step-by-step reduction of your code towards this absolute minimum, and you will find what causes the error.
first do mItm.display()
then write mItm.GetInspector.WindowState = 2;
this will work