jqGrid Edit Cell and afterSubmitCell - javascript

I use jqGrid 4.9.3-pre - free jqGrid by Oleg. I want to add a new record and edit without a modal window.
I do so:
On loadComplete I add a new empty record with id=0.Here we can add a
new record.
After adding a new entry from the database get its ID. Replace 0 value on ID.
After adding a new record is created another empty row, and so on.
jsFiddle
I think the problem is that the cell is still active?
I Found Solution. Thank Oleg!
var flag = false;
....
afterSaveCell: function(rowid, cellname, value, iRow, iCol) {
$('#' + lastRowId).attr("id", respText);
},
afterSubmitCell: function(serverresponse, rowid, cellname, value, iRow, iCol){
var rows = $("#contract_subgrid")[0].rows;
lastRowId = rows[rows.length-1].id;
var response = (serverresponse.statusText).trim();
if (response == 'OK'){
respText = serverresponse.responseText;
if(respText=='0' || respText==""){
return [true,""];
}
else {
$(this).jqGrid('setCell', lastRowId, 'id', respText);
$(this).jqGrid('addRowData', undefined, {});
return [true,""];
}
}else{
return [false,respText];
}
},
loadComplete: function () {
if(flag === false) {
$(this).jqGrid('addRowData', undefined, {});
flag = true;
}
},

Sorry, but I don't understand the scenario which you want to implement. The usage of cell editing (cellEdit: true) seems to me not the best choice here. In any way the afterSubmitCell will be never called if you use cellsubmit:'clientArray', which is default. The usage of addRowData with the same id="0" is not good. You can produce id duplicates. You can use
$(this).jqGrid('addRowData', undefined, {});
instead. The usage of undefined as the rowid will generate new unique rowid. More better would be to use
$(this).jqGrid('addRow', {position: "last"});
and inlineNav. You need to fix defaultValue: "Intim" to defaultValue: "IN" additionally.
You can define aftersavefunc inside of inlineEditing to update the rowid after saving to the server. You need to specify editurl for it. Look at jsfiddle.net/OlegKi/tzp91wnf/2 where you need to add editurl and aftersavefunc of cause. You need to use both .attr("id", newId) and .jqGrid('setCell', rowid, 'id', newId) to update the id after it will be generated by the backend.

Related

How to filter data based on new and old data

