Dynamic Angular and Ionic checkbox list - javascript

I have my app in Ionic and Angular. I have a list with checkbox items that come from an array. What I want is when the user clicks on a checkbox item, they are added to a separate list i.e my choices.
the code is:
App.js
$scope.myList = [
{name:'Choice one'},
{name:'Choice two)'}
];
HTML VIEW:
<div>
<ul class="list">
<li class="item item-checkbox" ng-repeat='item in myList | filter: search'>
<label class="checkbox">
<input type="checkbox" ng-model="option.myList[$index]">
</label>
<p ng-bind-html="item.name"></p>
</li>
<ul>
</div>
So I want the choices once clicked to be added to a list above which is similar code to the html above. Any ideas?

maybe something like this:
$scope.myList = [
{name:'Choice one'},
{name:'Choice two)'}
];
$scope.myChoices = [];
$scope.stateChanged = function(checked){
if(checked){
$scope.myChoices.push(checked);
}else{
var index = $scope.myChoices.indexOf(checked);
$scope.myChoices.splice(index,1);
}
}
html:
<div>
<ul class="list">
<li class="item item-checkbox" ng-repeat='item in myList | filter: search'>
<label class="checkbox">
<input type="checkbox" ng-model="option.myList[$index]" ng-change='stateChanged(option.myList[$index])'>
</label>
<p ng-bind-html="item.name"></p>
</li>
<ul>
</div>

See this demo with your code : http://play.ionic.io/app/89d16b54285b
You do not need to make a seperate list to show selected options somewhere else. Just attach selected property with each object this way <input type="checkbox" ng-model="item.selected">
<ul class="list">
<li class="item item-checkbox" ng-repeat='item in myList | filter: search'>
<label class="checkbox">
<input type="checkbox" ng-model="item.selected">
</label>
<p ng-bind-html="item.name"></p>
</li>
<ul>
Now you can use same myList anywhere to see which is selected using filter
<div class="item" ng-repeat="item in myList | filter:{selected:true}">
{{item.name}}
</div>

Related

how to access multiple class of child tags and the child tags themselves of a parent element in html using javascript?

I am creating a page where the user checks the checkbox of the dish name and set the quantity of orders they want for that particular dish. I want to give it a logic where it increments the quantity of a dish only when that particular dish is checked.
To do this all I can think of is to use the child elements of the ul element in the form section. I want to write a function in js that first checks if the checkbox of a particular li element is checked or not. If checked then only will it increase the quantity on the button pressed. But I can't figure out how to do so.
This is my HTML code.
<form>
<ul id = 'food_tracker'>
<li class="item-block">
<div class="food_box">
<input type="checkbox" class="cb" name="Food-item" id="food-item-" value="Tandoori Chicken"/>
<label for="food-item-one">Tandoori Chicken</label>
</div>
<div class="quantity">
<span class="decrease">-</span>
<p id="value">1</p>
<span class="increase">+</span>
</div>
<div class="pricing">
<p>$150</p>
</div>
</li>
<li class="item-block">
<div class="food_box">
<input type="checkbox" class="cb" name="Food-item" id="food-item-two" value="Schezwan Chicken"/>
<label for="food-item-two">Schezwan Chicken</label>
</div>
<div class="quantity">
<span class="decrease">-</span>
<p>1</p>
<span class="increase">+</span>
</div>
<div class="pricing">
<p>$329</p>
</div>
</li>
<li class="item-block">
<div class="food_box">
<input type="checkbox" class="cb" name="Food-item" id="food-item-three" value="Chicken Lollypop"/>
<label for="food-item-three"> Chicken Lollypop</label>
</div>
<div class="quantity">
<span class="decrease">-</span>
<p>1</p>
<span class="increase">+</span>
</div>
<div class="pricing">
<p>$229</p>
</div>
</li>
<li class="item-block">
<div class="food_box">
<input type="checkbox" class="cb" name="Food-item" id="food-item-four" value="Russian Chicken"/>
<label for="food-item-four">Russian Chicken</label>
</div>
<div class="quantity">
<span class="decrease">-</span>
<p>1</p>
<span class="increase">+</span>
</div>
<div class="pricing">
<p>$157</p>
</div>
</li>
<li class="item-block">
<div class="food_box">
<input type="checkbox" class="cb" name="Food-item" id="food-item-five" value="Afghani Chicken"/>
<label for="food-item-five">Afghani Chicken</label>
</div>
<div class="quantity">
<span class="decrease">-</span>
<p>1</p>
<span class="increase">+</span>
</div>
<div class="pricing">
<p value="149">$149</p>
</div>
</li>
</ul>
</form
In the javascript section, I am trying to use conditionals that if the checkbox of a particular element is checked only then can the quantity increase or decrease.
This is the link to the page
Online_Order_Page
Please correct me on where and what am I doing wrong.
I also want to create a function which will increase/decrease the pricing as the quantity for that particular dish increases/decreases.
Some tips on this will be appreciated as well.
Couple of things:
At the end of the js code, you loop through the items, and only attach an event listener to the buttons, if they are checked (by default, none of them are checked, so no event listeners are registered).
You try to attach an eventlistener to the increment/decrement buttons, but that's a NodeList of the buttons, not a single button.
You only have 1 count variable, and all the buttons are changing it. You need to keep count of each individual item's count.
A tip: Try to store your data in a different data structure. For example in an array of objects:
let items = [
{
id: 1,
name: 'Tandoori Chicken',
count: 1
checked: false,
},
{
id: 2,
name: 'Schezwan Chicken',
count: 1
checked: false,
},
...
];
You don't have to hard code them one-by-one, you can loop through the html items, get the names, the ids and the count and checked are always 1 and false by default.
While looping through them, you can attach an event listener to the checkbox, that sets the object's checked attribute to true/false, and the increment/decrement changes the count of the given object.
You will also be able to replace the shown amount within the event listener.

