How do I prevent jQuery .hover function from affecting all images simultaneously? - jquery-hover

I'm not sure the title explains it well enough, but was trying to keep it quite short!
So, I've got a number of images scattered around a page and have created a lightbox gallery for them all (.cboxElement is the class that calls it). What i wanted to add into this was a hover effect on each image affected by the lightbox so the user knows it can be zoomed.
The problem:
I didn't write the original code for the site and this is a new feature. Due to inconsistencies in classes across images, I had to prepend a tag before each image with a unique class for the hover method to refer to, as follows:
$("a.cboxElement").each(function(){
$(this).prepend("<span class='zoom'></span>");
});
Immediately following this, I've used the hover effect:
$("a.cboxElement").hover(function(){
$("a.cboxElement span").fadeIn('fast');
},
function(){
$("a.cboxElement span").fadeOut('fast');
});
The problem is that when I hover over an image on the page, the hover effect appears on every image simultaneously and I can't work out how to get it to affect only the image I'm hovering over.
Does anyone have any ideas as to what I could do?
Many thanks,
Jon

I think you just need to change the scope of your hover assignment:
$("a.cboxElement").hover(function(){
$(this).find("span").fadeIn('fast');
},
function(){
$(this).find("span").fadeOut('fast');
});
Your original code was saying: for each a.cboxElement, find all a.cboxElement elements' spans and fade them in/out. The above code says for each a.cboxElement, on hover, find the span for just this a.cboxElement and fade it in/out.

Also, you can use .fadeToggle with a single function:
$("a.cboxElement").hover(function(){
$(this).find("span").fadeToggle("fast");
});

Assign an id="..." attribute to each image and select it instead of the entire a.cboxElement class:
<img id="imageid1" ... >
$('#imageid1')....

$("a.cboxElement").hover(function(){
$(this).find('span:first').fadeIn('fast');
},
function(){
$(this).find('span:first').fadeOut('fast');
});

Related

Creating a new model in ember with a zurb foundation range slider bound to an attribute

I am trying to use the range slider from the zurb foundation framework with Ember. I want a slider next to an input field, both of them showing the same value updating each other so a user would be able to enter either a number by hand or use the slider to set a score for a game played in the past.
My template looks like this:
{{input type="text" id="new-game-score" value=newGameScore}}
<div class="range-slider" data-slider={{newGameScore}} data-options="start: 0; end: 16;">
<span class="range-slider-handle" tabindex="0" role="slider"></span>
<span class="range-slider-active-segment"></span>
</div>
And in the controller I'm calling this.get('newGameScore'); to get the value for the creation of the model.
When I open the template I get a text-input that behaves like I expect. It allows to set the score for the creation of the model. The data-slider-attribute of the slider next to it gets updated correctly, but it doesn't change how the slider looks and I can't move the slider at all.
When I set newGameScore as a function returning a number in the controller both the slider and the input field start out with the set value and I can move the slider. Moving it does not change the value of the input field though, while entering a number in the text field adjusts the data-slider-value without any visible change on the slider. The number used for the creation of the new model is the one from the text input.
I'm using ember-cli and installed foundation with ember install ember-cli-foundation-sass.
I have
var app = new EmberApp({
'ember-cli-foundation-sass': {
'modernizr': true,
'fastclick': true,
'foundationJs': 'all'
}
});
in my Brocfile and the corresponding view looks like this:
export default Ember.View.extend({
didInsertElement: function() {
this.$().foundation();
}
});
The controller is an ArrayController with the template showing all the games with their scores. I would like to keep at that way if possible.
I started out using the zurb foundation documentation:
http://foundation.zurb.com/docs/components/range_slider.html
and found the following solution to a more complicated but closely related problem:
http://danahartweg.com/foundation-5-sliders-in-dropdowns-using-emberjs
but I couldn't figure out how to properly synchronise the slider with newGameScore. http://danahartweg.com/foundation-5-sliders-in-dropdowns-using-emberjs states at the beginning of the article that ember with a foundation-slider is easy to do. So I assume I don't have to write custom on-change-functions to solve my problem, but maybe someone more experienced with ember can find a solution from bottom part of the article, although it seemed to me that this is only needed for the combination of the dropdown and the slider.
Thanks for reading and for any idea about this.
regards,
Andy
It's been a while since I've worked with an Ember app, but I do remember working with some of the quirks you've mentioned here.
In my article, I was data-binding both the slider value and the input value. Honestly, though, it would probably work better to just have the data-slider feed the input via the display_selector option without any binding. It's been a while since I worked with this code, so it might have been something I initially tried and failed with. It seems that might be better overall because it would let the display_selector option on the range-slider itself keep the internal state of the slider intact.
As far as using Ember data-bindings properly, html content is easy (as you've found), but element attributes are a little trickier. You have to use the bind-attr syntax: {{bind-attr data-slider="newGameScore"}}
I gave it another try after a good night's sleep.
I added:
$("#new-game-score").on('change', function(e) {
var target_slider = $('.range-slider');
var new_value = target_slider.attr('data-slider');
target_slider.foundation('slider', 'set_value', new_value);
});
And now the slider updated visibly when I enter values in the text-field.
I added:
var slider = this.$('.range-slider');
slider.on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function(e) {
$(e.target.parentElement).find('input[type=text]').trigger('change');
});
and to the slider: data-options="display_selector: #new-game-score and now it worked both ways!
I'm still a bit at a loss of why this all works, but my problem seems to be fixed.
It only works when I explicitly set newGameScore in the controller though and all in all I have the feeling I didn't use Ember as intended.
Also this only seems to work when I carefully make sure I release the mouse button while on the slider. If I want to set it to max for example and release the mouse button outside of where the slider is, the text-field gets updated but newGameScore does not.
I made it work with:
this.$(".slider-input").on("blur", function(e) {
var target_slider = $(e.target.parentElement.parentElement.parentElement).find(".range-slider")
var new_value = target_slider.attr("data-slider");
target_slider.foundation("slider", "set_value", new_value);
});
this.$(".range-slider").on("change.fndtn.slider", function(e) {
$(e.target.parentElement.parentElement.parentElement).find("input[type=text]").trigger("change");
});
in the view.
I'm still unhappy with setting the initial value in the controller. I'm unsure about on('blur'), but on('change') lead to a infinite circle of both functions calling each other.

