Searching in javascript (D3) - javascript

I want to create a simple search box wherein I am searching using a particular column in the dataset
Using D3 and a CSV dataset, I am able to read the rows, but how do I go about searching on a specific column (eg: ID here)
Code :
d3.csv("search.csv", function(d) {
return {
ID: d.ID,
history: d.History,
objective: d.Objective,
learning : d.Learning
};
}, function(error, rows) {
console.log(rows);
});
I need to understand how to create a search function, wherein, we can search and the auto-suggestions come up. I have looked at various examples, but don't know how to go about this inside the D3 CSV filter.
Examples looked at
( http://bl.ocks.org/jjzieve/a743242f46321491a950 ;
http://jsfiddle.net/Mottie/ztaz6/2/ )
)
Any directions/approach will be highly appreciated

A simple array.filter should be a sufficient "search" method for this:
var filterText = "some text to search";
var filteredData = data.filter(function(d){
return (d.ID.indexOf(filterText) === 0); // does it start with the string?
});
Here's a little working example:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<input type="text" id="filterOn" />
<div id="filteredList"></div>
<script>
var data = [];
for (var i = 0; i < 100; i++) {
data.push({
ID: (Math.random() * 10 + '').replace(".","")
});
}
onFilter();
d3.select('#filterOn').on('keyup', onFilter);
function onFilter(){
var filterText = d3.select('#filterOn').property('value');
filteredData = data;
if (filterText !== ""){
var filteredData = data.filter(function(d){
return (d.ID.indexOf(filterText) === 0);
});
}
d3.select('#filteredList').html(
filteredData.map(function(d){
return d.ID;
}).join("<br/>")
);
}
</script>
</body>
</html>

Related

How to remove an element from a separate JSON file using just that elements ID?

So I'm new to JS and none of the solutions I have found online have worked for me. I am creating a backend for a todolist, and I want to add the app.delete functionality so I can delete items from the list.
Here is the code in my separate json file:
[{"id":1,"name":"item 1","complete":true},{"id":2,"name":"Walk the dog","complete":false},{"id":3,"name":"Go shopping","complete":false}]
Here is what I tried, but to be honest I just wrote whatever came to mind for this:
app.delete('/todo/:id/delete', (request, response) => {
const id = request.params.id
const findTodobyID = (todos, id) => {
for(let i = 0; i < todos.length; i++){
if(todos[i].id === parseInt(id)){
return i
}
}
return -1
}
fs.readFile('./store/todos.json', 'utf-8', (err, data) => {
if(err) {
return response.status(500).send('Sorry, something went wrong.')
}
let todos = JSON.parse(data)
const todoIndex = findTodobyID(todos, id)
if (todoIndex === -1) {
return response.status(404).send('Sorry, ID not found')
}
todos[todoIndex].complete = true
fs.writeFile('./store/todos.json', JSON.delete(todos), () => {
return response.json({'status': 'Deleted ID' + id})
})
})
})
This is the error I get when I run it in Postman:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot DELETE /todos/3/delete</pre>
</body>
</html>
If you want to remove the todoIndexth element from an array:
todos.splice(todoIndex, 1);
Also before writing it, you should use:
JSON.stringify(todos);
Instead of JSON.delete(todos).

Use JavaScript Objects with jquery ui autocomplete

