Where should I be calling the getUserProperties function? - javascript

I'm trying to create a button that, upon clicking, "saves" the positions of multiple lists from a connected-sortable. I want the script to be able to retain the most recent position of each list item when the page is refreshed (i.e. If list 1 starts as A,B,C and I change it to B,A,C and refresh the page, it stays as B,A,C.).
I'm attempting to accomplish this by creating an array from an html document (published as a web app), save it using the getUserProperities function, and then return it the next time I open the web app.
I am able to log the positions without issue, but I'm having trouble figuring out where to run the getUserProperities function, or what other issue I may be dealing with.
In the console from the web app, I get this error Uncaught TypeError: Cannot read property 'getUserProperties' of undefined at saveList (userCodeAppPanel:4) at HTMLButtonElement.onclick (userCodeAppPanel:1).
Where should I be calling the getUserProperties function? From code.gs or index.html? I have been working off the example provided HERE.
The relevant portions of my code, from index.html are below.
<script>
$( function() {
$( "#myList, #flight1a, #flight1b, #flight2a, #flight2b, #flight3a, #flight3b, #sortable2" ).sortable({
connectWith: ".connectedSortable",
update: function(event, ui) {
var changedList = this.id;
var order = $(this).sortable('toArray');
var positions = order.join(';');
console.log({
id: changedList,
positions: positions
});
}
})
});
</script>
<script>
function saveList() {
google.script.run.PropertiesService.getUserProperties().setProperty('myProperty', JSON.stringify(positions));
var returnedObj = PropertiesService.getUserProperties("myProperty");
returnedObj = JSON.parse(returnedObj);
}
</script>
</head>
<body>
<button onclick="saveList()">Click me</button>

