Bootstrap 3 typeahead.js - remote url attributes - typeahead

I'm trying to call my remote url with added attributes to the url.
For now I have this working:
$('#league').typeahead({
remote: '/typeahead/get_league?query=%QUERY',
limit: 10
});
Now I would like to do something like this:
$('#league').typeahead({
remote: function () {
var q = '/typeahead/get_league?query=%QUERY';
if ($('#sport').val())
q += "&sport=" + encodeURIComponent($('#sport').val());
return base_url + q;
},
limit: 10
});
I would like to add the GET attribute 'sport' to the URL so I can narrow down my query on the backend. I tried the code above but I get a JS error.
The previous version of Bootstrap Typeahead allowed this type of setup. It was very useful as I could update the remote URL every time a key get hit.
Any idea how to make that work for this version ?

remote is exclusively for typeahead.js (not part of Bootstrap). But you are not using the remote correctly, it can be either a string or an object, not a function.
When you need to change the request URL, you can use replace:
$('#league').typeahead({
remote: {
url: '/typeahead/get_league?query=%QUERY',
replace: function () {
var q = '/typeahead/get_league?query=%QUERY';
if ($('#sport').val()) {
q += "&sport=" + encodeURIComponent($('#sport').val());
}
return base_url + q;
}
},
limit: 10
});
Check the docs here
Hope it helps.

Hieu Nguyen solution will not work for %QUERY wildcards.
According to Bloodhound.js documentation,
replace – .... If set, no wildcard substitution will be performed on url.
Bloodhound docs on github
So %QUERY will be passed as string without being replaced by text entered from user.
So you should put typeahead value into your url :
$('#league').typeahead({
remote: {
url: '/typeahead/get_league?query=%QUERY',
replace: function () {
var q = '/typeahead/get_league?query=' + $('#league').val();
if ($('#sport').val()) {
q += "&sport=" + encodeURIComponent($('#sport').val());
}
return base_url + q;
}
},
limit: 10
});

Here is a complete example with the QUERY result as well passed. Note that when the remote method is used variable substitution no longer functions. Thanks to hieu-nguyen for the majority of it!
jQuery('#city').typeahead({
name: "cities",
remote: {
url: current_web_root + '?action=ajax|getcities&query=%QUERY',
replace: function () {
var q = current_web_root + '?action=ajax|getcities&query=' + jQuery('#city').val();
if (jQuery('#state').val()) {
q += "&state=" + encodeURIComponent(jQuery('#state').val());
}
return q;
}
},
cache: false
});
jQuery("#state").change(function (e) {
jQuery('#city').val("");
});

Related

Angular HttpClient get request - how to get the text data sent?

