Creating Pages Dynamically - javascript

The following is my code where i am updating the content of the dynamically created pages constantly but the problem is my update function is running every 3 seconds on pages that i am not even viewing. i am not able to fix this.
var widgetNames = new Array();
var widgetId = new Array();
$( document ).on( "pagecreate", function() {
$( "body > [data-role='panel']" ).panel().enhanceWithin();
});
$(document).on('pagecreate', '#page1', function() {
$("#log").on('click', function(){
$.ajax({
url: "script.login",
type: "GET",
data: { 'page':'create_user', 'access':'user','username':$("input[name='username']").val(), 'password':$("input[name='password']").val()},
dataType: "text",
success: function (html) {
console.log(html);
widgetNames = new Array();
widgetId = new Array();
var res = html.match(/insertNewChild(.*);/g);
for(var i =0;i<res.length;i++){
var temp = res[i].split(',');
if(temp.length >= 3){
widgetNames[i] = (temp[2].replace('");','')).replace('"','');
widgetId[i] = temp[1].replace("'","").replace("'","").replace(/ /g,'');
}
}
var AllWidgets = ''
var testwidget = new Array();
var tempWidgetContent = html.match(/w\d+\.isHidden(.*)\(\) == false\)[\s\S]*?catch\(err\)\{ \}/gm);
for(var i =0;i<tempWidgetContent.length;i++){
var widgetContent = tempWidgetContent[i].substring(tempWidgetContent[i].indexOf('{')+1);
testwidget[i] = widgetContent.replace("site +","");
}
var widgetPart = new Array();
for(var i = 0; i<widgetNames.length; i++){
var pageHeaderPart = "<div data-role='page' id='"+widgetId[i]+"' data-pageindex='"+i+"' class='dynPageClass'><div data-role='header' data-position='fixed'><a data-iconpos='notext' href='#panel' data-role='button' data-icon='flat-menu'></a><h1>BASKETBALL FANATICO</h1><a data-iconpos='notext' href='#page2' data-role='button' data-icon='home' title='Home'>Home</a></div> <div data-role='content'>";
var pageFooterPart = "</div><div data-role='footer' data-position='fixed'><span class='ui-title'><div id='navigator'></div></span></div></div>";
widgetPart[i] = '<DIV style=\" text-align: center; font-size: 100pt;\" id=widgetContainer_'+widgetId[i]+'></DIV><SCRIPT>' + 'function UpdateWidgetDiv'+widgetId[i]+'() {' + testwidget[i] + '$(\"#widgetContainer_'+widgetId[i]+'").html(counterValue);' + '}' + 'setInterval(function(){UpdateWidgetDiv'+widgetId[i]+'()},3000)' + '</SCRIPT>';
AllWidgets +='<a href="#'+widgetId[i]+'" class="widgetLink" data-theme="b" data-role="button" >'+widgetNames[i]+'</a>';
var makePage = $(pageHeaderPart + widgetPart[i] + pageFooterPart);
makePage.appendTo($.mobile.pageContainer);
}
$('#items').prepend(AllWidgets).trigger('create');
var page = $('body').pagecontainer('getActivePage').prop("id");
console.log('The Page Id is: '+page);
}
});
});
});
In this code i am looking to run the following function
'setInterval(function(){UpdateWidgetDiv'+widgetId[i]+'()},3000)'
only for the page the user is viewing.

