Set Selected Indices in Multi Select Using Javascript - javascript

Im not sure why this isnt working and would love some help with it! And yes i have looked at this
Im trying to set multiple options in a select element as selected using an array holding the values i want selected and interating through both the array and the options in the select element. Please find code below:
// value is the array.
for (var j = 0; j < value.length; j++) {
for (var i = 0; i < el.length; i++) {
if (el[i].text == value[j]) {
el[i].selected = true;
alert("option should be selected");
}
}
}
After completing these loops nothing is selected, even though the alert() fires.
Any ideas are welcome!
Thanks
CM
PS (not sure whats happened to the code formatting).
EDIT: Full function
if (CheckVariableIsArray(value) == true) {
if (value.length > 1) { // Multiple selections are made, not just a sinle one.
var checkBoxEl = document.getElementById(cbxElement);
checkBoxEl.checked = "checked";
checkBoxEl.onchange(); // Call function to change element to a multi select
document.getElementById(element).onchange(); // Repopulates elements with a new option list.
for (var j = 0; j < value.length; j++) {
for (var i = 0; i < el.length; i++) {
if (el[i].text === value[j]) {
el[i].selected = true;
i = el.length + 1;
}
}
}
//document.getElementById(element).onchange();
}
}
else {
for (var i = 0; i < el.length; i++) {
if (el[i].innerHTML == value) {
el.selectedIndex = i;
document.getElementById(element).onchange();
}
}
}

Works for me. Are you setting el and value correctly? And are you sure you want to look at each option's innerHTML instead of it's value attribute?
See the jsFiddle.
HTML:
<select id="pick_me" multiple="multiple">
<option>Hello</option>
<option>Hello</option>
<option>Foo</option>
<option>Bar</option>
</select>
JS:
var value = ['Foo', 'Bar'],
el = document.getElementById("pick_me");
// value is the array.
for (var j = 0; j < value.length; j++) {
for (var i = 0; i < el.length; i++) {
if (el[i].innerHTML == value[j]) {
el[i].selected = true;
//alert("option should be selected");
}
}
}

Well, first of all, you must set the html select control multiple property, something like this "<select multiple="multiple">...</select>", and then you can use the javascript function SetMultiSelect (defined as below) to set the select html control:
function SetMultiSelect(multiSltCtrl, values)
{
//here, the 1th param multiSltCtrl is a html select control or its jquery object, and the 2th param values is an array
var $sltObj = $(multiSltCtrl) || multiSltCtrl;
var opts = $sltObj[0].options; //
for (var i = 0; i < opts.length; i++)
{
opts[i].selected = false;//don't miss this sentence
for (var j = 0; j < values.length; j++)
{
if (opts[i].value == values[j])
{
opts[i].selected = true;
break;
}
}
}
$sltObj.multiselect("refresh");//don't forget to refresh!
}
$(document).ready(function(){
SetMultiSelect($sltCourse,[0,1,2,3]);
});

Ran into this question and wasn't satisfied with the answers.
Here's a generic, non-jQuery version. It utilises Array.indexOf where possible, but falls back to a foreach loop if it isn't available.
Pass a node into the function, alongside an array of values. Will throw an exception if an invalid element is passed into it. This uses === to check against the value. For the most part, make sure you're comparing the option's value to an array of strings.
E.g. selectValues( document.getElementById( 'my_select_field' ), [ '1', '2', '3'] );
var selectValues = (function() {
var inArray = ( function() {
var returnFn;
if( typeof Array.prototype.indexOf === "function" ) {
returnFn = function(option, values) {
return values.indexOf( option.value ) !== -1;
};
} else {
returnFn = function(option, values) {
var i;
for( i = 0; i < values.length; i += 1 ) {
if( values[ i ] === option.value ) {
return true;
}
}
return false;
}
}
return returnFn;
}() );
return function selectValues(elem, values) {
var
i,
option;
if( typeof elem !== "object" || typeof elem.nodeType === "undefined" )
throw 'selectValues() expects a DOM Node as it\'s first parameter, ' + ( typeof elem ) + ' given.';
if( typeof elem.options === "undefined" )
throw 'selectValues() expects a <select> node with options as it\'s first parameter.';
for( i = 0; i < elem.options.length; i += 1 ) {
option = elem.options[ i ];
option.selected = inArray( option, values );
}
}
}());

Related

JS object changed to true, still treated like false

