jQuery Single Page app dynamic divs - javascript

I have a jQuery Single Page app that works but not the way I want it to.
I have a list of counties that is read from a JSON file (the list can be filtered). When one is chosen, it appears as a hyperlink that links to another "page" with a town from that county (the "page" is actually just a div in the same page). The trouble is I have to manually create the divs beforehand. E.g if there are five items in the JSON file and I want to add one more, I have to manually add an extra div in the page.
It works OK for the counties, I can add extra counties to the JSON and it builds an extra hyperlink but for the "page" it links to I need to create a new div in the html. When I create the divs dynamically (under the inner "each" in the Javascript code) nothing happens when you click on the link as the div does not exist in the html.
Is there a solution to this? (see code below)
HTML (with js):
<!doctype html>
<html>
<head>
<script src="js/jquery-1.11.2.min.js"></script>
<script src="jquery.mobile-1.4.5/jquery.mobile-1.4.5.js"></script>
<link rel="stylesheet" href="jquery.mobile-1.4.5/jquery.mobile-1.4.5.css"></script>
<title>How to Parse a JSON file using jQuery</title>
</head>
<body>
<div data-role="page">
Menu
<div data-role="content">
<div id="results">
<ul id="mynewlist" data-role ="listview" data-autodividers="true" data-filter="true" data-filter-reveal="true">
</ul>
</div>
</div>
<div data-role="panel" class="cd-panel from-left" data-position="left" data-position-fixed="false" data-display="reveal" id="myKoolPanel" data-theme="a">
<ul id ="myul" data-role="listview" data-theme="a" data-divider-theme="a" style="margin-top:-16px;" class="nav-search">
<li>
Towns in Ireland
</li>
<li>
Map of Ireland
</li>
</ul>
</div>
</div>
<script>
$(document).ready(function(){
$.getJSON( "data.json", function( data ) {
var items = [];
var z=0;
$.each( data, function( i, item ) {
z=z+1;
items.push('<li><a href=#textcontainer'+z+'>' + i + '</a></li>');
$.each(item, function(property, value) {
$('#textcontainer'+z).append(value);
});
});
$('#mynewlist').append( items.join('') );
});
});
</script>
<div id ="textcontainer1"> </div>
<div id ="textcontainer2"> </div>
<div id ="textcontainer3"> </div>
<div id ="textcontainer4"> </div>
<div id ="textcontainer5"> </div>
</body>
</html>
JSON file:
{
"Kerry": {
"town": "Kenmare"
},
"Cork": {
"town": "Mallow"
},
"Limerick": {
"town": "Charleville"
},
"Meath": {
"town": "Trim"
},
"Waterford": {
"town": "Lismore"
}
}

Using AngularJs you can solve it.
Define js file as below
var app = angular.module('app', []);
app.controller('ctrl', function ($scope) {
var data;
$scope.data =[{
"name":"Kerry",
"town": "Kenmare"
},
{
"name":"Cork",
"town": "Mallow"
},
{
"name":"Limerick",
"town": "Charleville"
},
{
"name":"Meath",
"town": "Trim"
},
{
"name":"Waterford",
"town": "Lismore"
}] ;
});
HTML file code :
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"> </script>
<script language="javascript" type="text/javascript" src="fileName.js"> </script>
</head>
<body>
<div ng-controller="ctrl">
<div ng-repeat="d in data">
{{d.name}} : {{d.town}}
</div>
</div>
</body>
</html>
I hope this will help.

Related

how can i click another page's link which includes functions in current page

