WinJS listview iteminvokedHanlder how to - javascript

I'm using the iteminvokedHandler and was wonder if there is a better way to interact with the listView.
Currently using this:
WinJS.UI.processAll(root).then(function () {
var listview = document.querySelector('#myNotePad').winControl;
listview.addEventListener("iteminvoked", itemInvokedHandler,false);
function itemInvokedHandler(e) {
e.detail.itemPromise.done(function (invokedItem) {
myEdit();
});
};
});
The problem is that everytime I click on the listview myEdit() is run and propagates within the listview. I was wondering how to do it once and stop invoking listview until I am done with myEdit? Is there a simpler way to handle such a situation as this?

Simple yet hard to see when you have a mind block and forget some of the basics (yes yes I'm still learning):
var testtrue = true;
WinJS.UI.processAll(root).then(function () {
var listview = document.querySelector('#myNotePad').winControl;
listview.addEventListener("iteminvoked", itemInvokedHandler,false);
function itemInvokedHandler(e) {
e.detail.itemPromise.done(function (invokedItem) {
if (testtrue === true){
myEdit();
}
});
};
});
In myEdit:
function myEdit() {
var theelem = document.querySelector(".win-selected #myNotes");
var gestureObject = new MSGesture();
gestureObject.target = theelem;
theelem.gestureObject = gestureObject;
theelem.addEventListener("pointerdown", pointerDown, false);
theelem.addEventListener("MSGestureHold", gestureHold, false);
function pointerDown(e) {
e.preventDefault();
e.target.gestureObject.addPointer(e.pointerId);
}
function gestureHold(e) {
if (e.detail === e.MSGESTURE_FLAG_BEGIN && test === true) {
e.preventDefault();
editNotes();
} else {
}
console.log(e);
}
theelem.addEventListener("contextmenu", function (e) {
e.preventDefault();}, false); //Preventing system menu
};
function editNotes() {
//The Code I wish to execute
return test = false;
};
What I needed was a conditional statement so that it would run if true and not if false. That same test needed to be done in the gestureHold otherwise it would continue to fire myEdit on the invoked item because of the way the gesture is attached to the item the first time it is run.

Related

How to detect DOM modification event

I have been trying to get listen to DOM change event for a several hours, however still cannot get it working.
I need to detect events that are showed in Chrome Debug Tools as changes displayed as pink color.
Here is what I've tried
function listenForDomModified(node, listener) {
node.addEventListener("DOMSubtreeModified", listener, false);
var iframes = node.getElementsByTagName("iframe");
for (var i = 0, len = iframes.length, doc; i < len; ++i) {
// Catch and ignore errors caused by iframes from other domains
try {
doc = iframes[i].contentDocument || iframes[i].contentWindow.document;
doc.addEventListener("DOMSubtreeModified", listener, false);
} catch (ex) {}
}
}
var findElements = function () {
elements.iframeBlock = $(SELECTOR.IFRAME_BLOCK);
};
var onIframeChange = function (e) {
console.log("CHANGE !!!");
alert("DOM CHANGES");
};
var setListeners = function () {
listenForDomModified(elements.iframeBlock[0],onIframeChange);
elements.iframeBlock.bind('DOMSubtreeModified', function(e) {
if (e.target.innerHTML.length > 0) {
alert("ON CHANGE");
}
alert("ON CHANGE");
});
//elements.iframeBlock.change(onIframeChange);
};
Please note, I tried these methods separately.
But still cannot get my function called. However Chrome displays these changes.
I would be grateful for any help.
Thanks
Have you tried
$(document).on('change', function () { /*code*/ });
Try this jQuery approach:
$("iframe").contents().find('body').on("change", function() {
alert("DOM CHANGES");
});
not tested...

Get id of triggered updatepanel only

I have two distinct updatepanels on my page and each of them have triggered by different buttons that are placed in different repeaters, updapenels work properly and to avoid from conflict i had setted their UpdateMode="Conditional" but i can't determine the id of updapanel which is triggering.
In InitializeRequest and EndRequest events, i need to determine which updatepanel triggered and then i can do some client-side animations specified on this updapanel.
Thanx.
So after all researches, the best practice looks like that:
Using Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequest) and Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(InitializeRequest)
i added all my triggers a data attribute like
<asp:LinkButton Text="Detay" data-sid="PickAppToShow" CssClass="btn btn-default btn-sm" ID="lbtSelectApplication" runat="server" /></td>
and at the request handlers look like that
function InitializeRequest(sender, args) {
try {
var consernedObject = getAjaxObjectFromSender(sender);
consernedObject.Start();
}
catch (e) {
fn_ErrorLog(e);
}
};
function EndRequest(sender, args) {
try {
var consernedObject = getAjaxObjectFromSender(sender);
consernedObject.End();
}
catch (e) {
fn_ErrorLog(e);
}
};
helper method is like :
function getAjaxObjectFromSender(sender) {
var poster = sender._activeElement;
if (poster == null) {
return DefaultObject;
}
var posterSid = poster.getAttribute('data-sid');
if (posterSid == null) {
return DefaultObject;
}
var consernedObject = window[posterSid];
if (consernedObject == null) {
return DefaultObject;
}
return consernedObject;
}
The trick is starting now, as you had seen above window[posterSid] gives you the given named js object. if you check my RequestHandlers; they are using two methods as consernedObject.Start(); and consernedObject.End(); which are predefined in another js file named AjaxObjects.
For example :
var DefaultObject = {
Start: function () {
//When Progress Start
App.blockElement($(window), "Pleae wait");
},
End: function () {
//When Progress End
App.unblockElement($(window));
}
};
var PickAppToShow = {
Start: function () {
//When Progress Start
App.blockElement($("#app-detail-content"), "Asking To Server");
},
End: function () {
//When Progress End
App.unblockElement($("#app-detail-content"));
}
};
var PickMemberToDetail = {
Start: function () {
//When Progress Start
App.blockElement($(window), "Wait For It");
},
End: function () {
//When Progress End
$("#modal-MembershipDetail").modal("show");
App.unblockElement($(window));
}
};
This method have solved all my problems but one that i need to take a parameter from serverside, which can be achived by using hiddenField.

