How do I remove an .append() then add an .append() - javascript

This is to show a check for a diagnostic page. I have an .append(not_ok) but when the swf file is 100% loaded I want to remove the not_ok append then add an .append(ok).
function callbackfunk(e){
$(".FlashNotLoaded").css("color", "red").append(not_ok);
var timer = setInterval(function(){
if(e.ref.PercentLoaded() === 100){
$(".FlashLoaded").remove();
$(".FlashLoaded").css("color", "green").append(ok);
}
}, 1000);
}
swfobject.embedSWF("/static/diag/countdown.swf", "flashDiv", "550", "400", "8.0.0", "expressInstall.swf", flashvars, params, attributes, callbackfunk);
The .append(not_ok) will be removed but the .append(ok) will not replace it. I've tried
.replaceWith(ok) but that doesn't seem to work either.

Generally with jQuery, you do that by leaving both on the page in the same spot. jQuery(notOkSelector).hide(); and jQuery(okSelecter).show();.
Hide makes the object display:none, and show reverses this.
EDIT: As long as the objects are already in the DOM (by default with display:none;)...
To show notLoaded:
$(".FlashLoaded").hide(); // it doesn't hurt to hide an already hidden object.
var notLoaded = $(".FlashNotLoaded");
notLoaded.css( 'color', 'red' );
notLoaded.show();
To hide notLoaded and show ok:
$(".FlashNotLoaded").hide();
var flashLoaded = $(".FlashLoaded");
flashLoaded.show();
flashLoaded.css( 'color', 'green' );
EDIT including your above code: Your coude may look like the following...
function callbackfunk(e){
$(".FlashLoaded").hide();
$(".FlashNotLoaded").css("color", "red").show();
var timer = setInterval(function(){
if(e.ref.PercentLoaded() === 100){
$(".FlashNotLoaded").hide();
$(".FlashLoaded").css("color", "green").show();
clearInterval(timer);
}
}, 1000);
}

this line
$(".FlashLoaded").remove();
removes the element(s) from the DOM, so the following line can't append anything to the DOM
$(".FlashLoaded").css("color", "green").append(ok);
I suppose you wanted to remove ok instead.

Are you appending new HTML tags? If so you can use jQuery replaceWiht() , it replace an existing element with a new element.

Related

Get child div of existing div using anchors next element without ID or class using JQuery

As you can see below $(nextDiv + ' > div').eq(i).fadeIn('slow'); does not work as it seems to be malformed. nextDiv is on inspection the div below the anchor, how do I achieve getting the two divs that sit inside it?
HTML:
Sub Click
<div>
<div>I want this to fade in on the click</div>
<div>Followed by this etc.</div>
</div>
Javascript:
function subClick(myAnchor)
{
var nextDiv = $(myAnchor).next();
function showDiv(i) {
if (i > 2) return;
setTimeout(function () {
$(nextDiv + ' > div').eq(i).fadeIn('slow');
showDiv(++i);
}, 50);
}
showDiv(0);
}
You are trying to concatenate a string with jQuery, that won't provide a valid selector. The concatenation would provide something like "[object Object] > div" which doesn't select any elements in your code.
Instead, get the div children using children() method on the jQuery nextDiv object.
nextDiv.children('div').eq(i).fadeIn('slow');
If there are only two divs then you can reduce the code using delay() method.
function subClick(myAnchor) {
var nextDivs = $(myAnchor).next().children();
// if you want to do the animation after the first then
// use the below code, where second animation initializing within
// the first animation success callback, which also provides a 50ms
// delay for second animation(avoid .delay(50) if you dont nedd that delay)
// nextDivs.eq(0).fadeIn('slow', function() {
// nextDivs.eq(1).delay(50).fadeIn('slow');
// });
// in case you just want to provide a 50ms delay
// between animation then use, your code does this
nextDivs.eq(0).fadeIn('slow');
nextDivs.eq(1).delay(50).fadeIn('slow');
}
var nextDiv = $(myAnchor).next(); then nextDiv is an object not a selector. If you want to access its div children use this:
nextDiv.children('div').eq(i).fadeIn('slow');

Changing / writing to element using casperjs and capture screenshot after the change

