This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Long click in Custom JS
#1
Hello,

what is appropriate way to add longclick event on object which by default has only click event. I don't to delete this click event, I want only additionally add longclick. Now I've tried something like below:

Code:
function onLongClick(selector, timeout, callback) {
   let touchstart, touchend;
   selector.on('touchstart mousedown', function(e) {
     touchstart = e.timeStamp;
   })

   selector.on('touchend mouseup', function(e) {
     touchend = e.timeStamp;
     if (touchend - touchstart > timeout) callback();
   })
 }


But it is triggered with also default click, but I want to cancel click event when longpress is detected. Maybe admin have some adviceWink
Reply
#2
Hi
Erwin did this long time ago, scene button is what you describing here
Code:
$(function() {
 
 // For scene buttons use 1 byte signe integer (5) object and following additional classes:
 // Scene 0 : -> scenebutton normalpressed_0 longpressed_128
 //  or
 // Scene 1 : -> scenebutton normalpressed_1 longpressed_129
 // ........ >>>>
 // Scene 16: -> scenebutton normalpressed_15 longpressed_143
 
 // Long pushtime is set by 'var defaultlongpushtime' or by classname longpresstime_xxx where xxx = (xxx * 0.1) seconds
 // Scene 0 as 1 sec long press : -> scenebutton normalpressed_0 longpressed_128 longpresstime_10
 
 // For doorbel button with bit values use 1 bit unsigned (1) object and following additional classes:
 // Pressed 1 : -> doorbellbutton_bit released_0 pressed_1
 //    or
 // Pressed 2 : -> doorbellbutton_bit released_1 pressed_0
 
 // For doorbel button with byte values use 1 byte unsigned integer (5) object and following additional classes:
 // Sampel 1 : -> doorbellbutton_byte released_0 pressed_255
 // Sampel 2 : -> doorbellbutton_byte released_255 pressed_0
 // Sampel 3 : -> doorbellbutton_byte released_100 pressed_50
 // Etc ...
 
 // Declare variables for timers
 var longpushtime, defaultlongpushtime = 30, intervaltime = 100, timer = 0, timerInterval;

 function sendvalue(addr, value, typemajor, typeminor) {
   var id = Scada.encodeGroupAddress(addr), obj = objectStore.objects[ id ];
   if (obj && obj.datatype.major == typemajor && obj.datatype.minor == typeminor) {
     setObjectValue({ address: obj.address , rawdatatype: obj.rawdatatype }, value, "text");
   }
 }

 // Function to get values from bit object with additional classnames
 function getconfig(el, prefix, minval, maxval) {
   var reg = new RegExp(prefix + "_(\\d+)"), matches = el.className.match(reg), res = 0;
   if (matches) {
     res = parseInt(matches[ 1 ], 10) || 0;
   }
   res = Math.max(minval, res);
   res = Math.min(maxval, res);
   return res;
 }
 
 // Function to get pushtime values from additional classnames
 function getpushtime(el, prefix) {
   var reg = new RegExp(prefix + "_(\\d+)"), matches = el.className.match(reg), res = defaultlongpushtime;
   if (matches) {
     res = parseInt(matches[ 1 ], 10) || 0;
   }
   res = Math.max(0, res);
   res = Math.min(1000, res);
   return res;
 }

 // Remove original events and add new press events
 $(".scenebutton")
   .off("vclick")
   .on("vmousedown", function() {
     var btnthis = $(this), objthis = btnthis.data("object"),
     longpressvalue = getconfig(this, "longpressed", 0, 255);
       longpushtime = getpushtime(this, "longpresstime");
     timerInterval = setInterval(function() {
       timer += 1;
       if (timer == longpushtime) {
         btnthis.css("opacity", 0.5);
         sendvalue(objthis, longpressvalue, 5, 0);
         clearInterval(timerInterval);
       }
     }, intervaltime);
   })
   .on("vclick", function() {
     var btnthis = $(this), objthis = btnthis.data("object"),
     normalpressvalue = getconfig(this, "normalpressed", 0, 255);
       longpushtime = getpushtime(this, "longpresstime");
     clearInterval(timerInterval);
     if (timer < longpushtime) {
       sendvalue(objthis, normalpressvalue, 5, 0);
     }
     btnthis.css("opacity", 1);
     timer = 0;
      })
     .on("vmouseout", function() {
     var btnthis = $(this), objthis = btnthis.data("object"),
     normalpressvalue = getconfig(this, "normalpressed", 0, 255);
       longpushtime = getpushtime(this, "longpresstime");
     clearInterval(timerInterval);
     if (timer > 0 && timer < longpushtime) {
       sendvalue(objthis, normalpressvalue, 5, 0);
     }
     btnthis.css("opacity", 1);
     timer = 0;
 });
 
 // Remove original events and add new press events
 $(".doorbellbutton_bit")
   .off("vclick")
   .on("vmousedown", function() {
     var btnthis = $(this), objthis = btnthis.data("object"),
     pressedvalue = getconfig(this, "pressed", 0, 1);
     sendvalue(objthis, pressedvalue, 1, 0);
   })
   .on("vclick vmouseout", function() {
     var btnthis = $(this), objthis = btnthis.data("object"),
     releasevalue = getconfig(this, "released", 0, 1);
     sendvalue(objthis, releasevalue, 1, 0);
  });
 
 // Remove original events and add new press events
 $(".doorbellbutton_byte")
   .off("vclick")
   .on("vmousedown", function() {
     var btnthis = $(this), objthis = btnthis.data("object"),
     pressedvalue = getconfig(this, "pressed", 0, 255);
     sendvalue(objthis, pressedvalue, 5, 0);
   })
   .on("vclick vmouseout", function() {
     var btnthis = $(this), objthis = btnthis.data("object"),
     releasevalue = getconfig(this, "released", 0, 255);
     sendvalue(objthis, releasevalue, 5, 0);
  });
});
------------------------------
Ctrl+F5
Reply
#3
Thanks for your answer but unfortunately in this example default click is unbinded(.off("vclick")) but I want not remove anything but only add long press action and when long press will be detected then only this long press should execute, but when original short click will be triggered then original action should also work.

I've tried a few options and this is enough for adding second event which trigger some other action than default:
Code:
let lastMousedown;
       motionsIcons.on("vmousedown",function(e) {
         lastMousedown = e.timeStamp;
       });
       
       motionsIcons.on("vmouseout",function(e) {
         let currentMouseout = e.timeStamp;
         
         if ((currentMouseout - lastMousedown) > 1000 && (currentMouseout - lastMousedown) < 3000) {
           let value = grp.getvalue(motion.disabling);
           grp.write(motion.disabling, !value);
         }
       });
Reply
#4
Hi,

Yes original event is dropped first but then added as normal_press and long_press event, this way you can send 1 when normal press and 129 when long pressed like a scene button should work.

BR,

Erwin
Reply
#5
Hello Erwin,

yes, for sure, your script is perfect, I've asked generally for universal longpress solution which will be an addition for default events. Today I've searched it for using it for disable automatic light by pressing on the light switch button so this was my goal, but such solution gives a lot of new possibilitiesWink
Reply
#6
You can over-ride original vclick handler like this:
Code:
var el = $('.testclass').get(0); // element reference
var ev = $._data(el, 'events').vclick[ 0 ]; // first vclick event
var orig = ev.handler; // original vclick event handler function
ev.handler = function(e) {
  console.log(e);
  orig(e);
};

Note that it will only work for the first .testclass element as $._data() first argument must be a real element reference, not jQuery element collection.
Reply


Forum Jump: