Does not load for loop data in the dynamically created fields - javascript

I can see the list of components normally but when I use the "Add more" functionality it refuses to load the data. Any idea why?
Normal select which loads data from for loop (HTML page):
<select name="component" data-live-search="true" id="component" class="form-control" title="Dropdown field">
{% for i in component %}
<option value="{{i.id}}">{{i.name}}</option>
{% endfor %}
(Inspect page)
<select name="component" data-live-search="true" id="component" class="form-control" title="Dropdown field">
<option value="2">test2</option>
<option value="3">sdf</option>
<option value="4">qwerty</option>
<option value="5">qwerty</option>
<option value="6">example</option>
</select>
Now I'm dynamically creating fields using createElement and setAttribute
(HTML page)
var field = document.createElement('select');
field.setAttribute('name','component');
field.setAttribute('data-live-search','true');
field.setAttribute('id','component');
field.setAttribute('class','form-control');
field.setAttribute('title','Dropdown field');
survey_options.appendChild(field);
But this does not contain the data from the for loop similar to the normal select function. Am I missing something?
(Inspect page)
<select name="component" data-live-search="true" id="component" class="form-control" title="Dropdown field"></select>

You need to create dynamic element with different id and append the options from rendered element. Check the below snippet
function appendNewDynamicComponent() {
var survey_options = document.querySelector("#survey_options");
var field = document.createElement('select');
// Create a random number
var random = +(Math.random() * 1e5).toFixed(0) + Date.now();
field.setAttribute('name', 'component');
field.setAttribute('data-live-search', 'true');
// Append random number to id to make it unique for newly created element
field.setAttribute('id', 'component_' + random);
field.setAttribute('class', 'form-control');
field.setAttribute('title', 'Dropdown field');
survey_options.appendChild(field);
// Below two lines would update the options for dynamicay created elements from the already rendered element
field.innerHTML = document.querySelector('select#component').innerHTML;
field.selectedIndex = -1;
}
#survey_options [name="component"] {
margin: 8px;
}
<div id="survey_options">
<select name="component" data-live-search="true" id="component" class="form-control" title="Dropdown field">
<option value="2">test2</option>
<option value="3">sdf</option>
<option value="4">qwerty</option>
<option value="5">qwerty</option>
<option value="6">example</option>
</select>
</div>
<br/>
<button onclick="appendNewDynamicComponent()">
Add Dynamic Component
</button>

Related

Remove option with certain text from dropdown menu

In my Django app (using {% load crispy_forms_tags %}) I have a following dropdown menu:
<div id="div_id_report_division" class="form-group">
<label for="id_report_division" class=" requiredField">Test<span class="asteriskField"></span</label>
<div class="">
<select name="report_division" class="select form-control" required="" id="id_report_division">
<option value="" selected="">---------</option>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
<option value="4">D</option>
<option value="5">E</option>
</select> </div> </div>
I wish to remove option number 5 on page load. My Javascript on post.html with everything is:
<script type="text/javascript">
function on_load(){
/*
option 1.:
document.querySelector('id_report_division option[value=5]').remove();
option 2.:
var x = document.getElementById('id_report_division');
x.remove(5);
option 3.:
document.querySelector('#id_report_division option[value=5]').remove();
const first = document.querySelector("[id='id_report_division']");
*/
document.querySelector("[id='id_report_division' option[value=5]]").remove();
}
on_load();
</script>
How can I easly remove this option? It would be better if I could remove option where text is E, in case that value changes. But there will always be only one text 'E', no need to itterate.
You can iterate the select options list, check the inner text and remove like so:
var selectobject = document.getElementById("id_report_division");
for (var i=0; i<selectobject.length; i++) {
if (selectobject.options[i].text == 'E')
selectobject.remove(i);
}

Clone or Add more fields using jquery including the functionality

