Create a 'select' drop-down menu in JavaScript - javascript

I'm having a problem in a simply js function. I have a web page where I show records in a table, and when I click on an icon (which stands for 'change this record'), that cell of table should be replaced with a dropdown menu in which the user can select the new value for that record based on the available ones.
I tried in a lot of ways:
function clickOnModifyProfessor(id, professors) {
let select = document.createElement("select");
select.setAttribute("id", id);
for (let i = 0; i < professors.length; i++) {
let el = document.createElement("option");
el.textContent = professors[i]['name'] + " " + professors[i]['surname'];
el.value = professors[i]['professorID'];
select.appendChild(el);
}
//I set id=2 simply to test with one specific record, if it works I'll just set another parameter to generalize the change.
const node = document.getElementById("2");
node.textContent = '';
node.appendChild(select);
}
With this code I just get the empty table cell after clicking on the modify button, but the strange thing is that if I try to create another element (textarea, password etc) it works perfectly, so I can't understand why it does this only with the select element. I also tried by creating the whole select with option elements and taking it to the table cell by the innerHTML, but it doesn't works (as before, it works with others elements that aren't 'select').
If it can help, here is the code fragment where I call this function:
echo "<tr><td>" . $row['subjectName'] . "</td>
<td id='" . $rowsCount . "'>
<p>" . $row['profName'] . " " . $row['profSurname'] . "
<i class='material-icons' onclick='clickOnModifyProfessor(" . json_encode($row['subjectName'], JSON_HEX_APOS) . "," . json_encode($professors, JSON_HEX_APOS) . ")'>create</i>
</p>
</td>
</tr>";
PS: I also tried to print in console document.getElementById(id).innerText after I append the new 'select' element to the document and it prints correctly the options I added.
Am I making an error? I hope it's sufficiently clear.

I answer my own question with the solution I found, maybe it can be helpful for someone.
The problem is that the materialize css' select can't render on browser without starting js before, so it's necessary to add class='browser-default' when we create the select element or, if we want materialize css select style, we need to use $('select').formSelect(); after the select element has been created with its options.

Related

How can I make one cell in a table "content editable" after hitting and edit button in the table

I am working on a permissions page on my site and currently have it sets up with three columns Username Permissions and Action. When I press the Edit button in the Action column I want to be able to edit the Permissions column only in that specific row. Right now I have it setting both the Username and Permissions cell to be contenteditable.
Here is is my definition of my table (data being pulled from DB):
echo "<td class='username'>" . $row['username'] . "</td>";
echo "<td class='permissions'>" . $row['isAdmin'] . "</td>";
echo "<td><input type='button' class='btn btn-primary edit' value='Edit'></td>"
And Here is the script I am currently using to change each column in the row:
var $this = $(this);
var tds = $this.closest('tr').find('td').filter(function () {
return $(this).find('.edit').length === 0;
});
//console.log(tds);
if ($this.val() === 'Edit') {
$this.val('Save');
if($this.id !== '.edit') {
tds.prop('contenteditable', true);
}
}
I need it to only select the <td class='permissions'> in the current row that the button was clicked on.
What is the proper way to select only that cell in the corresponding row?
I've tried multiple ways to try and only select it from tds based on the class but have had no success.
Instead of using the rather complicated construction
var tds = $this.closest('tr').find('td').filter(function () {
return $(this).find('.edit').length === 0;
});
you could simply do
var tds = $(this).closest('tr').find('td.permissions');
to identify the target element to make editable. I assume that this code is part of the 'click'-event function for the "edit" button..
I have made a fully editable HTML Table using DataTables and some custom code. I can't share the whole code though, as it is a closed-source project for work, but I think it will be helpfull.
Take a look at my repo
Some useful notes:
1) I used Mutation Observer Api to track changes in cell values. I stored every changed cell in an array and on clicking 'Save' the array gets sent with AJAX to the back-end.
2) There is a HTML attribute called contenteditable. It lets you edit, well, the content of an element. Use that to edit the cells' values before appending them to the array. Attach an event listener to the 'Edit' button and when it is clicked, add this attribute to all the 'td' elements of your table.
3) You just send the array with values to the back-end and run some simple queries to your database.
Hope it helps you.

Use LIKE operator to select all checkboxes that match pattern

