I use this function to retrieve results of the user search of a destination, but this gets all results from the world, how can I distinct results from certain country
function getPlace() {
setLoadingIcons(true);
var places = platform.getPlacesService(),
entryPoint = H.service.PlacesService.EntryPoint,
txtSearch = document.getElementById('txtSearch');
places.request(entryPoint.SEARCH, { 'at': _HEREmap.getCenter().lat + ',' + _HEREmap.getCenter().lng, 'q': txtSearch.value, 'size': 5 }, function (response) {
var items = response.results.items;
var placeHTML = '<div> <input hidden name="lat" value="{LAT}"><input hidden name="lat" value="{LNG}">{TITLE} <img src="Images/navigation Icon.png" id="arr" width="15" /> </div>';
var html = '';
for (var i = 0; i < items.length; i++) {
html += placeHTML.replace("{TITLE}", items[i].title).replace("{LAT}", items[i].position[0]).replace("{LNG}", items[i].position[1]);
}
document.getElementById('divSearchResult').innerHTML = html + '<div id="divCnclBtn"><img src="Images/Cancel Button.png" id="cnclBtn" onclick="onSearchTextBlur();"></div>';
document.getElementById('divSearchResult').style['display'] = 'block';
setLoadingIcons(false);
}, function (resp) {
//console.log('ERROR: ' + resp);
setLoadingIcons(false);
});
}
So, from what I can tell in the Places API reference, it's surprisingly hard to do...
First, instead of 'at' use 'in' with a bounding box (i.e. the bounding box of the country) to get rough filtering to work.
When you get results, look at each place result's address property and filter them by address.country (or address.countryCode).
Related
I have no expertise in javascript but I want to render this data which is showing in my console.log below
How can I make forloop or something like that to render this data in my html input?
create.html
<div class="col-sm-2">
<div class="form-group">
<label>Expected Values</label>
<input type="text" class="form-control" value="{{vital.expected_values}}" readonly>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Price</label>
<input type="text" class="form-control" value="{{vital.price}}" readonly>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#id_vitals").change(function () {
var vitals = $(this).val();
$.ajax({
url: $('#personForm').data('url'),
data: { 'vital_id': vitals },
success: function (response) {
console.log(response[vitals['name']])
}
});
});
})
</script>
I would do it somehow like that:
// Your data
let dataArray = [{data: 1, otherData: 2, elseData: 3}]
// The element, where you want to show it
let targetElement = document.getElementById('your-targer-id');
// The container element for elements
let newContainer = document.createElement('ul');
// Pure JS loop, easy to understand what is happening
// But you can also do it with .map();
for (let i = 0; i < dataArray.length; i++) {
// Add every line
newContainer.innerHTML+='<li>' + dataArray[i].data + '</li>';
// Or other things, depending how you want to show the data
newContainer.innerHTML+='<li> data value is: ' + dataArray[i].data + ' and otherData value is: ' + dataArray[i].otherData + '</li>'; //etc
}
// Append created list in target element
targetElement.appendChild(newContainer);
EDIT - now I see, that you want to display multiple values in text input, rather like so:
let dataArray = [...your-data-array]
let targetElement = document.getElementById('target-input');
for (let i = 0; i < dataArray.lenght; i++) {
// loop throug elements and add it to value attribute of input, separated by coma.
targetElement.value+=dataArray[i].expected_values + ', ';
}
So what I'm trying to accomplish is give the user a text box where they can type a city name. Based on what they type, US cities matching the text will be populated into a datalist. Once the city they like is showing in the datalist, I want them to be able to click the city and be forwarded to a URL based on the city they've chosen.
I've worked out the first portion, I have the following html:
function locationInputChange() {
var val = $('#locationLookup').val();
if (val === "") return;
if (val.length < 3) return;
console.log(val);
$.post("/ContentService/HomeSearch", {
q: val
}, function(res) {
var dataList = $("#locationlist");
dataList.empty();
if (res.length) {
for (var i = 0, len = res.length; i < len; i++) {
var opt = $("<option>" + res[i].Text + " </option>").attr("value", res[i].Value);
dataList.append(opt);
}
}
}, "json");
}
<input list="locationlist" id="locationLookup" style="width:80%;" oninput="locationInputChange()" />
<datalist id="locationlist">
</datalist>
and here is the js to get the matching results. /ContentService/HomeSearch will return a json list of matching cities.
I have it working to get the matching results and return and populate the datalist with the relevant options, but I'm stuck as to how to create links out of the datalist. I'm not married to the datalist avenue and I'm open to other methods to create the same effect.
I've got this simple webpage which uses google.visualization.Query to pull the values of three specific cells from this spreadsheet, and then sets the values of three corresponding input fields based on their unique id attributes.
google.load('visualization', '1', {'packages':['corechart']});
google.setOnLoadCallback(work);
function work() {
var queryWORK = new google.visualization.Query('https://docs.google.com/spreadsheet/ccc?key=1HpHMfoEnPgESb2XPVCgb7XyGwRAvrq3EoQj4WHj4vhA&sheet=QUERY');
queryWORK.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in ID Validation Query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var datatable = response.getDataTable();
var name = datatable.getValue(1,0);
var job = datatable.getValue(1,1);
var hours = datatable.getValue(1,2);
document.getElementById('name_out').value = name;
document.getElementById('job_out').value = job;
document.getElementById('hours_out').value = hours;
}
As it is currently, I have to "hard code" the row and column indexes for each cell I want to pull data from. How can I can get this to search through and retrieve data from the spreadsheet? What, for example, if I had a simple input field where I could enter a name and the "job" and "hours" would be returned. Is this even possible?
Thanks.
you can use Query.setQuery to set a SQL-like statement,
which can be used to select certain columns and rows
the following will select the Job & Hours columns where Name = Bill
'select B, C where A = "Bill"'
you can also search for partial text, this will select both Bill and Kim
'select B, C where A like "%i%"'
following is a working snippet, the inputs are given the same names as the Columns
enter a full or partial name and click Search to see the results...
google.charts.load('current', {
callback: function () {
document.getElementById('Search').addEventListener('click', searchSheet, false);
searchSheet();
function searchSheet() {
searchText = document.getElementById('Name').value;
var queryWORK = new google.visualization.Query('https://docs.google.com/spreadsheet/ccc?key=1HpHMfoEnPgESb2XPVCgb7XyGwRAvrq3EoQj4WHj4vhA&sheet=QUERY');
if (searchText !== '') {
queryWORK.setQuery('select B, C where A like "%' + searchText + '%"');
}
queryWORK.send(function (response) {
if (response.isError()) {
console.log('Error in ID Validation Query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var datatable = response.getDataTable();
for (var i = 0; i < datatable.getNumberOfColumns(); i++) {
document.getElementById(datatable.getColumnLabel(i)).value =
(datatable.getNumberOfRows() > 0) ? datatable.getValue(0, i) : '';
}
var chart = new google.visualization.Table(document.getElementById('table_div'));
chart.draw(datatable);
});
}
},
packages:['table']
});
div {
padding: 6px 6px 6px 6px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div><label for="Name">Enter Name: </label><input id="Name" type="text" value="Bill" /></div>
<div><input id="Search" type="button" value="Search" /></div>
<div><label for="Name">Job: </label><input id="Job" type="text" /></div>
<div><label for="Name">Hours: </label><input id="Hours" type="text" /></div>
<div id="table_div"></div>
Am struggling hard to bind an array object with list of span values using watcher in Angularjs.
It is partially working, when i input span elements, an array automatically gets created for each span and when I remove any span element -> respective row from the existing array gets deleted and all the other rows gets realigned correctly(without disturbing the value and name).
The problem is when I remove a span element and reenter it using my input text, it is not getting added to my array. So, after removing one span element, and enter any new element - these new values are not getting appended to my array.
DemoCode fiddle link
What am I missing in my code?
How can I get reinserted spans to be appended to the existing array object without disturbing the values of leftover rows (name and values of array)?
Please note that values will get changed any time as per a chart.
This is the code am using:
<script>
function rdCtrl($scope) {
$scope.dataset_v1 = {};
$scope.dataset_wc = {};
$scope.$watch('dataset_wc', function (newVal) {
//alert('columns changed :: ' + JSON.stringify($scope.dataset_wc, null, 2));
$('#status').html(JSON.stringify($scope.dataset_wc));
}, true);
$(function () {
$('#tags input').on('focusout', function () {
var txt = this.value.replace(/[^a-zA-Z0-9\+\-\.\#]/g, ''); // allowed characters
if (txt) {
//alert(txt);
$(this).before('<span class="tag">' + txt.toLowerCase() + '</span>');
var div = $("#tags");
var spans = div.find("span");
spans.each(function (i, elem) { // loop over each spans
$scope.dataset_v1["d" + i] = { // add the key for each object results in "d0, d1..n"
id: i, // gives the id as "0,1,2.....n"
name: $(elem).text(), // push the text of the span in the loop
value: 3
}
});
$("#assign").click();
}
this.value = "";
}).on('keyup', function (e) {
// if: comma,enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(e.which)) $(this).focusout();
if ($('#tags span').length == 7) {
document.getElementById('inptags').style.display = 'none';
}
});
$('#tags').on('click', '.tag', function () {
var tagrm = this.innerHTML;
sk1 = $scope.dataset_wc;
removeparent(sk1);
filter($scope.dataset_v1, tagrm, 0);
$(this).remove();
document.getElementById('inptags').style.display = 'block';
$("#assign").click();
});
});
$scope.assign = function () {
$scope.dataset_wc = $scope.dataset_v1;
};
function filter(arr, m, i) {
if (i < arr.length) {
if (arr[i].name === m) {
arr.splice(i, 1);
arr.forEach(function (val, index) {
val.id = index
});
return arr
} else {
return filter(arr, m, i + 1)
}
} else {
return m + " not found in array"
}
}
function removeparent(d1)
{
dataset = d1;
d_sk = [];
Object.keys(dataset).forEach(function (key) {
// Get the value from the object
var value = dataset[key].value;
d_sk.push(dataset[key]);
});
$scope.dataset_v1 = d_sk;
}
}
</script>
Am giving another try, checking my luck on SO... I tried using another object to track the data while appending, but found difficult.
You should be using the scope as a way to bridge the full array and the tags. use ng-repeat to show the tags, and use the input model to push it into the main array that's showing the tags. I got it started for you here: http://jsfiddle.net/d5ah88mh/9/
function rdCtrl($scope){
$scope.dataset = [];
$scope.inputVal = "";
$scope.removeData = function(index){
$scope.dataset.splice(index, 1);
redoIndexes($scope.dataset);
}
$scope.addToData = function(){
$scope.dataset.push(
{"id": $scope.dataset.length+1,
"name": $scope.inputVal,
"value": 3}
);
$scope.inputVal = "";
redoIndexes($scope.dataset);
}
function redoIndexes(dataset){
for(i=0; i<dataset.length; i++){
$scope.dataset[i].id = i;
}
}
}
<div ng-app>
<div ng-controller="rdCtrl">
<div id="tags" style="border:none;width:370px;margin-left:300px;">
<span class="tag" style="padding:10px;background-color:#808080;margin-left:10px;margin-right:10px;" ng-repeat="data in dataset" id="4" ng-click="removeData($index)">{{data.name}}</span>
<div>
<input type="text" style="margin-left:-5px;" id="inptags" value="" placeholder="Add ur 5 main categories (enter ,)" ng-model="inputVal" />
<button type="submit" ng-click="addToData()">Submit</button>
<img src="../../../static/app/img/accept.png" ng-click="assign()" id="assign" style="cursor:pointer;display:none" />
</div>
</div>
<div id="status" style="margin-top:100px;"></div>
</div>
</div>
folks! Today I created this script that has the following functionality:
add new items to array
list all items from the array
remove an item from the array
There are two functions:
addToFood() - adds the value of input to the array and updates
innerHTML of div
removeRecord(i) - remove a record from the array and updates
innerHTML of div
The code includes 3 for loops and you can see it at - http://jsfiddle.net/menian/3b4qp/1/
My Master told me that those 3 for loops make the solution way to heavy. Is there a better way to do the same thing? Is it better to decrease the loops and try to use splice? Thanks in advance.
HTML
<!-- we add to our foodList from the value of the following input -->
<input type="text" value="food" id="addFood" />
<!-- we call addToFood(); through the following button -->
<input type="submit" value="Add more to food" onClick="addToFood();">
<!-- The list of food is displayed in the following div -->
<div id="foods"></div>
JavaScript
var foodList = [];
function addToFood () {
var addFood = document.getElementById('addFood').value;
foodList.push(addFood);
for (i = 0; i < foodList.length; i++) {
var newFood = "<a href='#' onClick='removeRecord(" + i + ");'>X</a> " + foodList[i] + " <br>";
};
document.getElementById('foods').innerHTML += newFood;
}
function removeRecord (i) {
// define variable j with equal to the number we got from removeRecord
var j = i;
// define and create a new temporary array
var tempList = [];
// empty newFood
// at the end of the function we "refill" it with the new content
var newFood = "";
for (var i = 0; i < foodList.length; i++) {
if(i != j) {
// we add all records except the one == to j to the new array
// the record eual to j is the one we've clicked on X to remove
tempList.push(foodList[i]);
}
};
// make redefine foodList by making it equal to the tempList array
// it should be smaller with one record
foodList = tempList;
// re-display the records from foodList the same way we did it in addToFood()
for (var i = 0; i < foodList.length; i++) {
newFood += "<a href='#' onClick='removeRecord(" + i + ");'>X</a> " + foodList[i] + " <br>";
};
document.getElementById('foods').innerHTML = newFood;
}
You should use array.splice(position,nbItems)
function removeRecord (i) {
foodList.splice(i, 1); // remove element at position i
var newFood = "";
for (var i = 0; i < foodList.length; i++) {
newFood += "<a href='#' onClick='removeRecord(" + i + ");'>X</a> "
+ foodList[i] + " <br>";
};
document.getElementById('foods').innerHTML = newFood;
}
http://jsfiddle.net/3b4qp/5/
Now using JQuery:
$(function(){
$(document).on('click','input[type=submit]',function(){
$('#foods')
.append('<div>X '
+ $('#addFood').val() + '</div>');
});
$(document).on('click','.item',function(){
$(this).parent().remove();
});
});
http://jsfiddle.net/jfWa3/
Your problem isn't the arrays, your problem is this code:
node.innerHTML += newFood;
This code is very, very, very slow. It will traverse all exising DOM nodes, create strings from them, join those strings into one long string, append a new string, parse the result to a new tree of DOM nodes.
I suggest to use a framework like jQuery which has methods to append HTML fragments to existing DOM nodes:
var parent = $('#foods');
...
for (var i = 0; i < foodList.length; i++) {
parent.append( "<a href='#' onClick='removeReco..." );
That will parse the HTML fragments only once.
If you really must do it manually, then collect all the HTML in a local string variable (as suggested by JohnJohnGa in his answer) and then assign innerHTML once.
Here's some tips to, at least, make your code more portable (dunno if it will be better performance wise, but should be, since DOM Manipulation is less expensive)
Tips
First separate your event handle from the HTML
Pass the "new food" as a function paramater
Tie the array elements to the DOM using the ID
Instead of rerendering everything when something changes (using innerHTML in the list), just change the relevant bit
Benefits:
You actually only loop once (when removing elements from the array).
You don't re-render the list everytime something changes, just the element clicked
Added bonus: It's more portable.
Should be faster
Example code:
FIDDLE
HTML
<div id="eventBinder">
<!-- we add to our foodList from the value of the following input -->
<input id="addFood" type="text" value="food" />
<!-- we call addToFood(); through the following button -->
<button id="addFoodBtn" value="Add more to food">Add Food</button>
<!-- The list of food is displayed in the following div
-->
<div id="foods"></div>
</div>
JS
// FoodList Class
var FoodList = function (selectorID) {
return {
foodArray: [],
listEl: document.getElementById(selectorID),
idCnt: 0,
add: function (newFood) {
var id = 'myfood-' + this.idCnt;
this.foodArray.push({
id: id,
food: newFood
});
var foodDom = document.createElement('div'),
foodText = document.createTextNode(newFood);
foodDom.setAttribute('id', id);
foodDom.setAttribute('class', 'aFood');
foodDom.appendChild(foodText);
this.listEl.appendChild(foodDom);
++this.idCnt;
},
remove: function (foodID) {
for (var f in this.foodArray) {
if (this.foodArray[f].id === foodID) {
delete this.foodArray[f];
var delFood = document.getElementById(foodID);
this.listEl.removeChild(delFood);
}
}
}
};
};
//Actual app
window.myFoodList = new FoodList('foods');
document.getElementById('eventBinder').addEventListener('click', function (e) {
if (e.target.id === 'addFoodBtn') {
var food = document.getElementById('addFood').value;
window.myFoodList.add(food);
} else if (e.target.className === 'aFood') {
window.myFoodList.remove(e.target.id);
}
}, false);
Here is another sugestion:
function remove(arr, index) {
if (index >= arr.lenght) { return undefined; }
if (index == 0) {
arr.shift();
return arr;
}
if (index == arr.length - 1) {
arr.pop();
return arr;
}
var newarray = arr.splice(0, index);
return newarray.concat(arr.splice(1,arr.length))
}