Mootools Morph Height and back - height

Im looking for a solution for:
I want to toggel the height of a Div but not complet.
So i try this but didnt work. I see the first classchange in firebug and the heigth change to 36px.
But back didnt work. I try wiht add and remove class.
http://jsfiddle.net/Zbbd9/1/
$$('.outer').setStyle('height', '660px');
$$('.outer h2').addEvent('click', function(){
if (this.hasClass('close')) {
var parent = this.getParent();
parent.removeClass('close');
parent.morph({
'height': '660px'
});
} else {
var parent = this.getParent();
parent.addClass('close');
parent.morph({
'height': '36px'
});
}
});
UPDATE:
http://jsfiddle.net/Zbbd9/2/
Got it.
Best Regards

You're selecting the wrong parent container.
Try it like this:
$$('.outer h2').addEvent('click', function(){
var parent = this.getParent();
if (parent.hasClass('close')) {
parent.removeClass('close');
parent.morph({
'height': '660px'
});
} else {
parent.addClass('close');
parent.morph({
'height': '36px'
});
}
});
Adding a class to identify the current state is a solid way to do it, but you might want to consider other alternatives, too, like using toggleClass or referring to something completely different like a slider or similar.

Related

Ember.beforeOberver callback is asynchronous to property change

Context: http://emberjs.jsbin.com/diyirecu/23/edit
Is there anyway to have the Ember.beforeOberver callback run first and then the property changes? Or should I be using a different strategy all together?
Not sure if you can turn that event synchronous... However, I refactored your code to use some simple jQuery patterns (callbacks... I know, very non-Ember of me) that achieve the same thing. The code is clunky compared to what you were looking to achieve, but it works.
Example JSBin: http://emberjs.jsbin.com/diyirecu/26/edit
I also changed popObject to removeObject so that it actually removed the item you clicked on.
App.IndexController = Ember.ObjectController.extend({
content: {},
colors: ['red','blue','green'],
color: 'orange',
actions: {
addColor: function () {
var color = this.get('color'),
$ul = Ember.$('ul');
if (color) {
$ul.fadeOut(500, function () {
this.get('colors').pushObject(color);
this.set('color', '');
$ul.fadeIn();
}.bind(this));
}
},
removeColor: function (color) {
var $ul = Ember.$('ul');
$ul.fadeOut(500, function () {
this.get('colors').removeObject(color); //Changed from popObject
$ul.fadeIn();
}.bind(this));
}
},
});

Do something when Ember component is instantiated?

I call a component like this:
{{Gd-text-input label="Specify" name="Specify" key="entry.810220554" triggerKey="tada" hideIf="Client"}}
I would like to run some javascript-code that sets an additional property to this component.
What I'm trying to run is something like this
//Convert string ot array.
GdRadioInput = Em.Component.extend({
init: function(){
var cs = this.get('contentString');
console.log('doesthiswork?');
if(cs){
this.set('content', eval(cs));
}
}
});
But it doesn't run. If someone could just provide a sample that console.logs a the value of a property of a component whenever that component is created, that would be very helpful.
You can run this code in the init method
init:function(){
this._super();
hideIf = this.get('hideIf');
key = this.get('key')
if(hideIf === key){
this.set('class', 'hide');
}
}
Good luck
PD: now this method is private: http://emberjs.com/api/classes/Ember.Component.html#method_init
I know this is an old question, but I wanted to update it with the new way to do things. Instead of overriding the init function, you can now cause a function to run on initialization with .on('init'). Example:
GdRadioInput = Em.Component.extend({
setupFunc: function(){
var cs = this.get('contentString');
console.log('doesthiswork?');
if(cs){
this.set('content', eval(cs));
}
}.on('init')
});
A follow-up: Just in case you are depending on a fully loaded DOM tree, you can use .on('didInsertElement') instead of on('init'):
GdRadioInput = Em.Component.extend({
setupFunc: function(){
var cs = this.get('contentString');
console.log('doesthiswork?');
if(cs){
this.set('content', eval(cs));
}
}.on('didInsertElement')
});
That event is fired when the view's element has been inserted into the DOM: http://emberjs.com/api/classes/Ember.Component.html#event_didInsertElement

How to make a computed property that depends on a global class attribute?