I need a little guidance. I have an HTML form comprised of a very long list of items pulled from an array generated by a database query (it's a list of university courses). Users need to be able to select as many or as few courses as are relevant to their research: because the list can have hundreds or items I have a "select all" and a "select none" function and have added a jQuery shift-select batch selector to make this as easy as possible.
However, I also want them to be able to enter some text in an input box and click APPLY to select all checkboxes where the label text pattern matches using a LIKE operator (i.e., if they want all MATH courses, or all courses of level 2xx). The project is using PHP and JavaScript/jQuery/AJAX.
I know how to pull from the database based on LIKE queries, but I'm just a bit stumped as to how best loop through the generated form and target the items that are in my form. (My PHP is pretty strong, my jQuery is a bit shaky).
The list of checkboxes is generated via a loop through the array with each item set up as follows:
$o .= '<input id="'.$rw[2].'_'.$rw[0].'"
type=checkbox name="' . $rw[2].'_'. $rw[0]. '" />';
$o .= '<label for="'.$rw[2].'_'. $rw[0].'"> ' . $rw[1] . '</label>';
$o .= '</td>';
So we end up with a simple checkbox form with a LABEL FOR and the label text, and the items are all named as the array keys.
This is the HTML output for a typical item:
<tr><td><input id="110_105" type=checkbox name="110_105" />
<label for="110_105"> PHIL233</label></td></tr>
Sorry if this description is a bit long, but what I need is an idea of how to go about looping through the form's elements after it is generated to SELECT the checkbox for every item where the pattern matches.
Hope this makes sense!
Tamra
This situation is perfect for using AJAX to filter the checkbox list. I highly advocate for this instead.
But if you need to filter on the client it's fairly easy with JavaScript.
//give the labels a class so they are easy to find
var labels = document.getElementsByClassName('course-name');
//filtering text field
var query = document.getElementById('query');
//'apply' button
var queryBtn = document.getElementById('query-submit');
queryBtn.addEventListener('click', function() {
for (var i = 0; i < labels.length; i += 1) {
var label = labels[i];
var text = label.innerText;
if (text === query.value) {
label.previousElementSibling.checked = true;
}
}
}, false);
You can try it with jQuery find method.
http://api.jquery.com/find/
With it and the "Attribute Contains Selector", you can do the trick.
http://api.jquery.com/attribute-contains-selector/

Unable to set selected value with easyDropDown.js

I am attempting to use the easyDropDown.js add on to style my drop boxes but I have encountered an issue. My drop box is not statically created. When the webpage is loaded an array is used to append the drop down list. This drop box appears on multiple pages of my website and I am attempting to set it up so that when the user makes a selection on one page, that selection carries to every page.
Here's a step by step play-through of what the code is doing:
When the page is started it appends the easyDropDown list so that all the values are there.
$('#homeSelectSite').empty();
s = "";
s = "<option value='site'>Site</option>";
for (var i = 0; i < Sites.length; i++) {
s = s + "<option value='" + Sites[i].SiteID + "'>" + Sites[i].SiteID + " " + Sites[i].SiteName + "</option>";
}
$('#homeSelectSite').append(s);
Note: Sites is the array that I am using to fill the drop box.
Now once the drop box list has been created I need to set what value is selected. This value is set in the sessionStorrage if the user has made a selection on another page.
$('#homeSelectSite').easyDropDown();
var selectedSite = sessionStorage.getItem("CurrentSiteID");
if (selectedSite != undefined && selectedSite != null) {
$('#homeSelectSite').val(selectedSite);
}
So what the code is doing is this: emptying the current drop box, appending it with new values, styling it with easyDropDown, and finally setting the selected value. For some reason this will not work. The appending and styleing are working just fine but it will not allow me to set the selected value. I have also tried using this:
$('#homeSelectSite').easyDropDown('select', selectedSite);
Is there a reason why I cannot set the selected value? This all works if I remove everything related to easyDropDown.
I had a similar issue today as I was trying to set the selected value of a dropdown using easyDropDown.
What I did to fix it was to find out the index of the to-be selected option, rather than selecting it by value.
In your case it would be something like:
var index = 0;
$('#homeSelectSite option').each(function(i, item) {
if ($(this).val() === selectedSite) {
index = i;
}
});
$('#homeSelectSite').easyDropDown('select', index);
Hope it helps.
it looks like there's a bug in easyDropDown 2.1.4
Line 326 should be changed from:
index = self.$select.find('option[value='+index+']').index() - 1;
to:
index = self.$select.find('option[value='+index+']').index();
This will only solve the fact that easyDropDown was selecting the previous item instead of the one you wanted, but I'm not sure this would solve your issue. And yes, you must use the 'select' method from the plugin instead of 'val'.

How to differentiate the pressed button in later code?

I have trouble with this code..
I'm making a "zoo system", where using button click (its value=type of animal) it adds me new item (<select> of animals) of that type. The problem I have, is that I am not able to determine (because I'm using button, not submit and its $_POSTS), which of the 10 types of animals (10 buttons with different captions (e.g. "Add birds", "Add mammals", etc.) and different values of button) was "chosen" with the click.
And when I "Add birds", I'd like to create not only the <select> with particular birds, but I also want to create next element (e.g. next <select> with the color of its feathers). For each type, I'd like to have different element that I'd like to add to that stable <select>.
In my code, there's newdiv.innerHTML = \"$animals[1]\";, because it is working well if I manually put the value inside (it generates me select of animals with id_type=1).
$anim = array();
$res = mysqli_query($db,"SELECT * FROM animals ORDER BY name");
while ($arr = mysqli_fetch_assoc($res)) {
$anim[$arr['id_type']][] = "<option value='".$arr['id_animal']."'>".$arr['name']."</option>";
$animals[$arr['id_type']]= '<select name=id_anim[]>' . implode(' ', array_values($anim[$arr['id_type']])) . '</select>';
}
$anim_type = "";
$types = mysqli_query($db, "SELECT id_type, name_type FROM type_animals ORDER BY id_type");
while ($t = mysqli_fetch_assoc($types)) {
$anim_type .= "<button type='button' name='atype' value='".$t['id_type']."' onclick=\"zoo('dynamicInput', '".$t['id_type']."');\">Add ".$t['name_type']." </button>";
}
echo"
<script type=\"text/javascript\">
function zoo(divName, atype){
var newdiv = document.createElement('div');
newdiv.innerHTML = \"$animals[1]\";
document.getElementById(divName).appendChild(newdiv);
}
</script> ";
Do you think, it's somehow possible to differentiate which of the button was pressed so I can i.e. in JS have switch where for each number (value of pressed button, value of id_type), I can specify what content should be generated?
Or is it possible to generate content with PHP instead of JavaScript (so I can use something like $_POST - although it's just a button, not a submit)?
How can I use that passed value in JavaScript code, to generate more content due to that value? I see the foolish way, to manually insert 10 values, and for everyone set it's full content. But I'd like to see the smart way (i.e. the stable core, and the switch which generates its own content for each value)..
edit for #tttpapi: the generated code is:
stable: 4x <button type='button' name='atype' value='1-4' onclick=\"zoo('dynamicInput', '1-4');\">Add birds/mammals/beasts/herbivores </button>
generated after "birds" clicked:
<select name=id_anim[]><option value='1'>Parrot</option> <option value='2'>Pelican</option> <option value='3'>Hummingbird</option></select>
And this all is, in latter code coated in:
<form method='POST'><fieldset>
<div name='dynamicInput'></div>
</fieldset></form>
Thanks a lot ;)
You can get the value of the button click with
$button = $_POST["nameOfButton"];
Here replace "nameOfButton" with "atype".
Note: You need to put the same button name tag on the different buttons.

