Why wont Click events work for li elements on iOS? - javascript

I have a mobile app that I developed using PhoneGap (and html/css/javascript) and there is a part of the app that uses a list and I want to have a click event fire when the li is touched/clicked.
The weird thing is that it works fine when testing in Chrome w/Ripple, works fine on Android and BlackBerry, but in iOS it wont.
You can try out the app here:
Android -- https://market.android.com/details?id=com.viethconsulting.ALIVEapp
iOS -- http://itunes.apple.com/us/app/al!ve-volunteer-engagement/id475428488?ls=1&mt=8
BlackBerry -- Still waiting for App World approval.
If you look at the events calendar (labeled "Events Calendar" in the menu) that the events are listed in a table and have little "expand" buttons to the right.
You'll notice that touching/clicking the rows in the iOS version does nothing (though if you click the heading or the expand icon for each row it will work).
I have no idea why this is the case with iOS and not the other platforms. Any ideas?
Here are some examples of my code:
$(function()
{
$("li.rssRow").live({
click: function(){
if($(this).attr("rel") != "loaded") {
$(this).append('<div><br />Loading Content...<br /></div>');
$(this).children("div:first").load($(this).children(":first").children(":first").attr("rel")+"&mobile_grab=true #mobile_grab");
$(this).attr("rel","loaded");
$(this).children('img:first').rotate({angle:0,animateTo:180});
$(this).children('img:first').attr("rel","180");
}
else {
RotateImage($(this).children('img:first'));
$(this).children('div:first').slideToggle();
}
}
});
// Fix click functionality for calender item contact/map links on iOS devices
$('#span.c_data').live({
click: function() {
window.location = $(this).children("a:first").attr("href");
}
});
});
and the related HTML: (note: this content pulled from a different app, but uses identical code with exception of urls, yet it behaves exactly the same as well).
<div id="body_content" class="rssFeed">
<div class="rssBody">
<ul>
<li class="rssRow odd" rel="loaded">
<h4>Dec 12, 2011: new event</h4>
<img src="assets/img/expand_result.gif" class="expand" rel="0" style="-webkit-transform: rotate(0deg); ">
<p></p>
<div style="display: none; ">
<div id="mobile_grab" style="display:none;">
<div class="c_row">
<span class="c_label">Event Name:</span>
<span class="c_data">new event</span>
</div>
<div class="c_row">
<span class="c_label">Description:</span>
<span class="c_data"></span>
</div>
<div class="c_row">
<span class="c_label">Event Date:</span>
<span class="c_data">12-12-11<br></span>
</div>
<div class="c_row">
<span class="c_label">Event Time:</span>
<span class="c_data"></span>
</div>
<div class="c_row">
<span class="c_label">Location:</span>
<span class="c_data">
Grand Ledge Opera House<br>121 S. Bridge Street<br>Grand Ledge, MI 48837<br><br>
<a target="_blank" href="http://maps.google.com/maps?q=121+S.+Bridge+Street,Grand+Ledge,MI%2048837%20us">click here for Google Maps</a>
</span>
</div>
<div class="c_row">
<span class="c_label">Contact Person:</span>
<span class="c_data"></span>
</div>
<div class="c_row">
<span class="c_label">Event Registration:</span>
<span class="c_data">
<a target="_blank" href="http://mms.anytownbusinessnetwork.org/members/evr/regmenu.php?orgcode=BUSI">Click here to register for events...</a><br>
</span>
</div>
<div class="c_row" style="display:none;">
<span class="c_label">Outlook/vCalendar:</span>
<span class="c_data">click on the date(s) to add to your calendar:<br>12-12-11<br></span>
</div>
<div class="c_row" style="display:none;">
<span class="c_label">Email Reminder:</span>
<span class="c_data">
setup an email reminder for this event
</span>
</div>
</div>
</div>
</li>
<li class="rssRow even">
<h4>Jan 30, 2012: new event</h4>
<img src="assets/img/expand_result.gif" class="expand" rel="0">
<p></p>
</li>
</ul>
</div>
</div>
Thanks in advance for any help you can offer.
Also, this may not be the most efficient approach, so I welcome suggestions for improving the javascript as well. The HTML I can't do a whole lot about though.

