rails/angular ui router issue - ruby-on-rails

I've been doing a thinkster tutorial on combining rails and angular. I've been doing it steadily, but have been halted by an issue with the ui.router. The moment I place ['ui.router'] into my angular module it messes up my page. Any help would be greatly appreciated.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Angular App!</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="js/vendor/angular.min.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="flapperNews" ng-controller="MainCtrl">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy: '-upvotes'">
<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)">^</span>
{{ post.upvotes }}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{ post.title}}
</a>
<span ng-hide="post.link">
{{ post.title }}
</span>
</div>
<form ng-submit="addPost()" style="margin-top:30px">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text" placeholder="Title" ng-model="title"></input>
<input type="text" placeholder="Link" ng-model="link"></input>
</div>
<button type="submit">Post</button>
</form>
</div>
</div>
</body>
</html>
angular.module('flapperNews', ['ui.router'])
.factory("posts", [function(){
var o = {
posts: []
};
return o;
}])
.controller('MainCtrl', [
'$scope',
"posts",
function($scope, posts){
$scope.test = 'Hello world!';
$scope.posts = posts.posts;
$scope.posts = [
{title: "post 1", upvotes: 5},
{title: "post 2", upvotes: 2},
{title: "post 3", upvotes: 15},
{title: "post 4", upvotes: 9},
{title: "post 5", upvotes: 4}
];
$scope.addPost = function(){
if(!$scope.title || $scope.title === "") {return; }
$scope.posts.push({
title: $scope.title,
link: $scope.link,
upvotes: 0
});
$scope.title = "";
$scope.link = "";
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}]);

My guess is, that you already have the module flapperNews declared, and you are loosing the dependencies that where previously added. Check if elswehere (maybe in app.js) you have another code like this:
angular.module('flapperNews', [/** other deps**/]);
If you have it, just add ui.router to that module declaration.
Remember that if you pass a second parameter to angular.module, you will declare/redeclare that module. If you only pass the first parameter, the method will act as a getter and retreive the module.

Related

Angularjs ReferenceError: post is not defined

I'm working on a simple app that create posts and comments to learn how to create ROR apps implemented with Angularjs.
I'm finding a problem as I'm trying to make my addComment function work. Seems like the variable that holds the expected object is not defined. At least this is the message I got from network inspection
ReferenceError: post is not defined
at k.$scope.addComment (http://localhost:3000/javascripts/app.js:99:34)
at bb.functionCall (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:176:141)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:193:165
at k.$get.k.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:112:319)
at k.$get.k.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:113:48)
at HTMLFormElement.<anonymous> (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:193:147)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:31:225
at Array.forEach (native)
at q (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:7:280)
at HTMLFormElement.c (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:31:207)angular.js:9959 (anonymous function)angular.js:7298 $getangular.js:12695 $get.k.$applyangular.js:18941 (anonymous function)angular.js:2822 (anonymous function)angular.js:325 qangular.js:2821
If someone can se a problem in my code that points to this error please let me know.
follows my code
angular.module('flapperNews', ['ui.router'])
//Provider
.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
$urlRouterProvider.otherwise('home');
}])
//Posts service
.factory('posts', ['$http', function($http){
var o = {
posts: []
};
o.getAll = function() {
return $http.get('/posts.json').success(function(data){
angular.copy(data, o.posts);
});
};
o.create = function(post) {
return $http.post('/posts.json', post).success(function(data){
o.posts.push(data);
});
};
o.addComment = function(id, comment) {
return $http.post('/posts/' + id + '/comments.json', comment);
};
return o;
}])
//Main Controller
.controller('MainCtrl', [
'$scope',
'posts',
function($scope, posts){
$scope.posts = posts.posts;
$scope.addPost = function(){
if(!$scope.title || $scope.title == '') { return; }
posts.create({
title: $scope.title,
link: $scope.link
});
$scope.title = '';
$scope.link = '';
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}])
//Posts Controller
.controller('PostsCtrl', [
//the $scope declares that it will have elements visible in the view
'$scope',
'$stateParams',
//the posts under is the service
'posts',
function($scope, $stateParams, posts){
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function(){
if($scope.body === '') { return; }
posts.addComment( post.id, {
body: $scope.body,
author: 'user'
}).success(function(comment){
$scope.post.comments.push(comment);
});
$scope.body = '';
};}]);
and the html
<!DOCTYPE html>
<html>
<head>
<title>FlapperNews</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="javascripts/app.js"></script>
<script src="javascripts/application.js"></script>
<%= csrf_meta_tags %>
</head>
<body ng-app="flapperNews">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(post)"></span>
{{post.upvotes}}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()"
style="margin-top:30px;">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Title"
ng-model="title">
</div>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Link"
ng-model="link">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
<script type="text/ng-template" id="/posts.html">
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</h3>
</div>
<div ng-repeat="comment in post.comments | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(comment)"></span>
{{comment.upvotes}} - by {{comment.author}}
<span style="font-size:20px; margin-left:10px;">
{{comment.body}}
</span>
</div>
<form ng-submit="addComment()"
style="margin-top:30px;">
<h3>Add a new comment</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Comment"
ng-model="body">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
</body>
</html>
I think the problem is here Comments. You missed {. Because of which it is unable to find the stateparam id, which you are using to create post object on controller's scope.

AngularJS doesn't work in MVC Partial Views

I'm currently working on a ASP.NET MVC project. The sites of the web application are created with Bootstrap. Later I added some AngularJS script to be able to translate the page into different languages. This works fine for all the pages, but not so if a partial view is loaded from a page.
So, for example I have a page to search for rollout objects by name or host name. On the page all the angular expressions in curly braces are evaluated properly and are replaced with strings in several languages by using a translate script. Now if I filter the objects by one of the three attributes the partial view for that page is loaded showing the results of the search, but here are the angular expressions not evaluated and it just shows the expressions themselves.
Here is the page where it works properly:
#{
ViewBag.Title = "{{ 'ROLLOUT-OBJECT_MANAGEMENT.TITLE' | translate }}";
}
<!-- html -->
<div style="font-size: 20px; margin-top: 20px; margin-bottom: 20px;">
<div class="gray-background list-group-item" translate="{{'ROLLOUT-OBJECT_MANAGEMENT.TITLE'}}"></div>
</div>
<div class="list-group">
<div class="gray-background list-group-item">
<div class="row margin-bottom">
<div class="col-md-3">
<h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.FIRST_NAME'}}"></h6>
</div>
<div class="col-md-3">
<h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.SURNAME'}}"></h6>
</div>
<div class="col-md-3">
<h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.HOST_NAME'}}"></h6>
</div>
</div>
<div class="row margin-bottom">
<div class="col-md-3">
<!-- referenced in getPartial() -->
<input type="text" class="form-control" id="iFirstName" name="iFirstName" placeholder="">
</div>
<div class="col-md-3">
<!-- referenced in getPartial() -->
<input type="text" class="form-control" id="iSurName" name="iSurName" placeholder="">
</div>
<div class="col-md-3">
<!-- referenced in getPartial() -->
<input type="text" class="form-control" id="iHostName" name="iHostName" placeholder="">
</div>
<div class="col-md-3">
<!-- getPartial() added to click through javascript-->
<button type="submit" class="btn btn-primary btn-block" id="iButton"><span translate="{{'ROLLOUT-OBJECT_MANAGEMENT.BUTTON_SEARCH'}}"></span><span class="white-color glyphicon glyphicon-search"></span></button>
</div>
</div>
</div>
</div>
<div class="list-group">
<div class="gray-background list-group-item">
<h5><span translate="{{'ROLLOUT-OBJECT_MANAGEMENT.RESULTS'}}"></span><span class="purple-color glyphicon glyphicon-globe"></span></h5>
</div>
<!-- referenced in getPartial() -->
<div class="gray-background list-group-item">
<div class="row">
<div class="col-md-12" id="partialViewContainer">
#{Html.RenderPartial("_RolloutObjectManagementResultsPartial");}
</div>
</div>
</div>
</div>
<!-- layout -->
#Styles.Render(
"~/content/chosen/chosen.css",
"~/content/chosen/prism.css",
"~/content/chosen/style.css",
"~/content/bootstrap.css",
"~/content/Site.css")
<!-- javascript -->
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/chosen/chosen.jquery.js"></script>
<script src="~/Scripts/chosen/prism.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script>
var config = {
'.chosen-select': {},
'.chosen-select-deselect': { allow_single_deselect: true },
'.chosen-select-no-single': { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-width': { width: "95%" }
}
for (var selector in config) {
$(selector).chosen(config[selector]);
}
</script>
<script>
//add functionality to button
$('#iButton').click(function () {
getPartial('0');
});
</script>
<script>
function previous() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
if (temp > 0) {
temp = --temp;
}
getPartial(temp);
}
function next() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
temp = ++temp;
getPartial(temp);
}
</script>
<script>
function getPartial(newPage) {
//get search values
var tempFirst = document.getElementById("iFirstName");
var tempSur = document.getElementById("iSurName");
var tempHost = document.getElementById("iHostName");
var firstResult = tempFirst.value;
var surResult = tempSur.value;
var hostResult = tempHost.value;
//ajax call
$.ajax({
url: "_RolloutObjectManagementResultsPartial",
type: "POST",
data: { firstName: firstResult, surName: surResult, hostName: hostResult, page: newPage, count: 10 },
dataType: "html",
error: function (xhr) {
//alert(xhr.responseText);//debug
},
success: function (result) {
$("#partialViewContainer").html(result).find("select").each(function () {
$(this).chosen({});
})
},
complete: function () {
//alert("everything worked");//debug
}
});
}
</script>
And here is the partial view where it doesn't work (important are the expressions in {{...}}:
<!-- Import needed namespaces -->
#using RolloutTool.BusinessLayer.Foundation
#using RolloutTool.Utility
<!-- Initializing needed variables -->
#{
List<RolloutObject> RolloutObjects = ViewContext.Controller.ViewBag.RolloutObjects;
List<Cluster> Clusters = ViewContext.Controller.ViewBag.Clusters;
string name = "";
int count = 0;
string rowID = "";
int page = 0;
if (ViewContext.Controller.ViewBag.Page != null)
{
page = ViewContext.Controller.ViewBag.Page;
}
}
<!-- html elements -->
<div class="row">
<div class="col-md-12">
<table class="table">
<thead>
<tr>
<th style="width:25%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.EMPLOYEE'}}"></h6></th>
<th style="width:20%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.WORK_STATION'}}"></h6></th>
<th class="text-center" style="width:15%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.EDIT'}}"></h6></th>
<th class="text-center" style="width:25%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.CLUSTER'}}"></h6></th>
<th class="text-center" style="width:15%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.ASSIGN'}}"></h6></th>
</tr>
</thead>
<tbody>
<!-- creating all RolloutObject Table rows -->
#foreach (RolloutObject ro in RolloutObjects)
{
<!-- generating rowID -->
rowID = "row" + Convert.ToString(count);
count++;
<!-- generating the full employee name -->
name = Functions.TryGetValue(ro.Employee.FirstName) + " " + Functions.TryGetValue(ro.Employee.SecondName) + " " + Functions.TryGetValue(ro.Employee.Name);
<tr id="#rowID">
<td>#name</td>
<td id="#Convert.ToString(rowID + "_hn")">#Convert.ToString(Functions.TryGetValue(ro.Hostname))</td>
<!-- generate link to right rolloutobjectedit -->
<td class="text-center"><span class="btn-pencil glyphicon glyphicon-pencil blue-color glyph-hov" onclick="location.href='#Url.Action("RolloutObjectEdit", "RolloutObject", new {hostName = ro.Hostname })'"></span></td>
<!-- generating the link for cluster addition and populating cluster dropdown -->
<td class="text-center">
<div class="row">
<div class="col-sm-12">
<select class="chosen-select no-margin" style="width:100%" id="#Convert.ToString(rowID + "_cl")" name="iCluster" data-placeholder="Cluster">
#if (ro.Cluster != null)
{
<option selected>#Convert.ToString(Functions.TryGetValue(ro.Cluster.Name))</option>
}
else
{
<option></option>
}
#foreach (Cluster cluster in Clusters)
{
<option>#Convert.ToString(Functions.TryGetValue(cluster.Name))</option>
}
</select>
</div>
</div>
</td>
<td class="text-center"><span class="btn-ok glyphicon glyphicon-ok green-color glyph-hov" onclick="callAjax('#rowID')" /></td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-md-12">
<input class="hidden" id="hPage" value="#Convert.ToString(page)" />
<nav>
<ul class="pager">
<li class="pull-left"><a class="btn-paging glyphicon glyphicon-arrow-left" onclick="previous()"></a></li>
<li class="pull-right"><a class="btn-paging glyphicon glyphicon-arrow-right" onclick="next()"></a></li>
</ul>
</nav>
</div>
</div>
<!-- javascript -->
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/chosen/chosen.jquery.js"></script>
<script src="~/Scripts/chosen/prism.js"></script>
<script>
function callAjax(idRow) {
//get row values
var tempTD = document.getElementById(idRow + "_hn");
var tempSelect = document.getElementById(idRow + "_cl");
var tempHostName = tempTD.textContent;
var tempCluster = tempSelect.options[tempSelect.selectedIndex].text;
//ajax call
$.ajax({
url: "AddToCluster",
type: "POST",
data: { clusterName: tempCluster, hostName: tempHostName },
dataType: "html",
error: function (xhr) {
alert(xhr.responseText);
},
success: function (result) {
},
complete: function () {
//alert("everything worked");//debug
}
});
}
</script>
<script>
function previous() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
if (temp > 0) {
temp = --temp;
}
getPartial(temp);
}
function next() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
temp = ++temp;
getPartial(temp);
}
</script>
<script>
function getPartial(newPage) {
//get search values
var tempFirst = document.getElementById("iFirstName");
var tempSur = document.getElementById("iSurName");
var tempHost = document.getElementById("iHostName");
var firstResult = tempFirst.value;
var surResult = tempSur.value;
var hostResult = tempHost.value;
//ajax call
$.ajax({
url: "_RolloutObjectManagementResultsPartial",
type: "POST",
data: { firstName: firstResult, surName: surResult, hostName: hostResult, page: newPage, count: 10 },
dataType: "html",
error: function (xhr) {
alert(xhr.responseText);
},
success: function (result) {
$("#partialViewContainer").html(result).find("select").each(function () {
$(this).chosen({});
})
},
complete: function () {
//alert("everything worked");//debug
}
});
}
</script>
This is the _Layout.cshtml where the scripts are contained and loaded:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - {{ 'TITLE.PROGRAM' | translate }}</title>
#Styles.Render(
"~/Content/css",
"~/Content/flag-icon-css-master/assets/docs.css",
"~/Content/flag-icon-css-master/css/flag-icon.min.css",
"~/Content/Site.css")
<script src="~/Scripts/angular/angular.js"></script>
<script src="~/Scripts/angular/angular-translate.js"></script>
<script src="~/Scripts/angular/angular-cookies.min.js"></script>
<script src="~/Scripts/angular/translate.js"></script>
<script src="~/Scripts/angular/angular-route.min.js"></script>
<script src="~/Scripts/angular/angular-translate-storage-cookie.min.js"></script>
<script src="~/Scripts/angular/angular-translate-storage-local.min.js"></script>
</head>
<body ng-controller="Ctrl">
<!-- Here is the html for the navigation bar etc. -->
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
I am really not an expert on AngularJS as I only wanted to provide some cool translation feature, but I hope you guys have an idea why it doesn't work in the partial views.
Its just that you need to call the partial view using ng-include("'controller/action'"). Apostrophe(') is important while writing url.
Example
<div id="TestDiv" ng-include="templateUrl"></div>
and inside the angular controller
var app = angular.module("Layout", []);
app.controller("LoadPage", function ($scope, $http, $sce) {
//Initially
$scope.templateUrl = '/Home/DefaultPage';
// To dynamically change the URL.
$scope.NewProjFn = function () {
$scope.templateUrl = '/Home/ProjectPage';
};
});
It might well not at all be difficult for you to re-implement it but by using ng-include you also need not to make an ajax call. It do it all by itself which includes ajax call, compilation and display. But the functions like ng-click and other events will not work as its a one time compilation process.

Drag and Drop using angular JS malfunctioning

I am working on a task assignment board and i have a problem on shifting existing tabs (accordion) between certain div's ... The scope variables list is getting updated properly and the code works fine when i am jQuery accordion .But when i use an angular js accordion ,
The shifting of the accordion tabs gets duplicated .
// main HTML content
<!DOCTYPE html>
<html ng-app="App">
<title>Task WhiteBoard</title>
<head>
<meta charset="utf-8" />
<meta name="description" content="AngularJS + jQuery UI Drag-n-Drop" />
<link rel="stylesheet/less" type="text/css" href="css/main.less" />
<link href="css/zippy.css" rel="stylesheet">
<link href="css/jquery-ui-1.9.2.custom.min.css" rel="stylesheet"
type="text/css" />
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/jquery-1.8.1.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/angular.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
<script src="js/less-1.1.6.min.js"></script>
<meta charset="utf-8" />
<title>Angular Drag and Drop</title>
</head>
<body ng-controller="dndCtrl" ng-cloak>
<h3>Task Whiteboard</h3>
<div class='list1' droppable value='1' >
<div class='header'>
Free Tasks
</div>
<div class="below-header">
</div>
<div ng-repeat="item in list1" data-index="{{$index}}" draggable>
<div class="zippy" zippy-title="{{item.name}}">
{{item.content.newLabel}} <br/>
{{item.content.desc}} <br/>
{{item.content.effort}} <br/>
{{item.content.owner}} <br/>
{{item.content.issues}} <br/>
{{item.content.comments}} <br/>
{{item.content.dependency}} <br/>
</div>
</div>
</div>
<div class='list2' droppable value='2'>
<div class='header'>
Claimed Tasks
</div>
<div class="below-header">
</div>
<div ng-repeat="item in list2" data-index="{{$index}}" draggable>
<div class="zippy" zippy-title="{{item.name}}">
{{item.content.newLabel}} <br/>
{{item.content.desc}} <br/>
{{item.content.effort}} <br/>
{{item.content.owner}} <br/>
{{item.content.issues}} <br/>
{{item.content.comments}} <br/>
{{item.content.dependency}} <br/>
</div>
</div>
</div>
<div class='list3' droppable value='3'>
<div class='header'>
Completed Tasks
</div>
<div class="below-header">
</div>
<div ng-repeat="item in list3" data-index="{{$index}}" draggable>
<div class="zippy" zippy-title="{{item.name}}">
{{item.content.newLabel}} <br/>
{{item.content.desc}} <br/>
{{item.content.effort}} <br/>
{{item.content.owner}} <br/>
{{item.content.issues}} <br/>
{{item.content.comments}} <br/>
{{item.content.dependency}} <br/>
</div>
</div>
</div>
<div style="clear:both;">
list 1 size : {{list1.length}} <br/>
list 2 size : {{list2.length}} <br/>
list 3 size : {{list3.length}} <br/>
</div>
</body>
</html>
// services.js
//This makes any element droppable
//Usage: <div droppable></div>
App.directive('droppable', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(function (value) {
//This makes an element Droppable
element.droppable({
drop: function (event, ui) {
var dragIndex =
angular.element(ui.draggable).data('index');
if(angular.element(ui.draggable).parent().hasClass('list1') &&
element.attr('value')=='2') {
scope.list2.push(scope.list1[dragIndex]);
scope.list1.splice(dragIndex, 1);
}
else if (angular.element(ui.draggable).parent().hasClass('list2') &&
element.attr('value')=='3') {
scope.list3.push(scope.list2[dragIndex]); scope.list2.splice(dragIndex, 1);
// alert("list2 size : "+scope.list2.length);
}
else if (angular.element(ui.draggable).parent().hasClass('list2') && element.attr('value')=='1') {
scope.list1.push(scope.list2[dragIndex]);
scope.list2.splice(dragIndex, 1);
// alert("list3 size : "+scope.list3.length);
}
scope.$apply();
}
});
});
}
};
});
//zippy directive to give an accordion feel
App.directive('zippy', function(){
return {
restrict: 'C',
// This HTML will replace the zippy directive.
replace: true,
transclude: true,
scope:{ title:'#zippyTitle' },
template:'<div>'+
'<div class="title">{{title}}</div>'+
'<div class="body" ng-transclude></div><hr/>'+
'</div>',
// The linking function will add behavior to the template
link: function(scope, element, attrs) {
// Title element
var title = angular.element(element.children()[0]),
// Opened / closed state
opened = true;
// Clicking on title should open/close the zippy
title.bind('click', toggle);
// Toggle the closed/opened state
function toggle() {
opened = !opened;
element.removeClass(opened ? 'closed' : 'opened');
element.addClass(opened ? 'opened' : 'closed');
}
// initialize the zippy
toggle();
}
}
});
// In controller .js
$scope.list1 = [
{
name: 'Intelligent Design',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
},
{
name: 'Good Artist\'s Copy',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
},
{
name: 'Task Creation',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
}]
$scope.list2 = [
{
name: 'Task4',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
}]
$scope.list3 = [];

