phonegap jquerymobile issue: lost style when dynamically generating list items - jquery-mobile

I'm trying to generate a list dynamically from database. The results can be retrieved, however, jquerymobile style and data-role property seem to be lost. I see an ugly list instead of nicely rendered list:
I've tried to reproduce it using the simplest list item:
In my index.html, I have:
<ul data-role="listview" data-theme="d" data-divider-theme="d" data-inset="true" id="thisweekexpenselist"></ul>
In the javascript file, I have
function getExpenselist_success(tx, results) {
$('#busy').hide();
var len = results.rows.length;
for (var i=0; i<len; i++) {
var expense = results.rows.item(i);
$('#thisweekexpenselist').append('<li>Test Simplest</li>');
}
db = null;
}
It does not render correctly at all.

Try calling $('#thisweekexpenselist').listview('refresh'); at the end of the getExpenselist_success() function.

This helps:
$(document).bind('pagechange', function() {
$('.ui-page-active .ui-listview').listview('refresh');
});

Related

can you re-initiate a ui-popover?

Since I'm injecting a <span ui-popover></span> after the DOM is constructed I need to reinitiate the popovers otherwise it won't show.
Is there away to do that?
HTML
<div ng-repeat="i in comments">
<div id={{i._id}} class="task" commentId={{i._id}}> {{i.text}} </div>
</div>
I'm using the external rangy library that injects 's around highlighted texts. You can also inject elementAttirbutes to accommodate these span, This is shown in this part of the code:
JS
function initHighLighter() {
var cssApplier = null;
highlighter = rangy.createHighlighter(document);
cssApplier = rangy.createClassApplier('highlight-a',{elementAttributes: {'uib-popover':"test"}}/*, {elementAttributes: {'data-toggle':"popover", 'data-placement':"bottom", 'title':"A for Awesome", 'data-selector':"true", 'data-content':"And here's some amazing content. It's very engaging. Right?"}}*/);
highlighter.addClassApplier(cssApplier);
cssApplier = rangy.createClassApplier('highlight-b', {elementAttributes: {'uib-popover':"test"}}/*, {elementAttributes: {'data-toggle':"popover", 'data-placement':"bottom", 'title':"B for Best", 'data-selector':"true", 'data-content':"And here's some amazing content. It's very engaging. Right?"}}*/);
highlighter.addClassApplier(cssApplier);
}
I'm calling on to highlight parts of the texts, only after I upload them from the server (highlighter1 calls on init highlight written above)
JS
(function(angular) {
'use strict';
angular.module('myApp', ['ui.bootstrap'])
.controller('Controller', function($scope, $http, $timeout) {
$http.get('/comments')
.success(function(response) {
$scope.comments = response;
var allEl=[];
var i;
for (i=0; i<response.length; i++) {
allEl.push(response[i]._id);
}
$http.post('/ranges', {"commentIds":allEl})
.success(function(result){
result.forEach(function(item){
highlighter1(item.dataAction, item.rangyObject, true);
})
})
});
})
})(window.angular);
So in the end my DOM is being changed AFTER I initiated everything and then the attributes associated with the span don't do anything.
your markup should be (notice the prefix)
<span uib-tooltip="hello world"></span>
or if you want dynamic content
$scope.welcomeMessage = "hello world"; // inside controller
..
<span uib-tooltip="{{welcomeMessage}}"></span>
if you want to reinitialize the tooltip, you can trigger a $destroy event and have it rebuilt, one way if by using ng-if and setting it to true when you need it.
<span ng-if="doneUpdating" uib-tooltip="hello world"></span>

Create Table plugin dynamically using javascript API's

How to create Table plugin dynamically using javascript api's in jquery mobile.
Now i'm creating table plugin using append method in javascript, but i want create this in javascript api's.
Html
<table data-role="table" data-mode="columntoggle" class="ui-responsive table ui-shadow" id="today_app">
<tr><th>Name</th><th>Duration</th></tr>
</table>
javascript
for (var i = 0; i < serviceName.length; i++) {
$('#today_app').append('<tr><td>'+serviceName[i].name+'</td><td>'+serviceName[i].from+'</td></tr>');
}
Code without jquery mobile append...
var = document.getElementById('today_app');
for (var i = 0; i < serviceName.length; i++) {
var row = document.createElement("tr");
// create table cells
var td1 = document.createElement("td");
var td2 = document.createElement("td");
td1.innerHTML = serviceName[i].name;
td2.innerHTML = serviceName[i].form;
// adding cells to row
row.appendChild(td1);
row.appendChild(td2);
tableObj.appendChild(row);
}

jQuery Mobile styles being removed

I had code which I hardcoded...everything worked fine...then I swapped it out for dynamic updating:
<script>
var items = [];
$.getJSON('initialize.json', function(data) {
$.each(data["home"], function(key, val) {
var tmp1 = '';
var tmp2 = '';
$.each(val["group"], function(key2, val2) {
tmp1 += key2 + "/";
tmp2 += val2 + "/";
});
items.push('<li>'+key+' ('+tmp1.slice(0, -1)+')<br /><small>Completed '+tmp2.slice(0, -1)+' days ago</small><span class="ui-li-count">'+val["total"]+'</span></li>');
});
$("#temp").append(items.join(""));
});
</script>
Here is the container:
<ul id="temp" data-role="listview" data-theme="c">
<!-- Populated dynamically -->
</ul>
I have googled and tried the proposed solutions and none work:
jQuery Mobile rendering problems with content being added after the page is initialized
http://jquerymobile.com/test/docs/pages/page-dynamic.html
I've tried the above...I am curious to know why the above doesn't work...and what will and why???
You need to call listview('refresh') after you add new items to your listview. So try
$("#temp").append(items.join("")).listview("refresh");
instead of
$("#temp").append(items.join(""));
Updating lists
If you add items to a listview, you'll need to call the refresh()
method on it to update the styles and create any nested lists that are
added.
Here is working jsFiddle

