pugJS passing a variable to a mixin in a loop - pugjs

Trying to loop over some html based on how many questions there are while using a mixin.
I'm expecting that this code would loop over the div 3 times and pass each question into the mixins of input-label and input-field and spit out the proper html as if I'm using a mixin with just text.
PUG Code
- var questions = ['question one', 'question two', 'question three'];
- var answers = ['answer one', 'answer two', 'answer three'];
- for (var i = 0; i < questions.length; i++) {
div.row.row-loose
div.col-md-6
+input-label(#{questions[i]})
div.col-md-5
+input-field()(val=#{answers[i]} disabled)
- if(i == 0) {
span
- }
- else {
div.col-md-1
+button-default('Modify')
- }
- }
input-label.pug
mixin input-label(label)
label.control-label(class=attributes.class required for=attributes.id+'-'+label)
if attributes.required
span.required *
=label+':'
input-field.pug
mixin input-field()
input.form-control(type='text' class=attributes.class id=attributes.id value=attributes.value disabled=attributes.disabled readonly=attributes.readonly)
expected results
<div class="row row-loose">
<div class="col-md-6">
<label class="control-label">question one</label>
</div>
<div class="col-md-5">
<input class="form-control" type="text" disabled="disabled" val="answer one" />
</div><span> </span></div>
<div class="row row-loose">
<div class="col-md-6">
<label class="control-label">question two</label>
</div>
<div class="col-md-5">
<input class="form-control" type="text" disabled="disabled" val="answer two" />
</div>
<div class="col-md-1">
<button class="btn btn-default" type="button">Modify</button>
</div>
</div>
<div class="row row-loose">
<div class="col-md-6">
<label class="control-label">question three</label>
</div>
<div class="col-md-5">
<input class="form-control" type="text" disabled="disabled" val="answer three" />
</div>
<div class="col-md-1">
<button class="btn btn-default" type="button">Modify</button>
</div>
</div>
actual result - pugjs error
27| div.row.row-loose
28| div.col-md-6
29| +input-label(#{questions[i]})
------------------------------------------^
30| div.col-md-5
31| +input-field()(val=#{questions[i]} disabled)
32| - if(i == 0) {
Syntax Error: Unexpected character '#'

Found the problem..
Variables didn't need the interpolation since it's being passed to a mixin and not just as text. The input-label mixin call should read +input-label(questions[i])
And for the input-field mixin call, I had the wrong attribute. It's value not val. And also removing the interpolation. So looks like this: +input-field()(value=answers[i] disabled)

Related

Bootstrap 5 form validation - required & disabled

I currently have a disabled input box. I use the box to display the sum of two range sliders, where I update the value of the box via JavaScript.
I currently require that the value of the box equals 100 before allowing the form to be submitted. Is there a work-around where I can still disable the box, where it will still adopt the same Bootstrap style formatting (change color from red to green, etc) as a non-disabled box with the 'require' option?
Following a suggestion here, I've updated the code snippet below to almost be what I want. The only thing that I'd like to change, is to make 'rSum', the box that displays the sum, disabled (while still keeping all the validation formatting features). Ideally, I want this sum to adopt the validation feedback rather than the sliders, or other mutable input objects.
function checkSum() {
let currSum = parseInt(document.getElementById('rSum').value);
if (currSum != 100) {
document.getElementById('rSum').setCustomValidity('Must sum to 100%');
return false
} else {
document.getElementById('rSum').setCustomValidity('');
return true
}
}
function updateBoxes() {
const s1 = document.getElementById('range1');
const s2 = document.getElementById('range2');
let currSum = parseInt(s1.value) + parseInt(s2.value);
document.getElementById('rangeValue1').value = (s1.value)+"%";
document.getElementById('rangeValue2').value = (s2.value)+"%";
document.getElementById('rSum').value = (currSum)+"%";
}
// This last function is the original bootstrap validation example, modified to call 'checkSum()' instead
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.custom-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!checkSum()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<form class="custom-validation" novalidate>
<div class="mb-3 row">
<div class="form-group col-md-1">
<input class="form-control" type="text" id="rangeValue1" disabled>
</div>
<div class="form-group col-md-4 col-form-label">
<input type="range" class="form-range" min="0" max="100" step="5" id="range1" value="0" onchange="updateBoxes()" >
</div>
</div>
<div class="mb-3 row">
<div class="form-group col-md-1">
<input class="form-control" type="text" id="rangeValue2" disabled>
</div>
<div class="form-group col-md-4 col-form-label">
<input type="range" class="form-range" min="0" max="100" step="5" id="range2" value="0" onchange="updateBoxes()" >
</div>
</div>
<div class="mb-3 row">
<div class="form-group">
<input type="text" class="form-control text-center" id="rSum" placeholder="100%" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Probabilities must add up to 100%
</div>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-6 offset-md-1">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
A couple of ways to do this. Here I use an example form with some inputs that can be used in the slider validation (one is a range slider but could be a simple number input also).
I set an event handler for those elements, associate them using data attributes and then; very verbosely and a bit ugly for clarity, use them in a function.
function checkSum(event) {
const fearRequird = this.fearNeed;
const myFear = event.target;
const associated = document.querySelector(myFear.dataset.related);
const result = this.sumEl;
const thisValue = parseInt(myFear.value);
const associatedValue = parseInt(associated.value);
let currSum = thisValue + associatedValue;
result.value = currSum;
let isValidSlider = currSum >= fearRequird;
result.classList.toggle("is-valid", isValidSlider);
result.classList.toggle("is-invalid", !isValidSlider);
let t = isValidSlider ? '' : `You Fear ${thisValue} and ${associatedValue} total ${currSum}. You need total ${fearRequird} fear`;
result.setCustomValidity(t);
result.closest('.form-group').querySelector('.invalid-feedback').textContent = t;
return isValidSlider;
}
(function() {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
let forms = document.querySelectorAll('.needs-validation');
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function(form) {
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false)
});
const fearNeed = 100;
const myFears = document.querySelectorAll('.fear-factor');
const needs = {
fearNeed: fearNeed,
sumEl: document.querySelector('#rSum')
};
myFears.forEach((fearElement) => {
fearElement.addEventListener('change', checkSum.bind(needs), false);
});
})();
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<form class="row g-3 needs-validation mx-1 my-2" novalidate>
<div class="form-group">
<input type="text" class="form-control text-center" id="rSum" placeholder="100%" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Fears must add up to 100%
</div>
</div>
<div class="col-md-4">
<label for="validationCustomUsername" class="form-label">Fish Name</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend">Fish</span>
<input type="text" class="form-control" id="validationCustomFishname" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Must catch a fish.
</div>
<div class="valid-feedback">
Looks like an good catch!
</div>
</div>
</div>
<div class="col-md-3">
<label for="validationCustomFearMet" class="form-label">Scary cats fear</label>
<div class="input-group has-validation">
<input type="number" class="form-control fear-factor" min="0" max="100" step="1" value="13" id="validationCustomFearMet" data-related="#customRange3" required />
<span class="input-group-text" id="inputGroupPrepend">%</span>
<div class="invalid-feedback">
Please provide scary cats fear as a percent 0-100.
</div>
<div class="invalid-feedback">
Please provide scary cats fear as a percent 0-100.
</div>
</div>
</div>
<div class="mx-1">
<label for="customRange3" class="form-label">Fear range</label>
<input type="range" class="form-range fear-factor" min="0" max="100" step="1" value="0" data-related="#validationCustomFearMet" id="customRange3">
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>

Google Sheets HTML data input, can't get it to populate

Spreadsheet:
The html data entry:
I have been working on this for 8 hours, I cannot figure it out.
I have a website that I am uploading items to be sold. I have a Google sheet that I am keeping track of this information. We will have probably over 3,000 items to sell, so this html would be a lifesaver!
I however cannot get it to populate into my Google sheets. It runs, I don't get error messages, it just won't populate in my sheet.
This is my sheet, it is open
I am teaching myself how to do the website myself, I only have about 3 or 4 months under my belt. Any help would be WONDERFUL!
Code GS
function doGet(request) {
return HtmlService.createTemplateFromFile("Index").evaluate();
}
/* #Include JavaScript and CSS Files */
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
/* #Process Form */
function processForm(formObject) {
var url =
"https://docs.google.com/spreadsheets/d/1uF5YBKyfVxvrA4QrUuRqHrxe7C1qEySIxAL_r-PkBIQ/edit#gid=1180254005";
function processForm(formObject) {
var ss = SpreadsheetApp.getActive();
var ws = ss.getSheetByName("Data");
ws.appendRow([
formObject.location,
formObject.itemNumber,
formObject.name,
formObject.description,
formObject.price,
formObject.markedDown,
formObject.pricePaid,
formObject.category,
formObject.sold,
formObject.postedOnline,
]);
}
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<?!= include('JavaScript'); ?>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-6">
<form id="myForm" onsubmit="handleFormSubmit(this)">
<p class="h4 mb-4 text-center font-weight-bold">Seattle Bound Data</p>
<!-- Row 1 -->
<div class="form-row">
<div class="form-group col-md-4 font-weight-bold">
<label for="first_name">Location</label>
<input type="text" class="form-control" id="location" name="location" placeholder="Location">
</div>
<div class="form-group col-md-4 font-weight-bold">
<label for="itemNumber">Item Number</label>
<input type="text" class="form-control" id="itemNumber" name="itemNumber" placeholder="Item Number">
</div>
<div class="form-group col-md-4 font-weight-bold">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Name">
</div>
</div>
<!-- Row 1 -->
<!-- Row 2 -->
<div class="form-row">
<div class="form-group col-lg-12 font-weight-bold">
<label for="description">Description</label>
<input type="text" class="form-control" id="description" name="description" placeholder="Description">
</div>
</div>
<!-- Row 2 -->
<!-- Row 3 -->
<div class="form-row">
<div class="form-group col-md-4 font-weight-bold">
<label for="price">Price</label>
<input type="number" class="form-control" id="price" name="price" placeholder="$00.00">
</div>
<div class="form-group col-md-4 font-weight-bold">
<label for="markedDown">Marked Down</label>
<input type="number" class="form-control" id="markedDown" name="markedDown" placeholder="$00.00">
</div>
<div class="form-group col-md-4 font-weight-bold">
<label for="pricePaid">Price Paid</label>
<input type="number" class="form-control" id="pricePaid" name="pricePaid" placeholder="$0.00">
</div>
</div>
<!-- Row 3 -->
<!-- Row 4 -->
<div class="form-row">
<div class="form-group col-sm-6 font-weight-bold">
<label for="categories">Categories</label>
<div class="form-check form-check-inline">
<select name="categories">
<option value="media">Media</option>
<option value="tools">Tools</option>
<option value="clothes">Clothes</option>
<option value="bears">Bears</option>
<option value="misc">Misc</option>
<option value="electronics">Electronics</option>
</select>
<div class="form-group col-sm-6 font-weight-bold">
<p>Sold</p>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sold" id="true" value="true">
<label class="form-check-label" for="true">True</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sold" id="false" value="false">
<label class="form-check-label" for="false">False</label>
</div>
</div>
<div class="form-group col-sm-6 font-weight-bold">
<p>Posted Online</p>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="postedOnline" id="true" value="true">
<label class="form-check-label" for="true">True</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="postedOnline" id="false" value="false">
<label class="form-check-label" for="false">False</label>
</div>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-block">Submit</button>
</form>
<div id="output"></div>
</div>
</div>
</div>
</body>
</html>
JavaScript.html
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.processForm(formObject);
document.getElementById("myForm").reset();
}
</script>
I was able to run the code but with few corrections.
In app script, inside the pocessForm() function you are again declaring a new function with the same name, which is unnecessary and your code does not run because of this. So you should remove the outer function and just keep inner one.
When you deploy your app, the activeSheet function does not work. Instead, use
SpreadsheetApp.openById("")
and give the id of the spreadsheet which you can find in the link of the spreadsheet. These will be the alphanumeric character string. For your sheet it's this - "1uF5YBKyfVxvrA4QrUuRqHrxe7C1qEySIxAL_r-PkBIQ".
function doGet(request) {
return HtmlService.createTemplateFromFile('Index').evaluate();
}
/* #Include JavaScript and CSS Files */
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
/* #Process Form */
function processForm(formObject) {
Logger.log(JSON.stringify(formObject));
// var ss = SpreadsheetApp.getActive(); // incorrect
const ss = SpreadsheetApp.openById("");
const ws = ss.getSheetByName('Data');
ws.appendRow([formObject.location,
formObject.itemNumber,
formObject.name,
formObject.description,
formObject.price,
formObject.markedDown,
formObject.pricePaid,
formObject.category,
formObject.sold,
formObject.postedOnline]);
}
And this works.
Suggestion - You may want to handle the form validation. Currently, if a user submits the form with any empty field, app script throws error. Easy way to handle this is by making each input field required in html.

Angular error:Form submission canceled because the form is not connected

What I am trying to do is -
I am trying to add a form to the existing form but the data not getting stored
what the error coming up -
in the console its showing form connection is missing.. how can I connect it with following code I have?
The code behind the click is something like this:
<button type="submit" class="btn btn-default" routerLink="../viewemployee" [disabled]="empForm.invalid">Add Employee</button>
please refer the link below for the code.. need help to move on from this to solve other tasks.
If it is required to post the code here as well, I will do.Please answer and respond.
Thanx in advance.
How to connect the form in angular routing
createemployee.component.html
<h2>Add Employee:</h2>
<form class="form-horizontal" #empForm="ngForm">
<div class="form-group">
<label class="control-label col-sm-2" for="name">Name:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" minlength="4" maxlength="10" pattern="^[A-Za-z0-9]*[A-Za-z0-9][A-Za-z0-9]\S*$" [(ngModel)]="model.name" placeholder="Enter Your Name"
#name="ngModel" required/>
<div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.pattern">
No Spaces
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="position">Position:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="position" minlength="4" maxlength="10" pattern="^[a-z]*$" [(ngModel)]="model.position" placeholder="Enter your position"
#position="ngModel" required />
<div *ngIf="position.invalid && (position.dirty || position.touched)" class="alert alert-danger">
<div *ngIf="position.errors.required">
Position is required.
</div>
<div *ngIf="position.errors.pattern">
Only Alphabets are must be entered
</div>
<div *ngIf="position.errors.minlength">
Position must be at least 4 characters long.
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="salary">Salary:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="salary" pattern="[0-9]*"
minlength="5" maxlength="7" [(ngModel)]="model.salary" placeholder="Enter Salary" #salary="ngModel" required />
<div *ngIf="salary.invalid && (salary.dirty || salary.touched)" class="alert alert-danger">
<div *ngIf="salary.errors.required">
Salary is required.
</div>
<div *ngIf="salary.errors.minlength">
Salary must be in 5 numbers.
</div>
<div *ngIf="salary.errors.maxlength">
Salary must not be exceeded morethan 7 numbers.
</div>
<div *ngIf="salary.errors?.pattern">Only numebers should be typed
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default" routerLink="../viewemployee" [disabled]="empForm.invalid">Add Employee</button>
<button type="button" class="btn btn-default" routerLink="../home">Cancel</button>
</div>
</div>
</form>
You could change your component as follows:
Add event handler to the form:
<form (ngSubmit)="continue()">
Handle the routing in code:
continue() {
...
this.router.navigateByUrl("../viewemployee");
}
You need to inject the router:
constructor(private router: Router) {}

Angular 4 Reset status form

I have a modal with a form, and some required fields.
When I open the modal I correctly see the fields empty, if I write something in the field required and then I cancel the words writed I correctly see the field as invalid.
The problem is that if I close and reopen the modal I want to see the empty fields like if it's the first time I open it but for some reason I see the previous invalid status also if I reset the form.
This is my modal after I close it, it seems that the status never be resetted:
<form #modelForm="ngForm">
<div class="modal-body" *ngIf="checkpoint">
<div class="row">
<div class="form-group label-floating">
<label class="control-label">{{'checkpoint.table.dialog.labels.name'
| translate }}<span class="star">*</span>
</label> <input class="form-control" id="name" name="name" required
[(ngModel)]="checkpoint.name" #name="ngModel" /><small
[hidden]="name.valid || name.pristine" class="text-danger">
{{'checkpoint.table.validations.required' | translate }}</small>
</div>
</div>
<div class="row">
<div class="form-group label-floating">
<label class="control-label">{{'checkpoint.table.dialog.labels.passStockAlert'
| translate }}</label> <input pattern="[0-9]*"
class="form-control" name="passStockAlert"
id="passStockAlert"
[(ngModel)]="checkpoint.passStockAlert"
#checkPoint="ngModel" /><small
[hidden]="checkPoint.valid || checkPoint.pristine"
class="text-danger">
{{'checkpoint.table.validations.invalid' | translate }}</small>
</div>
</div>
<div class="row">
<div class="category form-category">
<span class="star">*</span> {{ 'form.requiredfields' |
translate }}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-info btn-round"
(click)="save();resetForm(modelForm)" data-dismiss="modal"
[disabled]="modelForm.form.invalid || modelForm.form.pristine"
label="Save">{{'checkpoint.table.dialog.save' |
translate }}</button>
<button type="button" class="btn btn-danger btn-round"
(click)="resetForm(modelForm)" data-dismiss="modal">{{'checkpoint.table.dialog.close' |
translate }}</button>
</div>
</form>
And this is my reset form method:
resetForm(myForm: NgForm) {
myForm.form.reset();
}
I have successfully implemented this:
my-component.html
<form (ngSubmit)="resetFormFlags(myForm)" #myForm="ngForm">
<h4> title </h4>
<button type="submit"> btnText</button>
</form>
my-component.ts
resetFormFlags(myForm: any) {
myForm.reset();
}
Hope it helps!
Try like this below code :
<form name="modelForm" role="form" novalidate (ngSubmit)="resetForm(modelForm)" #modelForm="ngForm">
<div class="modal-body" *ngIf="checkpoint">
<div class="row">
<div class="form-group label-floating">
<label class="control-label">{{'checkpoint.table.dialog.labels.name'
| translate }}<span class="star">*</span>
</label>
<input class="form-control" id="name" name="name" required [(ngModel)]="checkpoint.name" />
<small [hidden]="!(modelForm.controls.name?.dirty && modelForm.controls.name?.invalid)" class="text-danger">
{{'checkpoint.table.validations.required' | translate }}
</small>
</div>
<button class="btn btn-primary" [disabled]="modelForm.form.invalid" type="submit">{{'checkpoint.table.dialog.save' | translate }}</button>
<button class="btn btn-white" type="button" (click)="resetForm(modelForm)"> {{'checkpoint.table.dialog.close' | translate }}</button>
</div>
</div>
</form>
componen.ts
resetForm(editForm: NgForm) {
editForm.reset();
}

ion-content does not allow to push an Object. Showing undefined

I am getting some issue while working with ionic framework. I am trying to work on Grocery app Where user can add items. The code which I have written doesn't work showing "undefined" with blank field and But when I replace "ion-content" tag with "div" tag then My code works fine. I am confused why is this happening? Please help Thanks.
<ion-content>
<div class="grocery-wrapper">
<ion-item ng-repeat="groceryItem in groceryItems">
<div class="row">
<div class="col col-20">
<label class="checkbox checkbox-balanced">
<input class="checkbox" type="checkbox"/>
</label>
</div>
<div class="col col-33 g-items">{{groceryItem.itemName}}</div>
<div class="col g-items">{{groceryItem.Quantity}}</div>
<div class="col g-items">{{groceryItem.Rate}} rs/kg</div>
</div>
</ion-item>
<div id="getGroceryItem" ng-show="GroceryItem">
<div class="row">
<div class="col col-50">
<label class="item item-input item-floating-label">
<span class="input-label">Grocery Item</span>
<input ng-model="gItem" type="text" placeholder="Grocery Item">
</label>
</div>
<div class="col">
<label class="item item-input item-floating-label">
<span class="input-label">Kg</span>
<input ng-model="gKg" type="text" placeholder="kg">
</label>
</div>
<div class="col">
<label class="item item-input item-floating-label">
<span class="input-label">Price</span>
<input ng-model="gPrice" type="text" placeholder="Price">
</label>
</div>
</div>
<div class="row">
<button class="button button-block button-balanced button-medium" ng-click="addGroceryItem()">
ADD ITEM
</button>
</div>
</div>
</div>
</ion-content>
app.controller('getGrocery', function($scope){
//console.log("Grocery Items");
$scope.groceryItems = [
{
'itemName':'Rice',
'Quantity':'5kg',
'Rate':'50'
},
{
'itemName':'Wheat',
'Quantity':'6kg',
'Rate':'44'
}
];
//Hide show elemment
$scope.GroceryItem = false;
$scope.addGroceryItem = function() {
//$scope.groceryObj = {};
$scope.groceryItems.push(
{
itemName:$scope.gItem,
Quantity:$scope.gKg,
Rate:$scope.gPrice
}
);
console.log($scope.gItem)
console.log($scope.gKg)
console.log($scope.gPrice)
$scope.gItem = "";
$scope.gKg = "";
$scope.gPrice = "";
}
})
http://i.stack.imgur.com/1at2T.png
As per reference http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html
Angular Scopes and Prototypes.
AngularJS will often create child scopes inside of directives, for the same reasons we saw above: it allows a directive to have it’s own space for key/value pairs, without messing with higher level data. Child scopes inherit from parent scopes using prototypal inheritance. (There is an exception for isolated scopes);
But we often do want to transparently write to a higher level scope, and this is where the “dot rule” comes in. Let’s see how that is applied.
Do not do this
// Controller
$scope.gItem = "Test"
// HTML
<input ng-model="gItem">
That is bad because we can’t write to it from a child scope, because a child scope uses prototypal inheritance. Once you write to gItem from a child scope, it would become a distinct value in that child scope, and no longer refer up to the parent’s gItem.
Instead, do this
// Controller
$scope.newItem = {
gItem: "",
gKg: "",
gPrice: "",
}
// HTML
<input ng-model="newItem.gItem">
The difference is we are not storing the data directly on the scope. Now when ng-model wants to write, it actually does a read, then write. It reads the newItem property from the scope, and this will work from a child scope because a child scope will search upwards for a read. Once it finds newItem, it writes to newItem.gItem, which is no problem. It just works
Index.html should be
<body ng-app="grocery">
<ion-pane ng-controller="getGrocery">
<ion-header-bar class="bar bar-header bar-assertive">
<h1 class="title text-center">Grocery</h1>
<button class="button" ng-click="GroceryItem=!GroceryItem" ng-class="{active:GroceryItem}">
<i class="icon ion-android-add"></i>
</button>
</ion-header-bar>
<ion-content class="grocery-wrapper">
<ion-list>
<ion-item ng-repeat="groceryItem in groceryItems">
<div class="row">
<div class="col col-20">
<label class="checkbox checkbox-balanced">
<input class="checkbox" type="checkbox"/>
</label>
</div>
<div class="col col-33 g-items">{{groceryItem.itemName}}</div>
<div class="col g-items">{{groceryItem.Quantity}}</div>
<div class="col g-items">{{groceryItem.Rate}} rs/kg</div>
</div>
</ion-item>
<ion-item id="getGroceryItem" ng-show="GroceryItem">
<div class="row">
<div class="col col-50">
<label class="item item-input item-floating-label">
<span class="input-label">Grocery Item</span>
<input ng-model="newitem.gItem" type="text" placeholder="Grocery Item">
</label>
</div>
<div class="col">
<label class="item item-input item-floating-label">
<span class="input-label">Kg</span>
<input ng-model="newitem.gKg" type="text" placeholder="kg">
</label>
</div>
<div class="col">
<label class="item item-input item-floating-label">
<span class="input-label">Price</span>
<input ng-model="newitem.gPrice" type="text" placeholder="Price">
</label>
</div>
</div>
<div class="row">
<button class="button button-block button-balanced button-medium" ng-click="addGroceryItem()">
ADD ITEM
</button>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-pane>
app.js should be
app.controller('getGrocery', function($scope){
//console.log("Grocery Items");
$scope.groceryItems = [
{
'itemName':'Rice',
'Quantity':'5kg',
'Rate':'50'
},
{
'itemName':'Wheat',
'Quantity':'6kg',
'Rate':'44'
}
];
//Hide show elemment
$scope.GroceryItem = false;
$scope.newitem = {
gItem: "",
gKg: "",
gPrice: "",
}
$scope.addGroceryItem = function() {
//$scope.groceryObj = {};
console.log($scope.newitem.gItem)
console.log($scope.newitem.gKg)
console.log($scope.newitem.gPrice)
$scope.groceryItems.push(
{
itemName:$scope.newitem.gItem,
Quantity:$scope.newitem.gKg,
Rate:$scope.newitem.gPrice
}
);
$scope.newitem = {
gItem: "",
gKg: "",
gPrice: "",
}
}
});