Unable to slice strings retrieved from div's - javascript

I'm having trouble slicing text I retrieved from a div with javascript/jquery. I thought you could slice every string and that the .text() function always returned a string so I fail to see the problem. Any help will be greatly appreciated!
Fiddle
Html:
<body>
<div class="vaknaam">Div 1 :<span class="totaal">55%</span>
</div>
<div class="vaknaam">Div 2 :<span class="totaal">60%</span>
</div>
<div class="vaknaam">Div 3 :<span class="totaal">64%</span>
</div>
<div class="vaknaam">Div 4 :<span class="totaal">76%</span>
</div>
<div class="vaknaam">Div 5 :<span class="totaal">63%</span>
</div>
</body>
Javascript:
$(function () {
var divs = {};
var tempString, vakken = {};
$('.vaknaam').each(function (key, value) {
tempString = $(value).contents().filter(function () {
return this.nodeType == 3;
}).text();
tempString = tempString.slice(0, - 2);
vakken[tempString] = $(value).children('span').text();
});
for (var property in vakken) {
$('body').append("<p>" + property + "</p>");
}
});

You have several errors.
You need to declare an initialise the var vakken.
The slice method does not modify the string so you should assign what returns to something.
property var is just an index so you need to ask for vakken[property]
Your code should look like this:
$(function () {
var divs = {};
var tempString, vakken = {}; //1
$('.vaknaam').each(function (key, value) {
tempString = $(value).contents().filter(function () {
return this.nodeType == 3;
}).text();
tempString = tempString.slice(0, -4); //2
vakken[tempString] = $(value).children('span').text();
});
for (var property in vakken) {
$('body').append("<p>" + property + "</p>"); //3
}
});
Check out this codepen.

slice doesn't modify the initial string, which is immutable. Try:
tempString = tempString.slice(0, - 2);

Related

JS. How do I create a regex pattern by concatenation with variables

I am not able to fix the following:
<html>
<head>
<title>Test</title>
<script>
function myFunction(arr) {
var N = [0,1,2,3,4,5,6,7,8,9];
for (var s in N) {
var pattern = new RegExp('/^[A-z]et_[' + s + ']_\\d/');
// NOTE I get the following, is that how it should be?
// window.alert(pattern); => /\/^[A-z]et_[0]_\d\//
// NOTE: I checked that it works fine for a single digit case, say:
// var pattern = new RegExp(/^[A-z]et_[3]_\d/);
var newarr = arr.filter(elt => pattern.test(elt));
document.getElementById("demo").innerHTML = newarr;
}}
</script>
</head>
<body>
<div id="demo" onclick="myFunction(['aaaLet_0_0', 'Let_1_99', 'Let_2_', 'Let_3_99', 'Pet_2_', 'Pet_3_99', '_9_33']);">click here</div>
<hr>
<p>expected output: Let_1_99, Let_3_99, Pet_3_99</p>
</body>
</html>
I see many similar questions, but I have not been able to find out how to fix my code. It should be possible, shouldn't it?
EDIT
the following is what I need:
<html>
<head>
<title>Test</title>
<script>
var newarr = [];
function myFunction(arr) {
var N = [0,1,2,3,4,5,6,7,8,9];
for (var s in N) {
var pattern = new RegExp('^[A-z]et_' + s + '_\\d'); // NOTE: not /
var lnewarr = arr.filter(elt => pattern.test(elt));
if(typeof lnewarr !== 'undefined' && lnewarr.length > 0){newarr.push(lnewarr)};
}
document.getElementById("demo").innerHTML = newarr;
}
</script>
</head>
<body>
<div id="demo" onclick="myFunction(['aaaLet_0_0', 'Let_1_99', 'Let_2_', 'Let_3_99', 'Pet_2_', 'Pet_3_99', '_9_33']);">click here</div>
<hr>
<p>expected output: Let_1_99, Let_3_99, Pet_3_99</p>
</body>
</html>
(sorry if my post is mostly code. Hope it may helps somebody out there.)
Instead of for loop you can use a .join like this:
var pattern = new RegExp('^[A-Za-z]et_[' + N.join('') + ']_\\d');
//=> /^[A-Za-z]et_[0123456789]_\d/
This works for the case when you have singe character values in your array N.
For generic use you can use this expression:
var pattern = new RegExp('^[A-Za-z]et_(?:' + N.join('|') + ')_\\d');
//=> /^[A-Za-z]et_(?:0|1|2|3|4|5|6|7|8|9)_\d/
Using a for loop you can do this:
var N = [0,1,2,3,4,5,6,7,8,9];
var str='(?:';
for (var s in N)
str += s + '|';
str = str.replace(/\|$/, ')');
var pattern = new RegExp('^[A-Za-z]et_' + str + '_\\d');
//=> /^[A-Za-z]et_(?:0|1|2|3|4|5|6|7|8|9)_\d/

