I'm getting a text file as API response from here https://api.pwnedpasswords.com/range/D0597 that looks like this
007F24D71AC210875C58951F5D99ACC71D2:3
0097880A0B749B59A5F7FD0D943A133ADE1:4
00CAEC74DE2FA10428E6D3FAD065D53B865:4
00F8C45A33243D0A4FD293DC70130E82E00:1
024556F4CB4A1DA178A6EC4E43ECED22467:1
030BA417A72B878EC629BD585705D306260:1
03664676C5A123BE6927DB6BAC5F5427468:1
0491953CF08D183806C28DB827835D27348:1
04BA7B823BBB772A8172F94A757AAF59A39:2
04D3C208B89E12C60AB12900690E86C13DA:1
06856BA40BCB6BCE13C40F271487F347BA5:1
071E3D06232DEA85E297102F6037164C033:5
and I need to loop through and check if the value of an input is included in the list of first item. If present I need to show the second value after ":".
I was trying to use split() for new line and ":" and iterate but kind of got lost.
// data is your text file
var foo = data.split("\n"),
bar = "your input";
Object.keys(foo).forEach(function(key) {
if (foo[key].split(":")[0] === bar) {
console.log(foo[key].split(":")[1]);
}
});
I want to replace a particular line using javascript with new content.
This is the file content,
SERVER=1055#localhost
GROUP_SERVERS=2325#localhost
LINE_IAM_INTERESTED=KTYUIERVW:2800
FILE_PATH="C:\Program Files\somefile\Shared Files\"
In this line, LINE_IAM_INTERESTED=KTYUIERVW:2800 .I want to replace KTYUIERVW with KJHTERDY and 2800 with 78945
I have shown what I tried using fs appendfilesync
fs.appendFileSync('file_name').toString().split('\n').forEach(function(line){
app.console.log("called append");
var sEntry = line.split("=");
if (sEntry.length == 2) {
if (sEntry[0] == "LINE_IAM_INTERESTED") {
app.console.log("found one!!!!");
}
}
});
you can try READ -> REPLACE -> WRITE flow:
fs.writeFileSync('file_name', fs.readFileSync('file_name').replace('KTYUIERVW:2800', 'KJHTERDY:78945'))
appendFile and appendFileSync are used for adding to the end of the file. Although you can do it as a one liner as shown in the other answer, I've kept the structure of your code the same. Here you want to read the data, modify it then re-write it. Using the block of code you have, you can modify it to use readFileSync and writeFileSync.
let newData = fs.readFileSync('file_name', 'utf-8').split('\n').map(line => {
let sEntry = line.split('=')
if (sEntry.length == 2) {
if (sEntry[0] == "LINE_IAM_INTERESTED") {
console.log("found one!!!!");
return sEntry[0] + '=' + 'KJHTERDY:78945'
}
}
return line
}).join('\n')
fs.writeFileSync('file_name', newData)
I've swapped the forEach for map which lets us change the array data by returning the desired value. The new array is then joined back together and written back to the file.
What is good practice when storing an HTML select dropdown into a JavaScript variable. I also need to capture the value which they selected and pass that through.
I originally tried to use jQuery to create the option and hold it in a variable but it would error out.
var keyNamesList = $('<option></option>').val('').html('Select a Key');
I then used an HTML string and appended the options list in a loop with with more HTML represented as a string. See JSFIDDLE link for a mock up.
var keyNamesList = "<option value = ''> Select an item</option>"
keyNamesList += "<option value = '"+data.key+"'>" + data.value + "</option>";
JSFIDDLE
$('<option></option>')...
Should just be $('option').
PS: What are you trying to do?
It's unlikely that using an append per option and setting the value and content via the DOM API is going to cause a big performance hit, but just as general rule it's considered good practice to avoid multiple append and DOM mutation calls if you can, so I would normally build a single HTML string:
function getOptions(data, blank) {
var optTpl = '<option value="%key%">%label%</option>',
options = [];
if (blank) {
// if blank is truthy then append an option - if bool true then
// a default label, otherwise use the value of blank as label
options.push(optTpl
.replace('%key%','')
.replace('%label%', (blank === true ? 'Select one...' : blank))
);
}
$.each(data, function (i, datum){
options.push(optTpl
.replace('%key%',datum.key)
.replace('%label%', datum.value)
);
});
return options.join('');
}
// usage:
$('theSelectElement').append(getOptions(data, 'Select something!'));
I like to use a kind of template and call string replacements but you could build the strings on each iteration like you proposed in your question:
options.push("<option value = '"+data.key+"'>" + data.value + "</option>");
Example un-integrated with yours: http://jsfiddle.net/8tjwL6u5/
still quite new to jQuery / Javascript and am struggling a little.
I have created an attribute called catno that I have assigned to several links. Then I want all instances inside banner-1 to be called into another link separated by a comma. i.e
New Link
I'm just struggling in making this happen. The code I have right now only returns the first catno.
Any help would be great!
JSFIDDLE
<div id="banner-1>
New Link
</div>
$sd('.buy-outfit').attr('href', function() {
return $sd("#banner-1 .add-catno").attr('catno') + ',';
});
Fiddle Demo
var arr_catno = $("#banner-1 a").map(function () { //create array using .map
return $(this).attr('catno'); // add element attribute catno to array
}).get().join(); //use .join() to get comma separated string of array
$('.new-link').attr('href', arr_catno); //assign it to href
.map()
Updated after OP's Comment
Fiddle Demo
$('[id^=banner-] .new-link').attr('href', function () {
return $(this).parent().find('a').map(function () {
return $(this).attr('catno');
}).get().join();
});
Attribute Starts With Selector [name^="value"]
.parent()
.find()
[id^=banner-] --> select all the elements with id starting with banner-
Use $.map to produce an array of catnos and them join them into a string.
$('.new-link').attr('href', function() {
return $.map($(".add-catno"), function (el) {
return $(el).data('catno');
}).join(',');
});
Note in the example that I've changed the catnos attributes to data attributes. Using data is considered good practice for when you want to add arbitrary data to your HTML.
Fiddle
Given an arbitrary HTML element with zero or more data-* attributes, how can one retrieve a list of key-value pairs for the data.
E.g. given this:
<div id='prod' data-id='10' data-cat='toy' data-cid='42'>blah</div>
I would like to be able to programmatically retrieve this:
{ "id":10, "cat":"toy", "cid":42 }
Using jQuery (v1.4.3), accessing the individual bits of data using $.data() is simple if the keys are known in advance, but it is not obvious how one can do so with arbitrary sets of data.
I'm looking for a 'simple' jQuery solution if one exists, but would not mind a lower level approach otherwise. I had a go at trying to to parse $('#prod').attributes but my lack of javascript-fu is letting me down.
update
customdata does what I need. However, including a jQuery plugin just for a fraction of its functionality seemed like an overkill.
Eyeballing the source helped me fix my own code (and improved my javascript-fu).
Here's the solution I came up with:
function getDataAttributes(node) {
var d = {},
re_dataAttr = /^data\-(.+)$/;
$.each(node.get(0).attributes, function(index, attr) {
if (re_dataAttr.test(attr.nodeName)) {
var key = attr.nodeName.match(re_dataAttr)[1];
d[key] = attr.nodeValue;
}
});
return d;
}
update 2
As demonstrated in the accepted answer, the solution is trivial with jQuery (>=1.4.4). $('#prod').data() would return the required data dict.
Actually, if you're working with jQuery, as of version 1.4.3 1.4.4 (because of the bug as mentioned in the comments below), data-* attributes are supported through .data():
As of jQuery 1.4.3 HTML 5 data-
attributes will be automatically
pulled in to jQuery's data object.
Note that strings are left intact
while JavaScript values are converted
to their associated value (this
includes booleans, numbers, objects,
arrays, and null). The data-
attributes are pulled in the first
time the data property is accessed and
then are no longer accessed or mutated
(all data values are then stored
internally in jQuery).
The jQuery.fn.data function will return all of the data- attribute inside an object as key-value pairs, with the key being the part of the attribute name after data- and the value being the value of that attribute after being converted following the rules stated above.
I've also created a simple demo if that doesn't convince you: http://jsfiddle.net/yijiang/WVfSg/
A pure JavaScript solution ought to be offered as well, as the solution is not difficult:
var a = [].filter.call(el.attributes, function(at) { return /^data-/.test(at.name); });
This gives an array of attribute objects, which have name and value properties:
if (a.length) {
var firstAttributeName = a[0].name;
var firstAttributeValue = a[0].value;
}
Edit: To take it a step further, you can get a dictionary by iterating the attributes and populating a data object:
var data = {};
[].forEach.call(el.attributes, function(attr) {
if (/^data-/.test(attr.name)) {
var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
return $1.toUpperCase();
});
data[camelCaseName] = attr.value;
}
});
You could then access the value of, for example, data-my-value="2" as data.myValue;
jsfiddle.net/3KFYf/33
Edit: If you wanted to set data attributes on your element programmatically from an object, you could:
Object.keys(data).forEach(function(key) {
var attrName = "data-" + key.replace(/[A-Z]/g, function($0) {
return "-" + $0.toLowerCase();
});
el.setAttribute(attrName, data[key]);
});
jsfiddle.net/3KFYf/34
EDIT: If you are using babel or TypeScript, or coding only for es6 browsers, this is a nice place to use es6 arrow functions, and shorten the code a bit:
var a = [].filter.call(el.attributes, at => /^data-/.test(at.name));
Have a look here:
If the browser also supports the HTML5 JavaScript API, you should be able to get the data with:
var attributes = element.dataset
or
var cat = element.dataset.cat
Oh, but I also read:
Unfortunately, the new dataset property has not yet been implemented in any browser, so in the meantime it’s best to use getAttribute and setAttribute as demonstrated earlier.
It is from May 2010.
If you use jQuery anyway, you might want to have a look at the customdata plugin. I have no experience with it though.
As mentioned above modern browsers have the The HTMLElement.dataset API.
That API gives you a DOMStringMap, and you can retrieve the list of data-* attributes simply doing:
var dataset = el.dataset; // as you asked in the question
you can also retrieve a array with the data- property's key names like
var data = Object.keys(el.dataset);
or map its values by
Object.keys(el.dataset).map(function(key){ return el.dataset[key];});
// or the ES6 way: Object.keys(el.dataset).map(key=>{ return el.dataset[key];});
and like this you can iterate those and use them without the need of filtering between all attributes of the element like we needed to do before.
You should be get the data through the dataset attributes
var data = element.dataset;
dataset is useful tool for get data-attribute
or convert gilly3's excellent answer to a jQuery method:
$.fn.info = function () {
var data = {};
[].forEach.call(this.get(0).attributes, function (attr) {
if (/^data-/.test(attr.name)) {
var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) {
return $1.toUpperCase();
});
data[camelCaseName] = attr.value;
}
});
return data;
}
Using: $('.foo').info();
You can just iterate over the data attributes like any other object to get keys and values, here's how to do it with $.each:
$.each($('#myEl').data(), function(key, value) {
console.log(key);
console.log(value);
});
I use nested each - for me this is the easiest solution (Easy to control/change "what you do with the values - in my example output data-attributes as ul-list) (Jquery Code)
var model = $(".model");
var ul = $("<ul>").appendTo("body");
$(model).each(function(index, item) {
ul.append($(document.createElement("li")).text($(this).text()));
$.each($(this).data(), function(key, value) {
ul.append($(document.createElement("strong")).text(key + ": " + value));
ul.append($(document.createElement("br")));
}); //inner each
ul.append($(document.createElement("hr")));
}); // outer each
/*print html*/
var htmlString = $("ul").html();
$("code").text(htmlString);
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/prism.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism-okaidia.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 id="demo"></h1>
<ul>
<li class="model" data-price="45$" data-location="Italy" data-id="1234">Model 1</li>
<li class="model" data-price="75$" data-location="Israel" data-id="4321">Model 2</li>
<li class="model" data-price="99$" data-location="France" data-id="1212">Model 3</li>
</ul>
<pre>
<code class="language-html">
</code>
</pre>
<h2>Generate list by code</h2>
<br>
Codepen: https://codepen.io/ezra_siton/pen/GRgRwNw?editors=1111
One way of finding all data attributes is using element.attributes. Using .attributes, you can loop through all of the element attributes, filtering out the items which include the string "data-".
let element = document.getElementById("element");
function getDataAttributes(element){
let elementAttributes = {},
i = 0;
while(i < element.attributes.length){
if(element.attributes[i].name.includes("data-")){
elementAttributes[element.attributes[i].name] = element.attributes[i].value
}
i++;
}
return elementAttributes;
}
If you know the name of keys you can also use object destructuring to get values like this
const {id, cat, cid } = document.getElementById('prod').dataset;
You can also skip keys you don't need and get the ones you need like this
const { cid, id } = document.getElementById('prod').dataset;
100% Javascript no jQuery ;)
DOMStringMap :
console.log(document.getElementById('target-element-id').dataset);
or custom variable :
var data = {};
Object.entries(document.getElementById('target-element-id').dataset).forEach(([key, val]) => {
data[key] = val;
});
console.log(data);