Polymer 2.0 capture long press on dynamically generated paper-cards - polymer-2.x

Issue: How to select multiple paper-cards and know which ones is selected on user long press/tap on the card.
Description:
I have dynamically generated paper-cards and I render them on the page using template Dom-repeat. At present I have included checkboxes on each paper-card so that the user can select those checkbox associated with the paper-card. That way the user on the screen can select multiple cards on which I can action the next functionality.
I guess the better user experience will be that the user be able to tap or click on the paper-card and be able to hold his finger/mouse for say .5sec and be able to select that card rather than checkbox style selection.
If I am able to get a working code snippet of how a multiple paper-card selection is used then I will be able to provide a better UX for the app.
Current Code Snippet:
(here I am using a paper-icon-button to get the user selected paper-card element).
<template is="dom-repeat" items="{{itemsList}}" as="item">
<paper-card style="float:center; width: 95%" class$="
{{_computeCardColorTran(item.type)}}" data-index$="{{item._id}}">
<paper-icon-button icon="icons:arrow-drop-down" style="color:
grey;" id$="bttn#{{item._id}}" item="[[item]]" on-
tap="doSomeDiffAction">
</paper-icon-button>
<iron-image class="pad"
src="../images/image1"
preload
sizing="contain"
style="" >
</iron-image>
</paper-card>
</template>
What I wish to have (something like below) -->
<template is="dom-repeat" items="{{itemsList}}" as="item">
<paper-card style="float:center; width: 95%" class$="
{{_computeCardColorTran(item.type)}}" data-index$="{{item._id}}"
something-like-user-pressed-longed="
callFunctionUserPressedForLong"
>
<paper-icon-button icon="icons:arrow-drop-down" style="color:
grey;" id$="bttn#{{item._id}}" item="[[item]]" on-
tap="doSomeDiffAction">
</paper-icon-button>
<iron-image class="pad"
src="../images/image1"
preload
sizing="contain"
style="" >
</iron-image>
</paper-card>
</template>
And in script javascript function in dom-module I can extract the paper-card selected
function callFunctionUserPressedForLong(e){
var id = e.model.item._id;
console.log('User pressed for long time on the paper-card = '+ id);
}
function doSomeDiffAction(e){
var id = e.model.item._id;
console.log('Not a long press event. User taped or clicked paper card button. Do different action e.g. open popup. = '+
id);
}
Thanks

