ng-enter directive and select attribute confilicted with each other - javascript

Consider this code:
<typeahead class="typeahead"
search="searchPersonage(term)"
select="selectPersonage(item)"
ng-model="typeaheadModel"
ng-enter='selectCustomer(typeaheadModel)'>
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr typeahead-item="customerPhone"
ng-repeat="customerPhone in customerPhones">
<td>{{customerPhone.Title}}</td>
<td>{{customerPhone.Value}}</td>
</tr>
</tbody>
</table>
</typeahead>
as you can see I have a typeahead tag and in this tag i have ng-enter directive and select attribute. What I need is when an unkown phone number is entered by user and if that number is not in typeahead objects and then user hits the enter button, I want it to be pushed in an array. But I want only that unknown number to be pushed.
However, now when user hits the enter button, not only the number is pushed in the array but also the select method is called. This causes the unknown number to be pushed into the target array, alongside an object from typeahead data source.
$scope.selectCustomer = function (item) {
$scope.selectedPhones.push({
Value: item.Value,
Title: item.Title
});
};
$scope.selectPhone = function (item) {
for (var i = 0; i < $scope.customerPhones.length; i++) {
if (item == $scope.customerPhones[i].Title
|| item == $scope.customerPhones[i].Value) {
$scope.selectedPhones.push({
Value: $scope.customerPhones[i].Value,
Title: $scope.customerPhones[i].Title
});
$scope.customerPhones = [];
flag = false;
}
}
if (flag) {
if (item.match("^09[0-3][0-9]{8}$")) {
$scope.selectedPhones.push({
Value: item,
Title: 'Unknown'
});
$scope.customerPhones = [];
}
else {
toaster.showError('This number is not valid : ' + item);
$scope.customerPhones = [];
}
}
$scope.typeaheadModel = "";
flag = true;
}

Related

Remove first duplicate from an array of objects in JavaScript

