UPDATE
I thought about this and this is what I'm thinking. Maybe I can just filter the list on input (when I type into the input box) rather than automatically have this filter. Is this possible?
I've created a combo box with angular, and I've bound a scope variable to my input using ng-model. Right now the functionality is, you can search for an item in the dropdown. when you click on an item in the dropdown, that value is copied into the input.
however, when I go back into the input to search again, it only brings up items that match the search, which is expected. But I'd like to make it so when you click on the input again, the text that was in the input stays there, but the drop down shows all results.
is this doable? Maybe I can bind a different scope variable to the value of the input?
heres the fiddle: https://jsfiddle.net/mLsbmfb7/25/
html:
<div class='center' ng-app="myapp" ng-controller="appCont">
<div class='form-box'>
<div class='inputs-box'>
<div>
<span>First</span>
<input type='text' ng-model="firstname"/>
</div>
<div>
<span>Last</span>
<input type='text' ng-model="lastname"/>
</div>
</div>
<div class='add-button' ng-click="addPerson()">
add
</div>
</div>
<div class='ppl-list-title'>
<div class='inputs-box'>
<div class='inline-block-top find-word'>Find</div>
<div class='inline-block-top'>
<input id='filter-input' type='text' ng-model='filterText'/>
<div>
<ul class='hidden'>
<li ng-repeat='person in people2 | filter:{fullName:filterText}'
ng-click='setInputValue(person.fullName)'>
<span class=''>{{person.fullName}}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
controller and jquery:
var myapp = angular.module("myapp", []);
myapp.controller('appCont', function($scope) {
$scope.firstname = "";
$scope.lastname = "";
$scope.fullname = function() {
return $scope.firstname + ' ' + $scope.lastname;
};
var Person = function(){
this.firstname = "";
this.lastname = "";
this.isActive = true;
this.fullName = "";
};
function getFullName(first, last) {
return first
+ " "
+ last
};
function getPerson(first, last, active) {
var newPerson = new Person();
newPerson.firstname = first;
newPerson.lastname = last;
newPerson.isActive = active;
newPerson.fullName = first + ' ' + last;
return newPerson;
};
$scope.addPerson = function() {
var personToAdd =
getPerson($scope.firstname, $scope.lastname, true);
$scope.people2.push(personToAdd);
$scope.firstname = '';
$scope.lastname = '';
};
$scope.setInputValue = function(full) {
$scope.filterText = full;
};
$scope.people2 = [
getPerson("first", "test", true),
getPerson("second", "try", false),
getPerson("third", "testing", true)];
});
$(document).ready(function() {
$('#filter-input').on('focusin', function() {
$('ul').slideToggle();
});
$('#filter-input').on('focusout', function() {
$('ul').slideToggle();
});
});
function stringFullTrim(word) {
while(word.indexOf(' ') > -1) {
word = word.replace(' ', ' ');
}
return word.trim();
}
Did it by using a fake text input to update the real filter.
<input id='filter-input' type='text' ng-model='temp' ng-keyup='filterText = temp'/>
<input id='filter-input' type='hidden' ng-model='filterText'/>
Then on selecting, copy text into it and wipe the filter, so next search would be fresh again.
<li ng-repeat='person in people2 | filter:{fullName:filterText}'
ng-click='setInputValue(person.fullName); $parent.temp = person.fullName; $parent.filterText = ""'>
You might want to handle some edge cases like user typed the full thing but didn't select.
Note: the $parent is used because of ng-repeat is creating a child scope. The usual way to solve this is to use "the dot" but sometimes I feel like using $parent.
I've edited your fiddle
Related
Hello I would like to load data options of the 2nd select from mysql when I click on a value of the first selectors.
And keep the JSON data of the last fields selected and keep append function.
I know how to import data from mysql, but I Would like to get Values each time I change the first selectors without changing all second selectors, only the concerned selector.
How it works.
I select a category ( not shown in the code )
the most important:
The select 1 receive all categories of category selected.
The select 2 receive all categories of select 1 subcategory
when the 1first category is changed, the 2nd selector are loaded but don't forget I need to add unlimited fields without changing all 2nd selectors
im using this code:
https://plnkr.co/edit/kKjhpy0fdnOprFA8PAYx?p=preview
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="appCtrl">
<h3>Add Input fields dynamically</h3>
<button ng-click="addSelectItem()">Add select Field</button>
<div ng-repeat="item in selects">
<select ng-model="item.type"><option ng-repeat='option1 in type' value='{{option1.nomcarac}}' >{{option1.nomcarac}}</option></select>
<select ng-model="item.brandname" ><option ng-repeat='option1 in valuelist' value='{{option1.nomcarac}}' >{{option1.nomcarac}}</option></select>
<button ng-click="getValue(item)">get input value</button>
</div>
<pre>{{inputs | json}}</pre>
<pre>{{selects | json}}</pre>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('appCtrl', function($scope) {
$scope.inputs = [];
$scope.selects = [];
$scope.type = [{nomcarac: "phone"},{nomcarac: "shoes"}]
$scope.phonelist = [{nomcarac: "apple"},{nomcarac: "motorola 10g"}]
$scope.valuelist = [{nomcarac: "test"},{nomcarac: "test2"}]
$scope.shoeslist = [{nomcarac: "jean michel"},{nomcarac: "motorola 10g"}]
var count = 1;
var fieldname;
$scope.addItem = function(){
fieldname = "Field " + count;
$scope.inputs.push({name: fieldname});
count++;
}
$scope.addSelectItem = function(){
fieldname = "Field " + count;
$scope.selects.push({name: fieldname});
count++;
}
$scope.getValue = function(item){
alert(item.value);
}
});
</script>
</body>
</html>
If I understood you correctly, you want to populate options of the second select every time, you change the value of the first select in the group.
If so, you can use ngChange to accomplish this and store the values list within the corresponding item object:
var app = angular.module('myApp', []);
app.controller('appCtrl', function($scope) {
$scope.inputs = [];
$scope.selects = [];
$scope.type = [{nomcarac: "phone"}, {nomcarac: "shoes"}];
$scope.phonelist = [{nomcarac: "apple"}, {nomcarac: "motorola 10g"}];
$scope.shoeslist = [{nomcarac: "jean michel"}, {nomcarac: "gucci"}];
var count = 1;
var fieldname;
$scope.addItem = function(){
fieldname = "Field " + count;
$scope.inputs.push({name: fieldname});
count++;
};
$scope.addSelectItem = function(){
fieldname = "Field " + count;
$scope.selects.push({name: fieldname});
count++;
};
$scope.getValue = function(item){
console.log(item);
};
$scope.getValuesList = function(item) {
//get actual data from db
switch (item.type){
case 'phone':
item.valuelist = angular.copy($scope.phonelist);
break;
case 'shoes':
item.valuelist = angular.copy($scope.shoeslist);
break;
default:
item.valuelist = [];
break;
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="appCtrl">
<h3>Add Input fields dynamically</h3>
<button ng-click="addSelectItem()">Add select Field</button>
<div ng-repeat="item in selects">
<select ng-model="item.type" ng-change='getValuesList(item)'>
<option ng-repeat='option in type' value='{{::option.nomcarac}}' >{{::option.nomcarac}}</option>
</select>
<select ng-model="item.brandname">
<option ng-repeat='option in item.valuelist' value='{{::option.nomcarac}}' >{{::option.nomcarac}}</option>
</select>
<button ng-click="getValue(item)">get input value</button>
</div>
<pre>{{inputs | json}}</pre>
<pre>{{selects | json}}</pre>
</div>
I am trying to do an edit field in angular js but I don't know how to do that one help me
below is my Crud operation code
var app = angular.module('myApp', [])
app.controller('myCtrl', ['$scope', function($scope) {
$scope.products = ["venu", "balaji", "suresh"];
$scope.addItem = function() {
$scope.errortext = "";
if (!$scope.addMe) {
return;
}
if ($scope.products.indexOf($scope.addMe) == -1) {
$scope.products.push($scope.addMe)
} else {
$scope.errortext = "The item is already in your names list.";
}
}
$scope.removeItem = function(x) {
$scope.errortext = "";
$scope.products.splice(x, 1);
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="x in products">{{x}}<span ng-click="removeItem($index)">×</span>
</li>
</ul>
<input ng-model="addMe">
<button ng-click="addItem()">ADD</button>
<p>{{errortext}}</p>
<p>Try to add the same name twice, and you will get an error message.</p>
</div>
</div>
I am doing crud operations in angular js. i have done Delete and Add but I dont know how to do Edit operation in angular js
var app = angular.module('myApp', [])
app.controller('myCtrl', ['$scope', function($scope) {
$scope.products = ["venu", "balaji", "suresh"];
$scope.addItem = function() {
$scope.errortext = "";
if (!$scope.addMe) {
return;
}
if ($scope.products.indexOf($scope.addMe) == -1) {
$scope.products.push($scope.addMe)
} else {
$scope.errortext = "The item is already in your names list.";
}
$scope.addMe = "";
}
$scope.removeItem = function(x) {
$scope.errortext = "";
$scope.products.splice(x, 1);
}
$scope.edit = function(index){
$scope.addMe = $scope.products[index];
$scope.products.splice(index, 1);
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="x in products">{{x}}
<span ng-click="removeItem($index)">×</span>
<span style="color:blue;cursor:pointer;" ng-click="edit($index)">Edit</span>
</li>
</ul>
<input ng-model="addMe">
<button ng-click="addItem()">ADD</button>
<p>{{errortext}}</p>
<p>Try to add the same name twice, and you will get an error message.</p>
</div>
</div>
Try this.
The solution is here:
HTML
<li ng-repeat="x in products" ng-click="preEdit(x, $index)">{{x}}<span ng-click="removeItem($index)">×</span></li>
<input ng-model="addMe">
<button ng-if="isAdd" ng-click="addItem()">ADD</button>
<button ng-if="!isAdd" ng-click="editItem()">EDIT</button>
JS
$scope.isAdd = true;
$scope.preEdit = preEdit;
var index = '';
function preEdit(x, i){
$scope.addMe = x;
index = i;
$scope.isAdd = false;
}
$scope.editItem = editItem ;
function editItem (){
$scope.products[index] = $scope.addMe;
$scope.isAdd = true;
$scope.addMe = '';
index = '';
}
Look my solution in filddle: https://jsfiddle.net/tfx8njw6/
At first you need to add a edit option on the <li> say,
<ul>
<li ng-repeat="x in products">{{x}}
<span ng-click="removeItem($index)">×</span>
<span ng-click="editItem($index)">Edit</span>
</li>
</ul>
Then add a controller function for edit editItem() like
$scope.editItem= function(index) {
$scope.addMe = $scope.products[index];
//this variable will allow you to check whether the operation is an edit or add
$scope.editIndex = index;
}
You can then reuse your addItem() function like this
$scope.addItem = function() {
$scope.errortext = "";
if (!$scope.addMe) {
return;
}
if(angular.isDefined($scope.editIndex)){
$scope.products[$scope.editIndex] = $scope.addMe;
//reset the variable to undefined after using it
$scope.editIndex = undefined;
}else{
if ($scope.products.indexOf($scope.addMe) == -1) {
$scope.products.push($scope.addMe);
} else {
$scope.errortext = "The item is already in your names list.";
}
}
}
If you want to take it to the "next level", check out xeditable. :)
https://vitalets.github.io/angular-xeditable/#text-simple
Good luck!
For Edit what you can do:
0.Pass the id on edit click and get data of that id and assign to the same variable you have used for add and hide add button and show update button.
1.Either use the same text field which you are using for add and show/hide button add/update accordingly.
2.You can use separately div which includes one text box and button to update.Show/hide as per you action.
I want to update my object with values from text fields.
I think the problem is with the click eventhandler on the button but not sure. I've tried a few things, Your help would be amazing.
HTML
<form>
<label><p>Book Name: </p></label>
<input name="booktitle" id="booktitle" type="text" value="I'm a value">
<label><p>Total Pages: </p></label>
<input type="text">
<label><p>Current Page: </p></label>
<input type="text">
<button id="my-Btn" type="button">Add to List</button>
</form>
JS
(function() {
// Create book object
var book = {
name: 'JavaScript & jQuery',
totalPages: 622,
pages: 162,
pagesLeft: function() {
var total = this.totalPages - this.pages;
return total;
},
percentageLeft: function() {
var totalPercentage = this.pagesLeft() / this.totalPages * 100
return Math.round(totalPercentage);
}
};
// write out book name and pages info
var bookName, totalPages, pagesLeft, percentageLeft; //declares variables
bookName = document.getElementById('bookName'); // gets elements from document
totalPages = document.getElementById('totalPages');
pagesLeft = document.getElementById('pagesLeft');
percentageLeft = document.getElementById('percentageLeft');
bookName.textContent = book.name; // write to document
totalPages.textContent = 'Total Pages: ' + book.totalPages;
pagesLeft.textContent = book.pagesLeft();
percentageLeft.textContent = book.percentageLeft() + '%';
// pull value from text field and set to object
document.getElementById("my-Btn").addEventListener("click", function() {
book.name = document.getElementById('booktitle').value;
});
}());
Code Pen of what I have so far.
http://codepen.io/Middi/pen/pRGOVW
Thanks in advance.
Your code already updates an object's property (book.name) with a value from a text field (#booktitle). You can see this by adding alert(book.name); after the line
book.name = document.getElementById('booktitle').value;
As Jazcash noted, if you wanted to display the updated book name everytime it was changed, you'd need to add
bookName.textContent = book.name;
In your eventlistener, so it'd look something like this:
document.getElementById("my-Btn").addEventListener("click", function() {
book.name = document.getElementById('booktitle').value;
bookName.textContent = book.name;
});
The problem is you're setting your divs textContent based on book here: bookName.textContent = book.name;. But then you need to do it again in your event like so:
book.name = bookName.value;
bookName.textContent = book.name;
You'll need to do this for all your fields
I am trying to use autocomplete function of jquery inside my angular controller and that doesn't work may be because of ng-model or ng-repeat I don't know exactly ^^
My html file contains this code
<div ng-if="data._id" data-ng-controller="AddonExclusivityCtrl" ng-init="init()">
<hr>
<label>Add an addon that is not bookable with this one:</label>
<input id="addon-search" type="text"
ng-model="addon_filter_name"
class="form-control" placeholder="Search for an addon...">
<br>
<div ng-show="data._embedded.exclusive_with && data._embedded.exclusive_with.length > 0">
<label>Not bookable with:</label>
<ul>
<li ng-repeat="exclusive_with in data._embedded.exclusive_with">
{{exclusive_with.description}} <a href="#"
ng-click="removeExclusivity($event, exclusive_with)"
title="Remove mutual exclusivity">
<span class="glyphicon glyphicon-trash"></span></a>
</li>
</ul>
</div>
</div>
And my controller contains the following code :
var lastFetchedAddonList = [];
$scope.init = function() {
$('#addon-search').autocomplete({
source: function( request, response ) {
Addon.query({ name: request.term, global: null }, function(results) {
lastFetchedAddonList = results.data;
var suggestions = [];
angular.forEach(results.data, function(v, i){
suggestions.push({ label: v.description, value: i });
});
response(suggestions);
});
},
select: function( event, ui ) {
event.preventDefault();
if ($scope.data._embedded === undefined) {
$scope.data._embedded = [];
}
if ($scope.data._embedded.exclusive_with === undefined) {
$scope.data._embedded.exclusive_with = [];
}
var addon = lastFetchedAddonList[ui.item.value];
var exclusiveAddon = new AddonExclusivity();
exclusiveAddon._id = $scope.data._id;
exclusiveAddon.exclusive_with_addon = addon.name;
AddonExclusivity.save(exclusiveAddon, function(){
$rootScope.addNotification('Added ' + addon.description + ' as mutually exclusive with ' + $scope.data.description);
$scope.data._embedded.exclusive_with.push(addon);
$('#addon-search').val('');
});
return false;
}
});
};
$scope.removeExclusivity = function($event, addon) {
$event.preventDefault();
AddonExclusivity.delete({ id: $scope.data._id, other_id: addon.name }, function(){
$rootScope.addNotification('Addon ' + addon.description + ' is not anymore mutually exclusive with ' + $scope.data.description);
$scope.data._embedded.exclusive_with.splice($scope.data._embedded.exclusive_with.indexOf(addon), 1);
});
};
Thank you for your help in advance :)
Instead of using jquery autocomplete, you can use plain html to create your autocomplete.
See this post here
I have the same problem. The reason is angularjs repeat ng-model tag the id is always the same.
So only the first tag with that id works fine with autocomplete.
but the second and after with same id would not work.
I am looking at angular-module angucomplete-alt angucomplete-alt
This should solve your problem.
I've a list on ng-repeat that displays a list of results from a $http query (bind to an input). I'd like both for the list to disappear when the user clicks on one of the results and for the initial empty value of the model to be restored.
Basically, the functionality is as follows:
User searches term, list displays results, user clicks on result, list disappears, user clicks on input again to make another search, list with new results appear.
So far I've managed to make the list disappear, but not to make it appear again when the user makes another search.
Here's the relevant code:
<input type="text" ng-model="name" ng-click="Research()"/>
<ul ng-hide="clicked" ng-show="retype">
<li ng-repeat="result in results" ng-click="getDetails(result.id)">{{result.title}}</li>
</ul>
And the JS:
function Ctrl($scope, $http) {
var get_results = function(name) {
if (name) {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=8').
success(function(data3) {
$scope.results = data3.results;
});
}
}
$scope.name = '';
$scope.$watch('name', get_results, true);
$scope.getDetails = function (id) {
$http.get('http://api.discogs.com/artists/' + id).
success(function(data) {
$scope.artist = data;
});
$http.get('http://api.discogs.com/artists/' + id + '/releases?page=1&per_page=500').
success(function(data2) {
$scope.releases = data2.releases;
});
$scope.clicked = true;
}
function Research(){
$scope.retype = true,
$scope.name = '';
}
Plunkr is down, I'll make one as soon as possible. Any idea about what am I missing?
I tidied up your code a little bit. Please note that the div is shown only when artist is defined. So when it is set to undefined by the $scope.clear() method, the mentioned div is hidden.
Html part:
<div ng-controller="Ctrl">
<input type="text" ng-model="name" ng-focus="clear()"/>
<ul>
<li ng-repeat="result in results" ng-click="getDetails(result.id)">{{result.title}}</li>
</ul>
<div ng-show="artist">
<h1>Artist</h1>
<ul>
<li>{{artist.name}}</li>
<li>{{artist.release_url}}</li>
<li>{{artist.uri}}</li>
<li>{{artist.resource_url}}</li>
</ul>
</div>
</div>
JavaScript part:
var myApp = angular.module('myApp',[]);
function Ctrl($scope, $http) {
$scope.name = undefined;
$scope.artist = undefined;
$scope.results = undefined;
var search = function (name) {
if (name) {
$http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=8').
success(function(data3) {
$scope.results = data3.results;
});
}
}
$scope.$watch('name', search, true);
$scope.getDetails = function (id) {
$http.get('http://api.discogs.com/artists/' + id).
success(function(data) {
$scope.artist = data;
});
$http.get('http://api.discogs.com/artists/' + id + '/releases?page=1&per_page=500').
success(function(data2) {
$scope.releases = data2.releases;
});
}
$scope.clear = function () {
$scope.name = undefined;
$scope.artist = undefined;
$scope.results = undefined;
}
}
There is working JSFiddle.
Your Research function is unnecessary because you don't need ng-show and ng-hide same time...
secondly you set clicked to ok but never set it false again after your research done...
here is working PLUNKER
Try using just one ng-hide or ng-show, instead of both. Since you never set clicked back to false, it is probably overriding the retype.
Both functions are two-way, so you can just use ng-hide="clicked", and inside function Research, set $scope.clicked to false.