What is the ember way to add popovers to views?

I'm working on a events board app. Events are displayed in columns at the height matching the start time and pack into the space if there is more then one overlapping. Each event is a view and I want to have a div next to the view that shows and hides on hover.
I know how to bind to mouseEnter and mouseLeave to show and hide part of the template but I want to show something adjacent to my view/template not within it.
I've already got some computed properties on the view to place the event with the correct height and width so I don't want to add the popover inside the view.
Here is something to mess with http://jsbin.com/osoner/1/edit
Seems like something simple but I want to make sure I'm doing things the Ember way.
After messing a little with your provided jsbin, here the results.
Basically what I've done was adding a new popup css declaration wich do position the popup so that it appears outside the parent view, and also moved the {{#if...}} helper into the originating view.
If you want to go more fancy, checkout this jsfiddle wich uses the twitter boostrap popover.
Hope it helps.

Ember-table: fails when used in a hidden div (workarounds welcome!)

I'm trying to use ember-table inside a Bootstrap tab, but apparently if the table is contained in a tab that is initially display: none, the table layout doesn't work: everything is mis-sized and stuck in the upper-left of the table container.
I've narrowed the problem down by making a manually display-toggled div and it exhibits the same behavior.
I have a couple of ideas of how to workaround this, but I'm interested in others' ideas.
Also, should I file this as a bug? Seems like a common use case.
You can resize the table when you open the tab.
this.get('tableController').set('_width',820);
I had a similar situation, albeit not exactly the same. I initially show the ember-table component in a 'light' view, with one width, but the user can toggle between that and a 'full' view, with a larger width (as implied by its container). The toggle to larger width would size the container correctly but the portion of the ember-table not visible in the light view would contain only blank space, not cell contents nor borders, nor column headers. It's as if it never re-rendered after the container's dimensions changed.
The solution I found was to force a re-render of the table manually on the basis of an external property I would change when this light/full mode was toggled by the user. To achieve this, I extended the table component as shown:
export default Ember.Table.EmberTableComponent.extend({
// exposes a hook to resize (i.e. rerender) the table when it would otherwise
// not have been detected
resizeTriggered: function() {
this.handleWindowResize();
}.observes('resizeTrigger')
});
Since I'm using ember-cli, I saved the above under components/my-table-component.js.
Having done this, I would then include the table in my template like this:
{{my-table-component
columnsBinding="columns"
contentBinding="content"
resizeTrigger=resizeTriggerProperty
}}
Now, I simply update the controller's resizeTriggerProperty to any (new) value every time I want to ensure that the table re-renders. In my case, I would set it in the course of an action (e.g. MyRouteController):
actions: {
triggerResize: function() {
this.set('resizeTriggerProperty', new Date().getTime());
}
}
This may be a little late, but I am using Ember Table 0.4.1 (latest), and I found that ember table redraws on window resizes, so I used this to make the tab show the table when the tab changes:
$(window).resize();
and this did the trick, ember table redraws itself whenever I change the tab.

