- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-07-2023 01:34 AM
On Service Portal, we would like to make the Data Table widget show the "True/False" field as checkbox and editable by just clicking on it, but not sure about how to customize the widget. Can it be achieved by editing HTML/CSS or server script?
Could someone please advise me on how to customize the cloned widget to meet the requirements?
Best Regards,
Aki
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-12-2023 02:04 PM
Hm what could also be, is that the GlideAjax's callback is actually executed before the record watcher callback. This would explain the strange delay...
I would assume you can improve the behavior by not relying on the recordwatcher anymore and just apply the changed value by your own:
1.) In the Client Callable Script Include, return the new value for your field, e.g.:
var ListEditUtils = Class.create();
ListEditUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
toggleItem: function () {
var inc = new GlideRecord('incident');
if (inc.get(this.getParameter('item'))) {
inc.active = !inc.active;
inc.setWorkflow(false);
inc.update();
return inc.active.toString(); // return the new value
}
return 'false';
},
type: 'ListEditUtils'
});
2.) In the client controller, modify the c.click like this (to apply the updated field value on your own, of course you wont be using the active field - so please modify the script as you would also for the script include above):
// ...
c.click = function (item) {
var ga = new window.GlideAjax('global.ListEditUtils');
ga.addParam('sysparm_name', 'toggleItem');
ga.addParam('item', item.sys_id);
ga.getXMLAnswer(function (result) {
item.active.display_value = result;
tableScope.$apply(); // rerender the table
});
};
//...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-11-2023 09:09 AM
Hm strange, i just saw that i had a typo in the GlideAjax callback, it should not be scope, but tableScope.
The full widget client controller:
api.controller=function($compile) {
var c = this;
var tableScope = null;
c.click = function (item) {
var ga = new window.GlideAjax('global.ListEditUtils');
ga.addParam('sysparm_name', 'toggleItem');
ga.addParam('item', item.sys_id);
ga.getXMLAnswer(function (result) {
tableScope.$evalAsync(function () {});
});
};
c.init = function (tableElement) {
tableScope = tableElement.scope();
var filter = tableScope.data.filter;
tableScope.click = c.click.bind(c);
var template = tableScope.widget.template
.replace(/::item\[field\]/g, 'item[field]') // disable two-way binding on widget-data-table
.replace('</th>', '</th><th>Actions</th>')
.replace('</td>', '</td><td ng-class="{selected: item.selected}"><button ng-click="click(item)">X</button></td>');
tableElement.html(template);
$compile(tableElement.contents())(tableScope);
};
};
For me, this is working perfectly fine...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-11-2023 10:05 AM
Hi @Markus Kraus ,
Thank you so much for your support. After replacing the client controller script, the second row is now updated!
However, it still takes about 5 or more seconds for the value change to be reflected on the list...
I'm using the cloned Data table from URL definition widget to fix the table to "sc_task", but do you think it's related to the symptom? Or, is it just due to our demo instance's performance?
Here is the server script of the cloned widget:
(function() {
deleteOptions(['table', 'field_list', 'filter', 'order_by', 'order_direction', 'order', 'maximum_entries']);
/* if (input) {
data.table = input.table;
data.view = input.view;
} else {
data.table = $sp.getParameter('table') || $sp.getParameter('t');
data.view = $sp.getParameter('view');
}*/
data.table = 'sc_task';
if (!data.table) {
data.invalid_table = true;
data.table_label = "";
return;
}
var gr = new GlideRecordSecure(data.table);
if (!gr.isValid()) {
data.invalid_table = true;
data.table_label = data.table;
return;
}
// page is where the record URLs go, URL parameter wins
data.page_id = $sp.getParameter("target_page_id");
if (!data.page_id) {
var sp_page = $sp.getValue('sp_page');
if (sp_page) {
var pageGR = new GlideRecord('sp_page');
pageGR.get(sp_page);
data.page_id = pageGR.id.getDisplayValue();
}
}
// widget parameters
data.table_label = gr.getLabel();
data.fields = $sp.getListColumns(data.table, data.view);
copyParameters(data, ['p', 'o', 'd', 'filter', 'fixed_query']);
copyParameters(data, ['relationship_id', 'apply_to', 'apply_to_sys_id']);
data.filterACLs = true;
data.show_new = true;
data.show_keywords = true;
data.show_breadcrumbs = true;
data.fromUrl = true;
data.useInstanceTitle = (options.use_instance_title == "true");
data.headerTitle = data.useInstanceTitle ? options.title : gr.getPlural();
data.enable_filter = input.enable_filter || options.enable_filter == true || options.enable_filter == "true";
data.dataTableWidget = $sp.getWidget('widget-data-table', data);
function copyParameters(to, names) {
names.forEach(function(name) {
data[name] = $sp.getParameter(name);
})
}
// in case this widget is tied to the wrong instance type
function deleteOptions(names) {
names.forEach(function(name) {
delete options[name];
})
}
})()
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-12-2023 02:04 PM
Hm what could also be, is that the GlideAjax's callback is actually executed before the record watcher callback. This would explain the strange delay...
I would assume you can improve the behavior by not relying on the recordwatcher anymore and just apply the changed value by your own:
1.) In the Client Callable Script Include, return the new value for your field, e.g.:
var ListEditUtils = Class.create();
ListEditUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
toggleItem: function () {
var inc = new GlideRecord('incident');
if (inc.get(this.getParameter('item'))) {
inc.active = !inc.active;
inc.setWorkflow(false);
inc.update();
return inc.active.toString(); // return the new value
}
return 'false';
},
type: 'ListEditUtils'
});
2.) In the client controller, modify the c.click like this (to apply the updated field value on your own, of course you wont be using the active field - so please modify the script as you would also for the script include above):
// ...
c.click = function (item) {
var ga = new window.GlideAjax('global.ListEditUtils');
ga.addParam('sysparm_name', 'toggleItem');
ga.addParam('item', item.sys_id);
ga.getXMLAnswer(function (result) {
item.active.display_value = result;
tableScope.$apply(); // rerender the table
});
};
//...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-13-2023 08:31 AM
Hi @Markus Kraus ,
Thank you so much for the modification! Now the field is updated on the list just after clicking the button, amazing!
I really appreciate it and accepting it as Solution. Thank you so much!
*BTW: I have another question in my other post below regarding how to keep the page scroll position even after refreshing pages. So if you already have some good idea, I would also appreciate your advice.