Script loaded with HeadJS runs only on second click - javascript

Script loaded with HeadJS runs only on second click. How to get Aviary launcher on first click?
http://jsfiddle.net/ynts/6hgEb/
function aviary(id, src) {
var $id = id;
var $src = src;
head.load(
"http://feather.aviary.com/js/feather.js",
function() {
var featherEditor = new Aviary.Feather({
apiKey: 12345,
apiVersion: 3
// ... ///
});
featherEditor.launch({
image: $id,
url: $src
});
}
);
}
$(document).on('click', 'img', function(){
var $img = $(this).attr('src');
aviary('edit-pic', $img);
});

You need to wait for the plugin to initialize, before calling the launch function. There is onLoad event you can use:
var featherEditor = new Aviary.Feather({
apiKey: 12345,
apiVersion: 3,
onLoad: function() {
featherEditor.launch({
image: $id,
url: $src
});
}
});

Answering mikebridge, for the case when it doesn`t open a second time:
Some dark reason prevents feather to be instantiated more than once.
Use window.globalAviaryFeather to hold the instance.
function launch(url) {
window.globalAviaryFeather.launch({
image: "imgId",
url: url
})
}
var url = "..."
if (window.globalAviaryFeather) {
launch(url)
} else {
window.globalAviaryFeather = new Aviary.Feather({
...
onLoad: function() {
self.launch(url)
}
})
}

Related

clevertap event not trigger in javascript

I have to create subscribe and unsubscribe email page. all functionality is working fine. but when I call clevertap event, CT event is not triggered in CT dashboard.
<script type="text/javascript">
var clevertap = {
event: [],
profile: [],
account: [],
onUserLogin: [],
notifications: [],
privacy: [],
};
// replace with the CLEVERTAP_ACCOUNT_ID with the actual ACCOUNT ID value from your Dashboard -> Settings page
clevertap.account.push({ id: "TEST-000-000-001Z" });
clevertap.privacy.push({ optOut: false });
clevertap.privacy.push({ useIP: true });
(function () {
var wzrk = document.createElement("script");
wzrk.type = "text/javascript";
wzrk.async = true;
wzrk.test = 'page';
wzrk.src =
("https:" == document.location.protocol
? "https://d2r1yp2w7bby2u.cloudfront.net"
: "http://static.clevertap.com") + "/js/a.js";
var s = document.getElementsByTagName("script")[0];
console.log('s.parentNode : ', s.parentNode)
s.parentNode.insertBefore(wzrk, s);
wzrk.onerror = (e) => reject(new Error(`Failed to load script '${src}'. Error: ${e.toString()}`));
})();
</script>
onload I have call page view event
<script>
window.onload = function () {
console.log('on load');
var isReEncode = false; //Should be true only if your server is url encoding the URL on unsubscribe landing page
var withGroups = true; // Should be true if the unsubscribe groups should be displayed on the landing page.
var stageName;
$WZRK_WR.getEmail(false, withGroups);
showSectionBaseOnStage();
setTimeout(() => {
clevertap.event.push("Page viewed", {
"ProductName": "ABC",
"PageTitle": "Unsubscribe",
"Page": 'Group Unsubscribe',
"PageURL": window.location.href,
"SourceURL":""
});
console.log("on load ct event call", clevertap);
}, 5000);
};
</script>
Page viewed event not trigger
Please let me know where I do a mistake.
Thank you

Image preview script breaks on uploading the same image that was previously deleted

I am using this package, and I have modified it a bit, so that I can upload, drag and sort the images and preview them in the browser. Uploading works fine, and deleting of images. But I found a scenario when the script breaks. When I have more than one image and I delete the first image, on trying to upload the same image that I deleted the script doesn't work anymore. But if I don't try to upload the same image immediately and first upload some other and then the one that was deleted, then it works. Also, I don't get any errors in the console. I am not sure how to fix this.
My full code is here.
This is part of the code:
$(document).ready(function () {
var imageCounter = 0;
$('#articleForm').submit(function () {
uploadPosition();
});
function uploadPosition() {
var uploadedImagesPositions = [];
$.each($('.jFiler-item-thumb-image'), function (index, value) {
$(this).attr('data-position-index', index);
uploadedImagesPositions[index] = $(this).find('img').attr('src');
});
if (!$('input[name="uploadedItems"]').length) {
$('<input>', {
type: "hidden",
name: "uploadedItems"
}).appendTo('#articleForm')
}
$('input[name="uploadedItems"]').val(JSON.stringify(uploadedImagesPositions));
$("input[name^='jfiler-items-exclude-']:hidden").detach();
console.log(uploadedImagesPositions);
}
$('#upload').filer({
limit: null,
maxSize: null,
extensions: null,
changeInput: '<div class="jFiler-input-dragDrop"><h1>+</h1></div>',
showThumbs: true,
appendTo: '.uploaded_items',
theme: "default",
templates: {
box: '<div class="jFiler-item-list"></div>',
item: '<div class="jFiler-item img-container dragdiv"></div>',
itemAppend: '<div class="jFiler-item img-container dragdiv"></div>',
progressBar: '<div class="bar"></div>',
itemAppendToEnd: false,
removeConfirmation: false,
_selectors: {
list: '.jFiler-item-list',
item: '.jFiler-item',
progressBar: '.bar',
remove: '.jFiler-item-trash-action',
}
},
uploadFile: {
url: "/admin/articles/ajax",
data: {
'_token': $('input[name="_token"]').val()
},
type: 'POST',
enctype: 'multipart/form-data',
beforeSend: function () {},
success: function (data, el) {
uploadedImagesPositions = [];
console.log(data);
var filenameArray = data.split('/');
var name = filenameArray.slice(-1).pop();
var filename = name.replace(/[\/\s()]/g, '');
var imageContainer = $('[data-jfiler-index="' + imageCounter + '"]').first();
$('<div class="jFiler-item-thumb-image"><img src="/imagecache/thumb/' + filename + '"></div><div class="overlay"><span><i class="jFiler-item-trash-action ion-trash-a"></span></div>').appendTo(imageContainer);
imageCounter++;
$(".dragdiv").each(function () {
makeElementAsDragAndDrop($(this));
});
$('.images-refresh').hide();
$('.images-refresh').click(function () {
$(this).closest("form").submit()
});
function makeElementAsDragAndDrop(elem) {
$(elem).draggable({
revert: "invalid",
cursor: "move",
helper: "clone"
});
$(elem).droppable({
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function (event, ui) {
uploadedImagesPositions = [];
$('.images-form a').hide();
$('.images-refresh').show();
var $dragElem = $(ui.draggable).clone().replaceAll(this);
$(this).replaceAll(ui.draggable);
makeElementAsDragAndDrop(this);
makeElementAsDragAndDrop($dragElem);
}
});
}
var parent = el.find(".jFiler-jProgressBar").parent();
el.find(".jFiler-jProgressBar").fadeOut("slow", function () {
$("<div class=\"jFiler-item-others text-success\"><i class=\"icon-jfi-check-circle\"></i> Success</div>").hide().appendTo(parent).fadeIn("slow");
});
},
error: function (el) {
console.log(el);
var parent = el.find(".jFiler-jProgressBar").parent();
el.find(".jFiler-jProgressBar").fadeOut("slow", function () {
$("<div class=\"jFiler-item-others text-error\"><i class=\"icon-jfi-minus-circle\"></i> Error</div>").hide().appendTo(parent).fadeIn("slow");
});
},
statusCode: {},
onProgress: function () {},
},
dragDrop: {
dragEnter: function () {},
dragLeave: function () {},
drop: function () {},
},
addMore: true,
clipBoardPaste: true,
excludeName: null,
beforeShow: function () {
return true
},
onSelect: function () {},
afterShow: function () {},
onRemove: function (el) {
imageCounter = $('.img-container').size() - 1;
//uploadPosition();
//console.log(el.find('img').attr('src'));
},
onEmpty: function () {
imageCounter = 0;
},
captions: {
button: "Choose Files",
feedback: "Choose files To Upload",
feedback2: "files were chosen",
drop: "Drop file here to Upload",
removeConfirmation: "Are you sure you want to remove this file?",
errors: {
filesLimit: "Only {{fi-limit}} files are allowed to be uploaded.",
filesType: "Only Images are allowed to be uploaded.",
filesSize: "{{fi-name}} is too large! Please upload file up to {{fi-maxSize}} MB.",
filesSizeAll: "Files you've choosed are too large! Please upload files up to {{fi-maxSize}} MB."
}
}
});
});
Update
I have updated fiddle with HTML and CSS as well as javascript code, unfortunately, I couldn't get it to work, so not sure how helpful it is, but at least you can see the full code.
I am using this scripts on my page where I upload images:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js" integrity="sha384-I6F5OKECLVtK/BL+8iSLDEHowSAfUo76ZL9+kGAgTRdiByINKJaqTPH/QVNS1VDb" crossorigin="anonymous"></script>
<script type="text/javascript" src="{{ asset('js/foundation/foundation.min.js') }}"></script>
<script>$(document).foundation();</script>
<script type="text/javascript" src="{{ asset('js/jquery-ui/jquery-ui.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('js/jquery-filer/jquery-filer.js') }}"></script>
jquery-filer is the script that I use for upload, the one that I have in fiddle.
And this is my server-side function for ajax upload. I am using PHP laravel in the backend:
public function ajaxUpload() {
if (Input::hasFile('file')) {
$files = Input::file('file');
foreach ($files as $file) {
$time = microtime(true);
$name = $file->getClientOriginalName();
$filename = $time.'-'.preg_replace('/[(\)\s]/u', '', $name);
if(substr($file->getMimeType(), 0, 5) == 'image') {
try {
$original = Image::make($file)->save(public_path($this->destinationPath.'/'.$filename));
\Log::info('try: '.$filename."\n");
} catch (Exception $e) {
\Log::info('Caught exception: '.$e->getMessage(). "\n");
}
$img = Image::cache(function($image) use ($original){
return $image->make($original);
});
}
}
}
return $this->destinationPath.$filename;
}
I have tried to salvage the problem part in your code and came up with this (Fiddle).
The problem part is probably in the success function. Instead of trying to get element by its index, use the 2nd argument passed to the success function.
success: function(data, el) {
uploadedImagesPositions = [];
var filenameArray = data.split('/');
var name = filenameArray.slice(-1).pop();
var filename = name.replace(/[\/\s()]/g, '');
// Instead of this
// var imageContainer = $('[data-jfiler-index="' + imageCounter + '"]').first();
// Use this
var imageContainer = el;
$('<div class="jFiler-item-thumb-image"><img src="/imagecache/thumb/' + filename + '"></div><div class="overlay"><span><i class="jFiler-item-trash-action ion-trash-a"></span></div>').appendTo(imageContainer );
}
The problem could also be caused by your server side, which we have no access right now.
Try to update to https://innostudio.de/fileuploader/ (jQuery.filer was transfered to the Fileuploader)
I was also using a JS image uploader which has the same type of issue. When a user uploads an image and deletes it and uploads the same image again, it does not work.
So I fixed it using:
$('input[type="file"]').val(null);
in the image deleted event.

Use a prepended image as wallpaper using Mozactivity Firefox OS

I want to fetch an image from the web and set it as wallpaper on the Firefox OS device.
So far I've tried two approaches,
$(document).on( 'click', '#share-image', function() {
walp = new Image()
walp.onload = function () {
var walCanvas = document.createElement('canvas');
walCanvas.width = walp.width;
walCanvas.height = walp.height;
var walCtx = walCanvas.getContext('2d');
walCtx.drawImage(walp,0,0);
walCanvas.toBlob( function (walBlob) {
var Activitiy = new MozActivity({
name: 'share',
data: {
type: 'image/*',
number: 1,
blobs: [walBlob]
}
});
});
};
walp.src = image; //image is the link to jpeg.
});
And this one...
var shareImage = document.querySelector("#share-image"),
imgToShare = document.querySelector('#prependedImage');
alert(imgToShare);
if (shareImage && imgToShare) {
shareImage.onclick = function () {
if(imgToShare.naturalWidth > 0) {
// Create dummy canvas
var blobCanvas = document.createElement("canvas");
blobCanvas.width = imgToShare.width;
blobCanvas.height = imgToShare.height;
// Get context and draw image
var blobCanvasContext = blobCanvas.getContext("2d");
blobCanvasContext.drawImage(imgToShare, 0, 0);
// Export to blob and share through a Web Activitiy
blobCanvas.toBlob(function (blob) {
new MozActivity({
name: "share",
data: {
type: "image/*",
number: 1,
blobs: [blob]
}
});
});
}
else {
alert("Image failed to load, can't be shared");
}
};
}
Both work for a locally saved image but don't work for the image that is fetched from a remote location.
I've also tried following approaches.
var pre = '<img width="100%" data-l10n-id="prependedImage" id="prependedImage" src="'+image+'" />';
$('#image1').prepend(pre);
and
$('#prependedImage').attr('src',image);
Both work, but neither presents the wallpaper menu unless it is a locally saved image.
I'm new to javascript and would appreciate an answer which explains what's wrong with code samples.
Thanks.
Can you try something like:
var xhr = new XMLHttpRequest({
mozSystem: true
});
xhr.open("GET", "http://25.media.tumblr.com/4751d1eccf9311ee0e05bdff819a7248/tumblr_n2yxzxzxr81rsg8blo1_250.png", true);
xhr.responseType = "blob";
xhr.onload = function () {
//sample activity
var activity = new MozActivity({
name: "share",
data: {
type: "image/*",
number:1,
blobs: [this.response],
filenames:["wallpapertest.png"]
},
});
};
xhr.onerror = function () {
alert("Error with System XHR");
};
xhr.send();
You will also need to set the app as privileged and add the systemxhr permission in the manifest:
"permissions": {
"systemXHR": {}
},
"type": "privileged"

How to jasmine test jQuery post ajax properties (e.g url)

I have this basic jQuery post to a url which I would like to test it. I do Sinon create server test already, but I'd like to test the url and properties given in the method as well, but I got error because jQuery.post(url, data).always(callback) cannot be called on undefined object.
And also what else should I be testing?
Here's my jQuery code.
define(['jquery'], function (jQuery) {
var ProductListingService = function () {
var self = this;
self.create = function (sku, quantity, price, callback) {
var url = '/url';
var data = { 'sku': sku, 'quantity': quantity, 'price': price };
jQuery.post(url, data).always(callback);
};
};
return ProductListingService;
});
This is my test
define(['service/ProductListingService'], function (ProductListingService) {
describe('ProductListingService', function () {
var productListingService, server;
beforeEach(function () {
productListingService = new ProductListingService();
server = sinon.fakeServer.create();
});
it('posts and call to /url', function () {
server.respondWith('POST', '/url',
[201, { "Content-Type": "application/json" }, '']
);
var callback = sinon.spy();
productListingService.create('sku', '1', 10.0, callback);
server.respond();
expect(callback.calledOnce).toBeTruthy();
});
it('posts and call to /url', function () {
spyOn(jQuery, "post").andCallFake();
productListingService.create('sku', '1', 10.0, sinon.spy());
expect(jQuery.post.mostRecentCall.args[0]["url"]).toEqual("/api/listing/create");
});
});
});
I think the easier solution is replacing sinon with Jasmine's ajax.js (http://jasmine.github.io/2.0/ajax.html):
define(['service/ProductListingService'], function (ProductListingService) {
describe('ProductListingService', function () {
var productListingService;
beforeEach(function () {
productListingService = new ProductListingService();
jasmine.Ajax.install();
});
afterEach(function() {
jasmine.Ajax.uninstall();
});
it('posts and call to /url', function () {
var callback = sinon.spy();
productListingService.create('sku', '1', 10.0, callback);
var request = jasmine.Ajax.requests.mostRecent();
request.response({
"status": 201,
"contentType": "application/json",
"responseText": ""
});
expect(request.method).toEqual("POST");
expect(request.url).toEqual("/url");
expect(callback.calledOnce).toBeTruthy();
});
it('posts and call to /url', function () {
productListingService.create('sku', '1', 10.0, sinon.spy());
expect(jasmine.Ajax.requests.mostRecent().url).toEqual("/api/listing/create");
});
});
});

Defining multiple instances of a jquery ui widget on a single page

I am developing a website where I use a custom build jQuery widget to load data into multiple divs.
This is the code for the widget:
(function ($, window, document, undefined) {
$.widget ("my.contentloader", {
options: {
loading_message: true
},
_create: function () {
var that = this;
$.ajax ({
type: "POST",
url: that.options.url,
data: {data: that.options.formdata, limit: that.options.limit, offset: that.options.offset},
beforeSend: function (html) {
if (that.options.loading_message) {
$(that.options.target_area).html ("<div id='loading'>Loading</div>");
}
},
success: function (html) {
if (that.options.loading_message) {
$('#loading').remove ();
}
$(that.options.target_area).html (html);
},
error: function (html) {
$(that.options.error_area).html (html);
}
});
},
_setOption: function (key, value) {
this.options[key] = value;
$.Widget.prototype._setOption.apply (this, arguments);
}
});
})(jQuery, window, document);
I load data using the widget like this:
$('#targetdiv').contentloader ({
url: '<?php echo $action_url; ?>',
target_area: '#popup_box',
formdata: {'username' : username_email, 'password' : password}
});
I am having problems loading multiple instances on the same page.
Is there a way to not instantiate the widget on a specific div like this?
$('#targetdiv').contentloader
I think you need to assign each instance to a variable. That way, you can control each instance, or write a function that iterates over an array of instances.
var contentLoaders = [];
$('.target-div').each(function(i, data) {
contentLoaders[i] = $.widget("my.contentloader", { ... });
});
So then you should be able to operate on each loader independently, like:
for (var i in contentLoaders) {
var contentLoader = contentLoaders[i];
contentLoader.option( ... );
}
Also, you're using the DOM ID $('#loading') for multiple instances of the widget. This is wrong. You need to either use separate loaders for each widget, or else check to see if the ID exists and only insert the new node if it doesn't exist. And same for removing it.
** I've added this example block, hope it helps: **
//
// This is a way to do it if you want to explicitly define each contentloader.
// Below that, I'll write out a way to define the contentloaders in a loop.
//
var contentLoader1 = $('#targetdiv1').contentloader ({
url: '<?php echo $action_url; ?>',
target_area: '#popup_box',
formdata: {'username' : username_email, 'password' : password}
});
contentLoader1.option('url', 'http://google.com');
var contentLoader2 = $('#targetdiv2').contentloader ({
url: '<?php echo $action_url; ?>',
target_area: '#popup_box',
formdata: {'username' : username_email, 'password' : password}
});
contentLoader2.option('url', 'http:/apple.com');
// Push each widget instance into an array of widget objects
var contentLoaders = [];
contentLoaders.push(contentLoader1);
contentLoaders.push(contentLoader2);
for (var i in contentLoaders) {
console.log(i, contentLoaders[i].option('url'));
}
// Should print:
// 0 http://google.com
// 1 http://apple.com
//
//
// How to set a bunch of widgets at once from an array of content loader data
//
//
var contentLoaderData = [
{
divid: '#targetDiv1',
url: 'google.com',
formdata: {
username: 'joeshmo',
password: 'joeshmo1'
}
},
{
divid: '#targetDiv2',
url: 'apple.com',
formdata: {
username: 'plainjane',
password: 'plainjane1'
}
}
];
// Array of widget instances
var contentLoaders = [];
$.each(contentLoaderData, function(index, value) {
var contentLoader = $(this.divid).contentloader({
url: this.url,
target_area: '#popup_box',
formdata: {'username' : this.formdata.username, 'password' : this.formdata.password}
});
// Push each contentLoader instance into the contentLoaders array
contentLoaders.push(contentLoader);
});
for (var i in contentLoaders) {
console.log(i, contentLoaders[i].option('url'));
}
// Should print:
// 0 http://google.com
// 1 http://apple.com

Categories

Resources