Multiple click handlers for a single element

I've written a few events to handle opening and closing of a snap js drawer. This code below works, but I feel it could be written more efficiently. Any suggestions?
function openMobileMenu() {
event.preventDefault();
snapper.open('left');
$('#btn-menu').off('click', openMobileMenu);
$('#btn-menu').on('click', closeMobileMenu);
}
function closeMobileMenu() {
event.preventDefault();
snapper.close('left');
$('#btn-menu').on('click', openMobileMenu);
$('#btn-menu').off('click', closeMobileMenu);
}
$('#btn-menu').on('click', openMobileMenu);
Make your code modular and your concepts explicit.
You can start by creating a MobileMenu object which encapsulates the logic.
Note: The following code was not tested.
var MobileMenu = {
_snapper: null,
_$button: null,
_direction: 'left',
init: function (button, snapper, direction) {
this._$button = $(button);
this._snapper = snapper;
if (direction) this._direction = direction;
this._toggleSnapperVisibilityWhenButtonClicked();
},
_toggleSnapperVisibilityWhenbuttonClicked: function () {
this._$button.click($.proxy(this.toggle, this));
},
toggle: function () {
var snapperClosed = this._snapper.state().state == 'closed',
operation = snapperClosed? 'open' : 'closed';
this._snapper[operation](this._direction);
}
};
Then in your page you can just do the following to initialize your feature:
var mobileMenu = Object.create(MobileMenu).init('#btn-menu', snapper);
Modularizing your code will make it more maintainable and understandable in the long run, but also allow you to unit test it. You also gain a lot more flexibily because of the exposed API of your component which allows other code to interact with it.
E.g. you can now toggle the menu visibility with mobileMenu.toggle().
Use a variable to keep track of the state:
var menu_open = false;
$("#btn-menu").on('click', function(event) {
event.preventDefault();
if (menu_open) {
snapper.close('left');
} else {
snapper.open('left');
}
menu_open = !menu_open; // toggle variable
});
snap has a .state() method, which returns an object stuffed with properties, one of which is .state.
I think you want :
$('#btn-menu').on('click', function() {
if(snapper.state().state == "closed") {
snapper.open('left');
} else {
snapper.close('left');
}
});
Or, in one line :
$('#btn-menu').on('click', function() {
snapper[['close','open'][+(snapper.state().state == 'closed')]]('left');
});
Also, check How do I make a toggle button? in the documentation.

Returning true on Link Click Event isn't working

