jQuery Mobile click events on dynamic list items - html

I'm having trouble getting click events from list items. In this page:
http://bec-systems.com/list-click.html
The first the entries in the list fire click events. However, if I dynamically add 3 more events by pushing the "Refresh Update List" button, the next 3 list entries do not generate click events.
Appreciate any suggestions as to how I can make this work, or generally improve the code.
Thanks,
Cliff
Code is also listed below:
<!DOCTYPE html>
<html>
<head>
<title>Status</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#refreshUpdateButton").on("click", function(event, ui) {
console.log("refreshUpdateButton")
versions = ["0.3", "0.4", "0.5"]
for (var i=0; i < versions.length; i += 1) {
$("#updateVersionsList").append('<li><a id="updateVersionItem-' + (i+3) + '">' + versions[i] + '</a></li>');
if ($("#updateVersionsList").hasClass('ui-listview')) {
$("#updateVersionsList").listview("refresh");
} else {
$("#updateVersionsList").trigger('create');
}
}
})
$('[id^=updateVersionItem]').on("click", function(event, ui) {
console.log("updateVersion, selected = " + $(this).attr('id'));
})
});
</script>
</head>
<body>
<!-- Software update page -->
<div data-role="page" id="software-update-page">
<div data-role="header">
<h1>Software Update</h1>
</div><!-- /header -->
<div data-role="content">
<h1>Select Software version:</h1>
<ul data-role="listview" id="updateVersionsList">
<li><a id="updateVersionItem-0">0.0</a></li>
<li><a id="updateVersionItem-1">0.1</a></li>
<li><a id="updateVersionItem-2">0.2</a></li>
</ul>
<br>
<a data-role="button" class="ui-btn-left" id="refreshUpdateButton">Refresh Update list</a>
</div><!-- /content -->
</div>
</body>
</html>

Use this form of .on() (per comments below).
$(document).on("click", '[id^=updateVersionItem]', function(event, ui) {
console.log("updateVersion, selected = " + $(this).attr('id'));
})
Example: http://jsfiddle.net/saluce/YaAEJ/
Otherwise, whenever you dynamically add the new elements, you need to attach the click event to those items.
Assuming the following code:
function doThisOnClick(event, ui) {
console.log("updateVersion, selected = " + $(this).attr('id'));
}
$('[id^=updateVersionItem]').on("click", doThisOnClick);
You can either unbind the handler and reattach to all matching items:
$('[id^=updateVersionItem]').off("click", doThisOnClick);
$('[id^=updateVersionItem]').on("click", doThisOnClick);
Or just dynamically add it to the new items once you add it:
$("#updateVersionsList").append('<li><a id="updateVersionItem-' + (i+3) + '">' + versions[i] + '</a></li>').on("click", doThisOnClick);

create a new function and call it for default and dynamic elements
<a onclick="myfunction()">

Related

AngularJS - Remove/Add Class on element based off if element is active/hover/or contains a value

