How to add a image inside var quotes - var

<body>
<div id="quote"></div>
<div id="image"></div>
<script>
(function() {
var quotes = [
{
text: "test1",
}]
$('image').html("<img src='https://image.com/image.png'>")
},
{
text: "test2",
}
];
var quote = quotes[Math.floor(Math.random() * quotes.length)];
document.getElementById("quote").innerHTML =
'<span>' + quote.text + '</span>';
})();
</script>
</body>
Updated
This is my code and i want to add an image here. I tried adding $('image').html("https://image.com/image.png'>") but it didn't work

You can add link to image or byteArray:
<script>
(function() {
var quotes = [
{
text: "Sample text",
byte: fileInputInByteArray,
imageSrc: "http://images/example.jpg"
}
</script>

Related

Chrome Extension User Upload Image

I'm wondering if it's possible to allow the user to upload an image to the extension and have that image display as a background image.
Let the user select a file, with <input type="file">
Turn the file into a data URL
Save the data URL with chrome.storage.local.set
Use a content script to replace the background image in web pages
Potential Problem: https://developer.chrome.com/docs/extensions/mv3/declare_permissions/#unlimitedStorage
Note: This permission applies only to Web SQL Database and application
cache (see issue 58985). Also, it doesn't currently work with wildcard
subdomains such as http://*.example.com.
Proof of concept:
https://github.com/GrippenDynamik/Set_Background_Image
manifest.json
{
"manifest_version": 3,
"name": "Set Background Image",
"version": "1.0",
"action": {
"default_title": "Set Background Image"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["/js/content_script.js"]
}
],
"permissions": [
"storage"
]
}
background.js
async function action_onClicked(tab, onClickData) {
chrome.tabs.create({
active: true,
url: chrome.runtime.getURL("/html/file_picker.html"),
});
}
chrome.action.onClicked.addListener(action_onClicked);
/html/file_picker.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<label for="file_picker">Choose an image to upload</label><br>
<input type="file" id="file_picker" accept="image/*"><br>
<br>
<button type="button" id="button_clear">Clear background image</button>
<br>
<img id="image"><br>
<script type="application/javascript" src="/js/file_picker.js"></script>
</body>
</html>
/js/file_picker.js
function storage_onChanged(changes, areaName) {
let settings = {};
if (areaName == "local") {
if (changes.image_data_url) {
settings.image_data_url = changes.image_data_url.newValue ?? "";
}
if (changes.image_filename) {
settings.image_filename = changes.image_filename.newValue ?? "none";
}
}
set_image(settings);
}
function set_image(settings) {
let image = document.getElementById("image");
if (settings.image_data_url !== undefined) { image.src = settings.image_data_url; }
if (settings.image_filename !== undefined) { image.alt = settings.image_filename; }
}
function remove_image() {
chrome.storage.local.remove(["image_data_url", "image_filename"]);
}
function store_image() {
if (this.files.length > 0) {
const reader = new FileReader();
reader.addEventListener("load", () => {
chrome.storage.local.set({"image_data_url": reader.result, "image_filename": this.files[0].name});
});
reader.readAsDataURL(this.files[0]);
}
}
// Initialization
chrome.storage.local.get(["image_data_url", "image_filename"])
.then(items => {
set_image({image_data_url: items.image_data_url ?? "", image_filename: items.image_filename ?? "none"});
}
);
document.getElementById("file_picker").addEventListener("change", store_image);
document.getElementById("button_clear").addEventListener("click", remove_image);
chrome.storage.onChanged.addListener(storage_onChanged);
/js/content_script.js
function storage_onChanged(changes, areaName) {
if (areaName == "local" && changes.image_data_url) {
set_background_image(changes.image_data_url.newValue, true);
}
}
function set_background_image(data_url, changed) {
if (data_url) {
// https://www.w3schools.com/jsref/prop_style_backgroundimage.asp
document.body.style.backgroundImage = "url('" + data_url + "')";
}
else if (changed) {
document.body.style.backgroundImage = "initial";
}
else {
console.log("You haven't 'uploaded' an image yet. Please click the extension action.");
}
}
// Initialization
chrome.storage.local.get("image_data_url")
.then(items => set_background_image(items.image_data_url, false));
chrome.storage.onChanged.addListener(storage_onChanged);

how to add callbacks to kendo dialog actions

I've tried using the Kendo UI DialogService to call up my own component in a dialog. The issue I'm having is in using custom actions for my dialog.
Including an ng-template with custom buttons and actions somewhat defeats the purpose of using the dialogService and clutters my template with markup not directly related to it.
I've tried using code like this:
const saveAction = { text: 'Save', primary: true };
const cancelAction = { text: 'Cancel' };
const dialog = this.dialogService.open({
title: 'Edit data',
content: FormComponent,
actions: [
cancelAction,
saveAction
]
});
const form = dialog.content.instance;
form.data = data;
dialog.result.subscribe((result) => {
if (result === saveAction) {
form.save();
}
});
This will let me run a save function from my FormComponent, but won't allow me to stop the dialog from closing if the form validation is off or the save fails.
I have managed to prevent the dialog from closing after you click an action by taking a copy of the dialogs action event emitter, and replacing it with my own.
It's a hack solution to this. Hopefully Kendo will provide something better in future.
const saveAction = { text: 'Save', primary: true };
const cancelAction = { text: 'Cancel' };
const dialog = this.dialogService.open({
title: 'Edit data',
content: FormComponent,
actions: [
cancelAction,
saveAction
]
});
const form = dialog.content.instance;
form.data = data;
const actionEmitter = dialog.dialog.instance.action;
dialog.dialog.instance.action = new EventEmitter<any>();
const sub = dialog.dialog.instance.action.subscribe(action => {
// Perform any check here based on whether you want the dialog to close or not
if(form.validate()) {
// Only call this if you want the dialog to close
actionEmitter.emit(action);
}
});
dialog.result.subscribe((result) => {
sub.unsubscribe(); // clean up
if (result === saveAction) {
form.save();
}
});
You can use method 'setOptions', but I don't know why this method doesn't exist in Telerik Document: https://docs.telerik.com/kendo-ui/api/javascript/ui/dialog
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.2.619/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.2.619/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.2.619/js/kendo.all.min.js"></script>
</head>
<body>
<div id="dialog"></div>
<input type="button" value="show dialog" onclick="showDialog()" />
<script>
$("#dialog").kendoDialog({
visible: false,
content: 'first content',
actions: [{
text: "OK",
action: function (e) {
return false;
},
primary: true
}, {
text: "Cancel"
}]
});
function showDialog() {
var dialog = $("#dialog").data("kendoDialog");
dialog.setOptions({
closable: false,
content: 're-open content',
actions: [{
text: 'test1',
primary: true
},
{
text: 'test2'
}
]
});
dialog.open();
console.log(dialog.options.actions)
}
</script>
</body>
</html>

How to add img src attribute with VueJs

In my NodeJs route, I have the following:
router.get('/list/:id', function(req, res, next) {
request("http://localhost:3000/api/journal/" + req.params.id, function(error, response, body) {
var json = JSON.parse(body);
res.render('listdetail', { title: 'Journal', data: json });
});
});
The data is a json object containing all my screen fields. One of the fields is a base64 presentation of an image.
Then, in my List Detail html I have the following:
<div id="app">
<img class="materialboxed" src="{{data.base64Image}}" width="200">
</div>
This is surely not working... How can I add to the src attribute the base64 information that was sent by NodeJS?
I tried also the following:
<img class="materialboxed" :src=imagebase64Source width="200">
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
imagebase64Source: {{data.base64Image}}
}
})
</script>
But it obviously does not work
Thanks
EDIT:
Strange, it's working now!
Here's what I've done:
<img class="materialboxed" src="{{ data.base64Image }}" width="200">
The only difference I can see is the spacing between the mustache.
Thanks to all who helped.
You can do it simply like this:
<template>
<div>
<img :src="image"/>
</div>
</template>
<script>
module.exports = {
data: function() {
return {
image: //your b64 string there
};
}
};
</script>
Pay attention by the way, depending on what you have on your string, you may have to add a header to the raw string.
<template>
<div>
<img :src="imgWithHeader"/>
</div>
</template>
<script>
module.exports = {
data: function() {
return {
image: //your b64 string there
};
},
computed: {
imgWithHeader() {
return 'data:' + MIMETypeOfTheImage + ';base64,' + this.image;
}
}
};
</script>
Of course you should figure out what is the type of the image, in this case.
I think the method you tried should work if the syntax is corrected
So this:
<img class="materialboxed" :src=imagebase64Source width="200">
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
imagebase64Source: {{data.base64Image}}
}
})
</script>
should be changed to this:
<img class="materialboxed" :src="imagebase64Source" width="200">
<script type="text/javascript">
var app = new Vue({
el: '#app',
data () {
return {
imagebase64Source: data.base64Image,
}
}
})
</script>

