Ionic pass data - html

I got these codes online and below are what the codes are supposed to achieve as stated by the owner.
The user can add a new contact (name, email address and phone number)
List of contacts should be shown
The user can delete any contact from the contact list
The User can edit any contact from the contact list
However, when I tried it out, there is a default data in the contact list and if I want to add/save additional data to the contact list, it will only save the data in the contact list after I edit what one of the data which was already in the contact list.
enter image description here
Below are the codes:
1. HTML:
<ion-view view-title="Dashboard">
<ion-content class="padding">
<div>
<form>
<label>Name</label>
<input type="text" name="name" ng-model="newcontact.name"/>
<label>Email</label>
<input type="text" name="email" ng-model="newcontact.email"/>
<label>Phone</label>
<input type="text" name="phone" ng-model="newcontact.phone"/>
<br/>
<input type="hidden" ng-model="newcontact.id" />
<input type="button" value="Save" ng-click="saveContact()" />
</form>
<table border='1',cellpadding='10',cellspacing ='0', width ='600'>
<tr>
<td Align = 'center'>Name</td>
<td Align = 'center'>Email</td>
<td Align = 'center'>Phone</td>
<td Align = 'center'>Action</td>
</tr>
<tr ng-repeat="contact in contacts">
<td Align = 'center'>{{ contact.name }}</td>
<td Align = 'center'>{{ contact.email }}</td>
<td Align = 'center'>{{ contact.phone }}</td>
<td Align = 'center'>
edit |
delete
</td>
</tr>
</table>
</div>
</ion-content>
</ion-view>
2.JS: (controller)
angular.module('starter.controllers', [])
.controller('DashCtrl', function($scope, ContactService) {
$scope.contacts = ContactService.list();
$scope.saveContact = function () {
ContactService.save($scope.newcontact);
$scope.newcontact = {};
}
$scope.delete = function (id) {
ContactService.delete(id);
if ($scope.newcontact.id == id) $scope.newcontact = {};
}
$scope.edit = function (id) {
$scope.newcontact = angular.copy(ContactService.get(id));
}
})
(services)
angular.module('starter.services', [])
.service('ContactService',function() {
var uid = 1;
var contacts = [{
id: 0,
'name': 'Viral',
'email': 'hello#gmail.com',
'phone': '123-2343-44'
}];
//save method create a new contact if not already exists
//else update the existing object
this.save = function (contact) {
if (contact.id == null) {
//if this is new contact, add it in contacts array
contact.id = uid++;
contacts.push(contact);
} else {
//for existing contact, find this contact using id
//and update it.
for (i in contacts) {
if (contacts[i].id == contact.id) {
contacts[i] = contact;
}
}
}
}
//simply search contacts list for given id
//and returns the contact object if found
this.get = function (id) {
for (i in contacts) {
if (contacts[i].id == id) {
return contacts[i];
}
}
}
//iterate through contacts list and delete
//contact if found
this.delete = function (id) {
for (i in contacts) {
if (contacts[i].id == id) {
contacts.splice(i, 1);
}
}
}
//simply returns the contacts list
this.list = function () {
return contacts;
}
});
codes credit to : https://viralpatel.net/blogs/angularjs-service-factory-tutorial/

Related

Getting input text search auto filled using jquery & jsp not working

