Repeat Javascript/jQuery until specific outcome - javascript

I currently have the following code that looks at an unordered list and selects a random item. I want to make sure the same 'li' doesn't get selected twice in a row, or even better, don't select a repeat li until all of them have been selected.
var list = $('#headshots li:visible').toArray();
var elemlength = list.length;
var randomitem = list[Math.floor(Math.random() * elemlength)];
Full code:
function sawpHomepageAgencyHeadshots() {
var fullList = [1,2,3,4,5,6,7,8,9,10];
window.setInterval(function(){
var random = fullList.slice(0).sort(function() {
return .5 - Math.random();
});
$('#headshots li').each(function() {
var i = parseInt($(this).css('background-image').replace(/\D+/, ''));
random = $.grep(random, function(value) { return value != i; });
});
var list = $('#headshots li:visible').toArray();
var elemlength = list.length;
var randomitem = list[Math.floor(Math.random()*elemlength)];
$(randomitem).css({'background-image': 'url("' + absoluteDomainPath + 'images/headshots/headshot-' + random[0] + '.jpg")'});
}, 3000);
}
Added fiddle: http://jsfiddle.net/MBP2t/

remove the random item from the list variable, then it can not be selected again.
Take a look at this fiddle where I use an interval to select each item randomly.
http://jsfiddle.net/ghcNM/
var list = $('#headshots li:visible');
var loop = setInterval(doit, 500);
function doit(){
if(list.length){
randomitem = list.splice(Math.floor(Math.random() * list.length), 1)
$(randomitem).css('background', '#ff0000');
}else{
clearInterval(loop);
}
}

You need to maintain state somewhere in your application, so there are two basic options here:
Do it in memory:
Keep an array of visited items, then, when you pull an item, check if it's in the list you've already seen. If it's not, add it to the list. If it is, randomly pick again.
Do it in the DOM:
Do you search for a node like this: $('#headshots li:visible').not('.seen')
After you've found an item, do item.addClass('seen') to mark it as seen, then continue.
Once your jQuery selector returns no values, you can remove the seen class from all elements.
For what it's worth, the second option is pretty gross.

Related

A function to affect multiple rows to substr and copy with Javascript

So, i have this code, it works:
var curp = document.getElementById("id_sc_field_curp_id_1");
var getcurp = curp.options[curp.selectedIndex].text;
var rfc = getcurp.substr(0, 10);
document.getElementById("id_sc_field_virtual_rfc_1").value = rfc;
It copy the text inside the field (td - CURP) "id_sc_field_curp_id_1", and trim it to put the result in another field (RFC) "id_sc_field_virtual_rfc_1"
Example img
JSFIDDLE: https://jsfiddle.net/90yzgcqe/1/
I want to adapt the code to work with the other rows, witch have an incremental id...
id_sc_field_curp_id_1,id_sc_field_curp_id_2,id_sc_field_curp_id_3, d_sc_field_virtual_rfc_1, d_sc_field_virtual_rfc_2, d_sc_field_virtual_rfc_3...etc
Im making this function, but... i dont know how to make it work...
function rfc() {
for (var i = 0; i <= 19; i++) {
var curp = document.getElementById("id_sc_field_curp_id_" + i);
var getcurp = curp.options[curp.selectedIndex].text;
var rfc = getcurp.substr(0, 10);
document.getElementById("id_sc_field_virtual_rfc_" + i).value = rfc;
}
}
What is wrong?
Some jQuery gets us there fairly easily, first get the matching dropdowns and then interact with them.
$(function() {
//get the list of dropdowns that start with all but the numeral
var lst = $("[id^='id_sc_field_curp_id_']");
$.each(lst, function(idx, elem) {
//lets store the dropdown for use in the loop
let $field = $(elem);
//for example lets print the selected text
console.log($field.find("option:selected").text());
});
});
There are a couple of options from there, you can use the dropdown to create the rfc's id, or use the jQuery function closest() to get it. Once you have the associated rfc's input it should be trivial to get set the value.
EDITED:1
More specific javascript, and a link to a modified jsFiddle
$(function() {
//get the list of dropdowns that start with all but the numeral
var lst = $("[id^='id_sc_field_curp_id_']");
$.each(lst, function(idx, elem) {
//lets store the dropdown for use in the loop
let $field = $(elem);
//for example lets alert the selected text
alert($field.find("option:selected").text().substr(0,10));
$field.closest("[id^='idVertRow']")
.find("[id^='id_sc_field_virtual_rfc_']")
.val($field.find("option:selected").text().substr(0,10));
});
});

