How can I change selected option based on database value? - javascript

In order to get you familiar with my work, I have table filled with data from database and it's basically CRUD - Create, Read, Update, Delete table.
Now, I have one table column where are EDIT and DELETE buttons placed. When I click on EDIT button, Bootstrap 5 modal pop-ups and inside of that modal there're <input> elements, also filled with data from database. Everything works fine (is filled correctly and based on ID of selected row) except that I can't get <select> to change its value on value from database.
Here's my <select> element (HTML):
<div class="mb-3">
<select name="carStatus" id="carStatus" class="form-control form-control-lg" required>
<option value="U obradi" selected disabled hidden></option>
<option value="Na cekanju">Na cekanju</option>
<option value="U procesu">U procesu</option>
<option value="Zavrseno">Zavrseno</option>
</select>
<div class="invalid-feedback">Niste unijeli status!</div>
</div>
This is js code where I handle values of input fields inside of modal:
// Fill in values and handle edit event
tbody.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.editLink")) {
e.preventDefault();
let id = e.target.getAttribute("id");
editUser(id);
}
});
const editUser = async (id) => {
const data = await fetch(`action.php?edit=1&id=${id}`, {
method: "GET",
});
const response = await data.json();
//Here I am handling value of carStatus (<select>)
if(response.carStatus == "Na cekanju"){
selectElement("carStatus", 'Na cekanju');
}
else if(response.carStatus == "U procesu"){
selectElement("carStatus", 'U procesu');
}
else if(response.carStatus == "Zavrseno"){
selectElement("carStatus", 'Zavrseno');
}
else{
selectElement('carStatus', '');
}
//There are a lot of others element that I handle on the way like this:
document.getElementById("id").value = response.id; //This works
enter code here
//But I didn't want to put all of them because it'd take too much space...
//Here's my function where I am trying to handle value of selected element:
function selectElement(request, valueToSelect) {
let element = document.getElementById(request);
element.value = valueToSelect;
//Also I am getting the correct value -> when I select some row where Zavrseno is placed I really get Zavrseno in console...
console.log(response.carStatus);
}
};
Ohh, by the way there are 4 possible values that can be selected:
"U obradi", "Na cekanju", "U procesu", "Zavrseno"

I actually found out what's the reason why my code didn't work, even though it should've worked perfectly fine, because code itself was written correctly.
The problem was I also had the add modal at the same page with same id which was carStatus (id="carStatus"). Removing it was enough to fix the problem.
Now, the thing is I know that you can't have same id's at the same page, but can somebody explain me why's element which is placed inside Add modal causing problem when I am triggering this action on edit button?

Related

How to serialize just one value of input via jQuery?

I started to do dropdown list instead select bcz it is not possible to stylize but I did not think to future and now I found that if I want to save data from form to db I need to get ids via $_POST instead of names.
For ex. I have dropdown list with status of product:
New
Old
Handmade
If I want to save chosen sattus for chosen product it is better for me to get ID of status option. Bcz my table is like this:
item_id | option_value
1 | 1
If I send name as "old" via $_POST, I need to get its ID from another table before insert it.
I created dropdown list like this:
/* SELECT REPLACED BY DIV JS */
var select = $('.add-item__select').hide(); // Hide original select options
// Replace each select by div
select.each(function() {
var selectVal = $(this).find('.add-item__select-main').text(),
name = $(this).attr('name');
newDropdownDiv = $('<input class="add-item__input-select" name="' + name + '" placeholder="' + selectVal + '" readonly required><i class="arrow down"></i></input>')
.insertAfter($(this))
.css({paddingLeft: '0.3em', cursor: 'pointer'});
});
Each SELECT has addaed INPUT after it.
If I want to show shosen vale from dropdown list I need to show it in this way:
$('.add-item__input-select').val("text copied from list");
After this if I add ID of option to input in this way:
$('.add-item__input-select').attr("value", optionID);
Then If I want to serialize all fields values from form and this is point,
$('.add-item__form').serializeArray()
I get two results for status:
name: "status", value: "text copied from list"
and
name: "status", value: optionID
But I need just optionID.
I have everything optimized for this structure, so I would like to ask you if there is some easy way how to fix it or I need to modify structure.
I am thinking to remove INPUT and just change SELECT opacity to 0 instead of display none and use SELECT for form data serialize. But then I will need to replace all INPUTs by some DIV which will hold text of chosen option and also change everything else connected with it. For ex, if user clicked on INPUT the label was showed above it.
Thanks for advices
I found one solution but I have problem that it is working just if user will not refresh page. In DOM is everything the same after refresh but serializeArray() get just input text value and not value="ID" after page refresh.
I just remove these values which I do not want from FormData.
// Send formData to upload.php
$('.add-item__form').on('submit', function() {
event.preventDefault();
event.stopPropagation();
if ( checkFieldsIfNotEmpty() == true ) {
var formDataFields = $('.add-item__form').serializeArray(), // Get all data from form except of photos
count = Object.keys(data).length; // count fields of object
// Fill formData object by data from form
$.each(formDataFields, function(index, value) {
if ( value.name === 'category' && !$.isNumeric(value.value) || value.name === 'subcategory' && !$.isNumeric(value.value) ) {
// do nothing
} else if ( (value.name.indexOf('filter') >= 0) && !$.isNumeric(value.value) ) {
// do nothing
}
else {
formData.append(value.name, value.value); // add name and value to POST data
}
});
// foreach - fill formData with photos from form
$.each(data, function(index, value) {
formData.append('files[]', value);
});
uploadData(formData); // send data via ajax to upload.php
}
});
Can you advice me what can be problem?

