I am trying to implement Bootstrap Typeahead to eventually use an Elasticsearch instance I have, but I cannot even get the basic example to work in Django (2.2.6). I am taking the majority of this code from the examples page. Here is the HTML I am using:
typeahead.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
<script type="text/javascript">
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substringRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push(str);
}
});
cb(matches);
};
};
var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];
$('.typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
source: substringMatcher(states)
});
</script>
</head>
<body>
<div id="the-basics">
<input class="typeahead" type="text" placeholder="States of USA">
</div>
</body>
</html>
Here is the page/URL I am trying to access:
urls.py
from django.urls import path
from . import views
app_name = 'materials'
urlpatterns = [
path('typeahead/', views.typeahead_view, name='typeahead')
]
And this is the basic view I have set up for this page:
views.py
def typeahead_view(request):
return render(request, 'materials/typeahead.html')
Nothing happens when I start typing in the input...
There is a problem with your html page. First of all, jquery was not added in it and secondly add all the js file at the end of the body. Check below updated code for the html file.
typeahead.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="the-basics">
<input class="typeahead" type="text" placeholder="States of USA">
</div>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
<script type="text/javascript">
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substringRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push(str);
}
});
cb(matches);
};
};
var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];
$('.typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
source: substringMatcher(states)
});
</script>
</body>
</html>
It works properly. I hope this will help you :)
We've been banging our heads on how to optimize a lock-state downloading a large set of data with Ember-data/Rest-adapter. We're preloading an app with data from a REST API and one of the sets has ha weight of ~2M for some users. What we want to do is avoid the lock-state that the app runs into when extracting all these records.
In this example the interface is supposed to update i on each frame, but "hangs" as soon as the JSON is downloaded and being prepared. This is of-course related to the single-threaded execution, but there has to be some way of making this graceful?
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return [];
},
setupController: function(controller) {
var element = document.getElementById('counter');
var i = 0;
var l = function() {
element.innerHTML = i;
i++;
window.requestAnimationFrame(l);
}.bind(this);
l();
this.store.find('record').then(function(data){
console.log('loaded', data);
});
}
});
App.RecordModel = DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
birthdate: DS.attr('date'),
created: DS.attr('date'),
});
App.RecordAdapter = DS.RESTAdapter.extend({
host: 'https://gist.githubusercontent.com/hussfelt/100fedf00009bdcbb962/raw/',
pathForType: function() {
return 'json_example.json';
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://builds.emberjs.com/tags/v1.10.0/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/tags/v1.10.0/ember.debug.js"></script>
<script src="http://builds.emberjs.com/beta/ember-data.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div id="counter"></div>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
</script>
</body>
</html>
The solution was to skip using the RESTAdapter to populate this set of data.
Instead we'd do a normal Ajax request with Ember.$, fetching the data - then loop through the data in chunks and use store.pushPayload to inject into the store.
Thanks to people in #emberjs at freenode for the ideas!
The below script could surely be optimized pushing more records each time instead of one at a time. But it solves the problem, and minimizes the lock-state.
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return [];
},
setupController: function(controller) {
var element = document.getElementById('counter');
var i = 0;
var l = function() {
element.innerHTML = i;
i++;
window.requestAnimationFrame(l);
}.bind(this);
l();
// Prebuild options object
var options = {
// Requesting url
url: 'https://gist.githubusercontent.com/hussfelt/100fedf00009bdcbb962/raw/json_example.json',
// Using GET
type: 'GET',
// This is a cross-domain request
crossDomain: true,
// On successful request
success: function(data) {
// Run the inception-loop
recordLoop(Ember.$.parseJSON(data));
},
};
// Trigger the request
Ember.$.ajax(options);
// Disable the normal find for records
//this.store.find('record').then(function(data){
// console.log('loaded', data);
//});
/**
* Will populate the store in each 60th of a second
* #param object data The data to populate with
* #return void
*/
var recordLoop = function(data) {
// Setup counters
var x, i = 0;
// Prebuild awesome object - to match push-payload
var records = {
records: []
};
// Loop through records, populate array and push to store
for (x = (data.records.length - 1), i = 0;
(x >= 0 && i <= 300); x--, i++) {
// Prepare object
records.records = [data.records[x]];
// Push to store
this.store.pushPayload('record', records);
// Remove the actual element from the data
data.records.splice(x, 1);
}
// Run again, if we have content
if (data.records.length > 0) {
window.setTimeout(function() {
recordLoop(data);
}, 1000 / 60);
}
}.bind(this);
}
});
App.RecordModel = DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
birthdate: DS.attr('date'),
created: DS.attr('date')
});
App.RecordAdapter = DS.RESTAdapter.extend({
host: 'https://gist.githubusercontent.com/hussfelt/100fedf00009bdcbb962/raw/',
pathForType: function() {
return 'json_example.json';
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://builds.emberjs.com/tags/v1.10.0/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/tags/v1.10.0/ember.debug.js"></script>
<script src="http://builds.emberjs.com/beta/ember-data.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div id="counter"></div>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
</script>
</body>
</html>
I have the following index.html:
<!DOCTYPE html>
<html>
<body>
<script type="text/x-handlebars" id="index">
<ul>
{{#each todo in todos}}
<li>{{todo}}</li>
{{/each}}
</ul>
<button {{action 'generate'}}/>Generate a to-do</buton>
</script>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.6.1.js"></script>
<script src="js/app.js"></script>
</body>
</html>
And app.js:
App = Ember.Application.create();
App.Router.map(function() {});
App.IndexRoute = Ember.Route.extend({
model: function() {
return {todos: ['To-do 1', 'To-do 2']};
},
});
// This is a function I cannot change, because I don't own it.
// So I'm forced to get the updated model as the result of this.
// Here is some dummy-but-working implementation, for simulation purpose:
function generate(todolist) {
var n = todolist.todos.length + 1;
todolist.todos.push("To-do " + n);
return todolist;
}
App.IndexController = Ember.ObjectController.extend({
actions: {
generate: function() {
var oldToDoList = this.get('model');
var newToDoList = generate(oldToDoList);
this.set('model', newToDoList);
console.log(this.get('model').todos);
},
},
});
When I click on the generate button, I effectively see the growing to-dos array in console, but UI doesn't update.
Shouldn't #each content update automatically when completely replacing controller's model, or am I missing something?
your generate method doesn't actually generate a new array, so Ember won't notice that you've changed the property (because it's a reference to the same array). In your particular instance you should just use pushObject and Ember will know you're modifying the same array.
function generate(todolist) {
var n = todolist.todos.length + 1;
todolist.todos.pushObject("To-do " + n);
return todolist;
}
I'm trying to implment this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <base href="http://<?=$_SERVER['HTTP_HOST'];?>/" /> </head> </html> <body> <script language="javascript" type="text/javascript" src="http://www.google.com/jsapi"></script> <script type='text/javascript'> google.load('visualization', '1', { 'packages': ['geochart'] }); var dataRows; var mapOptions = { colors: ['#FF6F28', '#FFD7C4'], backgroundColor: {
stroke: '#ffffff',
strokeWidth: 0,
fill: '#ffffff' }, width: 500, height: 312, region: 'US', resolution: 'provinces' }; dataRows = [['UT',0],['Texas',1],['California',2],['New York',3]];
function initGlobalMap() { var mapData = new google.visualization.DataTable(); mapData.addColumn('string', 'Region'); mapData.addColumn('number', 'ID'); mapData.addRows(dataRows); var geochart = new google.visualization.GeoChart(document.getElementById('chart_geo2')); google.visualization.events.addListener(geochart, 'select', function () {
var selection = geochart.getSelection();
var id = mapData.getValue(selection[0].row, 1);
window.location = '/uploadedFiles/Code/GoogleGeoChartApi.aspx?id=' + id; }); geochart.draw(mapData, mapOptions); } google.setOnLoadCallback(initGlobalMap); </script> <div id='chart_geo2'></div> </body>
With firefox 10, doesn't works tooltips.
The problem is base tag, if I remove base tag it works fine.
But i need the base tag.
Any solution?
Place the chart into iframe without base tag.
I have the following html and js code snippets. Basically, I'm trying out Ember's select element. The problem is that I can't detect when the select element is ready to access.
HTML:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href='lib/uniform/css/uniform.default.css' rel='stylesheet'/>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="../lib/ember.min.js"></script>
<script type="text/javascript" src='lib/uniform/jquery.uniform.js'></script>
<script type="text/javascript" src="Form.js"></script>
</head>
<body>
<script type="text/x-handlebars">
</script>
<script type="text/x-handlebars">
{{#view contentBinding="FormExample.selectValues" valueBinding="type" tagName="select"}}
{{#each content}}
<option {{bindAttr value="fullName"}}>{{fullName}}</option>
{{/each}}
{{/view}}
</script>
</body>
</html>
JS:
FormExample = Ember.Application.create({
ready: function()
{
this._super();
// $("select").uniform(); // doesn't work
$(document).ready( function(){
console.log( $("select") );
//$("select").uniform(); // doesn't work
});
}
});
FormExample.Person = Ember.Object.extend({
id: null,
firstName: null,
lastName: null,
fullName: function()
{
return this.get('firstName') + " " + this.get('lastName');
}.property('firstName','lastName').cacheable()
})
FormExample.selectValues = Ember.ArrayController.create({
content: [
FormExample.Person.create({id:1, firstName: 'a', lastName:'a'}),
FormExample.Person.create({id:2, firstName: 'b', lastName:'b'}),
FormExample.Person.create({id:3, firstName: 'c', lastName:'c'})
],
// test for auto binding
add: function()
{
this.pushObject( FormExample.Person.create({id:4, firstName: 'd', lastName: 'd'}) );
}
});
Output: []
I found it..
Changes to HTML:
instead of using view and create option manually, use the following code
{{view FormExample.select
contentBinding="FormExample.selectOptions"
selectionBinding="FormExample.selectedOption.person"
optionLabelPath="content.fullName"
optionValuePath="content.id"}}
Changes to JS:
FormExample.select = Ember.Select.extend({
didInsertElement: function()
{
$("select").uniform();
}
});