I wanna create a property that depends on a global attribute:
App.Test= Em.Object.extend();
App.Test.reopenClass({ all: Em.A() });
App.Other = Em.object.extend({
stuff: function() {
return "calculated stuff from this.get('foo') and App.Test.all";
}.property('foo', 'App.Test.all.#each.bar')
});
As a workarround I could create a observer and always set a dummy property with a new random value to trigger the property change, but is there a better way to do this?
I need this for some caching. I've a really crazy, and single threaded backend. So I write my own Model classes. So I try to reimplement a bit of the logic in the client for a better caching.
Ive an Item class (App.Item) and another class where each instance has a calculated reduced list of Items.
App.Model = Em.Object.extend({
});
App.Model.reopenClass({
all: Em.A(),
load: function(hash) {
return this.get('all').pushObject(this.create(hash));
}
});
App.Item = App.Model.extend({
});
App.List = App.Model.extend({
loadedInitItems: false,
items: function() {
if(!this.get('loadedInitItems')) { this.set('loadedInitItems', true); Backend.call('thelist', function(item) { App.Item.load(this); }); }
return App.Item.all.filter(function(item) {
// heavy filter stuff, depends on a lot of propertys on the current list instance
});
}.property('someprops', 'App.Item.all.#each.foo')
});
Backend.call represents some AJAX stuff
the point is, that now any item could change so that the filter will return something diffrent. And there are other places om the application, where the user can add Items. I dont want to call the backend again, because its very slow! And I know that the backend will not modify the list! So I wanna cache it.
This is just a reduced example of my use case, but I think've described the point. In reallity I have this dozend of times, with over 25000 objects.
have you tried adding 'Binding' to your property and then the value you want to bind to ?, something like this:
App.PostsController = Em.ArrayController.extend({
nameOfYourVariableBinding: "App.SomeObject.propertyYouWantToBindTo"
})
It looks like the problem is the double uppercase letter. So App.test ist working, but not App.Foo.test.
But I was able to find a Solution with the ArrayProxy.
Its about this:
App.Model = Em.Object.extend({
});
App.Model.reopenClass({
all: Em.A(),
load: function(hash) {
return this.get('all').pushObject(this.create(hash));
}
});
App.Item = App.Model.extend({
});
App.List = App.Model.extend({
loadedInitItems: false,
items: function() {
var self = this;
if(!this.get('loadedInitItems')) {
this.set('loadedInitItems', true);
Backend.call('thelist', function(item) {
App.Item.load(this);
});
}
return Em.ArrayProxy.extend({
content: App.Item.all,
arrangedContent: function() {
return this.get('content').filter(function(item) {
// heavy filter stuff, depends on a lot of propertys on the current list instance
// use self.get('someprops')
})
}.property('content.#each.foo')
});
}.property('someprops')
items: function() {
if(!this.get('loadedInitItems')) { this.set('loadedInitItems', true); Backend.call('thelist', function(item) { App.Item.load(this); }); }
return App.Item.all.filter(function(item) {
// heavy filter stuff, depends on a lot of propertys on the current list instance
});
}.property('someprops', 'App.Item.all.#each.foo')
});

hover over and each

I want the user to hover over a a link which has a class called picture and the span to animate (increase the padding top), here is the code I have made so far but when the user hovers over it, it animates them all, i only want it to animate the one the user has hovered over.
$('.picture').each(function(){
$('.picture').hover(function(){
$('.picture span').animate({
'padding-top' : '20px'
},'fast');
});
$('.picture').mouseout(function(){
$('.picture span').animate({
'padding-top' : '10px'
},'fast');
});
});
Any help would be appreciated I think its somewhere on the each function Im going wrong but am unsure. A link to it can be found here: http://bathroomsyork.co.uk/
I don't see any benefit of your outer each() call. You should try this:
$('.picture').hover(
function() {
$(this).find('span').animate({'padding-top' : '20px'},'fast');
},
function() {
$(this).find('span').animate({'padding-top' : '10px'},'fast');
}
);
Note that we select all picture class elements, then use both parameters of the hover() function to specify mouseenter and mouseleave event callbacks.
Within each callback, get the child spans of the currently hovered element, $(this), and perform the animation.
You don't need to iterate over all elements, you can bind the event handler to all the matched elements at the same time.
Also, use $('span', this) to select the correct <span> from the hovered element.
$('.picture').on({
mouseenter: function () {
$('span', this).animate({
'padding-top': '20px'
}, 'fast');
},
mouseout: function () {
$('span', this).animate({
'padding-top': '10px'
}, 'fast');
}
});
this worked in the end guys:
$('.picture').each(function(){
$(this).hover(function(){
$('span', this).animate({
'padding-top' : '20px'
},'fast');
}, function(){
$('span', this).animate({
'padding-top' : '10px'
},'fast');
});
});
When I tried the examples with the on() i got a console error, what does that do exactly as I haven't seen that before?
thanks anyway.
You don't need each.
$('.picture').on('mouseenter mouseleave', function(e){
var padding = e.type == 'mouseenter' ? '20px' : '10px';
$('span', this).animate({
'padding-top' : padding
},'fast');
});

Ember.Binding.transform migration to latest code

Ember.Binding.transform has been removed or replaced in the latest ember. I have a number of bindings that take this form:
valueBinding: Ember.Binding.transform({
to: function(value, binding) {
//return something
},
from: function(value, binding) {
//return something
}
}).from('parentView.content.finishBy'),
Can anyone advise me how I should update my code to the new regime?
You can add your computed property definition to Ember.computed, see
http://jsbin.com/awufuv/edit#source:
Ember.computed.finishBy = function() {
return Ember.computed('parentView.content.finishBy', function(key) {
var finishBy = Ember.getPath(this, 'parentView.content.finishBy');
return finishBy === 'now';
}).cacheable();
};
You can then use it like this:
App.obj = Ember.Object.create({
parentView: {
content: {
finishBy: 'now'
}
},
finishProp: Ember.computed.finishBy()
});
See more examples in https://github.com/emberjs/ember.js/blob/master/packages/ember-metal/lib/computed.js#L417-434
Just to be clear: you're not forced to add your custom computed property to Ember.computed. You can basically declare the function anywhere in your code. Now that I think about it, you might want to add your helper to your applications namespace instead of adding / poluting it to Ember. But that's just an issue of personal preference.
There's a pretty good discussion on the original commit on how to update your code.
However, in your case, I think you could just use a computed property:
value: function(key, value){
if(arguments.length===1){
//return something
} else{
//set and return something
}
}).property('parentView.content.finishBy')