how to make a copy to clipboard button with js - javascript

so i was trying to make a button that when clicked it copy a value from a variable
like
<button onclick="copyToClipboard()">COPY</button>
and then on that function it takes the element to copy from a variable like
var copyids = {
"ids": [
{
"name": "id1",
"id": 192389021
},
{
"name": "id2",
"id": 123879032
},
{
"name": "id3",
"id": 149018292
},
]
};
so like copyids.ids[0].id and it copy that value
i hope its understandable

Maybe this helps
function copyToClipboard() {
let temp = document.createElement('textarea');
temp.value = copyids.ids[0].id;
document.body.appendChild(temp);
temp.select();
document.execCommand('copy');
document.body.removeChild(temp);
}

To copy, you will need to select before what you want to copy. Maybe you should put the data of the variable somewhere and copy it.
https://www.w3schools.com/howto/howto_js_copy_clipboard.asp

I made you a solution with the ability to select the desired data cell from the array. I've added a select tag for you, listing the name of each cell.
And at the choice of a specific option with you copy id in accordance with the specified name.
function copyToClipboard() {
var copyids = {
ids: [
{
name: "id1",
id: 192389021,
},
{
name: "id2",
id: 123879032,
},
{
name: "id3",
id: 149018292,
},
],
};
let selectIndex = document.querySelector("select").selectedIndex;
let storage = document.createElement("input");
storage.value = copyids.ids[selectIndex].id;
console.log(storage.value);
document.body.appendChild(storage);
storage.select();
document.execCommand("copy");
document.body.removeChild(storage);
}
<button onclick="copyToClipboard()">COPY</button>
<select>
<option value="id1">id1</option>
<option value="id2">id2</option>
<option value="id3">id3</option>
</select>