making form elements disappear with javascript

I'm a little new to javascript. I have a bunch of checkboxes for an html form. The checkboxes are dynamically generated from a python script. The last checkbox I have is entitled "N/A", I want to make it so that if any of the other checkboxes are checked, the "N/A" checkbox automatically disappears. If the N/A checkbox is checked, the others disappear. And of course, if I uncheck the boxes, the opposite should occur. I know that i need to assign the different input fields different id's so javascript can identify them, but I'm not sure how to write the javascript to make the actual disappearing action to occur.
Thank you.
edit;; Some dynamic python code:
print "<blockquote><strong>Labels:</strong><br/>"
for elem in output_list:
if elem not in non_delete_list:
print "<input type=\"checkbox\" name=\"remove_cd\" value=\"" + elem + "\" />" + elem + "<br/>"
print "<input type=\"checkbox\" name=\"remove_cd\" value=\"r_on\" />N/A:"
print_reason_list()
print "<font color=\"#cc0000\">Reason Required</font><hr/>"
So basically, anything with the value=elem part is dynamic, the final checkbox is N/A (value="r_on").
edit 2:
So I'm able to get the boxes to disappear thanks to #Ankit (using document....style.display= "none"). The issue I'm having is that once a box is checked, respective id becomes PERMANENTLY hidden. In order to fix this, I made a hide and unhide function and my onclick looks like:
"onclick=if(this.checked){hide("NA")}else{unhide("NA")}"
And that allows me to uncheck the boxes and cause the respective tags to reappear. I'm running into a new issue however. With the checkboxes of value elem. If I check two boxes, and then uncheck one of the boxes, the "NA" appears again. I want it to remain hidden as long as there is an "elem" box that is checked. Basically, I need to rescan all the checkboxes to see their current states (I think). How can I do this?
You can enable/disable an html element through javascript with:
document.getElementById('<the id of your checkbox here>').disabled = true;
For your case just put a div tag around the dynamic check boxes and add/remove that div based on your need.
Example:-
print "<blockquote><strong>Labels:</strong><br/>"
for elem in output_list:
if elem not in non_delete_list:
print "<div id=\"listBox\" >"
print "<input type=\"checkbox\" name=\"remove_cd\" value=\"" + elem + "\" onclick=\"if(this.checked){myFunction("upperChkBoxes")}\" />" + elem + "<br/>"
print "</div>"
print "<input type=\"checkbox\" name=\"remove_cd\" value=\"r_on\" onclick=\"if(this.checked){myFunction("NA")}\" />N/A:"
print_reason_list()
print "<font color=\"#cc0000\">Reason Required</font><hr/>"
function myFunction(par){
// put your logic of add/remove here based on par value as "upperChkBoxes" or "NA"
}
Hope that helps.
You could show or hide an html element using css property display none
to make it disappear
document.getElementById('<the id of your checkbox here>').style.display = "none";
or to show back
document.getElementById('<the id of your checkbox here>').style.display = "block";
If you are using jquery you could easily use to accomplish the same
$('#id of the checkbox').hide() or $('#id of the checkbox').show()

Categories

Resources