Is it possible to change / add style to an element / DOM using casperjs ?
I would like to highlight the element before I capture a screenshot
I've tried doing the following:
1.Change the element - just adding border - this part works.
$(":contains('something')").filter(function() {
return (
$(this).clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.filter(":contains('something')").length > 0)
}).css('border', 'solid 1px black');
2.Then capture a screenshot after the change.
this.capture('test.png', undefined, {
format: 'jpg',
quality: 75
});
Screenshot is taken but without the changes I've made on the element.
I would do it that way :
First here a function which returns the css property of an element
//return the css property of an element called by its selector
//getElementBounds() not sufficient
casper.css = function(selector,propertyName){
"use strict";
var css = this.evaluate(function(sel,prop) {
return $(sel).css(prop);
},selector,propertyName);
return css;
};
And after i would use waitFor() :
casper.thenEvaluate(function(){
//here your jQuery code
})
.waitFor(function check(){
//wait this code to be true, so when one of your element has been modified
return (casper.css("your selector","border")==="solid 1px black");
//then execute this function asking for the capture
},function then(){
this.capture('test.png');
}
//if waitFor never becomes true, that means your jQuery code or my function doesn't work
},function timeout(){
casper.test.fail("Fail to modify elements");
});
I just give you my idea, the code doesn't work, or it might be if you specify the selector of one element which will be modified.

how to repeat same Javascript code over multiple html elements

Note: Changed code so that images and texts are links.
Basically, I have 3 pictures all with the same class, different ID. I have a javascript code which I want to apply to all three pictures, except, the code needs to be SLIGHTLY different depending on the picture. Here is the html:
<div class=column1of4>
<img src="images/actual.jpg" id="first">
<div id="firsttext" class="spanlink"><p>lots of text</p></div>
</div>
<div class=column1of4>
<img src="images/fake.jpg" id="second">
<div id="moretext" class="spanlink"><p>more text</p></div>
</div>
<div class=column1of4>
<img src="images/real.jpg" id="eighth">
<div id="evenmoretext" class="spanlink"><p>even more text</p></div>
</div>
Here is the Javascript for the id="firsttext":
$('#firstextt').hide();
$('#first, #firsttext').hover(function(){
//in
$('#firsttext').show();
},function(){
//out
$('#firsttext').hide();
});
So when a user hovers over #first, #firsttext will appear. Then, I want it so that when a user hovers over #second, #moretext should appear, etc.
I've done programming in Python, I created a sudo code and basically it is this.
text = [#firsttext, #moretext, #evenmoretext]
picture = [#first, #second, #eighth]
for number in range.len(text) //over here, basically find out how many elements are in text
$('text[number]').hide();
$('text[number], picture[number]').hover(function(){
//in
$('text[number]').show();
},function(){
//out
$('text[number]').hide();
});
The syntax is probably way off, but that's just the sudo code. Can anyone help me make the actual Javascript code for it?
try this
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink").show();
});
Why not
$('.spanlink').hide();
$('.column1of4').hover(
function() {
// in
$(this).children('.spanlink').show();
},
function() {
// out
$(this).children('.spanlink').hide();
}
);
It doesn't even need the ids.
You can do it :
$('.column1of4').click(function(){
$(this); // the current object
$(this).children('img'); // img in the current object
});
or a loop :
$('.column1of4').each(function(){
...
});
Dont use Id as $('#id') for multiple events, use a .class or an [attribute] do this.
If you're using jQuery, this is quite easy to accomplish:
$('.column1of4 .spanlink').hide();
$('.column1of4 img').mouseenter(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').show();
});
$('.column1of4 img').mouseleave(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').hide();
});
Depending on your markup structure, you could use DOM traversing functions like .filter(), .find(), .next() to get to your selected node.
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink, img").show();
});
So, the way you would do this, given your html would look like:
$('.column1of4').on('mouseenter mouseleave', 'img, .spanlink', function(ev) {
$(ev.delegateTarget).find('.spanlink').toggle(ev.type === 'mouseenter');
}).find('.spanlink').hide();
But building on what you have:
var text = ['#firsttext', '#moretext', '#evenmoretext'];
var picture = ['#first', '#second', '#third'];
This is a traditional loop using a closure (it's better to define the function outside of the loop, but I'm going to leave it there for this):
// You could also do var length = text.length and replace the "3"
for ( var i = 0; i < 3; ++i ) {
// create a closure so that i isn't incremented when the event happens.
(function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(',')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
})(i);
}
And the following is using $.each to iterate over the group.
$.each(text, function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(', ')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
});
Here's a fiddle with all three versions. Just uncomment the one you want to test and give it a go.
I moved the image inside the div and used this code, a working example:
$('.column1of4').each(function(){
$('div', $(this)).each(function(){
$(this).hover(
function(){
//in
$('img', $(this)).show();
},
function(){
//out
$('img', $(this)).hide();
});
});
});
The general idea is 1) use a selector that isn't an ID so I can iterate over several elements without worrying if future elements will be added later 2) locate the div to hide/show based on location relational to $(this) (will only work if you repeat this structure in your markup) 3) move the image tag inside the div (if you don't, then the hover gets a little spazzy because the positioned is changed when the image is shown, therefore affecting whether the cursor is inside the div or not.
EDIT
Updated fiddle for additional requirements (see comments).