Here is a DEMO
When creating the pages, as well as saving the page ids in the widgetId array, I am also saving the current page index as a data attribute on each dynamic page (data-pageindex), and I am assigning a class to all the dynamic pages (dynPageClass):
for (var i = 0; i< 3; i++){
var pageid = 'dynPage' + i;
widgetId.push(pageid);
var p = '<div data-role="page" id="' + pageid + '" data-pageindex="' + i + '" class="dynPageClass">';
p += '<div data-role="header"><h1>Dyn Page' + i + '</h1></div>';
p += '<div role="main" class="ui-content">I am dynamically created</div>';
p += '<div data-role="footer"><h1>Footer</h1></div>';
p += '</div>';
$('body').append($(p));
}
The the swipe code can be handled with one handler on the dynPageClass that handles both swipeleft and swiperight:
$(document).on("swiperight swipeleft", ".dynPageClass", function(e) {
var ind = parseInt($(this).data('pageindex'));
var topageid = "page2";
var rev = true;
if (e.type == 'swiperight'){
if (ind > 0){
topageid = widgetId[ind - 1] ;
}
} else {
rev = false;
if (ind < widgetId.length - 1){
topageid = widgetId[ind + 1] ;
}
}
$.mobile.changePage("#" + topageid, {transition: "slide", reverse: rev});
});
We first get the current page's index from the data attribute and parse it into an integer. Then we see if this is a right or left swipe. If right, and index is greater than 0, we need to go back one dynamic page. Otherwise it is a left swipe and if current page is not the last one, we need to go forward one page.
Your swipeleft code on page2 is left intact:
$(document).on("swipeleft", "#page2", function() {
$.mobile.changePage("#"+widgetId[0], {transition: "slide", reverse: false});
});

Related

JavaScript performance issue, appending li into ul offline

I have a performance related issue : it takes 10sec to load my ul -it contains more than 1000 li-.
Can you point me where the problem is. What can I optimize ?
Moreover I have some much trouble to read the profile result.
NB: the DOM element template is offline until I send it to the sandbox
var displayAllHypotheses = function () {
console.time('displayAllHypotheses');
console.profile('displayAllHypotheses');
var $template = $(_template);
var $item_example = $template.find('#item-example').clone();
var $list = $template.find('.content-ask ul.select-hypothese');
$item_example.removeAttr('id');
$template.find('#item-example').remove();
_$template_item_selected = $template.find('.item-example').removeClass('item-example').clone();
for (var i in _data_game.Hypotheses) {
var $clone = $item_example.clone();
var $a_select_hypothese = $clone.find('a');
$a_select_hypothese.html(_data_game.Hypotheses[i].nom).data('hypotheseid', _data_game.Hypotheses[i].id);
$a_select_hypothese.attr('href', '#' + i);
if (!!_hypotheses_selected[_data_game.Hypotheses[i].id]) {
$a_select_hypothese.addClass('inDaList');
}
$clone.appendTo($list);
}
$list.find('a').click(function () {
$('#mod_hypothese .part-select .select-hypothese a').removeClass('selected');
$(this).addClass('selected');
displayChooseButton();
});
$item_example = null;
$a_select_hypothese = null;
$clone = null;
$list = null;
console.timeEnd('displayAllHypotheses');
console.profileEnd('displayAllHypotheses');
return $template;
};
var initTemplate = function (data) {
console.time('initTemplate hypothese');
console.profile('initTemplate hypothese');
_template = data;
var $template = displayAllHypotheses();
$template.find('.close-modal').click(function () {
_sandbox.notify('close hypothese', null);
});
_sandbox.setTemplate($template);
initSearchBox();
displaySelectedHypotheses();
$template = null;
console.timeEnd('initTemplate hypothese');
console.profileEnd('initTemplate hypothese');
};
EDIT
So I tried the string concatenation :
var displayAllHypothesesString = function () {
console.time('displayAllHypothesesString');
console.profile('displayAllHypothesesString');
var $template = $(_template);
var $list = $template.find('.content-ask ul.select-hypothese');
var lis = '';
_$template_item_selected = $template.find('.item-example').removeClass('item-example').clone();
for (var i in _data_game.Hypotheses) {
if (!_hypotheses_selected[_data_game.Hypotheses[i].id]) {
lis += '<li><a data-hypotheseid="' + _data_game.Hypotheses[i].id + '" href="#' + i + '">' + _data_game.Hypotheses[i].nom + '</a></li>';
} else {
lis += '<li><a class="inDaList" data-hypotheseid="' + _data_game.Hypotheses[i].id + '" href="#' + i + '">' + _data_game.Hypotheses[i].nom + '</a></li>';
}
}
$list.empty().append(lis);
$list.find('a').click(function () {
$('#mod_hypothese .part-select .select-hypothese a').removeClass('selected');
$(this).addClass('selected');
displayChooseButton();
});
console.timeEnd('displayAllHypothesesString');
console.profileEnd('displayAllHypothesesString');
return $template;
};
It's working fast enough !!
But now I have HTML snippet in my JS and if the web designer need to pimp the li he'll have to go to the JS file.
But I guess there is no workaround on this issue, is there ?
You can try creating a variable and store all the data in it. Once you completed the loop, append it to the element you want so you dont have to call append that many times.
var listData;
for(var i; i<data.length; i++)
listData += "<li>some data</li>"
$("#element").html(listData)
Something like that.

