I am developing an app iOS app in appcelerator and I got a table with user.
When I click on the user it opens the profile but I also want the user to be able to copy the name just by tap and hold for 2 seconds.
These two event works fine separately but right now after tap and hold the click event fires to. How can I prevent the click event from firing after tap hold?
// Set the timeout
var holdTime = 500, timeout;
// Create the table touch start event listener
table.addEventListener('touchstart', function(e) {
// Set the selected user id
var itemValue = e.row.value_full;
// Define the function
timeout = setTimeout(function(e) {
// Create the fade out animation
var fadeOut = Titanium.UI.createAnimation({
curve: Ti.UI.ANIMATION_CURVE_EASE_IN_OUT,
opacity: 0,
duration: 1000
});
// Create the loading screen
var copied = UI_messages.showFlash({label : 'Copied!'});
// Add the loading screen
win.add(copied);
// Save value to clipboard
Titanium.UI.Clipboard.setText(itemValue);
// Fade the message out
copied.animate(fadeOut);
}, holdTime);
});
// Create the event listener for touch move
table.addEventListener('touchmove', function() {
// Clear the timeout
clearTimeout(timeout);
});
// Create the event listener for touch move
table.addEventListener('touchend', function(e) {
// Clear the timeout
clearTimeout(timeout);
});
I've run into this problem before as well. The solution I used isn't very pretty, but it's the only effective way that I've found to suppress a touch event after a touch-and-hold.
The only working solution that I could find was to create a bool variable in a global namespace. In your setTimeout function, change the value of the bool to true to indicate that a touch-and-hold has occurred.
In the onClick event event for the row, check the global variable first to see if you've already created a touch-and-hold event - if you have, just return from the onClick event. This will effectively disable your click event when a touch-and-hold occurs.
Remember to set the global variable to false after the touch-and-hold function ends.
Related
Is it possible to open an url when an event is clicked? I want to route my users to an url contains details related to event.
Yes, you can. Just handle the change event of your scheduler like this:
$("#scheduler").kendoScheduler({
change: function (e) {
e.preventDefault(); // prevent the default action
if (e.events.length > 0) { // if true then user clicked an event, not an empty slot
window.location.href = 'stackoverflow.com'; // replace with the desired url
}
},
// ... set other properties ...
});
The e.events is an array that has list of clicked events.
Kendo Scheduler Change Event
I've created a Kendo Scheduler that binds to a remote data source. The remote datasource is actually a combination of two separate data sources. This part is working okay.
Question is... is there any way to prevent certain events from being destroyed?
I've stopped other forms of editing by checking a certain field in the event's properties and calling e.preventDefault() on the edit, moveStart and resizeStart events if it should be read-only. This works fine, but I can't prevent deletes.
Any suggestions greatly appreciated.
Just capture the remove event and process it as you have with the edit, moveStart, and reviseStart events. You should see a remove event option off the kendo scheduler. I can see it and capture it in version 2013.3.1119.340.
I think better way is to prevent user from going to remove event in the first place. Handling the remove event still has its validity as you can delete event for example by pressing "Delete" key).
In example below I'm assuming event has custom property called category and events with category equal to "Holiday" can't be deleted.
remove: function(e)
{
var event = e.event;
if (event.category === "Holiday")
{
e.preventDefault();
e.stopPropagation();
}
},
dataBound: function(e)
{
var scheduler = e.sender;
$(".k-event").each(function() {
var uid = $(this).data("uid");
var event = scheduler.occurrenceByUid(uid);
if (event.category === "Holiday")
{
// use .k-event-delete,.k-resize-handle if you want to prevent also resizing
$(this).find(".k-event-delete").hide();
}
});
},
edit: function (e) {
var event = e.event;
if (event.category === "Holiday")
{
e.container.find(".k-scheduler-delete").hide();
}
}
FYI, you can do this...
#(Html.Kendo().Scheduler<ScheduledEventViewModel>()
.Name("scheduler")
.Editable(e => e.Confirmation(false))
)
which will deactivate the default confirmation prompt for the scheduler. Then you can do your own prompt on items you want.
There is also a
.Editable(e => e.Destroy(false))
that you can do to remove the X on the event window. This particular example would remove it for all of the events, but there might be a way to remove it for specific ones.
I have a Kendo Grid, where I have defined an Editor like this:
#(Html.Kendo().Grid(Model.Data)
.Name("GridINT")
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.TemplateName("MyTemplateName")
.Window(w => w.Width(500))
.Window(w => w.Title("My Template")))
Before I engage the editor, I bind a mouseup handler to the rows, and I tweak the style of the command button. When the editor closes, whether by Submit, Cancel, or 'X', my handler and style tweaks are gone for the affected row. I need to restore them, but I haven't found the valid event. I have bound the cancel click event like this:
$('.k-grid-cancel').bind('click', function ( e ) {
colorCommandCells();
});
but if I restore my handler/style to a grid row here, the editor's closing process undoes what I have done.
Bottom line: how can I know that the editor is finished updating the grid (which it does, as I have described, even if the editor is cancelled) and which row was the one that the editor messed with?
This is the code that colors the command cells:
function colorCommandCells() {
// This block colors the command cell according to ISNEW. It must run every time the DataBound event occurs.
var grid = $("#GridINT").data("kendoGrid");
var gridData = grid.dataSource.view();
for (var i = 0; i < gridData.length; i++) {
var currentUid = gridData[i].uid;
var currentRow = grid.table.find("tr[data-uid='" + currentUid + "']");
var editButton = $(currentRow).find(".k-grid-edit");
var aColor = gridData[i].ISNEW == 1 ? "#FFCCFF" : "transparent";
var aText = gridData[i].ISNEW == 1 ? "Add" : "Edit";
var parent = $(editButton).closest("td");
$(parent[0]).css('background-color', function () { return aColor; });
editButton[0].innerHTML = "<span class=\"k-icon k-edit\"></span>" + aText;
}
}
Basically the Grid is rebound each time after such operations, and it is good to either use delegate events attached to the tbody of the Grid or bind the events each time when the dataBound event of the Grid occurs.
There are two parts to this answer: First, when building the DataSource for the Grid, assign a function to the Sync Event.
.Events(e => e.Sync("syncGrid"))
Also, when building the Grid, assign a function to the Cancel event.
.Events(e => e.DataBound("gridIsDataBound").Cancel("cancelEditor").Edit("gridEdit"))
You have to have both, because the Sync event will fire if the popup editor is closed via "Submit" and the Cancel event will fire if the popup editor is closed via "Cancel" or "X". Both functions should call something like this, where colorACommandCell is where I restore my style values:
function closeEditor() {
var timer;
clearTimeout(timer);
timer = setTimeout(colorACommandCell, 100);
}
There is still some activity related to the Grid that occurs after the editor closes (this is what clobbers my style tweaks). I found that, if I queued up my "fixes" to wait 0.1 seconds, then they would not get overwritten. Ideally, however, I'd like to have a more certain event that fires when the Editor is REALLY finished. I don't expect to be able to trust this timer on every machine that runs my code.
It is hard to expliain the actual code as i dont exactly know where the problem is, but it will be great if anyone can help in explaining how events are delegatd/bubbled in Ember.
I have a case where mouse move on document is not triggered inside one view. This happens when the view gets inserted dynamically using outlets.
MOUSE MOVE BINDING CODE:
MOVE_EVENT = touch ? 'touchmove' : 'mousemove',
$(document).on(MOVE_EVENT, function (e) {
console.log('move event move=true');
if (move) {
e.preventDefault();
stop = getY(e);
//console.log('move event move=true');
var val = pos + (start - stop) / h;
val = val > (max + 1) ? (max + 1) : val;
val = val < (min - 1) ? (min - 1) : val;
inst.scroll(target, val);
}
});
If I load the page with a router URL that shows the view in the outlet by default, the mouse move inside the view triggers mousemove on body. And when I gets into the view by changing states it doesnt happen: here is a log of a statechage that leads to the behaviour.
mouse move in repeat view
move event move=true
mouse move in repeat view
move event move=true
STATEMANAGER: Sending event 'chooseSkipTime' to state root.ote.
STATEMANAGER: Entering null
STATEMANAGER: Entering root
STATEMANAGER: Entering root.ote
STATEMANAGER: Entering root.ote.repeat
STATEMANAGER: Entering root.ote.repeat.skiptimes
STATEMANAGER: Entering root.ote.repeat.skiptimes.index
skiptimes view Inserted
skiptimes is inserted into an oulet on RepeatView. After such a state change the mouse move inside repeat view is not getting triggered, or it is not triggering the mousemove on document. At this same time as I move mouse outside the area of the parentview(RepatView) then mouse move shows log.
In a nutshell mousemove inside a view is not triggered. I have put:
mouseMove : function(e){
console.log('Mouse Move in Blah Blah View');
}
in every view inside RepeatView including RepeatView, none triggers. But mouse move on Parent of RepeatView and upwards is triggering as logs are shown.
It is hard to expliain the actual code as i dont exactly know where the problem is, but it will be great if anyone can help in explaining how events are delegatd/bubbled in Ember.
UPDATE
After further investigation it looks like the following stopPropogation in ember-latest is causing this, not yet able to understand why its going to else.
setupHandler: function(rootElement, event, eventName) {
var self = this;
rootElement.delegate('.ember-view', event + '.ember', function(evt, triggeringManager) {
var view = Ember.View.views[this.id],
result = true, manager = null;
manager = self._findNearestEventManager(view,eventName);
if (manager && manager !== triggeringManager) {
result = self._dispatchEvent(manager, evt, eventName, view);
} else if (view) {
result = self._bubbleEvent(view,evt,eventName);
} else {
//evt.stopPropagation();
}
return result;
});
Can I do this:
$('.box').delegate('.edit', 'click', function(edit_event){
...
var input = $('input', this);
input.focus().bind('blur keypress', function(event){
// here disable the first .edit event (don't allow click on that element)?
});
});
the event would be enabled again if certain conditions are met inside the 2nd event (and when a AJAX call is complete)
Since you're using the delegate()[docs] method, which is selector based, you could just add a class to the current .edit that excludes it from the selector.
// only invoke if it has "edit" class and not "disable" class
$('#box').delegate('.edit:not(.disable)', 'click', function (edit_event) {
// add the class to this edit element to disable it
var edit = $(this).addClass('disable');
var input = $('input', this);
input.focus().bind('blur keypress', function (event) {
// here disable the first .edit event (don't allow click on that element)?
// after some work, remove the class to re-enable the click
edit.removeClass('disable');
});
});
I used the not-selector[docs] so that the click event won't fire until the disable class is removed.