Pure JavaScript - Update just one cell in entire Html table - javascript

I have a rest call in my application (spring based) to update the User's Active (boolean) status using Fetch API like below:
async function activateUser(obj) {
var fullURL = obj.getAttribute("href");
let response = await fetch(fullURL, {
method: 'POST'
});
let result = await response.json();
if (response.ok) {
alert(result.username + " Activated Successfully.. !!");
obj.parentElement.parentElement.cells[6].innerHTML = "true";
//getAllUsersApi(endpoint);
} else {
alert(response.status + "Error Occurred.. !!");
}
}
All works well.
Now, I am trying to update just that cell of my html table to true whose Initial value was false. I am updating the html table's cell by hard-coding the column number using (as you can see above too) - obj.parentElement.parentElement.cells[6].innerHTML = "true";. I was wondering if there is some way we can find the false in that row for that particular user and update that cell only. Prior to this I was reloading the entire table (the commented line in the JS code above), which nobody will prefer. I tried to find the solution here and here. But couldn't find the stating point for my situation.
From my rest call I am returning the User object so I was just wondering if I could search the table (on client side) just for that particular user and update that just one corresponding cell. In the table Id, Username and email are unique if that helps to find and replace false to true..
Summarized question: How can I update just one cell of my html table by utilizing the response from my REST call?

Since each ID is unique, you can add that to each row as an id="user id goes here" attribute. Then each cell can be given a class to specify it's purpose.
For example:
<table>
<tr id="user_{{ user ID }}">
<td class="user-name">{{ user name }}</td>
<td class="user-email">{{ user email address }}</td>
<td class="is-user-active">{{ user active status }}</td>
</tr>
</table>
Since the result is returning the username, I am guessing it can also return the ID, in which case your code would look like this:
if (response.ok) {
let isUserActive = document.querySelector(`#user_${result.id} .is-user-active`);
isUserActive.innerHTML = "true"
}

There is not really much magic to do. Instead of targetting cell 6, you would check find out the column number by finding the column header that has the title "Enabled". Replace this:
obj.parentElement.parentElement.cells[6].innerHTML = "true";
With:
let row = obj.closest("tr");
let titles = row.closest("table").querySelectorAll("th");
for (let cellNo = 0; cellNo < titles.length; cellNo++) {
if (titles[cellNo].textContent.includes("Enabled")) {
row.cells[cellNo].textContent = "true";
}
}
This is based on the information you have given in the question (not behind links) and in comments/chat.

Related

using queryselector to get textContent from td tags without class names

I am trying to create a datascraper using node.
Here is a sample html code for an item that I am trying to scrape:
<tr class="cool">
<td>Todd</td>
<td>Bob eats shoes <br/>[Stack]
</tr>
Here is some code that I am using to extract:
cars.forEach(carCard=> {
const carCool = {
number: carCard.querySelector('?').textContent,
date: carCard.querySelector('?').textContent,
};
});
I was wondering if there was anyway I could get the text of 'Todd' and [Stack] using this query selector. I do not know what I would need to put in place of the question marks. If not is there a different method I can use to accomplish this?
Please help.
You could do the following:
// To get all the td fields
const tds = document.querySelectorAll('td');
// to get the content of the td fields
tds.forEach(td => {
console.log(td.textContent);
})

Get X and Y position after searching an element in a HTML table

I'm having troubles thinking a solution to this problem.
I have this table and a JSON like this one:
{:id=>"e-123",
:subject_initials=>"IN",
:grade=>"12"}
I need to search on the table the id of the person (which in this case is "e-123") and search on the first row the initials of the subject and put the grade on the X and Y position.
The result of the example above should be something like this
Any idea how to do this?
Need to search through the heading inputs to get a column index and search through the user id inputs to get a row index then use eq() method to isolate the one you need to update
var $subjectInput = $('tr').first().find('input').filter(function() {
return this.value === data.subject_initials
});
var $idInput = $('tr').find('td:eq(1) input').filter(function() {
return this.value.toLowerCase() === data.id
});
var colIdx = $subjectInput.parent('td').index();
var rowIdx = $idInput.closest('tr').index();
$('tr').eq(rowIdx).find('td').eq(colIdx).find('input').val(data.grade)
Adding some additional classes on these 2 types of inputs would help make the selectors for finding them easier
If the rows are generated dynamically adding an ID to the row and course name class to the data entry inputs you could simplify the whole thing immensely
<tr id="e-123">
.....
<input class="form-control course_IN">
JS
$('#' + data.id).find('input.course_' + data.subject_initials).val(data.grade)
DEMO

