JQuery mobile listview update from json file - json

after spending last days trying to find out a solution , now I'm asking help for understanding which is/are the error/s of my code. Starting from the following external Json file listviewJsonData.json
var itemList = [{"title":"Title_1","description":"Blah blah1"},{"title":"Title_2","description":"Blah blah2"}];
I'm updating a listview trough the following code:
<div id="dataList">
<ul data-role="listview" data-inset="true">
<script type="text/javascript">
var serviceURL = "https://.../.../listviewJsonData.json";
var outputitem = '';
$.getJSON(serviceURL,function(data) {
$.each(data, function(index,item) {
outputitem += '<li><h4>'+ item[index].title +'</h4></li>';
$('#dataList').append(outputitem);
}
$('#dataList').listview('refresh');
});
</script>
</ul>
</div>
This code doesn't get me any update and the listview remains empty,
I've also checked this post but I was not able to find out a solution to my issue.
Can anyone give me any help?
thnks a lot

Your script is in-line and may fire before jQuery Mobile loads or enhances your markup. Try invoking your script by firing it as part of your pageinit event.
http://jquerymobile.com/demos/1.2.0/docs/api/events.html
$( '#aboutPage' ).live( 'pageinit',function(event){
enhanceMyDataList();
});
Also, you are appending <li> items to a container <div>, not your <ul>. Move/combine your id attribute.
<ul id="dataList" data-role="listview" data-inset="true">

Try this:
<div>
<ul id="dataList" data-role="listview" data-inset="true">
</ul>
<script type="text/javascript">
var serviceURL = "https://.../.../listviewJsonData.json";
$.getJSON(serviceURL,function(data) {
$.each(data, function(index,item) {
$('#dataList').append('<li><h4>'+ item.title +'</h4></li>');
});
$('#dataList').listview('refresh');
});
</script>
</div>
EDIT: I changed the div id to ul and a syntax error on script.

Related

Issue with ng-bind-html

I'm trying to create a website using angular-js .I'm using rest api calls for getting data. I'm using ngSanitize as the data from rest call includes html character. Even if i use ng-bind-html in my view the html tags are not removed .What is the mistake in my code.Can anyone help me
var app = angular.module('app',['ngSanitize','ui.bootstrap']);
app.controller("ctrl",['$scope','$http','$location','$uibModal',function($scope,$http,$location,$uibModal,){
//here im making my rest api call and saving the data in to $scope.items;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-sanitize.js"></script>
<body ng-app="app" ng-controller="ctrl">
<div class="hov" ng-repeat ="item in items">
<br/>
<div>
<hr class="divider" style="overflow:auto;">
<ul>
<li style="font-family: Arial, Helvetica, sans-serif;font-weight:900px;">
<h3>Name<span style="color:#0899CC;" ng-model="id2" ng-bind-html="item.name"></span></h3>
</li>
<li>
<h4>Description: <span ng-bind-html="item.description"></span></h4>
</li>
</ul>
</div>
</div>
</body>
So you want to allow HTML tags or deny them ?
If you want the html to be escaped in the data coming from your server, just use ng-bind. It will replace < with < and > with > thus showing the HTML tags instead of computing them.
If you want to completely remove any HTML tags
Try this filter
filter('htmlToPlaintext', function() {
return function(text) {
return text ? String(text).replace(/<[^>]+>/gm, '') : '';
};
}
);
then in your HTML :
<h3>Name<span style="color:#0899CC;" ng-model="id2" ng-bind-html="item.name | htmlToPlaintext"></span></h3>
If you trust the source and want to compute the HTML it send you
You can use this filter
app.filter('trusted', function($sce){
return function(html){
return $sce.trustAsHtml(html)
}
});
then in your HTML :
<h3>Name<span style="color:#0899CC;" ng-model="id2" ng-bind-html="item.name | trusted"></span></h3>
And
<h4>Description: <span ng-bind-html="item.description | trusted"></span></h4>
I have the same problem before some time , then i created a filter for this problem, You can use this filter to do sanitize your html code:
app.filter("sanitize", ['$sce', function($sce) {
return function(htmlCode) {
return $sce.trustAsHtml(htmlCode);
}
}]);
in html you can use like this:
<div ng-bind-html="businesses.oldTimings | sanitize"></div>
businesses.oldTimings is $scope variable having description of strings or having strings with html tags , $scope.businesses.oldTimings is the part of particular controller that you are using for that html.
see in the snapshot:
you can use limitHtml filter to do the same:
app.filter('limitHtml', function() {
return function(text, limit) {
var changedString = String(text).replace(/<[^>]+>/gm, ' ');
var length = changedString.length;
return changedString.length > limit ? changedString.substr(0, limit - 1) : changedString;
}
});
Then you can add bothe filter in your html like that:
<p class="first-free-para" ng-bind-html="special.description| limitHtml : special.description.length | sanitize">
Hope it will work for you.

Element not getting deleted even after I have used even delegation

I made this form using jQuery.
The jQuery code which I wrote to add this is as follows :
formView:function(){
var htmlStr = '<form><input class = "name"/><input class = "imageUrl"/><input class = "counter"/></form><button class="cancel">Cancel</button>'
$('#form').html(htmlStr);
// octopus.changeFlag();
}
and the code to collapse this form, I used jQuery as event delegation as below :
$('#form').on('click','cancel',function(e){
console.log("Hello world");
$('#form').html('');
// e.preventDefault();
});
My HTML code is as below:
<body>
<ul class = "list">
</ul>
<img class="image" src="images/Vaibhav.jpg">
<div id="count"></div>
<div id="admin">
<button class="admin">Admin</button>
<div id = "form"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
Whenever I click on cancel, it should collapse the form, but its not happening. Thanks in advance.
p.s. I am a beginner to jQuery.
You need to add . to your selector for class cancel
$('#form').on('click','.cancel',function(e){
console.log("Hello world");
$('#form').remove();
// e.preventDefault();
});

How do I generate nested DOM elements based on an AJAX result in Angular?

I'm new to Angular so be gentle with me! I'm looking at rendering subsection DOM elements based on an AJAX response, how do I go about implementing the below in Angular?
On page load a list of section headers is returned from the controller:
Clicking on any of these sections (red) would show a subsection list (blue), each of these blue headers can be clicked to show another list (black), bearing in mind I only want to show the immediate-child sections for each section/subsection/sub-subsection header click:
I've got the template code I want to use for each of these, but how do I go about bringing these templates together?
So far from looking around I get the impression I should be creating a directive for the section, sub-section and sub-sub-section (yes?), can I then bind a template to the result of an HTTP Service call? I.e expanding as the detail screenshot above:
<div area="PSED">
Personal, Social and Emotional Development
<div aspect="MH">
Making Relationships
<div goal="BLAH">
<input type="checkbox"> Blah, Blah, Blah
</div>
</div>
</div>
I was hoping to reduce page load time by returning as little data as necessary and populating sections as-required by the user.
I hope this is a reasonable question as I couldn't find anything demonstrating what I need (perhaps my ignorance of ng was causing me to omit an important keyword from my searches).
Thanks in advance for any advice provided.
Andy
If I understand the question, you are trying to dynamically add nodes to a tree-like structure after an ajax call. You can use a combination of ng-include and a recursive template to do this. Here's a rough example that doesn't include the logic for collapsing nodes but I think it gets the idea across.
View:
<script type="text/ng-template" id="tree_item_renderer.html">
<span ng-click="add(data)">{{data.name}}</span>
<ul>
<li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'">
</li>
</ul>
</script>
<ul ng-app="Application" ng-controller="TreeController">
<li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'"></li>
</ul>
Controller:
angular.module("myApp", []).
controller("TreeController", function($scope, $http) {
$scope.delete = function(data) {
data.nodes = [];
};
$scope.add = function(data) {
var post = data.nodes.length + 1;
var newName = data.name + '-' + post;
//make your call here and set your child node data
//$http.get('...').then(function(res){
// data.nodes.push({name: newName,nodes: res.data});
//});
//test data
data.nodes.push({name: newName,nodes: []});
};
$scope.tree = [{name: "Top Node", nodes: []}];
});
Working jsFiddle: http://jsfiddle.net/nfreeze/c9mrhxf2/1/

AngularJS - How to bind multiple dynamically added elements to other elements in different sections of HTML?

I apologize if I worded the question incorrectly, I am attempting to build a survey builder and I am running into a problem. Here is the link to an example plunker:
Updated:
plunker
JS:
(function() {
var app = angular.module('FormBuilder');
var stageController = function($scope, componentBuilder) {
//var test = "<div>test<button>Im a Button</button></div>";
$scope.components = [];
$scope.components2 = [];
$scope.selectedComponentIndex = -1;
//$scope.list = [{html:test}];
//$scope.componentSettings = "";
$scope.showComponentSettings = function(componentName, index) {
$scope.componentSettings = componentName;
$('#navTab a[href="#componentSettingsPage"]').tab('show');
};
$scope.addMultipleChoice = function() {
var component = componentBuilder.createMultipleChoice();
$scope.components2.push(component);
$scope.components.push(component.name);
};
$scope.addTextEntry = function() {
var component = componentBuilder.createTextEntry();
$scope.components.push(component);
};
$scope.addReadOnlyTextEntry = function() {
var component = componentBuilder.createReadOnlyTextEntry();
$scope.components.push(component);
};
$scope.delete = function(index) {
$scope.components.splice(index, 1);
};
};
app.controller("stageController", stageController);
}());
HTML:
<body>
<div ng-controller="stageController">
<!-- div>
<div ui-sortable="" ng-model="list">
<div ng:repeat="item in list" class="item">
{{item}}
</div>
</div>
</div-->
<div>
Value of scope.inner = {{components}}
</div>
<div style="display: table-row">
<div ng-include="" src="'nav.html'" style="width: 300px; display: table-cell;"></div>
<div ng-include="" src="'stage.html'" style="display: table-cell;"></div>
</div>
</div>
<script type="text/ng-template" id="multipleChoice">
<div class="multipleChoice"></div>
</script>
<script type="text/ng-template" id="textEntry">
<div class="textEntry"></div>
</script>
<script type="text/ng-template" id="readOnlyTextEntry">
<div class="readOnlyTextEntry"></div>
</script>
UPDATED question and example:
Please see my current plunker for the problem I am having. The plunker shows an example form builder that allows a user to added various components to build a form, this example allows multiple choice, text entry, and read only text entry components.
The left nav contains two tabs, one for the components and another for custom settings such as changing the question label or adding more choices to a component. My current problem is that I don't know the best method/practice to bind elements on the item settings to a specific form component in the collection.
So if a user adds a multiple choice component, clicks on it, it will show the item settings, and then be able to modifying the component settings for that specific component.
I hope this is more clear, any help is appreciated, thank you in advance.

Click Function for Dynamic Content from JSON Array

I have a PHP file that serves up a JSON array populated from a MySQL database and is loaded into the DOM. This data is loaded via jQuery getJSON() method into the #navContent divide of the HTML document. This functions as planed.
At the very-bottom of the HTML doc, I have a click function that targets the #navItem div that was dynamically loaded into the DOM but this does not fire. I am assuming the <li ID = 'navItem'... isnt kept when the data is dynamically populated..??
What do I have wrong? For now, I just want all the divides that were dynamically created into the #navContent div to click thru to a URL.
<html>
. . .
<head>
. . .
<script type="text/javascript">
var ajaxLoader = '';
var container = "navItem";
var appendE = "navContent";
var dns = 'http://192.168.1.34';
var navContent = '/andaero/php/regulatory_list.php';
var bodyContent = '/wiki/index.php/Airworthiness_Directive #content';
<!-- ================ When Ready Do This ============================ -->
<!-- **************************************************************** -->
$(document).ready(function(){
loadNav(dns + navContent, container, appendE);//<- This gets loaded into the navContent<div
loadPage(dns + bodyContent, "bodyContent");
});
. . .
</script>
<body>
. . .
<div id="navScrollContainer" class="navContentPosition">
<div id="navContent" >
<li id="navItem" style="display: none;">
<h1 class="navH1"></h1>
<h2 class="navH2"></h2>
<p class="navP"></p>
<hr class="navHR" />
</li>
</div>
</div>
. . .
</body>
<!-- ================ Functions ===================================== -->
<!-- **************************************************************** -->
<script type="text/javascript">
/* --------------- Handle Pg Loading ----------------- */
function loadPage(url, pageName) {
$("#" + pageName).load(url, function(response){
// transition("#" + pageName, "fade", false);
});
};
function loadNav(url, container, appendE) {
$.getJSON(url, function(data){
$.each(data.items, function(){
var newItem = $('#' + container).clone();
// Now fill in the fields with the data
newItem.find("h1").text(this.label);
newItem.find("h2").text(this.title);
newItem.find("p").text(this.description);
// And add the new list item to the page
newItem.children().appendTo('#' + appendE)
});
$('#navHeaderTitle').text(data.key);
//transition("#" + pageName, "show");
});
$('#navItem').click(function(e){ //<-- THIS IS BROKE!! HELP!!
e.preventDefault();
$('#bodyContent').load('www.google.com');
});
};
</scrip>
</html>
============ EDIT ================
I tried everything that was sugested with no prevail. I ended up using the code Shyju answered with but one modification to get it to work: As per the docs,
.on( events [, selector] [, data], handler(eventObject) ), I changed [,data] from the tag ID to just the tag type. ie: a. This function now since I wrapped the whole with the tag. See bellow:
Changed HTML to:
<div id="navScrollContainer" class="navContentPosition">
<div id="navContent" >
<li id="navItem" style="display: none;">
<a> //<-- ADDED THIS TAG WRAPPER!!
<h1 class="navH1"></h1>
<h2 class="navH2"></h2>
<p class="navP"></p>
<hr class="navHR" />
</a>
</li>
</div>
</div
Changed the Function to (Note that .on() allows a click event on any TAG element--even new ones--since the event is handled by the ever-present previous element after it bubbles to there.:
$('#navContent').on('click', 'a', function(e){//<--CHANGED DATA TO 'a'
e.preventDefault();
$('#bodyContent').load('http://www.google.com');
});
for dynamic content, you should use jquery on.
http://api.jquery.com/on/
So your code should look like this
$("#navScrollContainer").on("click","#navItem").click(function(e){
e.preventDefault();
$('#bodyContent').load('www.google.com');
});
But i guess you should not use the id selector for click event, because ids will (And should) be unique for an element. So when you load new content, the id will be different i believe. Probably you can use class name which is common for all those elements to be clicked.
on method is availabe from jQuery 1.7 version only. If you are using a previous version, you should use live as Niyaz mentioned.
http://api.jquery.com/live/
Instead of:
$('#navItem').click(function(){});
try using:
$('#navItem').live('click', function(){}); // jQuery older than 1.7
or
$('#navItem').on('click', function(){}); // jQuery 1.7 or newer
It would appear so that all your nav elements are created with the same ID. This
$('#navItem').click(function(e){ //<-- THIS IS BROKE!! HELP!!
will apply to only one of them I suppose. Try adding some sort of counter to the ID when you are cloning:
var newItem = $('#' + container).clone();
newItem.attr("id","something_unique_in_here");