I would suggest wrapping your WHOLE LI content into n A element, and manage your click event there - JQuery Mobile does this as well - by using styling you can make sure everything is rendered in order, and it WILL work in ANY browser (mobile/desktop as well), since it's just a standard A tag...
e.g.
<li class="rssRow odd" rel="loaded">
<a href="#" rel="http://mms.anytownbusinessnetwork.org/Calendar/moreinfo.php?eventid=16646" title="View this feed at Anytown Business Network Calendar RSS Feed" target="_blank"><h4>Dec 12, 2011: new event</h4>
<img src="assets/img/expand_result.gif" class="expand" rel="0" style="-webkit-transform: rotate(0deg); ">
......
</a>
</li>
Hope this helps!

cursor:pointer;
Add this style to the li tag.

Related

Right/Context Click in IE11 using selenium webdriver is not working properly

I have to perform right click on a element on a page to open/select a context menu. When I try to do this, using Action class it performs the click operation but not on the element. It executes contextClick() command at some other place on screen instead of element I have passed as a argument to contextClick().
I am running application on Windows 10 with IE11.
Here is the HTML code of page.
<ul id="menus" class="list" style="height: 613.734px;">
<li id="1" class="default">
<div class="inner-div" style="display: inline;">
<span class="menu"></span>
<span class="menu-title">Delete All</span>
</div>
<div class="menuBtn" title="Hide"></div>
</li>
<li id="2" class="default">
<div class="inner-div" style="display: inline;">
<span class="menu"></span>
<span class="menu-title">Delete User</span>
</div>
<div class="menuBtn" title="Hide"></div>
</li>
<li id="3" class="default">
<div class="inner-div" style="display: inline;">
<span class="menu"></span>
<span class="menu-title">Add User</span>
</div>
<div class="menuBtn" title="Hide"></div>
</li>
</ul>
This is the code I am trying.
WebElement element = driver.findElement(By.xpath("//li[.='Add User']");
Actions action= new Actions(driver);
action.contextClick(element).perform();
I have tried with below InternetOptions as well but no luck.
InternetExplorerOptions ieCapabilities = new InternetExplorerOptions();
ieCapabilities.setCapability("nativeEvents", true);
ieCapabilities.setCapability("unexpectedAlertBehaviour", "accept");
ieCapabilities.setCapability("ignoreProtectedModeSettings", true);
ieCapabilities.setCapability("disable-popup-blocking", true);
ieCapabilities.setCapability("enablePersistentHover", false);
new InternetExplorerDriver(ieCapabilities);
It should right click on the element like it does in all the other browsers, however; it performs rightClick on different location instead of the element given.
Can anyone please help me on this?
IE Installation issue was there during OS update. Seems to be resolved after reimage.

How to ignore javascript until button is click, then run

I have been adding ticket sales to our home page but it has dramatically slowed down the site. We have about 1250 shows for this season and even though adding this to the home page sales has gone up but people are complaining about the speed.
Currently I'm using the javascript:showhide to hold the ticket purchase information in a hidden div that shows when you click buy tickets.
I would like to have it NOT run anything in the hidden div unless the buy tickets button is click. Then it would pull the ticketing information and populate the div.
We will have about 300 of the ticketing scripts on the page at one time like Show1-Oct, Show2-Oct, Show3-Oct, Show1-Nov, Show2-Nov, Show3-Nov and so on.
Any ideas or help is greatly appreciated.
<div class='topShow bg-Show-Main'>
<a href='Show1.php'><img alt='Show1' title='Show1' src='images/show/Show1.jpg'>
<p class='title'>Show1</p>
<p>Opens October 30th</p>
</a>
<div class='btnContainer2'>
<a class='btn1' style="text-align: left; width:49%; display: inline-block;" href='Show1.php'>More info</a>
<a class='btn2 red' style="text-align: right; width:50%; display: inline-block;" href="javascript:showhide('Show1-Oct')">Buy Tickets</a>
</div>
<div id="Show1-Oct" style="display:none;">
<script type="text/javascript" src="http://website.com/booking/index.php?controller=FrontEnd&action=ActionLoad&theme=10&view=list&icons=T&cid=15&locale=1"></script>
</div>
<div class='clear'></div>
</div>
<div class='topShow bg-Show-Main'>
<a href='Show2.php'><img alt='Show2' title='Show2' src='images/show/Show2.jpg'>
<p class='title'>Show2</p>
<p>Opens October 31st</p>
</a>
<div class='btnContainer2'>
<a class='btn1' style="text-align: left; width:49%; display: inline-block;" href='Show2.php'>More info</a>
<a class='btn2 red' style="text-align: right; width:50%; display: inline-block;" href="javascript:showhide('Show2-Oct')">Buy Tickets</a>
</div>
<div id="Show2-Oct" style="display:none;">
<script type="text/javascript" src="http://website.com/booking/index.php?controller=FrontEnd&action=ActionLoad&theme=10&view=list&icons=T&cid=16&locale=1"></script>
</div>
<div class='clear'></div>
</div>
Loading up a separate javascript file for each element on the page is a really bad idea.
A more sane design would be to have a single script that makes an ajax call for the necessary data for each listing when needed (when the user clicks that 'buy tickets' button) and injects it into the page. Something along these lines: (some extraneous HTML removed from your sample code, but you'll get the idea)
$('.btn2').on("click", function() {
var myId = $(this).parent().next().attr("id"); // or store this as a data attribute on the button or somewhere else conveniently accessible
console.log("Get data for ", myId);
$.get("/whatever?id=" + myId, function(response) {
// assuming that ajax call returns html, just inject it into the div:
$('#" + myId').html(response);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='topShow bg-Show-Main'>
<div class='btnContainer2'>
<a href="#" class='btn2 red'>Buy Tickets</a>
</div>
<div id="Show1-Oct">
</div>
<div class='clear'></div>
<div class='btnContainer2'>
<a href="#" class='btn2 red'>Buy Tickets</a>
</div>
<div id="Show2-Oct">
</div>
<div class='clear'></div>
</div>

Get data from element without id or class

I am building a Chrome extension (and therefore can only use JavaScript) and I need to get the link that resides in the h2 with the heading2 class.
However, there are multiple h2 items with that class (not shown here), and I will not know what the link will point to, as it changes monthly.
In this example, the content of the header is "Think before you tweet". It will always be under another header that contains the words "Featured Topic."
What I am looking to get is the /think_before_you_tweet from the href= of that h2 item. It shows that I have already completed the topic underneath the h2, but that will not always be the case.
Here is the code for the website:
<div class="chosen_for_you_section">
<div class="internal_container">
<h2 class="section_header"><img src="/public/s360/img/360-spinner.png" class="s360LogoHeader">Featured Topic <i class="fa fa-info-circle"></i> <span class="infoTxt">Read about what to do</span></h2>
<article class="article_block masonry_item " data-article_id="431">
<div class="article_image">
<img src="/thumb/public/media/nh/images/twitter_tweet_think_before_send.png?q=&h=278" />
<i class="fa fa-check-square-o article_complete article_type_icon" title="Article"></i>
<div class="action_icons">
<span class="like "><a title="Favorite"><i class="fa fa-heart"></i></a></span>
</div>
</div>
<header>
<h2 class="heading2">Think Before You Tweet!</h2>
<div class="article_required_complete">Congratulations, you've completed this required topic.</div>
<div class="category_blocks">
<p>
Social Media
</p>
</div>
</header>
</article>
<div class="focus_items">
<div class="home_side">
<p>
<img alt="" src="" style="width: 430px; height: 422px;" /><!-- I hid the img src here because it reveals some personal information and is not important -->
</p>
<p></p>
</div>
</div>
</div>
</div>
I can use jQuery in my extension, but I do not have any back-end capabilities.
Use jQuery :contains selector:
$('h2.section_header:contains("Featured Topic") + article a')[0].href
Looks like you've gotta loop through the h2.section_header headers, see if the text matches whatever you want, and then grabs the link from the header following itself.
$('h2.section_header').each(function(index, element) {
var $element = $(element);
if ($element.text().match(/Featured Topic/i)) {
$('#result').html($element.next('article').find('h2.heading2 a').attr('href'));
}
});
#result {
border: 3px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
<div class="chosen_for_you_section">
<div class="internal_container">
<h2 class="section_header"><img src="/public/s360/img/360-spinner.png" class="s360LogoHeader">Featured Topic <i class="fa fa-info-circle"></i> <span class="infoTxt">Read about what to do</span></h2>
<article class="article_block masonry_item " data-article_id="431">
<div class="article_image">
<img src="/thumb/public/media/nh/images/twitter_tweet_think_before_send.png?q=&h=278" />
<i class="fa fa-check-square-o article_complete article_type_icon" title="Article"></i>
<div class="action_icons">
<span class="like "><a title="Favorite"><i class="fa fa-heart"></i></a></span>
</div>
</div>
<header>
<h2 class="heading2">Think Before You Tweet!</h2>
<div class="article_required_complete">Congratulations, you've completed this required topic.</div>
<div class="category_blocks">
<p>
Social Media
</p>
</div>
</header>
</article>
<div class="focus_items">
<div class="home_side">
<p>
<img alt="" src="" style="width: 430px; height: 422px;" /><!-- I hid the img src here because it reveals some personal information and is not important -->
</p>
<p></p>
</div>
</div>
</div>
</div>
with jQuery's :contains selector use this:
jQuery('h2:contains("Featured Topic") ~ article h2.heading2 a').attr('href')
try at http://jsfiddle.net/ug01a0d2/
without jQuery try to bind to class "section_header" or use a cycle with the textContent check to iterate all "h2.section_header"
If there are multiple H2 class heading2 :
$('h2[class*="heading2"] a').each(function(){
var href = $(this).attr('href');
// Do what you want with this href
});
Use XPath! The syntax is pretty, uh, unfortunate, but it's very powerful:
var result = document.evaluate('//h2[#class="section_header"]/following-sibling::article//h2[#class="heading2"]/a', document, null, XPathResult.ANY_TYPE, null );
That should select that anchor node. I'm not sure if it's available to extensions, but Chrome defines a handy helper method called $x that eliminates all that boilerplate around the query.
More information: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript

Creating JQuery div class filter not working

I am trying to make a filter with JQuery that hides all div's and then only shows div's depending on a class inside it called "brand", I managing to get it to hide all div's however it will not show the ones matching the class.
The alert I have added inside the statement is showing so I think it may be something to do with the parent show, has anyone got any ideas?
The html:
<div class="section-link" id="section-tooltip" data-content="Popup with option trigger" rel="popover" data-placement="right" title="" data-original-title="">
<div class="section-features" style="display: none;">
<p><i class="icon-star"></i> protective, waterproof lid</p>
<p><i class="icon-star"></i> enhanced wooden coating</p>
<p><i class="icon-star"></i> long lasting materials</p>
<p><i class="icon-star"></i> 2 year warranty</p>
<p><i class="icon-star"></i> includes durable bag</p>
</div>
<div class="brand tp" style="display: none;"></div>
<div class="price" style="display: none;"> £47.99</div>
<a href="Garden-Games-Picnic-Table-Sandpit-6407.html">
<img src="picnic_table_sandpit.jpg" title="Garden Games Picnic Table Sandpit" alt="Garden Games Picnic Table Sandpit" width="220">
<h3 align="center">Garden Games Picnic Table Sandpit</h3>
<p align="center">
<span> was: £69.99</span>
<span> Now: £47.99</span>
<span class="button">More Info</span>
</p>
</a>
<a name="a6407"></a>
</div>
/\ there are about 20 div's like this with different brand classes example class="brand garden"
The Js:
function brand(string){
var brand = string;
$('.section-link').hide();
if ($('.section-link').children('.brand').hasClass(brand)) {
alert(brand);
$(this).parent().show();
}
}
I am also testing via the chrome url bar javascript: brand("tp");
Any help greatly appreciated,
Simon
You need to use multiple selector here because you need to fetch .brand elements which also have the specified class
function brand(string){
var brand = string;
$('.section-link').hide();
$('.section-link').children('.brand.' + brand).parent().show();
}
Demo: Fiddle

Replace class depending on event

If have a set of collapsible elements, in which I need to replace classes left and right depending on event isCollapse:
<div class="collapsible-set">
<div class="collapsible">
<h3>
<a class="left">
<span class="left"></span>
</a>
</h3>
</div>
<div class="collapsible">
<h3>
<a class="right">
<span class="right"></span>
</a>
</h3>
</div>
</div>
I need to toggle the classes. Is there an eaiser way to do this than what I came up with?
if (collapse) {
$('.left').addClass('topLeft').removeClass('left');
$('.right').addClass('topRight').removeClass('right');
} else if (!collapse) {
$('.topLeft').addClass('left').removeClass('topLeft');
$('.topRight').addClass('right').removeClass('topRight');
}
There must be an eaiser way to do this without writing so much code...
look at toogleClass http://api.jquery.com/toggleClass/
$('.collapsible:eq(0)').find('a').toggleClass('topLeft').toggleClass('left');
$('.collapsible:eq(1)').find('a').toggleClass('topRight').toggleClass('right');
This should do the trick
$(".collapsible").find(".topLeft, .left").toggleClass("topLeft", collapse).toggleClass("left", !collapse);
$(".collapsible").find(".topRight, .right").toggleClass("topRight", collapse).toggleClass("right", !collapse);

Categories