CasperJS click is leads to error even when the element exists - javascript

I'm trying to click on a logout button, which I have retrieved from the current page. I successfully got the id of the logout link. But when I click on it, an error occurs
Cannot dispatch mousedown event on nonexistent selector
function getLogoutId()
{
var logoutid = "";
$(document).find("a").each(function(key,value){
var id = $(this).attr("id");
if(id.toLowerCase().indexOf("logout") > -1)
{
__utils__.echo("insidelogout" + id);
logoutid = id;
}
});
return logoutid;
}
var logoutid = this.evaluate(getLogoutId);
fs.write("logout.txt", this.getHTML(), 'w');
this.thenClick("#"+logoutid, function(){});
I have written the html content to a file, in which I checked for the id and it is there. The id attribute in question looks like this:
et-ef-content-ftf-flowHeader-logoutAction

I see nothing wrong with your code aside from strange usage of jQuery.
You can try other CSS selectors for clicking:
casper.thenClick("[id*='logout']"); // anywhere
or
casper.thenClick("[id$='logoutAction']"); // ending
or
casper.thenClick("[id|='logoutAction']"); // dash-separated
Maybe it is an issue with the code that follows the shown code. You can try to change thenClick to click.

Have you tried using just this.click("#"+logoutid);?
Also have you considered using jQuery to click on the button? Something like this...(first make a variable of your id so you can pass into jQuery).
var id = "#"+logoutid;
this.evaluate(function(id){
jQuery(id).click();
},id);

Related

Appended button only works on first div appended to

I'm trying to get each button that is appened to ('avatar-container comment ng-scope'), to be fully functional. Currently, only the top button is the button that is functional, and I'm not sure exactly why. Here's my code :
Also, I've already tried using addEventListener, but I was still running into the same problem :(.
$(document).ready(function () {
var groupcomments = $('.group-comments') // Container "Group Comments" are in
$(groupcomments).ready(function () {
function ucall(user) {
window.open('derp.com/userid=' + user, 'popup', 'width=600', 'height=600')
};
if (groupcomments[0]) {
var comments = groupcomments[0].getElementsByClassName('avatar-container comment ng-scope') // This gathers all of the comments themselves
$.each(comments, function () { // (you know this) but, this is looping over each comment.
var user = $(this).find('a')[0].href.toString();
user = user.replace(/[^\d]/g, '')
$(this).append('<button id=btnn>Click</button>') // using $(this) (which i assume are the comments, it appends the button to the comment)
var btn = document.getElementById('btnn') // getting the button
$(btn).click(function () {
ucall(user) // when button is clicked, call ucall function.
})
})
}
})
})
I commented in everything that should be useful, the button being appended worked, but it being clicked does not. Only on the first one appended. I'm just stuck right here.
You are adding a button <button id=btnn">Click</button> inside a loop. This means that you are adding several buttons all with the same ID. So, when you call document.getElementById('btnn'), you are only getting the first match in the list of buttons with the same ID.
You are only allowed to have one element with an ID. IDs are unique.

Trying To Add Onclick To Links, But Can't With .onclick

So I'm trying to use ajax to put content into a div, and trying to have it change all internal links before it adds the content so that they will use the funciton and load with ajax instead of navigating to another page. My function is supposed to get the data with ajax, change the href and onclick attributes of the link, then put it into the div... However, all it's doing is changing the href and not adding an onclick attribute at all. Here's what I was using so far:
function loadHTML(url, destination) {
$.get(url, function(data){
html = $(data);
$('a', html).each(function(){
if ( $.isUrlInternal( this.href )){
this.onclick = loadHTML(this.href,"forum_frame"); // I've tried using both a string and just putting the function here, neither seem to work.
this.href = "javascript:void(0)";
}
});
$(destination).html(html);
});
};
Also, I'm using jquery-urlinternal. Just thought that was relevant.
You can get the effect you want with less effort by doing this on your destination element ahead of time:
$(destination).on("click", "A", function(e) {
if ($.isUrlInternal(this.href)) {
e.preventDefault();
loadHTML(this.href, "forum_frame");
}
});
Now any <a> that ends up inside the destination container will be handled automatically, even content added in the future by DOM manipulations.
When setting a function to onclick through js it will not show on the markup as an attribute. However in this case it is not working because the function is not being set correctly. Easy approach to make it work,
....
var theHref=this.href;
this.onclick = function(){loadHTML(theHref,"forum_frame");}
....
simple demo http://jsbin.com/culoviro/1/edit

Removing Yet not Deleting an Element/Variable from an HTML Document

I am testing out with a different way of menus. My code is the following:
JavaScript
var hubOpen = 0;
var test = "test";
$(document).ready(function(){
$('#hub').click(function(){
if(hubOpen == 0){
$('#hub').append(test);
hubOpen = 1;
} else {
//code for taking "test" out here
hubOpen = 0;
};
});
});
HTML
<body>
<p id="hub">Hub</p>
</body>
If you'd like, here's a jsFiddle here. The code is to make sure that when the id "hub" is clicked, "test" appears. When hub is clicked again, "test" disappears. The code, when run, opens test, doesn't let you click it again, but it doesn't delete "test" (as there is no code for it).
My question: How would I delete the variable "test" from the document but not to delete the variable forever, as I would need to use it later? Would the jQuery method
.replace();
work?
Thanks in advance!
To remove all the contents of an element, jQuery offers .empty():
$('#hub').empty();
The variable is completely separate from the element, so no problems there. If you wanted to restore the original text, just use .text():
$('#hub').text('Hub');
Updated fiddle
You can do something like this:
$(document).ready(function(){
$('#hub').click(function(){
$(this).text() == 'Hub' ? $(this).html('text') : $(this).html('Hub');
});
});
On click if the text is 'Hub' change it to 'text' else change it again to 'Hub'.

