Using JQuery to pass JSON data into DIVs - javascript

Hi I have the following recommendation from an expert and I am trying to rebuild my Code based on these recommendations:
from $.each() you can return true or false. If you return false, the
loop stops.
Try not to build HTML from concatenated strings. This is prone to XSS
vulnerabilities that are easy to avoid. jQuery gives you the tools to
build HTML safely.
Generally, for the same reason, try to avoid working with .html(),
especially if you already have DOM elements to work with.
Don't use inline event handlers like onclick. At all. Ever.
This is the new Code I am working on:
var page = 1;
$(document).on('click', '#devotionclick', function blogs() {
$('#postlist').empty();
// $('#category').prepend('<div class="categories_listing"><span data-type="blogs" data-category="5">Blog Category</span></div>');
var count = "5";
var result = $.getJSON('http://howtodeployit.com/api/get_posts/?count=' + count + '&page=' + page, function (data, status) {
if (data !== undefined && data.posts !== undefined) {
$.each(data.posts, function (i, item) {
var str = item.title;
$('#postlist').append('<div class="article"' + item.id + '"><div>' + item.title + '</div><div>' + item.excerpt + '</div></div>');
if (data !== undefined) {
$('#stats').text('Page ' + data.query.page + ' of ' + data.pages + ' | Total posts ' + data.count_total + '');
}
if (data.query.page < data.pages) {
$("#loadmore").show();
} else {
$("#loadmore").hide();
}
});
page++;
}
});
$('#postlist').append('<div id="loadmore"><div id="stats"></div><div id="loadmore">load more</div></div>');
$('#loadmore').click(blogs);
});
HTML:
!-- Page: home -->
<div id="home" data-role="page">
<div class="ui_home_bg" data-role="content"></div>
<div data-role="listview">
Daily Devotional Messages
</div><!-- links -->
</div><!-- page -->
<!-- Page: Daily Devotional Messages -->
<div id="devotion" data-role="page">
<div data-role="header" data-position="fixed">
<h2>Daily Devotional Messages</h2>
</div><!-- header -->
<div data-role="content" id="postlist"> </div><!-- content -->
</div><!-- page -->
The issues I am having right now is:
When I click on the Button it Loads the first 5 Posts but when I click on the 'load more' Text, it Loads the next 5 rather than Appending to existing Lists.
The Lists isn't displayed as a Listview item which should be clickable

Problem 1
It is because of $('#postlist').empty(); in the click handler.... you are removing all items from the page before loading new items. Remove this

Related

JQuery Accordion active on document load instead of on click despite having active false