So I have a select group of reason and other select-group for subreason. I want to add more reason but as soon as I click on the button the same field appear but it changes the value of above fields too. I need them to be independent but also perform the (reason -subreason).
Code
<div class="tab" id="add_reason">
<h4 class="card-title">Reason</h4><Br>
<label for="roads">Select Branch</label>
<select name="reason[]" id="reason" class="form-control required">
<option value="">Reasons</option>
<option class="road" value="Road">Road</option>
<option class="driver" value="Driver">Driver's Fault</option>
</select><br>
<select id="subreason" name="subreason[]" class="form-control">
<optgroup label="Road" required>
<option>Pot Holes</option>
<option>No boards at starting and ending point of Bridge</option>
<option>No Painting to Divider</option>
<option>Speed Breaker without Zebra Crossing</option>
</optgroup>
<optgroup label="Driver" required>
<option>Lane Cutting</option>
<option>Overtaking from Wrong side</option>
<option>Corner Overtaking</option>
</optgroup>
</select>
<button type="button" class="btn btn-primary" id="btn-reason">Add Reasons</button>
</div>
Script
$(document).ready(function(){
var $optgroups = $('#subreason > optgroup');
$("#reason").on("change",function(){
var selectedVal = this.value;
$('#subreason').html($optgroups.filter('[label="'+selectedVal+'"]'));
});
});
$(document).ready(function(){
$("#btn-reason").click(function(){
$('#add_reason').clone(true).appendTo('#add_reason');
});
});
The first thing to know about jQuery .clone() is that it creates new DOM elements from some existing ones.
That implies the same rules as any other dynamically created elements:
Do not use ids
Delegate event handlers
Additionnally, the cloned set of elements cannot be appended multiple places... So, to use it as a templating trick, you have to clone twice. Once on page load (to save them before any change occurs) and once again when appending somewhere.
$(document).ready(function() {
// Cloned "templates"
let reason_wrapper = $(".reason-wrapper").clone()
var $optgroups = $(".subreason > optgroup").clone()
// "delegated" event handler for any existing or future .reason element
$(document).on("change", ".reason", function() {
var selectedVal = this.value;
$(this)
.closest(".reason-wrapper")
.find(".subreason")
.html($optgroups.clone().filter('[label="' + selectedVal + '"]'));
});
// "delegated" event handler for any existing or future .btn-reason element
$(document).on("click", ".btn-reason", function() {
reason_wrapper.clone().appendTo("#add_reason");
});
});
.reason-wrapper {
margin-top: 1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tab" id="add_reason">
<h4 class="card-title">Reason</h4>
<div class="reason-wrapper">
<label for="roads">Select Branch</label>
<select name="reason[]" class="reason form-control required">
<option value="">Reasons</option>
<option class="road" value="Road">Road</option>
<option class="driver" value="Driver">Driver's Fault</option>
</select>
<br>
<select name="subreason[]" class="subreason form-control">
<optgroup label="Road" required>
<option>Pot Holes</option>
<option>No boards at starting and ending point of Bridge</option>
<option>No Painting to Divider</option>
<option>Speed Breaker without Zebra Crossing</option>
</optgroup>
<optgroup label="Driver" required>
<option>Lane Cutting</option>
<option>Overtaking from Wrong side</option>
<option>Corner Overtaking</option>
</optgroup>
</select>
<button type="button" class="btn btn-primary btn-reason">Add Reasons</button>
</div>
</div>

Only send data from html form select is it is active

I have a series of select parts of a form, the javascript hides multiple possibilities for the following dropdown until the current drop down has a selection made, this determines which dropdown the user sees using the style="display:none;" attribute and javascript to switch it to block, .css({'display':'block'});.
The problem is that each <select> segment has the same name, e.g. <select class="form-control" name='phylum' id="sel1_1" style="display:none;"> this name='phylum' is used in the post phase of the form and needs to be associated with whichever dropdown list is used, but all of these have the default as 0 so if this is set it is overwritten by the final select in the list.
In javascript I therefore need to disable the html code, switching display:none; to display:block; has no effect as it is style only. Could I add disabled to all the <select> elements and somehow activate the required one?
Some example html and javascript snippets follow.
html
<div class='col-12 left'>
<div class='form-group'>
<label id="sel1_0" style="display:none;" for='uname'>Phylum/Division</label>
<select class="form-control" name='phylum' id="sel1_1" style="display:none;">
<option value="phylum" data-value="0">Choose</option>
<option value="Annelid" data-value="1">Annelid</option>
<option value="Arthropod" data-value="2">Arthropod</option>
<option value="Bryozoa" data-value="3">Bryozoa</option>
<option value="Chordata" data-value="4">Chordata</option>
<option value="Cnidaria" data-value="5">Cnidaria</option>
<option value="Echinoderm" data-value="6">Echinoderm</option>
<option value="Mollusc" data-value="7">Mollusc</option>
<option value="Nematode" data-value="8">Nematode</option>
<option value="Platyhelminthes" data-value="9">Platyhelminthes</option>
<option value="Rotifer" data-value="10">Rotifer</option>
<option value="Sponge" data-value="11">Sponge</option>
</select>
<select class="form-control" name='phylum' id="sel1_2" style="display:none;">
<option value="0" data-value="0">Choose</option>
<option value="1" data-value="1">C1</option>
<option value="2" data-value="2">D1</option>
</select>
</div>
</div>
javascript
$("#sel0").change(function() {
$('#sel1_1').css({'display':'block'});
The following doesn't seem to work
$('#sel1_1').css({'active'});

How to get the selected text of options in multiple select?

I am trying to get the selected option in multiple select, I can get the value in the form of an array, but I can't get the text of the option.
$(function() {
$('#sizeAddCategory').change(function(e) {
var selected = $(e.target).text();
console.log("selected " + selected);
$('#textAreaAddCategory').val(selected.join(','));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group col-sm-6">
<label for="sel1">Select Sizes (hold ctrl or shift (or drag with the mouse) to select more than one):</label>
<br/>
<select required class="form-control" id="sizeAddCategory" multiple>
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
<option value="4">four</option>
</select>
</div>
<div class="form-group col-md-3">
<label for="name">Selected Sizes</label>
<br/>
<textarea required disabled rows="4" class="form-control" id="textAreaAddCategory"></textarea>
</div>
On $(e.target).text(), I am getting all the options text, I need the text of only selected options, so I can display it in the textarea.
Using .text() on a select will give the text of the control - i.e. all of the options, not just the selected ones.
To get the selected text (not value as you pointed out you can already get), you can use:
$(this).find("option:checked").map((i,e)=>$(e).text()).toArray();
Here, $(this).find("option:checked") will give you the option elements that have been selected while the .map will return the .text() for each of those values into a jquery array, with .toArray() to convert to a normal js array.
$(function() {
$('#sizeAddCategory').change(function() {
var selected = $(this).find("option:checked").map((i,e)=>$(e).text()).toArray();
console.log("selected", selected);
$('#textAreaAddCategory').val(selected.join(','));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group col-sm-6">
<label for="sel1">Select Sizes (hold ctrl or shift (or drag with the mouse) to select more than one):</label>
<br/>
<select required class="form-control" id="sizeAddCategory" multiple>
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
<option value="4">four</option>
</select>
</div>
<div class="form-group col-md-3">
<label for="name">Selected Sizes</label>
<br/>
<textarea required disabled rows="4" class="form-control" id="textAreaAddCategory"></textarea>
</div>
It's because the target that you're defining is in the select tag. Instead of using:
$('#sizeAddCategory').change(function(e) {
use:
$('.option-category').click(function(e) {
and add a class in the options:
<option value="{{$size->id}}" class="option-category">{{$size->name}}</option>
you write :
var selected = $(e.target).text();
you should get the value of selectbox and
you should write
var selected = $(e.target).val();
oh my god
i right now understand what did you mean
ok
write :
$("#selectBox").change(function(e){
var x = $(e.target).find("option:checked").text();
console.log(x);
});

How to hide select2 with options jQuery

I have select form with options, for search by keywords. I'm using select2 lib.
But my select form is created dynamically, and I want to hide and show some select form depending on user's choice.
Now the problem is that, if I choose something from the list:
For ex Production plant, it will appear new select form in which I have options. (it's working good)
If I again go to Production resources and choose another type:
Now I chose Production segment and prev select form is hidden, but in case if I want to go back to the Production plant, it will not appear:
My code:
$("#productionResources").change(function () {
var prodRes = $("#productionResources :selected").html();
$("#selectedProdRes").html(prodRes);
var id = $(this).val();
if (id != "") {
$('#' + id).select2().next().show();
}
idChanging(id);
});
function idChanging(id) {
$("#productionResources").change(function () {
$('#' + id).select2().next().hide();
});
}
HTML:
<div class="display-in-row">
<label>Production resources</label><br>
<select class="form-control" id="productionResources">
<option selected></option>
<option value="productionPlant">Production plant</option>
<option value="productionSegment">Production segment</option>
<option value="valueStream">Value stream</option>
<option value="workCenterGroup">Work center group</option>
<option value="workCenter">Work center</option>
<option value="station">Station"</option>
</select>
</div>
<div class="display-in-row">
<div class="col-12">
<label id="selectedProdRes"></label><br>
<select asp-for="ProductionPlantId" asp-items="Model.ProductionPlant" class="form-control content" id="productionPlant"></select>
<select asp-for="ProductionSegmentId" asp-items="Model.ProductionSegment" class="form-control content" id="productionSegment"></select>
<select asp-for="ValueStreamId" asp-items="Model.ValueStream" class="form-control content" id="valueStream"></select>
<select asp-for="WorkCenterGroupId" asp-items="Model.WorkCenterGroup" class="form-control content" id="workCenterGroup"></select>
<select asp-for="WorkCenterId" asp-items="Model.WorkCenter" class="form-control content" id="workCenter"></select>
<select asp-for="StationId" asp-items="Model.Station" class="form-control content" id="station"></select>
</div>
</div>
The problem comes from your function idChanging():
As soon as you change the 1st select, the event of idChanging() is set and remains. So everytime you select #productionResources, all the events defined by idChanging() will get triggered, so all the previously selected selects will be hidden.
The following should work:
I add a class secondary-select to all the secondary selects to facilitate, but this is not required:
<div class="display-in-row">
<div class="col-12">
<label id="selectedProdRes"></label><br>
<select asp-for="ProductionPlantId" asp-items="Model.ProductionPlant" class="form-control content secondary-select" id="productionPlant"></select>
<select asp-for="ProductionSegmentId" asp-items="Model.ProductionSegment" class="form-control content secondary-select" id="productionSegment"></select>
<select asp-for="ValueStreamId" asp-items="Model.ValueStream" class="form-control content secondary-select" id="valueStream"></select>
<select asp-for="WorkCenterGroupId" asp-items="Model.WorkCenterGroup" class="form-control content secondary-select" id="workCenterGroup"></select>
<select asp-for="WorkCenterId" asp-items="Model.WorkCenter" class="form-control content secondary-select" id="workCenter"></select>
<select asp-for="StationId" asp-items="Model.Station" class="form-control content secondary-select" id="station"></select>
</div>
</div>
$("#productionResources").change(function () {
// Define title
var prodRes = $("#productionResources :selected").html();
$("#selectedProdRes").html(prodRes);
// Make sure none of the 2nd select is visible
$('.secondary-select').select2().next().hide();
// Display the select according to the ID
var id = $(this).val();
if (id !== '') {
$('#' + id).select2().next().show();
}
});

Categories