addition function for input that comes within ng-repeat - javascript

Can someone please point me in the right direction or give me anything on how to make an addition function work with an input that will be created dynamically and is as long the ng-repeat ( which is mostly more than one ) ? I am having trouble on connecting the input by ng-model with the function, so couldn't accomplish anything.
the simplest form of can be like this...
<div ng-repeat="gameName in gameNames track by $index">
<p> {{gameName.title}}</>
<input type="number" >
</div>
Result : {{total}}
will be forever thankful.

First you need to add a ng-model in the input so angular can track it:
<input type="number" ng-model="gameName.value">
For a calculated field, add a method to your controller
$scope.total = function() {
var total = 0;
angular.forEach($scope.gameNames, function(gameName, key) {
total = total + gameName.value;
});
and then bind to it directly. It will know when it needs to recalculate as its constituent values change.

Related

Getting highest value from one of many inputs

so I have a simple input field:
<Input type="number" defaultValue="1" className="quantity"></Input>
but it is rendered by react as 12 different DOM elements. I need to get values from every input element or just the highest one if it is possible without getting every value. I was trying this:
var amount = document.getElementsByClassName('quantity')
but it outputs 'undefined'. Can you guys help here?
document.getElementsByClassName('quantity') would only work if your input had a class attribute. <input class="quantity"> It has a className attribute instead.
What you want to get all the inputs is
document.querySelectorAll('[className~="quantity"]')
Try this:
const maxValue = Math.max(...(Array.from(document.querySelectorAll('.quantity')).map(el => parseInt(el.value, 10))));

ng-disabled on inputs from ng-repeat loop

I'm displaying inputs basing on array like this
<div data-ng-repeat="n in langInput.values">
<input type="text"
id="auction_name_{{n.selected}}"
class="form-control"
name="auction_name_{{$index}}"
data-ng-model="inputs.auction_name[$index + 1]"
data-ng-minlength="5"
data-ng-maxlength="60"
required />
<span data-ng-show="sellItem['auction_name_'+$index].$error.required">Wymagane!</span>
It also give's me ability of angularjs validation. Next after <form> is closed I want to create "next" button but I also want to do validation there so if user don't fullfill required inputs he will not be able to click it.
Array which I'm ng-repeating on is:
$scope.langInput = {
count: 3,
values: [
{
id: "1",
selected: "pl"
},
{
id: "2",
selected: "eng"
}
],
add: function () {
if (this.count < 7) {
this.values.push({id: this.count, selected: "eng"});
this.count += 1;
console.log(this.values);
}
},
remove: function () {
if (this.count > 2) {
this.values.pop();
this.count -= 1;
console.log(this.count);
}
}
};
I know I can use this ng-disabled directive however I don't know how I can check this inputs which are displayed in loop because its name is changing depending on $index of loop.
I've created plunker
My situation is that I know that I can disable button when some of element is invalid by ng-disabled="sellItem.$error" but in my form in real project I have this form much bigger and I have many ways of acomplishing form so in the end when user finish fullfilling form user still got some of inputs which are not even shown invalid.
So I can't use ng-disabled="sellItem.$error" because after user complete form he still got invalid inputs in background.
I also can not split form to many little forms because it will call 1 endpoint on submit.
What I did in real project is inject 3 different buttons and show them on correct step. Every of this button need to have ng-disabled to not let user to go to next step without completing step' inputs.
So intead of ng-disabled="sellItem.$error" I need to specify all inputs in ng-disabled of one step ( which is about 5 inputs ).
So it would look something like this:
ng-disabled="sellItem.first_input.$error &&
sellItem.second_input.$error && ..."
And I would do this but then I come to problem that I can't "loop" inside of ng-disabled and I want to "loop" inside it because names of inputs are generated by JS
name="auction_name_{{n.id}}"
they and not constant they change, user can add more inputs and delete them
at page start I have two inputs which after JS run are name="auction_name_1" and name="auction_name_2" (due to binding interpolated value) and then user can and third one name="auction_name_3"so I can't also hardcode them within ng-disabled.
I don't know how I can check this inputs which are displayed in loop because its name is changing depending on $index of loop.
Generally one stores the input as a property of the object in the array so that it stays with the object as its position in the array changes.
Also use the id property of the object:
<form name="sellItem" ng-submit="submit()">
<div data-ng-repeat="n in langInput.values">
<input type="text"
id="auction_name_{{n.selected}}"
class="form-control"
̶n̶a̶m̶e̶=̶"̶a̶u̶c̶t̶i̶o̶n̶_̶n̶a̶m̶e̶_̶{̶{̶$̶i̶n̶d̶e̶x̶}̶}̶"̶
name="auction_name_{{n.id}}"
̶d̶a̶t̶a̶-̶n̶g̶-̶m̶o̶d̶e̶l̶=̶"̶i̶n̶p̶u̶t̶s̶.̶a̶u̶c̶t̶i̶o̶n̶_̶n̶a̶m̶e̶[̶$̶i̶n̶d̶e̶x̶ ̶+̶ ̶1̶]̶"̶
data-ng-model="n.input"
data-ng-minlength="5"
data-ng-maxlength="60"
required />
<span data-ng-show="sellItem['auction_name_'+n.id].$error.required">Wymagane!</span>
<span data-ng-show="sellItem['auction_name_'+n.id].$error.minlength">Za krótkie!</span>
<span data-ng-show="sellItem['auction_name_'+n.id].$error.maxlength">Za długie!</span>
</div>
<button type="submit" ng-disabled="sellItem.$error">
{{Submit}}
</button>
</form>
Be sure to generate unique values for the id property.
Update
Added Submit button.
For more information, see
AngularJS Developer Guide - forms
AngularJS <form> Directive API Reference
AngularJS ng-submit Directive API Reference

ng-model misbehaving with HTML reset method

Im trying to be as ellaborative as i can with my question....
Scenario:
I have three input fields in my html page Two of them are to accept user inputted values and the third one binds(adds) these two values.
Done so far:
I initially used <input value="{{value1+value2}}" id="value3"/> which took the values as string; solved this issue by substracting the string by 0. But, this calculated values wont go off even using the reset button.
Then someone here on SOF told me to use <input ng-model="(value1-0)+(value2-0)" id="value3"/> which works, but i noticed that even though the values disapper visually the model still holds some value.
(When, i enter some value into the first input field, the third calculated field add the value of the inputted field with the previous value of the second input field(value that the second field had previous to the reset)
NOTE:
Reset method resets the values of the first two user inputted fields, but not that of the third calcualtion field while using <input value="{{value1+value2}}" id="value3"/> OR <input ng-bind="value1+value2" id="value3"/>
While, when using <input ng-model="(value1-0)+(value2-0)" id="value3"/> the calculated field is visually cleared but when i enter some value into one of the user inputted fields(value1 or value2) the calculated field adds the entered number with the previous number that the field ccontained.
I tried many ways to solve this issue, but with no suuccess.... can someone please guide me through?
Thanks in advance.....
Here's a simple fiddle . Follow the link and take a look.
Basically, to have only number values in the user inputed fields, I used HTML5 number inputs, readily available in any newer browser.
<div ng-controller="MyCtrl">
<input type="number" ng-model="value1" />
<input type="number" ng-model="value2" />
<input type="text" ng-model="value1 + value2" />
<button type="button" ng-click="reset()">RESET</button>
</div>
And as for the javascript, here is my controller:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', MyCtrl)
function MyCtrl($scope) {
$scope.value1 = '';
$scope.value2 = '';
$scope.value3 = '';
$scope.reset = function() {
$scope.value1 = '';
$scope.value2 = '';
$scope.value3 = '';
};
}
The three values are first initialized as empty strings, and on ng-click of the RESET button, they are nullified again.
NOTE: For the sake of simplicity I used number inputs instead of trying to implement some kind of javascript validation which I would suggest for production level. The point of my answer was just to explain the principle using the most basic concepts.

Can I change dyanmic javascript variable depending on user form input?

My question here is if there is a way to change the dynamic price calculation depending on the name a user enters in the input field.
I have code that works very well for calculating a dynamic price in an html form. Here is the code:
Using this input:
<input class="typeahead" type="text" placeholder="Amount" name="Amount"/>
My Javascript then calculates price:
jQuery("input[name='Amount']").change(function () {
if (isNaN(parseFloat(this.value)) || !isFinite(this.value)) {
jQuery(this).val('');
return false;
}
var calc = parseFloat(this.value) * 0.95;
jQuery(this).parents("form").find("input[name='price']").val(calc);
});
That by itself works fantastic. It calculates the amount by .95 and then assigns that value as price.
If I add this into the form:
<input class="stores typeahead" type="text" placeholder="Stores" name="name"/>
What can I do here to be able to calculate the price at different values depending on the store name. For example, if someone enters McDonalds, I want it to calculate at .90. If someone enters Target, I want it to calculate at .92. The previous javascript cannot accomplish this because it calculates everything at .95 instead of being able to change depending on the store entered.
I would prefer to accomplish this with javascript because I'm not very skilled with php.
You can create a Javascript object for this.
var stores = {
"McDonalds" : .90,
"Target" : .92,
}
var storeName = jQuery(this).parents("form").find("input[name='name']").val();
console.log(stores[storeName]); //Output the store cost to console.
Though I think the jQuery lookup function is questionable. I'm sure there is a better way to select that textbox. But that's the general concept you're looking for.

Knockout - Checking checkboxes according to observableArray

So I have a list of schedules that I need to display for a user and show which schedules he or she is currently on and give them the possibility to jump on and off said schedules.
My viewmodel looks like this
self = this;
self.shifts = ko.observableArray();
self.selectedShifts = ko.observableArray();
//I populate self.shifts here with a WEB API call
//Run through each shift and check if current user is on it and set checked / not checked value for checkbox
ko.utils.arrayForEach(self.shifts(), function(shift) {
//Clear array
self.usersOnShift([]);
//Populate array with all users on the shift
self.usersOnShift = ko.observableArray(WEB API CALL HERE);
var userInShift = ko.utils.arrayFirst(self.usersOnShift(), function(user) {
if (selectedUserId == user.ID) {
return true;
}
});
if (userInShift) {
self.selectedShifts.push(shift.ID);
}
});
ko.applyBindings(self);
My HTML looks like this
<div class="simple_overlay" id="shiftOverlay">
<div class="details">
<div data-bind="foreach: shifts">
<div><span class="staff-initials" data-bind="text:wardName"> </span><input type="checkbox" data-bind="value: ID, checked: $root.selectedShifts"/> </div>
</div>
<div>
Connect
Close
</div>
</div>
</div>
I can see that the value of the checkboxes are set correctly to the ID of the corresponding shifts. However a shift that I know the user in question is on is not checked and I know that the selectedShifts observableArray contains the value.
Somehow the "checked: $root.selectedShifts" call / check is not working but I know that it contains the right value. What am I doing wrong?
The problem is that your value is an integer, but when bound to the checkbox element, it becomes a string. When the checked binding tries to find the value in the array, it doesn't find a match because it uses strict equality for comparison and (2 === "2") is false.
The simplest way to work around this problem is to convert your values to string when you add them to the array:
self.selectedShifts.push("" + shift.ID);
Of course this means that your model has to change, and that might not be a great solution. I came up with a custom binding, checkedInArray that replaces checked and supports any type of value. You can learn about it, see it in action, and use it like this:
<input type="checkbox" data-bind="checkedInArray: {value: ID, array: $root.selectedShifts }" />
In Knockout 2.3.0 (which is still in development) there will be a new binding, checkedValue, that will allow you use any type of value with the checked binding. Using that version, you could update your HTML to use checkedValue:
<input type="checkbox" data-bind="checkedValue: ID, checked: $root.selectedShifts"/>
Is shift.ID an observable property? If it is, then you need to add it to the array like this:
self.selectedShifts.push(shift.ID());
Otherwise you're just adding the whole observable to the array, and not the value.

Categories

Resources