Ember: Cannot read property 'enterStates' of undefined and textfield update

I have the following problem with ember.
I have a table with a set of datas. I have an event that returns me the current element of the table. Then it opens another view by transitioning into a new state and writes the selected table data in a textfield.
click: function(e) {
var element = $(e.target).closest("td");
App.tee = element.text().trim();
var router;
router = this.get('controller.target.router');
router.transitionTo('newRoute')
As you can see I have some other routes in my router as well.
The last two routes(home and profile) are part of a nav-tab. They work perfectly beside I click on the table. Then i get the following error when i click on a tab: Uncaught TypeError: Cannot read property 'enterStates' of undefined
Ok i give it another try to explain what i wanted to do.
What i want to do is to create a table with some data (for example persons).
When i click on a specific person in the table the corresponding table-data should be shown in the textfields that appear below. Whenever i click on another person the textfields below should change to the informations of the current clicked person in the table. When i click "New" Button a more detailed Tabview appears on the right side with some additional informations. I was playing around with ember and so far i just implemented some of the views and the routing. Im stucked as i have tried to implement the event that updates the textfield below the table. It updates once but after it has transitioned into the new state(newRoute) nothing happens. I know the code is very raw, but it is just a test to understand how this works in ember.
Ok the solution was easier than i thought. The problem was not the state changing. It was more a problem of how to access the data and how to effect the change of binded data. I realised too late that i needed to understand how the variable access works in Ember and what exactly the App.initialize() method does. So App.initialize() initializes all Controller classes in the router. If you want to access any variables within a controller you have to get the access over the router like
{{view Ember.TextField valueBinding="App.router.tableController.person"}}
Secondly i wasnt familiar with the usage of the set and get methods in Ember and the difference between extend and create. I wondered before where ember instantiates my object.
So my problem had nothing to do with states it was just a totally misunderstanding of the ember framework. Im a noob thats all.
Ok, this is the first shot of the answer.
I think the main issue is just a typo gotoHome instead of goToHome in the template.
By the way I get rid of some deprecation warnings by using <button {{action }}></button> instead of Ember.Button.
There is some other warnings when I click on the table, because you are referencing some properties which don't exist.
here is the corresponding fiddle: http://jsfiddle.net/Sly7/rKw9A/25/
Since I don't understand how it should work exactly, I'm not sure of the overall behavior. I let you explain me the flow (by editing the question please).
Any other comment is welcome :)

rendering views dynamically on EmberJS

I just having a little trouble to implement a special kind of view for Ember, I'm digging on the source for days but can't find how to make it work... Can you take a look and tell me what's wrong? It's a small code, a specific problem when rendering one view from another (it's not doing the binds right...).
The sample code (with comments) that demonstrate the problem is here: http://jsfiddle.net/wilkerlucio/rUUuN/
Edit:
Just to clarify, I'm trying to do a view that dynamically render another view. It can be useful for a lot of implementations, like tabs for example. On tabs you have the tabs and the container that shows current tab, so, the view that I'm trying to accomplish is like this current tab container. Each tab has it own view, and I need that my view be able to render the view for the current tab.
I know I can do things like just hide a view and show the other, but it's not the way I want it right now. This CardView that I'm creating should have a binding to a property that will return a view instance, and the CardView will render this view, and will update if the property that points the view updates.
You can see a more full covered example about what I'm trying to do here: http://jsfiddle.net/wilkerlucio/Ztdpb/
Thanks
I think that you need to specify the template as such:
App.CardView = Ember.View.extend({
defaultTemplate: SC.Handlebars.compile('{{App.obj.value}}')
});
or
App.CardView = Ember.View.extend({
templateName: 'sample'
});
If you are planning to have many child views, then you may want to try to use a collection view.
This link is a bit old, but it is still not bad: http://guides.sproutcore20.com/using_handlebars.html
I've also blogged about how it implemented CRUD operations with Ember (SC2) here.
Hope this helps.