I'm trying to compare an old value in a <td> with the new value entered by the end user. I'm using ng-blur to detect when there is focus out of the field rather than calling the function. The problem is I can't get this very simple logic to work and I can't figure out why.
This is my table:
<main ng-controller="mainCtrl">
<table class="table table-bordered table-hover" ng-controller="tableCtrl">
<p ng-model="old">{{old}}</p>
<thead>
<th>user name</th>
<th>script name</th>
<th>cron format<span class="glyphicon glyphicon-question-sign" data-toggle="tooltip" data-original-title="Min|Hour|Day Of Month|Month|Day Of Week"></span></th>
</thead>
<tbody ng-repeat="(user_id,script_id) in data">
<tr ng-repeat="(script_id, cron_format) in script_id">
<td class="userName">{{user(user_id)}}</td>
<td class="scriptName">{{script(script_id)}}</td>
<td class="cronFormat"><input type="text" ng-model="cron_format" ng-blur="saveCron(user_id,script_id,cron_format)"/></td>
</tr>
</tbody>
</table>
and this is the comparison :
$scope.old = $scope.cron_format = "";
$scope.saveCron(user_id, script_id, cron_format) {
if ($scope.old == $scope.cron_format) {
return; //value was unchanged
}
$.post("updateCronChange.php", "user_id=" + userId + "&script_id=" + scriptId + "&cron_format=" + cronFormat, function (data) {
alert('cron format changed to:' + cronFormat);
});
$scope.old = $scope.cron_format;
});
Currently, the function executes each time the field is out of focus. What am I missing here?
You can use ng-init for each iteration of the ng-repeat to store the old value, and then use it in the function to compare:
<tr ng-repeat="row in data" ng-init="oldCron = row.cron_format">
And in the function call:
ng-click="saveCron(row.user_id,row.script_id,row.cron_format,oldCron)"
And finally inside the function itself:
$scope.saveCron = function(userId,scriptId,cronFormat,oldCron){
console.log("old cron: " + oldCron);
console.log("new cron: " + cronFormat);
if (oldCron != cronFormat) {
//assign
}
}
Fiddle.
If I understand you correctly, you are trying to save an old value and print it out. You can try changing it to this -
if ($scope.old != $scope.cron_format) {
$.post("updateCronChange.php", "user_id=" + userId + "&script_id=" + scriptId + "&cron_format=" + cronFormat, function(data) {
alert('cron format changed to:' + cronFormat);
});
$scope.old = $scope.cron_format;
}
Here is a working example if you like -
var test = angular.module('test', []);
test.controller('TestCtrl', ['$scope',
function($scope) {
$scope.myModel = '';
$scope.old = '';
$scope.getNewValue = 'false'
$scope.saveModel = function(value) {
if ($scope.old != value) {
$scope.getNewValue = 'true';
$scope.old = value;
$scope.myModel = '';
// Here you can do your post request
} else {
$scope.getNewValue = 'false';
}
};
}
]);
.green {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app='test'>
<div ng-controller="TestCtrl">Enter Some Text
<input type="text" ng-model="myModel" ng-blur="saveModel(myModel)">
<p>Old Value - {{old}}</p>
<p>Current Value - {{myModel}}</p>
<p class="green">Get New Value - {{getNewValue}}</p>
</div>
</div>
Related
I have to debug a snippet written in AngularJS.
//===== service ==
app.service('allUserService', function($http) {
var config = {
headers: {
'X-XSRF-TOKEN': gettingValueFromSomewhere()
}
};
this.getAll = function() {
var restUrl = CONTEXT_PATH + '/rest/path/mypath';
return $http.get(restUrl, config).then(function(response) {
console.log(response.data.body); // console prints an Array which is correct
return response.data.body;
});
}
});
//========= controller ====
app.controller('UserCtrl', function($scope,allUserService) {
var valueArray = [];
valueArray = allUserService.getAll();
console.log(valueArray);
$scope.faqBook = valueArray;
});
allUserService :I am getting correct result from Rest webservie and console log shows desired return (an Array)
faqUserCtrl : I am not getting desired value in console log. Pls help me in finding the issue. It should have an array. I am expecting an Array in $scope.faqBook.
Important to Note, when I return a hardcoded array from allUserService, the code works fine
<div class="container" ng-app="UserModule" ng-controller="UserCtrl">
<p>Search : <input type="text" ng-model="search"/></p>
<table id="mainTable" class="table table-striped table-hover">
<tr ng-repeat="x in faqBook | filter:search">
<td><ul class="list-group"><li class="list-group-item">Question: {{ x.question }}</li><li class="list-group-item"> Answer: {{ x.answer }}</li></ul></td>
</tr>
</table>
</div>
I'm starting to fiddle with jquery and I'm going kind of crazy... I am making a little script to fetch football players from a fantasy football website. I have the following html and JS to work with:
<table class="table table-striped">
<thead>
<tr>
<th>Jugador</th>
<th>Equipo</th>
<th>Puntos</th>
</tr>
</thead>
<tbody>
<tr class="jugador">
<td>Sergio-Ramos</td>
<td>Real Madrid</td>
<td></td>
</tr>
<tr class="jugador">
<td>Messi</td>
<td>F.C. Barcelona</td>
<td></td>
</tr>
<tr class="jugador">
<td>Morales</td>
<td>Levante</td>
<td></td>
</tr>
<tr class="jugador">
<td>Bale</td>
<td>Real Madrid</td>
<td></td>
</tr>
</tbody>
</table>
And the following JS:
<script>
var puntos_jugador = [];
$(".jugador").each(function(index) {
var nombre = $(this).find("td").eq(0).text();
puntos_jugador = puntosJugador(nombre);
console.log(nombre);
console.log(puntos_jugador);
$(this).find("td").eq(2).text("Hola");
});
function puntosJugador(nombre) {
var puntos = [];
$.get('https://www.comuniazo.com/comunio/jugadores/' + nombre, function(response) {
$(response).find('.tr-points, .tr-status').each(function(fila) {
//var jornada = $(this).find("td").eq(0).text();
var puntos_jornada = $(this).find(".bar").text();
puntos.push(puntos_jornada);
//console.log('Jornada ' + jornada + ' ' + puntos);
});
});
return puntos;
}
</script>
The thing is the console.log(puntos_jugador) does return an array filled with the information:
However I cannot access puntos_jugador[0] or try puntos_jugador.toString() .
Could anyone tell me what am I doing wrong (maybe everything) or give me some orientation on how to fix this?
Thanks on beforehand and sorry for my low JS level, I'm working on it.
The problem in your code is that you are doing an asynchronous call with $.get and then you return the result directly without waiting for the response, which will always be the empty array define above.
You should wait for the response and then call a callback (or use promises)
Something like this:
var puntos_jugador = [];
$(".jugador").each(function(index) {
var nombre = $(this).find("td").eq(0).text();
puntosJugador(nombre, function(result) {
console.log('done');
puntos_jugador = result;
console.log(nombre);
console.log(puntos_jugador);
});
$(this).find("td").eq(2).text("Hola");
});
// <---- HERE pass a callback and then call it when you have all results.
function puntosJugador(nombre, cb) {
var puntos = [];
$.get('https://www.comuniazo.com/comunio/jugadores/' + nombre, function(response) {
console.log('response ',response)
$(response).find('.tr-points, .tr-status').each(function(fila) {
//var jornada = $(this).find("td").eq(0).text();
var puntos_jornada = $(this).find(".bar").text();
puntos.push(puntos_jornada);
//console.log('Jornada ' + jornada + ' ' + puntos);
console.log('here', puntos);
});
cb(puntos);
});
}
Refactor your method to this:
function puntosJugador(nombre) {
var puntos = [];
$.get('https://www.comuniazo.com/comunio/jugadores/' + nombre, function(response) {
$(response).find('.tr-points, .tr-status').each(function(fila) {
//var jornada = $(this).find("td").eq(0).text();
var puntos_jornada = $(this).find(".bar").text();
puntos.push(puntos_jornada);
//console.log('Jornada ' + jornada + ' ' + puntos);
});
return puntos;
});
}
Example: plunker
From the above example, I have created a simple form with filter option using angular.
As far as the filter concern, it's a default filter which is provided by angular. Currently, when I search the text "br", it shows the id 1 and 10.
I would like to add the regEx in the search input.The search can be done using regEx.
what I need is, The search item can be
"br" => It show two data,
"b*" => Show all the data starts with b.
"*" => All the data
"*br" => All the data ends with br.
The above search should show the relevant data as per the search input.
scripts.js
var app = angular.module('app',[]);
app.controller('regEx', function($scope, $http) {
$scope.init = function() {
$http.get('https://jsonplaceholder.typicode.com/users/').success(function(data) {
$scope.data = data;
console.log(data);
}).error(function(e) {
console.log(e);
});
}
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="regEx" class="container">
<h1>RegEx in Angular search</h1>
<input type="text" class="form-control" ng-model="search" autofocus>
<br />
<table ng-init="init()" class="table table-bordered animated fadeIn">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Phone Number</th>
<th>username</th>
<th>website</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="d in data | filter:search">
<td>{{d.id}}</td>
<td>{{d.name}}</td>
<td>{{d.phone}}</td>
<td>{{d.username}}</td>
<td>{{d.website}}</td>
</tr>
<tr ng-if="d.length < 1">
<td colspan="5" class="text-center">No Router Found</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
In this case I would probably create a custom filter.
The tricky part here is that your object model is not flat, so we have to do a deep traversal to check the fields. The caveat to this approach is that you could potentially be checking against fields that are not visible (although i believe this is how the default angular filter behaves).
If that is an issue, you could adjust the filter to pass in a list of fields to check against and use those to filter out unwanted fields.
Here is the filter :
app.filter('wildcard', function() {
return function(list, value) {
if (!value) {
return list;
}
var escaped = value.replace(/([.+?^=!:${}()|\[\]\/\\])/g, "\\$1");
var formatted = escaped.replace('*', '.*')
if (formatted.indexOf('*') === -1) {
formatted = '.*' + formatted + '.*'
}
var output = []
angular.forEach(list, function(item) {
var regex = new RegExp('^' + formatted + '$', 'im');
if (traverse(item, regex)) {
output.push(item);
}
});
return output
}
function traverse(item, regex) {
for (var prop in item) {
//angular property like hash
if(prop[0] === '$$'){
return;
}
var value = item[prop];
if (typeof value === 'object') {
traverse(value, regex);
}
if(regex.test(value)){
return true;
}
}
}
})
And then in you html :
<tr ng-repeat="d in data | wildcard:search">
Here is the plunker
Thanks For viewing this post.i am facing a jquery issue .After a successful AJAX call, I want to update an element on page. However, it is not being updated.
what am i doing i am opening a text box on click of span then add text and and on focus out event i am making Ajax call but cant update new text to same span when that i clicked before please help me
here is my js code
$(document).on('click', '.td-edit', (function (e0) {
var thisObj = $(this);
var olddata = thisObj.html();
var newDom = '<input type="text" value="' + olddata + '" class="new-value" style="border:#bbb 1px solid;padding-left:5px;width:75%;"/ >';
thisObj.parent('td').html(newDom);
}));
$(document).on('focusout', '.new-value', (function (e1) {
var thisObj = $(this);
var type = thisObj.parent('td').attr('class');
var newData = thisObj.val();
var santanceId = thisObj.parent('td').parent('tr').attr('id');
santanceId = parseInt(santanceId.replace('tr', ''));
thisObj.parent('td').html('\'<img src="uploads/loading.gif">\'');
if (type === 'sentnc') {
$.ajax({
type: "POST",
url: "operations.php",
data: {
santanceId: santanceId,
sentnc: newData
},
success: function () {
var newDom = '<span class="td-edit">' + newData + '</span>';
thisObj.parent('td').html(newDom);
}
});
}
}));
HTML:
<div class="chat-space nano nscroller">
<div id="table-row">
<table id="rep-data">
<tbody>
<tr>
<th align="left">Sentences</th>
<th align="left" colspan="3">Reps</th>
</tr>
<tr id="tr1" rowspan="2">
<td class="sentnc"><span class="td-edit">Rana is working</span></td>
<td colspan="3" class="senrep"><span class="td-edit">p1.ref = I, p1.name = julie</span><br>
<br>
<span style="color:#000;">Guess Rep1: </span><span id="1gr1">p1.ref = I, p1.has = name1, p1.name.made_from = rana</span><br>
<span style="color:#000;">Guess Rep2: </span><span id="2gr1">p1.ref = I, p1.name = rana</span><br>
<span><a style="color:#3399FF !important;" alt="1" rel="1 " class="updateGuess" id="upd1" href="javascript:void(0);">Update Guess Rep</a></span><br>
<br></td>
</tr>
</tbody>
</table>
</div>
Your success handler should be:
success: function (data) {
var newDom = '<span class="td-edit">' + data + '</span>';
thisObj.parent('td').html(newDom);
}
Here, the data is the data returned by your server, after the ajax Call
Im trying to find the results in a table column if its set in my function below, most of this was setup by someone else, ive just added some extras into it, my final one is searching 1 column only by name set in the thead but alas in its current edition nothing happens at all :|
thanks for any help
USAGE
<a href='javascript:searchTable("Bob", "table",1,"Name");'>Test</a>
TABLE
<table id="table" class="table">
<thead>
<tr>
<th id="blank"> </th>
<th id="Name">Name</th>
<th id="Dept">Department</th>
<th id="JobTitle">Job Title</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td>Bob</td>
<td>IT</td>
<td>IT Support</td>
</tr>
<tr>
<td> </td>
<td>Fred</td>
<td>Finance</td>
<td>Finance Man</td>
</tr>
</tbody>
</table
FUNCTION
function searchTable(inputVal, tablename,starts, column) {
var table = $(tablename);
table.find('tr:not(.header)').each(function (index, row) {
if (column != '') {
//Columnname
var Cells = $(row).find('td').eq(column);
} else {
//AllCells
var Cells = $(row).find('td');
}
if (Cells.length > 0) {
var found = false;
Cells.each(function (index, td) {
if (starts == 1) {
var regExp = new RegExp((starts ? '^' : '') + inputVal, 'i');
} else {
var regExp = new RegExp(inputVal, 'i');
}
if (regExp.test($(td).text())) {
found = true;
return false;
}
});
if (found == true) $(row).show().removeClass('exclude'); else
$(row).hide().addClass('exclude');
}
});
}
As you're passing the column as a string, you need get the corresponding elements index:
var Cells = $(row).find('td:eq(' + $('#' + column).index() + ')');
The above presumes that you're matching based on the id, if you're matching based on the text within the <th> you could use the :contains selector:
$(row).find('td:eq(' + $(table.prop('id') + ' th:contains(' + column + ')').index() + ')');
If you can control and modify the function calls, the best thing to do would be to just pass the elements index directly to the function:
javascript:searchTable("Bob", "table", 1, 1); <-- Would be the "Name" column
That way, you won't have to do any of the above.
By the way, your table selector is incorrect based on your comment, not sure if that's just a typo on your part?
var table = $(tablename);
Should be:
var table = $('#' + tablename);
I am not sure what you are trying to control but you can use this to loop through rows and get the values of cells.
$("#table>tbody>tr").each(function(){
var name= $(this).children("td").eq(1).html();//Name
var department= $(this).children("td").eq(2).html();//Department
var jobTitle= $(this).children("td").eq(2).html();//Job Title
alert(name);
});
http://jsbin.com/uvefud/1/edit
Edit:
You can try this searchTable function.
function searchTable(name,tableName,row,column){
var $Tds= $("#"+tableName+">tbody>tr").eq(row-1).children("td");
if(column=="Name"){
$Tds.eq(1).html(name);
}
else if(column=="Dept"){
$Tds.eq(2).html(name);
}
else if(column=="JobTitle"){
$Tds.eq(3).html(name);
}
}
http://jsfiddle.net/W9zpq/2/
Usage: This will update the name column of 2nd row of tbody to 'Bob'
searchTable("Bob", "table",2,"Name")