Delete multiple rows of Table in AngularJS

I have angularjs table added with check boxes to each row and a common remove button outside the table, so that multiple rows can be selected and deleted at a time. When rows are selected and remove is clicked, that particular rows will be deleted. This is fine and till here its working in the below plunker too. Now what I need is when a particular row is selected, its rowid has to be sent as a parameter to another URL. when this URL(URL formed by selected rowIds) with ids is called, automatically the rows will be deleted from first URL data, and now the table has to be updated from first URL. null will be returned from second url with ids as parameters and at the same time that rows will be deleted from JSON data of first URL.
Here is a demo:http://plnkr.co/edit/UzKdIGSubEfHoF7FHoCd?p=preview
Below is the code for the table:
<div ng-controller="SampleController">
<form class="form-horizontal">
<a class="btn btn-info" ng-click="subt_click()">Submit</a>
</form>
<div class="table-responsive" ng-show="tableData.length > 0">
<table class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr>
<th><input name="all" type="checkbox" ng-click="selectAllFriends()" /></th>
<th>ID</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in tableData">
<td><input name="all" type="checkbox" ng-model="x.checked" /></td>
<td>{{x.id}}</td>
<td>{{x.body}}</td>
</tr>
</tbody>
</table>
</div>
<input ng-hide="!tableData.length" type="button" class="btn btn-danger pull-left" ng-click="remove()" value="Remove">
app.js:
$scope.remove = function () {
var newDataList = [];
$scope.selectedAll = false;
angular.forEach($scope.tableData, function (checked) {
if (!checked.checked) {
newDataList.push(checked);
}
});
$scope.tableData = newDataList;
};
$scope.isAll = false;
$scope.selectAllFriends = function () {
if ($scope.isAll === false) {
angular.forEach($scope.tableData, function (x) {
x.checked = true;
});
$scope.isAll = true;
} else {
angular.forEach($scope.tableData, function (x) {
x.checked = false;
});
$scope.isAll = false;
}
};
In brief what i need is:
I get table data from first url. (pls check the plunk and the url i used is jsonplaceholder.typicode.com/posts)
When a checkbox is selected from a row in table and remove button is clicked, that rowid has to be sent to second URL(need to call another url, need not post) and this url when called along with selected rowids deletes that particular row details from first url and returns a null.
Finally, the first url data(which will be modified by just calling second url with rowids) has to be updated in the table present already.
How can I change this code to send rowid to second url and call that url to update the table. Thanks in advance!!
$scope.xListNo is never affected in your statements.
May be you wanted to use xListNo which is your function parameter (without $scope) ?
So does index in your second statement, which should be idx.
Double check your variables spelling and it should work !
#Deborah : Went through your Plunker and could not find any code for Posting ids to an URL. Assuming that you are doing that somewhere, Still there can be two cases, whether to remove data as soon as call is made or removing it after response from API call. The better way would be removing after the success of API.
So, what you should do probably is to keep your entire table data in a variable (as you have already done, after your GET call).
//Table Data
$http.get("http://jsonplaceholder.typicode.com/posts")
.success( function(response) {
$scope.tableData = response;
});
Now In remove function you can create an array of rows which are checked and send them to URL..Like:
$scope.remove = function(){
$scope.deletedIds = [];
$scope.tableData.forEach(function(x){
if(x.checked){
$scope.deletedIds.push(x)
}
}
makePostCallFOrDeletion()
}
//use this if POST call
function makePostCallFOrDeletion(){
$http.post("deleteurl", angular.toJson($scope.deleteIds)).then(function(response){
$scope.tableData = response //assuming you get the updated JSON back.
//if you don't get JSON back, delete yourself from JSON, like
$scope.tableData.forEach(function(x,i){
if ($scope.deleteIds.indexOf(x.id) !== -1)
$scope.tableData.splice(i, 1);
}
}
As per my understanding of your question, this should get you going..
EDIT: OP wanted GET call for deleting (which as per my opinion is not a good idea, since number of IDs can be too large)
//use this if GET call
function makePostCallFOrDeletion(){
$http.get("deleteurl" + append IDs here,).then(function(response){
//$scope.tableData = response //assuming you get the updated JSON back.
//if you don't get JSON back, delete yourself from JSON, like
$scope.tableData.forEach(function(x,i){
if ($scope.deleteIds.indexOf(x.id) !== -1)
$scope.tableData.splice(i, 1);
}
}

Angular js, on select element i want to POST data to save it in the database then i want to update it with PUT without page reload

I have a table which had a select field in it which I'd like to save into database if it dosnt exist yet through POST data. If it does exist then I'd like to update the already existing row in the database.
This can be found in the tbody in which i have my tablerow with an ng-repeat to display all data from a json.
<td>
<select id="statusSelect{{anime.id}}" ng-model="statusId" ng-options="animeStatus.id as animeStatus.status for animeStatus in animeStatuses"
ng-change='addUserAnime( "<?php echo Yii::app()->user->id; ?>", anime.id, statusId )'>
</select>
</td>
Next this is my code for what im trying to do in the angular controller:
$scope.addUserAnime = function( userId, animeId, statusId, userAnime )
{
if ( userId == '' ) {
//alert user that he/she needs to log in first
} else {
//loop through my json where i saved from which user which anime is saved with which status
for (var i = 0; i < $scope.usersAnime.length; i++) {
//if there is an already existing entry then i want to update it if not then i want to introduce it into DB with POST
if ($scope.usersAnime[i].anime_id == animeId && $scope.usersAnime[i].user_id == userId) {
$scope.userAnime = $.extend({}, $scope.usersAnime[i]);
$scope.userAnime.status_id = statusId;
$scope.userAnime.date_modified = today;
saveUserAnime();
return;
}
}
$scope.userAnime = {
id: 0,
user_id: userId,
anime_id: animeId,
status_id: statusId,
rating: '',
date_modified: today
};
saveUserAnime();
}
};
Problem is that if i POST a new entry it gets saved in the database, but if i dont reload the page and i change the select again giving it a new option it gets POSTed again instead of using PUT for update.In the end i end up with two entries instead of one. I want to introduce it to database on first select and i want to update it if its changed after. Is that possible. I tryed doing it with $dirty using the table as form but thats a nono.
In the saveUserAnime() function its correctly deffined to use POST if its new entry and use PUT if its an existing one. I have another form for which it works. The problem must be in this current function.
Just put that code where you get the object with the animeStatus and put that in a function and call it directly after that. Now you can call that function when your POST is done, so the new data will be loaded.
Otherwise you could also check through SQL, if that value exists in your table, so you don't need your check in angularjs, that would be easier than this one.

How to automatically call a JavaScript that modify a value before show this value?

I am very new in JavaScript and I have the following problem to solve.
I have a table that contains this td cell:
<td class= "dateToConvert" width = "8.33%">
<%=salDettaglio.getDataCreazione() != null ? salDettaglio.getDataCreazione() : "" %>
</td>
This retrieve a String from an object and show it into the cell
The problem is the retrieved string represent a date having the following horrible form: 20131204 and I have to convert it into the following form: 2013-12-04.
So I am thinking to create a JavaScript that do this work when the value is retrieved.
My problem is: how can I do to automatically call the JavaScript before to show the value into the td cell? (So I show the modified output in the desidered form)
EDIT 1:
So I have create thid JavaScript function into my page:
function convertData() {
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.innerText = td.innerText.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
}
But it don't work because it never enter in this function (I see it using FireBug JavaScript debugger). Why? What am I missing? Maybe have I to call it explicitly in some way in my td cell?
Of course it is better to fix backend method to make it return proper format. But since you have no control over it try to use something like this:
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.textContent = td.textContent.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
Check the demo below.
var tds = document.querySelectorAll('.dateToConvert');
[].slice.call(tds).forEach(function(td) {
td.textContent = td.textContent.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
});
<table>
<tr>
<td class= "dateToConvert" width = "8.33%">
20131204
</td>
<td class= "dateToConvert" width = "8.33%">
20140408
</td>
</tr>
</table>

Categories

Resources