I need some help with my CasperJS script.
I don't know how can I get all my pictures as an array from the current folder.
And how to loop to insert each one in the correct input.
Mmmh, difficult to explain so there is my starting code.
I put comment where I have problem.
var casper = require('casper').create();
casper.start('http://imgchili.net/', function() {
// Get a list with all the picture from the current folder.
// For each picture, click this button.
this.mouseEvent('click', 'input.button1:nth-child(6)');
this.fillSelectors('form#upload_form', {
// Another loop here.
'.grey > input:nth-child(2)': /* First picture */,
'.grey > input:nth-child(4)': /* Second picture */,
'.grey > input:nth-child(6)': /* Third picture */
}, true);
casper.capture('captureTest.png');
});
// 8s can be too low if I have a lot of pictures!
casper.wait(8000, function() {
casper.capture('captureResult.png');
})
casper.then(function() {
this.echo(this.fetchText('textarea.input_field:nth-child(11)'));
})
casper.run();
EDIT:
Thanks it helps me a lot. But I have problem to loop the inputs.
var fs = require('fs'),
casper = require('casper').create(),
myImages = fs.list(fs.workingDirectory + '/img');
casper.start('http://imgchili.net/', function() {
// For each image, click to add a new upload input.
// Begin with 2 because 0 = "."" and 1 = "..".
for (var i = 2; i < myImages.length; i++) {
this.mouseEvent('click', 'input.button1:nth-child(6)');
}
// It doesn't work and show no error...
for (var i = 2; i < myImages.length; i++) {
j = i*2;
input = '.grey > input:nth-child(' + j + ')';
this.fillSelectors('form#upload_form', {
input : '/img/' + myImages[i],
}, false);
// Even this part doesn't work
console.log('i = ' + i + ' & imgName = ' + myImages[i]);
}
});
casper.then(function() {
casper.capture('result.png');
});
casper.run();
You can use PhantomJS file system to get your current folder files. Here is the API Documentation.
The following gets your current folders files, and then filters all .png's into a new array. You can then use a loop to click the button for each image. You will have to alter / add your own code because this does not accomplish the upload task. This will should help you though.
// vars
var fs = require('fs'); // reference to phantomJS file system
var myFolder = fs.list(fs.workingDirectory); // gets all files in current folder
var myImages = []; // only images from current folder
var url = 'http://imgchili.net/'; // starting url
var fileType = '.png'; // image file type to filter by
casper.then(function() {
// create array of just images
for (var i = 0; i < myFolder.length; i++) {
if (myFolder[i].indexOf(fileType) != -1) {
myImages.push(myFolder[i]);
}
}
// click for each image
for (i = 0; i < myImages.length; i++) {
this.mouseEvent('click', 'input.button1:nth-child(6)');
}
});
// wait for images to be uploaded
// set timeout or defaults to caspers step timeout
casper.waitForSelector('#page_body', function() {
casper.capture('captureResult.png');
}, 15000);
Related
How to get gif frames using node gm?
Example on PHP
$frames = new \Imagick( 'image.gif' )->coalesceImages();
https://github.com/aheckmann/gm
https://github.com/aheckmann/gm/issues/512
gm("./image.gif").identify(function (err, val) {
let frames_count = val.Scene.replace(/\d* of /, "");
for(let i = 0; i < frames_count; i++) {
let path = `./frame${i}.png`;
this.selectFrame(i).write(path, function () {
console.log(arguments[3]);
});
}
});
On IOS, when I close photoswipe to return to the page, it wont return to the scroll position I was at when I clicked the thumbnail.
Instead the page scrolls back to the # which was specified when I initially called the page.
For example if photoswipe is on www.somepage.html, and I navigate to the page using:
www.somepage.html#footer
and then scroll up and click a thumnail in #middle of page, on closing photoswipe, the page scrolls back down to the footer.
I've tried disabling history in the photswipe options, and i've also tried clearing the hash data from the url using:
//clear hash
//$(document).ready(function (e) {
// window.location.hash = '';
// window.history.pushState("", document.title, window.location.pathname);
//
//});
But none of it seems to work. If I navigate to the page without the # in the page, everthing is fine.
I'm guessing I may have to pass a variable in the url instead of the # and scroll to the div in question via javascript?
I already have the javascript in place to scroll, but I'm not sure how to read the variable from the url and then use it's value in Javascript.
If this is likely to be the best fix for the issue, could anyone give an example of the javascript code needed?
Here's my current scroll code:
$(function () {
$('a[href*=#]:not([href=#],[data-toggle],[data-target],[data-slide])').click(function () {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
If anyone else has the same issue, I've managed to fix this by passing the div id to the page in the query string rather than using a #.
Here's the code:
$(window).ready(function () {
if (document.location.search.length) {
target = getUrlVars()["id"];
scrollToID('#' + target, 750);
} else {
return;
}
//target = $url().param('id');
//if (target == '') return;
});
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
// scroll function
function scrollToID(id, speed){
var offSet = 100;
var targetOffset = $(id).offset().top - offSet;
var mainNav = $('#main-nav');
$('html,body').animate({scrollTop:targetOffset}, speed);
if (mainNav.hasClass("open")) {
mainNav.css("height", "1px").removeClass("in").addClass("collapse");
mainNav.removeClass("open");
}
}
if (typeof console === "undefined") {
console = {
log: function() { }
};
}
I want to upload multiple files to rails server and want to show separate progress bar for each files. I am using ng-file-upload to upload files. files are getting uploaded but it showing progress for only last file and not for others..I am attaching my code. please help.
Angular controller code:
$scope.upload_file = function() {
var files = $scope.files;
var uploadUrl = base_url+"/upload_image";
var job_id = $scope.directive.id;
if(current_user.role == "third_party_vendor" || current_user.role == "employee")
{
var source = current_user.user_login+"-"+current_user.role;
}
else
{
var source = $scope.dataObj.source["user_login"]+"-"+$scope.dataObj.source["role"];
}
if(job_id === "" || job_id === undefined || files === undefined || files === ""){
error_notification("Please select a job and a file.");
return;
}
hideLoader();
$("#upload_resume_queue").modal('show');
var formData = new Array();
formData['job_id'] = job_id;
formData['context'] = "inside_page";
formData['source'] = source;
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.log(file.name);
$scope.upload = $upload.upload({
url: uploadUrl,
data:{myObj: formData},
file: file,
}).progress(function(evt) {
//console.log('percent: ' +parseInt(100.0 * evt.loaded / evt.total));
file.progress = Math.round(evt.loaded * 100 / evt.total)
}).success(function(responseText) {
hideLoader();
try{
var response = responseText;
}catch(e){
error_notification("Invalid Excel file Imported.");
return;
}
if(response.status==='wrong_content_type')
error_notification("Please upload a valid file format.",0);
if(response.status==='job_application_present'){
$scope.duplicate = true;
$scope.jobID = job_id;
$scope.user_id = response.user_id;
$scope.application_id = response.application_id;
//showModal('#duplicate_application_modal');
error_notification("Job Application already present for this user and job.",0);
}
if(response.status==='invalid_email')
error_notification("The email in the resume is an invalid one.",0);
if(response.status==='success')
success_notification("The uploaded resume has been parsed.",0);
});
}
};
Html code:
<input type="file" class="required file_browse" ng-file-select="" ng-model="files" multiple />
I am not able test the following but, I think I found what is wrong.
In JavaScript variables are scoped to functions. So, in your for loop you change value of file in var file = files[i]; line. At the end, after for loop finished the value of file is the last file.
At some point .progress event is fired by ng-file-upload to notify you about progress (for one of the files). And you update the status, but, since file has the value of the last file, not the one you expected to be, the last file's status is being updated.
That's why only the last file updated. To solve, you need to access the correct file for each progress event. To do this, you can keep file variable using an anonymous function.
for (var i = 0; i < files.length; i++) {
(function(file) {
console.log(file.name);
$scope.upload = $upload.upload({
url: uploadUrl,
data:{myObj: formData},
file: file,
}).progress(function(evt) {
//console.log('percent: ' +parseInt(100.0 * evt.loaded / evt.total));
file.progress = Math.round(evt.loaded * 100 / evt.total)
}).success(function(responseText) {
// the other stuff
});
})(files[i])
}
In your code there may be other problems related to variable scopes and javascript event loop. For more information please take a look at this.
A have several views with WebViews on them. I need to make it in a coverFlowView. For that i make my views toImage, to put after on the coverFlow, but the issue is that i get images with webView not loaded... I tried to make setTimeout, but it doesn't help.
var cover = Titanium.UI.iOS.createCoverFlowView({
images: forflowImages
});
for (var k = start; k < cData.length; k++) {
r = Ti.UI.createView({});
for (var j = 0; j < child.objects.length; j++) {
tmp = Ti.UI.createWebView({
left : 10,
top : 10,
right : 10,
bottom : 10,
width : Ti.UI.FILL,
height : Ti.UI.SIZE,
willHandleTouches: true,
backgroundColor : '#fff2df',
});
tmp.html = obj.html;
no.add(tmp);
r.add(no);
}
}
r.addEventListener("load", function(e) {
blob = r.toImage();
});
forflowImages.push(blob);
}
cover.setImages(forflowImages);
With this code, coverFlowView doesn't have any views.
setTimeout(function() {
blob = r.toImage();
}, 500);
Also doesn't help, i have activity indicator on the page saved, content seems didn't have time to load before toImage function acted.
You are ordering things the wrong way, and you have multiple syntax errors, also you are listeneing for the load event on the wrong type of view, you shold be listeneing on the WebView, try this instead:
var forflowImages = [];
var container = // This should already be in the view stack somewhere
var cover = Titanium.UI.iOS.createCoverFlowView();
function loadListener(e) {
forflowImages.push(e.source.toImage());
if(forFlowImages.length == child.objects.length) {
// We have all the images for cover flow
cover.setImages(forflowImages);
}
}
var containerView = Ti.UI.createView();
for (var j = 0; j < child.objects.length; j++) {
var tmp = Ti.UI.createWebView({html : obj.html);
tmp.addEventListener("load", loadListener);
container.add(tmp);
tmp.repaint();
}
I removed some of your code that was syntactically incorrect and trimmed it down so it would be easy to understand. All this code does is add an event listener that handles the conversion of a webview to an image.
I have a webpage with prettyPhoto and a youtube video inside the web page.
With jquery I do:
$("#youtubevideo embed").attr("wmode", "opaque");
also tried $("#youtubevideo embed").attr("wmode", "transparent");
In firefox image is over the youtube video, but the corners of pretty photo are missing. Not really missing because if I scroll up ad down they are shown. But still they don't appear correctly.
In Chrome video is still on top of the images :( Is there a way to fix this? Thanks
after 2 days of searching the web for the answer i've found a pure JS function that fix it in all browsers!
there you go:
function fix_flash() {
// loop through every embed tag on the site
var embeds = document.getElementsByTagName('embed');
for (i = 0; i < embeds.length; i++) {
embed = embeds[i];
var new_embed;
// everything but Firefox & Konqueror
if (embed.outerHTML) {
var html = embed.outerHTML;
// replace an existing wmode parameter
if (html.match(/wmode\s*=\s*('|")[a-zA-Z]+('|")/i))
new_embed = html.replace(/wmode\s*=\s*('|")window('|")/i, "wmode='transparent'");
// add a new wmode parameter
else
new_embed = html.replace(/<embed\s/i, "<embed wmode='transparent' ");
// replace the old embed object with the fixed version
embed.insertAdjacentHTML('beforeBegin', new_embed);
embed.parentNode.removeChild(embed);
} else {
// cloneNode is buggy in some versions of Safari & Opera, but works fine in FF
new_embed = embed.cloneNode(true);
if (!new_embed.getAttribute('wmode') || new_embed.getAttribute('wmode').toLowerCase() == 'window')
new_embed.setAttribute('wmode', 'transparent');
embed.parentNode.replaceChild(new_embed, embed);
}
}
// loop through every object tag on the site
var objects = document.getElementsByTagName('object');
for (i = 0; i < objects.length; i++) {
object = objects[i];
var new_object;
// object is an IE specific tag so we can use outerHTML here
if (object.outerHTML) {
var html = object.outerHTML;
// replace an existing wmode parameter
if (html.match(/<param\s+name\s*=\s*('|")wmode('|")\s+value\s*=\s*('|")[a-zA-Z]+('|")\s*\/?\>/i))
new_object = html.replace(/<param\s+name\s*=\s*('|")wmode('|")\s+value\s*=\s*('|")window('|")\s*\/?\>/i, "<param name='wmode' value='transparent' />");
// add a new wmode parameter
else
new_object = html.replace(/<\/object\>/i, "<param name='wmode' value='transparent' />\n</object>");
// loop through each of the param tags
var children = object.childNodes;
for (j = 0; j < children.length; j++) {
try {
if (children[j] != null) {
var theName = children[j].getAttribute('name');
if (theName != null && theName.match(/flashvars/i)) {
new_object = new_object.replace(/<param\s+name\s*=\s*('|")flashvars('|")\s+value\s*=\s*('|")[^'"]*('|")\s*\/?\>/i, "<param name='flashvars' value='" + children[j].getAttribute('value') + "' />");
}
}
}
catch (err) {
}
}
// replace the old embed object with the fixed versiony
object.insertAdjacentHTML('beforeBegin', new_object);
object.parentNode.removeChild(object);
}
}
}
now you can just run in when the page loads with jQuery:
$(document).ready(function () {
fix_flash();
}
Also you can add ?wmode=transparent to each youtube link
So if you have code like:
<iframe src="http://www.youtube.com/embed/aoZbiS20HGI">
</iframe>
You need to change it to:
<iframe src="http://www.youtube.com/embed/aoZbiS20HGI?wmode=transparent">
</iframe>