I am trying to execute some code that has a callback when clicking on specific links. The callback is to click the link again, but on the second pass, the method returns true to follow normal behavior. But for some reason, it's not working? I use clickedLink for proper scope. In the event callback, this was referring to window.
UPDATE
For a little more clarity, I agree normally this wouldn't be an optimal solution, but I am using Google's Tag Manager to monitor eCommerce traffic. I am trying to make sure product clicks get pushed to their dataLayer, and using their event callback to resume normal behavior. More info here: https://developers.google.com/tag-manager/enhanced-ecommerce#product-clicks
This is my updated method based on the answers below, but it still doesn't work.
var shopCartBtnClicked = false;
var clickedLink;
jQuery('#pdp_add_cart, .add_to_cart_button').click(function(e) {
if (shopCartBtnClicked === true) {
shopCartBtnClicked = false; //I make it here just fine
} else {
e.preventDefault();
clickedLink = this;
var pdp = false;
if (mmProduct) {
//On detail page
mmProduct.qty = jQuery('input[name="quantity"]').val();
pdp = true;
} else {
//on a shopping page
mmProduct = findProductClicked(this);
mmProduct.qty = 1;
}
dataLayer.push({
'event': 'addToCart',
'ecommerce': {
'currencyCode': 'USD',
'add': {
'products': [{
'name': mmProduct.name,
'id': mmProduct.id,
'price': mmProduct.price,
'quantity': mmProduct.qty
}]
}
},
'eventCallback': function () {
//Are we on a product detail page with a form, or just a shopping page with a link?
if (pdp) {
jQuery('form.cart').submit(); //This part works just fine
} else {
mmProduct = null;
shopCartBtnClicked = true;
$(clickedLink).trigger('click'); //This doesn't
}
}
});
}
});
Its not very well done, but this should work:
var shopCartBtnClicked = false;
var clickedLink;
jQuery('.add_to_cart_button').click(function(e) {
if (shopCartBtnClicked === true) {
shopCartBtnClicked = false;
// dont return, just let javascript handle this one
} else {
// only execute when you have not set it to true
e.preventDefault();
clickedLink = this;
shopCartBtnClicked = true;
$(clickedLink).trigger('click');
}
});
I do have to wonder why you don't just execute your other logic first and then not prevent default anyway.
Taking #somethinghere's answer, your code can further be simplified to improve readability:
var shopCartBtnClicked = false;
jQuery('.add_to_cart_button').click(function(e) {
if( shopCartBtnClicked ) {
shopCartBtnClicked = false;
// dont return, just let javascript handle this one
} else {
// only execute when you have set it to true
e.preventDefault();
shopCartBtnClicked = true;
this.click();
}
});
Or, as suggested by #Regent:
var shopCartBtnClicked = false;
jQuery('.add_to_cart_button').click(function(e) {
shopCartBtnClicked = !shopCartBtnClicked;
if( shopCartBtnClicked ) {
e.preventDefault();
this.click();
}
});
OK guys, thank you for helping me get there. Normally, all of the other answers would work great, but for this specific tag manager instance, it appears (for some unknown reason), document.location works in the event callback fine here. This works.
It's weird because I used $(this).('form.cart').submit(); in a callback earlier in the code.
'eventCallback': function () {
//Are we on a product detail page with a form, or just a shopping page with a link?
if (pdp) {
jQuery('form.cart').submit();
} else {
mmProduct = null;
document.location = $(clickedLink).attr('href');
//$(clickedLink).trigger('click');
}
}

WinJS gestureRecognizer - how to trap multiple gestures

I've been using this article (and some others) to try and implement a gesture recognition in my app, and it does work. However, what I want to do is to detect multiple gestures; for example, a swipe, and a touch. What i don't seem to be able to do is to establish whether the MouseUp event is caused by the end of a gesture, or by a single touch.
function processUpEvent(e) {
lastElement = e.currentTarget;
gestureRecognizer.processUpEvent(e.currentPoint);
processTouchEvent(e.currentPoint);
}
What happens currently is it processed both. How can I detect whether the user has 'let go' of the screen for a swipe, or a touch?
EDIT:
var recognizer = new Windows.UI.Input.GestureRecognizer();
recognizer.gestureSettings = Windows.UI.Input.GestureSettings.manipulationTranslateX
recognizer.addEventListener('manipulationcompleted', function (e) {
var dx = e.cumulative.translation.x
//Do something with direction here
});
var processUp = function (args) {
try {
recognizer.processUpEvent(args.currentPoint);
}
catch (e) { }
}
canvas.addEventListener('MSPointerDown', function (args) {
try {
recognizer.processDownEvent(args.currentPoint);
}
catch (e) { }
}, false);
canvas.addEventListener('MSPointerMove', function (args) {
try {
recognizer.processMoveEvents(args.intermediatePoints);
}
catch (e) { }
}, false);
canvas.addEventListener('MSPointerUp', processUp, false);
canvas.addEventListener('MSPointerCancel', processUp, false);
So I need to handle both processUp and manipulationcompleted, but one or the other.
You can have a look at my "input" demo in codeSHOW. Just install the codeSHOW app (http://aka.ms/codeshowapp) and look at the Pointer Input demo and "see the code" or just go to the source code on CodePlex.
Hope that helps.
I've found a way to do this, but it's not pretty:
var eventFlag = 0;
var processUp = function (args) {
try {
recognizer.processUpEvent(args.currentPoint);
if (eventFlag == 0) {
// do stuff
} else {
eventFlag = 0;
}
}
catch (e) { }
}
recognizer.gestureSettings = Windows.UI.Input.GestureSettings.manipulationTranslateX
recognizer.addEventListener('manipulationcompleted', function (e) {
var dx = e.cumulative.translation.x
//Do something with direction here
eventFlag = 1;
});

Categories

Resources