strange ng-repeat behaviour with back button - angularjs

I have this hidden input in my form
<input type="hidden" ng-repeat="dasBottle in bottles track by $index" value="{{ dasBottle.id }}" name="bottles[]" />
When a button gets clicked, the option currently selected in a select input gets added to the page:
$scope.bottles.push(bottle);
with the correct value and everything is fine.
<input type="hidden" ng-repeat="dasBottle in bottles track by $index" value="30" name="bottles[]" class="ng-scope">
The user can add as many of these as they wish and the value is correct every time.
However, if the user submits the form, but then presses the back button, the same process works, however each new hidden field has the value of the first hidden input added before the form was first submitted, in this case 30. The only way to get it back to normal is to refresh the page.
The scope variable does get set to an empty array when the controller is setup:
$scope.bottles = [];
Any help would be appreciated, thanks.

You might explicitly add index to the array of data you want to form from your form:
bottles[{{ $index }}]
My colleagues on the backend side say that this doesn't change the way data arrives to them, but strange behaviour gets fixed.

Related

AngularJS Dependent dropdown with ng-repeat is leaving blank

I am trying to make a dependent dropdown but somehow the second dropdown is always leaving a blank if i am changing the first dropdown.
<select class="form-control DB_Control" id="Sector" ng-model="selected_sector" ng-init="selected_sector = initial_selected_sector" ng-options="each.sector for each in data track by each.sector" ng-change="getSubsector()">
<select class="form-control DB_Control" ng-model='related_subsector3' ng-options="subsector for subsector in sub_sectors track by subsector" >
$scope.getSubsector = function() {
$scope.related_subsector3 = $scope.sub_sectors[0]
}
Just for more information, if i am printing the value of $scope.related_subsector3 in function getSubsector, its printing correct value but its not setting the value in template.
I don't think that would work. What I would try is to create another function called "$scope.getSubSectorChildren()" which would populate the second dropdown on the change of the first one. That way you can keep the data population more flexible and it would be easier to test/debug.

AngularJS: make the select work on click of dropdown, ngMessages issue

So I have a select box which populates some values into the dropdown using ng-options So I want to show the error messages as soon as the user click on the dropdown and focus out without making a selection.
JS Code
$scope.someMap = [{ name:"Abc", id:"a"},
{ name:"XYZ", id:"b"},
{ name:"FGH", id:"c"},
{ name:"TY", id:"d"}
];
HTML
<select name="inpName" ng-model="person.name" ng-options="i as i.name for i in someMap track by i.id" required>
<option value="" selected hidden/> </select>
<div ng-messages="form.inpName.$error" ng-if="form.inpName.$touched">
<div ng-message="required">Required field</div>
</div>
</div>
So it is working in a case where I add a blank option like option value="" selected hidden/> </select> and select some valid value and then select the blank option again, it gives error message as Required field.
But as you can see, the above selectbox will be blank once the page loads, so if use click on the dropdown and focus out without selecting or move to other field without selecting any value it should give error as Required field.
now if I try to iterate through the value of form.inpName.$error is never having any value and i cannot validate it using the above technique.
I have tried ng-show , ng-if , message expression may be am lacking some expertise.All of them works after selecting valid entry from dropdown and then moving back to blank option.
Solutions which would not work for me
Check model value:I do not want to go to model for these types of field and check if they are blank then show some error message, rather I want to iterate through the $error array and find the issue with the field
Make the default option selected when page loads- Cannot do it.
Add a field as selected one options : This will also not work because if the user did not touch the selection at all and filled all other fields the $error will not be populated for this select dropdown.
Any help would be much appreciated, really struck on this one.
As helped by #Ininiv in above post the code i posted works fine in plunker but not in my dev environment.
So based on some POJO/Entity out objects gets formatted with properties as null.So when i select and the option populates angular does not see as a change in the model, unless i select a value from dropdown and select a blank option from dropdown again. It gets activated.
But I wanted it to start working from the first touch itself, if left blank the error message should pop up.
To tackle this the ngModel needed to be set to null, when the dropdown the $error thing is activated and If i leave it blank and move to other field the error shows up.
So basically on the change of model only the ngMessages directive get activated which was not happening for dropdowns which were populating based on some object properties.

Clear ng-model then Update ng-model with new value