Fetching data in chunks

I have a carousel which I have built, which gets a list of products from my API and then each product is created as a slide in a carousel. This is all working perfectly.
When the current slide becomes active I download all of the images for that slide and populate the slide. This data also comes from the API.
What I want to do is have a speedier way to do this. At the moment I am loading these one at a time as they become "active". Ideally I want to be able to load 5 in straight away. So that the start of the array (0) is in the center of the loading array. Then when a user navigates left or right through the carousel I want to call in the next one forward or back.
So far my code is working so that when a slide is active it will have all images loaded, the code I have used for this is here:
module.carousel = (function(){
"use strict";
var exports = {};
exports.details = {};
exports.init = function (options) {
var defaultOptions = {
speed: 1500,
next: {},
back: {},
target: {}
};
if(options == null) options = {};
options = $.extend(defaultOptions, options);
exports.details.targetLength = options.target.children('li').length - 1;
exports.details.position = 0;
exports.details.products = options.target.children('li');
options.target.children('li:nth-child(' + (exports.details.position + 1) + ')').addClass('active');
exports.details.position += 1;
getMedia();
function removeActive() {
options.target.children('li.active').removeClass('active');
}
function addActive() {
options.target.children('li:nth-child(' + (exports.details.position) + ')').addClass('active');
}
function nextItem() {
if(exports.details.position >= exports.details.targetLength + 1) {
exports.details.position = 1;
} else {
exports.details.position += 1;
}
removeActive();
addActive();
getMedia();
}
function getMedia() {
var id = options.target.children('li.active').attr('data-id');
$.ajax({
url: "/beta/api/v1/watches/id/" + id + "/media",
dataType: "json",
async: false,
success: function(data) {
var mediaItems = "";
for(var x = 0, tot = data.length; x < tot; x++) {
mediaItems += "<div class='box'><img src='" + data[x] + "' class='intro-image'></div>";
}
$('#' + id + '_media').html(mediaItems);
}
});
}
function previousItem() {
if(exports.details.position === 1) {
exports.details.position = exports.details.targetLength + 1;
} else {
exports.details.position -= 1;
}
removeActive();
addActive();
getMedia();
}
$('html, body').on('swipeleft', function(event) {
event.stopPropagation();
nextItem();
});
$('html, body').on('swiperight', function(event) {
event.stopPropagation();
previousItem();
});
};
return exports;
}());
That is how my carousel works, and this is how I start it :
$(document).ready(function() {
$.getJSON("/beta/api/v1/watches", function(data) {
var productArray = [];
for(var i = 0, tot = data.length; i < tot; i++){
var productItem = "";
if(i === 0) {
productItem += "<li data-id='" + data[i].id + "' class='product active'>";
} else {
productItem += "<li data-id='" + data[i].id + "' class='product'>";
}
productItem += "<div class='product-header'><h3>"
+ data[i].name + "</h3><h3>" + data[i].case_finish
+ "</h3><h3>" + data[i].id + "</h3><h3>£" + data[i].price + "</h3></div>";
var product = data[i];
productItem += "<div id='" + data[i].id + "_media'></div>";
productItem += "</li>";
productArray.push(productItem);
}
$('#carousel').html(productArray);
$(document).on('swipeleft swiperight', function(event) {
event.stopImmediatePropagation();
});
module.carousel.init({
target: $('#carousel'),
next: $('#next'),
back: $('#back')
});
});
});

Getting the currently active page id

