Generating Ongoing Looping Links without Repeats using JavaScript - javascript

I am trying to create a button that sends users through a 'loop' of links, and keeps going through it anywhere, perhaps with its own 'memory'.
(REFERENCE CODE BELOW) For example, I want the first click to go to the first item, /roles/mafia, then the second click (from another tab, browser, or device) to go to the second one, /roles/doctor, and so on. When the button has been clicked six times (so the list has finished), the seventh time should loop back to the first one.
So if Bob clicks on the button with his Mac, it will take him to /roles/mafia.
But then seconds later, if Jill clicks on it with her iPhone, it will link to /roles/doctor, and so forth.
Here is my JS, but this doesn't work since this is a pseudo-random system, rather than forming a loop.
<script type="text/javascript">
var urls = [
"/roles/mafia",
'/roles/doctor',
'/roles/cupid',
'/roles/mafioso',
'/roles/pimp',
'/roles/detective'
];
function goSomewhere() {
var url = urls[Math.floor(Math.random()*urls.length)];
window.location = url; // redirect
}
</script>
And then the HTML button:
JOIN SERVER
I am aware this won't have a quite simple solution, and I'm very new to the concept of JavaScript and memory, so any help, even just a snippet to inspire another coder to find the answer, is enough.
Thanks for any help in advance :)

Related

Clicking a link does not refresh the content

I've been looking at how to automate actions on a webpage with PhantomJS, however I'm having issues manipulating the page to do what I want it to.
I'm using this as test site. I've managed to get Phantom to open the webpage and scrape the random sentence from the #result span. But now what I want to do is get another sentence without re-launching the script. I don't want to close and re-open the page as Phantom takes ages to launch the webkit and load the page. So I thought I could get another sentence by getting Phantom to click on the 'Refresh' button below the sentence box. Here's what I have at the moment:
var page = require('webpage').create();
console.log("connecting...");
page.open("http://watchout4snakes.com/wo4snakes/Random/RandomSentence", function(){
console.log('connected');
var content = page.content;
var phrase = page.evaluate(function() {
return document.getElementById("result").innerHTML;
});
console.log(phrase);
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
page.evaluate(function() {
$("frmSentence").click();
});
});
var content = page.content;
var phrase = page.evaluate(function() {
return document.getElementById("result").innerHTML;
});
console.log(phrase);
phantom.exit();
});
As you can see I'm trying to click the refresh button by using a .click() function, but this isn't working for me as I still get the same sentence as beforehand. Given the HTML for the button:
<form action="/wo4snakes/Random/NewRandomSentence" id="frmSentence" method="post" novalidate="novalidate">
<p><input type="submit" value="Refresh"></p>
</form>
I'm not sure what I should be referencing in the script to be clicked on? I'm trying the form ID 'frmSentence' but that isn't working. I'm wondering if .click() is the right way to go about this, is there some way for Phantom to submit the form that the button is linked to? Or maybe I can run the associated script on the page that gets the sentence? I'm a bit lost on this one so I don't really know which method I should go with?
You have a problem with your control flow. page.includeJs is an asynchronous function. If you have some other statements page.includeJs, they are likely executed before the script is loaded and the callback is executed. It means in your case that you've read the sentence 2 times before you even trigger a click.
If you want to do this multiple times, I suggest to use recursion since you cannot write this synchronously. Also, since you want this to be fast, you cannot use a static setTimeout with a timeout of 1 second, because sometimes the request may be faster (you lose time) and sometimes slower (your script breaks). You should use waitFor from the examples.
Instead of loading jQuery every time, you can move page.includeJs up and include everything else in its callback. If you only need to click an element or if jQuery click doesn't work (yes, that happens from time to time), you should use PhantomJS; click an element.
web scraping is about sending require information to a web server and get the result. It is not about behaving like a user clicking button or entering search criteria.
All you need to do in this example is send a POST request to http://watchout4snakes.com/wo4snakes/Random/NewRandomSentence. The result is just text in page.content, it does not even need to evaluate. So to get more than one sentence you just need to do a loop of page.open

remember most recent click