I use jquery ui autocomplete on a form to autocomplete city and postal code from a text file.
The text file is formatted like this :
FR;24108;Bergerac
FR;24109;Bergerac
FR;24110;Léguillac-de-l'Auche
FR;24110;Saint-Léon-sur-l'Isle
FR;24110;Manzac-sur-Vern
The autocomplete works on the corresponding field but I would like when user choose a postal code to fill automatically the city in the field city.
And this is where where it doesn't work. I've tried to create an object with label / value :
autoCompleteData.push({cp: values[1]+'', city: values[2] + ''})
If I do a console.log(), I can see my object but I have difficulty to use it in order to use it in response needed by jquery ui autocomplete. I've seen some examples based on json response but I don't know how to adapt this to my needs. I've also tried to convert my object to json but doesn't work.
Could your explain me how to do this ?
Here is my working code
$.ajax({
url: "path-to-file/ZipCodes.txt?id=1",
dataType: "text",
success: function (data) {
var autoCompleteData = data.split('\n');
var lines = data.split(/\r\n|\n/);
//Set up the data arrays
var autoCompleteData = Array();
for (var j = 0; j < lines.length; j++) {
var values = lines[j].split(';'); // Split up the comma seperated values
//postcodes.push(values[1], values[2]);
autoCompleteData.push(values[1] + '');
//autoCompleteData.push({cp: values[1], city: values[2] + ''});
//console.log(autoCompleteData[0][1]);
$("#edit-code-postal").autocomplete({
source: function (request, response) {
var results = $.ui.autocomplete.filter(autoCompleteData, request.term);
response(results.slice(0, 10)); // Display the first 10 results
},
// We fill the city field
select: function (event, ui) {
// here I need help to use my object
}
});
}
});
And a working snippet without Ajax since I can't load my file on SO. I juste use an array instead :
$(document).ready(function() {
var data = [
"FR;24001;Périgueux",
"FR;24002;Périgueux",
"FR;24100;Saint-Laurent-des-Vignes",
"FR;24100;Lembras",
"FR;24100;Bergerac"
];
//var autoCompleteData = data.split('\n');
var lines = data;
//Set up the data arrays
var data1 = [];
var data2 = [];
var data3 = [];
var autoCompleteData = Array();
//var headings = lines[0].split(';'); // Splice up the first row to get the headings
for (var j = 0; j < lines.length; j++) {
var values = lines[j].split(';'); // Split up the comma seperated values
//postcodes.push(values[1], values[2]);
autoCompleteData.push(values[1] + '');
//autoCompleteData.push({cp: values[1], city: values[2] + ''});
}
//console.log(autoCompleteData[0][1]);
$("#edit-code-postal").autocomplete({
source: function(request, response) {
var results = $.ui.autocomplete.filter(autoCompleteData, request.term);
response(results.slice(0, 10)); // Display the first 10 results
},
// On remplit aussi la ville
select: function(event, ui) {
$('#edit-ville').val(ui.item.city);
}
});
});
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Postal code (try "24...": </label>
<input id="edit-code-postal">
<label for="tags">City: </label>
<input id="edit-ville">
</div>
</body>
</html>
}
//console.log(autoCompleteData[0][1]);
$("#edit-code-postal").autocomplete({
source: function (request, response) {
var results = $.ui.autocomplete.filter(autoCompleteData, request.term);
response(results.slice(0, 10)); // Display the first 10 results
},
// On remplit aussi la ville
select: function (event, ui) {
$('#edit-ville').val(ui.item.city);
}
});
}
});
You can push two values in autoCompleteData one will be label which we will be using in searching input field values and other any variable i.e : in below code i have use data: values[2] then we get this value and apply to your textbox using $('#edit-ville').val(ui.item.data);
Demo code :
$(document).ready(function() {
var data = [
"FR;24001;Périgueux",
"FR;24002;Périgueux",
"FR;24100;Saint-Laurent-des-Vignes",
"FR;24100;Lembras",
"FR;24100;Bergerac"
];
//var autoCompleteData = data.split('\n');
var lines = data;
//Set up the data arrays
var autoCompleteData = Array();
for (var j = 0; j < lines.length; j++) {
var values = lines[j].split(';'); // Split up the comma seperated values
autoCompleteData.push({
label: values[1],
data: values[2]
});
}
//console.log(autoCompleteData[0][1]);
$("#edit-code-postal").autocomplete({
source: function(request, response) {
var results = $.ui.autocomplete.filter(autoCompleteData, request.term);
response(results.slice(0, 10)); // Display the first 10 results
},
// On remplit aussi la ville
select: function(event, ui) {
$('#edit-ville').val(ui.item.data);//setting value in textfield
}
});
});
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Postal code (try "24...": </label>
<input id="edit-code-postal">
<label for="tags">City: </label>
<input id="edit-ville">
</div>
</body>
</html>

How to fetch data from a database using PHP and pass it to Javascript

I am making a website using HTML, CSS, MySQL and Javascript that will allow the user to login and play a quiz, the quiz has 40 questions.
The Javascript code bellow is a countdown timer, that contains the variable named "questions" after 40 seconds, it will pass automatically to the next question.
var i = 0;
var cEl = document.getElementById('countdown');
var qEl = document.getElementById('question');
var questions = [
'Question1 ?',
'Question2 ?',
'Question3 ?',
'Question4 ?'
];
var Countdown = function (time) {
this.time = time;
this.observers = [];
};
Countdown.prototype.start = function () {
setTimeout(function () {
if (this.time-- > 0) {
this.updateObservers();
this.start();
}
}.bind(this), 1000);
};
Countdown.prototype.addObserver = function (observer) {
this.observers.push(observer);
};
Countdown.prototype.updateObservers = function () {
var i, l = this.observers.length;
for (i = 0; i < l; i++) {
this.observers[i](this.time);
}
};
function printTime (time) {
cEl.innerHTML = time + 's';
}
function nextQuestion (time) {
if (time <= 0) run();
}
function run () {
var c;
if (i < questions.length) {
qEl.innerHTML = questions[i++];
c = new Countdown(40);
c.addObserver(printTime);
c.addObserver(nextQuestion);
printTime(c.time);
c.start();
} else {
document.body.innerHTML = 'Fin du quiz';
}
}
run();
And this is the part of my "quiz.php" file where I want the questions to be inserted :
<!doctype html>
<html>
<head>
<title>
Quiz
</title>
</head>
<body class="no-scroll">
<div>
<!-- some code here -->
</div>
<!-- some code here -->
<script src="js/countdown_script.js"></script>
</body>
</html>
For now, the questions are in the following variable :
var questions = [
'Question1 ?',
'Question2 ?',
'Question3 ?',
'Question4 ?'
];
But I want to use questions and their answers that are already in a database, each question has 2 or 3 possible answers, I've read that I'm not supposed to add the php code inside of a .js file, I tried to add the questions variable in the php code bellow but it did not work :
<!doctype html>
<html>
<head>
<title>
Quiz
</title>
</head>
<body class="no-scroll">
<div>
<!-- some code here -->
</div>
<!-- some code here -->
<script src="js/countdown_script.js">
var questions = [
'Question1 ?',
'Question2 ?',
'Question3 ?',
'Question4 ?'
];</script>
</body>
</html>
What is the best way to do that in my case? Given that I'm still a beginner and I only know html, css, some javascript, php and mysql.
You need to make a small API.
Step 1. make an additional page in your application that will output clean JSON array with data from the dataabse
For example: myApiWithQuestions.php
{
questions: {
question1: {
"content":"content of the question",
"possibleAnswers":[
"something", "another answer"
]
},
question2: {
"content":"content of the question",
"possibleAnswers":[
"something", "another answer"
]
},
}}
Step 2: Make an ajax call using JQuery to look for the page you have just created
$(document).ready(){
$.ajax({
url: "myApiWithQuestions.php",
})
.done(function( data ) {
//use data as an array, iterate through it and put your questions to the DOM
});
}
On .done function continue with execution of your script
Where did you read that you're not supposed to run PHP code in Javascript?
Anyway, it doesn't really matter: you can. I do it all the time.
<script type="text/javascript" src="js/countdown_script.js">
<script type="text/javascript"><!--
var questions = [
<?php
//create and run your mysql query
//loop through your results
while($row=mysql_fetch_array($results)){
//print your results in javascript format
printf("'%s ?'\n",$row['question']);
}
?>
];
--></script>

Using data from .CSV with JavaScript

I have an .csv file that looks like:
oS,browName,browVer,timeCanvas,timeSvg
Windows,Firefox,25.0,0.25,1.23
Windows,Opera,12.16,0.572,1.465
And i would like to do a function that will count arithmetic mean for timeCanvas and timeSvg looking something like:
for (int i = 0; i < maxrow; i++)
{
if(oS=Windows)
{
if(browName=FireFox
{
if(browVer=25.0)
{
a=a+1;
timeC=timeC+timeCanvas
timeS=timeS+timeSvg
}
}
}
...
}
I googled my problem and only solution i could find was jquery-csv 0.7 with toObjects method (http://code.google.com/p/jquery-csv/)> I would like to know is it possible with this libaarry to do what i want?? And if there are some good examples (couldnt find myself)??
..........................................................................
Edit:
so i tryed vadim solution but it deos not working and i dont know hwat i do worng.Here is the code.
<script type="text/javascript" src="jquery-1.3.2.js"></script>
<script type="text/javascript">
function draw(){
var a = 0,
timeC = 0,
timeS = 0,
meanCFf=0,
meanSFf= 0;
$.get('test1.csv').done(function(data) {
var i,
lines = data.split('\n'),
line = lines[0].split(','),
oS = line.indexOf('oS'),
browName = line.indexOf('browName'),
browVer = line.indexOf('browVer'),
timeCanvas = line.indexOf('timeCanvas'),
timeSvg = line.indexOf('timeSvg');
for(i=1; i<lines.length; i++) {
line = lines[i].split(',');
if(line[oS] === 'Windows') {
a++;
timeC += parseFloat(line[timeCanvas], 10);
timeS += parseFloat(line[timeSvg], 10);
}
}
});
meanCFf = timeC/a;
meanSFf = timeC/a;
var os1 = document.getElementById("osInfo1");
os1.innerHTML = "Twoja średnia to: " + meanCFf;
var os2 = document.getElementById("osInfo2");
os2.innerHTML = "Twój sytem operacyjny to: " + meanSFf;
}
</script>
</head>
<body onload="draw()">
<p id="osInfo1"></p>
<p id="osInfo2"></p>
</body>
It looks like for loop is not working coz a is zero all the time.
Using jQuery you can do something like this:
JavaScript (script.js)
$(function() {
var a = 0,
timeC = 0,
timeS = 0;
$.get('test1.csv').done(function(data) {
var i,
lines = data.split(/\r\n|\n/),
line = lines[0].split(','),
oS = line.indexOf('oS'),
browName = line.indexOf('browName'),
browVer = line.indexOf('browVer'),
timeCanvas = line.indexOf('timeCanvas'),
timeSvg = line.indexOf('timeSvg');
for(i=1; i<lines.length; i++) {
line = lines[i].split(',');
if(line[oS] === 'Windows' && line[browName] === 'Firefox' && line[browVer] === '25.0') {
a++;
timeC += parseFloat(line[timeCanvas], 10);
timeS += parseFloat(line[timeSvg], 10);
}
}
$('#osInfo1').html("Twoja średnia to: " + timeC/a);
$('#osInfo2').html("Twój sytem operacyjny to: " + timeS/a);
});
});
HTML
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>CSV Test</h1>
<div id="osInfo1"></div>
<div id="osInfo2"></div>
</body>
</html>
You could get the folder manually with javascript and then attempt to manually parse it OR you could use PHP.
PHP has some great libraries for working with CSV which come standard.
Rather than go through all the effort of working with it manually every time I would personally create a simply PHP JSON service which carries out the function you require of the csv simply and delivers the data. You can then retrieve you the data using Javascript AJAX allowing you perform the code you need as usual.
Overall, I think you'll find this will mean less code for you and theres a lot more documentation on the net to support both the PHP CSV and the JSON service.
Of course, this is assuming that you have a server that has PHP.

Rally: Empty RevisionHistory in StandardCardRenderer

I created a custom application in Rally that is a modified version of the Catalog App Kanban Board. I took the StandardCardRendered and extended it by adding fields, changing formatting, and hiding objects. I'm trying to duplicate the "Days Since Last Column Move" code and my RevisionHistory object appears to be empty, so I'm really just calculating the "Days Since Story Created". How do I correctly calculate the "Days Since List Column Move"?
All my calculation logic is stored in the this._getColumnAgeDays function and I included CreationDate and RevisionHistory in my Fetch, but these fields weren't necessary in the code for Catalog App Kanban Board. Below is a sample of the code.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>App Example: Test</title>
<meta name="Name" content="App Example: Test" />
<meta name="Vendor" content="Test" />
<script type="text/javascript" src="/apps/1.26/sdk.js"></script>
<script type="text/javascript">
var EnhancedCardRenderer = function(column, item, options)
{
rally.sdk.ui.cardboard.BasicCardRenderer.call(this, column, item, options);
var that = this;
this.getCardBody = function()
{
var card = document.createElement("div");
card.innerHTML = item.Name;
// Add card footer.
var CardFooterDiv = document.createElement("div");
dojo.addClass(CardFooterDiv, 'footerCardBorder');
dojo.addClass(CardFooterDiv, 'footerCardFormat');
var DaysMessage = "Days: " + that._getColumnAgeDays();
CardFooterDiv.appendChild(document.createTextNode(DaysMessage));
card.appendChild(CardFooterDiv);
return card;
};
this._getColumnAgeDays = function()
{
var daysOld = 0;
function getLastStateChange() {
var revisions = item.RevisionHistory.Revisions;
var lastStateChangeDate = "";
rally.forEach(revisions, function(revision) {
if (lastStateChangeDate.length === 0) {
var attr = options.attribute.toUpperCase();
if (revision.Description.indexOf(attr + " changed from") !== -1) {
lastStateChangeDate = revision.CreationDate;
}
if (revision.Description.indexOf(attr + " added") !== -1) {
lastStateChangeDate = revision.CreationDate;
}
}
});
return lastStateChangeDate || item.CreationDate;
}
var lastStateDate = getLastStateChange();
var lastUpdateDate = rally.sdk.util.DateTime.fromIsoString(lastStateDate);
return rally.sdk.util.DateTime.getDifference(new Date(), lastUpdateDate, "day");
};
};
function onLoad() {
var cardboard;
var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
var cardboardConfig = {
attribute: "Kanban",
cardRenderer:EnhancedCardRenderer,
fetch:"Name,FormattedID,Owner,ObjectID,CreationDate,RevisionHistory,Revisions"
};
cardboardConfig.cardOptions = { attribute: cardboardConfig.attribute };
cardboard = new rally.sdk.ui.CardBoard(cardboardConfig, rallyDataSource);
cardboard.display(dojo.body());
}
rally.addOnLoad(onLoad);
</script>
<style type="text/css">
</style>
</head>
<body>
</body>
</html>
You'll want to add Revisions to your fetch. The reason this works in the Kanban app is because the CardBoard component on which it is built is doing this behind the scenes automatically.
Note that fetching Revision History/Revisions can be an expensive operation- that is the reason the Kanban does the initial data load first and then once the board is rendered makes secondary requests to gather aging data from the revision history.

Categories