BACKGROUND
My app consist of 2 static pages and x number of dynamically generated pages. The number of dynamically generated pages varies from time to time. My first static page is a login page. Once you login you are taken to the 2nd static page which is a welcome screen and then you can start swiping left to view the dynamically generated pages.
What i want to achieve
I basically want to get the page id of the currently active page. As in i want to get the id of the page i am currently viewing. i tried the following
pageId = $('body').pagecontainer('getActivePage').prop("id");
console.log('==========================>THIS IS ID: '+pageId);
It only gives me the page id of the 2nd static page and not the id of the dynamically generated pages because when i swipe left to view my dyanamically generated pages the console log does not print at all.
Here is the code for the entire relevant js
var widgetNames = new Array();
var widgetId = new Array();
//ActivePageId
var pageId = ''
$(document).on("pagecreate", function () {
$("body > [data-role='panel']").panel().enhanceWithin();
});
$(document).on('pagecreate', '#page1', function () {
$("#log").on('click', function () {
$.ajax({
url: "script.login",
type: "GET",
data: {
'page': 'create_user',
'access': 'user',
'username': $("input[name='username']").val(),
'password': $("input[name='password']").val()
},
dataType: "text",
success: function (html) {
console.log(html);
widgetNames = new Array();
widgetId = new Array();
var res = html.match(/insertNewChild(.*);/g);
for (var i = 0; i < res.length; i++) {
var temp = res[i].split(',');
if (temp.length >= 3) {
widgetNames[i] = (temp[2].replace('");', '')).replace('"', '');
widgetId[i] = temp[1].replace("'", "").replace("'", "").replace(/ /g, '');
}
}
var AllWidgets = ''
var testwidget = new Array();
var tempWidgetContent = html.match(/w\d+\.isHidden(.*)\(\) == false\)[\s\S]*?catch\(err\)\{ \}/gm);
for (var i = 0; i < tempWidgetContent.length; i++) {
var widgetContent = tempWidgetContent[i].substring(tempWidgetContent[i].indexOf('{') + 1);
testwidget[i] = widgetContent.replace("site +", "");
}
var widgetPart = new Array();
for (var i = 0; i < widgetNames.length; i++) {
var pageHeaderPart = "<div data-role='page' id='" + widgetId[i] + "' data-pageindex='" + i + "' class='dynPageClass'><div data-role='header' data-position='fixed'><a data-iconpos='notext' href='#panel' data-role='button' data-icon='flat-menu'></a><h1>BASKETBALL FANATICO</h1><a data-iconpos='notext' href='#page2' data-role='button' data-icon='home' title='Home'>Home</a></div> <div data-role='content'>";
var pageFooterPart = "</div><div data-role='footer' data-position='fixed'><span class='ui-title'><div id='navigator'></div></span></div></div>";
var check = "<div data-role='content'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='b'>" + widgetNames[i] + "</div>";
widgetPart[i] = '<DIV style=\" text-align: center; background-color:#989797; font-size: 75pt;\" id=widgetContainer_' + widgetId[i] + '></DIV><SCRIPT>' + 'function UpdateWidgetDiv' + widgetId[i] + '() {' + testwidget[i] + '$(\"#widgetContainer_' + widgetId[i] + '").html(counterValue);' + '}' + 'setInterval(function(){UpdateWidgetDiv' + widgetId[i] + '()},3000)' + '</SCRIPT>';
AllWidgets += '<a href="#' + widgetId[i] + '" class="widgetLink" data-theme="b" data-role="button" >' + widgetNames[i] + '</a>';
var makePage = $(pageHeaderPart + check + widgetPart[i] + pageFooterPart);
makePage.appendTo($.mobile.pageContainer);
}
$('#items').prepend(AllWidgets).trigger('create');
//Get Active Page ID
$( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) {
pageId = $('body').pagecontainer('getActivePage').prop("id");
alert( "The page id of this page is: " + pageId );
});
}
});
});
});
Please advise and sorry if it is a bad question to ask as I am a beginner.
You were getting the active page from within the ajax call, not when swiping to a new page.
The detection code needs to fire when you are on one of the dynamic pages, show you could use pagecontainershow to detect the pageID as soon as the page displays (http://api.jquerymobile.com/pagecontainer/#event-show).
$( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) {
pageId = $(":mobile-pagecontainer" ).pagecontainer('getActivePage').prop("id");
});
UPDATE: Using pageid when updating pages:
It looks like you want an update every 3 seconds on the active page. so create a function for the entire page:
function UpdateActivePage(){
//get active page
pageId = $(":mobile-pagecontainer" ).pagecontainer('getActivePage').prop("id");
//figure out index
var idx;
for (var i=0; i<widgetId.length; i++){
if (widgetId[i] == pageid){
idx = i;
break;
}
}
//run your update
eval(testwidget[idx]);
$("#widgetContainer_" + pageid).html(updated stuff);
}
setInterval(UpdateActivePage, 3000);