keep dynamically added elements after postback

i got a big problem with jquery and the postback.
i'm dynamically adding html elements to my page. e.g. JQuery UI Tabs.
but after postback ALL dynamically added elements are gone.
how can i keep all of these elements after postback and also the values of textboxes and datetimepicker?
greetz
Tobi
EDIT:
e.g. i'm adding some JqueryUI Tabs with this code:
$(function () {
var $tab_title_input = $("#tab_title"),
$tab_content_input = $("#tab_content");
var tab_counter = 1;
var $addButton = $('<li class="ui-state-default ui-corner-top add-button"><span>+</span></li>');
$addButton.click(function () { addTab(); });
var $tabs = $("#tabsTravel, #tabsWork").tabs({ autoHeight: true, fillSpace: true,
tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
add: function (event, ui) {
var tab_content = $tab_content_input.val() || "Tab " + tab_counter + " content.";
$(ui.panel).append("<p>" + tab_content + "</p>");
$("#tabsTravel ul.ui-tabs-nav").append($addButton);
}
});
$("#tabsTravel ul.ui-tabs-nav").append($addButton);
// actual addTab function
function addTab() {
tab_counter++;
var tab_title = "worker " + tab_counter;
$tabs.tabs("add", "#tabsTravel-" + tab_counter, tab_title)
.tabs("select", "#tabsWork-" + tab_counter, tab_title);
}
// close icon: removing the tab on click
$("#tabsTravel span.ui-icon-close").live("click", function () {
var index = $("li", $tabs).index($(this).parent());
$tabs.tabs("remove", index);
tab_counter--;
});
$("#tabsWork span.ui-icon-close").live("click", function () {
var index = $("li", $tabs).index($(this).parent());
$tabs.tabs("remove", index);
// tab_counter--;
});
$('#button').click(function () {
addTab()
});
});
how can i implement this localStorage to this code?
greetz
Bl!tz
Normally this would be the job of your server-side code; you would save the added elements in the the session cache, or in the database if the changes need to be permanent.
You could also consider using the new HTML5 session storage, or local storage, but this approach will probably be more of a hassle; best to use the sophisticated server-side libraries of PHP, .NET, etc, if possible.
Edit
Here's a simple example. Let's say your client script adds some HTML to the page:
var html = "<div>hello world</div>";
$("body").append(html);
Now, you can save it in local storage like this:
localStorage.setItem("dynamichtml", html);
If you put something in your page startup script like this:
$(document).ready(function() {
if (localStorage["dynamichtml"]) {
$("body").append(localStorage["dynamichtml"]);
}
});
Then you will have achieved the dynamic functionality. Note that the localStorage data will remain saved until the user deletes it explicitly.

Changing the color of a selected link that is embedded in a table

I'm trying to use class names to change the color of a link after it has been selected, so that It will remain the new color, but only until another link is selected, and then it will change back.
I'm using this code that was posted by Martin Kool in this question:
<html>
<head>
<script>
document.onclick = function(evt) {
var el = window.event? event.srcElement : evt.target;
if (el && el.className == "unselected") {
el.className = "selected";
var siblings = el.parentNode.childNodes;
for (var i = 0, l = siblings.length; i < l; i++) {
var sib = siblings[i];
if (sib != el && sib.className == "selected")
sib.className = "unselected";
}
}
}
</script>
<style>
.selected { background: #f00; }
</style>
</head>
<body>
One
Two
Three
</body>
It works fine until I try to out the links in a table. Why is this? Be easy, I'm a beginner.
There is no error, the links are changing to the "selected" class, but when another link is selected, the old links are keeping the "selected" class instead of changing to "unselected". Basically, as far as I can tell, it's functioning like a vlink attribute, which is not what I'm going for.
And yes, the links are all in different cells, how would you suggest I change the code so that it works correctly?
OK, actually, I spoke too soon.
document.onclick = function(evt)
{
var el = window.event? event.srcElement : evt.target;
if (el && el.className == 'unselected')
{
var links = document.getElementsByTagName('a');
for (var i = links.length - 1; i >= 0; i--)
{
if (links[i].className == 'selected')
links[i].className = 'unselected';
}
el.className = 'selected';
}
return false;
}
This code you gave me works great, visually, it does exactly what I want it to do. However, It makes my links stop working... They change color, but dont link to anything, and then when I remove the script, they work fine. What am I doing wrong/what do I have to change to make this work?
Also, I want to do the same thing somewhere else in my website, where the links are all in one <div> tag, separated by <p> tags. How can I make this work?
You're looping through the siblings. If the links are in separate <td>'s then they're no longer siblings.
You can loop through all the links like this:
document.onclick = function(evt)
{
var el = window.event? event.srcElement : evt.target;
if (el && el.className == 'unselected')
{
var links = document.getElementsByTagName('a');
for (var i = links.length - 1; i >= 0; i--)
{
if (links[i].className == 'selected')
links[i].className = 'unselected';
}
el.className = 'selected';
}
return false;
}
I've also added a return false; at the end of the function to stop you going to '#'
Is there an error or is there just nothing happening? A good first step if you are a javascript beginner is to use a tool like Firebug so you see detailed error messages, and you can add in console.log statements to see what's going on while you run your code.
By ‘in tables’ do you mean putting each link in its own cell? Because that would make this line:
var siblings = el.parentNode.childNodes;
fail to select other links outside of the cell. You'd have to find another way to signal which element is the link container.

Resources