Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 8ab257f

Browse files
joelwilliamsmithColinEberhardt
authored andcommitted
Intel App Framework implementation
correcting markdown adding readme initial commit of intelappframework implementation
1 parent 971a2b5 commit 8ab257f

24 files changed

+2188
-0
lines changed

intelappframework/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#Intel's App Framework Property Cross Implementation
2+
3+
Intel's App Framework was formally jqMobi. It is a javascript library specifically designed for mobile HTML5 app development.
4+
5+
The Property Cross implementation makes use of the MVC framework as well as the jqUI components.

intelappframework/app.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
var app = new $.mvc.app();
2+
3+
app.loadControllers(["searchService", "search", "results", "favourites", "formatter"]);
4+
app.loadModels(["property", "recentSearch", "favourites"]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
$.mvc.controller.create("favourites", {
2+
3+
show: function() {
4+
var $resultList = $("#resultList");
5+
$resultList.empty();
6+
7+
favourites.getAll(function(faves) {
8+
9+
if (faves.length === 0) {
10+
$resultList.html("You have not added any properties to your favourites");
11+
} else {
12+
$.each(faves, function(index, fave) {
13+
var property = new Property();
14+
var prop = fave.property;
15+
property.id = prop.id;
16+
property.set({
17+
thumb_url: prop.thumb_url,
18+
price: prop.price,
19+
title: prop.title,
20+
summary: prop.summary,
21+
img_url: prop.img_url,
22+
bedroom_number: prop.bedroom_number,
23+
bathroom_number: prop.bathroom_number
24+
});
25+
property.save(function() {
26+
$resultList.append($.template("resultsTpl",{property:prop}));
27+
});
28+
});
29+
}
30+
31+
$("#resultListHeader h1").html("Favourites");
32+
$("#loadMore").hide();
33+
//transition to results view
34+
$.ui.loadContent("results",false,false,"slide");
35+
});
36+
37+
},
38+
39+
addRemove: function(id) {
40+
var that = this;
41+
favourites.get(id, function(fave) {
42+
//if property doesn't exist as a favourite then add it
43+
if (fave.property === '') {
44+
45+
properties.get(id, function(property) {
46+
47+
var fave = new Favourites();
48+
fave.id = id;
49+
fave.set({property:property});
50+
fave.save(function() {
51+
$("#addRemoveFave").addClass("fave");
52+
});
53+
});
54+
} else {
55+
//else remove from favourites
56+
fave.remove(function() {
57+
$("#addRemoveFave").removeClass("fave");
58+
});
59+
}
60+
});
61+
}
62+
});
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+

2+
$.mvc.controller.create("formatter", {
3+
4+
currency: function(value) {
5+
return "£" + this.number(value);
6+
},
7+
title: function(title) {
8+
//chops off the second comma and everything after it.
9+
var parts = title.split(",");
10+
return parts[0] + "," + parts[1];
11+
},
12+
number: function(number) {
13+
number = number + "";
14+
var j = (j = number.length) > 3 ? j % 3 : 0; //part before first comma
15+
return (j ? number.substr(0, j) + ',' : "") + number.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + ',');
16+
}
17+
18+
19+
});
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
$.mvc.controller.create("results", {
2+
views: {"propertyTpl": "views/property.tpl"},
3+
4+
goToProperty: function(id) {
5+
properties.get(id, function(property) {
6+
$("#property").html($.template("propertyTpl",{property:property}));
7+
var $addRemoveFaveButton = $("#addRemoveFave");
8+
$addRemoveFaveButton.attr("href", "/favourites/addRemove/" + id);
9+
favourites.isFave(id, function(isFave) {
10+
if (isFave) {
11+
$addRemoveFaveButton.addClass("fave");
12+
} else {
13+
$addRemoveFaveButton.removeClass("fave");
14+
}
15+
});
16+
if (property.bedroom_number == 0) {
17+
$("#bedroomNumber").hide();
18+
} else {
19+
$("#bedroomNumber").show();
20+
}
21+
if (property.bathroom_number == 0) {
22+
$("#bathroomNumber").hide();
23+
} else {
24+
$("#bathroomNumber").show();
25+
}
26+
$.ui.loadContent("property",false,false,"slide");
27+
});
28+
}
29+
});
+234
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
$.mvc.controller.create("search", {
2+
views: {"resultsTpl": "views/result.tpl",
3+
"recentSearchTpl": "views/recentSearch.tpl",
4+
"headerTpl": "views/resultListHeader.tpl",
5+
"locationTpl": "views/locationList.tpl",
6+
"loadMoreTpl": "views/loadMore.tpl"
7+
},
8+
$resultList: $("#resultList"),
9+
$errorMessage: $("#errorMessage"),
10+
$locList: $("#locList"),
11+
$recentSearches: $("#recentSearches"),
12+
$loadMore: $("#loadMore"),
13+
$loadingSpinner: $("#loadingSpinner"),
14+
placeName: '', displayName: '', pageNum: 1,
15+
16+
/* Sets the display name locally - this is either the long_title of the location object, or formatted coordinates in the case of geo search */
17+
setDisplayName: function(location, placeNameOrCoords) {
18+
function to2DP(value) {
19+
return (Math.round(value * 100))/100;
20+
}
21+
if (this.displayName === '') {
22+
if (placeNameOrCoords.latitude && placeNameOrCoords.longitude) {
23+
this.displayName = to2DP(placeNameOrCoords.latitude) + "," + to2DP(placeNameOrCoords.longitude);
24+
} else {
25+
this.displayName = location.long_title;
26+
}
27+
}
28+
},
29+
30+
/* Adds a search to the recent search list */
31+
addToRecentSearches: function(response) {
32+
var loc = response.locations[0];
33+
var recentSearchId = loc.place_name;
34+
var recentSearch = new RecentSearch();
35+
var that = this;
36+
37+
recentSearch.get(recentSearchId, function(existing) {
38+
if (existing.display_name !== "") {
39+
//if recent search already exists, needs to move to top
40+
recentSearch.remove(function() {
41+
$('li[data-recent-search-id="' + recentSearchId + '"]').remove();
42+
});
43+
that.displayName = existing.display_name;
44+
}
45+
recentSearch.id = recentSearchId;
46+
recentSearch.set({
47+
display_name: that.displayName,
48+
total_results: $.mvc.controller.formatter.number(response.total_results),
49+
searchTimeMS: new Date().getTime()
50+
});
51+
recentSearch.save(function() {
52+
that.$recentSearches.prepend($.template("recentSearchTpl", {search: recentSearch}));
53+
that.$recentSearches.find($(":nth-child(5)")).remove();
54+
recentSearch.prune();
55+
});
56+
$("#recentSearchLabel").show();
57+
});
58+
},
59+
60+
/* Sets an error message and displays the element */
61+
setErrorMessage: function(message) {
62+
this.$errorMessage.html(message);
63+
this.$errorMessage.show();
64+
},
65+
66+
/* Adds properties to the model, updates the results view and transitions to results view */
67+
updatePropertiesList: function(response) {
68+
var that = this;
69+
response.listings.forEach(function(prop){
70+
var property = new Property();
71+
property.id = prop.guid;
72+
property.set({
73+
thumb_url: prop.thumb_url,
74+
price: $.mvc.controller.formatter.currency(prop.price),
75+
title: $.mvc.controller.formatter.title(prop.title),
76+
summary: prop.summary,
77+
img_url: prop.img_url,
78+
bedroom_number: prop.bedroom_number,
79+
bathroom_number: prop.bathroom_number
80+
});
81+
property.save(function() {
82+
that.$resultList.append($.template("resultsTpl",{property:property}));
83+
});
84+
});
85+
var numResults = that.$resultList.find("a").length;
86+
var totalResults = response.total_results;
87+
88+
$("#resultListHeader h1").html(
89+
$.template("headerTpl", {
90+
numResults: $.mvc.controller.formatter.number(numResults),
91+
totalResults: $.mvc.controller.formatter.number(totalResults)}));
92+
$.ui.updateHeaderElements($("#resultListHeader")); //unfortunately needed for load more to update num results value in the header
93+
94+
if (numResults === totalResults) {
95+
this.$loadMore.hide();
96+
} else {
97+
this.$loadMore.find("a span").html(
98+
$.template("loadMoreTpl", {
99+
numResults: $.mvc.controller.formatter.number(numResults),
100+
totalResults: $.mvc.controller.formatter.number(totalResults),
101+
searchTerm: this.displayName}));
102+
this.$loadMore.show();
103+
}
104+
105+
},
106+
107+
/* Outputs the results of a search to the DOM and switches the view to the results view */
108+
locationFound: function(response, locOrCoords) {
109+
if(response.listings.length === 0) {
110+
this.setErrorMessage("There were no properties found for the given location.");
111+
}
112+
var loc = response.locations[0];
113+
this.placeName = loc.place_name;
114+
this.setDisplayName(loc, locOrCoords);
115+
this.updatePropertiesList(response);
116+
//transition to results view
117+
$.ui.loadContent("results",false,false,"slide");
118+
119+
this.addToRecentSearches(response);
120+
},
121+
122+
/* Lists all the locations for an ambiguous search */
123+
listLocations: function(response) {
124+
$("#locListLabel").show();
125+
var that = this;
126+
this.$locList.empty();
127+
$.each(response.locations, function(index, loc) {
128+
that.$locList.append($.template("locationTpl", {loc: loc}));
129+
});
130+
this.$locList.show();
131+
},
132+
133+
/* Performs the search for location or coordinates */
134+
performSearch: function(locOrCoords) {
135+
this.$loadingSpinner.show();
136+
this.$errorMessage.hide();
137+
this.$locList.hide();
138+
$("#locListLabel").hide();
139+
140+
this.$resultList.empty();
141+
this.pageNum = 1;
142+
var that = this;
143+
144+
$.mvc.controller.searchService.findProperties(locOrCoords, this.pageNum, function(response) {
145+
that.$loadingSpinner.hide();
146+
switch (response.application_response_code) {
147+
case "100":
148+
case "101":
149+
case "110":
150+
that.locationFound(response, locOrCoords);
151+
break;
152+
default:
153+
if (!response.locations || response.locations.length === 0) {
154+
that.setErrorMessage("The location given was not recognised.");
155+
} else if (response.locations.length > 1) {
156+
that.listLocations(response);
157+
}
158+
break;
159+
}
160+
}, function() {
161+
that.setErrorMessage("An error occurred while searching. Please check your network connection and try again.");
162+
that.$loadingSpinner.hide();
163+
});
164+
},
165+
166+
/* Performs a string search, using the value entered in the input box */
167+
string:function() {
168+
var location = $('#stringSearch').val();
169+
if (location === "") {
170+
this.setErrorMessage("Please enter a location to search for");
171+
} else {
172+
this.displayName = '';
173+
this.performSearch(location);
174+
}
175+
},
176+
177+
/* Performs a geo location search */
178+
geo: function() {
179+
var that = this;
180+
function success(loc) {
181+
that.displayName = '';
182+
that.performSearch(loc.coords);
183+
};
184+
function error(msg) {
185+
that.setErrorMessage("The use of location is currently disabled.");
186+
};
187+
188+
if (navigator.geolocation) {
189+
navigator.geolocation.getCurrentPosition(success, error);
190+
} else {
191+
this.setErrorMessage("The use of location is currently disabled.");
192+
}
193+
},
194+
195+
/* Searches on a recently searched location */
196+
recent: function(placeName, displayName){
197+
this.displayName = displayName;
198+
this.performSearch(placeName);
199+
},
200+
201+
loc: function(placeName) {
202+
this.displayName = '';
203+
this.performSearch(placeName);
204+
},
205+
206+
/*Loads more results, for the current search*/
207+
loadMore: function() {
208+
var $loadMoreLabel = this.$loadMore.find("h3");
209+
$loadMoreLabel.html("Loading...");
210+
this.pageNum += 1;
211+
var that = this;
212+
$.mvc.controller.searchService.findProperties(this.placeName, this.pageNum, function(response) {
213+
that.updatePropertiesList(response);
214+
$loadMoreLabel.html("Load more...");
215+
});
216+
},
217+
218+
/* Init - adds recent searches from local storage to the DOM */
219+
init: function() {
220+
var that = this;
221+
var recentSearch = new RecentSearch();
222+
recentSearch.getAll(function(searches) {
223+
if (searches.length !== 0) {
224+
$("#recentSearchLabel").show();
225+
}
226+
searches.sort(function(a, b) {
227+
return b.searchTimeMS - a.searchTimeMS;
228+
});
229+
$.each(searches, function(index, search) {
230+
that.$recentSearches.append($.template("recentSearchTpl", {search: search}));
231+
});
232+
});
233+
}
234+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
$.mvc.controller.create("searchService", {
2+
3+
buildUrl: function(placeNameOrCoords, pageNumber) {
4+
var placeName = placeNameOrCoords.latitude && placeNameOrCoords.longitude ? "" : placeNameOrCoords;
5+
6+
return "http://api.nestoria.co.uk/api?" +
7+
"callback=?&" +
8+
"country=uk&" +
9+
"pretty=1&" +
10+
"encoding=json&" +
11+
"listing_type=buy&" +
12+
"action=search_listings&" +
13+
"page=" + pageNumber + "&" +
14+
"place_name=" + placeName + "&" +
15+
"centre_point=" + placeNameOrCoords.latitude + "," + placeNameOrCoords.longitude;
16+
17+
},
18+
19+
findProperties: function(placeNameOrCoords, pageNumber, callback, errorCallback) {
20+
var url = this.buildUrl(placeNameOrCoords, pageNumber);
21+
$.jsonP({
22+
url: url,
23+
success: function(response) {
24+
callback(response.response);
25+
},
26+
error: function() {
27+
errorCallback();
28+
}
29+
});
30+
}
31+
});

0 commit comments

Comments
 (0)