Preselected ng-select value issue - javascript

I'm trying to get a preselected value within , i've tried multiple tutorials and looked for answers here but none worked.
Here's the deal ->
I load my shifts with $http.get("api/shifts"), then:
<select multiple class="form-control" ng-options="shift as shift.nom for shift in shifts" ng-model="selectedShift"></select>
And it goes to a modal window. But before this modal window opens, I can preselect a shift (to see who would be able to do it). In this case, I have
if(preselectedShift){
$http.get("api/shifts/"+preselectedShift._id).success(function(shift){
$scope.selectedShift = shift; //so it's replacing the ng-model in <select>
})
}
And all shifts appear as they should, but gives me no preselected shift. I also tried with a loop.
for (shifts.length) -> if(shift[i]._id == preselectedShift._id) ->$scope.selectedShift = shift[i]
Which gave me an error "value.forEach is not a function"
Nor ng-select="shift._id == preselectedShift._id" has worked (gives the same error).
Thank you in advance!

The problem was with "multiple" in the select tag. Multiple means that I can select multiple options and therefore the passed object is an array.
So I had to init $scope.selectedShift = [] and then, as Matthew suggested $scope.selectedShift.push($scope.shifts[x])

I think you're pretty close with your solution, it's just that forEach is not supported natively, if you use a for loop like so it should be good:
$scope.selectedShift = [];
if(preselectedShift){
$scope.selectedShift.length = 0;
$http.get("api/shifts/"+preselectedShift._id).success(function(shift){
for(var x = 0; x < $scope.shifts.length; x++){
if($scope.shifts[x]['_id'] === shift['_id']){
$scope.selectedShift.push($scope.shifts[x]);
}
}
})
}
The reason you have to do this is because in your ng-options you use shift as shift.nom ... which means that in order for it to be selected it actually has to be the same reference from the array not just something equaling it. Here's a quick example explaining (hopefully) how angular checks to see if to select something:
var myTest = { test: 4};
var myArray = [{ test: 4 }];
var myTest2 = myArray[0];
console.log(myArray[0] === myTest); //this outputs false
console.log(myArray[0] === myTest2); //this outputs true

Related

Change string (text-element) in svg-element