I have an Angular/Ionic app that communicates with a Django backend. I am using this.http.get() to communicate with this server (on Heroku) and the Django server should be sending the text "OK". Instead, I am either (dependent on specific usage of this.http.get()) getting an error where the statusText is the text I want, or something like Object { _isScalar: false, source: {…}, operator: {…} }
My Django code is simple:
def make(request, otherParams):
...
return HttpResponse("OK")
I know that the get() has made it to the server, because the server runs certain things when the corresponding function is called.
How do I, from the Angular frontend, detect if the Django script has sent the "OK" or not?
(The error is not due to any of various CORS policies, I have installed django-cors-headers)
EDIT:
if it's relevant, I'm on a Windows PC, testing on localhost/Firefox Nightly with Ionic 5 and Angular 9.
Here is my frontend code, cutting the irrelevant bits. The way I've made my GET request is not consistent, having tried many. This one is suggested in the below post, and still fails.
import { Component, OnInit } from '#angular/core';
import { AlertController } from '#ionic/angular';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-submit',
templateUrl: './submit.page.html',
styleUrls: ['./submit.page.scss'],
})
export class SubmitPage implements OnInit {
constructor(public alertController: AlertController, private http: HttpClient) { }
ngOnInit() {
}
//irrelevant variable-getting
save() {
console.log(this.list);
if (this.title == null || this.title == "") {
this.presentAlert("Uncompleted fields", "Please complete the Title field!");
}
else if (this.sub == null || this.sub == "") {
this.presentAlert("Uncompleted fields", "Please complete the Subtitle field!");
}
else if (this.content == null || this.content == "") {
this.presentAlert("Uncompleted fields", "Please complete the Content field!");
} else {
try {
if (this.list.length == 0) {
console.log(this.list);
throw "empty list";
}
//more irrelevance
}
catch{ this.presentAlert("Uncompleted fields", "Please complete the list!"); }
if (temp2) {
this.makePost();
}
}
}
makePost() {
var temp = (<root url> + encodeURIComponent(this.title) + `/` + (this.posterID).toString() + '/' + encodeURIComponent(this.sub) + '/' + encodeURIComponent(this.content) + '/' + this.happy.toString() + '/' + this.angry.toString() + `/` + this.stressy.toString() + `/` + this.energy.toString() + '/' + this.worry.toString());
console.log(temp);
this.http.get(temp).toPromise()
.then(r => console.log('response', r)).catch(error => console.error(error));
}
}
Assuming you are using the HttpClient to invoke your GET request, you need to actually do something with this.http.get().
Try doing something like this instead:
If you can use async/await
const response = await this.http.get(<url>);
If you cannot use async/await
this.http.get(<url>).then(r => console.log('response', r) ).catch( error => console.error(error) );
If you just do:
const response = this.http.get(<url>);
console.log(response);
You are effectively logging the Promise and not the resolved Promise that holds the data you're after.
If you can show more code from your Angular app, it would help determine if this is your problem or not. For basic troubleshooting, I would first validate that your GET request (in your Python app) works by itself. Using Postman, you can test this (along with methods). If you GET request works fine, then the issue is more than likely something in you angular app which I described how to fix above.
It turned out that my Angular script was trying to interpret the response as JSON, not the plaintext I wanted. Using the code from the answer by mwilson and adding { responseType: 'text' } into the get() parameters, the console now logs the response successfully.
My The code snippet now looks like this: this.http.get(url, { responseType:'text'}).toPromise().then(r => console.log(r)).catch(error => console.error(error));
BTW feel free to point out any improvements/optimizations to the above code if you feel it needs it.

Flutter Dart: RegEx to extract URLs from a String

This is my string:
window.urlVideo = 'https://node34.vidstreamcdn.com/hls/5d59908aea5aa101a054dec2a1cd3aff/5d59908aea5aa101a054dec2a1cd3aff.playlist.m3u8';
var playerInstance = jwplayer("myVideo");
var countplayer = 1;
var countcheck = 0;
playerInstance.setup({
sources: [{
"file": urlVideo
}],
tracks: [{
file: "https://cache.cdnfile.info/images/13f9ddcaf2d83d846056ec44b0f1366d/12.vtt",
kind: "thumbnails"
}],
image: "https://cache.cdnfile.info/images/13f9ddcaf2d83d846056ec44b0f1366d/12_cover.jpg",
});
function changeLink() {
window.location = "//vidstreaming.io/load.php?id=MTM0OTgz&title=Mairimashita%21+Iruma-kun+Episode+12";
}
window.shouldChangeLink = function () {
window.location = "//vidstreaming.io/load.php?id=MTM0OTgz&title=Mairimashita%21+Iruma-kun+Episode+12";
}
I am using flutter dart.
How can I get window.urlVideo URL link and image URL link and .vtt file link?
Or
How can I get a list of URLs from a String?
I tried finding a way with and without using RegEx but I couldn't.
Any help is apreciated
This may not be the complete regex, but this worked for me for randomly picked links:
void main() {
final text = """My website url: https://blasanka.github.io/
Google search using: www.google.com, social media is facebook.com, http://example.com/method?param=flutter
stackoverflow.com is my greatest website. DartPad share: https://github.com/dart-lang/dart-pad/wiki/Sharing-Guide see this example and edit it here https://dartpad.dev/3d547fa15849f9794b7dbb8627499b00""";
RegExp exp = new RegExp(r'(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\w/\-?=%.]+');
Iterable<RegExpMatch> matches = exp.allMatches(text);
matches.forEach((match) {
print(text.substring(match.start, match.end));
});
}
Result:
https://blasanka.github.io/
www.google.com
facebook.com
http://example.com/method?param=flutter
stackoverflow.com
https://github.com/dart-lang/dart-pad/wiki/Sharing-Guide
https://dartpad.dev/3d547fa15849f9794b7dbb8627499b00
Play with it here: https://dartpad.dev/3d547fa15849f9794b7dbb8627499b00
Try this,
final urlRegExp = new RegExp(
r"((https?:www\.)|(https?:\/\/)|(www\.))[-a-zA-Z0-9#:%._\+~#=]{1,256}\.[a-zA-Z0-9]{1,6}(\/[-a-zA-Z0-9()#:%_\+.~#?&\/=]*)?");
final urlMatches = urlRegExp.allMatches(text);
List<String> urls = urlMatches.map(
(urlMatch) => text.substring(urlMatch.start, urlMatch.end))
.toList();
urls.forEach((x) => print(x));
Getting just the https? and ftp url's that are in quotes is this :
r"([\"'])\s*((?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?#)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-zA-Z0-9\u00a1-\uffff]+-?)*[a-zA-Z0-9\u00a1-\uffff]+)(?:\.(?:[a-zA-Z0-9\u00a1-\uffff]+-?)*[a-zA-Z0-9\u00a1-\uffff]+)*(?:\.(?:[a-zA-Z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/(?:(?!\1|\s)[\S\s])*)?)\s*\1"
Where the Url is captured in group 2.
https://regex101.com/r/UPmLBl/1
Much safer to use a library like linkify instead of rolling your own regex.
/// Attempts to extract link from a string.
///
/// If no link is found, then return null.
String extractLink(String input) {
var elements = linkify(input,
options: LinkifyOptions(
humanize: false,
));
for (var e in elements) {
if (e is LinkableElement) {
return e.url;
}
}
return null;
}