jQuery, selecting just number from id like "article-23"

All right, I have a div tag which got a class="blog-post" and id like id="article-23" (where "23" could be any number, as it is id of blog post in a database). I need to somehow get just a number from that id and than apply some rules to that div tag. So say:
if number from id % 2 == 0 {
set text colour black to associated div tag with class of blog-post
} else {
set text colour white to associated div tag with class of blog-post
}
Thats just a "pseudo" code to show logic that I wan't to apply dependent if number from id is even or odd, but the question remains same, how do I just get number from id like "article-23" ?
As simple as
var number = "article-23".match(/\d+/)[0];
But you have to be sure that any digit exists in the string, otherwise you'd get a error.
You can actually apply rules via function, which makes this the cleanest solution (in my opinion):
$(".blog-post").css('color', function () {
return +this.id.replace('article-', '') % 2 ? 'blue' : 'red';
});
http://jsfiddle.net/ExplosionPIlls/Jrc5u/
Try this:
$('.blog-post[id^="article-"]').each(function () {
if (parseInt(this.id.replace('article-', '')) % 2 === 0) {
$('#' + this.id).css('color', 'black');
} else {
$('#' + this.id).css('color', 'white');
}
});
jsFiddle Demo
As an alternative, HTML5 supports these things called "data attributes", which are specifically meant for attaching data to your DOM without abusing things like the "class" or "id" attributes. jQuery provides a handy .data method for reading these attributes in a more obvious way.
You can add your own numeric ID attribute using something like "data-id":
<div class="blog-post" data-id="23" />
$("#blog-post").each(function () {
console.log($(this).data("id")); // Look up the data-id attribute
});
If I'm understanding correctly, you want the number after the hyphen of the id tag of your .blog-post class.
var article = $(".blog-post").attr('id'); //get the id
var article = article.split("-"); // split it on hyphens
return article = article[article.length-1]; // return the last element

Change a variable or activate a JS-linked <select> dropdown with Greasemonkey

I'm looking to change a javascript variable on page load with Greasemonkey.
The variable I'm looking to change is iDisplayLength the default value is 25, I want to change it to -1 on page load.
This is the script I tried; it did not work:
function changeTheDefaultViewVarLol() {
location.href = "javascript:void(windows.iDisplayLength = -1)";
};
changeTheDefaultViewVarLol();
Edit: From a comment below, the target page is tf2spreadsheet.blogspot.com.
The OP is actually trying to change the number of rows displayed on the page -- a function that is triggered by the "Show {x} entries" <select> dropdown.
You would just use:
unsafeWindow.iDisplayLength = -1;
No need for any of that changeTheDefaultViewVarLol() stuff.
However, this will not have the effect that you want if iDisplayLength is used by the page just after the page sets it to 25.
You will probably have to call a JS function to apply the new value. Link to the target page if this is the case.
Update for additional page information:
What you are actually trying to do is to invoke the "Show All entries" functionality of that page.
So, don't think in terms of poking JS variables, think in terms of activating whatever JS is tied to that <select>.
For a normal page similar to the one you specified, code like this would do it:
var showAllOpt = document.querySelector ('#main_table_length select option[value="-1"]');
var changeEvent = document.createEvent ("HTMLEvents");
if (showAllOpt) {
showAllOpt.parentNode.selectedIndex = showAllOpt.index;
changeEvent.initEvent ("change", true, true);
showAllOpt.parentNode.dispatchEvent (changeEvent);
}
BUT, that page AJAXes-in the desired table long after the page "loads". So, an additional step is needed, like so:
var showAllEntriesSelect = setInterval ( function() {
setSelectValueWhenitLoads (
"#main_table_length select option",
"-1",
showAllEntriesSelect
);
}
, 200
);
function setSelectValueWhenitLoads (cssSelector, targetValue, timerVar) {
var showAllOpt = document.querySelector (
cssSelector + '[value="' + targetValue + '"]'
);
if (showAllOpt) {
clearInterval (timerVar);
showAllOpt.parentNode.selectedIndex = showAllOpt.index;
var changeEvent = document.createEvent ("HTMLEvents");
changeEvent.initEvent ("change", true, true);
showAllOpt.parentNode.dispatchEvent (changeEvent);
}
}

Categories

Resources