Uncaught ReferenceError: variable is not defined on onclick function Javascript

Today , i have been read all the topic about this but couldn't come up with a solution that's why i am opening this topic.
This is my function which creates the view and i am trying to have a onclick function which should directs to other javascript function where i change the textbox value.
<script type="text/javascript">
$('#submitbtnamazon')
.click(function(evt) {
var x = document.getElementById("term").value;
if (x == null || x == "" || x == "Enter Search Term") {
alert("Please, Enter The Search Term");
return false;
}
listItems = $('#trackList').find('ul').remove();
var searchTerm = $("#term").val();
var url = "clientid=Shazam&field-keywords="
+ searchTerm
+ "&type=TRACK&pagenumber=1&ie=UTF8";
jsRoutes.controllers.AmazonSearchController.amazonSearch(url)
.ajax({
success : function(xml) {
$('#trackList')
.append('<ul data-role="listview"></ul>');
listItems = $('#trackList').find('ul');
html = ''
tracks = xml.getElementsByTagName("track");
for(var i = 0; i < tracks.length; i++) {
var track = tracks[i];
var titles = track.getElementsByTagName("title");
var artists = track.getElementsByTagName("creator");
var albums = track.getElementsByTagName("album");
var images = track.getElementsByTagName("image");
var metaNodes = track.getElementsByTagName("meta");
//trackId ="not found";
trackIds = [];
for (var x = 0; x < metaNodes.length; x++) {
var name = metaNodes[x]
.getAttribute("rel");
if (name == "http://www.amazon.com/dmusic/ASIN") {
trackId = metaNodes[x].textContent;
trackIds.push(trackId);
}
}
for (var j = 0; j < titles.length; j++) {
var trackId=trackIds[j];
html += '<div class="span3">'
html += '<img src="' + images[j].childNodes[0].nodeValue + '"/>';
html += '<h6><a href="#" onclick="someFunction('
+trackId
+ ')">'
+trackId
+ '</a></h6>';
html += '<p><Strong>From Album:</strong>'
+ albums[j].childNodes[0].nodeValue
+ '</p>';
html += '<p><Strong>Artist Name:</strong>'
+ artists[j].childNodes[0].nodeValue
+ '</p>';
html += '<p><Strong>Title:</strong>'
+ titles[j].childNodes[0].nodeValue
+ '</p>';
/*html += '<p><Strong>Created:</strong>'
+ releaseDate
+ '</p>';*/
html += '</div>'
}
}
//listItems.append( html );
$("#track").html(html);
$("#track").dialog({
height : 'auto',
width : 'auto',
title : "Search Results"
});
// Need to refresh list after AJAX call
$('#trackList ul').listview(
"refresh");
}
});
});
</script>
This is my other function where i change the textbox value. it works actually with other values e.g. when i give hardcoded string value. I can see the value in the console but for some reason it gives me the error like :
here the string starts with B is AsinId where i take from amazon. I am definitely in need of help because i am totally stucked.
Uncaught ReferenceError: B00BMQRILU is not defined 62594001:1 onclick
<script type="text/javascript">
function someFunction(var1) {
tracktextbox = document.getElementsByName("trackId");
for (var i = 0; i < tracktextbox.length; i++) {
tracktextbox[i].value = var1;
}
$('#track').dialog('close');
}
</script>
The problem is '<h6><a href="#" onclick="someFunction('+trackId+ ')">', from the error it is clear that trackId is a string value, so you need to enclose it within "" or ''. So try
'<h6><a href="#" onclick="someFunction(\'' + trackId + '\')">'

The right use of jQuery? Owl carousel