showing undefined data and cannot find my dropdown id

I have question about the query selector, because I am passing a lot of function for my textboxes that will update different chart when using the dropdown list. I am always getting undefined in my console.log() Undefined screenshot this is my drop down Dropdown Screenshot.
const selectory = $('#needed').filter(":selected").val();
//const selectory = $("div.chartNine select").val();
function interactiveChart() {
console.log(selectory)
console.log(bzvaqxnufhyd1.value)
if (selectory == 'vdn6') {
updatingValue = [bzvaqxnufhyd1.value, bzvaqxnufhyd2.value, bzvaqxnufhyd3.value, bzvaqxnufhyd4.value, bzvaqxnufhyd5.value, bzvaqxnufhyd6.value, bzvaqxnufhyd7.value];
nineChart2.data.datasets[0].data = updatingValue;
nineChart2.update();
nineChart2.render(); }
}
needed is my id tag for my select under the div chartNine.
and this is my textbox
<input type="text3" id="bzvaqxnufhyd1" onchange="interactiveChart()" value="0" />
I will be using that function for 7 different charts that is why I need to have that select value so whenever I selected a new drop down, if else will do the magic in my interactiveChart function.
I hope someone can help me or lighten me up regarding my situation. Thank you.
Solved. I just added multifunction on my textbox which is this one.
<input type="text3" id="bzvaqxnufhyd1" onchange="interactiveChart()" value="0" />

How to make divs which are created when a form is submitted, remain in place when the form is resubmitted

I am making a webpage where the user can use a form to search for a string and then divs will appear showing rows with matching info from a database. Then when a checkbox is clicked on a row it will move up to another div. I would like for the rows which have been selected via the checkbox to remain where they are when the form is resubmitted but still disappear when the checkbox is unclicked.
I have taken this video to show how it is currently working, which should hopefully make my question make sense.
https://imgur.com/a/DmkP0ut
This is the code for my form
<form action = "" method = "POST">
<div class = "searchcontainer">
<input id = "search" type="search" name = "search" class = "textbox" placeholder
= "Type the students name and press Enter to search...">
<input type = "submit" style="display:none" id = "submitsearch"/>
</div>
</form>
Then when the form is submitted this code will run to create the divs that appear (This is just a really short version, let me know if you need to see all of it)
<?php
if(isset($_POST['search'])){
$input = $_POST['search'];
$result = $conn->query("select * from logins");
let r<?php echo $studentid ?> = document.createElement("div");
r<?php echo $studentid ?>.id = "r<?php echo $studentid ?>";
r<?php echo $studentid ?>.className = "rowcontainer";
document.getElementById("tablecontainer").appendChild(r<?php echo $studentid ?
>);
Then this is the Javascript code which moves the rows to the 'selected' container when the checkbox is ticked and back to the 'tablecontainer' when unckecked.
<script>
const main = document.querySelector(".tablecontainer");
const selected = document.querySelector(".selected");
main.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("move")) {
const rowContainer = tgt.closest(".rowcontainer");
if (tgt.checked) {
selected.append(rowContainer);
}
}
})
selected.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("move")) {
const rowContainer = tgt.closest(".rowcontainer");
main.append(rowContainer)
}
})
</script>
From what I found online it looks like I will need to se session variables to keep the rows in place once they have been selected, but I dont really know how to do this, so help would be appreciated.
Thanks
Edit: I have a had a look through these answers but as a beginner they do not make much sense to me. I have found that I can use
var rowsselected = document.getElementById("selected").children;
to get a list of all the children divs in my selected div, so is there a way I can save this list so it persists when the form is resubmitted and take the children from this list and append them to selected again. If you could show examples that would be good. Also I should have mentioned this in the main post but I would also like to carry over info from the rows which have been selected to the next page so if I could make the ids of these rows into session variables or something like that that would be good.

Setting values of dynamically added input fields changing all input fields

