Twitter Typeahead remote - typeahead

I am trying to use Twitter typeahead but I am facing a problem. I don't know how typeahead passes the string to the server. Is it through a GET parameter? If so, what is the name of the parameter?

Easiest through a GET parameter, you can choose whatever parameter you want.
In JS:
$('#search').typeahead({
name: 'Search',
remote: '/search.php?query=%QUERY' // you can change anything but %QUERY, it's Typeahead default for the string to pass to backend
});
In PHP (or whatever backend you have):
$query = $_GET['query'];
Hope you get the basic idea.

You might want to consider something like this, it is a very basic remote datasource example. The get parameter in this example is 'q'
// Get your data source
var dataSource = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: 'path/to/your/url/json/datasource/?q=%QUERYSTRING',
wildcard: '%QUERYSTRING'
}
});
// initialize your element
var $typehead = $('#form input').typeahead(null, {
source: dataSource
});
// fire a select event, what you want once a user has selected an item
$typehead.on('typeahead:select', function(obj, datum, name) {
//your code here
});
////////////////////////////////////
# in python (django) we get a query string using the request object passed through a view like this
query = request.GET.get('q') or ""
//the caveat [or ""] is just to prevent null exceptions
///////////////////////////////////
# using php
$query = ($_GET['q']) ? $_GET['q'] : "";

Related

APEX row selector part 2

