I'm trying to resize images after the view and images load on screen.
I have this TAG route and after update the EmberJS to RC7 I saw that the didInsertedElement stopped to work like before, it run one time only, but I need it to run every time I enter the view.
So I tried to run the code on setupController like this:
App.TagRoute = Ember.Route.extend({
model: function(params) {
return App.TKRPTumblr.findAll(params.tag);
},
setupController: function(controller, tag) {
if(typeof tag === 'object'){
controller.set('content', tag.response);
}else{
App.TKRPTumblr.findAll(tag)
.then(function(data) {
controller.set('content', data.response);
});
}
this.resizeView();
},
resizeView: function(){
var WIDTH = 0, RATIO, IMG, IMG_HEIGHT, IMG_WIDTH, FINAL_WIDTH, SIDEBAR_WIDTH = $('#sidebar').outerWidth(), MAX_WIDTH = $(window).width() - SIDEBAR_WIDTH, MAX_HEIGHT = $(window).height() - 125;
if($('html .post').find('img').length > 0){
$('.post').each(function(){
IMG = $(this).find('img');
IMG_WIDTH = IMG.attr('width');
IMG_HEIGHT = IMG.attr('height');
if(IMG_WIDTH > MAX_WIDTH){
RATIO = MAX_WIDTH / WIDTH;
IMG.width(MAX_WIDTH).height(IMG_HEIGHT * RATIO);
}
if(IMG_HEIGHT > MAX_HEIGHT){
RATIO = MAX_HEIGHT / IMG_HEIGHT;
IMG.width(IMG_WIDTH * RATIO).height(MAX_HEIGHT);
}
WIDTH += IMG.width();
});
if(isNaN(WIDTH)){
WIDTH = $('.post img').width() + SIDEBAR_WIDTH;
$('body').children('.ember-view').innerWidth(WIDTH);
}else{
WIDTH += SIDEBAR_WIDTH + 100;
$('body').children('.ember-view').innerWidth(WIDTH);
}
var evt = document.createEvent('Event');
evt.initEvent('_htmlReady', true, true);
document.dispatchEvent(evt);
}else{
Ember.run.next(this, function() {
this.resizeView();
});
}
}
});
Unfortunately it didn't worked as well :/ I can't figure out now how to do that :(( can anyone help me?
it run one time only, but I need it to run every time I enter the view.
If you rely on data returned by your model hook, then I guess you should rather use the routes afterModel hook, this is called every time you enter the route and the model is resolved.
App.TagRoute = Ember.Route.extend({
afterModel: function() {
this.resizeView();
}
...
});
But if you only care to invoke your function every time the route is entered no matter if the model is resolved or not, then using the routes activate hook is also an option:
App.TagRoute = Ember.Route.extend({
activate: function() {
this.resizeView();
}
...
});
Hope it helps.
Related
this is my simple test code for lazy load
http://codepen.io/kevkev/pen/bVVGdE
it works so far .. but the thing is that hidden images in an onclick function for buttons etc. doesnt work!
(watch through my code and scroll to end and push the button)
you can see in the network feedback that it already had load the images.
i could figure out that the problem is "display:none"
.pop {
display:none;
z-index:99;
position:absolute;
width:100%;
height:auto;
background:inherit;
}
Because display: none; elements are unknown in position. And the lazyloader doesn't know, when and if you change this. Therefore it decides to eager load it. If you want a lazyloader that automatically detects this use https://github.com/aFarkas/lazysizes/.
As alternative I would recommend justlazy, because it's more lightweight and don't uses jQuery.
1. Define placeholder (similar to that what you have done):
<span data-src="path/to/image" data-alt="alt" data-title="title"
class="placeholder">
</span>
2. Initialize lazy loading after your button click:
$(document).ready(function () {
$("#art").click(function () {
$("#art_pop").fadeIn(300);
Justlazy.registerLazyLoadByClass("placeholder", {
// image will be loaded if it is 300 pixels
// below the lower display border
threshold: 300
});
});
// other code ..
});
thanks guys! but I also got a working solution on this:
http://codepen.io/kevkev/full/meebpQ/
$(document).ready(function () {
$("#art").click(function () {
$("#art_pop").fadeIn(300);
});
$(".pop > span, .pop").click(function () {
$(".pop").fadeOut(600);
});
});
;(function($) {
$.fn.unveil = function(threshold, callback) {
var $w = $(window),
th = threshold || 0,
retina = window.devicePixelRatio > 1,
attrib = retina? "data-src-retina" : "data-src",
images = this,
loaded;
this.one("unveil", function() {
var source = this.getAttribute(attrib);
source = source || this.getAttribute("data-src");
if (source) {
this.setAttribute("src", source);
if (typeof callback === "function") callback.call(this);
}
});
function unveil() {
var inview = images.filter(function() {
var $e = $(this);
if ($e.is(":hidden")) return;
var wt = $w.scrollTop(),
wb = wt + $w.height(),
et = $e.offset().top,
eb = et + $e.height();
return eb >= wt - th && et <= wb + th;
});
loaded = inview.trigger("unveil");
images = images.not(loaded);
}
$w.on("scroll.unveil resize.unveil lookup.unveil", unveil);
unveil();
return this;
};
})(window.jQuery || window.Zepto);
/* OWN JAVASCRIPT */
$(document).ready(function() {
$("img").unveil(200, function() {
$(this).load(function() {
this.style.opacity = 1;
});
});
});
I have an amount field in my Form that I multiply by 100 after submission in my controller.
The problem is that the view renders the multiplication before moving on to the next page.
How can I avoid that?
More generally, how do I prevent the view to display the modified value once it's submitted?
I'm using ember.js with rails in the backend, but I think it's more of a MVC problem.
this is the view:
{{input value=model.amount mask="999[999].99"
classNames="form-control" placeholder=(t 'transactions.amount')}}
and this is the controller:
actions: {
create: function() {
var _this = this;
var model = this.get('model');
model.set('amount', model.get('amount') * 100);
model.save().then(function(transaction) {
_this.get('target').transitionToRoute(_this.get('destination'), transaction.get('id'));
}, function(response){
_this.set('errors', response.errors);
});
}
}
This would be a good case to use a computed property, which you would use in your template:
displayAmount: function(key, value, previousValue) {
// setter
if (arguments.length > 1) {
this.set('amount', value * 100);
}
// getter
return this.get('amount') / 100;
}.property('amount')
The syntax for computed properties is going to change soon so you may need this version:
displayAmount: Ember.computed("amount", {
get: function() {
return this.get("amount") / 100;
},
set: function(key, amount) {
this.set("amount", amount * 100);
}
})
I'm making a hybrid app with AngularJS and Cordova, using a Laravel 4 API & Backoffice.
I can make a picture with the application, but it does not upload. I don't really know how to upload the picture, and i don't really know how i can troubleshoot all of it.
I upload the image to the API-route i wrote, using the same upload-method as i use to do with the backoffice. This is what i have in the AngularJS-Controller, which uses Cordova to do the stuff.
var pictureSource; // picture source
var destinationType; // sets the format of returned value
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
function clearCache() {
navigator.camera.cleanup();
}
var retries = 0;
function onPhotoDataSuccess(fileURI) {
var win = function (r) {
clearCache();
retries = 0;
alert('Done!');
}
var fail = function (error) {
if (retries == 0) {
retries ++
setTimeout(function() {
onPhotoDataSuccess(fileURI)
alert("kgoa ne keer opnief beginne");
}, 1000)
} else {
retries = 0;
clearCache();
alert('Ups. Something wrong happens!');
}
}
var options = new FileUploadOptions();
options.fileKey = "image";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
options.params = {};
params.value1 = "test";
params.value2 = "param";
// if we need to send parameters to the server request
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://10.0.1.13/ClimbrBackoffice/public/api/routes/new/create"), win, fail, options);
}
// Called when a photo is successfully retrieved
//
function onPhotoURISuccess(imageURI) {
// Uncomment to view the image file URI
// console.log(imageURI);
// Get image handle
//
var largeImage = document.getElementById('largeImage');
// Unhide image elements
//
largeImage.style.display = 'block';
// Show the captured photo
// The inline CSS rules are used to resize the image
//
largeImage.src = imageURI;
}
// A button will call this function
//
$scope.capturePhoto = function(){
// Take picture using device camera and retrieve image as base64-encoded string
navigator.camera.getPicture(onPhotoDataSuccess, onFail, {
quality : 100,
destinationType : Camera.DestinationType.FILE_URI,
sourceType : Camera.PictureSourceType.CAMERA,
allowEdit : true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 250,
targetHeight: 400,
saveToPhotoAlbum: true,
correctOrientation: true
});
}
// A button will call this function
//
$scope.getPhoto = function(source) {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 100,
destinationType: destinationType.FILE_URI,
sourceType: source });
}
I searched the web for good tutorials or explanations, but they drove me crazy.
Can someone please help me out?
Thanks!
Thomas
Your Angular controller should have the following function
$scope.upload = function() {
var options = {
fileKey: "file",
fileName: "image.png",
chunkedMode: false,
mimeType: "image/png"
};
$cordovaFileTransfer.upload("http://yourdomain.com/image_handler", "/android_asset/www/img/ionic.png", options).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
$scope.showAlert('Done', 'File Uploaded');
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
$scope.showAlert('Error', err);
}, function (progress) {
// constant progress updates
});}
And on your server, Laravel function could simply handle the image as:
public function getImageFromDevice(){
$destinationPath = 'uploads/';
$newImageName='MyImage.jpg';
Input::file('file')->move($destinationPath,$newImageName);
}
Do not forget to inject $cordovaFileTransfer in your controller.
That's it, this is a simple example you can extend it.
Credits to: Phonegap + Laravel 4 How to upload file
I wrote my first scriptaculous script to create a slideshow between some div element :
var SlideShow = Class.create({
initialize:function(element, delayStart){
this.element = element;
this.delayStart = delayStart;
this.slides = this.element.childElements();
this.numberOfSlides = this.slides.size();
this.numberActiveSlide = 1;
this.start_slideshow();
},
start_slideshow: function()
{
this.switch_slides.delay(this.delayStart);
},
switch_slides: function()
{
this.slides[this.numberActiveSlide].fade();
if (this.numberActiveSlide == this.numberOfSlides) { this.numberActiveSlide = 1; } else { this.numberActiveSlide = this.numberActiveSlide + 1; }
Effect.Appear.delay(this.slides[this.numberActiveSlide], 850);
this.switch_slides.delay(this.delay + 850);
}
});
document.observe("dom:loaded", function(){
var slideshows = $$('div.slideshow');
slideshows.each(
function(slideshow) {
s = new SlideShow(slideshow, 2);
});
});
But I always get this error and It's been hours I can't figure it out where my problem is!
Undefined is not an object (evaluating this.slides[this.numberActiveSlide]);
Thanks you !
Nick
99% sure it's a context issue. Make sure you bind your function calls so that this is retained throughout your code.
Debug what this is in switch_slides: it should be the same thing as this in start_slideshow. If it's not, bind your call to switch_slides to your instance:
start_slideshow: function()
{
this.switch_slides.bind(this).delay(this.delayStart);
},
You'll probably have to do the same in switch_slides where it calls itself.
Is there any way to reload the same image using mootools. I have a camera that gives me image, but I have to refresh it. I wrote this, but it doesn't work so well:
var url = "some valid url to some image.jpg";
var timer = 10;
var periodical;
var camera_container;
var refresh = (function() {
var loader = new Asset.image(url, {
onLoad : function() {
camera_container.empty();
camera_container.inject(loader);
}
});
});
window.addEvent('domready', function() {
// the periodical starts here, the * 1000 is because milliseconds required
refresh.periodical(timer * 1000, this);
camera_container = $('camera-image');
});
Any help appreciated. Thanks.
why not add a seeding bit to the url?
(function() {
var url = "some valid url to some image.jpg?";
this.timer = 10;
var counter = 0;
this.refresh = (function() {
var loader = new Asset.image(url + counter, {
onLoad: function() {
camera_container.empty();
camera_container.inject(loader);
counter++;
}
});
});
})();
window.addEvent('domready', function() {
// the periodical starts here, the * 1000 is because milliseconds required
refresh.periodical(timer * 1000, this);
this.camera_container = $('camera-image');
});
this way the url will always be path/image.jpg?n where n changes and will force the browser to re-fetch it.
I think something like this also can work:
<div id="image-holder">
<img src="http://www.image.com/image.jpg"/>
</div>
var srcImage = 'http://www.image.com/image.jpg';
var reloadTime = 4000;
var holder = document.id('image-holder');
var imageReload = function(){
holder.empty();
var newImage = new Element('img',{
id:'image',
src:srcImage ,
alt:'image new'
}).inject(holder);
}
var start = function() {
interval = imageReload.periodical(reloadTime);
};
start();