I have a form where users can create recipes. I start them off with one ingredient field (among others) and then use .append() to add as many more as they want to the div container that holds the first ingredient. The first input field has an id of IngredientName1 and dynamically added input fields are IngredientName2, IngredientName3, etc.
When they start typing in the input field, I pop a list of available ingredients filtered by the value they key into IngredientNameX. When they click on an ingredient in the list, it sets the value of the IngredientNameX field to the text from the div - like a search & click to complete thing. This all works very well; however, when you add IngredientName2 (or any beyond the one I started them with initially) clicking on an available ingredient sets the values of every single IngredientNameX field. No matter how many there are.
I hope this is enough context without being overly verbose, here's my code (I've removed a lot that is not relevant for the purpose of posting, hoping I didn't remove too much):
<div id="ingredientsContainer">
<input type="hidden" id="ingredientCounter" value="1">
<div class="ingredientsRowContainer">
<div class="ingredientsInputContainer"><input class="effect-1 ingredientsInput" type="text" name="IngredientName1" placeholder="Ingredient" id="IngredientName1" data-ingID="1"><span class="focus-border"></span></div>
</div>
<input type="hidden" name="Ingredient1ID" id="Ingredient1ID">
</div>
<script>
$(document).ready(function(){
$(document).on('keyup', "[id^=IngredientName]",function () {
var value = $(this).val().toLowerCase();
var searchValue = $(this).val();
var valueLength = value.length;
if(valueLength>1){
var theIngredient = $(this).attr("data-ingID");
$("#Ingredients").removeClass("hidden")
var $results = $('#Ingredients').children().filter(function() {
return $(this).text() === searchValue;
});
//user selected an ingredient from the list
$(".ingredientsValues").click(function(){
console.log("theIngredient: "+theIngredient);//LOGS THE CORRECT NUMBER
var selectedIngredientID = $(this).attr("id");
var selectedIngredientText = $(this).text();
$("#IngredientName"+String(theIngredient)).val(selectedIngredientText);//THIS IS WHAT SETS EVERYTHING WITH AN ID OF IngredientNameX
$("#Ingredient"+String(theIngredient)+"ID").val(selectedIngredientID);
$("#Ingredients").addClass("hidden");
});
$("#Ingredients *").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
} else {
$("#Ingredients").addClass("hidden")
}
});
$("#AddIngredient").click(function(){
var ingredientCounter = $("#ingredientCounter").val();
ingredientCounter++;
$("#ingredientCounter").val(ingredientCounter);
$('#ingredientsContainer').append('\
<div class="ingredientsRowContainer">\
<div class="ingredientsInputContainer"><input class="effect-1 ingredientsInput" type="text" name="IngredientName'+ingredientCounter+'" placeholder="Ingredient" id="IngredientName'+ingredientCounter+'" data-ingID="'+ingredientCounter+'"><span class="focus-border"></span></div>\
</div>\
<input type="hidden" name="Ingredient'+ingredientCounter+'ID" id="Ingredient'+ingredientCounter+'ID">\
');
});
});
</script>
[UPDATE] I realized the problem is happening because the function is running multiple times. I assume this happening because I'm calling a function on keyup of a field whose id starts with IngredientName so when one has a key up event, all existing fields run the function. How do i modify my:
$(document).on('keyup', "[id^=IngredientName]",function () {
to only run on the field with focus?

Angular UI-Bootstrap Typeahead: Accept top item as selected on ENTER

Simple question, but is there a way to have the first item in the dropdown results be the selected item when ENTER is pressed?
An example of this is the user types in "PC0" and sees "PC001" listed as the first option, can we have it use "PC001" on the typeahead-on-select option when ENTER is hit?
I am currently using typeahead-on-select to run a function that calls the input via id and grabs the Value for use in the function. It seems to use what was entered into the textbox instead of the selected value, either on ENTER or Click.
HTML:
<input id="applicationComboBox"
type="text"
ng-model="applicationComboBox"
uib-typeahead="a as a.Value for a in applicationList | filter:$viewValue"
typeahead-on-select="getApplication()"
class="form-control">
JS for the getApplicationValue() looks like this:
$scope.getApplication = function () {
$scope.ApplicationValue = applicationComboBox.value;
}
The issue is the applicationComboBox.value is what text the user has typed into the input at the time of the click/enter instead of the clicked/highlighted value respectively. So in previous example "PC0" would be the value instead of "PC001".
When the user selects/press enter the ng-model applicationCombox is is updated automatically. If you want another value $scope.ApplicationValue to be updated after the selection, do the following
$scope.applicationCombox = ""; //your existing model.
$scope.getApplication = function () {
$scope.ApplicationValue = $scope.applicationCombox;
}
Let us know.
I was able to get a solution that worked for me.
HTML:
<input id="applicationComboBox"
type="text"
ng-model="applicationComboBox"
uib-typeahead="a as a.Value for a in applicationList | filter:$viewValue"
typeahead-on-select="onApplicationSelect($item, $model, $label, a)"
class="form-control">
JS:
$scope.onApplicationSelect = function (item, model, label, application) {
applicationComboBox.value= item.Value;
}

Categories