disabling modal popup in jqgrid - javascript

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

Related

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

Javascript, after disabling a button, need to make it available again. JS not working

Language: Javascript (PHP page)
I have 2 buttons on a page:
-- One is an upload image button (#upload),
-- & another is a "save / submit form" button (.multi-accordion-submit).
What the .js below does is it disables the submit button (.multi-accordion-submit) while files are being uploaded while user uses the other button (#upload) & text inside #upload says "Uploading...".
After an upload & text goes back to "Upload More" for #upload, the .multi-accordion-submit button's disabled attribute should now be removed.
But the problem is, it remains disabled and unclickable, rendering the submit button (.multi-accordion-submit) useless.
I don't know how to fix it, the code below looks fine & should work.
Any guidance and assistance would be greatly appreciated! Thanks for your time.
$(function () {
var btnUpload = $('#upload');
var status = $('#status');
var url = $('#upload_path').val();
new AjaxUpload(btnUpload, {
action: url,
//Name of the file input box
name: 'image',
onSubmit: function (file, ext) {
$('#upload-error').hide();
if (!(ext && /^(pdf|ai|psd|bmp|cdr|clk|gif|jpg|jpeg|ppt|pub|doc|docx|pcx|pic|pict|pct|png|ps|tif|tiff|emf|wmf|indd)$/.test(ext))) {
// check for valid file extension
$('#upload-error').show();
return false;
}
btnUpload.text('Uploading...');
$('.multi-accordion-submit').attr('disabled', true);
},
onComplete: function (file, response) {
if ($('.file-elements').length > 0) {
if ($('.file-elements:visible').length == 0) {
window.location.href = document.location.href;
} else {
btnUpload.text('Upload More');
$('.multi-accordion-submit').attr('disabled', false);
}
} else {
btnUpload.text('Upload More');
$('.multi-accordion-submit').attr('disabled', false);
}
//Add uploaded file to list
if (response === "success") {
$('<li></li>').appendTo('#files').html(file).addClass('upload-files');
} else {
$('<li></li>').appendTo('#files').text(file).addClass('upload-files');
}
}
});
});
//try to use
$('.multi-accordion-submit').attr('disabled','disabled');
//and
$('.multi-accordion-submit').removeAttr('disabled');
Attribute disabled is either exists or not (it`s value doesn't taken into account)
To remove disabled state from element you need to remove disabled attribute not just change it's value.
$('.multi-accordion-submit').removeAttr('disabled');
Notes:
Actually it may be confusing with jQuery because in 1.6+ prop and removeProp methods was introduced for work with native properties, but to remove disabled state you need to use prop and not removeProp (once removed native properties cannot be added again)
$('.multi-accordion-submit').prop('disabled', false);

Having trouble with Javascript autocomplete library when getting data with getJSON

I'm running into issues with the following code:
var setupSearch = {
searchSuggest: function(field) {
$.getJSON('/get-all-journals', {'url':'on'}, function(data) {
var SHCount = Number($.cookie('SHCount'));
var SHArray = new Array();
for (i=1; i <= SHCount; i++) {
SHArray.push($.cookie('SH'+i));
}
$(field).ddautocomplete(removeDuplicate(SHArray), data.response.docs, {
matchContains: true,
max: 5,
cacheLength: 5000,
selectFirst: false,
scroll: false,
formatResult: function(str) { return str; },
formatItem2: function(item) {
return item.journal_display_name;
},
formatMatch2: function(item) {
return item.journal_display_name;
},
formatResult2: function(item) {
return item.journal_display_name;
}
});
});
},
searchForm: function(form) {
var field = form.find('textarea');
// Setup query field for default text behavior
// setupField(field);
setupSearch.searchSuggest(field);
field.autogrow();
field.keydown(function(e) {
if (e.keyCode == 13) {
form.submit();
return false;
}
});
// Make all forms submitting through Advanced Search Form
form.submit(function(e) {
e.preventDefault();
setupSearch.submitSearch(form, field);
});
},
submitSearch: function(form, field) {
if (advancedSearch.checkMinFields() || (!field.hasClass('defaultText') && field.val() != '')) {
// Sync the refine lists
// syncCheckboxLists($('#refineList input'), $('#advancedRefineList input'));
form.find('button').addClass('active');
$('#advancedSearchForm').submit();
} else {
$('#queryField').focus();
}
},
When I try to use the autocomplete drop-down by hitting enter, it seems to hit a "race condition" where the form will submit what I've typed rather than what autocomplete places into the textfield. Is there some way I can control the order of events so that the form.submit() will use what autocomplete fills into the text field?
The actual autocomplete dropdown menu is most likely represented as a styled list (or some other element) that is floated to be positioned below the textbox. On submit, have your function wait (a second or two max) for the autocomplete menu to be either destroyed or hidden. This will ensure that the plugin has time to fill in the textbox before the data is submitted.
EDIT
Try something like this:
$("#myDropdown").bind("autocompleteclose", function(){
// Continue with submitting your form
});
Use that where you would submit your form, and put the submitting code inside the callback. That way, it will wait for the autocomplete to close before submitting the form. You will want to add some kind of timeout to this to prevent it from submitting after a long delay (not sure when something like this might happen, though).

Simulate Textbox Click to get focus

I am trying the following code to fire click event on a textbox while clicking on a button as the focus() function is not working in IE8
function simulateClick(elm) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var canceled = !elm.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
// uh-oh, did some XSS hack your site?
} else {
// None of the handlers called preventDefault
// do stuff
}
}
This code works fine if the element is of type checkbox but not textbox, is there anything I might need to add?
This is the code for focus
function ResponseEnd(sender, args) {
if (args.get_eventArgument().indexOf("Filter") != -1) {
var grid = document.getElementById("<%= radGridEnquiries.ClientID %>");
var label = $(grid).children("table").children("tbody").children(".rgRow").children("td:has(span)").children("span")[0];
if (label != null) {
label.focus();
}
else {
var noRecTemp = $(grid).children("table").children("tbody").children("tr.rgNoRecords").children("td:has(div)").children("div");
noRecTemp.focus();
}
}
if (postInProgress)
postInProgress = false;
}
The real scenario is I have some textboxes set as filters in a Telerik RadGrid and having no filter icons but when the user posts a filter and the request is finished in IE8 the filter textbox is still with focus preventing the user to input new filters unless clicks on the textbox manually again
P.S. Sorry if this post is seen as answer but couldn't update this question with proper indented code. Thanks

jqGrid Edit Cell and afterSubmitCell

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.

Categories