Sharepoint: How to show AppendOnlyHistory on a display template in a cross-publishing scenario

The overarching requirement I am trying to implement is to show comments (made on a list, item by item basis).
I added the feature on the authoring side by enabling versioning on the list and adding a text field with the option "Append Changes to Existing Text" set to true.
This indeed allows me to comment on items and displays them chronologically, but on the authoring side only.
The issue is that the UI part will be done on another site collection and I can't find a straightforward way to get all comments there.
So far, every resource I have found points to
<SharePoint:AppendOnlyHistory runat="server" FieldName="YourCommentsFieldName" ControlMode="Display"/>
The thing is, I can't (don't know how to) use this inside a display template.
So far, I am getting all my data using the REST API, via
var siteUrl=_spPageContextInfo.webAbsoluteUrl.replace("publishing","authoring");
$.ajax({
url: siteUrl + "/_api/web/lists/getbytitle('" + listname + "')/items(" + id + ")",
type: 'GET',
async:false,
headers: {"accept": "application/json;odata=verbose",},
dataType: 'JSON',
success: function(json) {
console.log(json);
//var obj = $.parseJSON(JSON.stringify(json.d.results));
//alert(obj);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error :"+XMLHttpRequest.responseText);
}
});
What this gives me is the latest comment only. I need a simple way to get a hold of the entire thread.
I ended up using javascript object model to get them like so:
function GetComments(listname, itemId) {
var siteUrl = _spPageContextInfo.webAbsoluteUrl.replace("publishing", "authoring");
if ($(".comments-history").length) {
$().SPServices({
operation: "GetVersionCollection",
async: false,
webURL: siteUrl,
strlistID: listname,
strlistItemID: itemId,
strFieldName: "Comments",
completefunc: function (xData, Status) {
$(xData.responseText).find("Version").each(function (data, i) {
var xmlComment = $(this)[0].outerHTML;
var arr = xmlComment.split(/comments|modified|editor/g);
var comment = arr[1].trim().substring(2, arr[1].length-2);
var dateSt = Date.parse((arr[2].substring(1, arr[2].length)).replace('/"', ''));
var user = getUsername(arr[3]);
var st = "<div class='comment-item'><div class='comment-user'>" + user + "(" + FormatDate(dateSt) + ")</div>";
st += "<div class='comment-text'>" + comment + "</div></div>";
$(".comments-history").append(st);
});
}
});
}
}
the parsing could be better, but this is just an initial working idea

Firefox Add-On to redirect urls based on wildcards