How to merge duplicate values in a for loop javascript

I am new to js and I don't understand much of codes and conditions in js.
My question is simple but I need someone to give me a good example if possible as I know what I need but it is getting hard to implement that in code.
This is my code with 2 arrays where the data is coming from.
blind_tmp = '';
for (i=0; i<#All of Blind Relationship Link.length; i++){
blind_tmp = blind_tmp + '<p>[**' + #All of Element Title[i] + '**](' + #All of Blind Relationship Link[i] + ')'
};
What simple needed is that. I want merge records that are duplicates printed.
for example: if Blind Relationship link is AF44 and after 6 elements this AF44 comes again so I want both to be written like 1.AF44,2.AF44
while now it is writing the elements how they come along
example:
AF11,AF22,AF33,AF44,AF55,AF66,AF77,AF44
so in this example you see two AF44
I want them to be written like this
AF11,AF22,AF33,AF44AF44,AF55,AF66,AF77
any help with a code example is appreciated.
The idea is to iterate through each element in the blindRelationshipLink and store those elements in a temporary array which will be used to check the number of occurrence of an array element.
var blindRelationshipLink = ['AF11','AF22','AF33','AF11','AF44','AF44','AF55','AF66','AF77','AF11','AF22','AF11'];
var arrTemp = [];
var p = '';
blindRelationshipLink.forEach(function(arr){
var count = 0;
arrTemp.forEach(function(a){
if(arr === a)
count++;
});
arrTemp.push(arr);
if(count){
count++;
arr= arr + '.' + count;
}
p = p + arr + ',';
});
alert(p);
You test by running the code snippet.
This approach is not best but it may serve your purpose.
Here is a snippet
var elemArray = ['AF11', 'AF22', 'AF33', 'AF44', 'AF55', 'AF66', 'AF77', 'AF44']; // Array of elements
//A new array which which will contain elements which pass our case
var finalArray = [];
elemArray.forEach(function(item) { // loop through main array
// Check if element is present or else push the element
if (finalArray.indexOf(item) == -1) {
finalArray.push(item);
} else {
// if element is there find the index
var getIndex = finalArray.indexOf(item);
// remove the element, else there will be duplicate
finalArray.splice(getIndex, 1);
//concate the matched element
var newElem = item + item;
// push the element in specfic index
finalArray[getIndex] = newElem;
}
})
console.log(finalArray)
Current drawback with this code is what will happen if there are multiple repeated item in the main array. For example presence of AF33 more than twice.
DEMO

Deleting item from array in Javascript

I have the following task - there is an array of some items. I use random, get item number, write item's value in div and delete element with item number from array.
e.g.
array = (1,2,3)
random = 2
div = 3
delete from array = (1,2)
looping, etc
So I wrote the following script:
window.onload = function () {
var verb_array = new Array (1,2,3)
var random_verb_array = Math.floor(Math.random() * (verb_array.length - 0+0)) + 0;
var random_verb_array_2 = verb_array[random_verb_array];
var show = document.getElementById("wuza").innerHTML = random_verb_array_2;
delete verb_array[random_verb_array];
var test = document.getElementById("huza").innerHTML = '<Br><Br>' + verb_array
}
<!DOCTYPE html>
<div id="wuza"></div>
<div id="huza"></div>
Item has no value in array, but it's position still remains. How can I avoid it and finally total wipe it from the array?
You're probably looking to use splice.
verb_array.splice(random_verb_array, 1);
So assuming random_verb_array is the random index you've come up with, it'll remove 1 (second parameter) from the given index (first parameter).
Learn more about Array.splice()

Use Selected Options Value in For Loop