Select 2 random divs with the same class jQuery

my question is simple, suppose I have 10 divs:
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
<div class="someDiv"></div>
And I want that when I click 'foo' just 2 of the divs change their background to red. How can I achieve this with something like Math.random from js?
Try this - Use Math.Random and parseInt
Working Demo Here
$(document).ready(function(){
var r1 = (Math.random()*10);
var r2 = (Math.random()*10);
if(parseInt(r1)==parseInt(r2)) // IF BOTH ARE SAME
{
if(parseInt(r1)==10)
{
r2=r2-1;
}
else
{
r2=r2+1;
}
}
var allDiv = $('.someDiv');
$(allDiv[parseInt(r1)]).css({'background':'red'});
$(allDiv[parseInt(r2)]).css({'background':'red'});
});
Here is the simplified version of https://stackoverflow.com/a/11186765/2000051
Demo: http://jsfiddle.net/lotusgodkk/fK8Xw/69/
JS:
function shuffle(array) {
var m = array.length,
t, i;
while (m) {
i = Math.floor(Math.random() * m--);
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
$(function () {
$("button").click(function () {
var $all = $(".someDiv").removeClass("red");
$(shuffle($all).slice(0, 3)).addClass("red");
});
});
A generalized approach for specified number of elements to change.
just change var numOfDivToChange=2; to apply the effect to more elements.
$(document).ready(function(){
var numOfDivToChange=2;
$('.foo').click(function(){
//get all similar elements array
var allFoos = document.getElementsByClassName('someDiv');
//sanity check
if(numOfDivToChange>allFoos)
return false;
for(var i=0;i<numOfDivToChange;i++)
{
//generate a random index
var randIndex = Math.floor((Math.random() * allFoos.length) + 1);
//set the css changes you want
allFoos[randIndex].css('background','red');
}
});
});
Try This
UPDATE:
$(document).ready(function(){
$('.foo').click(function(){
var rand1 = Math.floor((Math.random() * 10) + 1);
var rand2 = Math.floor((Math.random() * 10) + 1);
var a = document.getElementsByClassName('someDiv')[rand1];
var b = document.getElementsByClassName('someDiv')[rand2];
a.css('background','red');
b.css('background','red');
});
});

jquery map array returning NaN in iterator

I am trying to parse this array of checkbox values and remove the "N".
Using the replace function yields the error TypeError: numberArr[i].replace is not a function, and if I remove the replace function, the script simply outputs NaN for my values.
Fiddle here http://jsfiddle.net/j0w5tkg9/3/
<div id='opts'>
<input type="checkbox" data-cost="0" value="44N12345" name="options[]">
<input type="checkbox" data-cost="0" value="55N6789" name="options[]">
</div>
<div id='output'></div>
function getAllocArray() {
var numberArr = $.map($('input:checkbox:checked'), function (e, i) {
return +e.value;
});
var varOutput = '<ul>';
for (var i = 0, len = numberArr.length; i < len; i++) {
varOutput += "<li>" + numberArr[i].replace(/N/,'') + "</li>";
}
varOutput += '</ul>';
$('#output').text(varOutput);
};
$('#opts').on('click', 'input:checkbox', null, getAllocArray);
Do not convert value to Number. Replace +e.value to e.value:
var numberArr = $.map($('input:checkbox:checked'), function (e, i) {
return e.value;
});
Numbers does not have replace method.

struggling with creating asterisks in Javascript

I've been struggling with this for some time now. What I wanted to create is to output a triangle of asterisks based on user's input. Let say user entered size 5, it would look something like this:
*
**
***
****
*****
My HTML looks like:
<p>
Size: <input type="text" id="size">
<input type="button" value="Draw" onclick="draw()">
</p>
<pre id="output">
</pre>
In my Javascript, I have:
function draw()
{
var size = customJS.get ( "size" ); //I have a custom library where it get the Id from HTML
var theTriangle = makeTriangle( size.value ); //sending in the size
customJS.set ("output", theTriangle); //will set theTriangle to display to "output" in HTML
}
function makeTriangle( theSize )
{
var allLines = ""; // an empty string to hold the entire triangle
for ( var i = 0; i <= size; i++) // this loop size times
{
var oneLine = createLine ( i <= size ); // amount of asterisks for this line
allLines += oneLine;
}
return allLines;
}
function createLine ( length )
{
var aLine = ""; // an empty string to hold the contents of this one line
for ( var j = 0; j <= i; j++ ) //this loop length times
{
aLine += '*';
}
return aLine + "<br>";
}
anyone have any tip on how I go about this? thank you so much!
Newlines in HTML normally display as spaces, but you want them to show as newlines. The pre tag makes newlines actually appear as new lines, so wrap the output in a pre tag:
customJS.set ("output", "<pre>" + theTriangle + "</pre>");
Also, you're calling createLine like this:
var oneLine = createLine ( i <= size );
i <= size yields a boolean (true or false) rather than a number. You probably mean to just pass it i:
var oneLine = createLine ( i );
Additionally, you're setting size like this:
var size = customJS.get = ( "size" );
You probably want to drop the second equals, since as is, it sets the variable size to the string "size".
And finally, you've got a few variables wrong: in makeTriangle, you're looping size times, but size is undefined; you probably meant theSize. In createLine, you're looping i times, but i is undefined; you probably meant length.
With all that, it works.
There were several bugs in your code. For example using theSize instead size as parameter in the function makeTriangle(), using i instead of length in the createLine() function in the for loop condition.
Another one was:
use
return aLine + "<br/>";
instead of
return aLine + "\n";
The working solution for your code can be found in this jsFiddle: http://jsfiddle.net/uwe_guenther/wavDH/
And below is a copy of the fiddle:
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>Size:
<input type="text" id="sizeTextField">
<input id='drawButton' type="button" value="Draw">
<div id='output'></div>
</p>
<script src='main.js'></script>
</body>
</html>
main.js
(function (document) {
var drawButton = document.getElementById('drawButton'),
sizeTextField = document.getElementById('sizeTextField'),
output = document.getElementById('output');
function makeTriangle(size) {
var allLines = '';
for (var i = 0; i <= size; i++) {
var oneLine = createLine(i); // amount of asterisks for this line
allLines += oneLine;
}
return allLines;
}
function createLine(length) {
var aLine = '';
for (var j = 0; j <= length; j++) {
aLine += '*';
}
return aLine + "<br/>";
}
drawButton.onclick = function () {
output.innerHTML = makeTriangle(sizeTextField.value);
};
})(document);
You can leverage some JavaScript tricks to make the code a bit more terse:
<div style="text-align: center">
<label>Size:
<input type="text" id="size" value="5">
</label> <pre id='output'></pre>
</div>
<script>
var size = document.getElementById('size'),
output = document.getElementById('output');
function update() {
var width = +size.value, // Coerce to integer.
upsideDown = width < 0, // Check if negative.
width = Math.abs(width), // Ensure positive.
treeArray = Array(width).join('0').split('0') // Create an array of 0s "width" long.
.map(function(zero, level) { // Visit each one, giving us the chance to change it.
return Array(2 + level).join('*'); // Create a string of *s.
});
upsideDown && treeArray.reverse(); // If width was negative, stand the tree on its head.
output.innerHTML = treeArray.join('\n'); // Join it all together, and output it!
}
size.onkeyup = update;
update();
size.focus();
</script>
http://jsfiddle.net/mhtKY/4/

Looking for a javascript solution to reorder divs

I have some divs in the page that show different things of the same kind, for example offers, now offers have ending time, and also posted time, if the user wants to order by ending time, or posted time, they should be re ordered.
I'm looking for a javascript solution that could do that, any particular libraries under Ext JS , or JQuery would work
Here is how these divs look like
<div data-sortunit="1" data-sort1="40" data-sort2="156" data-sort3="1"
data-sort4="1317620220" class="item">
</div>
<div data-sortunit="2" data-sort1="30" data-sort2="116" data-sort3="5"
data-sort4="1317620220" class="item">
</div>
<div data-sortunit="3" data-sort1="10" data-sort2="157" data-sort3="2"
data-sort4="1317620220" class="item">
</div>
So I wanna be able to sort these divs based on data-sortN, N being an integer
Edit: OK, now that you've supplied some HTML, here's javascript code that will sort that specific HTML by the desired column number:
function sortByDataItem(containerID, dataNum) {
var values = [];
$("#" + containerID + " .item").each(function(index) {
var item = {};
item.index = index;
item.obj = this;
item.value = $(this).data("sort" + dataNum);
values.push(item);
});
values.sort(function(a, b) {return(b.value - a.value);});
var container = $("#" + containerID);
for (var i = 0; i < values.length; i++) {
var self = $(values[i].obj);
self.detach();
container.prepend(self);
}
return;
}
$("#sort").click(function() {
var sortValue = $("#sortColumn").val();
if (sortValue) {
sortValue = parseInt(sortValue, 10);
if (sortValue && sortValue > 0 && sortValue <= 3) {
sortByDataItem("container", sortValue);
return;
}
}
$("#msg").show(1).delay(5000).fadeOut('slow');
});
You can see it work here in a jsFiddle: http://jsfiddle.net/jfriend00/JG32X/
Since you've given us no HTML to go on, I've made my own HTML and shown you how you can use jQuery to sort:
HTML:
<button id="sort">Sort</button><br>
<div id="productList">
<div class="row"><div class="productName">Popcorn</div><div class="price">$5.00</div></div>
<div class="row"><div class="productName">Peanuts</div><div class="price">$4.00</div></div>
<div class="row"><div class="productName">Cookie</div><div class="price">$3.00</div></div>
<div class="row"><div class="productName">Beer</div><div class="price">$5.50</div></div>
<div class="row"><div class="productName">Soda</div><div class="price">$4.50</div></div>
</div>
Javascript (run after page is loaded):
$("#sort").click(function() {
var prices = [];
// find all prices
$("#productList .price").each(function(index) {
var str = $(this).text();
var item = {};
var matches = str.match(/\d+\.\d+/);
if (matches && matches.length > 0) {
// parse price and add it to the prices array
item.price = parseFloat(matches[0]);
item.row = $(this).closest(".row").get(0);
item.index = index;
prices.push(item);
}
});
// now the prices array has all the prices in it
// sort it using a custom sort function
prices.sort(function(a, b) {
return(a.price - b.price);
});
// now pull each row out and put it at the beginning
// starting from the end of the prices list
var productList = $("#productList");
for (var i = prices.length - 1; i >= 0; i--) {
var self = $(prices[i].row);
self.detach();
productList.prepend(self);
}
});
And, a jsFiddle that shows it in action: http://jsfiddle.net/jfriend00/vRdrA/.
I made a tiny jqueryPlugin out of jfriend00's answer:
(function($){
$.fn.sortChildrenByDataKey = function(key, desc){
    var i, els = this.children().sort(function(a, b) {return (desc?1:-1)*($(a).data(key) - $(b).data(key));});
    for (i = 0; i < els.length; i++) {
        this.prepend($(els[i]).detach());
    }
return this;
};
})(jQuery);
Your HTML:
<div id="myContainer">
<div data-myKey="4"> ... </div>
<div data-myKey="2"> ... </div>
...
</div>
Usage:
$('div#myContainer').sortChildrenByDataKey('myKey', true_or_false);
The children of the container can be any Elements. Its only important, that they are immediate children and have data-X key.
Thank you, jfriend00!!

Categories

Resources