I want users to be able to input CSS input, and have that CSS applied to the last selected element(selected by the "rangeselector" variable). The code selects the right element, but only the first CSS-rule is applied.
ex: "background: blue; color:red;" only applies the background.
The function runs through the array correctly.
function customCss(){
css = $("input.css").val();
if(css.length < 10){
alert("Insert valid CSS");
}else{
cssArray = css.split(";");
counter = 0;
cssArray.forEach(function(){
var ruleSplit = cssArray[counter].split(":");
target = $("[content_child=" + rangeselector + "]");
target.css(ruleSplit[0] , ruleSplit[1]);
counter = counter + 1;
});
}
}
If you know the problem, or have a better way of achieving the same goal, i would gladly hear you suggestions.
Thanks
By using Array.forEach() you already have the index and the reference to Array. You don't need use a counter
cssArray = css.split(";");
// counter = 0;
cssArray.forEach(function(obj, key, array){
var ruleSplit = obj.split(":");
target = $("[content_child=" + rangeselector + "]");
target.css(ruleSplit[0] , ruleSplit[1]);
// counter = counter + 1;
});
have you tried stripping the elements before you set them? What's probably happening is that it's trying to set something like "color " instead of "color"
function customCss(){
css = $("input.css").val();
if(css.length < 10){
alert("Insert valid CSS");
}else{
cssArray = css.split(";");
counter = 0;
cssArray.forEach(function(){
var ruleSplit = cssArray[counter].split(":");
target = $("[content_child=" + rangeselector + "]");
target.css(ruleSplit[0].trim() , ruleSplit[1].trim());
counter = counter + 1;
});
}
}
Related
I am trying to make a script that will clone a div, cards in bootstrap 4, and change text in the div. I want this to happen a certain number of times., depending on the variable. However, when I use the script below I'm getting 8 cards (7 clones), instead of the 3 clones that it is supposed to be making. Does anyone know what is happening here?
$(document).ready(function(){
var cards = 3;
var id = "";
var newClass = "";
var i;
for(i = 0; i < cards; i++) {
id = id + "1";
newClass = newClass + "1"
$(".listings").clone().addClass(newClass).appendTo("body");
$("."+newClass).attr("id",id);
$("#" + id + " " + "h1").text("$5000");
}
});
change
.addClass(newClass)
to
.prop("class",newClass)
I have a for loop that creates as many as I write in an input field. first time I write a number in the imput all is ok... he generates for example 3 fields. When I delete 3 and write 5, he add two objects but he also clear other... if I select an option in the first , I want to keep it selected when I add some other fields....
this is an example: https://jsfiddle.net/exv8s2sq
and this is the code:
Insert number<input type="text" id="number" name="number" ><br><br>
<div id="container"></div>
<script>$('#number').on('keyup', function () {
changenumber(this.value);
});
$('#number').on('paste', function () {
changenumber(this.value);
});
var now = 0;
function changenumber(val) {
container = document.getElementById("container");
var diff = val - now;
if (diff > 0) {
for (var u = now + 1; u <= val; u++) {
container.innerHTML = container.innerHTML +
" Select from options <select id='selectobj" + u + "' name='selectobj" + u + "' style='width:25%;'>" +
"<option>A</option>" +
"<option>B</option>" +
"<option>C</option>" +
"</select><br><br>";
now = u;
}
}
}</script>
thanks
Lorenzo from Rome
Instead of using innerHTML, i would suggest using jQuery as selector and use element.append(selectbox) to add new items. I've updated your fiddle with a working example based on your code:
http://jsfiddle.net/exv8s2sq/1/
There is also room to refactor your code a bit. When using jQuery, native javascript isn't really necessary for dom manipulation.
Wrap your elements in a div with a specific class so you can easily count how many items you already have. Then depending on the number you enter, check whether you need to add or remove elements from your container.
Use jQuery selectors all the way, it is easier to identify your elements, and use the methods it provides such as .each() and .append()
$('#number').on('input', function () {
changenumber(this.value);
});
function changenumber(val) {
if (val !== '') {
// Wrap your elements in a div with a specific class
var select = '<div class="select-wrapper">Select from options <select><option>A</option><option>B</option><option>C</option></select></div>';
// Count number of selects div
var nbOfSelects = $('.select-wrapper').length;
// Check if you need to add or remove elements
if (nbOfSelects < val) {
// Add an element
for (var i = 0; i < (val - nbOfSelects); i++) {
$('#container').append(select);
}
} else {
// Loop through elements
$('.select-wrapper').each(function (i) {
// Remove an element
if (i >= val) {
$(this).remove();
}
});
}
}
}
JSFiddle demo
Try this, it adds an attribute of selected to the previous selected option using an onchange event listener
$('#number').on('keyup', function () {
changenumber(this.value);
});
$('#number').on('paste', function () {
changenumber(this.value);
});
var now = 0;
function changenumber(val) {
container = document.getElementById("container");
var diff = val - now;
if (diff > 0) {
for (var u = now + 1; u <= val; u++) {
container.innerHTML = container.innerHTML +
" Select from options <select onchange='updateDom(this)' id='selectobj" + u + "' name='selectobj" + u + "' style='width:25%;'>" +
"<option>A</option>" +
"<option>B</option>" +
"<option>C</option>" +
"</select><br><br>"; now = u;
}
}
}
function updateDom(s){
s.options[s.selectedIndex].setAttribute("selected","selected")
}
previous and Next buttons don't have limitations, ie: can move before and after first and last pages... cant seem to limit this.
I've created if statements to try and stop the button from executing but it wont work. any ideas?
jsFiddle: https://jsfiddle.net/s7ac8aq3/
$(function() {
$(document).ready(function(){
//amount of items on page
var num = $('.post').length;
//set items per page
var itemsPerPage = 1;
var nav = false;
//array of all items
var items = $(".post");
//rounds up to the nearest whole number -- number of pages needed to display all results
var numOfPages = Math.ceil((num / itemsPerPage));
//container div
var paginationContainer = $("#pagination-container");
//initial link num
var linkNum = 1;
paginationContainer.prepend("<button class='pagination' id='btn-prev' value='prev'>Prev</button>");
//creates all pagination links as input buttons (can be anything... li, a, div, whatever)
for(i = 0; i < numOfPages; i++)
{
paginationContainer.append("<button class='pagination' id='btn-" + (i + 1) +"' " + "value='" + (i + 1) + "'>" + (i + 1) + "</button>");
}
paginationContainer.append("<button class='pagination' id='btn-next' value='next'>Next</button>");
//does the initial filtering of the items, hides anything greater than page 1
items.filter(":gt(" + (itemsPerPage -1) + ")").hide();
//finds the input feilds and executes onclick
paginationContainer.find('button').on('click', function(){
//REQUIRED RESETS NAV BOOL SO CLICKS WILL REGISTER
nav = false;
//stores the value of the link in this var
var val = $(this).val();
//if value is next or prev
if(val == "prev")
{
if(linkNum > 1)
{
nav = true;
linkNum = linkNum - 1;
var currentBtn = paginationContainer.find("#btn-" + linkNum);
var otherButtons = paginationContainer.find('button');
otherButtons.attr('class', "pagination");
currentBtn.attr('class', "current");
currentBtn.focus();
}
}
else if (val == "next")
{
if(linkNum < numOfPages)
{
nav = true;
linkNum = linkNum + 1;
var currentBtn = paginationContainer.find("#btn-" + linkNum);
var otherButtons = paginationContainer.find('button');
otherButtons.attr('class', "pagination");
currentBtn.attr('class', "current");
currentBtn.focus();
}
}
if(nav == false)
{
//reoves the current class from all buttons before reassigning
var otherButtons = paginationContainer.find('button');
linkNum = $(this).val();
otherButtons.attr('class', "pagination");
//assigns current class to current button
$(this).attr("class", "current");
}
//creates an array of items to hide based on if the set results are less than the link num
var itemsToHide = items.filter(":lt(" + ((linkNum-1) * itemsPerPage) + ")");
// adds any items that are greater than the set results from the link num to the hide array
$.merge(itemsToHide, items.filter(":gt(" + ((linkNum * itemsPerPage) -1) + ")"));
// hides the items in hide array
itemsToHide.hide();
//shows all items NOT in the hide array
var itemsToShow = items.not(itemsToHide);
itemsToShow.show();
});
});
});
A little debugging of your jsFiddle identified the problem. In this part of the code:
} else if (val == "next") {
if (linkNum < numOfPages) {
nav = true;
linkNum = linkNum + 1;
the value of linkNum is sometimes being stored as a string. As a result, adding "3"+1 produces "31" in JavaScript.
The trivial solution is to convert it to an integer before the addition:
linkNum = parseInt(linkNum,10) + 1; // always use a radix
https://jsfiddle.net/mblase75/s7ac8aq3/3/
However, I would instead prefer to solve the problem at its source, a few lines down:
if (nav == false) {
var otherButtons = paginationContainer.find('button');
linkNum = $(this).val();
When you store linkNum in the first place, .val() returns a string. Parse it as an integer right away:
linkNum = parseInt($(this).val(),10);
https://jsfiddle.net/mblase75/s7ac8aq3/4/
and then you don't have to change it before performing the addition.
Your problem in linkNum variable, when you click on certain page number, variable gets a string value, after that when you trying to add 1 you receive a new string, for example "3" + 1 => "31", "4" + 1 => "41"
I'm building a (very) mini JS framework to use for customizing my eBay listings. I do know how to circumvent their "no remote scripts" policy, and I could use jQuery, but this is really an exercise in getting myself better at JS.
I have a function of the global window object which returns a bunch of methods, like this:
window.iq = (function(){
return {
tag: function(tag) {
return document.getElementsByTagName(tag);
},
map: function(el, attr) {
var arr = [];
el = iq.tag(el);
for (i = 0; i < el.length; i++) {
var x = el[i].getAttribute(attr);
arr.push(x);
}
return arr;
},
// A bunch of others like this
};
})();
I'm having trouble (by which I mean I'm utterly stuck) iterating through an array of data-name attributes and hiding or showing images based on whether there is a match. Here's the function:
iq.click('#mblThumbs img', function(){
var dn = iq.map('img', 'data-name');
for (i = 0; i < dn.length; i++) {
if (this.getAttribute('data-name') === dn[i]) {
iq.fadeOut(200, iq.sel('#mblSlide img:not([data-name="' + dn[i] + '"])'));
iq.fadeIn(200, iq.sel('#mblSlide img[data-name="' + dn[i] + '"]'));
}
}
});
I can cycle through the first two images as many times as my heart desires, but as soon as I click on anything past the second image, the function only continues to work for it, and the subsequent indexes in the array. I'm guessing that this is either a problem with my map method, or maybe something to do with array length? I don't know. I'm flummoxed. Any thoughts or suggested are much appreciated.
FIDDLE: http://jsfiddle.net/h8z7c/
The issue is indeed with your click callback. Your fadeout selector is finding the first image that is not data-name=dn[i], which is always either "one" (if you clicked 2), or "two" (if you clicked 1). You either need to use selAll to grab all of the elements that are not the clicked one, or keep track of which one is currently selected. Here are the two ways of fixing it.
// Make sure they are all hidden
iq.click('#mblThumbs img', function(){
var dn = iq.map('img', 'data-name');
for (i = 0; i < dn.length; i++) {
if (this.getAttribute('data-name') === dn[i]) {
var outs = iq.selAll('#mblSlide img:not([data-name="' + dn[i] + '"])');
for (var j = 0; j < outs.length; j++) {
iq.fadeOut(200, outs[j]);
}
iq.fadeIn(200, iq.sel('#mblSlide img[data-name="' + dn[i] + '"]'));
}
}
});
// Or keep track of the currently selected
var selected = "one";
iq.click('#mblThumbs img', function(){
var dn = iq.map('img', 'data-name');
for (i = 0; i < dn.length; i++) {
if (this.getAttribute('data-name') === dn[i] && dn[i] !== selected) {
iq.fadeOut(200, iq.sel('#mblSlide img[data-name="' + selected + '"]'));
iq.fadeIn(200, iq.sel('#mblSlide img[data-name="' + dn[i] + '"]'));
selected = dn[i];
}
}
});
I am new to JavaScript and am trying to create a function that changes the background color of my HTML document each time I click on a DIV. The code I have just loops though my array all the way to the end instead of one loop per click on my DIV. I know I am missing something that increments each time I click on the DIV, but can't figure out what. In my HTML document I have a DIV
<div id="autoText" onclick="moveMe()"></div>.
Here is my JavaScript so far:
var multipleColors = [];
multipleColors[0] = "red";
multipleColors[1] = "blue";
multipleColors[2] = "yellow";
function moveMe() {
for (i=0; i < multipleColors.length; i++) {
console.log("This is step " + i);
this.document.body.style.backgroundColor=multipleColors[i];
}
}
I would really appreciate anyone's advice?
Thanks.
If you want to continue from the beginning of the after you reached its end, use %(modulo) operator:
var multipleColors = [];
multipleColors[0] = "red";
multipleColors[1] = "blue";
multipleColors[2] = "yellow";
var current = 0;
function moveMe() {
current++;
var newIdx = current % multipleColors.length;
this.document.body.style.backgroundColor = multipleColors[newIdx];
}
Instead of using a loop, use a counter variable that you increase whenever the element is clicked:
var index = 0;
function moveMe() {
console.log("This is step " + index);
this.document.body.style.backgroundColor=multipleColors[index];
index += 1;
}
If you want to continue from the beginning of the array after you reached its end, reset the variable:
var index = 0;
function moveMe() {
console.log("This is step " + index);
this.document.body.style.backgroundColor=multipleColors[index];
index += 1;
if (index === multipleColors.length) {
index = 0;
}
}
try something like this
var multipleColors = [];
multipleColors[0] = "red";
multipleColors[1] = "blue";
multipleColors[2] = "yellow";
function moveMe() {
this.document.body.style.backgroundColor=(multipleColors[multipleColors.indexOf(this.document.body.style.backgroundColor)+1])?multipleColors[multipleColors.indexOf(this.document.body.style.backgroundColor)+1]:multipleColors[0];
}
You can keep adding the more colors in array.
DEMO