I want to alert on when checkbox checked but this code is not working

I'm trying to figure out why the alert boxes and console logs don't work as intended when I check a checkbox.
jquery code
$(document).ready(function(){
$("#location").click(function(){
$("input[name='location']:checked").each(function(){
alert("go");
});
});
});
laravel blade checkbox code
<div class="sidebar-box">
<h5>Location</h5>
<ul class="checkbox-list">
#foreach($store_location as $store_location)
<li class="checkbox">
<label>
<input type="checkbox" class="i-check" id="location" name="location">
{{ $store_location->store_location_name }}
</label>
</li>
#endforeach
</ul>
</div>
First you should answer, if the #foreach loop works fine and renders the ul > li list correctly. I gues it works.
The JS Code
I've rewritten your code and it works even though there is a problem in your code. You really should use non-identical id attributes. You can use classes or what ever multiple times in different HTML tags, but not the id attribute. But this does not cause the problem. Have a look on the example:
Example (in plain JavaScript)
document.querySelectorAll('#location').forEach(locationEl => {
locationEl.addEventListener('click', () => {
document.querySelectorAll('input[name=location]:checked').forEach(el => {
console.log('go');
});
});
});
/*
"Equivalent" to your jQuery Code:
$(document).ready(function(){
$("#location").click(function(){
$("input[name='location']:checked").each(function(){
alert("go");
});
});
});
*/
<ul>
<li>
<input type="checkbox" name="location" id="location">
</li>
<li>
<input type="checkbox" name="location" id="location">
</li>
<li>
<input type="checkbox" name="location" id="location">
</li>
<li>
<input type="checkbox" name="location" id="location">
</li>
</ul>
Better:
document.querySelectorAll('input[name=location]').forEach(locationEl => {
locationEl.addEventListener('click', () => {
document.querySelectorAll('input[name=location]:checked').forEach(el => {
console.log(el.value, 'is checked');
});
});
});
<ul>
<li>
<input type="checkbox" name="location" value="1">
</li>
<li>
<input type="checkbox" name="location" value="2">
</li>
<li>
<input type="checkbox" name="location" value="3">
</li>
<li>
<input type="checkbox" name="location" value="4">
</li>
</ul>
With input[name=location] as a selector you are addressing any input tag with an attribute name with a value of location. And this should just work.
The Blade Template Code
You are using most probably by accident the same variable name for the variable which should be iterated and the output item of each loop. You should try to rename them depending on the name of the variable which holds the array of your desired information:
<div class="sidebar-box">
<h5>Location</h5>
<ul class="checkbox-list">
#foreach($store_location as $location)
<li class="checkbox">
<label>
<input type="checkbox" class="i-check" name="location">
{{ $location->store_location_name }}
</label>
</li>
#endforeach
</ul>
</div>
If this won't work, consider to upload some part of your rendered HTML code. The one you've uploaded is the blade code, right? Or try to debug your variables that you've pushing toward your blade template. Good luck!

Angular array values connected to ng-model

I'm using two <select> tags to push values to an array in the $scope. For some reason this array then becomes connected to the select elements and when they are changed it changes the array elements.
I have made a codepen to demonstrate this behaviour.
View:
<div class="form-group">
<div class="row">
<div class="col-sm-4">
<label class="item item-input item-select">
<div class="input-label positive">
Select Parameter
</div>
<select ng-model="data.param">
<option ng-repeat="param in params track by $index" value="{{param}}">{{param}}</option>
</select>
</label>
</div>
<div class="col-sm-4">
<label class="item item-input item-select">
<div class="input-label positive">
{{data.param || 'SELECT'}}
</div>
<select ng-model="data.childParam">
<option ng-repeat="child in children[data.param] track by $index" value="{{child}}">{{child}}</option>
</select>
</label>
</div>
<div class="col-sm-4">
<button class="btn btn-primary" ng-click="addParam(data)"> SAVE</button>
</div>
</div>
<ul class="list-group">
<li ng-repeat="savedParm in activeExercise.Params track by $index" class="list-group-item"><strong>{{savedParm.param}}</strong> : {{savedParm.childParam}}
</li>
</ul>
{{activeExercise.Params}}
</div>
Controller:
$scope.addParam = function(data) {
console.log(data);
if (!$scope.activeExercise.Params) {
$scope.activeExercise.Params = [];
}
if ($scope.activeExercise) {
$scope.activeExercise.Params.push(data);
} else if ($scope.editExercise.Params) {
$scope.editExercise.Params.push(data);
}
console.log(JSON.stringify($scope.activeExercise));
}
You add to array reference to object, so when you change value in select, you change property existing object, but not object reference, so all reference point to object with updated field.
for solving you can copy object fields to new object, like:
var ndata = {param:data.param, childParam:data.childParam}
and then push to array ndata object instead data