I'm just playing around with some svg-drawings.
Actually I have a svg-drawing, that contains some grouped Elements.
I like to copy one of These Elements and give it e new value in its Text-field.
First I copy the Element:
var selectedSymbol = document.getElementsByClassName('selected');
if(selectedSymbol.length >>0)
{
var newSymbol = selectedSymbol[0].cloneNode(true);
//now Change Information of <text id='BMK'>emptyBMK</text>
}
Of course every grouped Symbol has this text-field, with same id, so I think I Need to Change it only in selected Symbol but newSymbol.getElementsById('BMK') does not work :(
Ok, I did it, but I am not sure if this is a good practice:
for (var x = 0; x < newSymbol.childElementCount; x++)
{
if(newSymbol.Children[x].id == "BMK")
newSymbol.children[x].innerHTML = "newBMK";
}
Can someone tell me if this is ok?
I mean it works but seems a bit strange to me.

jQuery - using global array and wait for $get to load retrieved data?

Been struggling all day with looking at code examples and can't get this to work.
Basically I want to load an array using the HTML from four local files.
Then I'll use that HTML to fill a div dynamically with some kind of animated slider.
My problem is that I can't seem to get the timer to wait for the html to be retrieved and assigned to the variables. The GET is working great, but the variables don't seem to be loaded outside the GET loop.
I can see the asynch GET filling the array properly, but the elements remain undefined in the loop. I think they're global variables so it shouldn't be that.
I'm new at jQuery and have been using SO for examples, so open to any suggestions - hopefully this is just an obvious fix for an experienced javascript coder.
Here's my code:
window.standings = new Array(4);
window.iURL = 0;
standingsURL = ["MondayNight.html", "TuesdayNight.html", "WednesdayNight.html", "ThursdayNight.html"]
for (window.iURL = 0; window.iURL < window.standings.length; window.iURL ++) {
$.get(standingsURL[window.iURL], function( data ) {
window.standings[window.iURL] = data;
alert (window.standings[window.iURL]);
}, "text");
}
setTimeout(function repeatTimeout() {
if(window.standings[window.standings.length] !== undefined){
for (window.iURL = 0; window.iURL < window.standings.length; window.iURL ++) {
alert (window.standings[window.iURL]);
}
} else {
alert ("Wait again");
setTimeout(repeatTimeout, 2500);
}
}, 1000);
The first issue I can see is that in your repeatTimeout function, you're referencing an item in your array that doesn't exist.
window.standings[window.standings.length]
which is equivalent to window.standings[4]
You have an array with four items in it, and you're referencing array index 4 here - but arrays are zero-indexed, so only indexes 0, 1, 2, and 3 are valid. Try:
window.standings[window.standings.length - 1]
Edit:
Declare an empty array:
window.standings = []
Instead of: window.standings[window.iURL] = data;, do this:
window.standings.push(data)
Your if function now checks for length:
if(window.standings.length === 4)
This is a relatively crude solution. Check out this SO post for more information about the when function.

GetElementsByClassName Not Working As Expected [duplicate]

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 8 years ago.
I have a table that typically looks like this on the screen:
The multiple rooms are displayed by using a foreach loop.
Now I need to disable all the second dropdown boxes when a value has been selected in one of the first ones, or vice versa.
Typical code for one of the dropdown boxes is
<select onchange="std()" class="numrooms" name="numrooms[4]">
<option value="" selected>Select</option>
<option value="1"> 1</option>
<option value="2"> 2</option>
</select>
I am using the following javascript:
function std() {
d = document.getElementsByClassNames("numrooms").value;
if (d>0) {
document.getElementsByClassNames('numrooms_nr').disabled = true;
}else{
document.getElementsByClassNames('numrooms_nr').disabled = false;
}
}
function nr() {
e = document.getElementsByClassNames("numrooms_nr").value;
if (e>0) {
document.getElementsByClassNames('numrooms').disabled = true;
}else{
document.getElementsByClassNames('numrooms').disabled = false;
}
}
but it doesn't work.
I have tried changing the classes to IDs and then using GetElementById() in the script and that does work, but of course it only works on one pair of dropdowns. I thought going to classes and using Get ElementsBy ClassName() would do the trick, but apparently not.
Am I missing something obvious? Or doing it completely wrong?
EDIT
As everyone pointed out, I wrote "getElementsByClass" in the question when it should have been "getElementsByClassName". However that was a mistake when I wrote the question and not in my actual code. I've corrected it here now.
EDIT2
I'm getting there, but not quite fully sorted yet. I've adopted #Notulysses suggestion so for testing purpose my script is
function std() {
d = document.getElementsByClassName('numrooms')[1].value;
if (d>0) {
var n = document.getElementsByClassName('numrooms_nr')
for(var i=0;i<n.length;i++){
n[i].disabled = true;
}
}else{
var n = document.getElementsByClassName('numrooms_nr')
for(var i=0;i<n.length;i++){
n[i].disabled = false;
}
}
}
function nr() {
e = document.getElementsByClassName('numrooms_nr')[0].value;
if (e>0) {
var n = document.getElementsByClassName('numrooms')
for(var i=0;i<n.length;i++){
n[i].disabled = true;
}
}else{
var n = document.getElementsByClassName('numrooms')
for(var i=0;i<n.length;i++){
n[i].disabled = false;
}
}
}
function(std) now disables all of the second dropdown boxes when the first dropdown in the second room is selected (because I have set it to 1). Similarly function(nr) disables all of the first dropdown boxes (because I have set it to [0]).
But how do I disable all the second dropdowns when any of the first dropdowns is selected?
You are using getElementsByClass (it doesn't exist) and changing property for the whole collection (not valid, you should iterate through Node list to change attribute's value). You should do something like this :
var n = document.getElementsByClassName('numrooms')
for(var i=0;i<n.length;i++){
n[i].disabled = true;
}
Its GetElementsByClassName not GetElementsByClass and it returns you NodeList of nodes so if you want to change any property you need to use indexing, i.e, looping:
document.getElementsByClassName('numrooms_nr')[0].disabled = true;
and here is your complete code:
var d = document.getElementsByClassNames("numrooms");
for(var i=d.length-1;i>=0; i--){
if(n[i].value > 0){
n[i].disabled = true;
}
else{
n[i].disabled = false;
}
}
You are using it wrong. It's not getElementsByClass , it is getElementsByClassName. And it returns a HTMLCollection of found elements. To have an access to any element you should use indexing.
document.getElementsByClassName('someclass')[0] <- index
See the link for more details -> Link
getElementsByClassName and getElementsByTagName do not return a single element, like get ElementById. Rather, they return an array containing all the elements with that class. This has tripped up many Javascripters over time. Also note that getElementsByClassName won't work in early IE versions (surprise surprise!)
As such, you are missing the bit with the [0] or [1] or the [2] etc. after getElementsByClassName is written, for example:
document.getElementsByClassName("numrooms")[0]
will refer to the first of the bunch with that class name.

Different return value console/javascript with jquery

I'm new to javascript/jquery/html, and I have to develop a little simulator with html and javascript.
I have an array with stored html id and a function that should update input based on the passed state.
The code is something like this:
var dev_array = [["#8_1", "#8_2"], ["#8_3", "#8_4"], ["#8_5", "#8_6"], ["#8_7", "#8_8"]];
function send_dev_state_ctrl(state){
dev_array.forEach(function(entry){
for (i = 0; i < entry.length; ++i) {
console.log(entry[i]);
var input =$(entry[i]);
console.log(input);
input.value =value_hash_dev[i];
handle_ctrl_send(input);
}
});
}
The console show:
#8_1
[input#8_1, context: document, selector: "#8_1", jquery: "1.10.1", constructor: function, init: function…]
...
If I digit $("#8_1") in console, I have the following output:
[<input type=​"hidden" id=​"8_1" name=​"8:​1" value=​"1">​]
What should I do to have the same return value in javascript?
I don't know why but doing:
var input =$(entry[i])[0];
It returns the same value of console.
I don't like it, but it works.
You are not $'ing up your console.log you are just spitting out the array value.
Change this:
console.log(entry[i]);
To this:
console.log($(entry[i]));
And you will get the same result for both.
---- EDIT ----
My bad i misread the question, so you are correct doing
var input =$(entry[i])[0];
Will work, this is because $(entry[i]) is an object and the first value in that object is the DOM element which is accessed by doing $(entry[i])[0];.
Another method would be do to this:
var input =$(entry[i]).get(0);
Which pretty much does the same thing.
Unfortunately there is not much other way of doing it.

HTML JS Only half of select list is being deleted?

This is weird, im trying to clear my select list and exactly half is being cleared, not everything. Its also every other item which is left behind. I havent included the data here, but just the setup of the select list. The data is 10 items and only 5 are deleted. UniList calls DeleteAll. The first alert prints out '10' and the second prints out '5'
DID is just document.getelementbyid()
function DeleteAll(string) {
var i;
var list = DID(string);
alert(DID(string).options.length);
for (i = 0; i<list.options.length; i++) {
list[i] = null;
}
alert(list.options.length);
alert("finished deleting");
}
<select size='12' name='UniList' id='UniList' style='width:180px;' onclick=changeuni('UniList','Uni')>
<option value=''></option>
<option value=''></option>
<option value=''></option>
</select>
list.options is a HTMLOptionsCollection that is assumed to be live:
Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.
So with every iteration one item is removed and the document is updated so that list.options and thus list.options.length is updated too. So instead of removing the first, second, third, etc. option of the list you actually remove the first, third, fifth, etc. option.
Use list.options[0] instead to always remove the first option:
while (list.options.length > 0) {
list.options[0] = null;
}
Or remove the options from behind:
for (i = list.options.length-1; i>=0; i--) {
list.options[i] = null;
}
By the way: The HTMLSelectElement has a remove method to remove an option by its index:
while (list.length > 0) {
list.remove(0);
}
You could just replace your existing DeleteAll function with
function DeleteAll(listId) {
var list = document.getElementById(listId);
list.options.length=0;
}
or even
function DeleteAll(listId) {
document.getElementById(listId).options.length=0;
}
If you still prefer to use DID() you can just swap it in
This might be an option as well
while ( list.options.length > 0 )
{
list[0] = null;
}
Try looping from the end of the select list to the beginning. UI suspect as you are deleting them it is reordering the array such that once you have deleted half your next index then is over the top. eg if you have 10 items then after deleting 5 it will try to delete item with index 6 but you only have a list length of 5 so that won't work...
So basically try:
for (i = list.options.length-1 ; i>=0; i--) {
list[i] = null;
}
I think I got my indexes right there but adjust the loop accordingly in case I got it wrong.
Edit:
I realised that there is also a better way to delete. Just use list.options.length=0 will clear your list. I've put some examples into a jsFiddle so you can see them in action (and so I coudl test they worked).
http://jsfiddle.net/HUvA2/3/ - The first button runs your method (You'll see it deletes every other entry) and the second runs my modified loop which you can see gets rid of them all. The "best" button just sets the list length to 0. :)

Categories