You have to use on-down and on-up events from Polymer and watch time diff between these two events yourself.
In example below, on-down and on-up event functions are the same for both components (paper-card and paper-icon-button). Inside the on-down function (_onDown), the current time is saved to variable. Inside on-up method (_onUp) is detection for tap/click on button (if time diff between on-down and on-up is <0.5s and event target is the element with id=bttn#{{item._id}} and long-press somewhere inside paper-card (including paper-icon-button).
_onDown(e) {
this.startTime = Date.now()
}
_onUp(e) {
let id = e.model.item._id;
//stopPropagation because this is otherwise called twice - from paper-card and from paper-icon-button
e.stopPropagation()
let id = "1"
if (Date.now() - this.startTime > 500) {
console.log(`long press somewhere inside paper-card :: id=${id}`);
} else if (e.target.id == `bttn#${id}`) {
console.log(`Not a long press event. User taped or clicked paper card button :: id=${id}`);
}
}
<paper-card on-down="_onDown" on-up="_onUp">
<paper-icon-button on-down="_onDown" on-up="_onUp">Tap me</paper-icon-button>
</paper-card>

Related

Select one component on click from a list of components in Vue.js

Hello I am trying to implement a comment system using Vue.Js
https://jsfiddle.net/jahid93/597vtcoz/
[<div id='app'>
<cmt-component :type="comment"></cmt-component>
<div class="comments" v-for="comment in commentList">
<div>
<span>{{comment.id}}</span>
<span>{{comment.comment}}</span>
</div>
<span class="reply-spa" #click="actionReply(comment.id)">Reply </span>
<div>
<cmt-component v-if="(selected_comment == comment.id) && replypart" :type="reply"></cmt-component>
</div>
</div>
</div>][1]
in the reply part when i click on reply it shows the reply box and then if i click on another reply it hides the first reply box first then i have to click on reply box again for that reply box
But I want to implement when I click on second reply box it hides first one and also show the current one.
You're toggling replypart off when you click on another 'Reply' button; you'd want to change your actionReply method to something like this:
actionReply: function (id) {
// if this is the reply box for the selected comment, or if there are no reply boxes open
if (id === this.selected_comment || this.replypart === false) {
this.replypart = !this.replypart
}
this.selected_comment = id
}

durandaljs 2.0 navigation

I have a view with pagination. When the user clicks on a page number, I display the data for that page.
I only want the data items to be replaced so I don't want to navigate to the "next page." So what I'm doing is using the router.navigate(url, { replace: false, trigger: false }); to add the page to the browser's history, but not to trigger the navigate there.
If after I get the data, I click on the browser's back button, the URL changes to the previous one, but I don't get an event. If once I'm back in the previous page, I click the browser's forward button, I get the trigger event from that page.
Example. I'm at /# and it is displaying page 1 of the data. The user click on the "next page" link on the page. I display page 2's data, and I replace the url with /#welcome/2 Now if I click on the browser's back button the URL changes back to /# but the page doesn't trigger. If I press the browser's forward button the URL changes back to /#welcome/2 and the page triggers. Now that that has happened, I can click the back button and page one will trigger; and I can go back and forth between page 1 and page 2. If the user clicks on "page 3", the problem happens again.
If you all need a working example, I will deploy it, but currently this is only running on my local box.
IMO paging, like sorting/filtering represent the internal state of a view/widget and shouldn't be presented via routes. Consider e.g. user is on #something/3 and bookmarks the url. After deleting a couple of items there's no #something/3 any longer and the bookmark fails. Here's some more thought food on that topic http://lostechies.com/derickbailey/2011/08/03/stop-using-backbone-as-if-it-were-a-stateless-web-server/
Update based on comments:
activate on hitting browser back get's not called for two reason. a) welcome.js returns a singleton and b) in shell.html viewCache is set to true. When the user press browser forward it get's called because at this time route #welcome/2 from the SPA perspective is called the first time, so activate kicks in.
One way to make the system work would be to force every page change (regardless if it was initialized by SPA or browser) running through activate. Here are the required steps: Convert the singleton into a constructor, set cacheViews: false and replace click events by normal hrefs that calls the page route.
Update 2
Here's an example that combines the inPage navigation (without router involvement) with the ability to use browser back/forth navigation. init is responsible for setting up things that are common for activate and gotoPage.
Viewmodel
define(['plugins/router', 'knockout'], function( router, ko ) {
var ctor = function() {
this.pageNo = ko.observable();
this.pageData = ko.observable();
};
ctor.prototype.activate = function( page ) {
this.init(page);
};
ctor.prototype.init = function( page ) {
this.pageNo(page || 1);
this.pageData('Data for ' + this.pageNo());
};
ctor.prototype.gotoPage = function( page ) {
var url = "extras/welcome/" + page;
this.init(page);
router.navigate(url, { replace: false, trigger: false });
};
return ctor;
});
View
<section>
<h1>
Hello Durandal Pagination
</h1>
<a data-bind="click: gotoPage.bind($data, 1)" style="cursor: pointer;">Page 1</a>
<a data-bind="click: gotoPage.bind($data, 2)" style="cursor: pointer;">Page 2</a>
<a data-bind="click: gotoPage.bind($data, 3)" style="cursor: pointer;">Page 3</a>
<h2 data-bind="text: pageData"></h2>
</section>
Live example at: http://dfiddle.github.io/dFiddle-2.0/#extras/welcome

JS onmousedown limited to left-click

I have built a sort of picture gallery in JS. On given img and p elements, the onmousedown events calls two functions: it loads a new image and a new description (see below)
But, as opposed to what I was thinking, the onmousedow it is triggered by right-click too. I don't like this and I'd love to limite the onmousedown event to the left-click of the mouse.
Is there any way to do this?
Many thanks for your help.
HTML:
<img style="max-width: 100%; cursor:pointer;" src="../../img/picture1.jpg" alt="text" title="click me"
id="showgallery" onmousedown="changeimg(); changedscrpt()" />
enter code here
<p class="myclass" style="text-align: center;" id="imgdescription">Description</p>
You should move out calls to changeimg() and changedscrpt() to separate method which would evaluate first whether left mouse was pressed, something like that:
onmousedown="checkAndChange(event, this)";
JavaScript:
function checkAndChange(e, obj)
{
if (leftMousePressed(e))
{
changeimg();
changedscrpt();
}
}
function leftMousePressed(e)
{
e = e || window.event;
var button = e.which || e.button;
return button == 1;
}
If the right mouse button will be pressed, JavaScript will not do anything (will not change next image).

WIndows 8 Metro List View Event Listener

I am trying to create a simple HTML Metro App for Windows 8. I want to display a list view, and based on the clicked item display different content on the screen. It sounds trivial, right?
But it doesn't work! Here is my code:
<div id="frameListViewTemplate" data-win-control="WinJS.Binding.Template">
<img data-win-bind="src: picture" class="thumbnail" />
</div>
<div id="basicListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : DataExample.itemList.dataSource, itemTemplate: select('#frameListViewTemplate'),onselectionchanged : handler}">
</div>
Than in the defult.js
var myListView = document.getElementById("basicListView").winControl;
myListView.addEventListener("selectionchanged", handler);
And the handler:
function handler() {
console.log("Inside the handler : ");
}
handler.supportedForProcessing = true;
So the handler is never called. My questions are: How can I add an event listener and its handler to the listview control.
How can I recognize which element on the list view was clicked.
P.S.
The listview is displayed properly in my app.
Thank you for help,
J
To get the item that is "clicked", you need to use itemInvoked. Selection changed would happen when the user cross slides on the item to select it, rather than taping/clicking to "invoke" it.
http://msdn.microsoft.com/en-us/library/windows/apps/br211827.aspx has some basic details.

Handle button action in a list

I am trying to develop an iphone application using sencha framework .I need to show a list of items in a list.Each cell in the list holds a button also.If the user clicks on a button in a particular index, then a popover needs to be displayer near to the button .I am using the following code to do this
itemTpl : '<div class="div1"><label class = "tag-name-hdr"> {tagnamehdr} </label> <label class = "tag-name-value" style="width:55px;"> value </label> <input type="text" class ="tag-name-text" name="lname" /> <label class = "unit-name" > unit </label> <select class = "unit-name_dropdown" > <option>mg/dr</option> <option>gm/dr</option> <option>m/dr</option> </select> <input type="image" id="popupbtn" class="template_popup_button" src="Images/arrow_more_orange.png" > </div>',
listeners : {
//itemtap : function(list, index, item, e, popupbtn) {
itemtap : function(list, index, item, evt) {
if(evt.getTarget('.template_popup_button')) {
alert(item);
alert(index);
showOverlay(item, evt, index);
}
}
}
Now my issue is that the popover is showing for the selected cell.I need to show the popover near to the clicked button.Is there any way to get the clicked button object to show the overlay/popover near to that.Now I am passing clicked item cell object as parameter to "showOverlay",i need to pass clicked button object
Thanks in advance..
The evt variable holds information about the event. You could check if evt.target is a button (or the button you want to act upon).
Note that if all you want is a single button per cell, you could use the onItemDisclosure config option, that will add a button for you with a handler.