Jquery mobile autocomplete to a listview

I like to add autocomplete feature for my jquery mobile page on a text box such that when user enters it should show the results in listview format. The code below shows the results but not in the listview format. Can someone point out how to fix it. Thanks.
<!DOCTYPE HTML>
<html>
<head>
<title>Finder</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/ui/1.8.20/jquery-ui.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<style>
input{text-transform:uppercase;}
</style>
<script>
$(document).ready(function() {
$( "#firstinputbox" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://ziplocator.cloudfoundry.com/rest/startsWithCity/",
dataType: "json",
data: {
maxRows: 10,
startsWith: request.term
},
success: function(data) {
response( $.map( data.zipcodes, function( item ) {
var listItem = ' <li class="ui-btn ui-btn-icon-right ui-li "><div class="ui-btn-inner ui-li"><div class="ui-btn-text">' + item.zipcodeId + '</div><span class="ui-icon ui-icon-arrow-r"></span></div></li>';
$(listItem).appendTo("#suggestions");
return {
label: item.cityName + ", " +item.zipcodeId + ", " + item.state,
value: item.cityName
}
}));
}
});
},
minLength: 1,
open: function() {
},
close: function() {
$('ul li').remove();
//should attach the value to the text box
}
});
});
</script>
</head>
<body>
<div data-role="page" data-add-back-btn="true" id="inputdialog">
<div data-role="header">
<h1>Enter Criteria here</h1>
</div>
<div data-role="content">
<input type="text" id="firstinputbox" placeholder="Enter here"/>
<ul id="suggestions" data-role="listview" data-inset="true"></ul>
</div>
<div data-role="footer">
</div>
</div>
</body>
</html>
You need to call the listview() function on your content after inserting the new content:
$('#suggestions').listview();
See Elijah Manor's explanation for the details.
Try calling the listview refresh method in your ajax success function.
$('#suggestions').listview('refresh');
try this one
In <li> tag remove class..... class="ui-btn ui-btn-icon-right ui-li "
Then it shows results in list view formats