Load Html Content if not exist JQuery AJAX

I have a page with 3 buttons. >Logos >Banners >Footer
When any of these 3 buttons clicked it does jquery post to a page which returns HTML content in response and I set innerhtml of a div from that returned content . I want to do this so that If I clicked Logo and than went to Banner and come back on Logo it should not request for content again as its already loaded when clicked 1st time.
Thanks .
Sounds like to be the perfect candidate for .one()
$(".someItem").one("click", function(){
//do your post and load the html
});
Using one will allow for the event handler to trigger once per element.
In the logic of the click handler, look for the content having been loaded. One way would be to see if you can find a particular element that comes in with the content.
Another would be to set a data- attribute on the elements with the click handler and look for the value of that attribute.
For example:
$(".myElements").click(function() {
if ($(this).attr("data-loaded") == false {
// TODO: Do ajax load
// Flag the elements so we don't load again
$(".myElements").attr("data-loaded", true);
}
});
The benefit of storing the state in the data- attribute is that you don't have to use global variables and the data is stored within the DOM, rather than only in javascript. You can also use this to control script behavior with the HTML output by the server if you have a dynamic page.
try this:
HTML:
logos<br />
banner<br />
footer<br />
<div id="container"></div>
JS:
$(".menu").bind("click", function(event) {
event.stopPropagation();
var
data = $(this).attr("data");
type = $(this).attr("type");
if ($("#container").find(".logos").length > 0 && data == "logos") {
$("#container").find(".logos").show();
return false;
}
var htmlappend = $("<div></div>")
.addClass(type)
.addClass(data);
$("#container").find(".remover-class").remove();
$("#container").find(".hidde-class").hide();
$("#container").append(htmlappend);
$("#container").find("." + data).load("file_" + data + "_.html");
return false;
});
I would unbind the click event when clicked to prevent further load requests
$('#button').click(function(e) {
e.preventDefault();
$('#button').unbind('click');
$('#result').load('ajax/test.html ' + 'someid', function() {
//load callback
});
});
or use one.click which is a better answer than this :)
You could dump the returned html into a variable and then check if the variable is null before doing another ajax call
var logos = null;
var banners = null;
var footer = null;
$(".logos").click(function(){
if (logos == null) // do ajax and save to logos variable
else $("div").html(logos)
});
Mark nailed it .one() will save extra line of codes and many checks hassle. I used it in a similar case. An optimized way to call that if they are wrapped in a parent container which I highly suggest will be:
$('#id_of_parent_container').find('button').one("click", function () {
//get the id of the button that was clicked and do the ajax load accordingly
});

jQuery event delegation with non-trivial HTML markup?

I have two DIVs, first one has a link in it that contains the id of the second DIV in its HREF attribute (complete setup on jsbin).
I want to animate the second DIV when user clicks on the first - anywhere on the first. I also want to use event delegation because I'll have many such "DIV couples" on a page (and I'm using a JS snippet from this SO answer).
If user clicks on the DIV itself, it will work - just check firebug console output. The problem is, if user clicks on one of the SPANs or the link itself, it doesn't work anymore.
How can I generalize the click handler to manage clicks on anything inside my DIV?
Here's the JS:
$('#a').click(function(e) {
var n = $(e.target)[0];
console.log(n);
if ( n && (n.nodeName.toUpperCase() == 'DIV') ) {
var id = $(n).find('a').attr('hash');
console.log(id);
$(id).slideToggle();
}
return false;
});
It took me so long to write up the question that I decided to post it anyway, perhaps someone suggests a better way.
Here's the solution I found (jsbin sandbox):
$('#a').click(function(e) {
var n = $(e.target)[0];
var name = n.nodeName.toLowerCase() + '.' + n.className.toLowerCase();
if (n && (name === "div.clicker" || $(n).parents("div.clicker").length )) {
var id = $(n).find('a').attr('hash');
if(!id) {
id = $(n).parents("div.clicker").find('a').attr('hash');
}
console.log(id);
}
return false;
});
Here is my solution. Not sure if that's exactly what you wanted, but it works for me.
$(document).ready(function() {
$('#a').click(function() {
var a = $("a", this);
$(a[0].hash).slideToggle();
});
});
Edit: Tested in both IE7 and Fx3
Edit: In that case...
$(function() {
$("a.tab").click(function() {
$($(this).attr("hash")).slideToggle();
return false;
});
});
Something like that might work (putting the tab class on anything that has a div "attached" to it). However, I'm not sure unless I actually see an example of it. Although if you want it to work when clicking on the span...you would attach the class to the span, and instead do:
$(function() {
$("span.tab").click(function() {
var a = $("a",this);
$(a.attr("hash")).slideToggle();
});
});
Not sure if you want an open div to close if another one is opened. If this doesn't solve your problem, it would help if you would put up an example on jsbin...

Categories

Resources