I am building an Application with PhoneGap. The application has content pulled from an outside resource. Within the content I pull, there are URLs. Since I load the content in my html dynamically, the href does not exist when the page is created. What I need is a way to find that dynamically added href once the content is loaded, and call a function on it when clicked.
Here is part of the html page where the content is placed, specifically in the #page-content div:
<div data-role="content">
<div id="page-title"></div>
<div id="page-region"></div>
<div id="page-content"></div>
</div>
Once the page is loaded with the content, the html page changes to this:
<div data-role="content" class="ui-content" role="main">
<div id="page-title">Mtg: Switchboard and Panelboard Basics: A Tour of the Eaton Hayward Facility<br></div>
<div id="page-region">Oakland/East Bay<br></div>
<div id="page-content"><p>THURSDAY February 20, 2014<br>
OEB Industry Applications Chapter<br>
- construction, differences, functions, features …<br>
Speakers: Joseph Burnett, Jason Maffioli, Kendyl Brown, and Bob Salter, Eaton<br>
Time: Light Dinner at 5:30 PM; Short Presentation at 6:00PM; Tours at 6:30 PM<br>
Cost: none<br>
Place:<br>
Web: www.ThisIsTheUrlINeed.com </p>
<p>We will discuss Basics of switchboard construction, functions and features, some of the basic “dos and don’ts” related to Switchboard specification, differences between Switchboards and Panelboards, some of the differences and similarities between switchboards and <span id="more-4060"></span>switchgear, and application limitations. The short presentation will be followed by a tour where attendees can see first-hand the basic building blocks, and how panelboards and switchboards are built.</p>
<br></div>
</div>
The function I wrote/found to try and grab the href is:
$('#page-content').on('click','a', function(){
console.log(this);
currentPage = $(this).attr('href');
window.open(currentPage, '_blank', 'location=yes')
});
Nothing appears in the console.log when I run it. I read that .on should be used for situations like this, so I am stumped as to what to do next.
Edit, here is the function I am using to populate the html page:
function IE_navigate(index) {
Bindex = index;
$.mobile.changePage('#eventPage', 'slidefade');
$.each(data, function(i,item){
if (i == Bindex) {
//Clear if page was previously populated
//Populate page
$('#page-title').html(item.title + "<br />");
$('#page-region').html(item.Region + "<br />");
$('#page-content').html(item.fullInfo + "<br />");
return false
}
});
};
Edit: SOLUTION Thanks to a combination of the two answers below (and all the help from everyone else!) here is how I was able to get this problem to work:
function IE_navigate(index) {
Bindex = index;
$.mobile.changePage('#eventPage', 'slidefade');
$.each(data, function(i,item){
if (i == Bindex) {
//Clear if page was previously populated
//Populate page
$('#page-title').html(item.title + "<br />");
$('#page-region').html(item.Region + "<br />");
$('#page-content').html(item.fullInfo + "<br />");
$(this).ready(function(e) {
$('#page-content').on('click','a', function(e){
e.preventDefault();
console.log(this)
currentPage = $(this).attr('href');
window.open(currentPage, '_system', 'location=yes')
});
});
// return false;
return false
}
});
};
Basically, the function needed to come after the content was loaded. My original method of implementation was not differentiating between the content before or after it was populated. Thanks again everyone!
you need to preventDefault action.
I have tried with sample data.
Demo: http://jsfiddle.net/a6NJk/642/
Jquery:
$('#page-content').on('click','a', function(e){
e.preventDefault();
console.log(this);
currentPage = $(this).attr('href');
window.open(currentPage, '_blank', 'location=yes')
});
//this function for generating dynamic html
$("#bb").click(function(){
$("#page-content").append("Web: www.ThisIsTheUrlINeed.com ");
})
The function you wrote/found to try and grab the href must be run after the page is populated with external content.
e.g
$.ajax({
url: 'http://external/foobar.html',
success: function( data, status, xhr ) {
// stuff data in #page-content and so on
// ...and when the anchor is in DOM;
$('#page-content').find('a').click(function(){
dooTheDoo($this.attr('href'));
});
}
})
Related
In my project, I have a JSON file. I display the data that is parsed inside a list (ul) under a div with the class, "inner", and show only the name and cost of each product that you can see in my JSON.
{
"product": [
{
"name": "samsung galaxy",
"image": "https://rukminim1.flixcart.com/image/832/832/mobile/v/z/x/samsung-galaxy-on-nxt-sm-g610fzdgins-original-imaenkzvmnyf7sby.jpeg?q=70",
"cost": "RS.10,000",
"detail": "Flaunt your style with the Samsung Galaxy On Nxt. Featuring a drool-worthy body and impressive features, this smartphone is built to perform. Talk to your mom, chat with your friends, browse the Internet - stay connected the way that suits you best - this smartphone is powerful enough to keep up with your busy lifestyle."
}
]
}
When I click on the first product (first list item), I want to show the detail (value detail) of this product in another page from that same JSON object; when I click on the second product, I want that to show in a different page too, but also from that same object.
Here's my HTML:
<html>
<head>
<title>jquery</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
$.ajax({
url: 'http://sonsofthunderstudio.in/jj/product.json',
dataType: 'jsonp',
jsonpCallback: 'jsonCallback',
type: 'get',
crossDomain : true,
cache: false,
success: function(data) {
$(data.product).each(function(index, value) {
console.log(value);
$( ".inner" ).append("<li>"+value.name+"<img src='" + value.image + "' width='50px' height='50px' / >"+value.cost+"</li>");
});
}
});
</script>
<div class="inner">
</div>
</body>
</html>
Where can I go from here?
When you want to show details of your product, You have to create a "ProductList.html" to show your product list, and create a "ProductDetail.html" to show product detail based on selected product.
when user click on a product, You have to pass the selected product to "ProductDetail.html" via url and get it in that page.
the 2 "encodeURIComponenet()" and "decodeURIComponent()" are javascript defined functions to make this action encoded and safe.
To achieve this, You have to append a "Link"(A Tag) to $(".inner"):
$(".inner").append("<a href='#'>"+value.name+"</a>");
in code above, you create a link, you pass the Product ID to destination page and In codes below, You set the "href" attribute for the link:
var _SelectedProduct = "ID=" + ProductID;
var _EncodeID = encodeURIComponenet(_SelectedProduct);
document.getElementById("YourLink").href = "ProductDetail.html?" + _EncodeID;
with these codes, when user click on a product, he will be redirected to "ProductDetail.html" with the selected product ID. You can get this ID in Your ProductDetail.js:
var _DecodeURL = decodeURIComponent(window.location);
var ID = _DecodeURL.split("=");
var _ProductID = ID[1];
with these codes, you split the passed url base on ("="), which means you will get the passed Product ID.(_ProductID).
and :
for(i=0;i<=product.lenght; i++){
if(product[i].ID == _ProductID){ ... }
}
You can add onclick event on li and call a function which will store the particular detail in localStorage.
On the next page you can access detail from localStorage and display it.
//--[Appending in your code]--
.
.
.
$(data.product).each(function(index, value) {
console.log(value);
$( ".inner" ).append("<li onclick='foo('"+value.detail+"')'>"+value.name+"<img src='" + value.image + "' width='50px' height='50px' / >"+value.cost+"</li>");
});
<script type="text/javascript">
function foo(detail)
{
localStorage.setItem("DETAIL",detail);
}
</script>
//--[On second page]--
<head>
<script type="text/javascript">
var detail = localStorage.getItem("DETAIL");
$("#details").html(detail);
</script>
</head>
<body>
<div id="details"></div>
</body>
When you append data first you need to do is to add an Identifier because you need to differentiate the elements and you need to put onClick to each element that you will append you can put it like this: '<li id="'+ index +'" onClick="clicklist(this)">'+ value.name (...) +'</li>'
The second thing you need to declare is a function called clicklist or something with the param element.
function clicklist(element) { }
Fill it with the code I will explain now:
You can access to your list data through the element with your jQuery functions. So first you can get id with var id = $(element).attr('id'); then you can find your list elements and get it value with var itemname = $(element).find("typeofelement.class").attr('value'); etc...
When you get all data in your list you need to open a new window with the params you get in the function. Then use this code:
//Add all the values you need in the other html (id and values) So repeat this line:
sessionStorage.setItem("ID", id);
//Open the window
window.open("yourother.html","_blank");
This is the simple way.
I have this script (I'm new to this, so I'm not very familiar with the terminology). Feel free to edit the question if you can rephrase it in a better way.
<script>
var counter=0;
var oldJSON = null;
setInterval(function() {
var mycounter=0;
$.getJSON('mydata.json', function(data) {
if(JSON.stringify(oldJSON) != JSON.stringify(data)){
$("#notifications").html("");
$("#notifications").append("<option style=display:none></option>")
$.each(data.items, function(i, v) {
counter= counter + 1;
document.getElementById('test').innerHTML=counter ;
$('#notifications').append('<option value="' + v.type + '">' + v.type +"->"+ v.text +"->"+v.pnr+ '</option>');
;});
}
oldJSON = data;
});
},2000);
</script>
It takes the data from a JSON file and appends it to #notifications which is a dropdown element.
What I'm trying to create is a Facebook type notification dropdown.
This is my html:
<div class="hello">
<select id="notifications" style="background-image:url(live_data.jpg);" ></select>
</div>
<div id="test" style="color:red;margin-left:90px;font-size: 15px;font-family: arial;"></div>
Now, as you may have seen, I appended a blank item to the dropdown so that the old data gets cleared out.
Now here lies the problem: when I clear this data, the first element comes onto the image(overlaps). I added a empty item for it(not a very good way, I know... here also suggestions are welcome). But the thing is when I select any of them it overlaps onto the image.
Any help or advice would do... thanks in advance.
I'm open to suggestions if there is any other way to do it
Once again I humbly come before you with bruises upon my head from beating my head against a wall...
I have been trying to learn as I go in figuring out how to populate a jQuery EasyUI accordion from a php/MySQL query. I believe that I am now getting the data back to the webpage correctly, but I am unable to figure out how to parse and format this to be displayed as the content on the page. What I am attempting to achieve is basically an accordion to display the contact history with each correspondence with an individual as an accordion item. Here is a sample of the output from the PHP query.
{"rows":[{"phone":"5554072634","contact_dt":"2014-01-27 22:51:37","method":"Email","who":"Scott","note":""},{"phone":"5554072634","contact_dt":"2014-01-27 23:08:49","method":"Spoke","who":"Scott","note":"Called back and she is not interested."}]}
I am trying to get the "contact_dt" as the title of each accordion tab and then format the rest of the elements in the body of the accordion tabs. Currently I'm getting a busy spinner when I select the Contact History tab that contains the accordion but this only yields a tiny square box in the body and does not alter the title. Here is the code that I'm sure I have mangled. First for the HTML portion...
<div id="history" title="Prospect Contact History" closable="true" style="padding:10px;">
<h2 class="atitle">Prospect Details</h2>
<div id="aa" class="easyui-accordion" style="width:500px;height:300px;">
<div title="Title1" data-options="iconCls:'icon-save'" style="overflow:auto;padding:10px;">
<h3 id="hist_title" style="color:#0099FF;">Accordion for jQuery</h3>
<p>Accordion is a part of easyui framework for jQuery.
It lets you define your accordion component on web page more easily.</p>
</div>
</div>
</div>
Now for the jQuery pieces... First is the JS to basically call the function. This is in the body at the end of the page.
<script type="text/javascript">
$('#tt').tabs({
onSelect:function(title){
if (title == 'Prospect Contact History'){
//$( "#hist_title" ).html( "Accordion function is working.");
accordionHistory();
}
}
});
</script>
Now for the function that is defined in the head and where I think the real mess is at.
function accordionHistory() {
$( "#hist_title" ).html( "Accordion function is working.");
var pp = $('#aa').accordion('getSelected'); // get the selected panel
if (pp){
pp.panel('refresh','contact_history.php?phone=' + phone); // call 'refresh' method to load new content
var temp = $('#aa').form('load',pp);
$.each( temp, function( i, val ) {
var txt1=$("<p>Time: ").html(val.contact_dt);
var txt2=$("</p><p>Method: ").html(val.method);
var txt3=$("</p><p>Who: ").html(val.who);
var txt4=$("</p><p>Note: ").html(val.note);
//$("#hist_title").html(val.contact_dt);
$("#hist_item").html(txt2,txt3,txt4);
});
}
}
I'm sure I'm displaying gross ignorance here in basic JS concepts. As I mentioned at the beginning I'm really using this as a learning exercise as well as building something useful. Any help would be greatly appreciated. Additionally, any online tutorials that might help walk me thru some of my conceptual shortcomings would be most welcome. Thanks in advance.
Well... I finally have figured out my issues. Here is the function that I'm now using to get this working.
function accordionHistory() {
var pp = $('#aa').accordion('getSelected'); // get the selected panel
if (pp){
$.ajax({
post: "GET",
url: "get_history.php?phone=" + phone,
dataType: 'json',
success: function( details ) {
$.each(details.rows, function(index, element) {
$('#hist_title').replaceWith(
'Phone: '
+ element.phone
+ 'Contact time: '
+ this.contact_dt
+ '<br/>Method: '
+ this.method
+ '<br/>Who: '
+ this.who
+ '<br/>Note: '
+ this.note
);
});
}
});
}
}
I hope some other noob like myself finds this useful.
We have approval with our client, just a heads up to cover me in any way.
We are needing to modify some of the code in a clients site if a cookie is seen on their computer, the client's site is in ASPX format. I have the first part of the code created, but where I am getting stuck is this:
I need to remove the last 2000 characters (or so) of the body of the page, then append the new HTML to it.
I tried:
$('body').html().substring(0, 10050)
but that doesn't work, I also tried copying that HTML (which did work) and put it back with the new code, but it created a loop of the script running.
Any suggestions on what I should do? It has to be javascript/jQuery sadly.
//////// EDIT ////////////
My script is brought in by Google Tag Manager, and added to the page at the bottom, then my script runs, this is what was causing the loop in the script. Basically, here is the setup:
My Script on my server is loaded into the client site using Google Tag Manager, added to the bottom of the page. From there it is able to execute, but when doing this, it creates a loop of adding the Google Tag Manager script, causing my code to re-add, causing it to re-execute again.
The client is not willing to do anything, he has pretty much told us to just figure it out, and to not involve his web guy.
This is the code straight from their site I am trying to edit.
<script language="JavaScript">
jQuery(function($){
$('#txtPhone').mask('(999) 999-9999? x99999');
$('#submit').click(function(){CheckForm();});
});
function CheckForm(theForm){
if (!validRequired($('#txtfirst_name'),'First Name')){ return false; }
if (!validRequired($('#txtlast_name'),'Last Name')){ return false; }
if (!validRequired($('#txtEmail'),'E-Mail Address')){ return false; }
if (!validEmail($('#txtEmail'),'E-Mail Address',true)){ return false; }
if (!validPhone($('#txtPhone'),'Phone Number')){ return false; }
var dataList='fa=create_lead';
dataList += '&name=' + $('#txtfirst_name').val();
dataList += '&lastname=' +$('#txtlast_name').val();
dataList += '&email=' + $('#txtEmail').val();
dataList += '&phone=' + $('#txtPhone').val();
dataList += '&vid=' + dealerOnPoiVisitId;
dataList += '&cid=' + dealerOnPoiClientId;
dataList += '&leadType=9';
dataList += '&leadSrc=32'; ////////////////////// THIS IS WHAT I AM ATTEMPTING TO CHANGE /////////////////////////
dataList += '&contactname=' + $('#contactname').val();
dataList += '&comment=' + encodeURIComponent($('#txtComments').val());
dataList += '&dvc=' +encodeURIComponent(DealerOn_Base64.encode($('#txtfirst_name').val() + $('#txtEmail').val()));
var lid=1;
$('#submit').prop('disabled', true);
$.ajax({
url:'/lead.aspx',
data: dataList,
dataType: 'json',
success: function(data){
$('#submit').prop('disabled', false);
lid=data.leadid;
if (lid > 1){
$('#submit').prop('disabled', false);
var jqxhr = $.post('/lead.aspx?fa=complete_lead&leadid=' + lid , function() {
window.location.href='/thankyou.aspx?name=' + $('#txtfirst_name').val() + '&lid=' + data.leadid;
});
}
},
error: function(request,error) {
$('#submit').prop('disabled', false);
}
});
}
</script>
This is the page on the site: www.moremazda.com/contactus.aspx
You have to add the HTML back:
var html = $('body').html().substring(0, 10050);
$('body').html(html);
Note that doing this, and just randomly removing chunks of HTML is not good practice, and could lead to a number of problems.
Technically you should be able to do this:
var bodyHTML = $('body');
bodyHTML.html(bodyHTML.html().substring(2000));
But as I pointed out in my comment above, that is a REALLY BAD idea.
If you have access to the HTML to the page, wrap the code you want to replace in a identifiable tag and remove that. I.e.:
<div id="tobeRemoved">Lorem Ipsum</div>
<script>
$('#toBeRemoved').empty();
</script>
If you can't edit the HTML, but you know that it is always the last script tag, you could do something like this:
var scripts = $('script');
scripts.get(-1).remove;
I think I may be missing something or haven't grasped a fundamental of jQuery. I have searched for hours but yet to find an answer to my question.
I've got an old website that I'm upgrading to use jQuery and many of the links call a JavaScript onClick call that passes multiple parameters, as per the example below:
View Details
The problem is that I've updated the old displayData function with various jQuery code and the displayData function is within the
$(document).ready(function() {
});
code, and this seems to prevent the function displayData being called using the onClick as it says object expected. I've moved the displayData function out from the $(document).ready() but by doing so, this has prevented references to other functions within the $(document).ready() code being referenced.
A cut down example of what I have is below:
<script>
$(document).ready(function() {
function displayData(title, isbn, dt, price) {
// there's a call to jQuery AJAX here
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebServices/BookService.asmx/GetBookReviews",
data: "{isbn: '" + isbn + "'}",
dataType: "json",
success: function(msg) {
DisplayReviews(msg.d);
}
});
return false;
}
function DisplayReviews(data) {
// data normally formatted here and passed to formattedData variable
var formattedData = FormatData(data);
$('#reviewScreen').html(formattedData);
}
function FormatData(data) {
// function reformats data... code removed for space..
return data;
}
});
</script>
<table>
<tr><td>View Reviews</td><td>Book Title</td></tr>
<tr><td>View Reviews</td><td>Book Title 2</td></tr>
</table>
What I'd like to do is to be able to remove the onclick="displayData();" within the link and instead us a jQuery click reference, something like
$('a.reviewLink').click(function() {
displayData(parameters go here....);
});
I just don't know how I'd pass the parameters to the function from the link as they would not longer be in the HTML onclick attribute.
If I continue to use the onclick attribute in the link, and move the displayData(params) out of the $(document).ready() code block, it works fine, but the moment I try and reference any of the other functions within the $(document).ready() code block I get the dreaded object expected error with the other functions such as DisplayReviews(param).
I don't know if this makes any sense.... sorry if it's confusing, I'm not the worlds best programmer and don't know all the terminology necessarily, so have tried as best I can to explain. I hope you can help.
Many thanks
The init code should go into the .ready(), not your library functions, those can be defined in a seperate .js file.
<script src="yourFunctions.js"></script>
<script>
$(document).ready(function(){
$('a.reviewLink').click(function() {
displayData(parameters go here....); // in yourFunctions.js
});
});
</script>
An alternative to passing inline parameters without using inline javascript, is to use HTML5's 'data-' attribute on tags. You can use it in xhtml, html etc as well and it just works.
html:
<div data-name="Jack" data-lastname="black">My name is</div>
jquery:
$('div').click(function(){
alert($(this).attr('data-name') + ' ' + $(this).attr('data-lastname'));
});
Note: You HAVE to use either jQuery's .attr() or native .getAttribute() method to retreive 'data-' values.
I use 'data-' myself all the time.
As pointed out by Skilldrick, displayData doesn't need to be defined inside your document ready wrapper (and probably shouldn't be).
You are correct in wanting to use the jQuery click event assignment rather than onClick - it makes your code easier to read, and is required by the principle of Unobtrusive Javascript.
As for those parameters that you want to pass, there are a few ways to go about the task. If you are not concerned with XHTML compliance, you could simply put some custom attributes on your link and then access them from your script. For example:
View Details
And then in your click event:
$('a.reviewLink').click(function() {
var booktitle = $(this).attr('booktitle');
var isbn = $(this).attr('isbn');
var pubdate = $(this).attr('pubdate');
var price = $(this).attr('price');
displayData(booktitle, isbn, pubdate, price);
});
I'm sure someone on here will decry that method as the darkest evil, but it has worked well for me in the past. Alternatively, you could follow each link with a hidden set of data, like so:
View Details
<ul class="book-data">
<li class="book-title">Book Title</li>
<li class="book-isbn">ISBN</li>
<li class="book-pubdate">Publish Date</li>
<li class="book-price">Price</li>
</ul>
Create a CSS rule to hide the data list: .book-data { display: none; }, and then in your click event:
$('a.reviewLink').click(function() {
var $bookData = $(this).next('.book-data');
var booktitle = $bookData.children('.book-title').text();
var isbn = $bookData.children('.book-isbn').text();
var pubdate = $bookData.children('.book-pubdate').text();
var price = $bookData.children('.book-price').text();
displayData(booktitle, isbn, pubdate, price);
});
There are lots of ways to accomplish your task, but those are the two that spring most quickly to mind.
I worked this up, so even though the question is answered, someone else might find it helpful.
http://jsbin.com/axidu3
HTML
<table border="0" cellspacing="5" cellpadding="5">
<tr>
<td>
View Reviews
<div class="displayData">
<span class="title">Book Title 2</span>
<span class="isbn">516AHGN1515</span>
<span class="pubdata">1999-05-08</span>
<span class="price">$25.00</span>
</div>
</td>
<td>Book Title 2</td>
</tr>
</table>
JavaScript
<script type="text/javascript" charset="utf-8">
jQuery(".reviewLink").click(function() {
var title = jQuery(".title", this.parent).text();
var isbn = jQuery(".isbn", this.parent).text();
var pubdata = jQuery(".pubdata", this.parent).text();
var price = jQuery(".price", this.parent).text();
displayData(title, isbn, pubdata, price);
});
function displayData(title, isbn, pubdata, price) {
alert(title +" "+ isbn +" "+ pubdata +" "+ price);
}
</script>
CSS
<style type="text/css" media="screen">
.displayData {
display: none;
}
</style>