Ajax jquery-ui accordion

I init my accordion in the following way:
$(function() {
$("#gallery_accordion").accordion({ event: false });
$("#gallery_accordion").click(function(e) {
var contentDiv = $(this).next("div");
contentDiv.load($(this).find("a").attr("href"));
});
});
The content is loaded onclick but the accordion is invisible.
Nothing is shown. Any help highly appreciated.
Thanks.
Update: The height stays at '0'. Any reason for that?
Here is the markup:
<div id="gallery_accordion">
<h3>My first gallery</h3>
<div id="gallery369">
</div>
<h3>The second gallery</h3>
<div id="gallery381">
</div>
</div>
Try changing your initial call to:
$("#gallery_accordion").accordion({ header: "h3", event : false });
And your HTML to:
<div id="gallery_accordion">
<div>
<h3>My first gallery</h3>
<div id="gallery369">
</div>
</div>
<div>
<h3>The second gallery</h3>
<div id="gallery381">
</div>
</div>
</div>
Each of your cells needs to have its own div tag and in the initial call you have now set the header to the H3 tag.
Hope this helps.
Here is a sample doc that loads the accordion:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>jQuery UI Example Page</title>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/themes/start/jquery-ui.css" rel="Stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
// Accordion
$("#gallery_accordion").accordion({ header: "h3"});
$("#gallery_accordion a").click(function(evt) {
var galleryId = $(this).attr('href').split('#')[1];
var contentDiv = $('#' + 'gallery' + galleryId);
if(contentDiv.html() == " ") {
var galleryContent = getGallery(galleryId);
contentDiv.html(galleryContent);
}
});
var galleryIdI = $('#gallery_accordion div div:first').attr('href').split('#')[1];
var contentDivI = $('#' + 'gallery' + galleryId);
var galleryContentI = getGallery(galleryId);
contentDivI.html(galleryContentI);
});
</script>
</head>
<body>
<!-- Accordion -->
<h2 class="demoHeaders">Accordion</h2>
<div id="gallery_accordion">
<div>
<h3>Gallery 1</h3>
<div id="gallery369"> </div>
</div>
<div>
<h3>Gallery 2</h3>
<div id="gallery381"> </div>
</div>
<div>
<h3>Gallery 3</h3>
<div id="gallery392"> </div>
</div>
</div>
</body>
</html>

Resources