Remove time from dynamically generated dropdown - javascript

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.

Related

Create Dynamic PHP Variables (Echoed Out) from JavaScript For Loop

I am attempting to cut down on some Javascript functions. Right now my current design I dynamic create Year list using Javascript. Now that I have it update the current selected value from the value stored in the database I am wondering if I can duplicate this across all the Year list that I have created. There are 10 in total.
Current code:
for (a = 1; a <= 1; a++) {
console.log("STARTING");
// reference to a specific dropdown list
var ddYears = $("#ddYears" + a + "");
console.log(ddYears);
var theStartYear = "$we" + a + "startyear";
console.log(theStartYear);
var ddCurrentSelectedYear = '<?php echo ' + theStartYear + '; ?>'; // THIS IS THE LINE I'M HAVING TROUBLE WITH
console.log(ddCurrentSelectedYear);
var initialOption = $("<option/>");
if (ddCurrentSelectedYear == "") {
initialOption.html("Year");
initialOption.val("");
initialOption.attr('selected', 'selected');
}
ddYears.append(initialOption);
//Loop and add the Year values to DropDownList.
for (var i = currentYear; i >= 1920; i--) {
var option = $("<option />");
if (i == ddcurrentSelectedYear) {
option.attr('selected', 'selected');
}
option.html(i);
option.val(i);
ddYears.append(option);
}
}
I'm trying to "hardcode" the variable so when it iterates through it can pick up from my PHP that value that should already be stored in a variable. I can do it with one value but I would like it to do it for 10 values so I don't have to make 10 separate functions for 1 PHP call. As the 'A' increments the variable is named the same in the backend meaning that value could potentially exist. I am not very good with JavaScript so it may be that my syntax is wrong.
Again, I can't emphasis this enough based off what I have seen on stackoverflow when I do call that line (that has I'm having trouble with it) like shown below it will retrieve a value from my PHP.
var ddcurrentSelectedYear = '<?php echo $we1startyear; ?>';
Does anyone see any issues with my JavaScript syntax?
Edit 1: There seems to be some confusion as to what I'm doing so I am placing some code below this that I'm currently using and it works. You will see all that changes is instead of the for loop I'm accessing it as a hardcoded name. The number is the only thing changing in the html selector and the PHP outputted variable. That is the whole purpose of what I'm trying to achieve with the for loop is instead of writing this function 20+ times for a character change have a for loop do the heavy lifting for me.... (Let me reinstate my question - Is there any way to write one function for what I'm currently doing below?
$(function () {
var ddYears = $("#dd1Years");
var ddCurrentSelectedYear = '<?php echo $we1startyear; ?>';
// create intial blank option
var initialOption = $("<option />");
if (dd1currentSelectedYear == "") {
initialOption.attr('selected', 'selected');
}
initialOption.html("Year");
initialOption.val("");
ddYears.append(initialOption);
//Loop and add the Year values to DropDownList.
for (var i = currentYear; i >= 1920; i--) {
var option = $("<option />");
if (i == dd1currentSelectedYear) {
option.attr('selected', 'selected');
}
option.html(i);
option.val(i);
ddYears.append(option);
}
}
$(function () {
var ddYears = $("#dd2Years");
var ddCurrentSelectedYear = '<?php echo $we2startyear; ?>';
//Loop and add the Year values to DropDownList.
for (var i = currentYear; i >= 1920; i--) {
var option = $("<option />");
if (i == ddCurrentSelectedYear) {
option.attr('selected', 'selected');
}
option.html(i);
option.val(i);
ddYears.append(option);
}
}
$(function () {
var ddYears = $("#dd3Years");
var ddCurrentSelectedYear = '<?php echo $we3startyear; ?>';
//Loop and add the Year values to DropDownList.
for (var i = currentYear; i >= 1920; i--) {
var option = $("<option />");
if (i == ddCurrentSelectedYear) {
option.attr('selected', 'selected');
}
option.html(i);
option.val(i);
ddYears.append(option);
}
}

Cant call Jquery function in if loop

my first ever question pretty sure I'm being a bit daft here, but am a beginner and would appreciate your help.
Im working on a webpage where there is a html table listing several columns of data.
When the page loads it runs a jquery script which counts the different types of "incidents" and plots them in another table which then another jquery script populates a graph.
I have a third script (javascript) which after a button is clicked, runs an if loop, which looks at the data in the first column and if it does not match the criteria then the row is deleted.
So far so good, the issue is that I want the script which populates the table for the graph to run again, but Im not sure how to call it from my if loop.
Ive put the two scripts below, basically I want to call the 1st script in the second script.
$(function () {
var NumFireAlarms = $("#incidents tr:contains('Fire Alarm')");
$("#result").html(NumFireAlarms.length + " Fire Alarm");
var firealarms = NumFireAlarms.length;
document.getElementById("no_of_incident_type").rows[1].cells[1].innerHTML = firealarms
var NumLockout = $("#incidents tr:contains('Lockout Out of Office Hours')");
$("#result").html(NumLockout.length + " Lockout Out of Office Hours");
var lockouts = NumLockout.length;
document.getElementById("no_of_incident_type").rows[2].cells[1].innerHTML = lockouts
var NumLockoutDayTime = $("#incidents tr:contains('Lockout Day Time')");
$("#result").html(NumLockout.length + " Lockout Day Time");
var lockoutsDayTime = NumLockoutDayTime.length;
document.getElementById("no_of_incident_type").rows[3].cells[1].innerHTML = lockoutsDayTime
var NumSensitiveIncident = $("#incidents tr:contains('Sensitive Incident')");
$("#result").html(NumSensitiveIncident.length + " Sensitive Incident");
var SensitiveIncident = NumSensitiveIncident.length;
document.getElementById("no_of_incident_type").rows[4].cells[1].innerHTML = SensitiveIncident
});
function filterForGraph() {
var incident_category = document.getElementById("Incident_Category").value;
var start_date = document.getElementById("start_date").value;
var end_date = document.getElementById("end_date").value;
var staff_type = document.getElementById("Job_Title").value;
var i;
var count = 0;
var table_length = document.getElementById("incidents").rows;
var TL = table_length.length;
for (i = TL - 1; i >= 1; i--)
{
var category_column = document.getElementById("incidents").rows[i].cells.item(0).innerHTML;
var date_column = document.getElementById("incidents").rows[i].cells.item(1).innerHTML;
var staff_colunm = document.getElementById("incidents").rows[i].cells.item(8).innerHTML;
if (category_column === incident_category)
{
alert("yay")
count++
}
else if (category_column !== incident_category)
{
alert("boo")
document.getElementById("incidents").deleteRow(i);
//CALL FIRST SCRIPT HERE??
}
}
}
I removed a few bits of code that did not seem to do anything, but I'm sure you can put them back. I think you might want something like this:
function updateTable(){
var elResult = document.getElementById("result");
var elNumIncidentType = document.getElementById("no_of_incident_type");
var firealarms: document.querySelectorAll("#incidents tr:contains('Fire Alarm')").length;
var lockouts: document.querySelectorAll("#incidents tr:contains('Lockout Out of Office Hours')").length;
var lockoutsDayTime: document.querySelectorAll("#incidents tr:contains('Lockout Day Time')").length;
var sensitiveIncident: document.querySelectorAll("#incidents tr:contains('Sensitive Incident')").length;
elResult.innerHTML = "";
elResult.innerHTML += "<div>" + firealarms + " Fire Alarm</div>";
elResult.innerHTML += "<div>" + lockouts + " Lockout Out of Office Hours</div>";
elResult.innerHTML += "<div>" + lockoutsDayTime + " Lockout Day Time</div>";
elResult.innerHTML += "<div>" + sensitiveIncident + " Sensitive Incident</div>";
elNumIncidentType.rows[1].cells[1].innerHTML = firealarms;
elNumIncidentType.rows[2].cells[1].innerHTML = lockouts;
elNumIncidentType.rows[3].cells[1].innerHTML = lockoutsDayTime;
elNumIncidentType.rows[4].cells[1].innerHTML = sensitiveIncident;
}
function filterForGraph() {
var elIncidents = document.getElementById("incidents");
var incident_category = document.getElementById("Incident_Category").value;
var table_length = document.getElementById("incidents").rows.length;
for (var i = table_length - 1; i >= 1; i--) {
var currentIncident = elIncidents.rows[i].cells;
var category_column = currentIncident.item(0).innerHTML;
if (category_column != incident_category) { elIncidents.deleteRow(i); }
}
updateTable();
}
$(function(){ updateTable(); });
Hi JonSG tried your code and it didnt work not sure why, but it gave me some ideas to work with and I think Ive cracked it
function Populate_Incident_No_Table() {
//previously function called updateTable
$(function () {
var NumFireAlarms = $("#incidents tr:contains('Fire Alarm')").length;
document.getElementById("no_of_incident_type").rows[1].cells[1].innerHTML = NumFireAlarms
var NumLockout = $("#incidents tr:contains('Lockout Out of Office Hours')").length;
document.getElementById("no_of_incident_type").rows[2].cells[1].innerHTML = NumLockout
var NumLockoutDayTime = $("#incidents tr:contains('Lockout Day Time')").length;
document.getElementById("no_of_incident_type").rows[3].cells[1].innerHTML = NumLockoutDayTime
var NumSensitiveIncident = $("#incidents tr:contains('Sensitive Incident')").length;
document.getElementById("no_of_incident_type").rows[4].cells[1].innerHTML = NumSensitiveIncident
});
}
function filterForGraph() {
var incident_category = document.getElementById("Incident_Category").value;
var i;
var TL = document.getElementById("incidents").rows.length;
for (i = TL - 1; i >= 1; i--)
{
var category_column = document.getElementById("incidents").rows[i].cells.item(0).innerHTML;
if (category_column !== incident_category)
{
document.getElementById("incidents").deleteRow(i);
}
}
Populate_Incident_No_Table();
drawGraph();
}
I think the issue was how I was trying to call the functions. So what I've done to achieve what I wanted (please excuse any bad terminology / phrasing).
First I tried to name the function $(function updateTable(){ this did not work when I then tried to call the function like this updateTable();
Second thing I tried was putting the updateTable() function "inside" a function and call that function. This has worked for me I dont know why.
Thanks for your help without it I would not have thought to try what I did

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

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

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/

Sorting disrupts the changing of nr

I have a problem with the sorting of a Javascript list. The list that is created when a text area is filled and a grading is chosen. It looks like this:
var element = '<li class="lista">' + filmen + '<span class="betyg">' + changeNumber(grade) + '</span></li>';
film_list.append(element);
I also have a function that converts the number in the span element to stars, it looks like this:
function changeNumber(number) {
var stars = "";
for(var i = 0; i < number; i++) {
stars += "*";
}
return stars;
}
The problem is that there are two buttons to sort the list, high and low depending on the grade, and when I push the buttons the list is sorted correctly. However, the stars disappear and the numbers turn up again. I have tried to call the function changeNumber from the sorting button but it doesn't seem to work. I'm not sure what I should use as the argument. Any suggestions as to what I should do?
The sorting function looks like this:
var button_high = $('#high');
var betyg_array = new Array();
button_high.click(function () {
$list = $("#filmerna ul");
$("#filmerna ul li")
.remove();
betyg_array.sort(function (x, y) {
return y[1] - x[1]
});
$.each(betyg_array, function () {
$nyFilm = $("<li />");
$nyFilm.attr("class", "lista")
$nyFilm.text($(this)[0]);
$nyBetyg = $("<span />");
$nyBetyg.attr("class", "betyg");
$nyBetyg.text($(this)[1]);
$nyBetyg.appendTo($nyFilm);
$nyFilm.appendTo($list);
changeNumber();
});
});
var button_high = $('#high');
var betyg_array = new Array();
button_high.click(function () {
$list = $("#filmerna ul");
$("#filmerna ul li")
.remove();
betyg_array.sort(function (x, y) {
return y[1] - x[1]
});
$.each(betyg_array, function () {
$nyFilm = $("<li />");
$nyFilm.attr("class", "lista")
$nyFilm.text($(this)[0]);
$nyBetyg = $("<span />");
$nyBetyg.attr("class", "betyg");
$nyBetyg.text($(this)[1]);
var stars = $nyBetyg.text(betyg_array); //this line and the line below was the solution
$nyBetyg.text(changeNumber(stars));
$nyBetyg.appendTo($nyFilm);
$nyFilm.appendTo($list);
});
});

Categories

Resources