Cannot Get Typeahead.js Working with MVC 5 Over Remote

I have no idea what I'm doing wrong, but I cannot get typeahead working in my MVC 5 application. I installed everything via NuGet and my view includes #Scripts.Render("~/bundles/typeahead"), which is rendering properly when viewing the source of the view. So the issue isn't that the dependencies are missing.
I am not seeing any drop down appear when I start typing, and using Fiddler I do not see any calls being made out to the remote that I setup that pulls the data.
Here's the line in my view that typeahead is being attached:
#Html.TextBoxFor(m => m.MainInfo.CompanyName,
new { #class = "form-control typeahead", id = "comp-name", autocomplete="off" })
Here's the portion of my script that configures typeahead and bloodhound:
$(document).ready(function() {
var clients = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "/info/client?like=%QUERY",
wildcard: '%QUERY',
filter: function (clients) {
return $.map(clients, function (client) {
return {
value: client.Name,
clientId: client.Identifier
};
});
}
}
});
clients.initialize();
$('#comp-name').typeahead(null,
{
display: 'value',
minLength: 1,
source: clients.ttAdapter(),
templates: {
empty: "Looks like a new client...",
suggestion: Handlebars.compile("<p><b>{{value}}</b> - {{clientId}}</p>")
}
});
});
Is there something that I've configured wrong in my javascript? I've used a few tutorials as well as their own documentation, but I cannot figure out what I'm doing wrong here. It almost feels like it's not properly initialized, but there are no errors being thrown.
NOTE: Just as an FYI I'm using Bootstrap 3 as well in case that changes anything.
EDIT: Here's my #section Scripts:
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/typeahead")
<script src="#Url.Content("~/Scripts/handlebars.min.js")"></script>
<script src="#Url.Content("~/Scripts/ProjectSetupFormScripts.js")"></script> <-- this is where typeahead is set up
This did the trick for me:
JS
#section Scripts {
<script type="text/javascript">
$(function () {
SetupTipeahead();
});
function SetupTipeahead() {
var engine = new Bloodhound({
remote: {
url: '/Employees/AllEmployees',
ajax: {
type: 'GET'
}
},
datumTokenizer: function (d) {
return Bloodhound.tokenizers.whitespace(d.FullName);
},
queryTokenizer: Bloodhound.tokenizers.whitespace
});
engine.initialize();
$('#FullName').typeahead(null, {
displayKey: 'FullName',
source: engine.ttAdapter(),
templates: {
empty: [
'<div class="empty-message">',
'No match',
'</div>'
].join('\n'),
suggestion: function (data) {
return '<p class="">' + data.FullName + '</p><p class="">' + data.ManNumber + '</p>';
}
}
});
}
</script>
EmployeesController has the following JsonResult
public JsonResult AllEmployees()
{
return Json(db.Employees.ToList(),JsonRequestBehavior.AllowGet);
}
Hello try to wrap your script in #section scripts {} this will place the script at the bottom just before the </body> tag and make sure you are not calling the function before your bundles load.
#section scripts {
<script>
$(document).ready(function() {
var clients = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "/info/client?like=%QUERY",
wildcard: '%QUERY',
filter: function (clients) {
return $.map(clients, function (client) {
return {
value: client.Name,
clientId: client.Identifier
};
});
}
}
});
clients.initialize();
$('#comp-name').typeahead(null,
{
display: 'value',
minLength: 1,
source: clients.ttAdapter(),
templates: {
empty: "Looks like a new client...",
suggestion: Handlebars.compile("<p><b>{{value}}</b> - {{clientId}}</p>")
}
});
});
</script>
}