So I want to be able to have a different styling for a link after you go to the page it's clicked on. I have been using the following code:
$(document).ready(function(){
var url = document.URL;
function contains(search, find) {
return search.indexOf(find) !== -1;
};
$('#topbar a').each(function(){
var link = $(this).attr('href');
var answer = contains(link,url);
if(answer === true){
$(this).addClass('check');
}
else{
$(this).addClass('nocheck');
};
});
});
This goes through the links in my navigation bar and checks if it's on the same page as the link, and it works, but I can't use it in one specific case: Random.
I have a link that generates a random page from the pages I have, so it does not have a specified link as it links to a function to randomly generate the page (note: I cannot change the function or access information from it).
So how can I detect that the random link was clicked previously so i can give it the .check class
If i understand your question correctly, your function does not work for the randomlink because this has a href like http://mysite.com/random, but the server will actualy redirect you to a different page, like http://mysite.com/about-me, and therefore the url of the active page does not match the href of the random button, and it will not get the active state.
One could argue if you would want it to get the active state, cause clicking it again would not (likely) bring you to the same page, but that is besides the question.
I can see to ways to solve this.
server side:
In stead of redirecting to ie. http://mysite.com/about-me in the random function, you could also redirect to http://mysite.com/about-me?random. By adding this get variable, you should not change the behaviour of the link (unless you have some very strict controller, or that variable is actually used, but that is unlikely). You could then detect with javascript if that variable is present in the url, and then activate the random button.
Something like this:
$(document).ready(function(){
var url = document.URL;
// check for random
if (url.indexOf('?random') >= 0) {
$('#topbar a.random').addClass('check');
}
// check all other
$('#topbar a:not(.random)').each(function(){
if($(this).attr('href').indexOf(url) >= 0){
$(this).addClass('check');
}
else{
$(this).addClass('nocheck');
};
});
});
cookie:
If you do not have acces to the server side random controller, you could do it entirely with javascript, by the use of a cookie (the only way I know to make a variable persist trough page requests).
On click of the random button, you would first set a random cookie to true with javascript, before letting the actual link do it's thing. On entering the page, you could then do a similar check as in my previous option, but in stead of the url you check if the cookie is tre. If so, you change it to false (so on the next page request the random button will not be active again) and set the randombutton to active.
As I believe the first solution is to be preferred (cookies should only be used as a last resort, they are sent on every page request, which means extra data, and your user might have cookies disabled, or there might be laws against using cookies, so the function could not always work), I will not write the javascript yet. Feel free to ask if you prefer this solution and need further help however.

javascript history.back losses the search result

Page A:
$(document).ready(function () {
bindData();
});
function bindData() {
$('#searchbtn').bind('click', function () { SearchResult(); });
}
function SearchResult() {
ajax call...
}
Page A HTML:
<input type="button" id="searchbtn" />
Page B Details---> this page comes after selecting a specific search result from page A search list
Back<br />
Now when I go back to the Page A I can see my search criteria's as they were selected but the result Div is gone. What I am trying to do is I want the search list to stay when the Page comes back.
I think what I can do here is some how call the searchbtn click event again when the page comes back so the list will come-up again. Can anyone tell me how to fire the searchbtn click event only when the page comes back from Page B. or point me in the right way of doing this..
Thanks
The Browser Back button has long been problematic with AJAX. There are scripts, workarounds, and techniques out there (depending on the framework that you want to use).
Since it appears that you are using jQuery (based on your posted JavaScript syntax), here is a link to another Stackoverflow post regarding back button jQuery plugins.
history.back() will return you to the last URL visited, meaning that any ajax calls made during the user's visit will not be automatically repeated. Your browser may automatically restore your form selections, but the SearchResults() function is only called by a click event, not a selection event.
You can bind URLs to ajax states using a framework like sammy.js. That way, history.back() would take you to a URL associated with SearchResults().
function bindData() {
var chkinput1 = $("input:checkbox[name=x]:checked").length;
var chkinput2 = $("input:checkbox[name=y]:checked").length;
if (chkinput1 > 0 && chkinput2 > 0) {
SearchResult();
}
$('#searchbtn').bind('click', function () { SearchResult(); });
}
I know this is the worst way to achieve this result but I think instead of using any other plugins to add complexity we will go with this for now. If anyone else is looking for the same question let me tell you again this is not the best practice as on returning back to the history we are calling the search result again depending upon the cached input selection of checkboxes and generating the whole ajax call again to display the list. On the first request I am caching the list and setting sliding expiration so its not taking anytime to comeback and so everyone lives happily.

Java Timer use on an ASP.NET 2.0 page with Master File