There is 2 pages. main.jsp and list.jsp
when I execute goPage() in main.jsp I would like to make event of click list.jsp's nav>ul>li(2).
because list.jsp shows information by click of javascript function
so i need to make click when i enter list.jsp
so anyway would be great if i can show elements in list.jsp
this is main.jsp
<body>
<div class="main_wrap">
<div class="sub1"><div class="main_title1">월별 통계</div></div>
<div class="sub2"><div class="main_title2"><a href="javascript:goPage();" onclick="callChart(50035); callPie(50035); callMap(50035); callTitle('살인');">발생 현황</div></div>
</div>
<script type="text/javascript">
function goPage() {
location.href="list.jsp";
}
</script>
</body>
this is list.jsp
all function is located in each scrript file.
<body>
<div class="wrap">
<div class="title">발생현황</div>
<nav>
<ul>
<li><img src="css/f4f0edb08c97567ce6b0475a63bf7000.png" alt="Italian Trulli" width="50px" height="30px"></img></li>
<li>살인</li>
<li>절도</li>
<li>강간</li>
<li>강도</li>
</ul>
</nav>
<div class="chart_map">
<span class="div_sub1">지도 전국 범죄율</span>
<div class='korea'></div>
</div>
<div class="chart_pie">
<span class="div_sub1">검거자</span>
<div class="pie_arrests"></div>
</div>
<script src="js/pie_period.js?v=<%=System.currentTimeMillis() %>"></script>
<script src="js/pie_arrests.js?v=<%=System.currentTimeMillis() %>"></script>
<script src="js/korea_map.js?v=<%=System.currentTimeMillis() %>"></script>
</div>
</body>
Instead of trying to make a click when going to list.jsp, maybe try running the same code when loading list.jsp instead, so add something like this to the file:
<!-- list.jsp -->
<script type="text/javascript">
window.addEventListener("load", function(event) {
callChart(50035);
callPie(50035);
callMap(50035);
callTitle('살인');
});
</script>
You could something like:
Redirect to the list.jsp with a query string
If there is a query string with a certain key - click the button
Code sample
On main page:
function goPage() {
location.href="list.jsp?doclick=1";
}
On list page:
document.addEventListener('DOMContentLoader', function () {
const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('doclick');
if(myParam == 1) {
callChart(50033);
callPie(50033);
callMap(50033);
callTitle('강간');
}
});

Passing variable to function on another page

I am working on a website and am planning on having it so that certain links will have a value set, this will change what container is displayed when the page loads. How would I have it so the link passes a value that would be used for the onload functions?
Here is a mockup of my HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Lunch</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="script.js"></script>
</head>
<body onload="navBar(); dateChange(); tabulate(0);">
<nav>
<ul>
<li>Appitizers</li>
<li>Breakfast</li>
<li>Lunch</li>
<li>Dinner</li>
<li>Dessert</li>
<li>Ten-Course Dinner</li>
<li>Send in your Recipes!</li>
</ul>
</nav>
<div class="main">
<div class="box">
<ul>
<li><a onclick="tabulate(this.id);" id="1">Chicken Clubhouse Sandwiches</a></li>
<li><a onclick="tabulate(this.id);" id="2">Smokey Tomato Soup</a></li>
</ul>
</div>
<div id="0" class="recipe" style="display: block;">
<div class="tabs">
<a class="tab"> </a>
</div>
<div class="page">
<p>The recipes you'll find here are ones you can use to impress guests at your next get together</p>
</div>
</div> <!--recipe card end-->
<div class="recipe" id="1">
<h1>Chicken Clubhouse Sandwiches</h1>
</div> <!--recipe card end-->
<div class="recipe" id="2">
<h1>Smokey Tomato Soup</h1>
</div> <!--recipe card end-->
</div>
</body>
</html>
And here is my tabulate function:
function tabulate(tabNum){
$('.recipe').each(function() {
if(tabNum==this.id){
this.style.display="block";
}
else{
this.style.display="none";
}
});
}
You would need to make use of the URL's GET parameters:
lunch.html?item=2
In conjunction with passing the variable into the JavaScript function:
// Set up an object for GET parameter
var $_GET = {};
// Find and extract the various GET parameters
if(document.location.toString().indexOf('?') !== -1) {
var query = document.location.toString().replace(/^.*?\?/, '').replace(/#.*$/, '').split('&');
for(var i=0, l=query.length; i<l; i++) {
var aux = decodeURIComponent(query[i]).split('=');
$_GET[aux[0]] = aux[1];
}
}
// Target a specific get parameter, given the GET parameter name
var tabNum = $_GET['item']; // Comes through as '2' in this example
// Pass the parameter into the function
function tabulate(tabNum){
$('.recipe').each(function() {
if(tabNum==this.id){
this.style.display="block";
}
else{
this.style.display="none";
}
});
}
See this post and this post for further reference.
Hope this helps! :)
I haven't tested this, but you should be able to get by with passing a GET variable via PHP into tabulate(), in a way like this:
function tabulate(tabNum){
$('.recipe').each(function() {
if(tabNum==this.id){
this.style.display="block";
}
else{
this.style.display="none";
}
});
}
window.addEventListener('DOMContentLoaded', function(evt) {
var id = <?php echo htmlspecialchars($_GET['id'], ENT_COMPAT, 'utf8'); ?>;
tabulate(id);
});

JavaScript: Trying to use a variable from a page loaded inside a DIV in another DIV

