create a new drop down based on another drop down in javascript - javascript

Here is my requirement.
List item
I have a couple of dropdowns A and B
I have a javascript key-value variable created:
var keyvalue={"key1":["value1","value2"],"key2":["value2","value4"]}
I am populating the keys in dropdown A, on selecting this dropdown, i am populating the corresponding values (froom the keyvalue variable) into the drop down B
Here is the sample code i a using :
The problem is even if i select a different option in dropdown A, the corresponding old option is present in the new drop down,i.e, new values are appended, rather than creating a new drop down
Any help is appreciated,thanks in advance.

You need to remove all options before populating. Add this directly right after your var quantity statement.
while (selectvalue.options.length > 0) {
selectvalue.remove();
}
Also, as mentioned by #francisco-presencia, you should lose the onchange in the HTML and instead use an event listener within your script.

I recommend you go the separation of concerns route. That means deleting the onclick="" event, and instead doing:
$('#key').change(function(){
$('#value').remove();
// Do the rest of the logic of retrievevalue() here.
});

You should use empty() to remove the old options before appending the new.
You can see it on my sample Fiddle:
JS Fiddle Here
$('#select2').empty().append(Weapons);

Related

Angular multi-select dropdown and lodash countby

I am kinda drawing a blank on this one facet, and I can't seem to quite figure it out.
So I have a simple HTML select => option element which is populated from the back-end (not really relevant tho)
My question is this:
Let's say I have a pre-made object such as this:
{
keyName1: 450,
keyName2: 800,
keyName3: 300
}
What I want to do is to check if the key name matches a name of an option value in my multi-select dropdown (the values come from an array, using 'ng-repeat' on the option), and if the option value matches the key, add the number value to some sort of increment variable, so I can display the total number of 'keyNames' found.
For example - if a user selects 'keyName1' the incrementer value will total 450. If a user selects 'keyName1' and 'keyName2' the incrementer value will total 1,250.
I am lost on how to accomplish this - right now it is reading only the very first item in the dropdown.
Here is the code doing that:
_.forEach($scope.widget.instance.settings.serviceContractTypes, function (type) {
// if item in array matches what is selected in multi-select option
if(type === $('#contractType:selected').text().trim()) {
// do stuff
}
});
Hope this all made sense, and thanks very much for any direction you might offer...
(does not have to utilize lodash, I'm just used to using it)
jQuery's :selected selector only works for HTML options:
"The :selected selector works for elements. It does not work for checkboxes or radio inputs; use :checked for them."
(https://api.jquery.com/selected-selector/)
You say "I have a simple HTML select => option element which is populated from the back-end (not really relevant tho)"
This could be relevant. By default, an HTML option tag does not support multiple selections; it has to explicitly be created as a select multiple in order to support that. Can you share the HTML code for the option to make it clear whether that's a problem or this is a red herring?
Also, can you echo $scope.widget.instance.settings.serviceContractTypes and share to make sure it's actually matching what's available in the text of the options?
ADDENDUM - Wait, I think I figured it out!
The $('#contractType:selected') selects all the selected options in #contractType and concatenates them. Then $('#contractType:selected').text().trim() trims this down to the first word, which is just the first selected option. You should do something like $('#contractType:selected').text().split(" ") and then check if each type is in the resulting list.

How to bind multiple function results as options to select in a form select pop down box?

Here is the fiddle http://jsfiddle.net/Dano007/b11xarpp/5/
To be clearer. In the drop down box, I'd like two options (text). when the user clicks one of these options the relevant function results are returned. Like see when clicking the buttons, which are for example only.
I've added the drop down box, but cannot see how to bind the results from the two queries to it.
Could I use something like ?
$("select#FriendsConnected option.filter-prop2").show();
$("select#FriendsConnected option.filter-prop1").show();
Feel like I've hot a brick wall with this and ideally would like some help with the fiddle to move past it.
In your HTML, change select id to a valid css id, something like: s_FriendsConnected
<select name="huge" class="btn-group select select-block mbl select-multiple" id="s_FriendsConnected">
In your Javascript, change the select = getElementByID(FriendsConnected)'s ID to your new select id: s_FriendsConnected
var select = document.getElementById("s_FriendsConnected");
This solves it on my local machine... will update with the jsfiddle in a while..
EDIT:
Here's the jsfiddle. : http://jsfiddle.net/b11xarpp/7/
UPDATE:::
As per your requirement, in this new jsfiddle, I've removed the buttons and placed option tags with values in the html.
In Javascript, I've removed the var select = document.getelementbyid() function.
Also, I've replaced your click functions for the buttons with on Change event to the select menu:
$('select#s_Friends').change(function(){
var selection = $(this).val();
if(selection=='f_connected')
FriendsConnected();
else if(selection=='f_requests')
FriendsPending();
});
That's mostly all. Here's the updated jsfiddle: http://jsfiddle.net/b11xarpp/8/

Prevent multiple select element from automatically sorting the value assigned to it basis the order of the indexes in the options

I am using the select2 plugin to convert a multiple select html element to a more presentable format. Also I don't think my question is very much dependent on the plugin.
What the plugin does internally is -
this.select.val(val);
where this.select points to the hidden multiple select element.
On feeding the function above a val of say - 2,4,0 ,
the value stored as confirmed when I do an alert(this.select.val()) is 0,2,4 , i.e. with automatic unwanted sorting according to the order of the options in the select element.. :/
DEMO - http://jsfiddle.net/rohanxx/DYpU8/ (thanks to Mark)
Is there a way to preserve the sort order after feeding in the value to my select element?
Thanks.
This is a very good question. I think this is more to do with the multiselect html element, rather than select2.
If you have a normal multiselect, there is no "order" sort of speak. You just have a list in the original order, with either each item selected or not.
I'm almost 100% sure there is a better way of doing this than the below, but for a workaround it should do just fine.
End result:
JavaScript code
// 'data' brings the unordered list, while 'val' does not
var data = $('#e1').select2('data');
// Push each item into an array
var finalResult = [];
for( item in $('#e1').select2('data') ) {
finalResult.push(data[item].id);
};
// Display the result with a comma
alert( finalResult.join(',') );
JSFiddle:
http://jsfiddle.net/DYpU8/4/
A little late for an answer but I actually found a way of doing this.
Keep in mine that this method will hide the options that are already selected, because for my use case it looked better, plus it needs to be that way in order the choices to be in the order the user made them.
$('.my-multi-select').select2('Your Options').on("select2:select", function (e) {
$('[data-option-id="' + e.params.data.id + '"]').insertBefore(_this.find('option:not(:selected):eq(0)'));
}).on("select2:open", function () {
_this.append(_this.find('option:not(:selected)').sort(function (a, b) {
return +a.getAttribute('data-sort-order') - +b.getAttribute('data-sort-order');
}));
});
And for the styles
.select2-results__option[aria-selected=true]{
display:none !important;
}
You will want to make sure you know how the jQuery .sort() function works for you to be able to modify this for your own needs.
Basically what this is doing is when you select an option, it gets hidden and then placed at the bottom of the other selected options, which are before the unselected options. And when you open the drop down, it sorts all of the unselected options by their pre-determined sort order.

jQuery Cloned django-selectable Autocomplete Dropdowns Not Working

As the title states, I have a django-selectable autocomplete form field on my page, that I am trying to clone dynamically after page load. The cloning part works, but the autocomplete fields do not function. I don't know the internals of django-selectable, and I'm still learning jQuery so I am lost as far as figuring out how to "fix" the autoselect functionality.
My general approach is this: I render the form widget using django template variable inside a div container, and I clone the div container.
HTML
<div class="autocomplete" id="autocomplete_{{ form.instance.id}}">{{form.autocomplete_dropdown}}</div>
jQuery
// This works, just the cloned form lacks "autocomplete" functionality.
var autocompleteArray = theDiv.find('.autocomplete');
var acClone = autocompleteArray.clone();
table.find(".column").append(acClone);
Based on SunnySydeUp's comments I made the following revisions:
jQuery
// Clone the div and all its contents
var acClone = autocompleteArray.clone(true, true);
// Get the children of the div
var acCloneChildrenArray = acClone.children();
// iterate through the children array, modify ids where they exist to make them unique
// e.g., unique id contained in idSuffix.
for (var i = 0; i < acCloneChildrenArray.length; i++) {
// if it has an id, make it unique
if (acCloneChildrenArray[i].getAttribute('id')) {
var ident = acCloneChildrenArray[i].getAttribute('id')
acCloneChildrenArray[i].setAttribute('id', ident+'_'+idSuffix);
};
};
Now the data and events are copied, but they are tied to the prototype/master dropdown. That is, clicking one of the cloned objects actually triggers the dropdown for the master. I guess the question comes down to how to attach the event handler dynamically to the new dropdowns?
Final working code (has a minor bug--duplicated dropdown button, but the autocomplete and dropdown functionality works, per SunnySydeUp's solution).
jQuery
// Clone the div
// We leave clone deepcopy flags at default==false
var acClone = autocompleteArray.clone();
// Get the children of the div
// You don't need to set unique id's on the children, it's irrelevant.
// Bind the new selectable fields to the event handlers.
window.bindSelectables('body');
I haven't used django-selectable before but I'm guessing it uses javascript/jQuery to make the autocomplete work. When you call clone, it doesn't clone the javascript for the dropdown. Try doing:
var acClone = autocompleteArray.clone(true);
Passing in true will make jQuery also copy the data and events on that input.
Clone documentation

jQuery: How to reset multiple dropdowns after they have been cloned?

At the moment my code clones 3 dropdowns everytime you click the add button.
I managed to get it to copy the row exactly because before, the first dropdown would reset by itself but the other two would not so I was just wondering how to reset all 3 dropdowns?
It is easiest to see in this JSFiddle:
http://jsfiddle.net/jydqK/7/
So, if you change the first dropdown to agent and then click the + you will see the second row appears duplicated whereas I would like it to reset to tags, operands and values.
Any help greatly appreciated.
You can use removeAttr to remove selected attribute and then fire a change() event.
In your case:
dropdownclone.find('select.tags option:selected').removeAttr('selected');
dropdownclone.find('select.tags option:first').attr('selected','selected');
dropdownclone.find('select.tags').trigger('change');
Modified example: http://jsfiddle.net/ZF3mc/2/
If I understood your question, you want the duplicated row of selects to reset their values.
In this case you can just remove this:
dropdownclone.find('select').each(function(index, item) {
//set new select to value of old select
$(item).val( $dropdownSelects.eq(index).val() );
});
and replace it with:
dropdownclone.find('option').attr('selected', false);
Find all dropdowns in your clone. For each dropdown, check every option tags for a selected attribute and remove it. Something like this:
clone.find('select').each(function() {
$(this).find('option').each(function() {
$(this).removeAttr('selected');
});
});
Or better yet, find only the selected option tags using :selected filter before removing.

Categories

Resources