I'm using meteor to build a web app that shows stock information. I currently have a input on the client side which takes in text. The input is hooked up to a Lookup API by Markit on Demand. This is the code:
Template.LookupTemplate.onRendered(function() {
this.$("#Lookup")
.focus()
.autocomplete({
source: function(request,response) {
$.ajax({
url: "http://dev.markitondemand.com/api/v2/Lookup/jsonp",
dataType: "jsonp",
data: {
input: request.term
},
success: function(data) {
response( $.map(data, function(item) {
return {
label: item.Name + " (" +item.Exchange+ ")",
value: item.Symbol
}
}));
},
minLength: 0,
select: function(event,ui ) {
console.log(ui.item);
}
});
}
});
}); //Closing tag of LoookupTemplate.onRendered
How do I capture the selection by the client? When the user starts typing a company name, the jquery autocomplete kicks in and gives the client a list of options to select from. Once the user selects it and hits "enter" (submits it), the page reloads to
http://localhost:3000/Overview?stockname=AAPL
How do I capture that input (AAPL in this case) and then pass it to another function that builds a chart for that particular stock?
--Router.js
Router.configure({
// This is the default layout/top-level template
layoutTemplate: 'layout'
});
Router.map(function() {
this.route('/', {
path: '/',
action: function() {
this.redirect('landingpage')
document.title = 'Cash'
}
});
// Route for the landing page when user is not logged in
this.route('landingpage', {
path: '/landingpage',
after: function() {
document.title = 'Cash'
}
});
// Route to our main app. Note that I use / path as I treat this as default behavior
this.route('/Overview', {
path: '/Overview',
after: function () {
document.title = 'Cash';
}
});
})
IronRouter only can read the param when you define them in the router. For the case of dynamically param created by the API, the best way is using javascript to read it. Please have a look at the solution in here
Related
Let's say I have 3 Taxons (Builders, States, Services). Is there a way to Filter "Edit Product Taxons" to list, when clicked, only "Services" Taxon in the dropdown? The spree view is edit_product.html.erb
Thanks
taxons.js
//= require solidus_admin/Sortable
Spree.ready(function() {
var productTemplate = HandlebarsTemplates['products/sortable'];
var productListTemplate = function(products) {
return _.map(products, productTemplate).join('') || "<h4>" + Spree.translations.no_results + "</h4>";
};
var saveSort = function(e) {
var item = e.item;
Spree.ajax({
url: Spree.routes.classifications_api,
method: 'PUT',
data: {
product_id: item.getAttribute('data-product-id'),
taxon_id: $('#taxon_id').val(),
position: e.newIndex
}
});
};
var formatTaxon = function(taxon) {
return Select2.util.escapeMarkup(taxon.pretty_name);
};
$('#taxon_id').select2({
dropdownCssClass: "taxon_select_box",
placeholder: Spree.translations.find_a_taxon,
ajax: {
url: Spree.routes.taxons_search,
params: {
"headers": {
"X-Spree-Token": Spree.api_key
}
},
data: function(term, page) {
return {
per_page: 50,
page: page,
q: {
name_cont: term
}
};
},
results: function(data) {
return {
results: data['taxons'],
more: data.current_page < data.pages
};
}
},
formatResult: formatTaxon,
formatSelection: formatTaxon
});
$('#taxon_id').on("change", function(e) {
Spree.ajax({
url: Spree.routes.taxon_products_api,
data: {
id: e.val,
simple: 1
},
success: function(data) {
$('#taxon_products').html(productListTemplate(data.products));
var el = document.querySelector('#taxon_products')
new Sortable(el, {
draggable: ".sort_item",
onEnd: saveSort
});
}
});
});
});
The above JS applies to Spree or Solidus e-commerce platforms.
Would like to be able to filter taxons to include name "Services".
To clarify:
Let's say I have "Builders, States and Services" taxonomies. In Admin Edit Product, all Taxons for builders, states, and services are listed in the dropdown list.
I would like to be able to filter which taxonomies get listed. In this case, I would like the dropdown list box to list only "Services" taxons.
**Would like to see this:**
Services -> Senior Care
Services -> Nurse
**Do not want this:**
Builders -> Wall
Builders-> Mason
Services -> Senior Care
Services -> Nurse
States -> Utah
States -> Texas
Managed to get this work by modifying taxon_autocomplete.js
I have been pretty much beginner at this part of javascript and I would appreciate any ideas how could be solved this problem.
I use requirejs to define my own modules where I also use backbone.js.
Let say I have the main module where I initialize my Backbone view which is rendered without any problem. Also, the click event where is calling method createSchemeForm creates the form correctly. The problem raises up in a situation when I call cancel method by click and the modules which are defined for Backbone view (e.g. "unicorn/sla/dom/helper"...) are undefined but when I called method createSchemeForm at the beginning the modules were executed without any problem.
Thank you in advance for any suggestions.
Backbone view
define("unicorn/sla/view/scheme", [
"unicorn/sla/dom/helper",
"unicorn/soy/utils",
"unicorn/sla/utils"
], function (DOMHelper, soyUtils, jsUtils) {
return Backbone.View.extend({
el: 'body',
inputData: {},
btnSaveScheme: 'btn-save-sla-scheme',
btnCancel: 'btn-cancel-sla-scheme',
btnCreate: 'btn-create-sla-scheme',
btnContainer: '#sla-scheme-buttons-container',
schemeContent: '#sla-scheme-content-section',
btnSpinner: '.button-spinner',
events: {
'click #btn-create-sla-scheme' : "createSchemeForm",
'click #btn-cancel-sla-scheme' : "cancel"
},
initialize: function(){
console.log("The scheme view is initialized...");
this.render();
},
createSchemeForm: function () {
this.spin();
DOMHelper.clearSchemeContent();
DOMHelper.clearButtonsContainer();
//Get button
$btnSave = soyUtils.getButton({isPrimary: 'true', id: this.btnSaveScheme, label: 'Save'});
$btnCancel = soyUtils.getButton({isPrimary: 'false', id: this.btnCancel, label: 'Cancel'});
//Append new created buttons
DOMHelper.addContent(this.btnContainer, AJS.format("{0}{1}", $btnSave, $btnCancel));
//Call service to get entry data for scheme creation form
AJS.$.ajax({
url: AJS.format('{0}={1}',AJS.I18n.getText('rest-url-project-scheme-input-data'), jsUtils.getProjectKey()) ,
type: "post",
async: false,
context: this,
global: false,
}).done(function (data) {
this.inputData = data;
$slaSchemeForm = soyUtils.getSchemeCreateForm({slaScheme : data, helpText: AJS.I18n.getText("sla-time-target-tooltip-text")});
DOMHelper.addContent(this.schemeContent, $slaSchemeForm);
jsUtils.scroll(this.schemeContent, 'slow');
}).fail(function () {
jsUtils.callFlag('error', AJS.I18n.getText("message-title-error"), AJS.I18n.getText("sla-error-load-scheme-input-data"));
}).always(function () {
this.stopSpin();
});
},
spin: function () {
AJS.$('.button-spinner').spin();
},
stopSpin: function () {
AJS.$('.button-spinner').spinStop();
},
cancel: function () {
jsUtils.clearButtonsContainer();
jsUtils.clearSchemeContent();
$btnCreateScheme = soyUtils.getButton({isPrimary: 'false', id: this.btnCreate, label: 'Create SLA Scheme'});
DOMHelper.addContent(this.btnContainer, $btnCreateScheme);
DOMHelper.addContent(this.schemeContent, soyUtils.getSchemesTable(new Array())); // TODO - get current data from server instead of empty array
}
});
});
Main module where is Backbone view initialize
define("unicorn/sla/project/batch", [
"unicorn/sla/utils",
"unicorn/sla/data/operations",
"unicorn/sla/data/validator",
"unicorn/sla/dom/helper",
"unicorn/sla/model/confirm/message",
"unicorn/sla/view/scheme",
"exports"
], function (jsUtils, operations, validator, DOMHelper, ConfirmMessage, SchemeView, exports) {
//Load project batch
exports.onReady = function () {
$schemeView = new SchemeView();
$schemeView.render();
}
});
AJS.$(function () {
AJS.$(document).ready(function () {
require("unicorn/sla/project/batch").onReady();
});
});
My JS below runs from my search bar and shows results in a same page DIV. I would like to edit this to take them to the page selected from the search bar maybe even using a separate JSON file, or not, either way.
$(function(){
var url = [
{ value: 'Home', data: 'http://google.com' },
{ value: 'Guide', data: 'http://google.com' },
{ value: 'Examples', data: 'ttp://google.com' },
{ value: 'Themes', data: 'http://google.com' },
{ value: 'Download', data: 'http://google.com' },
];
// setup autocomplete function pulling from currencies[] array
$('#autocomplete').autocomplete({
lookup: url,
onSelect: function (suggestion) {
var thehtml = '<strong>Page Name:</strong> ' + suggestion.value + ' <br> <strong>URL:</strong> ' + suggestion.data;
$('#outputcontent').html(thehtml);
}
});
});
You can use window.location.assign to load the URL as a new document.
// setup autocomplete function pulling from currencies[] array
$('#autocomplete').autocomplete({
lookup: url,
onSelect: function (suggestion) {
window.location.assign(suggestion.data);
}
});
Alternatively, you can use window.location.href = suggestion.data;
I'm not sure how to express this in code, as I can't seem to locate the problem, but my issue is that Backbone.history seems to be recording two items when a user clicks on a list item in my app.
This is not consistent.
My app has a 4 item navigation at the bottom that links to 4 main sections (the first one being home - routed to '/'). If I load up the app, go to one of the other navigation pages, then click the 'Home' button again and then click one of the navigation options I get a list of items to choose from. If I then choose one two entries are added - Firstly, for some reason, a reference to the home route with /# at the end and then the route for the item I clicked.
The end result is that 'back' then inexplicably takes me to the home page.
If it helps, my router looks like this...
var siansplanRouter = Backbone.Router.extend({
initialize: function () {
var that = this;
this.routesHit = 0;
//keep count of number of routes handled by your application
Backbone.history.on('route', function() { that.routesHit++; }, this);
window.SiansPlanApp.render();
window.SiansPlanApp.router = this;
},
routes: {
'': 'showHome',
'home': 'showHome',
'hub': 'showHome',
'samples': 'showJqmSamples',
'mealplanner': 'showCurrentMealPlanner',
'mealplanner/:planId': 'showMealPlanner',
'recipes': 'showRecipeSearch',
'recipes/:recipeId': 'showRecipe',
'settings': 'showSettings',
'versioninfo': 'showVersionInfo',
'*other': 'showHome'
},
routesHit: 0,
back: function() {
if(this.routesHit > 1) {
window.history.back();
} else {
//otherwise go to the home page. Use replaceState if available so
//the navigation doesn't create an extra history entry
this.navigate('/', { trigger: true, replace: true });
}
},
showHome: function () {
SiansPlanApp.renderHome();
},
showJqmSamples: function () {
SiansPlanApp.renderView(new SiansPlanApp.views.Hub.Samples());
},
showMealPlanner: function (planId) {
SiansPlanApp.renderView(new SiansPlanApp.views.Planner.MealPlanner({ id: planId }));
},
showCurrentMealPlanner: function () {
SiansPlanApp.renderView(new SiansPlanApp.views.Planner.MealPlanner({ current: true }));
},
showRecipeSearch: function () {
SiansPlanApp.renderView(new SiansPlanApp.views.Recipes.Search());
},
showRecipe: function (recipeId) {
SiansPlanApp.renderView(new SiansPlanApp.views.Recipes.Recipe({ id: recipeId }));
},
showSettings: function () {
SiansPlanApp.renderView(new SiansPlanApp.views.System.Settings());
},
showVersionInfo: function () {
SiansPlanApp.renderView(new SiansPlanApp.views.About.VersionInfo.ListView());
}
});
I've got some basic elements in a kick off file too here...
define(['router', 'regions/r-app', 'jquery', 'domReady'],
function (SiansPlanRouter, AppRegion) {
var run = function () {
// Global click event handler to pass through links to navigate
$(document).on("click", "a:not([data-bypass])", function (e) {
var href = { prop: $(this).prop("href"), attr: $(this).attr("href") };
var root = location.protocol + "//" + location.host + SiansPlanApp.root;
if (href.prop && href.prop.slice(0, root.length) === root) {
e.preventDefault();
Backbone.history.navigate(href.attr, true);
}
});
$.ajaxPrefilter(function (options, originalOptions, jqXhr) {
//options.url = '/api' + options.url;
});
// Create the global namespace region object.
window.SiansPlanApp = new AppRegion();
// Adds the authorization header to all of the API requests.
$(document).ajaxSend(function (e, xhr, options) {
xhr.setRequestHeader("Authorization", 'SiansPlan ' + SiansPlanApp.cookies.getSessionData());
});
// Load up session data if any is present yet - this can't happen until the XHR headers are set up.
SiansPlanApp.session.loadSession();
// Instantiate the router.
window.SiansPlanApp.router = new SiansPlanRouter();
// Boot up the app:
Backbone.history.start();
};
return {
run: run
};
});
I have a form working with JQuery Autocomplete and it works fairly well. Now I need another element to force a user to select a valid choice in the autocomplete input. The can type whatever they want and everything is filtered by autocomplete. But they have to select something from the served list.
If they don't the inputfield must get blanked. Tried out a few things with change and select to no avail. This is the code of my autocomplete. I saw some examples operation with data instead of source. This seems to make a big difference
$(function () {
$("#sp_name").autocomplete({
minLength: 2,
delay: 300,
source: function (request, response) {
$.ajax({
url: "./Search/",
dataType: "json",
data: {
term: request.term,
zoekterm: $("#al").html()
},
success: function (data) {
response($.map(data, function (item) {
return {
label: item.naam,
value: item.naam
}
}));
}
});
}
})
});
Try this:
I am using a local list here, but you can achieve this via json data source too.
Just add a change event. The only problem this can have is that if user does not click on
the suggestion, it will turn blank (even if user is entering the same text as suggestion).
It will be mandatory for user to click on the suggestion.
var list = ["c", "c++", "c#","Basic","Mongo"];
$('#auto').autocomplete({
source: list,
select: function (event, ui) {
$(this).val(ui.item ? ui.item : " ");},
change: function (event, ui) {
if (!ui.item) {
this.value = '';}
//else { Return your label here }
}
});
JsFidle for it: http://jsfiddle.net/sarcastic/7KdZP/112/
In your case, Change function would be something like this:
change: function (event, ui)
{
if (!ui.label) { this.value = ''; }
}