Combining aui-Tabview combined with aui-Pagination

I'm using AlloyUI components within a YUI script and am trying to combine aui-tabview (Pills) with aui-pagination such that clicking on each tab(pill) updates the pagination from the contents/nodelist for each tab. For example, if there are 7 items in the nodelist for tab-2 then I should get 7 pagination buttons, 6 items for tab-3 should show 6 pagination buttons, etc. I cannot get these two components to integrate. Any help would be gratefully received.
Here is my code:
<div id="myTab">
<ul class="nav nav-pills">
<li class="active">View all</li>
<li>Beauty</li>
<li>Days out</li>
<li>Holidays</li>
</ul>
<div class="products tab-content">
<div id="beauty" class="tab-pane">
<div>some content</div>
<div>some more content</div>
<div>more content</div>
<div>a few words</div>
</div>
<div id="days-out" class="tab-pane">
<div>some content</div>
<div>some more content</div>
<div>more content</div>
<div>a few words</div>
</div>
<div id="holidays" class="tab-pane">
<div>some content</div>
<div>some more content</div>
<div>more content</div>
<div>a few words</div>
</div>
</div>
</div>
<script>
YUI({
}).use('node', 'node-base', 'event', 'transition', 'anim', 'aui-tabview', 'aui-pagination', function(Y) {
new Y.TabView(
{
srcNode: '#myTab',
type: 'pills'
}
).render();
Y.one(".nav.nav-pills").delegate('click', function(e) {
var id = Y.one(e.currentTarget);
var href = id.get('href');
var arr = href.split("#");
var target = arr[1];
var pages = Y.all('#' +target + " > div");
var total_rows = pages._nodes.length;
Y.log(total_rows);
new Y.Pagination(
{
page: 1,
total: total_rows,
boundingBox: '#pagination',
circular: false,
contentBox: '#pagination .pagination-content',
on: {
changeRequest: function(event) {
var instance = this,
current = event.currentTarget,
state = event.state,
lastState = event.lastState;
if (lastState) {
pages.item(lastState.page - 1).setStyle('display', 'none');
}
pages.item(state.page - 1).setStyle('display', 'block');
}
},
after: {
changeRequest: function(event) {
// goto top
a = new Y.Anim(
{
node: 'body',
to: {scrollTop: 0},
duration: 0.4,
easing: Y.Easing.easeOut
}
);
a.run();
}
},
strings: {
next: '»',
prev: '«'
}
}
).render();
}, 'a');
}
);
</script>
Since I've received no answer to the above posting, I've been left with a few days to mull it over and come up with the following solution. Any additions or improvements welcome.
<script>
YUI({}).ready('node', 'event', 'transition', 'anim', 'aui-tabview', 'aui-pagination', function(Y) {
var tabs = '';
var setup = '';
var tabTargetID = '';
tabs = new Y.TabView(
{
srcNode: '#myTab',
type: 'pills'
}
).render();
setup = {
contentId: function() {
if (tabTargetID !== '') {
var content = tabTargetID;
} else {
var id = tabs.getActiveTab();
var href = id.one('a').get('href');
var arr = href.split("#");
var content = '#' + arr[1];
}
return content;
},
pages: function() {
return Y.all(setup.contentId() + " > div");
},
currentTabPageTotal: function() {
return setup.pages()._nodes.length;
}
};
var pages = setup.pages();
var pg = new Y.Pagination(
{
page: 1,
total: setup.currentTabPageTotal(),
boundingBox: '#pagination',
circular: false,
contentBox: '#pagination > ul',
offset: 1,
on: {
changeRequest: function(e) {
var instance = this,
state = e.state,
lastState = e.lastState;
// Set the pagination links active state
Y.all('.pagination > ul > li:not(.pagination-control)').removeClass('active');
var pg_links = Y.all(".pagination > ul > li:not(.pagination-control)");
pg_links.item(state.page - 1).addClass('active');
// Hide all but the focussed tabs 1st paginated page
pages.setStyles({display: 'none', opacity: '0'});
pages.item(state.page - 1).setStyle('display', 'block')
.transition({
opacity: {value: 1, duration: 1}
});
}
},
after: {
changeRequest: function(e) {
// goto top
a = new Y.Anim(
{
node: 'body',
to: {scrollTop: 0},
duration: 0.4,
easing: Y.Easing.easeOut
}
);
a.run();
}
},
strings: {
next: '»',
prev: '«'
}
}
).render();
tabs.on('selectionChange', function(e) {
var tabIndex = tabs.indexOf(e.newVal);
var tabContents = Y.all(".tab-content > div");
var tabTarget = Y.one(tabContents.item(tabIndex));
tabTargetID = '#' + tabTarget.get('id');
pages = setup.pages();
// Hide all but the focussed tabs 1st paginated content
Y.all(tabTargetID + ' > div').setStyles({display: 'none', opacity: '0'});
Y.one(tabTargetID + ' > div').setStyles({display: 'block'})
.transition({
opacity: {value: 1, duration: 1}
});
// For the focussed Tab, build the pagination links with x number of links and set to 1st page
pg.setAttrs({page: 1, total: setup.currentTabPageTotal()});
// Highlight the 1st pagination link
Y.all('.pagination > ul > li:not(.pagination-control)').removeClass('active');
Y.one('.pagination > ul > li:not(.pagination-control)').addClass('active');
});
});
</script>

Resources