Jquery- Dynamic added fields - prevent the last Item to be removed - javascript

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/

Related

Remove time from dynamically generated dropdown

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.

Loop through multiple select lists and count the number of times each option is selected

Part of a site I'm working on involves creating repeat instances of the same select - option. I would like to count the number of times each option has been selected, and then store that number as a variable, which can then be sent to php email function.
For example - if "Infallid" is selected 3 times - I get infallid = 3, and 0 for the others.
JS fiddle showing how it all works - https://jsfiddle.net/scx4shnd/2/
$("button").click(function(){
$("select[name='diskho'] > option:selected").each(function() {
alert(this.text + ' ' + this.value);
// should alert - "value 1 = x" , "value 2 = "y" ect" where x and y are different values (numbers)
});
$("select[name='spishall'] > option:selected").each(function() {
alert(this.text + ' ' + this.value);
});
});
You can use following logic to calculate the number of times an option has been selected:
$("button").click(function(){
var dishkoMap = {};
$("select[name='diskho'] > option:selected").each(function () {
var value = this.value;
if (dishkoMap[value]) { // if value already exists then increase it by 1
dishkoMap[value] += 1;
} else {
dishkoMap[value] = 1;
}
});
// dishkoMap is a dictionary object so you won't see anything in alert.
// open the browser console and you can see the counts corresponding
// to each selected option
console.log(dishkoMap);
});
Similarly, you can also write for Spishäll and Blandare.
I would suggest writing a function where you pass the name of the select and then return the countMap.
function getCountMap(name) {
var countMap = {};
$("select[name='" + name + "'] > option:selected").each(function () {
var value = this.value;
if (countMap[value]) { // if value already exists then increase it by 1
countMap[value] += 1;
} else {
countMap[value] = 1;
}
});
return countMap;
}
and then use it as:
var dishkoMap = getCountMap('dishko');
var spishallMap = getCountMap('spishall');
// etc.

Dynamic generation of select clear other elements in javascript

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")
}

Simplifying some jQuery code of keyup inputs

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>

Using values from Array to execute function in jQuery

I have a page that contains several divs. The divs have the same postfixes but different prefixes. What I want to do is loop through them and if one of them contain a 0 hide the description div.
The divs look like this:
<div id="first_desc">First</div><div id="first_note1">0</div>
<div id="second_desc">Second</div><div id="second_note1"></div>
<div id="third_desc">Third</div><div id="third_note1"></div>
My script is this:
$(document).ready(function() {
// Variables
var firstdiv = 'first';
var seconddiv = 'second';
var thirddiv = 'third';
// Array
var myArray = new Array(firstdiv, seconddiv, thirddiv);
for(var x = 0; x < myArray.length; x++) {
if('$("#' + myArray[x] + '_note1").text() === $.trim("0")') {
'$("#' + myArray[x] + '_desc").hide()';
}
}
});
So far this code is not working. Can anyone help me? Thanks.
You have some extra ' in there.
if($("#" + myArray[x] + "_note1").text() === $.trim("0")) {
$("#" + myArray[x] + "_desc").hide();

Categories

Resources