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")
}
Related
I have a dropdown that has times within a start and end time. I also have times displayed on my page that are "booked". I am trying to create a function that see if any "booked" values match the dropdown values, and if so, remove them from the array. I am having trouble figuring out how to design my JavaScript function to do so and would greatly appreciate any help in this.
remove.js
$(function () {
var removeItem = document.getElementsByClassName('set');
$('#time').find('option[value=="' + removeItem + '"]').remove();
});
time.js
var start = document.getElementById('start').innerHTML.split('.').join('').toLocaleLowerCase();
var end = document.getElementById('end').innerHTML.split('.').join('').toLocaleLowerCase();
var time = document.getElementById('time');
time.disabled = true;
var slotTimes = [];
document.getElementById("length").onchange = function (evt) {
var timeDistance = evt.target.value;
var startMoment = moment(start, "h:mm a");
var endMoment = moment(end, "h:mm a");
slotTimes = [];
while (startMoment.isSameOrBefore(endMoment)) {
slotTimes.push(startMoment.format("h:mm a"));
startMoment = startMoment.add(timeDistance, 'minutes');
}
addDropdown();
disabled();
};
function disabled(option) {
if (option != "") {
time.disabled = false;
}
}
function addDropdown() {
var doc = '',
times = slotTimes,
i;
for (i = 0; i < times.length; i++) {
doc += "<option value='" + times[i] + "'>" + times[i] + "</option>";
}
document.getElementById('time').innerHTML = doc;
disabled();
}
First, you ought to be using jQuery!
$('#foo') is the same as document.getElementById('foo')
$('.bar') is the same as document.getElementByClassName('bar')
Now to address your question, you are trying to put an html element
ie document.getElementByClassName('set')
in place of a value. Try running console.log(removeItem) and you will see what I mean.
I think what you are trying to do is this:
$(document).ready(function() {
$('.set').each(function() { //loop over all elements with a class == 'set'
const removeItem = $(this).val(); //get value of each element
$('#time').find('option=[value=="' + removeItem + '"]').remove();
});
});
If you need any more help let me know.
Hope this helps!
Update
You should put the removeItem loop at the end of the addDropdown function:
function addDropdown() {
var doc = '',
times = slotTimes,
i;
for (i = 0; i < times.length; i++) {
doc += "<option value='" + times[i] + "'>" + times[i] + "</option>";
}
document.getElementById('time').innerHTML = doc;
disabled();
$('.set').each(function() { //loop over all elements with a class == 'set'
const removeItem = $(this).val(); //get value of each element
$('#time').find('option=[value=="' + removeItem + '"]').remove();
});
}
Update 2
I would recommend rewriting your code to use the selectpicker bootstrap package. It looks like most of the "features" you are trying to make have simple keywords that selectpicker uses.
For example, to disable an option from this dropdown:
<select class="selectpicker" id="toppings">
<option id="opt_1">Mustard</option>
<option id="opt_2">Ketchup</option>
<option id="opt_3">Relish</option>
</select>
You simply do:
$('#opt_2').prop('disabled', true);
If you need to reference specific specific options by their parent dropdown, you can use the children method:
$('#toppings').children('.someClass').prop('disabled', true);
This will change all options of the toppings dropdown that have a class="someClass" to disabled.
I'm sure there are several features of the selectpicker package that you will find useful later on too!
I'm not sure what the problem is with your code specifically, but it is looking more and more like the selectpicker package, which you can use for free.
Thing that I'm making
I am making a webpage, which is to generate forum code automatically
when I enter content into inputs. Each character will be in different colors and the sentence will look like a gradient.
This is the jsfiddle sample.
When I enter a-p-p-l-e in to those inputs, the result will be as follow:
[color=3173d8]a[/color][color=416cd9]p[/color][color=5e5bdb]p[/color][color=8248dd]l[/color][color=a335df]e[/color]
Question
When more and more inputs and spans are created, the js code will be so bulky. But I don't know how to simplify them. I have tried to use thing like $(this).attr('target') , it just doesn't work. Can anyone help me to make it shorter if I would like to add more inputs, like saying 30.
More
What if i want the focus move itself to the next input if that input is typed with character already? Then I will be able to type word with 'tab'.
You can simplify your code like this.
Bind the keyup event once by using the id starts with selector.
var colors = ["3173d8", "416cd9", "5e5bdb", "8248dd", "a335df"]
$("[id^=input]").each(function (i) {
$(this).css('background', '#' + colors[i]);
});
$("[id^=input]").keyup(function () {
var index = $("[id^=input]").index(this);
$("span[id^=span]").eq(index).html('[color=' + colors[index] + ']' + $(this).val() + '[/color]');
});
Note that $("[id^='input']") will return all the elements whose id starts with "input".
Demo Fiddle
Edit for changing the focus
var colors = ["3173d8", "416cd9", "5e5bdb", "8248dd", "a335df"]
$("[id^=input]").each(function(i) {
$(this).css('background', '#' + colors[i]);
});
$("[id^=input]").keyup(function() {
if ($(this).val().trim().length) {
$(this).next().focus();
}
var index = $(this).index();
$("span[id^=span]").eq(index).html('[color=' + colors[index] + ']' + $(this).val() + '[/color]');
});
Edited Fiddle
Automatic making input, and full js solution. And it's easy to add new color.
// Define color separately
var colors = [
"3173d8", "416cd9", "5e5bdb", "8248dd", "a335df"
];
(function() {
$("body")
.append('<div id="parent"></div>')
.append('<code id="output"></code>');
var f = function() {
$("#output").html("");
for (var i = 0, val = ""; i < colors.length; i++) {
val = $("#parent input[data-num=" + i + "]").val();
$("#output").append('[color=' + colors[i] + ']' + val + '[/color]');
//or $("#output").append('<span id="span'+i+'">'+c+'</span>');
}
};
for (var i = 0; i < colors.length; i++) {
$('<input size="4" maxlength="1" />')
.attr("data-num", i)
.css('background', '#' + colors[i])
.keyup(f)
.appendTo("#parent");
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
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;
});
}
}
Here when i click on a particular player its score is displayed.But when again a player is clicked the previous score doesn't get cleared.So pls can anyone provide the solution.
$(document).ready(function () {
for (var i = 0; i < temp.length; i++)
$("#sidebar").append("<div id=" + i + " class='player'>" + temp[i].name + "</div>")
$(".player").click(function () {
var pla = $(this).attr('id');
$("#score").append(temp[pla].score);
//$(".content").append(a[pla].Events);
var selected = $(this).hasClass("highlight");
var a = $("span").append($(this).text());
$(".player").removeClass("highlight");
if (!selected) {
$(this).addClass("highlight");
$(this.Text()).remove();
}
});
});
You might need to add a call to .html() for the sidebar to clear its content, add it at the top of your document ready function.
So something like:
$("#sidebar").html();
I have a form field that is being duplicated / removed dynamically
See the fiddle here : http://jsfiddle.net/obmerk99/y2d4c/6/
In this feature, I also need to increment the NAME of the field ( and ID etc.. ) like so :
o99_brsa_settings[brsa_dash_wdgt_content][0]
o99_brsa_settings[brsa_dash_wdgt_content][1]
o99_brsa_settings[brsa_dash_wdgt_content][2] ...
It is working, but the problem is that when I add / remove fields , when it gets to the last ( actually first one ) , it will give me "undefined" and will not add anymore fields .
To see the problem you will need to "play" a bit with add/remove .
I believe the main problem is how to keep all of those on the same array level if we have [0] and [0][2]
I am far from a JS guru, and this code was somehow assembled from various sources. But I am kind of stuck right now, So any help will be appreciated .
Try this way:
$(function () {
$(".addScnt").on("click", function () {
var i = checkNumberOfElements();
var scntDiv = $("div[id^='widget_dup']:last");
var prevDiv = scntDiv.clone();
var newname = $(prevDiv).find("textarea").attr("name").substring(0, $(prevDiv).find("textarea").attr('name').indexOf(']'));
prevDiv.find('textarea').attr('name', newname + "][" + i + "]");
prevDiv.find('textarea').attr('id', newname + "][" + i + "]");
prevDiv.find('label').attr('for', newname + "][" + i + "]");
prevDiv.attr('id', $(prevDiv).attr('id') + "_" + i);
$(scntDiv).after(prevDiv);
});
$(document).on("click", ".remScnt", function (event) {
var i = checkNumberOfElements();
if (i <= 1) {
return false;
} else {
var target = $(event.currentTarget);
target.parent("div").remove();
}
});
});
function checkNumberOfElements() {
// Number of textareas
var i = $("textarea[name^='o99_brsa_settings[brsa_dash_wdgt_content]']").length;
// Number of divs
// var i = $("div[id^='widget_dup']").length;
if (typeof i === undefined) {
return 0;
} else {
return i;
}
}
Demo: http://jsfiddle.net/y2d4c/7/