The execCommand method has been deprecated, and it might not be supported by newer releases.
However, there is a Clipboard API that you can use in it's place.
To let the user select what to copy from your list:
<button onclick="copyToClipboard()">COPY</button>
<select>
<option value="id1">id1</option>
<option value="id2">id2</option>
<option value="id3">id3</option>
</select>
Then your function can work like this:
function copyToClipboard() {
var copyids = {
ids: [
{
name: "id1",
id: 192389021,
},
{
name: "id2",
id: 123879032,
},
{
name: "id3",
id: 149018292,
},
],
};
let selectedIndex = document.querySelector("select").selectedIndex;
navigator.clipboard.writeText(copyids[selectedIndex].name);

Related

Angular Changing/Replacing the value in a string based on the User selection

I am working on an offer letter template that will replace/modify Dynamic Data Points like Name, Address, Role, Salary, etc based on the candidate selected from a list of candidates. There is a fixed syntax for a dynamic data points i.e they will be enclosed within <<>>, for example :
Welcome to the family, <<Name>>
You will be paid <<Salary>> for the duration of your employment.
In other words, these few data points will change by selecting the candidate we want to offer the job and the rest of the template will remain the same. Here is a demo to help you understand.
This is a dummy array I have created with 1 template, In the real-world app, I can have many templates with different clauseNames, so I am looking for a permanent fix.
.ts file, Template List :
[{
templateId: 1,
templateName: "Offer",
clauses: [
{
clauseName: "Introduction",
clauseId: 1,
texts: [
{
text: "Hello <<Name>>, Welcome to the Machine",
textId: 1,
}]
},
{
clauseName: "Address",
clauseId: 2,
texts: [
{
text: "<<Address>>",
textId: 2,
}]
},
{
clauseName: "Date Of Joining",
clauseId: 3,
texts: [
{
text: "You can join us on <<DateOfJoining>>",
textId: 3,
}]
},
]
}]
and here is the candidate list,
candidateList = [
{ name: "Simba", address: "Some Random Cave" },
{ name: "Doe John", address: "line 4, binary avenue, Mobo" },
{ name: "B Rabbit", address: "8 mile road, Detroit" },
{ name: "Peter Griffin", address: "Spooner Street" },
{ name: "Speedy Gonzales", address: "401, hole 34, Slyvester Cat Road" },
{ name: "Morty", address: "Time Machine XYZ" },
{ name: "Brock", address: "pokeball 420, Medic center" },
]
You can use regular expressions to replace those placeholders such as:
var result = text.text.replace(/\<\<(.*?)\>\>/g, function(match, token) {
return candidate[token.toLowerCase()];
});
One way to incorporate this to your display is by creating a property that returns the formatted text.
I have updated your stackblitz here.
Take a look at this demo
I have modified the logic in below method:
showTeplate(name,address,doj) {
this.clauseList = [];
for (let a of this.templateList) {
if (a.clauses != null) {
for (let cl of a.clauses) {
const tempObj = JSON.parse(JSON.stringify(cl));
tempObj.texts.forEach(textObj => {
textObj.text = textObj.text.replace("<<Name>>",name);
textObj.text = textObj.text.replace("<<Address>>",address);
textObj.text = textObj.text.replace("<<DateOfJoining>>",doj);
})
this.clauseList.push(tempObj)
}
}
}
console.log("Clause list", this.clauseList)
}

How to get all values of given specific keys (for e.g: name) without loop from json?

I want to fetch all the names and label from JSON without loop. Is there a way to fetch with any filter method?
"sections": [
{
"id": "62ee1779",
"name": "Drinks",
"items": [
{
"id": "1902b625",
"name": "Cold Brew",
"optionSets": [
{
"id": "45f2a845-c83b-49c2-90ae-a227dfb7c513",
"label": "Choose a size",
},
{
"id": "af171c34-4ca8-4374-82bf-a418396e375c",
"label": "Additional Toppings",
},
],
},
]
}
When you say "without loops" I take it as without For Loops. because any kind of traversal of arrays, let alone nested traversal, involve iterating.
You can use the reduce method to have it done for you internally and give you the format you need.
Try this :
const data = {
sections: [
{
id: "62ee1779",
name: "Drinks",
items: [
{
id: "1902b625",
name: "Cold Brew",
optionSets: [
{
id: "45f2a845-c83b-49c2-90ae-a227dfb7c513",
label: "Choose a size"
},
{
id: "af171c34-4ca8-4374-82bf-a418396e375c",
label: "Additional Toppings"
}
]
}
]
}
]
};
x = data.sections.reduce((acc, ele) => {
acc.push(ele.name);
otherName = ele.items.reduce((acc2, elem2) => {
acc2.push(elem2.name);
label = elem2.optionSets.reduce((acc3, elem3) => {
acc3.push(elem3.label);
return acc3;
}, []);
return acc2.concat(label);
}, []);
return acc.concat(otherName);
}, []);
console.log(x);
Go ahead and press run snippet to see if this matches your desired output.
For More on info reduce method
In the context of cJSON
yes, we can fetch the key value for any of the object.
1 - each key value is pointed by one of the objects. will simply fetch that object and from there will get the key value.
In the above case for
pre-requisition: root must contain the json format and root must be the cJSON pointer. if not we can define it and use cJSON_Parse() to parse the json.
1st name object is "sections" will use
cJSON *test = cJSON_GetObjectItem(root, "sections");
char *name1 = cJSON_GetObjectItem(test, "name" )->valuestring;
2nd name key value
cJSON *test2 = cJSON_GetObjectItem(test, "items");
char *name2 = cJSON_GetObjectItem(tes2, "name")->valuestring;
likewise, we can do for others as well to fetch the key value.

Setting preselected values in multiple select with Ractive

I render a select multiple in Ractive with a computed list of all options possible, which works great. But I could not find a proper way of preselecting values.
So far I have something like:
data = [{
type: "Person",
Name: "John",
worksFor: [
"1",
"2"
]},{
type: "department",
id: "1",
Name: "Sales"
},{
type: "department",
id: "2",
Name: "Marketing"
},{
type: "department",
id: "3",
Name: "Accounting"
}]
new Ractive({
el: '#list',
template: DataTpl,
data: {myData: data},
computed: {
DepartmentList () {
//some code
return list_of_all_Departments;
},
PersonsList () {
//some Code
return list_of_persons
});
So in my Template I tried
{{#PersonsList}}
<select multiple>
{{#DepartmentList}}
<option value="{{id}}"
{{#if _.includes(PersonsList.worksFor, id)}} selected{{/if}}>{{Name}}
</option>
{{/DepartmentList}}
</select>
{{/PersonsList}}
But this just gave me a failed to compute. Does anyone know how to get those preselects?
This is one of the things where Ractive deviates from standards. You need to put a value attribute on <select>. The selected <option>'s value becomes <select>'s value. The kind of data you'll get from <select> depends if it's multiple or not. If it's a single-select, you get a single value. If it's multiple-select, you'll get an array.
Setting a pre-selected value is simply the other way around. Assign a value from your data to <select>'s value and, assuming those values exist on the <option>s, they'll be selected. No template mangling required.
Ractive.DEBUG = false;
var data = [{
type: "Person",
Name: "John",
worksFor: [
"1",
"2"
]
}, {
type: "department",
id: "1",
Name: "Sales"
}, {
type: "department",
id: "2",
Name: "Marketing"
}, {
type: "department",
id: "3",
Name: "Accounting"
}];
new Ractive({
el: '#list',
template: '#template',
data: {
selectedDepartments: [],
myData: data
},
computed: {
DepartmentList() {
return this.get('myData').filter(v => v.type === 'department');
},
PersonsList() {
return this.get('myData').filter(v => v.type === 'Person');
}
}
});
<script src="https://unpkg.com/ractive#0.8.11/ractive.min.js"></script>
<div id="list"></div>
<script type="template/ractive" id="template">
{{#PersonsList}}
{{ Name }}
<select multiple value="{{ worksFor }}">
{{#DepartmentList}}
<option value="{{id}}">{{Name}}</option>
{{/DepartmentList}}
</select>
{{/PersonsList}}
</script>
you must give the select a value and set the value to whatever is the default value

Mapping and binding nested objects and arrays

I have an object and within this object I have items and one of the items is an array which also contains objects. A sample of the data is shown below.
I am using knockout to bind this data to the view so I think I need to implement a double loop for returning the objects and the objects within the child array to be able to bind them in the view.
Sample data:
"singers": {
"ijiyt6ih": {
"id": ObjectId('ijiyt6ih'),
"name": "John",
"songs": [
{
"id": ObjectId('okoiu8yi'),
"songName": "Hello There",
"year": "1980"
},
{
"id": ObjectId('sewfd323'),
"songName": "No More",
"year": "1983"
}
]
},
"98usd96w": {
"id": ObjectId('98usd96w'),
"name": "Jack",
"songs": [
{
"id": ObjectId('iew342o3'),
"songName": "Hurry Up",
"year": "1985"
}
]
}
}
I need to find a way to appropriately loop through this so that I can modify the returned data to bind it to the viewModel using knockout.
Here is how my viewModel looks like:
singersViewModel = function(data) {
var self = {
singerId: ko.observable(data.id),
singerName: ko.observable(data.name),
songName: ko.observable(...),
songYear: ko.observable(...)
};
I am not sure if I will have to return two different sets of data or not.
As for the looping. I was able to loop and return the list of singers to display on the page but I am not able to get the list of songs displayed within each singer.
Here is my loop so far:
var self = {},
singer,
tempSingers = [];
self.singers = ko.observableArray([]);
for (singer in singers) {
if (singers.hasOwnProperty(singer)) {
tempSingers.push(new singersViewModel(singers[singer]));
}
}
self.singers(tempSingers);
I tried to duplicate the same type of loop for songs within this loop but i would get an error using hasOwnProperty because songs is an array.
In the included snippet you can see how you can map the original data to a viewmodel that can be bound to a view.
I've left the ids as regular properties, and converted the names into observables, so thatthey can be edited. At the bottom you can see the current viewmodel state.
There is also a sample view which iterates the list of singers, and also the list of song within each singer.
As you can see I'm implementing the solution using mapping. For mapping you need to implement a callback that receives each original object and returns a new one with a new structure. For example this part of the code
_.map(_singers, function(singer) {
return {
id: singer.id,
name: ko.observable(singer.name),
// ... songs:
})
iterates over each singer (the sample data in the question), and for each one creates a new object with the id, an observable which includes the name (and the mapping of songs, which I don't show in this fragment).
NOTE: I'm using lodash, but many browsers support map natively as an array function
var ObjectId = function (id) { return id; }
var singers = {
"ijiyt6ih": {
"id": ObjectId('ijiyt6ih'),
"name": "John",
"songs": [
{
"id": ObjectId('okoiu8yi'),
"songName": "Hello There",
"year": "1980"
},
{
"id": ObjectId('sewfd323'),
"songName": "No More",
"year": "1983"
}
]
},
"98usd96w": {
"id": ObjectId('98usd96w'),
"name": "Jack",
"songs": [
{
"id": ObjectId('iew342o3'),
"songName": "Hurry Up",
"year": "1985"
}
]
}
};
var SingersVm = function(_singers) {
var self = this;
self.singers = _.map(_singers, function(singer) {
return {
id: singer.id,
name: ko.observable(singer.name),
songs: _.map(singer.songs, function(song) {
return {
name: ko.observable(song.songName),
id: song.id
};
})
};
});
return self;
};
var vm = new SingersVm(singers);
//console.log(vm);
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-bind="foreach: singers">
<div>
<input data-bind="value: name"/> (<span data-bind="text: id"></span>)
<ul data-bind="foreach:songs">
<li>
<input data-bind="value: name"/> (<span data-bind="text: id"></span>)
</li>
</ul>
</div>
</div>
<pre data-bind="html: ko.toJSON($root,null,2)">
</pre>

Change first ng-options text in Angular

I have a dropdown with various versions. For the first version, I'd like to add "latest" to the displayed text on the dropdown only, is there a simple way to do that?
HTML:
<select ng-model='selectedVersion'
ng-options="version.name for version in versions"
class="form-control">
</select>
JS:
$scope.versions = [
{ name: "3.0" },
{ name: "2.0" },
{ name: "1.0" },
]
$scope.selectedVersion = $scope.versions[0];
So right now the dropdown shows "3.0", "2.0", "1.0", but I would like to have the first option be "3.0 (latest)".
I can change the object name directly, but I'm passing the selected object to another scope and would cause issues, so this won't be stable:
$scope.versions[0].name += " (latest)";
I just want "latest" to be show inside the dropdown if possible. Thanks!
If your array is always going to have latest first, you can do this:
<select ng-model='selectedVersion'
ng-options="(version.name == versions[0].name ? 'latest' : version.name) for version in versions"
class="form-control">
</select>
Is better wraps into a namespace for avoid problems between scopes
js
function MyCntrl($scope) {
var versions = [{ name: "3.0" }, { name: "2.0" }, { name: "1.0" },];
$scope.prop = {
"value": versions[0],
"values": versions
};
}
html
<div ng-controller="MyCntrl">
<select ng-model="prop.value" ng-options="v.name for v in prop.values">
</select>
</div>
Preview

Categories

Resources