I have found out that sometimes the simplest things you want to do are almost impossible to fund an answer for. I have an ASPX page in ASP.NET V2 programmed in Visual Studio 2005. The ASPX page has a behind code ASXP.VB page and is tied to a .master file. I have two buttons [Button_Process] that will eventually call a program that will extract data from a SQL table -- no problem here. [Button_Process] will also call a javascript timer that goes for 7seconds (enough time for the extraction to happen). We're doing the timer delay so a cute little graphic appears and makes the person using the page think the systems working and not to double-click the button -- I know there's other ways of doing this but this is our approach for know). Again there is no problem here. test with an aleart delivers a message seven seconds after clicking the [Button_Process] button. Everything is good in the world up to this point.
I have a second button, [Button_PM_Upload], that is hidden during this time. It will eventually call a program on button-click to take the info from the previous button click collecting, compare it to data in a second SQL table and update the second SQL table. All I want to do is to make that second button visible after the seven seconds is up. I very simple task but I am having problems finding the solution.
In the master page between head tags is this timer code that works remarkably well:
<script type="text/javascript">
<!--
var secs
var timerID = null
var timerRunning = false
var delay = 1000
function InitializeTimer()
{
// Set the length of the timer, in seconds
secs = 7
StopTheClock()
StartTheTimer()
}
function StopTheClock()
{
if(timerRunning)
clearTimeout(timerID)
timerRunning = false
}
function StartTheTimer()
{
if (secs==0)
{
StopTheClock()
// Here's where you put something useful that's
// supposed to happen after the allotted time.
// For example, you could display a message:
alert("The timer is working properly")
//document.getElementsByName ("Button_PM_Upload").style.display=
"block";
}
else
{
self.status = secs
secs = secs - 1
timerRunning = true
timerID = self.setTimeout("StartTheTimer()", delay)
}
}
//-->
</script>
On the ASPX.VB behind code page is this code for that button click and it works very well too:
Protected Sub Button_Process_OnClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button_Process.Click
'This code fires of the timer in the master file
ClientScript.RegisterStartupScript(GetType(Page), "Startup", "<script type=text/javascript>InitializeTimer()</script>")
End Sub
Through days of reading and research I found out that the timer is clientside and the behind code is Serverside and "never the two do talk". Articles on the NET say that to make the second button "grabable" by the javascript, I must instead of saying (visible=false) to initially make it invisible prior to the timer , which is serverside and doesn't deliver the button clientside, I need to tweak the display command. That code is located on the ASPX page for that button and looks like this in the source code:
<asp:Button ID="Button_PM_Upload" runat="server" Style="display: none; left: 632px;
position: absolute; top: 252px; z-index: 104;" Text="Upload to PartsMaster"
ToolTip="Change PR codes and Descriptions" Width="147px" />
As my older brother use to say in our youth, -- "everything is hunky-dory at this point". The next part that the articles say varies between authors. All do however have a close solution but do not tell where to place the code. I have been placing it under the alert in the Javascript in the master page. Here is what I am getting:
document.getElementsByName("Button_PM_Upload").style.display="block";
gives me -- button stays hidden
document.getElementsByName("Button_PM_Upload").style.display='block';
gives me -- button stays hidden
document.getElementsByName('Button_PM_Upload').style.display='block';
gives me -- button stays hidden
document.getElementsByName('Button_PM_Upload').style.display="block";
gives me -- button stays hidden
Whenever I substitute block for inline (one suggestion) all four code lines give me the same result (nothing). Whenever I substitute block for visible (another suggestion) all four code lines give me the same result. Whenever I substitute block with inline (another suggestion) all four codes lines give me the same result.
I did find this example where you put server code in -- ("<%=Button_PM_Upload%>") --, but all I get is an error (no matter how I arrange it) that reads this: BC30451: Name 'Button_PM_Upload' is not declared.
My web site has the master page on the root of the project. Also on the root is a folder called [PSC_Tools]. My ASPX and ASPX.VB pages are in that folder and I'm wondering if maybe its a simple path problem. Whatever it is, I am a standstill -- sometimes the simplest things to do are the hardest to find code for. Ajax tools are out of the question. The site was developed without them and if imported in, they interfer with the config file running the site.
Am I missing code somewhere? Am I not importing something? Does this have to do with the config or css files? I'm at a loss. I came across your site and could feel the heat of collected intellect and experience exuding out from my monitor. Hope I followed the rules for asking a question and would very much appreciate any help you could give. And as a help, coould you please let me know exactly where and on what page (ASPX, ASXP.VB, .master) the code should go.
Have a great weekend
There is an easy workaround: Wrap the button in a div:
<div id="x"><asp:Button/></div>
Then hide and show the div.
If you wanted to disable the button, use jQuery like this:
$('#x button').attr('disabled', 'disabled');
The trick is referencing the button through the wrapping element.

Title-changing effect/window event listener does not work

I tried to search but could not find out anything useful. This is a piece of code for my Greasemonkey script. Basically, I want to have the same effect as Gmail. When the page loads and you have new messages, the title will change repeatedly and make you notice. The problem is it does not work for the first time.
For example, if the user opens the page on new tab and does not move to the page, it does not work. But if the user moves to the tab and then moves to another tab, the script works.
Can anyone point me the right direction?
function startBlink(){
window.blinkInterval = setInterval(function(){
if(document.title != "Message"){document.title = "Message";}
else{document.title = "Application";}
} , 1000);
}
function blink(){
document.addEventListener("blur",function(){setTimeout(startBlink(),1000);},false);
document.addEventListener("focus",function(){clearInterval(window.blinkInterval);},false);
}
window.addEventListener("load",blink,false);
have you thought about changing (iterating through multiple variants of) window title instead of blinking (blur/focus)? that also attracts an eye.

Categories