This is a follow on to "APEX row selector" posted 5 days ago.
The problem was collecting multiple values from an interactive grid. From the excellent links to post supplied I was able to achieve this. However, the next part of the project is to open an edit dialog page and update multiple values.
I added this code to the attribute of the interactive grid:
function (config)
{
var $ = apex.jQuery,
toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(),
toolbarGroup = toolbarData.toolbarFind("actions3");
toolbarGroup.controls.push(
{
type: "BUTTON",
action: "updateCar",
label: "Edit Selected Cars",
hot: true,
});
config.toolbarData = toolbarData;
config.initActions = function (actions)
{
// Defining the action for activate button
actions.add(
{
name: "updateCar",
label: "Edit Selected Cars",
action: updateCar
});
}
function updateCar(event, focusElement)
{
var i, records, model, record,
view = apex.region("ig_car").widget().interactiveGrid("getCurrentView");
var vid = "";
model = view.model;
records = view.getSelectedRecords();
if (records.length > 0)
{
for (i = 0; i < records.length; i++)
{
record = records[i];
alert("Under Development " + record[1]);
vid = vid + record[1] + "||";
apex.item("P18_CAR").setValue(vid);
// need to open next page here and pass parameters
}
}
}
return config;
}
I need to know how to open a form and have the parameter values available to pass to an oracle update script.
Thank you for any help you can provide. I did find some posts but I really need a good example. I have tried everything to no avail.
There are various ways you could do this. Here's one way, perhaps someone else will offer a more efficient option.
The JavaScript options for navigation in APEX are documented here:
https://docs.oracle.com/en/database/oracle/application-express/19.1/aexjs/apex.navigation.html
Since you're trying to open a separate page, you probably want to use apex.navigation.dialog, which is what APEX automatically uses when opening modal pages from reports, buttons, etc.
However, as noted in the doc, the URL for the navigation must be generated server-side for security purposes. You need a dynamic URL (one not known when the page renders), so you'll need a workaround to generate it. Once you have the URL, navigating to it is easy. So how do you get the URL? Ajax.
Create an Ajax process to generate the URL
Under the processing tab of the report/grid page, right-click Ajax Callback and select Create Process.
Set Name to GET_FORM_URL.
Set PL/SQL code to the following
code:
declare
l_url varchar2(512);
begin
l_url := apex_page.get_url(
p_application => :APP_ID,
p_page => 3,
p_items => 'P3_ITEM_NAME',
p_values => apex_application.g_x01
);
apex_json.open_object();
apex_json.write('url', l_url);
apex_json.close_object();
end;
Note that I'm using apex_item.get_url to get the URL, this is an alternative to apex_util.prepare_url. I'm also using apex_json to emit JSON for the response to the client.
Also, the reference to apex_application.g_x01 is important, as this will contain the selected values from the calling page. You'll see how this was set in the next step.
Open the URL with JavaScript
Enter the following code in the Function and Global Variable Declaration attribute of the calling page:
function openFormPage(ids) {
apex.server.process(
'GET_FORM_URL',
{
x01: ids.join(':')
},
{
success: function (data) {
var funcBody = data.url.replace(/^"javascript:/, '').replace(/\"$/,'');
new Function(funcBody).call(window);
},
error: function (jqXHR, textStatus, errorThrown) {
console.error(errorThrown);
// handle error
}
}
);
}
In this case, I'm using apex.server.process to call the server-side PL/SQL process. Note that I'm passing the value of ids.join(':') to x01. That value will become accessible in the PL/SQL code as apex_application.g_x01. You can use additional items, or you can pass a colon-delimited string of values to just one item (as I'm doing).
The URL that's returned to the client will not be a standard URL, it will be a JavaScript snippet that includes the URL. You'll need to remove the leading and trailing parts and use what's left to generate a dynamic function in JavaScript.
This is generally frowned upon, but I believe it's safe enough in this context since I know I can trust that the response from the process call is not malicious JavaScript code.
Add a security check!!!
Because you're creating a dynamic way to generate URLs to open page 3 (or whatever page you're targeting), you need to ensure that the modal page is protected. On that page, create a Before Header process that validates the value of P3_ITEM_NAME. If the user isn't supposed to be able to access those values, then throw an exception.

Meteor subscriptions using deps

I'm trying to implement a searching feature in a Meteor application that re-subscribes/publishes a collection on every search, so there is only the exact Collection necessary in the client. I'm creating a reactive variable searchString, then changing it to the text in the search box on every search, then splitting the string into tags:
// Client
var searchString = "";
var searchStringDep = new Deps.Dependency;
var getSearchString = function(){
searchStringDep.depend();
return searchString;
}
var handle = Deps.autorun(function(){
var tags = getSearchString().split(" ");
tags = _.map(tags, function(tag){
return tag.replace(/[^\w]/g, "");
}).filter(function(t){
return t.toLowerCase();
});
Meteor.subscribe('results', tags);
});
Template.library.events({
'submit form': function(ev){
ev.preventDefault();
searchString = ev.target.search.value;
searchStringDep.changed();
}
})
Then, publishing a new Collection on the server, based on the tags:
// Server
Meteor.publish('results', function(tags){
regTags = _.map(tags, function(tag) { return new RegExp(tag)});
return Samples.find({tags: {$in: regTags}})
});
So I'm trying to match on regexes, but am having a weird issue where the subscription only changes when I add another tag, but changing existing tags fails.
So if the first searchString was tag1 and the second tag1 tag2, it works fine.
But if the first is tag1 and the second is tag2, the Collection doesn't update.
Any help is appreciated...I'm a beginner to Meteor, so if there is a better way to do what I'm trying to do, all suggestions are welcome. Thanks so much
'change #search': function(){
Meteor.subscribe('sampleResults', $('#search').val()); // or if you want on submit it's the same idea
}
and publish like
Meteor.publish('sampleResults, function(text){
return Samples.find({tags: {$regex: text}});
}
A few things:
1) Meteor has a very nice way of setting up reactive variables with the ReactiveVar component. I would suggest using that rather than creating another dependency for a variable.
2) The name that you are subscribing to: results is different than what is published on the server sampleResults and that can cause issues.
3) If you are on Meteor >= 0.9.1 you should be using Tracker and not Deps. You can use Deps if you want, but the new updated API is Tracker and is probably more stable. See the changelog for more details on that.
4) You don't have to set your Deps.autorun function equal to a variable. So you can have it as:
Tracker.autorun(function() {
// Code here
});

Passing a list in a url inside a TokenInput with Django, he only pass the last one

I am using jquery-tokeninput as an autocomplete to retrieve some objects in my app.
My js code to initialize the autocomplete is this:
function initialize_search(model, input_busca) {
var url = reverse('autocomplete.'+model) + "?tipos[]=almoxarifado&tipos[]=estoque";
var data = $(input_busca).data('tokeninput');
$(input_busca).tokenInput(url, {
hintText: 'Start to type',
preventDuplicates: true,
queryParam: 'name',
noResultsText: 'No results',
searchingText: 'Search',
prePopulate: data
});
}
All I want is to receive the parameter 'tipos[]' in my view, like this:
types = request.GET.getlist('tipos[]')
And receive this:
[u'almoxarifado', u'estoque']
But when i do this, he only gives me the last one and not all the list, in this case:
[u'estoque']
This is how I call the autocomplete function inside the js:
inicializa_busca('endereco', $("#id_enderecos"));
You must be aware that, ajax is to pass small data, check the size of this list, maybe is better an full post submission!

How to set mapping on Ember-Data

