make some column not editable in editable data-table - javascript

I have a web app, frontend using HTML5, backend using Django.
I have an editable table in HTML5.
But the use need to make some columns not editable.
I could only set the editable flag on the table basis, not sure how to set it on the column basis, as my table do not have a table body(call restful API to render the table body).
How could I make some column of the table not editable?
<table contenteditable='true' class="table table-bordered table-sm" width="100%" cellspacing="0" style="font-size: 1.0rem;"
id="bk-table"
data-toggle="table"
data-toolbar="#toolbar"
data-cookie="true"
data-cookie-id-table="materialId"
data-show-columns="true"
data-show-refresh="true"
data-show-fullscreen="true"
data-show-export="true"
data-height="650"
data-click-to-select="true"
data-id-field="id"
data-show-footer="true"
data-url="/api/materials/"
data-query-params="queryParams"
data-remember-order="true"
data-pagination="true"
data-side-pagination="client"
{# data-side-pagination="server" #}
data-total-field="count"
data-data-field="results">
<colgroup>
<col span="3" style="background-color:white">
<col span="5" style="background-color:#e8ecfd">
<col span="1" style="background-color:white">
<col span="7" style="background-color:#e8ecfd">
</colgroup>
<thead class="thead-dark" >
<tr >
<!--th data-sortable="true" >ID</th-->
<th data-field="state" data-checkbox="true"></th>
<th data-field="courseCode" data-formatter="renderCourse">Course Code</th>
<th data-field="type">Course Type</th>
<th class ='title' data-field="book.title">Course Material Title</th>
<th class ='author' name="Author" data-field="book.author">Author/Editor</th>
<th class ='pub_date' name="pub_date" data-field="book.pub_date">Publication Year</th>
<th class ='edition' data-field="book.edition">Edition + Special Edition</th>
<th class ='publisher' data-field="book.publisher">Publisher</th>
<th class ='isbn' data-field="book.isbn">iSBN or e-iSBN/VBID</th>
<th class ='Format_issued' data-field="book.Format_issued">Material Format</th>
<th class ='Purchase_Price' data-field="book.e_price_cur">eText SUSS Price Currency</th>
<th class ='Total_StockAndWrap' data-field="book.e_price">eText SUSS Price</th>
<th class ='Distribution_platform' data-field="book.Distribution_platform">Distribution Mode</th>
<th class ='Discard_Status' data-field="status">Book Status</th>
<th class ='discard_reason' data-field="discard_reason">Discard Reason</th>
<th data-field="remark">Remarks</th>
</tr>
</thead>
</table>
restapi:
class MaterialSerializer(serializers.ModelSerializer):
book = BookSerializer(many=False)
course = CourseSerializer(many=False)
courseId = serializers.ReadOnlyField(source='course.courseInfo.id')
year = serializers.ReadOnlyField(source='course.semester.year')
month = serializers.ReadOnlyField(source='course.semester.month')
term = serializers.ReadOnlyField(source='course.semester.term')
quota = serializers.ReadOnlyField(source='course.quota')
course_title = serializers.ReadOnlyField(source='course.courseInfo.title')
type = serializers.ReadOnlyField(source='course.courseInfo.type')
available = serializers.ReadOnlyField(source='course.courseInfo.available')
postgraduate = serializers.ReadOnlyField(source='course.courseInfo.postgraduate')
Presentation_Pattern = serializers.ReadOnlyField(source='course.courseInfo.pattern')
discipline = DisciplineSerializer(source='course.courseInfo.discipline')
retail_price_display = serializers.ReadOnlyField(source='book.retail_price_display')
cover = serializers.ReadOnlyField(source='book.cover')
courseCode = serializers.SerializerMethodField()
def get_courseCode(self, obj):
return f'{obj.course.courseInfo.discipline_code}{obj.course.courseInfo.code}'
class Meta:
model = Material
fields = ['id', 'book', 'course', 'course_title', 'type','school', 'available', 'postgraduate', 'courseCode', 'courseId', 'year', 'month', 'term', 'quota',
'modified', 'discipline', 'remark', 'status', 'is_discard', 'discard_reason', 'retail_price_display', 'Presentation_Pattern','cover']

You can use the same contenteditable attribute and set it to false. Although setting it on the <th> elements will not also set it on all the <td> elements in that column in tbody. You have to set contenteditable to false on every <td> in that column like:
<td contenteditable="false">Content</td>
Can you modify the restful API's render function to set the attribute?

We can achieve this by adding flags in Django models.
Add is_editable flag with default value as True. Based on this flag you can hide the edit button and also restrict users by editing this data through URL ID.
In MaterialSerializer model add is_editable = models.BooleanField(default=True)
Based on this flag you can hide/un-hide the edit functionality for the users.

Related

How can I edit the particular data from API in angular

Actually, I have listed some data from API using ngFor and it's working fine. But I have a problem with editing the data. When I click the edit button it's editing the overall data but I want to edit the particular row only. Here is my code. Please refer
HTML
<table class="table table-striped" style="width: 98%; margin: 10px auto;">
<thead>
<tr>
<th><strong>Name</strong></th>
<th><strong>Consent Type</strong></th>
<th><strong>Updated At</strong></th>
<th><strong>Status</strong></th>
<th><strong>Content</strong></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let consent of SystemConsent">
<th *ngIf="!editorStatus">{{consent.fileName}}</th>
<th *ngIf="editorStatus"><input type="text" value="{{consent.fileName}}" class="form-control"></th>
<th *ngIf="!editorStatus">{{consent.type}}</th>
<th *ngIf="editorStatus"><input type="text" value="{{consent.type}}" class="form-control"></th>
<th>{{consent.updatedAt}}</th>
<th *ngIf="!editorStatus">{{consent.status}}</th>
<th *ngIf="editorStatus"><input type="text" value="{{consent.status}}" class="form-control"></th>
<th *ngIf="!editorStatus" [innerHTML]="consent.content"></th>
<th *ngIf="editorStatus">
<ckeditor name="htmlEditor" [config]="config" [editor]="Editor" [(ngModel)]="consent.content" skin="moono-lisa" language="en">
</ckeditor>
</th>
<th><button class="btn trans-btn list-head-btn ng-star-inserted btn-gradient" (click)="changeEditor()">Edit</button></th>
<th><button [disabled]="!editorStatus" class="btn trans-btn list-head-btn ng-star-inserted btn-gradient" (click)="getEditorValue()">Save</button></th>
</tr>
</tbody>
</table>
Typescript
getAdminSystemPrefrences() {
this.adminDashboardService.getSystemPreferences().then(resp => {
this.SystemConsent = resp['data'].consent;
});
}
changeEditor() {
this.editorStatus = true;
}
getEditorValue() {
this.editorStatus = false;
}
Screenshot
Please Help me to fix this issue
You should define smth as a unique cell identifier (id, name, ...) in the data.
Define a public property to store the editing cell id
public selectedEditCellId; // number, string, UUID, etc
on invoking the edit mode, pass the cell id
changeEditor(cellId) {
this.selectedEditCellId = cellId;
this.editorStatus = true;
}
pass the cell ID on click
<td *ngIf="!editorStatus" (click)="changeEditor(CELL_ID)">{{consent.status}}
</td>
<td *ngIf="editorStatus && consent.id === selectedEditCellId">
<input type="text" value="{{consent.status}}" class="form-control">
<button (click)="changeEditor(undefined)">close editior</button>
</td>
then you can update the *ngIf condition to check the editorStatus property and the identifier
*ngIf="editorStatus && consent.id === selectedEditCellId"

Blazor: Apply Pagination with Entiy Framework on Datatable.Js

I have a Blazor project that uses Entity Framework and Binds to DataTable.js using JavaScript InterOp.
The project works well but in cases where records loaded from my table are bulky i experience delay and my app crashes at some point.
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-bordered"
id="example"
width="100%"
cellspacing="0">
<thead>
<tr style="font-size:14px">
<th>FEEDER ID</th>
<th>FEEDER NAME</th>
<th>FEEDER TYPE</th>
<th>DISTRICT ID</th>
<th>TCN 132Kv ID</th>
<th>INJECTION ID </th>
<th>FEEDER NO</th>
<th>FEEDER LENGTH </th>
<th>STATUS</th>
<th>FEEDER CODE</th>
<th>DOWNLOAD MAP</th>
</tr>
</thead>
<tbody>
#foreach (var data in feederview)
{
<tr style="font-size:14px">
<td>#data.FeederId</td>
<td>#data.FeederName</td>
<td>#data.FeederType</td>
<td>#data.DistrictId</td>
<td>#data.Tcn132kv33kvId</td>
<td>#data.InjectionssId</td>
<td>#data.FeederNo</td>
<td>#data.FeederLength</td>
<td>#data.Status</td>
<td>#data.FeederCode</td>
<td align="center">
<button class="btn-info btn-sm" id="btnDelete" value="delete"><i class="fa fa-eye fa-1x " aria-hidden="true"></i></button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
Above is my HTML Code definition with bindings
C# Blazor Server side code using Entity Framework
feederview = context.FeederView.Select(c => new FeederView()
{
FeederId = c.FeederId,
FeederName = c.FeederName,
FeederType = c.FeederType,
DistrictId = c.DistrictId,
Tcn132kv33kvId = c.Tcn132kv33kvId,
Tcn132kv33kvTransformerId = c.Tcn132kv33kvTransformerId,
InjectionssId = c.InjectionssId,
InjectionssTransformerId = c.InjectionssTransformerId,
FeederNo = c.FeederNo,
FeederLength = c.FeederLength,
Status = c.Status,
FeederCode = c.FeederCode,
}).ToList();
The list returns up to 2000 records which makes my app slow and crashes.
Above is the sample records shown ( for this i just loaded small records)
How can i add pagination to Datatable.js to allow me retrieve a particular amount of records on load and the remaining loads later?
I think you would need to look at server-side processing https://datatables.net/manual/data/
Otherwise, perhaps there is a way of utilising the new virtualization feature.
https://learn.microsoft.com/en-us/aspnet/core/blazor/components/virtualization?view=aspnetcore-5.0

Change background color for a group of columns not first two columns using jquery

I need to change background color for a group of columns using column id.The first two columns background would not need to change.How to achieve in Jquery?
This is I have tried so far.I have added my Complete script in this you can get more info about it.
var fromtime = obj[i].FromTime; // Here fromtime gives id of a column not index
var totime = obj[i].totime; // Here totime gives id of a column not index
$(row1).children('td').slice(fromtime,totime).not('td:eq(0)').not('td:eq(0)').css({ "background-color": workcolor });
Edit:
I have added my HTML Code
<table class="table table-striped" id="table1">
<thead>
<tr>
<th class="" id="profilepic">Image</th>
<th id="empName">Employee</th>
<th id="00">00:00</th>
<th id="01">01:00</th>
<th id="02">02:00</th>
<th id="03">03:00</th>
<th id="04">04:00</th>
<th id="05">05:00</th>
<th id="06">06:00</th>
<th id="07">07:00</th>
<th id="08">08:00</th>
<th id="09">09:00</th>
<th id="10">10:00</th>
<th id="11">11:00</th>
<th id="12">12:00</th>
<th id="13">13:00</th>
<th id="14">14:00</th>
<th id="15">15:00</th>
<th id="16">16:00</th>
<th id="17">17:00</th>
<th id="18">18:00</th>
<th id="19">19:00</th>
<th id="20">20:00</th>
<th id="21">21:00</th>
<th id="22">22:00</th>
<th id="23">23:00</th>
</tr>
</thead>
<tbody id="body1">
</tbody>
Complete script:
$(row1).children('td').not('td:eq(0)').not('td:eq(0)').css({ "background-color": workcolor });
I am appending a new row each time called "row1" that's cells background color needs to modified based on a "fromtime" to "ToTime" values.There is Children('td') td used means the whole row got colored.But I need the certain cells only.
your code have many other things that don't apply or doesn't seem relevant to the question, then, I making here a code that can help you with your exactly question (apply background to columns but not first and second ones).
I'm using a very basic logic, looping through all columns, starting at index 2 (cause you don't want the first 2 columns to have BG)
Maybe you won't use it exactly like I did below, but I'm sure that this can help and you may find a way to use it inside your code.
please, take a look at the snippet and tell me if you need more help here.
EDIT
If you need just some listed IDs to receive the background, maybe you can have or receive an array and then check to see if they are what you need. This will also change the foor loop, because now you don't need to start at 2, you can loop through all columns and will apply background just to the ones listed in the array, look below:
OPTION 1
loop through all columns (to ensure that you will find only columns, not any other element), then check the IDs.
$(document).ready(function(){
var arrayOfIDs = ["02", "03", "04", "07", "10", "15", "21"];
var myTable = $(".table-striped");
var myColumns = $(myTable.find("th"));
//loop through all columns
myColumns.each(function(){
var column = this;
//loop through all IDs you want to change
for (var i = 0; i < arrayOfIDs.length; i++){
if (column.id == arrayOfIDs[i]){
column.style.background = "rgba(50,50,200,0.85)";
}
}
});
});
th{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped" id="table1">
<thead>
<tr>
<th class="" id="profilepic">Image</th>
<th id="empName">Employee</th>
<th id="00">00:00</th>
<th id="01">01:00</th>
<th id="02">02:00</th>
<th id="03">03:00</th>
<th id="04">04:00</th>
<th id="05">05:00</th>
<th id="06">06:00</th>
<th id="07">07:00</th>
<th id="08">08:00</th>
<th id="09">09:00</th>
<th id="10">10:00</th>
<th id="11">11:00</th>
<th id="12">12:00</th>
<th id="13">13:00</th>
<th id="14">14:00</th>
<th id="15">15:00</th>
<th id="16">16:00</th>
<th id="17">17:00</th>
<th id="18">18:00</th>
<th id="19">19:00</th>
<th id="20">20:00</th>
<th id="21">21:00</th>
<th id="22">22:00</th>
<th id="23">23:00</th>
</tr>
</thead>
<tbody id="body1">
</tbody>
OPTION 2
Just loop through IDs to find the columns directly and then apply the BG.
--EDIT 2--> Also, if you need to modify the code on the run, create a function that changes background, this way, every time you need to change the background, call this function, passing the IDs you want and the color you want... as below:
$(document).ready(function(){
//function that loop through all IDs you want to change
var paintBackground = function(arrayOfIds, colorIWant){
for (var i = 0; i < arrayOfIds.length; i++){
var myId = arrayOfIds[i];
var column = $("#"+myId);
column.css('background', colorIWant);
}
}
var firstArrayToPaint = ["00", "01", "02", "06", "07", "08"];
paintBackground(firstArrayToPaint, "orange");
//Added a timeout just to better examplify, don't use the timeout if you don't need it
setTimeout(function(){
//add new row
var myTable = $('.table thead');
var row1 = document.createElement("tr");
myTable[0].append(row1);
//specifying new columns to this row
var qtdOfNewColumns = 6;
var secondArrayToPaint = ["17", "18", "19", "20", "21", "22"];
for (var i = 0; i < qtdOfNewColumns; i++){
var column = document.createElement("th");
column.id = secondArrayToPaint[i];
column.textContent = secondArrayToPaint[i]+":00";
row1.append(column); //adding the columns to the row
}
paintBackground(secondArrayToPaint, "yellow");
},1500);
});
th{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped" id="table1">
<thead>
<tr>
<th class="" id="profilepic">Image</th>
<th id="empName">Employee</th>
<th id="00">00:00</th>
<th id="01">01:00</th>
<th id="02">02:00</th>
<th id="03">03:00</th>
<th id="04">04:00</th>
<th id="05">05:00</th>
<th id="06">06:00</th>
<th id="07">07:00</th>
<th id="08">08:00</th>
<th id="09">09:00</th>
<th id="10">10:00</th>
</tr>
</thead>
<tbody id="body1">
</tbody>

How can I select a table heading which have same class name and not any other unique attribute in web driver

<th id="desc" class="sort" data="aWQ=">S.No</th>
<th class="table_head" data="bmFtZQ==">Customer</th>
<th class="table_head" data="c3R5bGVfbm8=">Style#</th>
<th class="table_head" data="c3R5bGVfZGVzYw==">Style Description</th>
<th class="table_head" data="ZmFicmljX2Rlc2M=">Fabric Description</th>
<th class="table_head" data="YXBwcm92ZWQ=">Status</th>
<th>Action </th>
The able code states that same class name for all columns,The ID & CLASS is assigned only when user selects a column to filter.
IN that case how can I select all the columns
with jQuery you can do this:
$('th').eq(1) // the "customer" element
$('th').eq(4) // the "fabric description" element
in vanilla JS, it's just as simple:
document.querySelectorAll('th')[1] // the "customer" element
document.querySelectorAll('th')[4] // the "fabric description" element
with this, you can easily select the nth table column, but you have to know the index of the column beforehand.

Populate Table in jQuery Mobile

I am using fooTable jQuery plugin as date grid in jQuery mobile. I have list of data I need to populate in the table. Initially with filtering and cell formatting. First I want to populate data in the table. I am using an external .js file to keep JavaScript separately.
HTML5 code, "$.App.initGridView" is not calling from "data-init" tag. Why isn't it working?
<div data-role="view" data-title="Platform" onloadeddata="$.App.initGridView" data-init="$.App.initGridView">
<table class="footable table" id="my-table">
<thead >
<tr data-theme="b">
<th >Ticket#</th>
<th >Date</th>
<th data-hide="phone">Operator Name</th>
<th data-hide="phone">Lease Name</abbr></th>
<th >Tank#</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
jQuery Code:
initGridView: function () {
var rtList = $.App.tempDB.getTicketList();
// I want to populate table here
}

Categories