get input text value when checkbox selected in li jquery?

I want to get only input value from li those checkbox is selected and send to the controller as key value pair means key as checkbox id and value as a input textbox value. There is multiple li inside ul.
I found something like a
$('li').find('input:checked, input[type=text]').map(function(i,el) {
getInputVal= el.type === 'checkbox'
? el.value
:"";
});
But not working.
Following is the my html code structure.
<ul id="sortable">
<li id="row_39" class="img">
<div class="checkbox">
<input type="checkbox" value="Mzk=" class="set_left" name="remove_img[]" id="remove_img[]">
<b><label class="set_center">1</label></b>
</div>
<div class="img_main">
<a rel="gallery" class="boxer" title="AA" href="/prod_images/prod_21_13905400722.jpg">
<img width="'200 height=" 136="" src="/prod_images/prod_21_13905400722.jpg">
</a>
</div>
<div class="desc">
<input type="text" value="AA" class="textbox" name="update_caption[]">
</div>
</li>
<li id="row_43" class="img">
<div class="checkbox">
<input type="checkbox" value="NDM=" class="set_left" name="remove_img[]" id="remove_img[]">
<b><label class="set_center">2</label></b>
</div>
<div class="img_main">
<a rel="gallery" class="boxer" title="AA" href="/prod_images/prod_21_13905400726.jpg">
<img width="'200 height=" 134="" src="/prod_images/prod_21_13905400726.jpg">
</a>
</div>
<div class="desc">
<input type="text" value="AA" class="textbox" name="update_caption[]">
</div>
</li>
..........
Please suggest me some answer.
Thanks in advance
I think what you are looking for is
var params = {};
$('li input:checked').each(function (i, el) {
params[this.id] = $(this).closest('li').find('input:text').val()
});
console.log(params)
Note: Your checkbox id is static so you will be overriding the same key in the object, you li elements has a dynamic part in its id, do you want to use that as the key for the params object

How to get form input value to replace form on submit with Angular.js

I'm new to Angular. I have a form in an ordered list. When a user inputs a value in the form and clicks "add", I'd like the value from the form to replace the form, and another list item added below with the same form allowing the user to add another item, etc., etc.
Below is what I've got so far. I have the ordered list with form input, but right now when you click "add", the item appears below as a separate list item instead of replacing the form. I'd like it to replace the form, then insert a new list item below with the same form so the user can continue to add items to the list in this manor.
items.html
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script>
<script src="items.js"></script>
</head>
<body>
<h2>Items</h2>
<div ng-controller="ItemCtrl">
<ol>
<li>
<form ng-submit="addItem()">
<input type="text" ng-model="itemText" size="30"
placeholder="add new item to list">
<input class="btn-primary" type="submit" value="add">
</form>
</li>
<li ng-repeat="item in items">
<span>{{item.text}}</span>
</li>
</ol>
</div>
</body>
</html>
items.js
function ItemCtrl($scope) {
$scope.items = [];
$scope.addItem = function() {
$scope.items.push({text:$scope.itemText});
$scope.itemText = '';
};
}
http://jsfiddle.net/kL4rp/
How do I get that to work as described?
Thanks
Looks like you just need to switch the form and ng-repeat directive.
Like so:
<div ng-controller="ItemCtrl">
<ol>
<li ng-repeat="item in items">
<span>{{item.text}}</span>
</li>
<li>
<form ng-submit="addItem()">
<input type="text" ng-model="itemText" size="30"
placeholder="add new item to list">
<input class="btn-primary" type="submit" value="add">
</form>
</li>
</ol>
</div>
jsfiddle example
I edited your fiddle:
http://jsfiddle.net/kL4rp/2/
I believe if you just place the ng-repeat of items above the form you will achieve the desired behavior.
<li ng-repeat="item in items">
<span>{{item.text}}</span>
</li>
<li>
<form ng-submit="addItem()">
<input type="text" ng-model="itemText" size="30"
placeholder="add new item to list">
<input class="btn-primary" type="submit" value="add">
</form>
</li>

Categories