When setting value of object to true it looks and seems it changed it but I still cant use it(as it stayed false).
validateNextMove() {
Card.setArrayNextMoveValid(this.cardRepository.findAll(), false);
let client = this.clientRepository.findByTurn(true);
let provjera = 0;
if (client instanceof UNOClient) {
let cards = client.getCards();
for (let i = 0; i < cards.length; i++) {
if (this.cardCanBePlaced(cards[i])) {
provjera++;
cards[i].setNextMoveValid(true);
console.log(cards[i].getNextMoveValid());
console.log(provjera);
}
}
if (provjera == 0) {
for (let i = 0; i < cards.length; i++) {
cards[i].setNextMoveValid(true);
console.log(cards[i].getNextMoveValid());
console.log(provjera);
}
}
How do I fix this ?
this is my method for checking if card can be place:
cardCanBePlaced(card){
let current = this.discardDeck.slice(-1)[0];
if(typeof current === 'undefined'){
return true;
}
//Check if card is allowed
if(
card.getColor() === current.getColor()
){
return true;
}
return false;
}
if in above mtehod i add global variable to count if there is any available it still doesnt make it work, something like this(counter++ if there is available card of that color)
if(card.getColor()!= current.getColor() && counter==0){
return true;
}

Javascript Update text from array

I am trying to update a text on a click event, but somehow the index of the foreach always give me the first iteration 0, what am I missing:
var sliderTitles = document.getElementsByClassName('avia-caption-title');
var nextSlideBtns = document.getElementsByClassName('next-slide');
var prevSlideBtns = document.getElementsByClassName('prev-slide');
for (var i=0; i < nextSlideBtns.length; i++) {
nextSlideBtns.item(i).onclick = setBtnNames();
}
setBtnNames();
function setBtnNames() {
console.log("clickedd");
Array.from(nextSlideBtns).forEach(
function(element, index, array) {
console.log(index); // always returns 0
if(index == 5) {
element.innerHTML = sliderTitles[0].innerHTML;
} else {
element.innerHTML = sliderTitles[index+1].innerHTML;
}
}
);
}

How to pass HTML style classes into a Javascript function argument

Is there a way that I can pass all style classes into a function?
The style classes represent a table row and i'm trying to hide all rows with the exception of the one that is being clicked. (code below, I apologise if it isn't in the code tags)
function toggle_visibility(id, param2, param3)
{
var getClasses = document.getElementsByClassName(id);
var getClasses2 = document.getElementsByClassName(param2);
var getClasses3 = document.getElementsByClassName(param3);
for (var i = 0; i < getClasses.length; i++)
{
if(getClasses[i].style.display == 'none')
{
getClasses[i].style.display = '';
}
}
for (var i = 0; i < getClasses2.length; i++)
{
if(getClasses2[i].style.display == '')
{
getClasses2[i].style.display = 'none';
}
}
for (var i = 0; i < getClasses3.length; i++)
{
if(getClasses3[i].style.display == '')
{
getClasses3[i].style.display = 'none';
}
}
}
The code works but isn't scalable currently so I would like to pass in every class and then search the classes with an 'if' statement. is this possible?
Thanks
You can use the arguments variable :
function toggle_visibility()
{
var first = true;
var i,j, getClasses;
for (i = 0; i < arguments.length; i++) {
getClasses = document.getElementsByClassName(arguments[i]);
for (j = 0; j < getClasses.length; j++)
{
if(getClasses[j].style.display == (first ? 'none' : ''))
{
getClasses[j].style.display = (first ? '' : 'none');
}
}
first = false;
}
}
With this you can call your function with any number of arguments, the first will be shown and all the other hidden
Create an array of all the classes available in the DOM and pass it as an argument to the function.
var All= document.getElementsByTagName("*");
var allClasses=[];
for(var i=0; i< All.length;i++){
if(All[i].className){
allClasses.push(All[i].className);
}
}
function toggle_visibility(allClasses)
{
//do whatever you want!
}

Can this function be re-written recursively or more cleanly?

This function match sets an attribute (collapsed) to true or false depending on
the value of a string :
function match(children) {
var data = $scope.treeData
for (var i = 0; i < data.length; i++) {
var s = data[i]
for (var i2 = 0; i2 < s.children.length; i2++) {
var s2 = s.children[i2]
for (var i3 = 0; i3 < s2.children.length; i3++) {
for (var i4 = 0; i4 < s2.children[i3].children.length; i4++) {
var text = "";
if ($scope.searchText == undefined) {
text = ""
} else {
text = $scope.searchText
}
if (s2.children[i3].children[i4].label
.toLowerCase() === text.toLowerCase()) {
s2.children[i3].collapsed = false
}
}
}
}
}
}
Excluding the bad use of variable names i3,i2 etc is there a cleaner method ?
As the inner most loop requires access to the outer loop can recursion still be used ?
Update :
Data structure :
[{"label":"test","collapsed":false,"children":[{"label":"test","collapsed":false,"children":[],"$$hashKey":"002"}],"$$hashKey":"001"}]
Update 2 :
Using a recursive function but the string 'test' is not being matched :
http://jsfiddle.net/U3pVM/19196/
fiddle src :
<div ng-app>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
</div>
</div>
function TodoCtrl($scope) {
var json = [{"label":"test","collapsed":false,"children":[{"label":"test","collapsed":false,"children":[],"$$hashKey":"002"}],"$$hashKey":"001"}]
var searchText = 'test'
function match(node, searchText){
angular.forEach(node.children, function(idx, child){
node.collapsed = child.label.toLowerCase === searchText.toLowerCase
console.log(node.collapsed)
if(child.children.length > 0){
match(child, searchText);
}
});
}
match(json, searchText);
}
Please try this :
function match2(obj) {
if (obj.children) {
for (var i = 0; i < obj.children.length; i++) {
match2(obj.children[i]);
}
}
else {
var text = $scope.searchText ? $scope.searchText : "";
if (obj.label
.toLowerCase() === text.toLowerCase()) {
obj.collapsed = false
}
}
Your JSFiddle is very nearly there. I made a couple of changes for this working JSFiddle.
First, you were passing an array into match and not an object. I changed your json variable to be json instead by removing the outer [], but you could also have fixed this by passing in json[0].
The other change was that you had the two parameters, child and idx, were the wrong way round.
function match(node, searchText){
angular.forEach(node.children, function(child, idx){
node.collapsed = child.label.toLowerCase === searchText.toLowerCase
console.log(node.collapsed)
if(child.children.length > 0){
match(child, searchText);
}
});
}
Here's another way of doing it, using some:
function match (node, searchText) {
node.collapsed = node.children.some(function(child) {
return child.label.toLowerCase === searchText.toLowerCase;
});
angular.forEach(node.children, function(child, idx){
match(child, searchText);
})
}
I think something like this may work for you. I don't know anything about angular there might be something there that would make it easier.
var searchText = ($scope.searchText == undefined) ? "": $scope.searchText;
match($scope.treeData, searchText);
function match(node, searchText){
$.each(node.children, function(idx, child){
node.collapsed = child.label.toLowerCase === searchText.toLowerCase
if(child.children.length > 0){
match(child, searchText);
}
});
}

remove null value in javascript

am having script with working condition but many for loop is there so any way to do this...to simplify this ...am new to script kindly help on this....
function change()
{
//document.getElementById("Geography").options[7]=new Option("", "newval", true, false);
var geo = document.getElementById("Geography").options;
var zon = document.getElementById("zone").options;
var coun = document.getElementById("country").options;
for (var i = 0; i < geo.length; i++)
{
if (geo[i].innerHTML == "Null Value" || geo[i].innerHTML == "")
{
document.getElementById("Geography").options[i] = null;
}
}
for (var i = 0; i < coun.length; i++)
{
alert("Loop1" + i);
if (coun[i].innerHTML == "Null Value")
{
document.getElementById("country").options[i] = null;
}
}
for (var i = 0; i < zon.length; i++)
{
//alert("Loop1" + i);
if (zon[i].innerHTML == "Null Value")
{
document.getElementById("zone").options[i] = null;
}
}
}
To remove an option, call removeChild() on the parent element.
var geoSel = document.getElementById("Geography");
var geo = geoSel.options;
for (var i = geoSel.options.length-1; i >= 0; i--) {
if (geo[i].innerHTML == "Null Value" || geo[i].innerHTML == "") {
geo.removeChild(geo[i]);
}
}
I count down instead of up because removing a child will cause the indexes of all the following children to be shifted down. In a count-up loop, that will cause elements to be skipped.
use this UPDATED DEMO
function change(){
var optionsArr = [];
optionsArr.push(document.getElementById("Geography").options);
optionsArr.push(document.getElementById("zone").options);
optionsArr.push(document.getElementById("country").options);
var optArrlenght = optionsArr.length;
for ( var j = 0; j < optArrlenght; j++){
var options = optionsArr[j];
var optionslength = options.length;
for (var i = 0; i < optionslength; i++)
{
if (options[i].innerHTML == "Null Value" || options[i].innerHTML == "")
{
options[i].remove();
i--;
optionslength--;
}
}
}
}
change();

Categories

Resources