I'm beginning to work with ember-data and I have a problem to map the data
Here an exemple of my code ( i've place a jsonTest as an exemple of the data received from de backend , I don't work on the backend and I cannot modify the response from the server )
Clive = Ember.Application.create();
// MODEL
Clive.Deadline = DS.Model.extend({
title : DS.attr('string'),
});
jsonTest = '{"items":[{"id":93,"title":"title","date":"14-11-2012"}]}';
// Adapter
Clive.adapter = DS.Adapter.create({
findAll : function(store,type){
var self = this;
self.didFindAll(store, type, jsonTest);
}
});
Clive.store = DS.Store.create({
revision: 11,
adapter: 'Clive.adapter'
});
Clive.deadlineList = Clive.Deadline.find().get('items');
When I run the code I have this error :
Uncaught Error: assertion failed: Your server returned a hash with the key 0 but you have no mapping for it
Here a jsfidlle with the exemple : http://jsfiddle.net/gilles/6D5BC/
The "server returned a hash with key 0" thing is because didFindAll() expects a javascript object not a string. So trying again with:
json = {"items":[{"id":93,"title":"title","date":"14-11-2012"}]};
// -> "Your server returned a hash with the key items but you have no mapping for it"
Next step is to transform the object to have naming conventions that ember is expecting. Since your model is named Deadline, use the following:
jsonTransformed = '{"deadlines": [{"id":93,"title":"title 1","date":"14-11-2012"},{"id":94,"title":"title 2","date":"14-11-2012"}]}';
I've added a second record, but you get the idea. Finally you need to change how the Clive.deadlineList variable is being set: Clive.Deadline.find() returns a collection of Clive.Deadline models, so just:
Clive.deadlineList = Clive.Deadline.find()
console.log(Clive.deadlineList.getEach('title'));
// -> title1, title2
Here is an updated jsfiddle with working example:
http://jsfiddle.net/mgrassotti/6D5BC/9/
Another simple solution is to use the following Gem. It will just make your life easier. You wont need to generate or structure the json manually.
gem 'active_model_serializers'
For more help, have a look on this free screencast

Django - jquery : populate combobox based on selection of another combobox

I am quite new to Django and jquery stuff. I am trying to populate a comboBox (ChoiceField in Django) based ont the choice selected in another comboBox (without reloading the page).
I can't find any simple example of such a basic application of ajax.
For now I'm call the following ajax function when I select an item from the first dropdown list.
function get_asset_from_type(){
var type_asset = $("#id_type").val();
var data = {type_asset:type_asset};
var args = {type:"POST", url:"/asset/etatType/", data:data};
$.ajax(args);
alert(type_asset);
return false;
};
It alerts the right type but gives a 403 error on the given url. Weird thing is this url works the first time I load the page. I don't understand what's going on..
EDIT:
403 error seems to be gone, remains the initial question :)
I think you're running up against a CSRF problem. As Django by default blocks POST requests that do not have a CSRF Token with a 403. There are a couple ways to deal with this in JS. One is to pull the value out of the cookie, the code to do that can be found here: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
or you can do it by passing the CSRF_TOKEN in with the javascript script tag:
<script src='myjavascript.js?CSRF_TOKEN={{ csrf_token }}'></script>
Note that it's using a double braket, instead of {%%}. This gets the value of the token, instead of the form input.
function getOptionsFromScriptSrc() {
// Get last script tag in parsed DOM.
// Due to the way html pages are parsed,
// the last one is always the one being loaded.
var options = {}
var js_src = $('script').last().attr('src');
if(js_src.match(/\?/)) {
var options_list = js_src.split('?')[1].split('&');
for(var i = 0; i < options_list.length; i++) {
var tmp = options_list[i].split('=');
options[$.trim(tmp[0])] = $.trim(tmp[1]);
}
}
return options;
}
function get_asset_from_type(){
var options = getOptionsFromScriptSrc();
var type_asset = $("#id_type").val();
var data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};
var args = {type:"POST", url:"/asset/etatType/", data:data};
$.ajax(args);
alert(type_asset);
return false;
};
I haven't, of course, tested this code, but I have used this method before and it works pretty well.
To the main problem of populating a select box, you need to specify a callback for your ajax post, and then deal with the data returned from your server:
function get_asset_from_type(){
var options = getOptionsFromScriptSrc();
var type_asset = $("#id_type").val();
var post_data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};
$.post('/asset/etatType/', post_data, function(data){
// Assuming server is going to respond with the html of the options, eg: <option value="1">One</option><option value="2">Two</option>...
$('#id_ofmyselectbox').append(data);
});
};