How to replace jqgrid alert messages(successfully added,deleted) to bootstrap alerts?I am using JQGRID 5.2.1. As we use following code in jqgrid for alerts
if (response.responseText) {
alert(response.responseText);
}
First of all I want to remind, that alert will be used by free jqGrid extremely seldom and only in critical situations, for example, if the grid can't be created at all.
On the other side, one could have the requirement don't use alert as common policy of a company and as common requirement to every JavaScript modules. It will corresponds to the polity of some web browsers (see the article for example).
One more example of requirement to replace alert usage will be creating unit tests, which reproduces some errors explicitly. It would be helpful to test the existence of an error only without displaying blocking alert.
In any way free jqGrid allows to define $.jgrid.defaults.fatalError method, which will be used by jqGrid instead of alert. For example, one can use the code like below
$.jgrid.defaults = $.jgrid.defaults || {};
$.jgrid.defaults.fatalError = function (errorText) {
$("body").prepend('<div class="alert alert-danger alert-dismissable">' +
'×' +
'<h4 class="alert-heading">Error</h4>' +
'<p>' + errorText + '</p>' +
'</div>').alert()
.on('closed.bs.alert', function () {
$(this).remove();
})
};
before creating of any grid.
https://jsfiddle.net/OlegKi/c70pfv6r/ is a simple grid, which uses Bootstrap CSS. I included $.jgrid.defaults.fatalError in the code, but it will be not really used. I modified the demo to include colNames parameter, which length don't corresponds the length of colModel parameter: https://jsfiddle.net/OlegKi/c70pfv6r/1/. jqGrid can't create the grid and it uses alert in such cases. One the other side one will see the following div instead:
I think there is a much easer way to do this. In case of Guriddo jqGrid as declared in the question it is possible to use the build in common function $.jgrid.info_dialog like this
if (response.responseText) {
$.jgrid.info_dialog('My Title', response.responseText, 'Close', { styleUI : 'Bootstrap'});
More on the common Guriddo jqGrid functions you can look here
Related
Is it possible to differentiate how documents open in a view on an XPage, depending on the status of a document using the getComponent("programmaticname").getValue() method?
If the status of the document is "Sent" then I want it to open in Edit mode. If the status of the document is "Reviewed" then I want it to open in Read Only mode.
I would like to compute the "openDocAsReadOnly" property in my view. Could someone show me what that code would look like?
This is a working example:
<xp:viewPanel
rows="30"
id="viewPanel1"
var="rowData">
<xp:this.facets>
<xp:pager
...>
</xp:pager>
</xp:this.facets>
<xp:this.data>
<xp:dominoView
var="view1"
viewName="yourView">
</xp:dominoView>
</xp:this.data>
<xp:viewColumn
id="viewColumn2"
displayAs="link"
columnName="Reviewer"
openDocAsReadonly="#{javascript:rowData.getColumnValue('Status') === 'Responded'}">
</xp:viewColumn>
It is important that
viewPanel has var="rowData" so openDocAsReadonly can reference to current row with rowData....
view column Status has not only "Status" as title but as Programmatic use name too
If all works fine then the URL of your Reviewer column should end with &action=openDocument if Status is "Responded" and &action=editDocument for all other cases.
Maybe the cause for you having trouble to get it to run is much easier: use for test "Responded", not "Reviewed". In your former question you told Status is called "Reviewed", so answers use this. But, your picture here shows "Responded".
Make sure you define a variable name in your viewPanel at All Properties >> data >> var (rowData is a frequently used variable name for that)
This variable holds an object of type NotesXspViewEntry, so it knows a method called .getColumnValue(colName:String), where colName is your Notes view column's programmatic name (I assume it's named "Status").
In consequence your openDocAsReadonly property could hold a code like this:
rowData.getColumnValue("Status")=="Responded"
EDIT:
sorry maybe made a mistake here; probably it doesn't work due to a wrong timing. Instead you could try to override the standard url link by defining it in the viewColumn's pageUrl property. A quick test revealed a code like this (I followed Knut Herrmann's observation):
var d = entry.getColumnValue("Status");
var a="editDocument";
if(d=="Responed") {
a="openDocument"
}
"/yourDocXpage.xsp?documentId=" + entry.getUniversalID() + "&action=" + a
Not really sure though whether this is the best of all solutions...
Is it possible to load from server via ajax JQGrid structure(columns) together with data ?
If possible, could you please show an example ?
There's no reason why not, you just ned to do things (asynchronously) in the correct order, something like this (forgive the psuedo code)
var jqGridOptions = {
/* various options here */
}
$.ajax({
url: jqGridStructureUrl
}).success(function(jqGridColumns){
// Add the col model to the other options
jqGridOptions.colModel = jqGridColumns.colModel
jqGridOptions.colNames = jqGridColumns.colNames
// set up the jqGrid
$j("#gridId").jqGrid(jqGridOptions)
})
This will get you part of the way there. I guess you'll also be wanting to load Data via Ajax in which case you can set the "Data" option on the jqGrid settings to a callback function (this is not very well documented) - OR you could fire off TWO ajax calls, one for data and one for structure and then when they're BOTH back munge the two together and instantiate your grid object
You can create jqGrid with all hidden columns. You need create grid with large enough number of columns. The names of the columns (in colModel) can have some generic values like "c1", "c2", "c3" ... The response from the server can contains colModel information together with the data. Inside of beforeProcessing callback you can change colModel and set new column headers. The answer demonstrates setting of column headers dynamically. The code column be simplified by usage setLabel method. Another answer demonstrates how to use setColProp to set the most settings of colModel full dynamically. If you would combine the solution with the usage of setColWidth method which I posted in the answer (see here too) then you could create perfect solution.
Trying to use Select2 and getting this error on multiple item input/text field:
"query function not defined for Select2 undefined error"
Covered in this google group thread
The problem was because of the extra div that was being added by the select2. Select2 had added new div with class "select2-container form-select" to wrap the select created. So the next time i loaded the function, the error was being thrown as select2 was being attached to the div element. I changed my selector...
Prefix select2 css identifier with specific tag name "select":
$('select.form-select').select2();
This error message is too general. One of its other possible sources is that you're trying to call select2() method on already "select2ed" input.
In case you initialize an empty input do this:
$(".yourelement").select2({
data: {
id: "",
text: ""
}
});
Read the first comment below, it explains why and when you should use the code in my answer.
I also had this problem make sure that you don't initialize the select2 twice.
For me this issue boiled down to setting the correct data-ui-select2 attribute:
<input type="text" data-ui-select2="select2Options.projectManagers" placeholder="Project Manager" ng-model="selectedProjectManager">
$scope.projectManagers = {
data: [] //Must have data property
}
$scope.selectedProjectManager = {};
If I take off the data property on $scope.projectManagers I get this error.
This issue boiled down to how I was building my select2 select box. In one javascript file I had...
$(function(){
$(".select2").select2();
});
And in another js file an override...
$(function(){
var employerStateSelector =
$("#registration_employer_state").select2("destroy");
employerStateSelector.select2({
placeholder: 'Select a State...'
});
});
Moving the second override into a window load event resolved the issue.
$( window ).load(function() {
var employerStateSelector =
$("#registration_employer_state").select2("destroy");
employerStateSelector.select2({
placeholder: 'Select a State...'
});
});
This issue blossomed inside a Rails application
I also got the same error when using ajax with a textbox then i solve it by remove class select2 of textbox and setup select2 by id like:
$(function(){
$("#input-select2").select2();
});
It seems that your selector returns an undefined element (Therefore undefined error is returned)
In case the element really exists, you are calling select2 on an input element without supplying anything to select2, where it should fetch the data from. Typically, one calls .select2({data: [{id:"firstid", text:"firsttext"}]).
Also got the same error when using ajax.
If you're using ajax to render forms with select2, the input_html class must be different from those NOT rendered using ajax. Not quite sure why it works this way though.
if (typeof(opts.query) !== "function") {
throw "query function not defined for Select2 " + opts.element.attr("id");
}
This is thrown becase query does not exist in options. Internally there is a check maintained which requires either of the following for parameters
ajax
tags
data
query
So you just need to provide one of these 4 options to select2 and it should work as expected.
I got the same error. I have been using select2-3.5.2
This was my code which had error
$('#carstatus-select').select2().val([1,2])
Below code fixed the issue.
$('#carstatus-select').val([1,2]);
I have a complicated Web App and I couldn't figure out exactly why this error was being thrown. It was causing the JavaScript to abort when thrown.
In select2.js I changed:
if (typeof(opts.query) !== "function") {
throw "query function not defined for Select2 " + opts.element.attr("id");
}
to:
if (typeof(opts.query) !== "function") {
console.error("query function not defined for Select2 " + opts.element.attr("id"));
}
Now everything seems to work properly but it is still logging in error in case I want to try and figure out what exactly in my code is causing the error. But for now this is a good enough fix for me.
For example, I call my default settings on every page load and bind a function to loadComplete to do some basic formatting for my grids.
On some pages, I have additional logic I would like to execute at the same time, but if I set loadComplete in the grid definition, it will overwrite the function set in my defaults.
Is there a way to bind multiple handlers, or some other way of executing all the necessary code? Thanks in advance.
I think you ask about an important problem existing in the current version of jqGrid. It's difficult to implement more as one event handler in jqGrid now. The problem is not important for small projects where you use jqGrid, but can be important in case that you want construct some classes which interprets jqGrid. Your current workaround is OK, but have the restriction which you understand yourself. The main problem that in the way you can implement only one more additional loadCompleteEx handler.
What I would suggest you is the usage of jQuery.trigger or better jQuery.triggerHandler. You can use it together with jQuery.bind and jQuery.unbind. In the way you can define any number of event handlers which works like standard jQuery events.
For example,
var grid = $("#list");
grid.bind('jqGridLoadComplete',function(e,data) {
alert ("in first jqGridLoadComplete event handler. Called for the page " +
data.page);
});
grid.jqGrid({
// jqGrid parameters
// ...
loadComplete: function(data) {
alert("main load complete");
$(this).triggerHandler("jqGridLoadComplete", data);
}
});
grid.bind('jqGridLoadComplete.jqGrid',function(e,data) {
alert ("in second jqGridLoadComplete event handler. Called for the page " +
data.page);
});
In the second jQuery.bind I used namespaced event 'jqGridLoadComplete.jqGrid' from the namespace 'jqGrid'. So you can use everything which you know (and which you need) about standard events in jQuery.
See the corresponding demo here. Try to switch the pages in the grid or change the sorting to call loadComplete.
I bind the second jqGridLoadComplete after the jqGrid definition. Because my demo uses datatype:'local' the first call of loadComplete will be before the binding executed. So at the first loadComplete execution will be the second jqGridLoadComplete event handler not called. So you should better to bind your event handler before the jqGrid definition. In the case you can be sure that the event will be always called.
UPDATED: IMPORTANT!!!. One don't need to trigger jqGridLoadComplete event explicitly inside of loadComplete if you use the current version of jqGrid. jqGrid do this already for you. The above code was written before the corresponding functionality are included in the main code of jqGrid. The answer just described the main idea how multiple event handlers could be implemented in jqGrid. After writing the answer I posted some pull requests to trirand with my suggestion to implement jQuery events in jqGrid. Starting with the version 4.3.2 (see here) jqGrid support the events.
if you want to do something before the request use the beforeRequest function.
you can also bind a function to the gridComplete option. could you give a code example to show what you are trying to do?
My hackaround solution:
// Global Variable in my common.js
var loadCompleteEx;
// set defaults
$.extend($.jgrid.defaults, {
datatype: 'json',
height: "100%",
...
loadComplete: function () {
if ($("#grid").getGridParam("reccount") === 0)
$("#empty-grid-message").show();
else
$("#empty-grid-message").hide();
// if loadCompleteEx is defined, call it at the end of loadComplete
if (loadCompleteEx)
loadCompleteEx();
}
}
// In my specific page js
loadCompleteEx = function () {
// Do more stuff after load completes
};
Works like a charm...is there any bad practice in here?
There is a much easier solution to this than I have seen recommended anywhere else:
// Set defaults
jQuery.extend(jQuery.jgrid.defaults, {
loadComplete: function () {
myCustomFunction();
}
});
loadComplete: function() {
// someOtherFunction();
$.jgrid.defaults.loadComplete(); // Runs myCustomFunction()
},
I"m trying to create an additional function for jqGrid to simplify adding JSON data to a grid that uses local data. The following attempt works except for one line, which causes it to fail.
$.fn.myrows = function(data) {
$(this).clearGridData();
$(this).jqGrid("setGridParam", {datatype: "json", loadonce: true});
$("#" + (this).selector)[0].addJSONData(data); // PROBLEMATIC LINE
$(this).jqGrid("setGridParam", {datatype: "local", loadonce: true});
};
This function is then called as $("#myGrid").myrows(jsonDataObject);.
Note that these lines work when they are not inside this function.
Any ideas? Thanks!
In the answer on your previous question I tried to explain how to extend jqGrid to support new method. To tell the truth, I don't see what real advantage you will have from the jqGrid extending. Why not just define your function as
var myrows = function(grid,data) {
// function body
};
and use it in the way:
myrows($("#myGrid"),jsonDataObject);
Much more important thing in my opinion is the implementation of what you need. Your current code have many disadvantages. If the grid has datatype: "local" then the local data paging can be used. The method addJSONData add all the data in the grid, so the page size can be broken.
If you have datatype: "local" and want to fill it with the data then the most effective way will be to set data parameter of the grid with respect of setGridParam and then just call $("#myGrid").trigger('reloadGrid',[{page:1}]) (see here).
Alternative you can use many other existing methods like addRowData which allows to add many rows of data at one method call.
If you get the JSON data from the server and thy to fill the grid with addJSONData method it will be really bad way. The versions of jqGrid starting with the version 3.5 has rich ways to customize the ajax request used. So it is strictly recommended that you don't use addJSONData in the case. See here for details.
You have a typo, do this on the line:
$("#" + $(this).selector)[0].addJSONData(data); // PROBLEMATIC LINE
The $ was missing before this