I am new in angular. I have created an inline editable table that can perform CRUD operation inline.
The row which I am creating, I made its id with starting key "a" like this
addNew(): void {
this.data.push({
id: "a" + this.newFieldCounter++,
isEditable: true,
});
}
But user click on add button and when he want to cancel the operation, it should remove that new editable row, for that I have written like this:
cancel(data): void {
this.data = this.data.filter((x) => !(x.id === data.id));
data.isEditable = !data.isEditable;
}
The cancel button working fine for new rows, but when I am clicking on the edit button of the existing record and when I am clicking on the cancel button, that existing record is also getting removed from the table. :(
Is there any way to do it?
Can you try this?
addNew(): void {
this.data.push({
id: "a" + this.newFieldCounter++,
isEditable: true,
isNew: true //for old entries it will be false or undefined
});
}
cancel(data): void {
this.data = this.data.filter((x) => x.id !== data.id && !x.isNew);
data.isEditable = !data.isEditable;
}
Updated
Store in an auxiliar obj the old data, and use a variable to know if is new or nor
onEdit(data)
{
this.isNew=false;
this.oldData={...data} //make a copy using spread operator
...
}
onAdd()
{
this.isNew=true;
...
}
In cancel you can pass the index of the data
<i .... (click)="cancel(tableData,i)"></i>
and
cancel(data,index)
{
if (this.isNew) //<--use the variable
this.data = this.data.filter((x) => !(x.id === data.id));
else
this.tableData[index] ={...this.oldData}
data.isEditable = !data.isEditable;
}
The simplest solution would be, to give new entries a flag, that they are new. So when cancelling the editing, only those entries will be filtered out, that are new.
Therefore you could add (blur)="removeNewFlag(data)" or something like this to remove the flag on submission of your input.
You probably run into an issue, since clicking on the cancel button triggeres the blur event as well. So you can either delay the removeNewFlag method or you can change your code to only submit the input with a button (like the paperplane in messengers).
Check out this demo

call parent widget function from inside dijit checkbox change function lopcated inside dgrid

I've got a dijit form checkbox inside an ondemand grid. The Ondemand grid is part of a dojo widget. I'd like to call one of the functions in the widget within the checkbox's on change event, but I cant seem to get a reference to the widget. Here is my code:
TicketUnMarkedSet: function (GridData) {
//set the unmarked ticket information
gridStore = new Memory({ data: GridData, idProperty: "ID" });
grid = new (declare([OnDemandGrid, DijitRegistry]))({
store: gridStore,
columns: {
CheckedOut: {
label: "CO",
renderCell: function (object, cell) {
var CO = true; // check the checked out check box based on data from db
if (object.CheckedOut == "No") {
CO = false;
}
var cellContent = domConstruct.create("div", {});
var cbox = new CheckBox({
checked: CO,
name: "idBox"
});
cbox.placeAt(cellContent);
on(cbox, "change", function (evt) {
var Staff = "No";
if (evt == true) {//check box is checked, flag ticket as checked out
Staff = cookie("LoggedInAs")
}
this.CheckOutTicket(Staff);//how to call CheckOutTicket function (this is the checkbox)
});
return cellContent;
}
},
..more columns
},
CheckOutTicket: function (Staff){
alert(Staff);
}
How can I get a reference to CheckOutTicket function ?
Thanks
Pete
I found a workaround, but maybe not the best solution. On the postCreate Event I define a global variable referencing the widget, and then use that variable to call the function from inside the change event for the checkbox
I'd suggest you to use dojo/topic to get what you want.
on(cbox, "change", function (evt) {
var Staff = "No";
if (evt == true) {//check box is checked, flag ticket as checked out
Staff = cookie("LoggedInAs")
}
topic.publish("CheckOutTicket", Staff);
});
And somewhere in your parent widget, for i.e. in postCreate
this.own(topic.subscribe("CheckOutTicket", this.CheckOutTicket));
Now you don't have to care about passing handler from parent to child widget and use global variables.

Is it possible to dynamically close or open a Jqgrid column search?

Is it possible to open and close the search function of certain columns after loading Jgrid?
The underlying code allows you to hide the search part, but does not affect the search function
It works fine to hide but I haven't found what I need to do to show it
this code does not affect the search function
I have to influence the search
$("#gs_name").closest(".ui-search-table").hide();
Sample jsfiddle
UPDATE
The desired combination in the Client Name column
search = hidden -> search = false
search = show -> search = true
$("#columnhide").click(function(){
$("#gs_name").val("")
$("#gs_name").closest(".ui-search-table").toggle();
});
If I correctly understand what you need to implement then http://jsfiddle.net/OlegKi/ejnrtocw/270/ demonstrates what you can do. The code uses
$("#columnhide").click(function(){
var $searchField = $("#gs_name");
$searchField.val(""); // clear the filter
$searchField.closest(".ui-search-table").toggle(); // hide or show the control
$(this).html("<b>" + ($searchField.is(":hidden") ? "Show" : "Hide") +
"</b> Client Name Search");
$("#grid")[0].triggerToolbar(); // force filtering without a filter in "name" field
});
and additionally modifies the code of `` callback to the following
ondblClickRow: function(rowid, iRow, iCol, e) {
var $grid = $(this),
cm = $grid.jqGrid("getGridParam", "colModel"),
cellvalue = $grid.jqGrid("getCell", rowid, iCol),
$searchField = $("#gs_" + cm[iCol].name);
if (!$searchField.is(":hidden")) {
$searchField.val(cellvalue);
this.triggerToolbar();
}
}
The hidden property in double click is a property of colModel. In your case you should use the jquery selector :hidden to do the job.
The code can be changed like this:
ondblClickRow: function(rowid, iRow, iCol, e) {
var cm = $(this).jqGrid("getGridParam", "colModel");
var cmvalues = $(this).jqGrid("getRowData", rowid);
$.each(cm, function(i,n){
if(!n.hidden) {
var elem = $('#gs_'+n.name);
if( elem.is(":hidden") {
// set it to empty to overcome search when trigger
elem.val("");
} else {
elem.val( cmvalues[n.name]);
}
}
});
this.triggerToolbar();
},
This code searches its data if the column is clicked
ondblClickRow: function(rowid, iRow, iCol, e) {
var $grid = $(this),
cm = $grid.jqGrid("getGridParam", "colModel"),
cellvalue = $grid.jqGrid("getCell", rowid, iCol),
$searchField = $("#gs_" + cm[iCol].name);
if (!$searchField.is(":hidden")) {
$searchField.val(cellvalue);
this.triggerToolbar();
}
},
All the columns are retrieved
ondblClickRow: function(rowid, iRow, iCol, e) {
var grid=$('#grid');
var cm = $(this).jqGrid("getGridParam", "colModel");
var cmvalues = $(this).jqGrid("getRowData", rowid);
$.each(cm, function(i,n){
if(!n.hidden) {
$('#gs_'+n.name).val( cmvalues[n.name])
}
});
this.triggerToolbar();
},
I could not set the first code according to the second code!
I want all column data to be searched by double clicking
this is important for a practical filter
I want to do a search in all areas by doing double clicking, but I will never search in hidden columns!

Odoo: JSON: Inherit view, hide edit button conditionally

I'm trying to hide the edit button in the bill of material form in Odoo, dependent on the state of a boolean.
I managed to remove the edit button permanent with the code below:
<xpath expr="//form[#string='Bill of Material']" position="attributes">
<attribute name="edit">false</attribute>
</xpath>
Now I tried to make it conditional with a boolean like this:
<xpath expr="//form[#string='Bill of Material']" position="attributes">
<attribute name="edit">true:realman==True;false:realman==False;</attribute>
</xpath>
This gives error:
SyntaxError: JSON.parse: unexpected non-whitespace character after
JSON data at line 1 column 5 of the JSON data
When I looked up the javascript file, I've found this is the code to handle the edit attribute:
/**
* Return whether the user can perform the action ('create', 'edit', 'delete') in this view.
* An action is disabled by setting the corresponding attribute in the view's main element,
* like: <form string="" create="false" edit="false" delete="false">
*/
is_action_enabled: function(action) {
var attrs = this.fields_view.arch.attrs;
return (action in attrs) ? JSON.parse(attrs[action]) : true;
},
I suppose I need to get false in that var attrs when the boolean realman in my form is False?
I've already tried to write it in curly brackets like the answer in this question: JSON.parse unexpected character error
That gave me errors too.
Why do I get this error and how can I fix this? Is this just a syntax error or are there more problems?
I successfully solved a similar issue by using field_view_get, but only if "realman" is passed into context
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = models.Model.fields_view_get(self, cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
realman = context.get('realman', True)
if not realman and view_type == 'form':
doc = etree.XML(res['arch'])
for t in doc.xpath("//form[#string='Bill of Material']"):
t.attrib['edit'] = 'false'
res['arch'] = etree.tostring(doc)
return res
if realman is instead a field and you need to enable/disable the edit button, then I'm afraid it is just not possible. AFAIK.
As Alessandro Ruffolo stated his solution doesn't work for buttons/actions depending on model's field. I have written solution in Javascript for that. It works in ODOO 10 (should in 9 also but I haven't tested it).
Example is checking on model's field "state". If it has value "noEditable" edit and delete buttons would hide. It isn't enough to overwrite is_action_enabled because ODOO is calling the method when there is no datarecord loaded yet. Therefore it's needed to check it again after methods do_show and reload.
// modify default form view for custom model my.custom.model
odoo.define('my.custom_model_form', function (require) {
"use strict";
var FormView = require('web.FormView');
FormView.include({
is_action_enabled: function(action) {
if (this.model == "my.custom.model" && this.datarecord && this.datarecord.state == "noEditable" &&
(action == 'delete' || action == 'edit')) {
// don't allow edit nor delete
return false;
}
// call default is_action_enabled method
return this._super.apply(this, arguments);
},
deleteItem: null,
deleteItemIdx: null,
deleteItemShown: true,
reinit_actions: function() {
// apply for my custom model only
if (this.model == "my.custom.model") {
// hide/show edit button
if (this.is_action_enabled('edit')) {
this.$buttons.find(".o_form_button_edit").show();
} else {
this.$buttons.find(".o_form_button_edit").hide();
}
// find delete item in sidebar's items
if (!this.deleteItem) {
// form view is adding it to "other"
if (this.sidebar && this.sidebar.items && this.sidebar.items.other) {
for (var i = 0; i < this.sidebar.items.other.length; i++) {
// on_button_delete is used as callback for delete button
// it's ugly way to find out which one is delete button, haven't found better way
if (this.sidebar.items.other[i].callback == this.on_button_delete) {
this.deleteItem = this.sidebar.items.other[i];
this.deleteItemIdx = i;
break;
}
}
}
}
// hide/show delete button
if (this.is_action_enabled('delete')) {
if (!this.deleteItemShown) {
this.deleteItemShown = true;
// add delete item to sidebar's items
this.sidebar.items.other.splice(this.deleteItemIdx, 0, this.deleteItem);
}
} else
if (this.deleteItemShown) {
this.deleteItemShown = false;
// remove delete item from sidebar's items
this.sidebar.items.other.splice(this.deleteItemIdx, 1);
}
}
},
reload: function() {
var self = this;
// run reinit_actions after reload finish
return this._super.apply(this, arguments).done(function() {
self.reinit_actions();
});
},
do_show: function() {
var self = this;
// run reinit_actions after do_show finish
return this._super.apply(this, arguments).done(function() {
self.reinit_actions();
});
}
});
});
I believe a solution with a computed field makes things simpler for these cases.
You can inherit the bill of material form and override it. Point the invisible condition to a computed field where you'll create your validation. Note that is necessary to add your computed field to the form, even though hiding it.
<xpath expr="//form[#string='Bill of Material']" position="attributes">
<attribute name="attrs">
{'invisible': [('show_bm_button', '=', False)]}
</attribute>
<field name="show_bm_button" invisible="1"/>
</xpath>
Then override the object in python and add the new computed field.
class ProductTemplate(models.Model):
_inherit = 'product.template'
show_bm_button = fields.Boolean(
compute='_compute_show_bm_button',
readonly=False, store=False
)
# #api.depends('realman') #Just as a sample, if you have this field in this Model
def _compute_show_bm_button(self):
for record in self:
realman = self._context.get('realman') or True
if realman:
record.show_bm_button = True
else:
record.show_bm_button = False

disabling modal popup in jqgrid

I want to create a custom message without using the modal popup in jqgrid. Is there a way to disable it? Or is there a way to change the contents of the modal?
Can you be more specific? If you want your own modal dialog, you could just add an event handler (on an Edit button, for example) that when fired will open your own custom dialog. You can use the jQuery UI dialog for this purpose, and just have it open to your own custom form.
Update
After inspecting the jqGrid source code, info_dialog is the function that is used to display this particular dialog. There is a separate call to display the "Loading..." popup. Offhand there does not seem to be a simple way to disable info_dialog. However, you could modify the jqGrid source to accomplish what you need. You could either:
Return immediately from info_dialog - which may be extreme because it could report other errors you need - or,
Find and comment out the call that is displaying this particular ajax error. There is some trial-and-error involved, but with only 18 calls to this function it will not take you long to track down. In fact, start by commenting out this instance, since it is called from the error function of an ajax call:
info_dialog(a.jgrid.errors.errcap,e.status+" : "+e.statusText+"<br/>"+u,a.jgrid.edit.bClose);
Obviously such a modification is a last resort, but once it works you might consider rolling a patch for the jqGrid team to disable the alert.
Search for div.loadingui div.msgbox { ... } somewhere in css files. I think editing this css class will get the job done.
i have changed the z-index of modal popup on runtime once you can access to it you can do any customization
editoptions: { size: 20, maxlength: 10,
dataEvents: [
{ type: 'keypress',
fn: function (e) {
if (e.keyCode == 13) {
**$("#info_dialog").css('z-index', '100000');**
}
}
}
]
} }
Also, if you can do it on another place if you have server response such as error
onCellSelect: function (rowid, iCol, aData) {
currentRow = rowid;
if (rowid && rowid !== lastsel) {
if (lastsel) jQuery('#ppGrid').jqGrid('restoreRow', lastsel);
$("#ppGrid").jqGrid('editRow', rowid, true, null, null, null, {}, reload,OnError);
lastsel = rowid;
}
else if (rowid && rowid === lastsel)
{ $("#ppGrid").jqGrid('editRow', rowid, true, null, null, null, {}, reload,OnError); }
}
Yes you can do it. you can make visible property to false [$("#info_dialog").visible(false);] of the modal box, and you can call what ever your custom modal box.
editrules: { custom: true, custom_func: validate_edit }
function validate_edit(posdata, colName) {
var message = "";
if (posdata != '' && $.isNumeric(posdata))
return [true, ""];
if (posdata == '')
message = colName + " field is required"
if (!$.isNumeric(posdata))
message = posdata + " is not a number";
alert(message);
$("#info_dialog").visible(false);
return [false, ""];
}
I know this is out of the topic, but have you tried SlickGrid https://github.com/mleibman/SlickGrid/wiki/examples

Categories