I am looking at writing a firefox extension which will take a url, apply a regex to it to produce a second url.
I then need to have firefox redirect to this new URL without the user having to do anyything.
Does anyone have any examples I could use to learn how to do this. I've used the firefox tutorials to get as far as this..
// Import the page-mod API
var pageMod = require("sdk/page-mod");
// Import the self API
var self = require("sdk/self");
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
pageMod.PageMod({
include: "*",
contentScript: 'window.alert("Matched Page");'
})
So my question is, how would I do this.
For instance, if a user types in http://www.mywebsite/data/7287232/wherever, I'd like them to be redirected to http://www.anotherwebsite/folder/7287232
Well.. answering to the initial head line:
https://addons.mozilla.org/en-US/firefox/addon/redirector
Or is that actually you? #ScaryAardvark ?
that example is very complex, the main purpose of that traceable channel example is to get a COPY of the sourcecode that gets loaded at that uri.
const { Ci, Cu, Cc, Cr } = require('chrome'); //const {interfaces: Ci, utils: Cu, classes: Cc, results: Cr } = Components;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/devtools/Console.jsm');
var observers = {
'http-on-modify-request': {
observe: function (aSubject, aTopic, aData) {
console.info('http-on-modify-request: aSubject = ' + aSubject + ' | aTopic = ' + aTopic + ' | aData = ' + aData);
var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
var requestUrl = httpChannel.URI.spec
if (/\.org/.test(requestUrl) || /http\:\/\/www\.mywebsite\/data\/7287232\/.+/.test(requestUrl)) {
httpChannel.redirectTo(Services.io.newURI('http://www.anotherwebsite/folder/7287232', null, null));
}
},
reg: function () {
Services.obs.addObserver(observers['http-on-modify-request'], 'http-on-modify-request', false);
},
unreg: function () {
Services.obs.removeObserver(observers['http-on-modify-request'], 'http-on-modify-request');
}
}
};
to register the observer on startup of addon run this:
//register all observers
for (var o in observers) {
observers[o].reg();
}
and on shutdown of addon unregister all observers like this:
//unregister all observers
for (var o in observers) {
observers[o].unreg();
}

Refresh a webpage just once after 5 seconds

I'm looking for a JavaScript solution (or whatever else) that will refresh a webpage ONLY once, after 5 seconds it has been opened. Is this possible without being stuck in a refresh loop?
try this:
setTimeout(function ()
{
if (self.name != '_refreshed_'){
self.name = '_refreshed_';
self.location.reload(true);
} else {
self.name = '';
}
}, 5000);
You could do this in many different ways, but I think the easiest would be to add a query string to the url after the refresh, allowing us to tell if the refresh has already occurred:
//Function to get query string value. Source: http://www.bloggingdeveloper.com/post/JavaScript-QueryString-ParseGet-QueryString-with-Client-Side-JavaScript.aspx
function getQuerystring(key, default_){
if (default_==null) default_="";
key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var qs = regex.exec(window.location.href);
if(qs == null)
return default_;
else
return qs[1];
}
//check if our query string is already set:
if(getQuerystring(r) !== 1){
setTimeout(function(){window.location.href = window.location.href + '?r=1'},5000)
}
If there is the possibility that a query string is already present, you will have to account for that and change the '?' to an '&'.
Sure, if you don't mind using jquery you can do it via an ajax call after waiting 5 seconds. Just throwing you some sample code:
How to wait 5 seconds with jQuery?
$(document).ready(function() {
// Get data
$.ajax({
url : '/tommyStockExchange/Data',
dataType : 'html',
data : {
'format' : 'H',
'type' : 'E'
},
success : function(data) {
$("#executions").html(data);
},
statusCode : {
404 : function() {
alert('executions url 404 :(');
}
}
});
});
Make it redirect to the same page with a different #hash and in JS only register the redirect if the hash isn't set.
You just need to pass some sort of data between page loads. This can be done in a multitude of ways — use a cookie, a URL query parameter, or something on the server side. Query parameter example:
if (!location.search.match(/(\?|&|^)stopRefreshing(=|&|$)/))
{
setTimeout(function ()
{
var search = location.search;
location.search = search ? search + '&stopRefreshing' : 'stopRefreshing';
}, 5000);
}
Demo: http://jsbin.com/ofawuz/edit