I'm new to Nativescript (used to be a Corona/Lua developer) and I need to create a function (similar to a RuntimeEventListener in Lua) that constantly gets user location and updates a dashboard with speed and altitude, for example.
My current code gets this info only when a button is pressed (which does not make sense for the kind of app I am trying to build). Question is, how to create and invoke such listener/function?
I am coding in Javascript and below it is my current code:
var Observable = require("data/observable").Observable;
var frames = require("ui/frame");
var orientation = require('nativescript-orientation');
orientation.enableRotation(); // The screen will rotate
console.log(orientation.getOrientation()); // Returns the enum DeviceOrientation value
var dialogs = require("ui/dialogs");
// Get geo coordinates
var geolocation = require("nativescript-geolocation");
if (!geolocation.isEnabled()) {
geolocation.enableLocationRequest();
}
/*
var watchID
watchId = geolocation.watchLocation(
function (loc) {
if (loc) {
console.log("(watchid) Received location: " + loc);
}
},
function(e){
console.log("(watchid) Error: " + e.message);
},
{desiredAccuracy: 3, updateDistance: 10, minimumUpdateTime : 1000 * 20}); // should update every 20 sec according to google documentation this is not so sure.
*/
//variables for the dashboard and the Origin
var originLoc //holds the lat,long of the starting point
var originHeading = "NNW"
var originTime = "0"
var originDistance = "0"
var mySpeed = "0"
var myDuration = "00:00"
var myDistance = "0"
var myAltitude = "0";
var myDirection;
var butAction = "START" //button action when it starts
var fbMeasurement = "imperial";
//Sets the right heading of the compass (if landscape, subtracts 90 degrees)
function headingCompass(args) {
var compassHead = "";
if (args>12 && args<=34) {
compassHead = "NNE";
} else if (args>34 && args<=57) {
compassHead = "NE";
} else if (args>57 && args<=80) {
compassHead = "ENE";
} else if (args>80 && args<=102) {
compassHead = "E";
} else if (args>102 && args<=124) {
compassHead = "ESE";
} else if (args>124 && args<=147) {
compassHead = "SE";
} else if (args>147 && args<=170) {
compassHead = "SSE";
} else if (args>170 && args<=192) {
compassHead = "S";
} else if (args>192 && args<=215) {
compassHead = "SSW";
} else if (args>215 && args<=237) {
compassHead = "SW";
} else if (args>237 && args<=260) {
compassHead = "WSW";
} else if (args>260 && args<=282) {
compassHead = "W";
} else if (args>282 && args<=305) {
compassHead = "WNW";
} else if (args>305 && args<=327) {
compassHead = "NW";
} else if (args>327 && args<=350) {
compassHead = "NNW";
} else {
compassHead = "N";
}
return compassHead;
}
//Gets current location when app starts
var geolocation = require("nativescript-geolocation");
if (!geolocation.isEnabled()) {
geolocation.enableLocationRequest();
}
var location = geolocation.getCurrentLocation({desiredAccuracy: 3, updateDistance: 10, maximumAge: 20000, timeout: 20000}).
then(function(loc) {
if (loc) {
console.log("Current location is: " + loc);
originLoc = loc;
if (fbMeasurement === "imperial") {
myAltitude = parseInt(loc.altitude * 3.28084);
mySpeed = (loc.speed * 2.23694).toFixed(1);
} else {
mySpeed = loc.speed.toFixed(1);
myAltitude = parseInt(loc.altitude);
}
myDirection = headingCompass(loc.direction)
}
}, function(e){
console.log("Error: " + e.message);
});
function createViewModel() {
var viewModel = new Observable();
viewModel.originHeading = originHeading;
viewModel.originTime = originTime;
viewModel.originDistance = originDistance;
viewModel.mySpeed = mySpeed;
viewModel.myDuration = myDuration;
viewModel.myDistance = myDistance;
viewModel.myAltitude = myAltitude;
viewModel.butAction = butAction;
//STARTs
var watchid;
viewModel.onTapStart = function(args) {
if (butAction==="START") {
//change button color to RED
var btn = args.object;
btn.backgroundColor = "#FF0000";
//change button text to "STOP"
this.set("butAction","STOP");
butAction = "STOP";
watchId = geolocation.watchLocation(
function (loc) {
if (loc) {
console.log("Received location: " + loc);
if (fbMeasurement === "imperial") {
myAltitude = parseInt(loc.altitude * 3.28084);
mySpeed = (loc.speed * 2.23694).toFixed(1);
} else {
mySpeed = loc.speed.toFixed(1);
myAltitude = parseInt(loc.altitude);
}
myDirection = headingCompass(loc.direction);
}
},
function(e){
console.log("Error: " + e.message);
},
{desiredAccuracy: 3, updateDistance: 10, minimumUpdateTime : 1000 * 1}); // should update every 20 sec according to google documentation this is not so sure.
} else {
//change button color to GREEN
var btn = args.object;
btn.backgroundColor = "#00FF00";
//change button text to "START"
this.set("butAction","START")
butAction = "START";
if (watchId) {
geolocation.clearWatch(watchId);
}
}
this.set("myAltitude",myAltitude);
this.set("mySpeed",mySpeed);
this.set("myDistance",myDirection);
}
return viewModel;
}
exports.createViewModel = createViewModel;
The watchlocation method is, in fact, a listener and will update your location when it is changed (based on this arguments). However, you will need to use some observable properties to update the info and reuse it where and when needed. Also, keep in mind that in Android the location is sometimes triggered after some distance (in my case approx. 100 steps gave the difference in the fourth sign after the dot).
If you are familiar with MVVM pattern this is the one used on regular basis in NativeScript applications.Here you can find the article for Data Binding in NativeScript.
So basically just execute your watch function (e.g. using loaded event for your Page) and then watch for changes in the Observable model (e.g. create Observable property latitude and use the updated info when and where needed)
e.g.
vm = new Observable();
vm.set("altitude", someDefaultValue);
vm.set("longitude", someDefaultValue);
geolocation.watchLocation(function(loc) {
vm.set("altitude", loc.altitude);
vm.set("longitude", loc.longitude);
console.log(vm.get("altitude")); // Observable model updated
console.log(vm.get("longitude"));
})
Related
The bot replies well when a command is sent.
How do I make the WhatsApp web bot to reply with an image pulled from a URL? I want it to be able to reply with an image pulled from a URL, for example, www.school.com/pic.jpg. On the code if a user text #time it replies with time and Date but I want it to reply with an image.
//
// FUNCTIONS
//
// Get random value between a range
function rand(high, low = 0) {
return Math.floor(Math.random() * (high - low + 1) + low);
}
function getElement(id, parent){
if (!elementConfig[id]){
return false;
}
var elem = !parent ? document.body : parent;
var elementArr = elementConfig[id];
for (var x in elementArr){
var pos = elementArr[x];
if (isNaN(pos*1)){ //dont know why, but for some reason after the last position it loops once again and "pos" is loaded with a function WTF. I got tired finding why and did this
continue;
}
if (!elem.childNodes[pos]){
return false;
}
elem = elem.childNodes[pos];
}
return elem;
}
function getLastMsg(){
var messages = document.querySelectorAll('.msg');
var pos = messages.length-1;
while (messages[pos] && (messages[pos].classList.contains('msg-system') || messages[pos].querySelector('.message-out'))){
pos--;
if (pos <= -1){
return false;
}
}
if (messages[pos] && messages[pos].querySelector('.selectable-text')){
return messages[pos].querySelector('.selectable-text').innerText;
} else {
return false;
}
}
function getUnreadChats(){
var unreadchats = [];
var chats = getElement("chats");
if (chats){
chats = chats.childNodes;
for (var i in chats){
if (!(chats[i] instanceof Element)){
continue;
}
var icons = getElement("chat_icons", chats[i]).childNodes;
if (!icons){
continue;
}
for (var j in icons){
if (icons[j] instanceof Element){
if (!(icons[j].childNodes[0].getAttribute('data-icon') == 'muted' || icons[j].childNodes[0].getAttribute('data-icon') == 'pinned')){
unreadchats.push(chats[i]);
break;
}
}
}
}
}
return unreadchats;
}
function didYouSendLastMsg(){
var messages = document.querySelectorAll('.msg');
if (messages.length <= 0){
return false;
}
var pos = messages.length-1;
while (messages[pos] && messages[pos].classList.contains('msg-system')){
pos--;
if (pos <= -1){
return -1;
}
}
if (messages[pos].querySelector('.message-out')){
return true;
}
return false;
}
// Call the main function again
const goAgain = (fn, sec) => {
// const chat = document.querySelector('div.chat:not(.unread)')
// selectChat(chat)
setTimeout(fn, sec * 1000)
}
// Dispath an event (of click, por instance)
const eventFire = (el, etype) => {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent(etype, true, true, window,0, 0, 0, 0, 0, false, false, false, false, 0, null);
el.dispatchEvent(evt);
}
// Select a chat to show the main box
const selectChat = (chat, cb) => {
const title = getElement("chat_title",chat).title;
eventFire(chat.firstChild.firstChild, 'mousedown');
if (!cb) return;
const loopFewTimes = () => {
setTimeout(() => {
const titleMain = getElement("selected_title").title;
if (titleMain !== undefined && titleMain != title){
console.log('not yet');
return loopFewTimes();
}
return cb();
}, 300);
}
loopFewTimes();
}
// Send a message
const sendMessage = (chat, message, cb) => {
//avoid duplicate sending
var title;
if (chat){
title = getElement("chat_title",chat).title;
} else {
title = getElement("selected_title").title;
}
ignoreLastMsg[title] = message;
messageBox = document.querySelectorAll("[contenteditable='true']")[0];
//add text into input field
messageBox.innerHTML = message.replace(/ /gm,'');
//Force refresh
event = document.createEvent("UIEvents");
event.initUIEvent("input", true, true, window, 1);
messageBox.dispatchEvent(event);
//Click at Send Button
eventFire(document.querySelector('span[data-icon="send"]'), 'click');
cb();
}
//
// MAIN LOGIC
//
const start = (_chats, cnt = 0) => {
// get next unread chat
const chats = _chats || getUnreadChats();
const chat = chats[cnt];
var processLastMsgOnChat = false;
var lastMsg;
if (!lastMessageOnChat){
if (false === (lastMessageOnChat = getLastMsg())){
lastMessageOnChat = true; //to prevent the first "if" to go true everytime
} else {
lastMsg = lastMessageOnChat;
}
} else if (lastMessageOnChat != getLastMsg() && getLastMsg() !== false && !didYouSendLastMsg()){
lastMessageOnChat = lastMsg = getLastMsg();
processLastMsgOnChat = true;
}
if (!processLastMsgOnChat && (chats.length == 0 || !chat)) {
console.log(new Date(), 'nothing to do now... (1)', chats.length, chat);
return goAgain(start, 3);
}
// get infos
var title;
if (!processLastMsgOnChat){
title = getElement("chat_title",chat).title + '';
lastMsg = (getElement("chat_lastmsg", chat) || { innerText: '' }).innerText; //.last-msg returns null when some user is typing a message to me
} else {
title = getElement("selected_title").title;
}
// avoid sending duplicate messaegs
if (ignoreLastMsg[title] && (ignoreLastMsg[title]) == lastMsg) {
console.log(new Date(), 'nothing to do now... (2)', title, lastMsg);
return goAgain(() => { start(chats, cnt + 1) }, 0.1);
}
// what to answer back?
let sendText
if (lastMsg.toUpperCase().indexOf('#HELP') > -1){
sendText = `
Cool ${title}! Some commands that you can send me:
1. *#TIME*
2. *#JOKE*`
}
if (lastMsg.toUpperCase().indexOf('#About') > -1){
sendText = `
Cool ${title}! Some commands that you can send me:
*${new Date()}*`
}
if (lastMsg.toUpperCase().indexOf('#TIME') > -1){
sendText = `
Don't you have a clock, dude?
*${new Date()}*`
}
if (lastMsg.toUpperCase().indexOf('#JOKE') > -1){
sendText = jokeList[rand(jokeList.length - 1)];
}
// that's sad, there's not to send back...
if (!sendText) {
ignoreLastMsg[title] = lastMsg;
console.log(new Date(), 'new message ignored -> ', title, lastMsg);
return goAgain(() => { start(chats, cnt + 1) }, 0.1);
}
console.log(new Date(), 'new message to process, uhull -> ', title, lastMsg);
// select chat and send message
if (!processLastMsgOnChat){
selectChat(chat, () => {
sendMessage(chat, sendText.trim(), () => {
goAgain(() => { start(chats, cnt + 1) }, 0.1);
});
})
} else {
sendMessage(null, sendText.trim(), () => {
goAgain(() => { start(chats, cnt + 1) }, 0.1);
});
}
}
start();
I am having some issues trying to use the console to modify the time remaining on one site.
I want to be able to set the Time remaining to zero to be able to proceed to the next page.
I believe that the issue is that there are multiple things that need to be set in order to proceed to the next page.
See code below, any help you can provide would be appreciated.
var pageLoaded = 0;
var timerStatus = 'pending';
var secondsRemaining = -1;
var secondsElapsed = -1;
var startTicks = 0;
var errorCount = 0;
var estimatedSecondsRemaining = -1;
var zeroTimeCounter = 0;
var intervalIdUpdateBothTimers;
var nonLinearGuid = null;
$(document).ready(function() {
setInterval('AutoSave()', 120000);
intervalIdUpdateBothTimers = setInterval('UpdateBothTimers()', 1000);
if (timerStatus == 'pending') {
var totaltimeclock = document.getElementById('TotalTimeClock');
if (totaltimeclock != null) {
document.getElementById('TotalTimeClock').innerHTML = '-- \: -- \: --';
}
var timeremainingclock = document.getElementById('TimeRemainingClock');
if (timeremainingclock != null) {
document.getElementById('TimeRemainingClock').innerHTML = '-- \: -- \: --';
}
StartTimer();
}
});
function loaded(i,f) {
if (document.getElementById && document.getElementById(i) != null)
{
f();
}
else if (!pageLoaded) setTimeout('loaded(\''+i+'\','+f+')',100);
}
function SuspendTimer() {
UpdateBothTimers();
if (timerStatus == 'active') {
var data = "s=2&cp=" + this.location.pathname + "&nlg=" + GetNonLinearGuid();
timerStatus = 'suspended';
$.ajax({
type: "POST",
url: "/Courses/ajax/CourseData.aspx",
data: data,
success: displayTime,
async: false
});
clearInterval(intervalIdUpdateBothTimers);
}
}
function AutoSave()
{
if (timerStatus == 'active')
{
SaveTime();
}
}
function SaveTime()
{
var data = '';
if (typeof window.IsScormPage === 'undefined')
{
data = "cp=" + this.location.pathname + "&sp=false";
}
else
{
data = "cp=" + this.location.pathname + "&sp=true";
}
data += "&nlg=" + GetNonLinearGuid();
$.ajax({
type: "POST",
url: "/Courses/ajax/CourseData.aspx",
data: data,
success: displayTime,
async: false
});
}
function StartTimer()
{
timerStatus = 'active';
SetNonLinearGuid();
SaveTime();
}
// Sets the nonLinearGuid with the one in the DOM
// the GUID was generated in the server side and
// passed it to the client side (DOM)
function SetNonLinearGuid()
{
var $nonLinearGuid = $("#nonLinearGuid");
if ($nonLinearGuid === undefined)
{
$nonLinearGuid = $("input[name=nonLinearGuid]");
}
if ($nonLinearGuid.length)
{
nonLinearGuid = $nonLinearGuid.val() || null;
window.nonLinearGuid = window.nonLinearGuid || nonLinearGuid;
}
}
function GetNonLinearGuid() {
var nlg = (window.NonLinearGuid || nonLinearGuid),
admin = getQueryStringByName("admin", parent.window.location.href) || "";
if (admin.toLowerCase() == "d3v") {
printNonLinearGuid(nlg);
}
return nlg;
}
function getQueryStringByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
function displayTime(result)
{
if (result.isOk == false)
{
alert(result.message);
}
else
{
var d = new Date();
startTicks = d.getTime();
secondsRemaining = parseInt($(result).find("SecondsRemaining").text());
secondsElapsed = parseInt($(result).find("SecondsElapsed").text());
redirectUrl = $(result).find("RedirectUrl").text();
var suspendTimer = $(result).find("SuspendTimer").text();
var dataNonLinearGuid = "?nlg=" + GetNonLinearGuid();
if (redirectUrl != "") {
location.href = redirectUrl;
}
isError = $(result).find("Error").text();
if (isError == "true")
{
errorCount++;
if (errorCount > 3)
{
logout();
}
}
isOverworked = $(result).find("IsOverworked").text();
if (isOverworked == "true")
{
location.href = "/Courses/MyAccountNonLinear.aspx" + dataNonLinearGuid;
}
if (suspendTimer.length > 0) {
if ($.trim(suspendTimer).toLowerCase() == "true") {
SuspendTimer();
}
}
}
}
function logout()
{
window.top.location.href = "/Courses/loggedout.aspx";
}
function UpdateBothTimers() {
if (timerStatus != 'active') return;
if (secondsElapsed >= 0)
{
UpdateElapsedTimer();
//secondsElapsed++;
}
if (secondsRemaining >= 0) {
UpdateRemainingTimer();
}
if (estimatedSecondsRemaining <= 0 && zeroTimeCounter == 0) {
zeroTimeCounter++;
SaveTime();
}
}
var lang;
function qt(m,lng) {
$('#timeRemaining').css('display', 'none');
setTimeout("$('#EOMQuiz').submit();", m * 1000);
lang = lng;
setTimeout('updateQ('+ m +')', 1000);
}
function updateQ(m) {
--m;
var text;
if (lang == 'es') {
text = 'Entregar - ' + m + ' segundos restantes para completar la prueba';
}
else {
text = 'Submit - ' + m + ' seconds remaining to complete the quiz';
}
if (m > 0) {
setTimeout('updateQ('+m+')', 990);
}
else
{
$('#eomsubmitDiv').css('background-color', '#FF0000');
text ='Submitting... Please Wait.';
}
if (m <= 10 && m > 0)
{
if (m % 2 == 0)
{
$('#eomsubmitDiv').css('background-color', '#FFFF00');
}
else
{
$('#eomsubmitDiv').css('background-color', '#FFFFAA');
}
}
$('#eomsubmit').attr('value', text);
}
function UpdateElapsedTimer()
{
var s = secondsElapsed + (GetTickDiff()/1000);
UpdateTimer('TotalTimeClock', s, 'UP');
}
function GetTickDiff()
{
var d = new Date();
var tickDiff = d.getTime() - startTicks;
return tickDiff;
}
function UpdateRemainingTimer()
{
var s = secondsRemaining - (GetTickDiff()/1000);
estimatedSecondsRemaining = s;
if (s < 0) s = 0;
UpdateTimer('TimeRemainingClock', s, 'DOWN');
}
function UpdateTimer(ClockID,ElapsedSeconds,ClockDirection){
//check to see if we can run this code yet
if(document.getElementById && document.getElementById(ClockID) != null){
//declare vars
var _Seconds = 0;
var _Minutes = 0;
var _Hours = 0;
//Format Seconds
_Seconds = Math.floor(ElapsedSeconds % 60);
if(_Seconds <= 9) {
_Seconds = "0"+_Seconds;
}
//Format minutes
_Minutes = Math.floor(ElapsedSeconds/60 % 60);
if(_Minutes <= 9) {
_Minutes = "0"+_Minutes;
}
//Format hours
_Hours = Math.floor(ElapsedSeconds/3600 % 60);
if(_Hours <= 9){
_Hours = "0"+_Hours;
}
document.getElementById(ClockID).innerHTML = _Hours + ":" + _Minutes + ":" + _Seconds;
if (timerStatus != 'active')
{
setTimeout('UpdateTimer(\''+ClockID+'\','+ElapsedSeconds+',\''+ClockDirection+'\')',1000);
return;
}
if(ElapsedSeconds > 0 || ClockDirection == "UP"){
if(ClockDirection == "UP")
{
ElapsedSeconds = ElapsedSeconds + 1;
}
else
{
ElapsedSeconds = ElapsedSeconds - 1;
}
//setTimeout('UpdateTimer(\''+ClockID+'\','+ElapsedSeconds+',\''+ClockDirection+'\')',1000);
}
else{
//Timer has hit zero. Lets make sure the next buttons are visible.
$('#next_top').show();
$('#next_bot').show();
}
}
else if(!pageLoaded) //call function again in 100ms
{
//setTimeout('UpdateTimer(\''+ClockID+'\','+ElapsedSeconds+',\''+ClockDirection+'\')',100);
}
}
function DisplayNextButtons(){
$('#next_top').show();
$('#next_bot').show();
}
function hideNextButtons(){
$('#next_top').hide();
$('#next_bot').hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I happened to stumble upon the same code. If you were on the same site as me,
I have a potential fix.
Instead of editing the time remaining I setup a script that will click next when the time has expired. I was too lazy to check whether they are checking timestamps server side. Also the server logs will look more similar to a regular user.
Instructions:
Download the following extension for Chrome
https://chrome.google.com/webstore/detail/custom-javascript-for-web/poakhlngfciodnhlhhgnaaelnpjljija?hl=en
Navigate to the site
click the CJS chrome extension button
check "enable cjs for this host"
paste the following JS snippet into the JS box
var t=setInterval(try_hit_next,1000);
function try_hit_next(){
if (estimatedSecondsRemaining <= 0)
window.location = $('#next_top').parent()[0]['href'];
}
click save
1) No needs to assign "setInterval" to a variable t
2) Has somebody tried to make fully automated script for this resource, i mean "driving defensive course" cause it pushes popups with personal questions randomly and besides shows pages with a сourse-related questions (constantly the same), so hope it's gonna be very useful "tool" )
Unfortunately the timers are actually being kept server-side. You can watch a POST to CourseData.aspx and it will return with new values for SecondsRemaining and SecondsElapsed. These new values are used to set the client-side timers. You can change the client side variables all you want but when you move to the next page, another call to CourseData.aspx is done to fetch the server time. So the server's timers rule this entire process.
I believe the only reason you see any JS timers is to provide a (now hidden) simple "time remaining" clock for the user.
However I am willing to bet that there's a way to POST a new time or SecondsRemaining to the CourseData.aspx page, I just don't know what set of post data variables might be needed to do so.
I am creating an inventory for object, When I pick object it stores in inventory but my display line (Press E to pick up) still showing.
method ONGUI, I think making some problem,
Here is code of FPS pickup.
#pragma strict
var InstructionBoxSkin : GUISkin;
var ButtonToPress : KeyCode = KeyCode.E;
var PickUpDistance = 1.7f;
private var canPickUp = false;
private var theItem : Item;
private var thePlayer : Transform;
private var dist = 9999f;
#script AddComponentMenu ("Inventory/Items/First Person Pick Up")
#script RequireComponent(Item)
function Awake ()
{
theItem = (GetComponent(Item));
if (InstructionBoxSkin == null)
{
InstructionBoxSkin = Resources.Load("OtherSkin", GUISkin);
}
}
function RetrievePlayer (theInv : Inventory)
{
thePlayer = theInv.transform.parent;
}
function OnGUI ()
{
//This is where we draw a box telling the Player how to pick up the item.
//
GUI.skin = InstructionBoxSkin;
GUI.color = Color(1, 1, 1, 0.7);
if (canPickUp == true)
{
if (transform.name.Length <= 1)
{
GUI.Box (Rect (Screen.width*0.5-(165*0.5), 200, 165, 22), "Press E to pick up " + transform.name + ".");
}
else
{
GUI.Box (Rect (Screen.width*0.5-(185*0.5), 200, 185, 22), "Press E to pick up " + transform.name + ".");
}
}
}
function Update ()
{
if (thePlayer != null)
{
dist = Vector3.Distance(thePlayer.position, transform.position);
if (dist <= PickUpDistance)
{
canPickUp = true;
}
else
{
canPickUp = false;
}
//This is where we allow the player to press the ButtonToPress to pick up the item.
if (Input.GetKeyDown(ButtonToPress) && canPickUp == true)
{
theItem.PickUpItem();
}
}
}
function OnDrawGizmosSelected ()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere (transform.position, PickUpDistance);
}
What could be the reason?
It looks like canPickUp is never set to false.
Does changing:
if (Input.GetKeyDown(ButtonToPress) && canPickUp == true)
{
theItem.PickUpItem();
canPickUp = false;
}
resolve the issue?
I have a problem because I can not add php session to post in javascript, or do not know how to do it, here is my code which is a problem.
if (!this.movesAvailable()) {
var xmlhttp = null;
this.over = true; // Game over!
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http://obiektywnywaper.pl/2048/post.php?user=&wynik="+self.score, true);
xmlhttp.send();
alert(self.score);
}
I tried something like this, but it does not work
if (!this.movesAvailable()) {
var xmlhttp = null;
var user=<?echo $_SESSION['user'];?>;
this.over = true; // Game over!
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http://obiektywnywaper.pl/2048/post.php?user="+user+"&wynik="+self.score, true);
xmlhttp.send();
alert(self.score);
}
I add also the js file
function GameManager(size, InputManager, Actuator, ScoreManager) {
this.size = size; // Size of the grid
this.inputManager = new InputManager;
this.scoreManager = new ScoreManager;
this.actuator = new Actuator;
this.startTiles = 2;
this.inputManager.on("move", this.move.bind(this));
this.inputManager.on("restart", this.restart.bind(this));
this.inputManager.on("keepPlaying", this.keepPlaying.bind(this));
this.inputManager.on("showInfo", this.showInfo.bind(this));
this.inputManager.on("hideInfo", this.hideInfo.bind(this));
this.setup();
}
// Restart the game
GameManager.prototype.restart = function () {
this.actuator.continue();
this.setup();
};
// Keep playing after winning
GameManager.prototype.keepPlaying = function () {
this.keepPlaying = true;
this.actuator.continue();
};
GameManager.prototype.showInfo = function () {
this.actuator.showInfo();
};
GameManager.prototype.hideInfo = function () {
this.actuator.hideInfo();
};
GameManager.prototype.isGameTerminated = function () {
if (this.over || (this.won && !this.keepPlaying)) {
return true;
} else {
return false;
}
};
// Set up the game
GameManager.prototype.setup = function () {
this.grid = new Grid(this.size);
this.score = 0;
this.over = false;
this.won = false;
this.keepPlaying = false;
// Add the initial tiles
this.addStartTiles();
// Update the actuator
this.actuate();
};
// Set up the initial tiles to start the game with
GameManager.prototype.addStartTiles = function () {
for (var i = 0; i < this.startTiles; i++) {
this.addRandomTile();
}
};
// Adds a tile in a random position
GameManager.prototype.addRandomTile = function () {
if (this.grid.cellsAvailable()) {
var value = Math.random() < 0.9 ? 2 : 4;
var tile = new Tile(this.grid.randomAvailableCell(), value);
this.grid.insertTile(tile);
}
};
// Sends the updated grid to the actuator
GameManager.prototype.actuate = function () {
if (this.scoreManager.get() < this.score) {
this.scoreManager.set(this.score);
}
this.actuator.actuate(this.grid, {
score: this.score,
over: this.over,
won: this.won,
bestScore: this.scoreManager.get(),
terminated: this.isGameTerminated()
});
};
// Save all tile positions and remove merger info
GameManager.prototype.prepareTiles = function () {
this.grid.eachCell(function (x, y, tile) {
if (tile) {
tile.mergedFrom = null;
tile.savePosition();
}
});
};
// Move a tile and its representation
GameManager.prototype.moveTile = function (tile, cell) {
this.grid.cells[tile.x][tile.y] = null;
this.grid.cells[cell.x][cell.y] = tile;
tile.updatePosition(cell);
};
// Move tiles on the grid in the specified direction
GameManager.prototype.move = function (direction) {
// 0: up, 1: right, 2:down, 3: left
var self = this;
if (this.isGameTerminated()) return; // Don't do anything if the game's over
var cell, tile;
var vector = this.getVector(direction);
var traversals = this.buildTraversals(vector);
var moved = false;
// Save the current tile positions and remove merger information
this.prepareTiles();
// Traverse the grid in the right direction and move tiles
traversals.x.forEach(function (x) {
traversals.y.forEach(function (y) {
cell = { x: x, y: y };
tile = self.grid.cellContent(cell);
if (tile) {
var positions = self.findFarthestPosition(cell, vector);
var next = self.grid.cellContent(positions.next);
// Only one merger per row traversal?
if (next && next.value === tile.value && !next.mergedFrom) {
var merged = new Tile(positions.next, tile.value * 2);
merged.mergedFrom = [tile, next];
self.grid.insertTile(merged);
self.grid.removeTile(tile);
// Converge the two tiles' positions
tile.updatePosition(positions.next);
// Update the score
self.score += merged.value;
// The mighty 2048 tile
if (merged.value === 2048) self.won = true;
} else {
self.moveTile(tile, positions.farthest);
}
if (!self.positionsEqual(cell, tile)) {
moved = true; // The tile moved from its original cell!
}
}
});
});
if (moved) {
this.addRandomTile();
if (!this.movesAvailable()) {
var xmlhttp = null;
this.over = true; // Game over!
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "http://obiektywnywaper.pl/2048/post.php?user=&wynik="+self.score, true);
xmlhttp.send();
alert(self.score);
}
this.actuate();
}
};
// Get the vector representing the chosen direction
GameManager.prototype.getVector = function (direction) {
// Vectors representing tile movement
var map = {
0: { x: 0, y: -1 }, // up
1: { x: 1, y: 0 }, // right
2: { x: 0, y: 1 }, // down
3: { x: -1, y: 0 } // left
};
return map[direction];
};
// Build a list of positions to traverse in the right order
GameManager.prototype.buildTraversals = function (vector) {
var traversals = { x: [], y: [] };
for (var pos = 0; pos < this.size; pos++) {
traversals.x.push(pos);
traversals.y.push(pos);
}
// Always traverse from the farthest cell in the chosen direction
if (vector.x === 1) traversals.x = traversals.x.reverse();
if (vector.y === 1) traversals.y = traversals.y.reverse();
return traversals;
};
GameManager.prototype.findFarthestPosition = function (cell, vector) {
var previous;
// Progress towards the vector direction until an obstacle is found
do {
previous = cell;
cell = { x: previous.x + vector.x, y: previous.y + vector.y };
} while (this.grid.withinBounds(cell) &&
this.grid.cellAvailable(cell));
return {
farthest: previous,
next: cell // Used to check if a merge is required
};
};
GameManager.prototype.movesAvailable = function () {
return this.grid.cellsAvailable() || this.tileMatchesAvailable();
};
// Check for available matches between tiles (more expensive check)
GameManager.prototype.tileMatchesAvailable = function () {
var self = this;
var tile;
for (var x = 0; x < this.size; x++) {
for (var y = 0; y < this.size; y++) {
tile = this.grid.cellContent({ x: x, y: y });
if (tile) {
for (var direction = 0; direction < 4; direction++) {
var vector = self.getVector(direction);
var cell = { x: x + vector.x, y: y + vector.y };
var other = self.grid.cellContent(cell);
if (other && other.value === tile.value) {
return true; // These two tiles can be merged
}
}
}
}
}
return false;
};
GameManager.prototype.positionsEqual = function (first, second) {
return first.x === second.x && first.y === second.y;
};
I don't know php, but classic asp works in similar fashion as far as I know. If you set the variable outside the scope of the function, and also include apostrophes, it should work.
var user="<?php echo $_SESSION['user'];?>"; //possibly declared outside of scope
Edited as per #developerwjk's comment about the php-syntax
I have been trying to fix a piece of javascript code but am not having any luck. The syntax looks correct but I keep getting an unexpected token '<' syntax error.
Please do not mark this question as a duplicate since I could not find the answer to my problem on this site.
Javascript:
// Function to get elements by class name for DOM fragment and tag name
function getElementsByClassName(objElement, strTagName, strClassName)
{
var objCollection = objElement.getElementsByTagName(strTagName);
var arReturn = [];
var strClass, arClass, iClass, iCounter;
for(iCounter=0; iCounter<objCollection.length; iCounter++)
{
strClass = objCollection[iCounter].className;
if (strClass)
{
arClass = strClass.split(' ');
for (iClass=0; iClass<arClass.length; iClass++)
{
if (arClass[iClass] == strClassName)
{
arReturn.push(objCollection[iCounter]);
break;
}
}
}
}
objCollection = null;
return (arReturn);
}
var drag = {
objCurrent : null,
arTargets : ['Fav', 'Tol', 'Rej'],
initialise : function(objNode)
{
// Add event handlers
objNode.onmousedown = drag.start;
objNode.onclick = function() {this.focus();};
objNode.onkeydown = drag.keyboardDragDrop;
document.body.onclick = drag.removePopup;
},
keyboardDragDrop : function(objEvent)
{
objEvent = objEvent || window.event;
drag.objCurrent = this;
var arChoices = ['Favourite artists', 'Tolerable artists', 'Rejected artists'];
var iKey = objEvent.keyCode;
var objItem = drag.objCurrent;
var strExisting = objItem.parentNode.getAttribute('id');
var objMenu, objChoice, iCounter;
if (iKey == 32)
{
document.onkeydown = function(){return objEvent.keyCode==38 || objEvent.keyCode==40 ? false : true;};
// Set ARIA properties
drag.objCurrent.setAttribute('aria-grabbed', 'true');
drag.objCurrent.setAttribute('aria-owns', 'popup');
// Build context menu
objMenu = document.createElement('ul');
objMenu.setAttribute('id', 'popup');
objMenu.setAttribute('role', 'menu');
for (iCounter=0; iCounter<arChoices.length; iCounter++)
{
if (drag.arTargets[iCounter] != strExisting)
{
objChoice = document.createElement('li');
objChoice.appendChild(document.createTextNode(arChoices[iCounter]));
objChoice.tabIndex = -1;
objChoice.setAttribute('role', 'menuitem');
objChoice.onmousedown = function() {drag.dropObject(this.firstChild.data.substr(0, 3));};
objChoice.onkeydown = drag.handleContext;
objChoice.onmouseover = function() {if (this.className.indexOf('hover') < 0) {this.className += ' hover';} };
objChoice.onmouseout = function() {this.className = this.className.replace(/\s*hover/, ''); };
objMenu.appendChild(objChoice);
}
}
objItem.appendChild(objMenu);
objMenu.firstChild.focus();
objMenu.firstChild.className = 'focus';
drag.identifyTargets(true);
}
},
removePopup : function()
{
document.onkeydown = null;
var objContext = document.getElementById('popup');
if (objContext)
{
objContext.parentNode.removeChild(objContext);
}
},
handleContext : function(objEvent)
{
objEvent = objEvent || window.event;
var objItem = objEvent.target || objEvent.srcElement;
var iKey = objEvent.keyCode;
var objFocus, objList, strTarget, iCounter;
// Cancel default behaviour
if (objEvent.stopPropagation)
{
objEvent.stopPropagation();
}
else if (objEvent.cancelBubble)
{
objEvent.cancelBubble = true;
}
if (objEvent.preventDefault)
{
objEvent.preventDefault();
}
else if (objEvent.returnValue)
{
objEvent.returnValue = false;
}
switch (iKey)
{
case 38 : // Down arrow
objFocus = objItem.nextSibling;
if (!objFocus)
{
objFocus = objItem.previousSibling;
}
objItem.className = '';
objFocus.focus();
objFocus.className = 'focus';
break;
case 40 : // Up arrow
objFocus = objItem.previousSibling;
if (!objFocus)
{
objFocus = objItem.nextSibling;
}
objItem.className = '';
objFocus.focus();
objFocus.className = 'focus';
break;
case 13 : // Enter
strTarget = objItem.firstChild.data.substr(0, 3);
drag.dropObject(strTarget);
break;
case 27 : // Escape
case 9 : // Tab
drag.objCurrent.removeAttribute('aria-owns');
drag.objCurrent.removeChild(objItem.parentNode);
drag.objCurrent.focus();
for (iCounter=0; iCounter<drag.arTargets.length; iCounter++)
{
objList = document.getElementById(drag.arTargets[iCounter]);
drag.objCurrent.setAttribute('aria-grabbed', 'false');
objList.removeAttribute('aria-dropeffect');
objList.className = '';
}
break;
}
},
start : function(objEvent)
{
objEvent = objEvent || window.event;
drag.removePopup();
// Initialise properties
drag.objCurrent = this;
drag.objCurrent.lastX = objEvent.clientX;
drag.objCurrent.lastY = objEvent.clientY;
drag.objCurrent.style.zIndex = '2';
drag.objCurrent.setAttribute('aria-grabbed', 'true');
document.onmousemove = drag.drag;
document.onmouseup = drag.end;
drag.identifyTargets(true);
return false;
},
drag : function(objEvent)
{
objEvent = objEvent || window.event;
// Calculate new position
var iCurrentY = objEvent.clientY;
var iCurrentX = objEvent.clientX;
var iYPos = parseInt(drag.objCurrent.style.top, 10);
var iXPos = parseInt(drag.objCurrent.style.left, 10);
var iNewX, iNewY;
iNewX = iXPos + iCurrentX - drag.objCurrent.lastX;
iNewY = iYPos + iCurrentY - drag.objCurrent.lastY;
drag.objCurrent.style.left = iNewX + 'px';
drag.objCurrent.style.top = iNewY + 'px';
drag.objCurrent.lastX = iCurrentX;
drag.objCurrent.lastY = iCurrentY;
return false;
},
calculatePosition : function (objElement, strOffset)
{
var iOffset = 0;
// Get offset position in relation to parent nodes
if (objElement.offsetParent)
{
do
{
iOffset += objElement[strOffset];
objElement = objElement.offsetParent;
} while (objElement);
}
return iOffset;
},
identifyTargets : function (bHighlight)
{
var strExisting = drag.objCurrent.parentNode.getAttribute('id');
var objList, iCounter;
// Highlight the targets for the current drag item
for (iCounter=0; iCounter<drag.arTargets.length; iCounter++)
{
objList = document.getElementById(drag.arTargets[iCounter]);
if (bHighlight && drag.arTargets[iCounter] != strExisting)
{
objList.className = 'highlight';
objList.setAttribute('aria-dropeffect', 'move');
}
else
{
objList.className = '';
objList.removeAttribute('aria-dropeffect');
}
}
},
getTarget : function()
{
var strExisting = drag.objCurrent.parentNode.getAttribute('id');
var iCurrentLeft = drag.calculatePosition(drag.objCurrent, 'offsetLeft');
var iCurrentTop = drag.calculatePosition(drag.objCurrent, 'offsetTop');
var iTolerance = 40;
var objList, iLeft, iRight, iTop, iBottom, iCounter;
for (iCounter=0; iCounter<drag.arTargets.length; iCounter++)
{
if (drag.arTargets[iCounter] != strExisting)
{
// Get position of the list
objList = document.getElementById(drag.arTargets[iCounter]);
iLeft = drag.calculatePosition(objList, 'offsetLeft') - iTolerance;
iRight = iLeft + objList.offsetWidth + iTolerance;
iTop = drag.calculatePosition(objList, 'offsetTop') - iTolerance;
iBottom = iTop + objList.offsetHeight + iTolerance;
// Determine if current object is over the target
if (iCurrentLeft > iLeft && iCurrentLeft < iRight && iCurrentTop > iTop && iCurrentTop < iBottom)
{
return drag.arTargets[iCounter];
}
}
}
// Current object is not over a target
return '';
},
dropObject : function(strTarget)
{
var objClone, objOriginal, objTarget, objEmpty, objBands, objItem;
drag.removePopup();
if (strTarget.length > 0)
{
// Copy node to new target
objOriginal = drag.objCurrent.parentNode;
objClone = drag.objCurrent.cloneNode(true);
// Remove previous attributes
objClone.removeAttribute('style');
objClone.className = objClone.className.replace(/\s*focused/, '');
objClone.className = objClone.className.replace(/\s*hover/, '');
// Add focus indicators
objClone.onfocus = function() {this.className += ' focused'; };
objClone.onblur = function() {this.className = this.className.replace(/\s*focused/, '');};
objClone.onmouseover = function() {if (this.className.indexOf('hover') < 0) {this.className += ' hover';} };
objClone.onmouseout = function() {this.className = this.className.replace(/\s*hover/, ''); };
objTarget = document.getElementById(strTarget);
objOriginal.removeChild(drag.objCurrent);
objTarget.appendChild(objClone);
drag.objCurrent = objClone;
drag.initialise(objClone);
// Remove empty node if there are artists in list
objEmpty = getElementsByClassName(objTarget, 'li', 'empty');
if (objEmpty[0])
{
objTarget.removeChild(objEmpty[0]);
}
// Add an empty node if there are no artists in list
objBands = objOriginal.getElementsByTagName('li');
if (objBands.length === 0)
{
objItem = document.createElement('li');
objItem.appendChild(document.createTextNode('None'));
objItem.className = 'empty';
objOriginal.appendChild(objItem);
}
}
// Reset properties
drag.objCurrent.style.left = '0px';
drag.objCurrent.style.top = '0px';
drag.objCurrent.style.zIndex = 'auto';
drag.objCurrent.setAttribute('aria-grabbed', 'false');
drag.objCurrent.removeAttribute('aria-owns');
drag.identifyTargets(false);
},
end : function()
{
var strTarget = drag.getTarget();
drag.dropObject(strTarget);
document.onmousemove = null;
document.onmouseup = null;
drag.objCurrent = null;
}
};
function init ()
{
var objItems = getElementsByClassName(document, 'li', 'draggable');
var objItem, iCounter;
for (iCounter=0; iCounter<objItems.length; iCounter++)
{
// Set initial values so can be moved
objItems[iCounter].style.top = '0px';
objItems[iCounter].style.left = '0px';
// Put the list items into the keyboard tab order
objItems[iCounter].tabIndex = 0;
// Set ARIA attributes for artists
objItems[iCounter].setAttribute('aria-grabbed', 'false');
objItems[iCounter].setAttribute('aria-haspopup', 'true');
objItems[iCounter].setAttribute('role', 'listitem');
// Provide a focus indicator
objItems[iCounter].onfocus = function() {this.className += ' focused'; };
objItems[iCounter].onblur = function() {this.className = this.className.replace(/\s*focused/, '');};
objItems[iCounter].onmouseover = function() {if (this.className.indexOf('hover') < 0) {this.className += ' hover';} };
objItems[iCounter].onmouseout = function() {this.className = this.className.replace(/\s*hover/, ''); };
drag.initialise(objItems[iCounter]);
}
// Set ARIA properties on the drag and drop list, and set role of this region to application
for (iCounter=0; iCounter<drag.arTargets.length; iCounter++)
{
objItem = document.getElementById(drag.arTargets[iCounter]);
objItem.setAttribute('aria-labelledby', drag.arTargets[iCounter] + 'h');
objItem.setAttribute('role', 'list');
}
objItem = document.getElementById('dragdrop');
objItem.setAttribute('role', 'application');
objItems = null;
}
window.onload = init;
This type of problem usually occurs when issuing an AJAX request which expects JSON or JavaScript as a response but it receives HTML in stead.
When expecting JSON or JavaScript the text of the response must be "eval"-uated by a JavaScript parser. If HTML code is received and evaluated as JSON or JavaScript, the presence of a lower than < or a greater than > symbol will cause errors.