Properties Service can only be accessed through Google Apps Script, so it must be called in one of your *.gs files. To execute a server-side function, you need to use google.script.run (there's also a guide available).
For example, in your code.gs file add this function:
function savePositions(propertyName, value) {
PropertiesService.getUserProperties().setProperty(propertyName, value);
}
Then, in your index.html file modify saveList() to:
function saveList() {
google.script.run.savePositions("myProperty", JSON.stringify(positions));
}

google.script.run could be used to call a server side function not to call directly the Properties Service.
For further details see https://developers.google.com/apps-script/guides/html/reference/run

Related

How to use the Firebase real time database for web application

In my website I'm Showing my database after user has given the database name, Is there any way I can constantly update the web shown databasebase without refreshing the page . I've tried using setInterval but it's not working for some reason .
function c(){
setInterval(beta, 1000);
}
function beta(){
var d = document.getElementById("opopo").value;
var firebaseRefff= firebase.database().ref('LOCATION/'+d);
firebaseRefff.on('child_added', snap=> {
var slot=snap.getKey();
var alloted=snap.child("ALLOTED").val();
var date=snap.child("DATE").val();
var limit=snap.child("LIMIT").val();
var time=snap.child("TIME").val();
$("table tbody").append(""+slot+""+alloted+""+date+""+limit+""+time+"Null");
});
}
You do not need, and should not use, setInterval to trigger the queries. What you have in your beta() function looks pretty good.
firebaseRefff.on('child_added', snap => {}) means "whenever a child is added under this location, trigger the callback function (empty in my example) with the parameter 'snap'". It will also be called once, initially, for each child that is already at that database reference location.
You need to make sure you've called beta() once to setup this trigger.
If you're still having problems, you might want to insert logging to make sure beta() is being called, what the full reference path is, if the callback is ever triggered, and if your jquery string is correct.

I am stuck getting a JSON return from the Linkedin API

I am using the RESTFUL API request. Here is my code:
$(document).ready(function(){
var LinkedinAuth = "https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=75rsv9vpa1ixv3&redirect_uri=https%3A%2F%2Fmattobra.github.io/page.html&state=987654321&scope=r_basicprofile"
$(button).click(function(){
LinkedinAuth
})
var start = function(){$.getJSON("https://api.linkedin.com/v1/people/~:(id,first-name,skills,educations,languages,twitter-accounts)?format=json", function(data){console.log(data)})
}
I have the user log in. And then it brings them to the next page. however, the json never gets returned.
I don't see you calling the start() function anywhere in your code. You only declare it. I think you should put it inside the button click function.

Modify dynamic element after script completes

I'm relatively new to JavaScript, so please bear with me.
I run an instance of the Blackboard Learn LMS. Feel sorry for me later. Blackboard displays different modules to end users to show different pieces of information. The Announcements module contains non-editable code that sends an Ajax request to display all system-wide and course-specific announcements for that particular user:
<div id="Announcements">
<div id="div_1_1"> </div>
<script type="text/javascript">
Event.observe(window, 'load', function () {
new Ajax.Request('/webapps/portal/execute/tabs/tabAction', {
method: 'post',
parameters: 'action=refreshAjaxModule&modId=_1_1&tabId=_2830_1&tab_tab_group_id=_155_1',
onSuccess: function (transport) {
try {
var res = transport.responseXML.getElementsByTagName('contents')[0].firstChild.nodeValue;
$('div_1_1').innerHTML = res.stripScripts();
page.globalEvalScripts(res, true);
} catch (e) {
$('div_1_1')
.innerHTML = 'Module information is temporarily unavailable. Please reload the page. <!--' + e.toString()
.escapeHTML()
.gsub('-', '-') + '-->';
}
},
onFailure: function (transport) {
$('div_1_1').innerHTML = 'Error loading module.';
}
});
});
</script>
</div>
The module brings up a lot of redundant information that I'd like to hide. Since there's no way to edit that particular code, I've been trying to figure out a way to do one of the following:
Modify the module's contents with additional scripting from another source on the page.
Copy the module's contents to a new, editable module, and display that one instead,
Both methods have proven impossible because the script in the Announcements module only runs once the page has loaded entirely, so there's no way to run a script afterward or wait until the process has completed.
Any ideas on how I might be able to modify the contents without editing its code directly?
I ended up using the DOMSubtreeModified event:
<script type="text/javascript">
$j = jQuery.noConflict();p
$j("#div_1_1").on("DOMSubtreeModified", function () {
var div = document.getElementById("div_1_1");
var inner = div.innerHTML;
inner = inner.substring(
inner.indexOf("<!-- Display course/org announcements -->")
);
div.innerHTML = inner;
});
</script>

Get Javascript variable in Template play framework 1.2.6

I need to get a javascript variable in my template ( play framework 1.2.6) :
#{extends 'main.html' /}
#{set title:'My Resa V.1' /}
<div id="content">
<div id="draggable" class="ui-widget-content">
<p>Drag me around</p>
</div>
<div id="circle"> <center>table 1</center></div>
</div>
<script>
$(function() {
$( "#draggable" ).draggable();
$( "#circle" ).draggable({
stop: function(event, ui) {
var circle = $(this).position();
var position= circle.top;
}
});
});
</script>
I want to get var position= circle.top;. Thanks
The main reason of your problem is that the play template engine is executed on a server side, and the javascript code is executed at the client side (i.e. into the web browser).
So if you want to add variable from the server state (from java), you should "write" (inject) your javascript code at server side, so it will be present when the page will load to the client, and thus can be executed there.
In order to do this, first you need to send your circle variable from the controller to the view using the following code:
Circle circle=getYourCircle();
render("path/to/your/view",circle);
Next, in your view file just replace the line where the position is initialized:
var position= ${circle.top};
Again, the ${} expression will be evaluated on the server and the value will be written into the body of the response that will be returned to the client. So, in this case if your circle has value for its top property equal to 40, the browser will get:
var position= 40;
for the corresponding line.
For the other way around (i.e. reading a javascript variable in the template) is not possible, unless you make a request to the server (for instance by using some of the jQuery.ajax variants), and send the value of the javascript variable.
The request should be accepted by a controller, and the value for the variable should be delegated to the view (same procedure as in the first code snippet). Even then the play template engine will be able to access the "javascript" variable (which now is request scope variable) and make additional transformations to it.
I hope this helps :)
thanks! I finally used Ajax mechanism:
...
var allPosition='';
for (var m in map){
allPosition+= m +'-' + map[m].top + '-' + map[m].left+'/';
}
var updateUserRoute = #{jsRoute #Application.saveDisposition() /}
...
function callAjax(updateUserRoute,allPosition){
$.ajax({
url: updateUserRoute.url(),
type: updateUserRoute.method,
data:{ positionTables: allPosition}
});
//.done(function( msg ) {
// alert( "disposition des tables sauvegardé" );
// });
}

Need to change the function name in JS, trying to keep it from breaking

I'm no javascript guru, I'm having to call an external JS file twice in one page. The JS file includes a function. Having this function called twice (once in each JS include) breaks the functionality. So I thought I'd modify the 2nd instance to a different function name. This works to allow the first instance to work correctly but breaks the 2nd one (The one with the function changed).
The function name is address and I'm trying to work just exactly what else needs to be modified in this script to reflect the name change. I fear there are other mentions of "address" that is legitimate and not associated with the function name. I'm at my wits end and am just not sure. Anyone care to look at this JS and help me find which instances of the word address need to be changed to correctly reflect the one function and var name?
/**
* execute part
*/
$(document).ready(function(){
address.bindZipcodeFind();
});
var address = {
bindZipcodeFind: function(){
$('.zipcode-searcha').click(function(){
$('.zipcode-search-resulta').text("로딩중...");
$.get('http://www.nuvonoir.com/postalcode2/zipsearch-action.php',{
query: $('#dongNamea').val()
},function(data){
$('.zipcode-search-resulta').html(data);
address.bindPutAddress();
})
});
},
bindPutAddress: function(){
$('.zipcode-search-resulta a').click(function(){
$('[id=zipcode1a]').val($(this).parent().parent().find('.postcd1').text());
$('[id=zipcode2a]').val($(this).parent().parent().find('.postcd2').text());
$('[id=OrdAddra]').val(address.remove_useless_addr($(this).parent().parent().find('.address').text()));
address.hideZipcodeFinder();
$('[name=addr]').focus();
return false;
});
},
remove_useless_addr: function(address){
if(address.indexOf('~') != -1){
address = address.split(' ').slice(0,-1).join(' ');
}
return address;
},
hideZipcodeFinder: function(){
$('.zipcode-findera').slideUp();
}
}
If you have no way to mitigate including code twice, then there's the only option: write that function was called elsewhere:
global variable
invisible element with certain id
or even more magic things:
field in document object or document root node (html/body)
location hash (URL part after #)
cookie/sessionStorage based on document.lastModified (it is equal to page generating time on server) or anything remaining stable within one page load.
Example using global variable:
function once() {
if (window.myOnceFuncIsCalled) return;
// do the main work
window.myOnceFuncIsCalled = true;
}

Categories