I have a component which require to handle both click and double click. Its code is like
Template :
<div class="routine_week routine-border box-height-fix fl pointer">
{{mark-down marking}}
</div>
Component
import Ember from 'ember';
export default Ember.Component.extend({
marking : 0,
isMarkable : false,
click : function(){
//click here
},
doubleClick : function(){
//double click here
}
});
Now issue is that doubleClick never got fired. If it does it also fires two click events. How can I ensure that doubleclick event will not interact with click
Ember is so powerful that I was able to imitate DoubleClick using SingleClick event. Its all depend upon Ember.run Loop. Here is the code for anyone like me trying to do that -
//capture event for singleClick only execute if there is no doubleClick
eventIO : null,
//ember actually execute the doubleClick but it also gives two singleClick
doubleClick : function(){
var eventIO = this.get('eventIO');
//check if there is any event for single click, disable it
if(eventIO != null){
Ember.run.cancel(eventIO);
this.set('eventIO',null);
}
// do the stuff with double click
},
// our click event which got executed in both single / double click
click : function(){
var eventIO = this.get('eventIO');
//if this is the first click , schedule it for later after 500 ms
if(eventIO === null)
{
var eventIO = Ember.run.later(this,function(){
//do single click stuff
var eventIO = this.get('eventIO');
///clear additional events
if(eventIO != null){
Ember.run.cancel(eventIO);
this.set('eventIO',null);
}
},500);
//register event to the component
this.set('eventIO',eventIO);
}
},
<p {{on 'dblclick' this.doubleClick}}></p>
Related
Slick keybindings left and right only work when the focus is on a slide. When the reveal modal is opened the focus is not on the slide thus the keybindings wont work. I am looking for a way to either set the focus correctly or set more of a global keybinding but keep in mind there may be more than one gallery on a page. Any suggestions would be greatly appreciated.
$('.galleryGroup').each(function(){
if (typeof $(this).data('gallery') !== 'undefined'){
var id = $(this).data('gallery');
// Open reveal on click
$('.galleriesImage'+id).click(function(){
// Open Reveal Modal
$('#galleriesReveal'+id).foundation('open');
// Cancel Any previously created reveals
$(window).on('closed.zf.reveal',function(){ $('#slides'+id).slick('unslick'); });
// Set the inital slide
if (typeof jQuery(this).data('ref') !== 'undefined'){ var iid=jQuery(this).data('ref'); }else{var iid=0;}
// Initiate slideshow
$('#slides'+id).slick({infinite: true,dots: false,lazyLoad: 'ondemand',autoplay: false,initialSlide: iid});
// Set focus on the slideshow
$('something').focus();
}).css('cursor','pointer');
}
});
With slick it only works when one of the buttons (prev / next) is focused or one of the slides. It does not work when you focus the whole slideshow
$(document).ready(function(){
$(document).foundation();
$('.galleryGroup').each(function(){
if (typeof $(this).data('gallery') !== 'undefined'){
var id = $(this).data('gallery');
// Open reveal on click
$('.galleriesImage'+id).click(function(){
// Open Reveal Modal
$('#galleriesReveal'+id).foundation('open');
// Cancel Any previously created reveals
$(window).on('closed.zf.reveal',function(){ $('#slides'+id).slick('unslick'); });
// Set the inital slide
if (typeof jQuery(this).data('ref') !== 'undefined'){ var iid=jQuery(this).data('ref'); }else{var iid=0;}
// Initiate slideshow
$('#slides'+id).slick({infinite: true,dots: false,lazyLoad: 'ondemand',autoplay: false,initialSlide: iid});
// Set focus on the first slide
//setTimeout(function() {
$('#slides'+id+' .slick-slide').eq(0).focus()
//}, 0);
}).css('cursor','pointer');
}
});
});
In general there are many parts which cna be simplified using the Foundation Sites API and better logic in the code.
https://codepen.io/DanielRuf/pen/RQmPbd
I have a component in my application.It have a form with text fields.It will have a submit button.When submit is pressed it will send a post request to the server.I also handled a keyboard event in components js file.When enter is pressed it will send a post request to the server.When the enter key is pressed two times continuously it is making two post request to the server with first request success and second request failed.
I want to make my app in such away even if the user presses the enter key two times continuously it should send only one post request to the server.Can any one help me solve this issue.Thanks in advance.
components js file:
export default Component.extend({
keyDown:function(event){
let self = this;
if(event.keyCode === 13){
self.send('submitform');
return false;
}
actions: {
submitform(){
//logic to handle the post request to the server
}
}
Try usig Ember.run.debounce,
export default Ember.Component.extend({
keyDown: function(event) {
let self = this;
if (event.keyCode === 13) {
// self.send('submitform');
Ember.run.debounce(self,self.get('submitform'),400);
return false;
}
},
submitform(){
//handle submit form logic
}
});
You can play with twiddle here
You will want to disable submitForm() until your POST request is complete. You can do this by setting a property submitting on the component and turning it on before the POST and off once the promise is resolved. Perhaps try something like:
export default Ember.Component.extend({
submitting: false,
keyDown: function(event) {
if (event.keyCode === 13) {
this.submitform();
}
},
submitform() {
// Run only if not currently submitting
if (!this.get('submitting')) {
// What to do when submit succeeds
const success = () => {
this.set('submitting', false);
}
// What to do when submit fails
const fail = () => {
this.set('submitting', false);
}
// Do the POST request
this.set('submitting', true);
this.get('someModel').save().then(success).catch(fail);
};
}
});
And, unrelated, this allows you to do fun things with your template such as disabling and styling the submit button for as long as the POST promise is not resolved yet:
<button {{action 'submitForm'}} disabled={{submitting}} class="{{if submitting 'loading'}}">
{{#if submitting}}
Submitting ...
{{else}}
Submit
{{/if}}
</button>
Oh and lastly, no need to use let self = this; anymore. Use ES6 arrow functions () => { ... } instead so you can keep using this inside.
I have a component which is my main interface. Inside this component, clicking a button opens ionic 2 modal which allows to choose items.
My modal page (itemsPage):
..list of items here
<button ion-button [disabled]="!MY_TURN || !selectedItem || !selectedItem.quantity"
(click)="useItem(selectedItem)">
<span>Choose item {{selectedItem?.name}}</span>
</button>
useItem() should:
Send item data to my main interface component
Close the modal
Execute a method in my main interface
How I can perform such actions? Couldn't find any documentation about communicating between modal and component in Ionic 2.
It is simply a matter of using parameters in viewController.
In your main interface component,
let chooseModal = this.modalCtrl.create(itemsPage);
chooseModal.onDidDismiss(data => {
console.log(data);
});
chooseModal.present();
In your modal page,
useItem(item) {
this.viewCtrl.dismiss(item);
}
Modal Controller link here
This is a clear example of getting data from modals in ionic.
You need to add a handler for modal’s onDismiss() and then return the data from the modal itself by passing the data to the ViewController’s dismiss() method:
// myPage.ts
// Passing data to the modal:
let modal = Modal.create(myModal, { data: [...] });
// Getting data from the modal:
modal.onDismiss(data => {
console.log('MODAL DATA', data);
});
this.nav.present(modal);
on the modal page
// myModal.ts
constructor(private navParams: NavParams, private viewCtrl: ViewController) {
// Getting data from the page:
var dataFromPage = navParams.get('data');
}
dismiss() {
// Returning data from the modal:
this.viewCtrl.dismiss(
// Whatever should be returned, e.g. a variable name:
// { name : this.name }
);
}
I have an ionic2 application with angular2, at one page I inject LoadingController and make use of it, at different location on my app.ts I catch all global http errors and want to display alert so I inject AlertController there .
So having 2 location which can at some point call a modal dialog creation and present it causing a problem that freezes the screen , I believe it is because there are 2 modals being open one on the other.
Is there any chance I can grab the current dialog and close it, or add param to create which closes any background modal ?
This is my code:
export class SandboxPage implements OnInit {
private _loadingModel;
constructor(private _navCtrl:NavController, private _alertCtrl:AlertController , private _loadingCtrl: LoadingController ) {
}
ngOnInit() {
this._loadingModel = this._loadingCtrl.create();
this._loadingModel.present();
let alert = this._alertCtrl.create({
title: 'Error',
message:"error message",
buttons: [{
text: 'Ok',
handler: () => {
// user has clicked the alert button
// begin the alert's dismiss transition
let navTransition = alert.dismiss();
}
}]
});
//timeout the error to let other modals finish dismissing.
setTimeout(()=>{
alert.present();
},500);
}
}
The ok click want close the alert model, Here in this example it's on the same page so I can dismiss the loading but when on different components it's not possible to do.
I have written this simple demo component to demonstrate a problem. The component code is below
App.FocusOutComponent = Em.Component.extend({
attributeBindings: ['tabindex'],
tagName: 'focus-out',
setFocus: function() {
console.log('clicked focus-out container');
this.$().find('button').focus();
console.log('focus set to button');
}.on('click'),
focussedOut: function() {
console.log('focussedOut from outer container');
}.on('focusOut'),
});
{{#focus-out id="focus-container" tabindex="-1"}}
<button id="text-button">Test Button</button>
{{/focus-out}}
When I run this and click on the focus-out element, this is the order of the logs. Link to demo
clicked focus-out container
focussedOut from outer container
focus set to button
Now when I am trying to write acceptance tests for this with the following code.
test('test visit / and click button', function() {
expect(0);
visit('/').then(function() {
find('focus-out').click();
console.log('after click in test');
});
});
The order of the logs are different. Link to demo.
clicked focus-out container
focus set to button
after click in test
focussedOut from outer container
The focusOut log got printed at the very end instead before the after click log. I was expecting the same order for the logs with just an additional log(after click) in the end.
Im not sure if this is a bug or something wrong with my code.
I also noticed another problem while executing tests. If I have focus on the chrome dev-tools while the tests are running, the focusOut event will not trigger at all.
Some help with this is much appreciated.
the click event doesn't set focus (being a back door route). You'll need to manually set focus then click if you want the same results.
Ember's Click Helper (sends mousedown/mouseup, then click)
function click(app, selector, context) {
var $el = app.testHelpers.findWithAssert(selector, context);
run($el, 'mousedown');
if ($el.is(':input')) {
var type = $el.prop('type');
if (type !== 'checkbox' && type !== 'radio' && type !== 'hidden') {
run($el, function(){
// Firefox does not trigger the `focusin` event if the window
// does not have focus. If the document doesn't have focus just
// use trigger('focusin') instead.
if (!document.hasFocus || document.hasFocus()) {
this.focus();
} else {
this.trigger('focusin');
}
});
}
}
run($el, 'mouseup');
run($el, 'click');
return app.testHelpers.wait();
}
Modified Test
test('test visit / and click button', function() {
expect(0);
visit('/').then(function() {
var el = find('focus-out');
el.focus();
click(el);
console.log('after click in test');
});
});
http://emberjs.jsbin.com/lefazevozi/1/edit?js,console,output
It's also important to note, that tearing down will also call the focus out event. So the main reason you were seeing the focusout at all was because on teardown it was losing focus from the button child.
Maybe focus should be set before mousedown on the click helper in the ember test, though I'm not sure what else that might affect, or if people wouldn't generally be expecting that since jquery doesn't do that.