Good afternoon.
I am trying to use the selected value in the options box in a for loop.
The theory being that if the user selects 3, for example, Javascript will populate 3 boxes with a fruit from the array.
Can anyone point me in the right direction? I have enclosed Codepen link too.
function changeText(){
var e = document.getElementById('selectbox');
var strUser = e.options[e.selectedIndex].value;
for (var i=0; i<=strUser; i++) {
document.getElementById('boldStuff').innerHTML = randomFruit + strUser;
}
}
http://codepen.io/jameswinfield/pen/aNWRKm
The ID element should be unique to the entire dom. You are using it multiple times for boldStuff. If you would like to be able to grab them like that you should use a class.
Here is a version that should do what you want: http://codepen.io/anon/pen/KzmGLP?editors=0010
Keep in mind that sets the value to every box, even the hidden ones. You will have to get a new random fruit per box or they will all have the same fruit.
I changed all id="boldStuff" to class="boldStuff",
grabbed all boldStuffs
var boldStuffs = document.getElementsByClassName('boldStuff');
and looped over every boldStuff
for (var i = 0; i < boldStuffs.length; i += 1) {
//And set the value of each boldStuff to a new random fruit.
boldStuffs[i].innerHTML = getRandomItem(fruitsArray);
}
The following line also only runs once so no matter how many boxes there are they will all have the same fruit (because randomFruit is never changed)
var randomFruit = fruitsArray[Math.floor(Math.random() * fruitsArray.length)];
You can use a function to grab a random fruit instead, something like this:
function getRandomItem(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
Then use getRandomItem(fruitsArray); to get a random fruit.

Want to keep "ALL" option in Javascript-CSS filter

There are about 16 posts in the front page and there is a filter with 4 drop-downs showing post categories. I have added category names as classes to the post div and I'm hiding them with javascript.
Used the following code to filter posts.
$('#filter select').change(function () {
var upper = $('#upper').val(); //these are IDs of select.
var sole = $('#sole').val();
var toe = $('#toe').val();
var midsole = $('#midsole').val();
var classes = '.' + [upper, sole, toe, midsole].join('.');
$('.box').hide().filter(classes,toeall).show();
});
.box is the class of the post container. this works perfectly.
The first option in each dropdown is "ALL" and I want to make it work.
For example, if I select ALL in "TOE" dropdown, it has to keep the existing results and and also show those posts which has one of the TOE categories as class.
Using the following code I tried to find all the values of TOE dropdown and show the posts with those classes too.
var toeall = new Array();
$('#toe option').each(function() {
toeall.push('.'+$(this).val());
});
if(toe=="all")
{
$('.box').hide().filter(classes&&toeall).show();
}
I know the code above is incorrect but can someone explain how to do it?
UPDATE: http://jsfiddle.net/kd3ybnnx/1/ <- Demo after answer from madalin ivascu
Try this:
$('#filter select').change(function () {
var upper = $('#upper').val(); //these are IDs of select.
var sole = $('#sole').val();
var toe = $('#toe').val();
var midsole = $('#midsole').val(),
array1 = [upper, sole, toe, midsole];
var ar =[];
$.each(array1,function(index,val){
if (val != 'all') {//note the value of all option has to be all
ar.push(val);
}
});
if(ar.length == 0) {$('.box').show();} else {
var classes = '.' + ar.join('.');
$('.box').hide().filter(classes).show();
}
});
jsfiddle: http://jsfiddle.net/kd3ybnnx/4/
Well.. you can try this:
$('#filter select').change(function () {
var upper = $('#upper').val(); //these are IDs of select.
var sole = $('#sole').val();
var toe = $('#toe').val();
var midsole = $('#midsole').val(),
array = [upper, sole, toe, midsole];
var counter = 0;
$.each(array,function(index,val){
if (val == 'all') {//note the value of all option has to be all
counter++;
}
})
if(counter == array.length) {
$('.box').show();
} else {
var classes = '.' + array.join('.');
$('.box').hide().filter(classes).show();
}
});
Basicaly, I check if all the selects have all, if they do I show all boxes. Else I filter because there is 1 filter at least.
You need a way to select values that are not 'all'. The way you would do this is walk through all elements and remove the ones you don't need from the array. Normally you would for example do this with an array.splice(index, 1) function
The problem (from a previous answer) with splice however is that it removes indices from the array so if there are four elements, the third is removed and when the each loop enters the fourth element there is no fourth element because it became the third. To solve this you can either:
Put the required elements in a new array instead of removing them
from the old array
Use an array where index doesn't change value (make it associative)
Use an each loop with an i variable that decreases every time you delete an element
UPDATE:
use a native javascript filter to easily filter out stuff
I've used the first from the list to create this example that works (tested it): I've chosen the fourth technique since it's mostly vanilla javascript, check out the commented code and the chosen alternative:
http://codepen.io/xaddict/pen/PqqYBa?editors=001
It's the easiest solution out of the three four above and remains readable
It uses a filter option to easily remove the 'all' values
function isNotAll(value) {
return value != 'all';
}
totals.filter(isNotAll);
Complete code:
$('#filter select').change(function() {
var upper = $('#upper').val(),
sole = $('#sole').val(),
toe = $('#toe').val(),
midsole = $('#midsole').val(),
totals = [upper, sole, toe, midsole];
function isNotAll(value) {
return value != 'all';
}
var filtered = totals.filter(isNotAll);
$(".box").show();
if (filtered.length) {
$(".box").hide().filter('.'+filtered.join('.')).show();
}
});

Categories