For my project I use the OwlCarousel. http://www.owlgraphic.com/owlcarousel/#more-demos
I managed to get 3 carousels on my page. But I think the page is getting to slow. Is there a possibility that I make to many steps?
Actually I don't need to read the json file because I store it in the localStorage one page before. But I didn't know how to delete it out without corrupting the code.
So the main question is how to make just one jQuery call to fill all 3 carousels?
This is the code I use to call the carousel:
<div id="dodatni1" style="visibility:hidden" >
<div id="owl-demo" class="owl-carousel" ></div>
</div>
<div id="dodatni2" style="visibility:hidden" >
<div id="owl-demo2" class="owl-carousel" ></div>
</div>
<div id="dodatni3" style="visibility:hidden" >
<div id="owl-demo3" class="owl-carousel" ></div>
</div>
And this is the carousel code:
$(document).ready(function() {
$("#owl-demo").owlCarousel({
jsonPath : 'json/fakeData.json',
jsonSuccess : customDataSuccess,
lazyLoad : false
});
function customDataSuccess(data){
var content = "";
var stevec = 0;
var dolzina = parseInt(localStorage.getItem('dolzina'));
for(var j=0;j<dolzina;j++){
if (stevec<10){
var imgg ="http://www.spleticna.si/images/"+localStorage.getItem('imga'+j);
var doza = localStorage.getItem('dozaa'+j);
if (doza == 3239){
content += "<a href=\"produkt.html?id=" + j + "&slider=a\" target='frejm' onclick='pokaziiframe()'><img src=\"" + imgg + "\" onError=this.src='napaka.png'></a>"
stevec=stevec+1;
}
}
}
$("#owl-demo").html(content);
}
});
$(document).ready(function() {
$("#owl-demo2").owlCarousel({
jsonPath : 'json/fakeData.json',
jsonSuccess : customDataSuccess,
lazyLoad : false
});
function customDataSuccess(data){
var content = "";
var stevec = 0;
var dolzina = parseInt(localStorage.getItem('dolzina'));
for(var j=0;j<dolzina;j++){
if (stevec<10){
var imgg = "http://www.spleticna.si/images/" + localStorage.getItem('imga'+j);
var doza = localStorage.getItem('dozaa'+j);
if (doza == 2615){
content += "<a href=\"produkt.html?id=" + j + "&slider=b\" target='frejm' onclick='pokaziiframe()'><img src=\"" + imgg + "\" onError=this.src='napaka.png'></a>"
stevec=stevec+1;
}
}
}
$("#owl-demo2").html(content);
}
});
$(document).ready(function() {
$("#owl-demo3").owlCarousel({
jsonPath : 'json/fakeData.json',
jsonSuccess : customDataSuccess,
lazyLoad : false
});
function customDataSuccess(data){
var content = "";
var stevec = 0;
var dolzina = parseInt(localStorage.getItem('dolzina'));
for(var j=0;j<dolzina;j++){
if (stevec<10){
var imgg = "http://www.spleticna.si/images/" + localStorage.getItem('imga'+j);
var doza = localStorage.getItem('dozaa'+j);
if (doza == 3140){
content += "<a href=\"produkt.html?id=" + j + "&slider=c\" target='frejm' onclick='pokaziiframe()'><img src=\"" + imgg + "\" onError=this.src='napaka.png'></a>"
stevec=stevec+1;
}
}
}
$("#owl-demo3").html(content);
}
});
I'm not sure how much speed you could get but you can rewrite your JS:
$(document).ready(function(){
//Assuming they all use the same data source/settings?
$("#owl-demo3,#owl-demo2,#owl-demo1").owlCarousel({
jsonPath : 'json/fakeData.json',
jsonSuccess : customDataSuccess,
lazyLoad : false
});
function customDataSuccess(data){
var content = "";
var stevec = 0;
var dolzina = parseInt(localStorage.getItem('dolzina'));
for(var j=0;j<dolzina;j++){
if (stevec<10){
var imgg = "http://www.spleticna.si/images/" + localStorage.getItem('imga'+j);
var doza = localStorage.getItem('dozaa'+j);
if (doza == 3140){
content += "<a href=\"produkt.html?id=" + j + "&slider=c\" target='frejm' onclick='pokaziiframe()'><img src=\"" + imgg + "\" onError=this.src='napaka.png'></a>"
stevec=stevec+1;
}
}
}
$("#owl-demo3").html(content);
}
});

Categories