I'm trying to use a variable from a page loaded inside a DIV in another DIV.
The text in the "bar" DIV on the "index.html" page should be replaced by the item id selected from the "page.html" loaded as an <object></object> inside the "content" DIV.
Or the item id should at least be stored in a global variable - which hasn't been working either - because when I run a function from the "index.html" page to retrieve it, it displays as "undefined".
All the code is below:
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index_style.css">
<title>Access element of other DIV</title>
</head>
<body>
<div id="bar">This text should be replaced by the Item ID selected below</div>
<div id="content">
<object type="text/html" data="page.html" width="100%" height="100%"></object>
</div>
</body>
</html>
index_style.css
body{
margin: 0px;font-family:arial;font-size:30px;text-align:center;color:#fff;
}
#bar{
position:relative;height:100px;line-height:100px;background-color:#555c60;color:#74de90;
}
#content{
position:absolute;top:100px;bottom:0px;right:0;left:0;overflow-y:hidden;
}
page.html
<link rel="stylesheet" href="page_style.css">
<script type="text/javascript" src="main.js"></script>
<center>
This is <b>page.html</b> which has been loaded <u>inside</u> the "content" DIV<br><br>
</center>
<div class="items" onclick="use_item_id(this);" id="item1">Item 1</div>
<div class="items" onclick="use_item_id(this);" id="item2">Item 2</div>
<div class="items" onclick="use_item_id(this);" id="item3">Item 3</div>
page_style.css
body{font-family:arial;font-size:30px;color:#fff;background-color:#1b1e4b;text-align:center;}
.items{cursor:pointer;}
.items:hover{color:#ff0000;}
main.js
function use_item_id(selected)
{
current_item = selected.getAttribute("id");
document.getElementById('bar').innerHTML = current_item;
alert(current_item);
}
The line document.getElementById('bar').innerHTML = current_item; in "main.js" seems to be the problem and I can't get it to work. The alert(current_item); works fine when the line above it isn't there so it's definitely getting the item id's correctly from "page.html". It's just not setting them as the innerHTML on the "index.html" page, or even storing them in a global variable to be retrieved from a function run on the "index.html" page (as mentioned above). Any code examples would be greatly appreciated.
I think it might be because the use_item_id() function is being executed from another page, so I might need some alternatives or other functions to get it to work.
It'd be great if anyone knows what the issue is. I appreciate all replies. Thanks in advance :)
You are not on the same document ... then in main.js
replace
document.getElementById('bar').innerHTML = current_item;
with
parent.document.getElementById('bar').innerHTML = current_item;
this solves your problem.
If you're trying to access variables from HTML documents it's highly recommended to use the data attribute. This is an example for a comment section:
In my item I set the data key for loading
<div class='resp-col col-12 comment-user-data'>
<div class='resp-col col-9'>
<div class="post-profile-image" style='background-image:url("<?=$user->profile_image?>")'></div>
<?=Html::a("<p class='post-user'>".$username."</p>", Url::to(['/account/'.$user->id.'/'.$user->username]))?>
</div>
<div class='resp-col col-3'><button class='reply-to' data-assoc-id='<?=$model->id?>' data-assoc-name='<?=$username?>'><i class="material-icons">reply</i></button></div> <-- set the data-assoc-id
</div>
<div class='resp-col col-12 comment-content-data'>
<?=$model->content?>
</div>
jQuery to load data key
$('.reply-to').on('click',function(){
$('#submit-comment').data('assoc-id', $(this).data('assoc-id'));
$('#comment-content').val('#'+$(this).data('assoc-name')+' ');
$('.base-modal').animate({
scrollTop: $("#comment-content").offset().top
}, 2000);
if($('#comment-content').css('display') == 'none'){
toggleCommentVisibility();
}
});

Combining results from WP-API using AngularJS

I currently have this site - http://dev.5874.co.uk/scd-data/ where I have a dropdown which displays results from WP-API which I am pulling in through AngularJS.
It currently combines the two sets of results as they're separate URL's, the results are in categories within a custom post type so if both posts are 'tagged' in the same category chosen they display twice. I need a way to combine the two sets of results but only showing one of the posts - I hope this makes sense. I'm very new to API data and AngularJS and I imagine there is a much simpler way of doing this. Any help would be much appreciated. Here is a snippet of my code to show how it's currently working.
Thanks in advance!
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<style>
.desc {display: none;}
</style>
<script type="text/javascript">
$(function(){
$('.selectOption').change(function(){
var selected = $(this).find(':selected').text();
//alert(selected);
$(".desc").hide();
$('#' + selected).show();
}).change()
});
</script>
<script>
var app = angular.module('myApp', []);
app.controller('northWestCtrl', function($scope, $http) {
var url = 'http://scd.blaze.wpengine.com/wp-json/posts?type=listings&filter[listing_area]=northwest';
$http.get(url).then(function(data) {
$scope.data = data.data;
});
});
</script>
<select class="selectOption">
<option>Search by Region</option>
<option>NorthWest</option>
<option>NorthEast</option>
<option>Midlands</option>
<option>EastAnglia</option>
<option>SouthEast</option>
<option>SouthWest</option>
<option>Scotland</option>
<option>Wales</option>
<option>NorthernIreland</option>
<option>ChannelIslands</option>
</select>
<div id="changingArea">
<body ng-app="myApp">
<div id="NorthWest" class="desc">
<div ng-controller="northWestCtrl">
<div ng-repeat="d in data">
<h2 class="entry-title title-post">{{d.title}}</h2>
<img src="{{d.acf.logo}}">
<div id="listing-contact">Contact: {{d.acf.contact}}, {{d.acf.position}}</div>
<div id="listing-address-1">
{{d.acf.address_1}}, {{d.acf.address_2}} {{d.acf.address_3}} {{d.acf.town}} {{d.acf.county}} {{d.acf.postcode}}
</div>
<div id="listing-phone">Telephone: {{d.acf.telephone}}</div>
<div id="listing-mobile">Mobile: {{d.acf.mobile}}</div>
<div id="listing-email">Email: {{d.acf.email}}</div>
<div id="listing-website">Website: {{d.acf.website}}</div>
<div id="listing-established">Established: {{d.acf.established}}</div>
<div id="listing-about">About: {{d.acf.about}}</div>
<div id="listing-mailingaddress">Mailing Address: {{d.acf.mailing_address_}}, {{d.acf.mailing_address_2}}, {{d.acf.mailing_address_3}}, {{d.acf.mailing_town}}, {{d.acf.mailing_county}}, {{d.acf.mailing_postcode}}</div>
<div id="listing-directions">Directions: {{d.acf.directions}}</div>
<div id="scd-link">View on The Shooting Club Directory</div>
</div>
</div>
</div>
</body>
</div>
Here is a working code pen - http://codepen.io/anon/pen/yePYdq
Angular is a great JavaScript front-end framework to choose, and you're off to a good start, but a lot of changes could be made. I've made some suggested changes for easier ways to do things below.
See this CodePen for all changes.
It looks like you've grasped the idea of ng-repeat, but there's definitely a lot of repeated HTML and JS in your view and controller, so let's see if we can do better.
Let's try this without jQuery to avoid direct manipulation of the DOM. And instead of many controllers, we can do this with a single controller.
<div ng-app="MyApp">
<div ng-controller="MyController">
...
</div>
</div>
<script type="text/javascript">
var app = angular.module('MyApp', []);
app.controller('MyController', ...);
</script>
For the dropdown, we'll use ng-repeat in our view and display the names of the shooting types from our model
...
<select ng-model="selectedListing">
<option
ng-repeat="listingShootingType in listingShootingTypes"
value="{{listingShootingType.name}}">
{{listingShootingType.name}}
</option>
</select>
...
<script type="text/javascript">
...
// Our selections/filters
$scope.listingShootingTypes = [
'All',
'Air Rifle/Air Pistol',
'Clay',
'ABT',
'Double Trap',
'English Skeet',
'English Sporting',
'Fitasc',
'Olympic Skeet',
'Olympic Trap',
'Simulated Game',
'Sport Trap/Compact',
'Universal Trench',
'ZZ/Helice',
'Rifle',
'Centrefire Target Rifle',
'Gallery Rifle',
'Muzzle Loading',
'Practice Shotgun',
'Smallbore Rifle'
];
...
</script>
With only one controller, we can still use ng-repeat for each listing.
<div ng-repeat="d in data">
<h2 class="entry-title title-post">{{d.title}}</h2>
<div id="listing-image"><img src="{{d.acf.logo}}"></div>
<div id="listing-contact">Contact: {{d.acf.contact}}, {{d.acf.position}}</div>
<div id="listing-address-1">
{{d.acf.address_1}}, {{d.acf.address_2}} {{d.acf.address_3}} {{d.acf.town}} {{d.acf.county}} {{d.acf.postcode}}
</div>
<div id="listing-phone">Telephone: {{d.acf.telephone}}</div>
<div id="listing-mobile">Mobile: {{d.acf.mobile}}</div>
<div id="listing-email">Email: {{d.acf.email}}</div>
<div id="listing-website">Website: {{d.acf.website}}</div>
<div id="listing-established">Established: {{d.acf.established}}</div>
<div id="listing-about">About: {{d.acf.about}}</div>
<div id="listing-mailingaddress">Mailing Address: {{d.acf.mailing_address_}}, {{d.acf.mailing_address_2}}, {{d.acf.mailing_address_3}}, {{d.acf.mailing_town}}, {{d.acf.mailing_county}}, {{d.acf.mailing_postcode}}</div>
<div id="listing-directions">Directions: {{d.acf.directions}}</div>
<div id="scd-link">View on The Shooting Club Directory</div>
</div>
Finally... How do we only display listings that match our selected shooting type from the dropdown? We could use a custom Angular filter!
...
<div ng-repeat="d in data | filter:isSelectedListing">
...
<script type="text/javascript">
...
// Let's define a custom Angular filter because the WordPress JSON is complex
$scope.isSelectedListing = function(listing) {
// Show nothing if nothing is selected
if (angular.isUndefined($scope.selectedListing) || $scope.selectedListing == '') {
return false;
}
// Show all if 'All' is selected
if ($scope.selectedListing == 'All') {
return true;
}
// If the shooting type we're looking for is present, show the listing.
// To do this, we parse the WordPress JSON object model.
if (angular.isDefined(listing.terms.listing_shooting_type)) {
for (var i = 0; i < listing.terms.listing_shooting_type.length; i++) {
if (listing.terms.listing_shooting_type[i].name == $scope.selectedListing) {
return true;
}
}
}
return false;
};
...
</script>
Hopefully this gives you an idea of how we better leverage ng-repeat + DRY :)
The entire CodePen is here.

dynamically setting variables in html5 body?

Hi i am trying to dynamically set some of the contents of an html5 body with var strings defined in a JS.
below is what i have written so far and it doesnt seem to display the value specified.
<link href="src/jquery.mobile-1.0.min.css" rel="stylesheet" type="text/css"/>
<script src="src/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="src/jquery.mobile-1.0.min.js" type="text/javascript"></script>
<body>
<script>
var name = "John Smith";
</script>
<div data-role="page" id="page">
<div data-role="header">
<button></button>
<h1>New Claim</h1>
</div>
<div data-role="content">
<ul data-role="listview">
<li> <p><h3>Your Name: <var>name</var></h3></p></li>
</ul>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
</body>
i am trying to insert John Smith inside the "Your Name: text.
Thanks
You will have to use JavaScript to "print" the contents of a variable, to the HTML-source. Here's an example:
<div id="test"></div>
document.getElementById('test').innerHTML = 'This goes into the element!';
But since you're using jQuery, you could do this as well:
$('#test').text('This goes into the element!');
You should either give the VAR-Tag itself or it's wrapping LI-Tag an unique ID.
In HTML
<li>
<p>
<h3>Your Name: <var id="name">name</var></h3>
</p>
</li>
JavaScript
var name = "John Smith";
$("#name").text(name);
And by the way:
You shouldn't nest a Heading inside of a Paragraph, this doesn't make any sense.
Paragraphs are INLINE while Headings are BLOCKELEMENTS.
Check out this FIDDLE
You probably want something like below. Have global JS variables assigned, reference them with a VAR html5 tag, use JS at the end of body (or after DOM load) to substitute the keys in the VAR tags with the values held in the global VARS object.
<script>
VARS = {};
VARS.name = "John Smith";
VARS.age = 45;
</script>
...
Name : <var>name</var><br/>
Age : <var>age</var>
...
<script>
// run once at end of body
var all = document.getElementsByTagName("var");
for(var i=0; i<all.length; i++) {
var elm = all[i];
var key = elm.innerHTML;
if(VARS[key] != null)
elm.innerHTML = VARS[key];
else
elm.innerHTML = "";
}
</script>
The tag isn't supposed to be used this way
Try this:
<link href="src/jquery.mobile-1.0.min.css" rel="stylesheet" type="text/css"/>
<script src="src/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="src/jquery.mobile-1.0.min.js" type="text/javascript"></script>
<body>
<script>
var name = "John Smith";
$(document).ready(function() {
$("#name").text(name);
});
</script>
<div data-role="page" id="page">
<div data-role="header">
<button></button>
<h1>New Claim</h1>
</div>
<div data-role="content">
<ul data-role="listview">
<li> <p><h3>Your Name: <span id="name"></span></h3></p></li>
</ul>
</div>
<div data-role="footer">
<h4>Page Footer</h4>
</div>
</div>
</body>
Edit: just to clarify one thing. The tag isn't supposed to be used to hold the place to the value of a variable. It's correct semantic meaning is more to represent a mathematical variable or a programming variable when you are showing some code on your page. If I'm wrong here, please someone correct me.
try this
$(document).ready(function() {
$("h3").text("Your name : John Smith");
});
Add some classes on your divs, to easuly select the good tags

Categories