I am using the JQuery accordion that contains nested accordions that worked fine when I had them purely in HTML. But in my case, I have to load the nested accordions in JQuery and that prevents the accordion from only being activated when clicked. The accordion is already open when the page loads. I also tried putting the accordion last in the JS and it still did not work. Code snippet:
HTML/ERB:
<% #year.each do |y| %>
<div class="accordion" id="years">
<h3 class="ui-accordion-header year"><%= y.date %></h3>
</div>
<% end %>
JS:
var months = [];
var loadURL = "stats/show";
$("div.accordion").accordion({
collapsible: true,
active: false,
autoHeight: true,
event: "click"
});
$.getJSON(loadURL, function(data){
//parse data and place in empty arrays
for(var key in data.month){
months.push(data.month[key]);
}
//give each year tab an index number
$('h3.year').each(function(index){
$(this).attr('id', 'ui-accordion-years-header-' + index);
})
for(var i = 0; i < months.length; i++){
//create and append month container to each year tab
$("#ui-accordion-years-header-" + i).after("<div id='months" + i + "' class='months accordion ui-accordion ui-widget ui-helper-reset ui-accordion-content ui-widget-content'></div>");
for (var j = 0; j < months[i].length; j++){
//parse each month of the year and place month tabs in month container
var accordion_month = '<h3 class= "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" role="tab" id="months_tab' + j + '" aria-controls="ui-accordion-1-panel-0" aria-selected="false" tabindex="0"><a href="#" name=' + months[i][j] + '>' + months[i][j] + '</a></h3>';
$("#months" + i).append(accordion_month);
}
}
}
Put accordian inside $.getJSON().
What you have done is added accordian before getting data.
So accordion is empty.
Then, you try to get data...
So accordion does not make it without the data.
So putting accordion inside $.getJSON after all statements makes all available for accordion.
Initialize the accordion after you successfully get the json and append all the elements inside.

Hide data, process to new div with each function

I have multiple same class divs that produce an array and a script that puts them into lists.
I would like to hide a JSON array object from briefly flashing (unprocessed) on the page before the script can process it into lists.
So I put them into a hidden div and the each function stops working.
The .hid divs actually contain:
<%=getCurrentAttribute('item','lists')%> that produce the JSON array.
<div class="hid" style="display:none;">[{"k":"Model","v":"AB"},{"k":"Color","v":"green"}]</div>
<div class="overview"></div>
<div class="hid" style="display:none;">[{"k":"Model","v":"AC"},{"k":"Color","v":"blue"}]</div>
<div class="overview"></div>
<div class="hid" style="display:none;">[{"k":"Model","v":"AD"},{"k":"Color","v":"red"}]</div>
<div class="overview"></div>
My script
jQuery('.hid').each(function () {
var $data = jQuery(this), spec,
specs = jQuery.parseJSON($data.html());
jQuery(".overview").html('<div class="bullet_spec"></div>');
jQuery.each(specs, function () {
jQuery(".overview").children('div').append('<div class="specs"><span class="label">' + this.k + ':</span><span class="value"> ' + this.v + '</span></div>');
});
{
}
});
http://jsfiddle.net/Qta2p/

Getting row data in dynamically created listview

Hi i'm creating list view dynamically. I want to get the data of particular row on click, to proceed to further steps.
my code is as below
function getList(tx, results){
$('#DeliveryList').empty();
var len = results.rows.length;
for(var i=0; i <len; i++)
{
var deliveryItems = results.rows.item(i);
var html = '<li data-role="list-divider">'+deliveryItems.DeliveryName+ ' | ' + deliveryItems.PrimaryName+' <span class="ui-li-count">Copay ='+deliveryItems.Total+'</span> </li><li><a><img src="Pending"/><h3>'+deliveryItems.Name1+'</h3><p>'+deliveryItems.Address+'</p><p>'+deliveryItems.City+' <b></b></p><p><strong>'+deliveryItems.ContactNumber+'</strong></p><a href="#PrescriptionPage" class="cls_btn" id="btn_list" onclick = "Prescription()" >Delivary Details</a></a></li>';
$('#DeliveryList').append(html).trigger('create');
}
$('ul').listview('refresh');
}
My html file looks like
<div data-role="page" id="page3" >
<div data-role="header">
Back
<h1>Heading</h1>
Home
</div><!-- /header -->
<ul data-role="listview" id="DeliveryList" data-inset="true" data-theme="d" data-divider-theme="b"> </ul>
</div>
can any one help me to achieve the result. Thanks in Advance.
It worked for me with below code
$('ul').children('li').on('click', function () {
alert('Selected Name=' + $(this).text());
});
You're using jQuery already, why not use it to create these elements aswell? I asume getList() is bound to an event.
// Create the element
var li = $('<li></li>');
// Add your class
li.addClass('list-divider');
// Change the innerHTML
li.html('Your content');
// Then append it to the list
$('#DeliveryList').append(li);
Simply alter this code to your need. This example just adds one <li> element with a class and some content.
Good luck.

Jquery Mobile Listview Clicked Item - Pass parameter to another page

I've a index.html page. Also this page contains lots of page like #home, #list #contacts etc.
in #list part i dynamically get data from my webpage and generate listview. I want that, when user click any of list item, redirect to #imageDetail page and pass image URL to page and show image
here is the #imageDetail page part
<div data-role="page" id="detailedIMAGE" data-theme="a">
<div data-role="header" data-theme="b" data-position="fixed">
<h1>Image Detail</h1>
</div>
<div data-role="content">
<img id="imageDetayURL" name="imageDetayURL" src="glyphish-icons/158-wrench-2.png"/>
<input type="text" disabled="disabled" id="brewername" name="brewername" />
</div>
</div>
</div>
And below code is my javascript code to get json data dynamically.
<script>
$('#last5').live("click", function() {
$.ajax({
url: "http://mysqlservice.com/getdata.json",
dataType: 'jsonp',
success: function(json_results){
$("#imageListDetay").html('');
console.log(json_results);
$('#imageListDetay').append('<ul data-role="listview" id="tweetul" data-theme="c"></ul>');
listItems = $('#imageListDetay').find('ul');
$.each(json_results.results, function(key) {
html = '<h3>'+json_results.results[key].screen_name+'</h3><span id="detailed_image">'+json_results.results[key].resim_url+'</span><img WIDTH=200 HEIGHT=100 src="http://mywebpage.org/upload/'+json_results.results[key].resim_url+'" /><p class="ui-li-bside"><img WIDTH=8 HEIGHT=13 src="images/07-map-marker.png"/> '+json_results.results[key].adres_data+'</p>';
listItems.append('<li><a name="imageDetayGoster" href="#detailedIMAGE">'+html+'</a></li>');
});
$('#imageListDetay ul').listview();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
//error
}
});
})
$("#detailedIMAGE").live("pagebeforeshow", function (e, data) {
var brewername = $('#detailed_image',data.prevPage).text();
$('#brewername').val(brewername);
$('#imageDetayURL').attr('src', 'http://mobil.harmankaya.org/'+brewername);
alert(brewername);
});
</script>
The problem is after page change alert(brewername) fires. But list all image urls that listed in listview not my selected.
How can i fixed this issue
Thanks in advance.
jQM Docs:
http://jquerymobile.com/test/docs/pages/page-dynamic.html
This is just quoting the docs but if you read the page it should give you an idea on how to accomplish this.
The application uses links with urls that contain a hash that tells
the application what category items to display:
<h2>Select a Category Below:</h2>
<ul data-role="listview" data-inset="true">
<li>Animals</li>
<li>Colors</li>
<li>Vehicles</li>
</ul>
Well, this is my way and works very good.
HTML
<div data-role="page" id="myPage">
<div data-role="content" id="myContent">
<ul data-role="listview" data-inset="true/false/whatever" id="myList"></ul>
</div>
</div>
Javascript
$("#myPage").live("pageshow",function(event){
// get your id from LINK and parse it to a variable
var json_list_callback = getUrlVars()[id];
// verify the URL id
if (json_list_callback === '') {json_list_callback === ''} //or what value you want
// define your path to JSON file generated by the ID declared upper
var json_URL = 'http://your.path.to.json.file.php.json?id=' + json_list_callback;
// get the JSON data defined earlier and append to your LIST
$.getJSON(json_URL,function(data){
var entries = data;
//populate our list with our json data
$.each(entries,function(index,entry){
// i use dummy data here, you can have whatever you want in youre json
$("#myList").append(
'<li>' +
// remember that this "page.html?id=' + entry.json_id + '" will be the link where getUrlVars will get the id declared earlier in function
'<a href="page.html?id=' + entry.json_id + '">' + entry.json_title + '<\/a>' +
'<\/li>'
);
});
//must refresh listview for layout to render
$("#myList").listview("refresh");
});
});
//this function gets from URL the id, category, whatever you declare like this: getUrlVars()['id'] or getUrlVars()['category'] after last symbol of "?"
// you can define your own symbol with this function
function getUrlVars() {
var vars = [],
hash;
var hashes = window.location.href.slice(window.location.href.lastIndexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
This works for me like a charm and i'm using it very often!
live event has been deprecated, use 'on',
exmple: $("#detailedIMAGE").on("pagebeforeshow", function (e, data){ // code });

KnockoutJS: template is not updated on observable array change (only on add, works on remove)

So, I have observable array with sites, which is shown via template. If I'll add site to this array, template is not updated, but if I'll remove site from array – voila! template became updated and all previously added sites became displayed too.
If I'll use nifty hack (commented in code) with replacement of whole array to new one then everything works.
BTW, I load template via AJAX and use "ko.applyBindings(viewModel)" after. I assume that works fine, because initial sites are displayed correctly.
$(function(){
//site entry in user's sites list
var siteObject = function(url, lastChecked, status){
this.url = url;
this.lastChecked = (lastChecked == 'undefined') ? '' : lastChecked;
this.status = (status == 'undefined') ? 'not_checked_yet' : status;
this.toDelete = false;
this.remove = function() {viewModel.sites.remove(this)};
};
viewModel = {
//=========== sites list managment ==========================
sites: ko.observableArray(),
//on "add" click in "add site" form
addSite: function(){
var $form = $('#add_site_form');
var siteUrl = $form.find('input[name="site"]').val();
/*nifty hack <----
var sites = this.sites();
sites.push(new siteObject(siteUrl));
this.sites(sites);*/
this.sites.push(new siteObject(siteUrl));
},
//on "remove sites" button click
removeSites: function() {
var sitesToRemove = [];
$.each(this.sites(), function(){
if (this.toDelete) sitesToRemove.push(this);
});
if (sitesToRemove.length == 0)
alert("Ни одного сайта не было выбрано для удаления.");
else {
var message = "Вы точно хотите перестать отслеживать";
for (var i in sitesToRemove) {
message += "\n\"" + sitesToRemove[i].url + "\"";
}
message += "?";
if (confirm(message)) {
$.each(sitesToRemove, function(){this.remove()});
//save new sites list to db
this.saveSitesListToDb();
}
}
//hide form
$('#remove_sites_form').slideToggle();
//toggle checkboxes
$('#content_sites_list .site_info input[type="checkbox"]').slideToggle();
};
And the template:
<!-- end of menu -->
<div id="content_sites_list"
class="grid_12"
data-bind="template: {name: 'sites_list_template', foreach: sites}"></div>
<!-- Templates -->
<script id="sites_list_template" type="text/x-jquery-tmpl">
<div class="site">
<div class="site_panel grid_12">
<div class="site_info">
–
<input type="checkbox" value="${url}"
class="delete_checkbox" data-bind="checked: toDelete" />
${url.substr(7)}
{{if status == "200"}}
<img src="img/green_light.png" alt="ok"/>
{{/if}}
</div>
<div class="site_stat">
<div class="site_last_check">Последняя проверка: ${dateTimestamp}</div>
</div>
</div>
</div>
</script>
I've tried this on latest beta on knockoutjs and on stable one.
I have made a jsFiddle which works fine.
There were some problems that JSLint was complaining about in the removeSites function of the viewModel. I fixed those and added a button and input field to be able to give some input, and everything ran smooth.
So you could try updating your removeSites function and see if it helps you,

Categories