I have below web page it shows I have created one table & added AddRow & remove row functions using jquery. I am calling JSP file through AJAX call for auto search.
But it seems working for only first row of table & when m searching in newly added row suggestions are showing in first row only.
Below is screenshot
$(document).ready(function() {
// Denotes total number of rows
var rowIdx = 0;
// jQuery button click event to add a row
$('#addBtn').on('click', function() {
// Adding a row inside the tbody.
$('#tbody').append(`
<tr id="R${++rowIdx}">
<td class="row-index text-center">
<p>Row ${rowIdx}</p>
</td>
<td class="cb"><input class="form-control" type="text" value="" id="inputString" name="inputString" />
<div id="showList">
<ul class="list-group"></ul>
</div>
</td>
<td>
<input type="checkbox" name="debit" class="form-control">
</td>
<td>
<input type="checkbox" name="credit"class="form-control">
</td>
<td>
<input type="number" name="amount" class="form-control">
</td>
<td class="text-center">
<button class="btn btn-danger remove" type="button">Remove</button>
</td>
</tr>`);
});
/*$("#tbody").on("keyup"," input[name^=inputString]", function(){
$("tbody tr").each(function () {
var search = $(this).closest('tr').find("td:eq(rowIdx) input").val();
if(search !='' && search !=null) {
$.ajax({
type:'POST',
url:'ledgers.jsp',
data:'key='+search,
success:function(data){
$('#showList').html(data);
}
});
}
else {
$('#showList').html('');
}
});
});*/
$("#tbody").on("keyup", " input[name^=inputString]", function() {
$("tbody tr").each(function() {
var search = $(this).closest('tr').find("input").val();
if (search != '' && search != null) {
$.ajax({
type: 'POST',
url: 'ledgers.jsp',
data: 'key=' + search,
success: function(data) {
$('#showList').html(data);
}
});
} else {
$('#showList').html('');
}
});
});
$("#tbody").on("click", "li", function() {
$('#inputString').val($(this).text());
$('#showList').html('');
});
// jQuery button click event to remove a row.
$('#tbody').on('click', '.remove', function() {
// Getting all the rows next to the row
// containing the clicked button
var child = $(this).closest('tr').nextAll();
// Iterating across all the rows
// obtained to change the index
child.each(function() {
// Getting <tr> id.
var id = $(this).attr('id');
// Getting the <p> inside the .row-index class.
var idx = $(this).children('.row-index').children('p');
// Gets the row number from <tr> id.
var dig = parseInt(id.substring(1));
// Modifying row index.
idx.html(`Row ${dig - 1}`);
// Modifying row id.
$(this).attr('id', `R${dig - 1}`);
});
// Removing the current row.
$(this).closest('tr').remove();
// Decreasing total number of rows by 1.
rowIdx--;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group required col-md-8">
<table class="table table-bordered" id="table_field">
<thead>
<tr id="r1">
<th>Row No</th>
<th>Ledger Name</th>
<th>Debit</th>
<th>Credit</th>
<th>Amount</th>
<th>Add or Remove</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
<tr>
<input class="btn btn-success" type="button" name="add" id="addBtn" value="Add">
</tr>
</table>
<center>
<input class="btn btn-success" type="submit" name="save" id="save" value="Save">
</center>
</div>
can anybody suggest me whats wrong with above code.
Run auto search for every table row TD input field
enter image description here
Please replace the keyup function() with below code:
$("#tbody").on("keyup", "input[name^=inputString]", function() {
var $this = $(this);
$("tbody tr").each(function() {
var search = $(this).closest('tr').find("input").val();
if (search != '' && search != null) {
$.ajax({
type: 'POST',
url: 'ledgers.jsp',
data: 'key=' + search,
success: function(data) {
$this.next('#showList').html(data);
}
});
} else {
$('#showList').html('');
}
});
});
Please let me know if you find any issues.
Thanks.

ng-repeat is not working to refresh the display results based on filter search

// My ng-repeat is displaying the results fine, but after typing in the search box it is not filtering results as per search. please help. Also, I'm getting data from http.get
// I'm new to angular js can you help how to repeat search results and display nothing when you don't enter anything in search box.
// I used ng-show this is helping initially to stop showing
topic and response are my column headers in sheet
<html>
<head>
<script src="menu.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
// Json file : https://spreadsheets.google.com/feeds/worksheets/1OJX_UfZ7KQ-NMKcpXmYT8Ml1OfzerPnmUyEcSoMqeZc/public/basic?alt=json
// code for displaying the data in tabs
// Json file : https://spreadsheets.google.com/feeds/worksheets/1OJX_UfZ7KQ-NMKcpXmYT8Ml1OfzerPnmUyEcSoMqeZc/public/basic?alt=json
function openPage(pageName,elmnt) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].style.color = "#969595";
}
document.getElementById(pageName).style.display = "block";
elmnt.style.color = "white";
}
//angular js code to display search in JSON URL data
var app= angular.module('sample', []);
app.controller('sampleController', function ($scope, $http) {
var url = "https://spreadsheets.google.com/feeds/list/153Obe1TdWlIPyveZoNxEw53rdrghHsiWU9l-WgGwCrE/od6/public/values?alt=json";
//var url1 = "https://spreadsheets.google.com/feeds/list/1OJX_UfZ7KQ-NMKcpXmYT8Ml1OfzerPnmUyEcSoMqeZc/2/public/values?alt=json";
//var url2 = "https://spreadsheets.google.com/feeds/list/1OJX_UfZ7KQ-NMKcpXmYT8Ml1OfzerPnmUyEcSoMqeZc/3/public/values?alt=json";
//var url = "https://spreadsheets.google.com/feeds/cells/1OJX_UfZ7KQ-NMKcpXmYT8Ml1OfzerPnmUyEcSoMqeZc/1/public/values?alt=json"; // url for sheet1
$http.get(url)
.success(function(data, status, headers, config) {
$scope.users = data.feed.entry;
//console.log($scope.users);
})
.error(function(error, status, headers, config) {
console.log(status);
console.log("Error occured");
});
app.filter('highlightFilter', $sce =>
function (element, searchInput) {
element = element.replace(new RegExp(`(${searchInput})`, 'gi'),
'<span class="highlighted">$&</span>');
return $sce.trustAsHtml(element);
});
$scope.search='';
$scope.searchFilter=function(item){
if(item.gsx$topic.$t.toLowerCase().indexOf($scope.search.toLowerCase()) != -1 || item.gsx$response.$t.toLowerCase().indexOf($scope.search.toLowerCase()) != -1){
// code to highlight
// code to highlight
return true;
}
return false;
}
});
</script>
</head>
<body>
<div ng-app="sample" ng-controller="sampleController">
<input type="text" name="search" ng-model="search" placeholder="Search in all sheets" ></input>
<br>
<br>
<table style="border: 1px solid black ;" >
<tbody>
<tr>
<td style="color:blue; font-size:14px;"><center><b>Question</b></center></td>
<td style="color:blue; font-size:14px;"><center><b>Response</b></center></td>
</tr>
<tr ng-repeat="user in users | filter:searchFilter">
<td style="border: 1px solid black ; width:30%;white-space: pre-wrap;">{{user.gsx$topic.$t}}</td>
<td style="border: 1px solid black ; width:70%;white-space: pre-wrap;">{{user.gsx$response.$t}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
If you want to add search filter on single field from $scope.users then you have to specify that property from json
<div ng-repeat="user in users | filter: { gsx$topic.$t : search}">
also please update input for modal as :
<input type="text" name="search" ng-model="search" placeholder="search" ng-click="didSelectLanguage()"></input>

Knockout foreach generate html fields

I want to display as many fields as user wants.
Maybe you have idea how can I do this case using foreach loop in Knockout framework.
For example numberOfFields is input field where user can enter how many fields he wants to display
<input id="numberOfFields" type="text" data-bind="value: obj().numberOfFields() />
<div data-bind="foreach: new Array(obj().numberofCashFlows())">
<label for="quantity$index()">Flow number $index()</label>
<input id="quantity$index()" type="text" data-bind="value: quantityArray[$index()]" />
</div>
Of course code doesn't work, I want to tell you what I mean.
If user enters 3 I want to show 3 labels and inputs with id quantity1, quantity2, quantity3 and with values: quantityArray[0], quantityArray[1], quantityArray[2]
Can you help me or give some advice?
If I got your question right, this should be it by approx. I've also added and observable to the Quantity to show you how you could expand on the example with bound properties.
console.clear();
function Quantity(id, label) {
var self = this;
self.id = id;
self.label = ko.observable(label);
};
ko.applyBindings(() => {
var self = this;
self.amount = ko.observable(0);
self.quantity = ko.observableArray([]);
self.amount.subscribe(function(amount) {
var quantity = self.quantity().length;
amount = Number(amount);
if (amount > quantity) {
for (var i = quantity; i < amount; i++) {
self.quantity.push(new Quantity(i+1, 'label for ' + (i+1)));
}
} else if (amount < quantity) {
var minus = quantity - amount;
for (var i = 0; i < minus; i++) {
self.quantity.pop();
}
}
});
self.amount(2);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<label>amount: </label>
<input type="number" data-bind="textInput: amount" min="0" />
<div data-bind="foreach: quantity">
<input type="text" data-bind="textInput: label, attr: { placeholder: 'label for ' + id }" /><span data-bind="text: label"></span><br />
</div>

Filter json file with tickboxes in Angular

I am trying to filter results from my JSON file so the user can click on ladies or mens 'styles', but some products have both a ladies and mens styles, so how would I be able to show the results for 'both' without having three tick boxes? I know I cannot have duplicate names in my JSON, but have done this just as an example for now. Any help would be appreciated. I have put my code here:
http://plnkr.co/edit/fXOZHqo48ntvsdJA875y?p=preview
<div ng-controller="myCtrl">
<div ng-repeat="(prop, ignoredValue) in { 'category': true, 'cut': true }" ng-init="filter[prop]={}">
<b>{{prop | capitalizeFirst}}:</b><br />
<span class="quarter" ng-repeat="opt in getOptionsFor(prop)">
<b><input type="checkbox" ng-model="filter[prop][opt]" /> {{opt}}</b>
</span>
<hr />
</div>
<div ng-repeat="w in filtered=(products | filter:filterByProperties)">
{{w.name}} ({{w.category}})
</div>
<hr />
Number of results: {{filtered.length}}
</div>
You need to make couple of changes in your json.
Whenever there is cut has one value then it would be string & whenever there is more than one value then you could maintain an array
like "cut": "ladies", "cut": "mens", & "cut": ["ladies","mens"]
You need to handle string and filter thing in your filterByProperties function
Markup
<span ng-show="!isArray(opt)" class="quarter" ng-repeat="opt in getOptionsFor(prop)">
<b><input type="checkbox" ng-model="filter[prop][opt]" /> {{opt}}</b>
</span>
Code
$scope.isArray = function(val) {
return angular.isArray(val)
}
$scope.filterByProperties = function(product) {
// Use this snippet for matching with AND
var matchesAND = true;
for (var prop in $scope.filter) {
if (noSubFilter($scope.filter[prop])) continue;
if (!$scope.isArray(product[prop])) { //if its not an array
if (!$scope.filter[prop][product[prop]]) {
matchesAND = false;
break;
}
} else {
//if its an array
for (var i = 0; i < product[prop].length; i++) {
var anyPropMatch = false;
if ($scope.filter[prop][product[prop][i]]) {
anyPropMatch = true;
break;
}
}
if (!anyPropMatch) {
matchesAND = false;
break;
}
}
}
return matchesAND;
};
Working Plunkr

Knockout - foreach databind in 2 column table layout

I have the following table where I'm attempting to loop through coverage lines. I would like 2 columns with a different line in each, however my code duplicates the same coverage in each column. Any suggesions on how to get a 2 column layout without the repetition? Which element should my foreach binding go on? Thanks.
<table class="coverage-table" data-bind="foreach: $root.clientVM.CustomCoverageLines">
<tr>
<td>
<input type="checkbox" data-bind="checked: Checked" />
<label>
<span data-bind="text: $data.Description"></span>
</label>
</td>
<td>
<input type="checkbox" data-bind="checked: Checked" />
<label>
<span data-bind="text: $data.Description"></span>
</label>
</td>
</tr>
</table>
You could add a computed property to your model that structures the data in the way that you want. See this JSFiddle for an example: http://jsfiddle.net/6gvtz51g/. An advantage to this approach is that you can specify a different row size if you would like.
HTML
<table data-bind="foreach: coverageLineRows">
<tr data-bind="foreach: $data">
<td>
<span data-bind="text: $data"></span>
</td>
</tr>
</table>
JavaScript
function ViewModel () {
var self = this;
self.coverageLines = ko.observableArray([
'Medical',
'Dental',
'Vision',
'Life'
]);
self.coverageLineRowSize = ko.observable(2);
self.coverageLineRows = ko.computed(function () {
var rows = [];
var i = 0;
var lines = self.coverageLines();
var size = self.coverageLineRowSize();
while (i < lines.length) {
rows.push(lines.slice(i, i += size));
}
return rows;
});
}
ko.applyBindings(new ViewModel());
How do you feel about this as a solution? Its not as flexible as the solution given by #JackieChiles in that it would need some tweaking to work with different amounts of rows. But the code I've provided does provide for a prettier look for two columns and it also has the ability to keep track of the check boxes next to each of your items. I suspect a combination of both our solutions will be in your end product :)
var vm = function () {
var self = this;
this.array = ko.observableArray([{
name: ko.observable('Medical'),
checked: ko.observable()
}, {
name: ko.observable('Dental'),
checked: ko.observable()
}, {
name: ko.observable('Vision'),
checked: ko.observable()
}, {
name: ko.observable('Life'),
checked: ko.observable()
}, {
name: ko.observable('Other'),
checked: ko.observable()
}]);
this.coverageSplit = ko.computed(function () {
var retArray = [];
var i = 0;
var arrayUnWrapped = this.array();
while (i < arrayUnWrapped.length) {
if (i >= arrayUnWrapped.length - 1) {
retArray.push({
col1: arrayUnWrapped[i],
col2: {
name: '',
checked: false,
hideThisCheck: true
}
})
console.log(retArray[retArray.length - 1]);
break;
}
retArray.push({
col1: arrayUnWrapped[i],
col2: arrayUnWrapped[i + 1]
});
i += 2;
}
return retArray;
});
this.check_click = ko.observable('None');
this.setLastClicked = function (name) {
if (name.length > 0) self.check_click(name);
};
};
ko.applyBindings(vm);
Here is a fiddle of it in action http://jsfiddle.net/ozrevulsion/sva9tnje/