On input change I create an array of objects. When any value enter within the input field, it pushes objects into array but the problem is when a text field is updated, it does again push items into array. I need to update the array instead of pushing more items.
var tableData = [];
$('.aantalNumber').change(function(){
var aantalNumberVal = $(this).val()
var Productnummer = $(this).closest('tr').find('.product_number').text();
var Productnaam = $(this).closest('tr').find('.product_name').text();
var verpakking =$(this).closest('tr').find('.verpakking').text();
tableData.push({aantalNumber:aantalNumberVal,Productnummer:Productnummer,Productnaam:Productnaam,verpakking:verpakking });
console.log(tableData);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr>
<td><input type="number" class="aantalNumber" name="Aantal1"></td>
<td class="product_number">01454</td>
<td class="product_name">Vendor Handdoeken ZZ vouw</td>
<td class="verpakking">5000 velper verpakking</td>
</tr>
<tr>
<td><input type="number" class="aantalNumber" name="Aantal2"></td>
<td class="product_number">218031</td>
<td class="product_name">Vendor Handdoeken ZZ vouw</td>
<td class="verpakking">5000 velper verpakking</td>
</tr>
<!-- Repeated tr and so on -->
First check if value exist, if available then update else push into tableData
var tableData = [];
$('.aantalNumber').change(function() {
var aantalNumberVal = $(this).val()
var Productnummer = $(this).closest('tr').find('.product_number').text();
var Productnaam = $(this).closest('tr').find('.product_name').text();
var verpakking = $(this).closest('tr').find('.verpakking').text();
if (tableData.some(tableData => tableData.Productnummer === Productnummer)) {
updateTableData(Productnummer, aantalNumberVal);
} else {
tableData.push({
aantalNumber: aantalNumberVal,
Productnummer: Productnummer,
Productnaam: Productnaam,
verpakking: verpakking
});
}
console.log(tableData);
});
function updateTableData(value, aantalNumber) {
for (var i in tableData) {
if (tableData[i].Productnummer == value) {
tableData[i].aantalNumber = aantalNumber;
break; //Stop this loop, we found it!
}
}
}
Working Demo

Check and uncheck checkbox with Angular

In my form I have a table with checkbox in all of these columns. I have 3 <tr> and each <tr> has its ng-repeate calling the webservice to display the clones (Json data).
When I click on a checkbox I generate a js array which records id using this code :
checkoptions (array, model) {
angular.forEach(array, (value, key) => {
if (array[key].checked) {
model.push(array[key].id)
}
})
And in HTML :
<tr ng-repeat="developer in $ctrl.developers">
<td>{{developer.label}}</td>
<td>
<input type="checkbox" id="{{developer.id}}"
ng-change="$ctrl.checkoptions($ctrl.developers,$ctrl.employees.developers)"
ng-model="developer.checked">
<label for="{{developer.id}}"></label>
</td>
It works, but the problem is that when I uncheck a checkbox it is not removed from the js array
I included an else part to remove from the array:
http://jsfiddle.net/x9m1nqvp/1/
$scope.checkoptions = function (array, model) {
angular.forEach(array, (value, key) => {
if (array[key].checked) {
var index = model.indexOf(array[key].id);
if(index == -1)
model.push(array[key].id)
}
else {
var index = model.indexOf(array[key].id);
if(index >=0)
model.splice(index, 1);
}
})
While Everton's answer gets the job done, it is a bit redundant checking every item in the array, every time a single checkbox changes state. You don't really have to update for every single item in the array.
Here is an example, where only the checkbox that's actually toggled, is added or removed from the employees.developers array (Note: no need for the redundant angular.forEach):
$scope.checkoption = function (developer){
if (developer.checked) {
var index = $scope.employees.developers.indexOf(developer.id);
if(index == -1)
$scope.employees.developers.push(developer.id)
} else {
var index = $scope.employees.developers.indexOf(developer.id);
if(index >=0)
$scope.employees.developers.splice(index, 1);
}
}
and how this is used in the html:
<tr ng-repeat="developer in developers">
<td>{{developer.label}}</td>
<td>
<input type="checkbox" id="{{developer.id}}"
ng-change="checkoption(developer)"
ng-model="developer.checked">
<label for="{{developer.id}}"></label>
</td>
</tr>

Angularjs data-ng-click wont work a second time...how?

JSP page
<form>
<table class="countrys" data-name="tableCountry">
<tr bgcolor="lightgrey">
<th>Country ID</th>
<th>Country Name</th>
</tr>
<tr data-ng-repeat="c in allCountrys"
data-ng-click="selectedCountry(c, $index);"
data-ng-class="getSelectedClass(c);">
<td>{{c.countryId}}</td>
<td>{{c.countryName}}</td>
</tr>
</table>
</form>
controller
$scope.selectedCountry = function(country, index){
angular.forEach($scope.allCountrys,function(value, key) {
if (value.countryId == country.countryId) {
$scope.selectedCountry = country;
}
});
$scope.selectedRowCountry = index;
}
$scope.getSelectedClass = function(country) {
if ($scope.selectedCountry.countryId != undefined) {
if ($scope.selectedCountry.countryId == country.countryId) {
return "selected";
}
}
return "";
};
css
tr.selected {
background-color: #aaaaaa;
}
there is this table on my page, once i press 1 row, it selects it, it changes the color, and it goes in both functions...
but once i click on another row, it wont go to the selectedCountry function, but only into the sgetSelectedClass function
i dont know why, i just wont to be able to select one row, then another one and so on...so that always just one row is selected
can u help me?
you defined $scope.selectedCountry as a function, but at first time when you click on selectedCountry, you make $scope.selectedCountry as a object by calling $scope.selectedCountry = country; inside your ng-click function.
So remane your scope variable.
$scope.selectedCountry = function(country, index){
angular.forEach($scope.allCountrys,function(value, key) {
if (value.countryId == country.countryId) {
$scope.selectedCountry = country; // rename this scope variable
}
});

Place a checkbox in between of 2 rows jquery MVC

I have a MVC web app in which I show a table.
Some of my rows can have a similar id, on which I need to show only one checkbox for all those rows, and individual checkboxes for the rows which don't have a matching id. Something like below:
row1 and row2 have the same id, hence the checkbox is in between them (denoted by red checkbox).
row3, row4 have different ids, hence they need to have their individual checkboxes (denoted by green).
I know I need to play on the rowspan property, but I am unable to visualize how to get on it.
Below is the sample code:
[Route("Search")]
[HttpGet]
public async Task<IActionResult> Search()
{
//Some API call
return View("Search", model);
}
View Code:
<table id="tblsearch">
#if (Model.HasRecords)
{
var counter = 0;
<tbody>
#foreach (var item in Model.SearchResults)
{
<tr>
<td>
<input type="checkbox" id="Dummy_#counter" name="chkSearch" data-id="#item.Id"/>
<label for="Dummy_#counter"></label>
</td>
<td>#item.FullAddress</td>
<td>#item.Price</td>
<td>#item.OfficeName</td>
}
else
{
<tr><td>Data Not Found</td></tr>
}
</table>
I am trying to first hide all the checkboxes, then trying to match the id's in each row, and then if the ids of 2 rows are same, I am trying to increase the rowspan by 2.
js code:
function pageLoad()
{
var rowCount = $('#tblSearch >tbody >tr').length;
for(var i=0;i<rowCount-1;i++)
{
$('#Dummy_' + i).hide();
}
var searchArray= [];
for (var i = 0; i < rowCount - 1; i++) {
searchArray[i]= $('#tblSearch >tbody >tr')[i].attr('data-id');
}
}
Please guide how to proceed.
You should control the layout of the page in this instance from your View, please forgive my syntax as I primarily work in vbhtml these days.
Important things are to order your search results (in case they aren't already)
Remember and update the last processed Id.
<table id="tblsearch">
#if (Model.HasRecords)
{
var counter = 0;
var lastId = -1;
<tbody>
#foreach (var item in Model.SearchResults.OrderBy(x=>x.Id))
{
<tr>
#if(lastId!= item.Id){
<td rowspan="#(Model.SearchResults.Count(x=>x.Id == item.Id) > 0 ? Model.SearchResults.Count(x=>x.Id == item.Id) : 1 )">
<input type="checkbox" id="Dummy_#counter" name="chkSearch" data-id="#item.Id"/>
<label for="Dummy_#counter"></label>
</td>
}
<td>#item.FullAddress</td>
<td>#item.Price</td>
<td>#item.OfficeName</td>
#lastId = item.Id;
//I assume there was code snipped here...
}
else
{
<tr><td>Data Not Found</td></tr>
}
</table>
There is no need for any javascript. You can simply group your items by the Id property and conditionally render the checkbox column with a rowspan attribute if its the first item in the group.
<tbody>
#foreach (var group in Model.SearchResults.GroupBy(x => x.Id))
{
bool isFirstRow = true;
foreach (var item in group)
{
<tr>
#if (isFirstRow)
{
<td rowspan="#group.Count()">
#Html.CheckBox("chkSearch")
</td>
isFirstRow = false;
}
<td>#item.FullAddress</td>
<td>#item.Price</td>
<td>#item.OfficeName</td>
</tr>
}
}
</tbody>

Remove selected rows on a button click in angular js

I have a table with check box for each row .
I need to remove the rows for the selected check boxes in the table on a button click. (this button is outside ng-repeat).
The index of the selected rows are populated to an array using ng-change function but i'm unable to remove the selected rows on a single button click
Here is the Fiddle
HTML
<div ng-app="approvalApp">
<div ng-controller="SimpleApprovalController" >
<table style="width:90%" border="5" >
<tr>
<th><input type="checkbox" ng-model="CheckAllData" ng- change="selectAll()" /></th>
<th>Date</th>
<th>AssociateID</th>
<th>Check-In</th>
<th>Checkout</th>
</tr>
<tr data-ng-repeat="approval in approvalitems">
<td><input type="checkbox" value="{{approval.ReqId}}" data-ng-model="approval.selected" data-ng-change="SelectDeselect($index)"/></td>
<td>{{approval.Date}}</td>
<td>{{approval.AssociateID}}</td>
<td>{{approval.CheckIn}}</td>
<td>{{approval.Checkout}}</td>
</tr>
</table>
<input type="button" value="Approve" data-ng-model="ApproveIndex" data-ng-click="ApproveRequest()" />
Script
$scope.SelectDeselect=function(index)
{
$scope.getIndexvalues = [];
angular.forEach($scope.approvalitems, function (approval,index) {
if (!!approval.selected) {
$scope.getIndexvalues.push(index);
$scope.CheckAllData = false;
}
});
console.log($scope.getIndexvalues);
};
$scope.ApproveRequest = function () {
$scope.selectedIdsArray = [{}];
angular.forEach($scope.approvalitems, function (item) {
if (!!item.selected) {
$scope.selectedIdsArray.push({ Reqid: item.ReqId, Status: "Approved" });
$scope.CheckAllData = false;
}
});
};
};
So how to use getIndexvalues in approverequest function , or is there any better way to remove it using other angular directive.
I'm a newbie to angular js .
Fiddle: http://jsfiddle.net/jpk547zp/1/
$scope.ApproveRequest = function () {
$scope.selectedIdsArray = [{}];
$scope.approvalitemsNew = [];
angular.forEach($scope.approvalitems, function (item) {
if (!!item.selected) {
$scope.selectedIdsArray.push({ Reqid: item.Date, Status: "Approved" });
$scope.CheckAllData = false;
item.hideThis = true;
console.log($scope.selectedIdsArray);
} else {
$scope.approvalitemsNew.push(item);
}
});
$scope.approvalitems = $scope.approvalitemsNew;
$scope.getIndexvalues = [];
};
Hope this helps.
you can simply do
$scope.ApproveRequest = function () {
$scope.approvalitems = $scope.approvalitems.filter(function(i){
return !i.selected;
});
};

Categories