This is the original code to open the opencart minicart with the dopdown arrow
$('#cart > .heading a').live('click', function() {
$('#cart').addClass('active');
$('#cart').live('mouseleave', function() {
$(this).removeClass('active');
$(this).removeAttr('class');
});
});
To close it on desktop screens I only have to leave the dropdown container with the mouse but it doesn't work with a mobile device like iPad or iPhone.
Maybe this could help:
$('#cart > .heading a').live('click', function() {
if($('#cart').hasClass('active') {
$('#cart').removeClass('active');
} else {
$('#cart').addClass('active');
}
$('#cart').live('mouseleave', function() {
$(this).removeClass('active');
$(this).removeAttr('class');
});
});
In shorter version this should also work, but I never found the toggleClass function to work for me, therefore I am toggling manually by if-else as above.
$('#cart > .heading a').live('click', function() {
$('#cart').toggleClass('active');
$('#cart').live('mouseleave', function() {
$(this).removeClass('active');
$(this).removeAttr('class');
});
});
Related
I am developing a plugin for draw.io and I have the following code
Draw.loadPlugin(function(ui){
if (ui.sidebar != null){
mxResources.parse('Download=Download');
mxResources.parse('Err=Err');
mxResources.parse('Other=Other');
ui.actions.addAction('Download', function() {
});
ui.actions.addAction('Err', function(){
});
ui.actions.addAction('Other', function(){
});
// Adds menu
ui.menubar.addMenu('Extra', function(menu, parent) {
ui.menus.addMenuItem(menu, 'Download');
ui.menus.addMenuItem(menu, 'Err');
ui.menus.addMenuItem(menu, 'Other');
});
}
});
I'm trying to insert a submenu in the Other option but I can't add it. And I don't really know how to do it
Thank you
Sorry if this question is too naive,but I am getting confused a lot on rendering views in Ember.
I have a 'Person' route. I am able to do CRUD operations on it.
router.js
this.route('person', function() {
this.route('index', { path: '' });
});
controllers/person/index.js
actions: {
createPerson: function() {
var person = this.get('store').createRecord('person');
this.set('person', person);
this.set('editPersonPane', true);
},
editPerson: function(person) {
this.set('person', person);
this.set('editPersonPane', true);
},
closeEditPerson: function() {
this.get('person').rollback();
this.set('editPersonPane', false);
},
savePerson: function(person) {
var _this = this;
person.save().then(function() {
_this.set('editPersonPane', false);
Ember.get(_this, 'flashMessages').success('person.flash.personUpdateSuccessful');
}, function() {
Ember.get(_this, 'flashMessages').danger('apiFailure');
});
},
deletePerson: function(person) {
var _this = this;
person.destroyRecord().then(function() {
_this.set('editPersonPane', false);
Ember.get(_this, 'flashMessages').success('person.flash.personDeleteSuccessful');
}, function() {
Ember.get(_this, 'flashMessages').danger('apiFailure');
});
}
}
What I want to do now is when I want to create a new person, a form slides in to create it. After filling up the form, I want the list view of persons to be updated immediately, without refreshing the page. Right now, I have been able to add the form and when I add a new person, I get a successful flash message but it's not updated in the view immediately. I have to refresh the page.
It might have to do something with observers but I am still not sure how.
Reloading a saved object will allow you to avoid having to refresh the page:
savePerson: function(person) {
var _this = this;
person.save().then(function(saved) {
saved.reload();
_this.set('editPersonPane', false);
Ember.get(_this, 'flashMessages').success('person.flash.personUpdateSuccessful');
}, function() {
Ember.get(_this, 'flashMessages').danger('apiFailure');
});
}
Also, it's worth noting that if you destructure and use ES6 syntax, you can clean up your code a bit as follows:
//controllers/person/index.js
//at the top of the file
import Ember from 'ember';
const { get, set } = Ember;
//other code
actions: {
//other actions
savePerson(person): {
person.save().then((saved) => {
saved.reload();
set(this, 'editPersonPane', false);
get(this, 'flashMessages').success('person.flash.personUpdateSuccessful');
}, () {
get(this, 'flashMessages').danger('apiFailure');
});
}
}
Which route is displaying your persons list?
Wouldn't something like this work better, so you can display the list and then edit a person within the persons.hbs outlet?
this.route('persons', function() {
this.route('person', { path: 'id' });
});
My code looks something like this
App.ItemRoute = Em.Route.extend({
setupController: function(controller) {
var model = this.modelFor('item');
controller.setProperties({
name : model.get('name'),
title: model.get('title')
});
}
});
App.ItemController = Em.ObjectController.extend({
saveOnChange: function() {
console.log('saveOnChange');
}.observes('name', 'title'),
});
From my understanding because i am using setProperties the observe should only fire once , but it fire two times
also wrapping the setProperties with beginPropertyChanges & endPropertyChanges still fires twice
what i ultimately is for it to not fire at all, so what i ended up doing was changing the controller code to be like this
App.ItemController = Em.ObjectController.extend({
load: false,
saveOnChange: function() {
if(!this.get('load')) {
this.set('load', true);
return;
}
console.log('saveOnChange');
}.observes('name', 'title'),
});
this code would work if the change is only fired once, but it won't work if its fired multiple times (that's my case)
The setProperties function doesn't coalesce your observers (unfortunately there's no way to do that), it just groups them into one operation. The source might help you to better see what it does:
Ember.setProperties = function(self, hash) {
changeProperties(function() {
for(var prop in hash) {
if (hash.hasOwnProperty(prop)) { set(self, prop, hash[prop]); }
}
});
return self;
};
So, back to your problem. The best way that I can think of is to debounce your function.
App.ItemController = Em.ObjecController.extend({
load: false,
saveOnChange: function() {
Em.run(this, 'debouncedSave', 150);
}.observes('name', 'title'),
debouncedSave: function() {
if(!this.get('load')) {
this.set('load', true);
}
}
});
If you're not familiar with debouncing, you can read about it here. There are probably some other solutions involving direct manipulation of the properties, but I'm not sure if that's a road you want to go down.
Hi I am trying to do things with emberjs and google maps.
The issue with google autocomplete api is if user enters text in location search but does not select any value from dropdown suggestion in textbox the first suggestion is not selected. I found a good solution for it on stack overflow solutiion in jquery only
I am trying to do it in ember.
App.AutocompleteAddressView = Ember.TextField.extend({
tagName: 'input',
autocomplete: null,
didInsertElement: function () {
this._super();
var options = {
componentRestrictions: {
country: "xx"
}
};
this.set('autocomplete', new google.maps.places.Autocomplete(this.$()[0], options));
//var autocomplete = new google.maps.places.Autocomplete(this.$()[0], options);
},
keyDown: function (e) {
var that = this;
var suggestion_selected = $(".pac-item.pac-selected").length > 0;
if (e.keyCode === 13 && !suggestion_selected) {
//key down arrow simulations
var event = Ember.$.Event('keypress', {
keyCode: 40
});
Ember.run(this.$("#searchTextField"), 'trigger', event);
console.log('loggin autocomplete');
console.log(this.get('autocomplete'));
//adding google map event and then triggering it
google.maps.event.addListener(this.get('autocomplete'), 'place_changed', function () {
var place = that.get('autocomplete').getPlace();
that.set('autocomplete_result', place)
console.log('google event was triggered');
console.log(that.get('autocomplete_result'));
});
google.maps.event.trigger(this.get('autocomplete'), 'place_changed');
}
}
});
Now I need to do simulation part. I guess ember testing has somthing that simulates keypress but I cannot used it.
If I use the solution from the link I mentioned things work fine first time but on clicking browser back navigation it does not work.
The solution I tried in code not working
I have an app which lists albums. When album is clicked on both AlbumView and App.overlay (also a view) are displayed.
App.overlay = Ember.View.create({...}) (Lightbox-like overlay).
and:
App.AlbumView = Ember.View.extend({
// close the selected album view by closing the overlay
close: function() {
App.overlay.close();
}
});
And here's the problem: I want to be able to close those both views by clicking on the overlay, but I want overlay to remain independent of AlbumView, so that I can use the overlay in other places (i.e. without introducing a coupling between the two). How can I do it?
Here is my current implementation, with tight coupling, which I really don't like:
App.overlay = Ember.View.create({
// handle clicking anywhere on the overlay
click: function() {
this.close();
},
// close the overlay (setting selectedAlbum's controller content to null hides the AlbumView)
close: function() {
App.selectedAlbumController.set('content', null); // this should not be here
this.remove();
}
});
I'm only just learning ember, so take this with a grain of salt...
You could add a 'visible' property to the overlay, and then observe it from the other AlbumView. Like this:
var overlay = Ember.View.create({
visible: true,
click: function() {
this.close();
},
close: function() {
this.set('visible', false);
this.remove();
}
});
App.AlbumView = Ember.View.extend({
overlayClosed: function() {
App.selectedAlbumController.set('content', null);
this.remove();
}.observes('overlay.visible')
});
What about extracting your close method in a mixin?
App.AlbumClosing = Ember.Mixin.create({
close: function() {
App.selectedAlbumController.set('content', null);
this.remove();
}
});
var overlay = Ember.View.create(App.AlbumClosing, {
click: function() {
this.close();
}
});