Angular and Ionic Application
I have a form that has a lot of <select> elements, The form offers the user to select from a list or if the <option> = 'Other' then I show another <input> to enter the value. I then save the value to another ng-model.
<select data-ng-model="minor.tests.liveEarth"
name="minorTestLiveEarth"
required>
<option></option>
<option>>200</option>
<option>>299</option>
<option>>500</option>
<option>>1000</option>
<option>Other</option>
</select>
</label>
<label class="item item-input item-stacked-label" ng-show="minor.tests.liveEarth === 'Other'">
<span class="input-label">Please Specify</span>
<input type="text"
placeholder="live earth other"
ng-maxlength="10"
data-ng-model="minor.tests.liveEarthOther"
name="minorTestLiveEarthOther">
</label>
I originally used <datalist> but doesn't show up on iOS.
I assigned the liveEarthOther to the same as the <select> liveEarth but it has 'Other' assigned to the ng-model, which then the user has to delete the input value Other before entering their value.
I have looked for a combobox kind of control but haven't found one that works properly.
How could I make this into a directive or any thing suitable that could perform the renaming without the user having to delete the value.
I want to use this functionality many times in the application I am building.
You may have overcomplicated things by re-using the ngModel. If you change the value minor.tests.liveEarth you'll mess up your select because anything other than the given values will cause nothing to be selected. But if you don't change minor.tests.liveEarth then you'll have to delete it when the user fills in the text input. This would then also mess up the select box!
What I would do is record the value of the text input to a different variable. Keep the ng-show="minor.tests.liveEarth === 'Other'" as it is, but change your input to
<input type="text"
placeholder="Fill in your other live earth"
ng-maxlength="10"
data-ng-model="tempVar" />
This way the input will be still be recorded, but the select won't be messed up on the ngModel change. Due to the placeholder, the user will know that they have to fill in the text box.
In your js, you'll have to create a validating function when the form is submitted along the lines of:
var validateLiveEarth = function(){
if(minor.tests.liveEarth === "Other"){
//check that tempVar meets validation
//assign tempVar to whatever form you're sending
}
}

AngularJS : Binding an input with variable made variable undefined

I am new to AngularJS, and I have a problem with ng-model.
Here's my code:
<section class="field row" ng-repeat="field in fields">
<input class="value" ng-show="editMode" placeholder="{{field.name}}" ng-model="field.value" type="url" />
</section>
As you can see, I'm looping through $scope.fields which I got from the server and is an array of about 40 objects that have keys like name and value.
Inside the section I have an input, which has the ng-model property set to field.value. When the server gives a value to the field, it is shown inside the input.
At some point I want to update the user's changes, by sending $scope.fields back to the server.
However, when the user changes something in the inputs, the value for the changes fields becomes undefined.
I hope this describes my problem well enough.
Thanks!
To get the changes, you should pass the original object name i.e fields. Refer below calling fn
ng-click="save(fields)"
The reason this caused a problem is simply because the input was a URL input and I was typing simple "hello" strings to test it, instead of typing URLS. Apparently AngulaeJS only puts the answer in the model if it matches the field type.

AngularJS: How to show the next form field depending on validity of the previous one

I need to display the next field in my form depending on the last value selected in the form. All fields in my form are independent views, specifically are ng-include.
The idea is not to show all fields when the page loads, and instead, show the next field according to the value selected in the previous field.
Example 1:
My first input (my first ng-include) is a text field, maybe on trigger onBlur check if the value is correct and then show the next field (my second ng-include), then, if that value is correct and then show the next field (my third ng-include).
Example 2:
This time my first input (my first ng-include) is a checkbox field, maybe on trigger onBlur check if the value is correct and then show the next field (my second ng-include), then, if that value is correct and then show the next field (my third ng-include).
Thanks.
Are you familiar with ng-show?
- It shows or hide element depended on value which you declare in ng-show tag.
You can wrap each field (or a group of fields) in ng-form and show the next section depending on the validity of the form of the current section. The fact that elements of the form are delivered via ng-include has little bearing on the approach:
<div ng-form="form1">
<input ng-model="v.one" required min-length="3">
</div>
<div ng-form="form2" ng-show="form1.$valid && !form1.$pending">
<input ng-model="v.two" required min-length="3">
</div>
<div ng-form="form3" ng-show="form2.$valid && !form2.$pending">
<input ng-model="v.three" required>
</div>
This is, of course, at a high-level, and doesn't deal with cases where previous becomes invalid while the next form is showing. For those, more complicated, cases it is better to do the logic in the controller and expose the decision via a function or a scope variable, e.g. showForm2():
<div ng-form="form2" ng-show="showForm2()">
<input ng-model="v.two" required min-length="3">
</div>

Resources