I have a magnifying glass that when you hover or click on it, it expands to a full search bar. I want the functionality to be that when the search bar is active, it will stay expanded until clicked off, or will stay expanded if the bar has a value. I have the logic in jQuery, but this is my first time using AngularJS (not Angular) and I do not know how to turn this jQuery into a directive, or if there is some built in functionality I am missing. Thank you!
jQuery("#inpt_search").on("focus", function () {
jQuery(this).parent("label").addClass("active");
});
jQuery("#inpt_search").on("blur", function () {
if (jQuery(this).val().length == 0)
jQuery(this).parent("label").removeClass("active");
});
var myApp = angular.module('myApp', []);
// set for Home Controller
myApp.controller('HomeCtrl', function($scope) {
$scope.blueClass = function() {
$scope.class_name = "blue";
$scope.multi_message ="Blue Class Added";
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
<html>
<head>
<link data-require="bootstrap-css#3.2.0" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<script data-require="angular.js#1.3.0-beta.5" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
</head>
<body ng-app="myApp">
<div class="container" ng-controller="HomeCtrl">
<div class="alert" ng-class="{blue:'bg-info', red:'bg-danger',green:'bg-success' }[class_name]">{{multi_message}}</div>
<a class="btn btn-info" ng-click="blueClass()"> Blue Class</a>
</div>
</body>
</html>

Class attribute missing from DOM in inspector

I'm using a function to try and select a div with a class attribute that is nested in a div with an ID. The function does nothing and after some debugging it turns out that when I inspect element in my browser, the div is not showing a class even though I have a class in my HTML. Because there's no class the function doesn't know what to select. See in the following code function playBall is calling function countDown which should be selecting div.timer.
<!DOCTYPE html>
<html>
<head>
<title>Home Run Derby (CSCI2447)</title>
<!-- CSS styles: This is for me to worry about; not you. -->
<link href="css/game.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var secondsRemaining = 30;
var score = 0;
var gamerFirstName;
$(document).ready(function(){
gamerFirstName = prompt("Please enter your first name."," ");
$('div#content p').text('Hello ' + gamerFirstName + '! Are you ready? After clicking "start", you will have 30 seconds to hit as many home runs as you can. The images appear randomly so be ready!');
$('div#gamespace').html('<img src="img/baseball.png"/>');
$('div.timer').removeClass('timer');
alert(numberX());
alert(numberY());
$('button#start_button').click(playBall);
tallyScore();
$('button#start_button').css({"width": "80px","height":"40px","font-size":"18px","background-color":"#b66f42","color": "#253f38", "font-family":"baseball"});
});
function numberX(){
return Math.floor(Math.random() * 636);
};
function numberY(){
return Math.floor(Math.random() * 350);
};
function tallyScore(){
score++;
$('span#score').text( score + " pts");
};
function playBall(){
countDown();
};
function countDown(){
secondsRemaining--;
$("div.timer").text(secondsRemaining + " Seconds Left");
};
</script>
</head>
<body>
<div id="content">
<div id="contenta">
<h1><span>Home Run Derby</span></h1>
<p></p>
<div id="controls">
<span id="score">0 pts</span>
<button type="button" id="start_button">Start!</button>
</div>
<div class="timer">
30 Seconds Left
</div>
</div>
<div id="gamespace">
</div>
</div>
</body>
</html>
In your document.ready function, you have the following line which is removing the class from timer from your div, so when the countDown function executes, it cannot locate the div.timer selector.
Just remove this line:
$('div.timer').removeClass('timer');

Add <li> dynamically reading from a folder photoswipe purpose

Sorry for my English, I am a new to jquery mobile and only have basic knowledge about javascript languages in general; I was playing around with a single page website mobile ( I usually use Dreamweaver CS6) and I reached a good result with photoswipe and everything was good since I had just few images. I have added a lot of them so now I would get the images' link dynamically.
In short, I want to start from a folder on my ftp and read all images file within it and create the <li> items for each one. Can I make this job with jquery mobile or should I use a language like php or .Net
I have read some examples around here and on google but they didn't help me a lot, like this one, I am sure it could be an answer for me in it but I don't know how to start
http://docs.phonegap.com/en/2.4.0/cordova_file_file.md.html#DirectoryReader
Here some code I'm using:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
<!-- Librerie PhotoSwipe -->
<link rel="stylesheet" type="text/css" href="../PhotoSwipe/photoswipe.css">
<link rel="stylesheet" type="text/css" href="../PhotoSwipe/styles.css">
<script type="text/javascript" src="../PhotoSwipe/klass.min.js"></script>
<script type="text/javascript" src="../PhotoSwipe/code.photoswipe-3.0.5.min.js"></script>
<!-- End PhotoSwipe -->
<script type="text/javascript">
$(document).ready(function(){ var myPhotoSwipe = $("#Gallery a").photoSwipe({ enableMouseWheel: false , enableKeyboard: false, captionAndToolbarAutoHideDelay: 0 }); });
</script>
Then my page
<div data-role="page" id="page">
<div data-role="header">
<h1>Title of my Page</h1>
</div>
<div data-role="content">
<ul id="Gallery" class="gallery">
<li>
<a href="../Images/img04.jpg">
<img src="../Images/img04.jpg" alt=""></a>
</li>
</ul>
</div>
When i land on this page everything works fine. Shall I use something like this?
That I took from this website, can I use JSON to accede to my ftp folder and than cycle the content?
Should I put this in a function? If yes who is going to call it?
$("#Photos").live("pagebeforeshow", function(){
$("ul#PhotoList").children().remove('li');
var tag = MyTag
$.getJSON("https://api.instagram.com/v1/tags/" + tag + "/media/recent?callback=?&client_id=####",
function(data){
$.each(data.data, function(i,item){
$("ul#PhotoList").append('<li><img src="' + item.images.low_resolution.url + '" alt="' + item.caption.text + '" width="200" /></li>');
});
});
var photoSwipeInstance = $("ul#PhotoList a").photoSwipe();
});
Any help is appriciated, thank you in advance, I am sure my issue here is my limited knowledge.
You should use pageinit and pagebeforeshow Instead of $(document).ready. Also .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live(). http://api.jquery.com/live/
Append list Items:
$("#PhotoList").append('<li><a href="..
When you finish refresh the list to display your new list:
$('#PhotoList').listview('refresh');
Update:
I use php programs on my server in order to retrieve json strings. Something like this...
xhr = new XMLHttpRequest();
xhr.open("GET","http://192.168.100.2/sr/quotelisttest?name="+s,true);
xhr.send("");
xhr.onreadystatechange = function() {
if (xhr.readyState === 4){
alert(xhr.readyState);
alert(xhr.responseText);
var v = JSON.parse(xhr.responseText);

Populating listview with jQuery Mobile on a multi-page template

I am trying to render a listview on a second page using jquery.mobile.
I am using a single HTML with multiple "pages".
<div data-role="page" id="foo">
List
</div>
<div data-role="page" id="bar">
<div id="ListDiv">
<ul id="listview" data-role="listview" data-inset="true">
</ul>
</div>
</div>
<!--application UI goes here-->
<script type="text/javascript">
$("#loadList").click(function(){
$.getJSON(
"http://localhost/index.php/api/list",{format: "json"},
function(data){
var output = '';
$.each(data, function(key, val) {
output += '<li>' + val +'</li>';
});
$('#listview').append(output).listview('refresh');
});
});
But the problem now is when I click the #loadList button, it does take me to the #bar page, however, it doesn't seem $("#loadList").click() gets executed, because the list doesn't show up on the #bar page. Namely, nothing gets appended to #listView.
Any thoughts?
First there's a problem in this code, $.getJSON loading logic is false. Change page can not be used in a same time with $.getJSON.
There are 2 ways you can make this work:
Remove onclick event and load your data during second page initialization:
$(document).on('pagebeforeshow', '#bar', function(){
$.getJSON(
"http://localhost/index.php/api/list",{format: "json"},
function(data){
var output = '';
$.each(data, function(key, val) {
output += '<li>' + val +'</li>';
});
$('#listview').append(output).listview('refresh');
});
});
});
Unfortunately there's a problem with this solution. Used page event is not going to wait for $.getJSON, so in some cases your listview will be empty when page loads and content will suddenly appear. So this solution is not that great.
Second solution is remove href="#bar" attribute from the button but leave a click event. When $.getJSON action is successful the use changePage function and load next page. In case there's a problem with accessing second page listview store your result (In this ARTICLE you will find how, or HERE) and append it again during a pagebeforeshow event of a #bar page.
I made you a working jsFiddle example: http://jsfiddle.net/Gajotres/GnB3t/
HTML :
<!DOCTYPE html>
<html>
<head>
<title>jQM Complex Demo</title>
<meta name="viewport" content="width=device-width"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
</head>
<body>
<div data-role="page" id="index">
<div data-theme="a" data-role="header">
<h3>
First Page
</h3>
</div>
<div data-role="content">
Load JSON data
</div>
</div>
<div data-role="page" id="second">
<div data-theme="a" data-role="header">
<h3>
Second Page
</h3>
Back
</div>
<div data-role="content">
<h2>Simple list</h2>
<ul data-role="listview" data-inset="true" id="movie-data" data-theme="a">
</ul>
</div>
<div data-theme="a" data-role="footer" data-position="fixed">
</div>
</div>
</body>
</html>
JS :
$(document).on('pagebeforeshow', '#index', function(){
$('#populate-button').on('click',function(e,data){
$.ajax({url: "http://api.themoviedb.org/2.1/Movie.search/en/json/23afca60ebf72f8d88cdcae2c4f31866/The Goonies",
dataType: "jsonp",
jsonpCallback: 'successCallback',
async: true,
beforeSend: function() {
$.mobile.showPageLoadingMsg(true);
},
complete: function() {
$.mobile.hidePageLoadingMsg();
},
success: function (result) {
ajax.jsonResult = result;
$.mobile.changePage("#second");
},
error: function (request,error) {
alert('Network error has occurred please try again!');
}
});
});
});
$(document).on('pagebeforeshow', '#second', function(){
ajax.parseJSONP(ajax.jsonResult);
});
var ajax = {
jsonResult : null,
parseJSONP:function(result){
$('#movie-data').empty();
$('#movie-data').append('<li>Movie name:<span> ' + result[0].original_name+ '</span></li>');
$('#movie-data').append('<li>Popularity:<span> ' + result[0].popularity + '</span></li>');
$('#movie-data').append('<li>Rating:<span> ' + result[0].rating+ '</span></li>');
$('#movie-data').append('<li>Overview:<span> ' + result[0].overview+ '</span></li>');
$('#movie-data').append('<li>Released:<span> ' + result[0].released+ '</span></li>');
$('#movie-data').listview('refresh');
}
}
You have id="loadList)", that is, with a closing parenthesis in
List
Maybe this is causing your problem?

On and Live behave differently on dynamic addition of elements

I am having the following code, i tried with jQuery live and on plugin, while trying with live, i am able to add the event handler which is already present for the element with the class "button" to the newly added element(added dynamically after page load) with the class "button" but on trying with the jQuery on plugin, i am unable to add the already existing event handler to the newly added element.
Example with Live
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<!--START: Adding of javaScript library -->
<script type="text/javascript" src="script/jquery.min.js"></script>
<!--END: Adding of javaScript library-->
<!--START: Adding of javaScript library need internet Connection-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!--END: Adding of javaScript library need internet Connection-->
</head>
<script>
jQuery(document).ready(function(){
jQuery(".button").live("click", test);
});
var i=0;
function test(event){
var elem=jQuery(this).parent().html();
jQuery("body").append("<div class=DivClass" + i++ + ">"+elem+"</div>" );
}
</script>
<body>
<div id="Container"><input value="click me" class="button" type="button"/></div>
</body>
</html>
Example With On
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<!--START: Adding of javaScript library -->
<script type="text/javascript" src="script/jquery.min.js"></script>
<!--END: Adding of javaScript library-->
<!--START: Adding of javaScript library need internet Connection-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!--END: Adding of javaScript library need internet Connection-->
</head>
<script>
jQuery(document).ready(function(){
jQuery(".button").on("click", test);
});
var i=0;
function test(event){
var elem=jQuery(this).parent().html();
jQuery("body").append("<div class=DivClass" + i++ + ">"+elem+"</div>" );
}
</script>
<body>
<div id="Container"><input value="click me" class="button" type="button"/></div>
</body>
</html>
and moreover i am able to put the event handler binding code using live outside of jquery ready which is working fine but if i put event handler binding using on outside of jquery ready, the event handler is not working.Thanks in advance for any help.
If you want to have your selector to be dynamically tested, you must pass it as argument, as in your code you're calling a function on a constant empty collection :
jQuery(document).ready(function(){
var i=0;
function test(event){
    var elem=jQuery(this).parent().html();
    jQuery("body").append("<div class=DivClass" + i++ +   ">"+elem+"</div>" );
  }
$(document).on("click", ".button", test);
});
(you'll see I defined test here before I pass it to the function, your code hurts my eyes)
jQuery('body').on('click', '.button', test);