I need to know how to send fields before a delete in jqgrid, to add is easy I have a script for that, but for delete I can't.
here a example to add:
{//add
recreateForm:true,
jqModal:true,
reloadAfterSubmit:true,
savekey: [true,13],
closeOnEscape:true,
closeAfterAdd:true,
height:150,
width:450,
url:"process/jqgridAnaOT.php",
addCaption : "Asigancion de Analista",
beforeSubmit:function(postdata){
var dataString = $("#formid").serialize();
var numReg = document.getElementById('OT').value;
var assign = document.getElementById('Siglas').value;
var txt_open = document.getElementById('txt_open2').value;
if(txt_open==0){
jAlert('La orden se encuentra cerrada, No es posible modificar datos',titulo);
return false;
} else { ...
} },
as you see, to add we have a form which we are able to manipulate the data in,
the function beforeSubmit allows us know data in the form, but when we delete a row it does not exist in the form if not a message from jqgrid.
There is a similar event when you delete the row. If you use Guriddo jqGrid you may want to look at the documentation here
i found a solution
http://www.trirand.com/blog/?page_id=393/help/how-to-send-additional-post-data-when-deleting-a-row#p17185
$(function(){
$("#list").jqGrid({
colNames:[...],
colModel :[...],
etc...
});
$("#list").jqGrid('navGrid','#pager',
{add:true,edit:false,del:true,search:false,refresh:true},
{//edit},
{//add},
{//del
code....
}
);
});
In this method i use the interface by default for jqgrid it most clearly to use, using the solution i adapted my code and it work's fine.
{//del
recreateForm:true,
jqModal:true,
reloadAfterSubmit:true,
savekey: [true,13],
closeOnEscape:true,
closeAfterAdd:true,
height:130,
width:450,
url:'process/jqgridAnaOT.php?pid="<?=$strPid?>"',
onclickSubmit: function(params){
var txt_open = document.getElementById('txt_open2').value;
var gr = jQuery("#list").jqGrid('getGridParam','selrow');
var val = jQuery('#list').jqGrid('getCell',gr,'Siglas');
if(txt_open==0){
jAlert('La orden se encuentra cerrada, No es posible modificar datos',titulo);
return false;
}
else {
return {Siglas:val};
}
}
} // fin del
I hope this code has usefull for somebody
Related
I have a grid setup using form editing. I want the the user to be able to edit only some of the rows. As a start, I figured the easiest way to do this was to have a column (probably hidden) in my server query and XML that denotes the Access or Role the user has. So essentially the grid now has a column "Access Role" with 'Y' or 'N' for each row. (where Y = user can edit, N = View/readonly)
I've tried a couple things to implement this. The best I've come up with is using the rowattr function, but my use is flawed since it hides the row in the grid (I don't want it hidden, just readonly):
function (rd) {
console.log('Row = '+rd.WWBPITM_SURROGATE_ID);
if (rd.ACCROLE === "N") {
console.log('RowAttr '+rd.ACCROLE);
return {"style": "display:none"};
}
This might be a start, but I'm not sure where to go from here and I'm not sure if I'm barking up the wrong tree with using rowattr.
I also tried using setCell in a loadComplete function, like this:
function GridComplete() {
var grid = $('#list1');
var rowids = grid.getDataIDs();
var columnModels = grid.getGridParam().colModel;
console.log('Check ACCROLE');
// check each visible row
for (var i = 0; i < rowids.length; i++) {
var rowid = rowids[i];
var data = grid.getRowData(rowid);
console.log('ACCROLE for '+rowid+' is '+data.ACCROLE);
if (data.ACCROLE == 'N') { // view only
// check each column
//console.log(data);
for (var j = 0; j < columnModels.length; j++) {
var model = columnModels[j];
if (model.editable) {
console.log('Is Editable? '+model.editable);
//grid.setCell(rowid, model.name, '', 'not-editable-cell', {editable: false, edithidden: true});
grid.setCell(rowid, model.name, '', 'not-editable-cell', {editoptions: { readonly: 'readonly', disabled: 'disabled' }});
}
}
}
}
}
But the editoptions don't seem to do anything with this.
Any ideas how to do this?
OK thanks for explaining about Form editing. Here's an example of how to prevent edits on certain records for jqGrid with form editing:
Start with this example of jqGrid form edit: http://www.ok-soft-gmbh.com/jqGrid/MulticolumnEdit.htm
Use the beforeInitData event to check your data before the edit form is displayed. Note that this is bound to the pager object.
Use getGridParam and getCell methods to get the current value you want. In my example I grabbed the client name
Add your own business logic for checking (I don't allow edits on 'test2')
Return false to prevent the edit form from popping up.
This example only handles edit, not insert or delete.
Replace $grid.jqGrid("navGrid", "#pager",...) from the example with this:
$grid.jqGrid("navGrid", "#pager", {view: true},
// Events for edit
{
beforeInitData: function (formid) {
var selectedRow = jQuery("#list").jqGrid('getGridParam','selrow'); //get selected rows
var selectedClient = $("#list").jqGrid('getCell', selectedRow, 'name');
if(selectedClient == 'test2')
{
alert('You are not allowed to edit records for client "' + selectedClient + '"');
return false;
}
}
},
// Events for add
{
beforeShowForm: function (formid) {
}
}
);
You didn't provide much information about how you're updating rows (there are various methods as described in JQGrid web page demos, but I took a guess as to a possible solution. I started with the example on the bottom of this page (trirand's web site wiki for inline_editing) http://www.trirand.com/jqgridwiki/doku.php?id=wiki:inline_editing and made a few changes.
Added a new data column securityGroup, and put in data like 'A', 'B', 'C'
Displayed the new data column in the grid
The example used the onSelectRow event to start editing a row if you clicked on a new row. I updated this callback to check the value of row['securityGroup'], and only start .editRow if it's in securityGroupA
JSFiddle at http://jsfiddle.net/brianwoelfel/52rrunar/
Here's the callback:
onSelectRow: function(id){
var row = $(this).getLocalRow(id);
if(id && id!==lastsel2){
jQuery('#rowed5').restoreRow(lastsel2);
if(row['securityGroup'] == 'A') {
jQuery('#rowed5').editRow(id,true);
}
lastsel2=id;
}
},
If this method won't work for you, please provide more information about how you're currently doing edits with jqGrid. This example obviously is very trivial and doesn't even post to PHP or mysql or anything.
In case it will be helpful for others, here is how I am implementing Read Only rows in Form Editing mode, based on a column which designates what level of access the user has to each row:
In editoptions, use the beforeShowForm event, like so:
beforeShowForm: function (formid) {
console.log('Checking for READONLY '+formid.name);
var selectedRow = jQuery("#list1").jqGrid('getGridParam','selrow'); //get selected rows
var selRole = $("#list1").jqGrid('getCell', selectedRow, 'ACCROLE');
if(selRole == 'N' || selRole == 'S' || selRole == 'R')
{
//$("<div>Sorry, you do not have access to edit this record.</div>").dialog({title: "Access Denied"});
formid.find("input,select,textarea")
.prop("readonly", "readonly")
.addClass("ui-state-disabled")
.closest(".DataTD")
.prev(".CaptionTD")
.prop("disabled", true)
.addClass("ui-state-disabled");
formid.parent().find('#sData').hide();
var title=$(".ui-jqdialog-title","#edithd"+"list1").html();
title+=' - READONLY VIEW';
$(".ui-jqdialog-title","#edithd"+"list1").html(title);
formid.prepend('<span style="color: Red; font-size: 1em; font-weight: bold;">You viewing READONLY data.</span>');
}
For a quick view of my problem I have made a working jsFiddle here:
In KnockoutJS I have made a custom extender validator to test if the input format is in the HHMM format. If it is it returns the new value, if it doesn't it will set it back to the old value this is currently working.
ko.extenders.acValidTimeHHMM = function (target, options) {
var result = ko.computed({
read: target,
write: function (newValue) {
var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
if (!re.test(newValue)) {
target.notifySubscribers(target());
//Time not in correct format return old time
return;
}
target(newValue);
}
}).extend({ notify: 'always' });
result(target());
return result;
};
The problem I am having is that I update my database when the value changes using a computed. However this is also firing when I reset the value back to its original using my validator. (Method based on Ryan Rahlf dirty flag technique here )
self.update = ko.computed(function () {
self.timeOne();
self.timeTwo();
alert("Fired");
});
The problem is obviously the line target.notifySubscribers(target()); in my validator. However without this line I can't reset the value to its old value and I can't find another way to do this.
So this only fires when a value actually changes rather then the validator resetting it. The jsFiddle demonstrates my problem exactly and can be used to make a working version (hopefully) I know its currently firing on page load too.
The problem I am having is that I update my database when the value changes using a computed.
I don't know all your logic, but I don't think this is a good idea to update the db each time your knockout view model has updated. May be you should look at knockout validation plugin. Using this plugin you can build the same custom validation rule and update the db only on form submit event.
About your problem...
The simplest solution I'm found is to send a success callback function to the validation extension like an option.
Something like this.
JS:
var ViewModel = function() {
var update = function () {
alert("value was successfully changed");
};
var cancel = function () {
alert("validation failed. previous value was returned");
};
var timeOne = ko.observable("1100").
extend({
acValidTimeHHMM: {
success: update,
fail: cancel
}
});
var timeTwo = ko.observable("1248").
extend({ acValidTimeHHMM: { success: update } });
return {
timeOne: timeOne,
timeTwo: timeTwo
};
};
ko.extenders.acValidTimeHHMM = function(target, option) {
var baseOptions = {
success: null,
fail: null
};
$.extend(baseOptions, option);
var result = ko.computed({
read: target,
write: function (newValue) {
var oldValue = target();
if(newValue == oldValue) return;
var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
if (!re.test(newValue)) {
target.notifySubscribers(oldValue);
if(typeof(baseOptions.fail) == "function")
baseOptions.fail();
return;
}
target(newValue);
if(typeof(baseOptions.success) == "function")
baseOptions.success()
}
}).extend({ notify: 'always' });
result(target());
return result;
};
ko.applyBindings(new ViewModel());
HTML:
<p>Time One<input data-bind='value: timeOne' /></p>
<p>Time Two<input data-bind='value: timeTwo' /></p>
I am trying to change the columns collection of my Kendo grid in the below way.
var grid = $("#grid").data("kendoGrid");
$http.get('/api/GetGridColumns')
.success(function (data) {
grid.columns = data;
})
.error(function (data) {
console.log(data);
});
This is changing the column collection but not reflecting immediately in my grid. But when I try to perform some actions in the grid (like grouping), then my new column set is appearing.
Please let me know how can I achieve this.
Regards,
Dilip Kumar
You can do it by setting the KendoUI datasource, destroy the grid, and rebuild it
$("#load").click(function () {
var grid = $("#grid").data("kendoGrid");
var dataSource = grid.dataSource;
$.ajax({
url: "/Home/Load",
success: function (state) {
state = JSON.parse(state);
var options = grid.options;
options.columns = state.columns;
options.dataSource.page = state.page;
options.dataSource.pageSize = state.pageSize;
options.dataSource.sort = state.sort;
options.dataSource.filter = state.filter;
options.dataSource.group = state.group;
grid.destroy();
$("#grid")
.empty()
.kendoGrid(options);
}
});
});
here you can just do this :
var options = grid.options;
options.columns = state.columns;
where you can retrieve the columns in a session or in a db
This jsfiddle - Kendo UI grid dynamic columns can help you - using kendo.observable.
var columns = data;
var configuration = {
editable: true,
sortable: true,
scrollable: false,
columns: columns //set the columns here
};
var grid = $("#grid").kendoGrid(configuration).data("kendoGrid");
kendo.bind($('#example'), viewModel); //viewModel will be data as in jsfiddle
For the ones who are using Kendo and Angular together, here is a solution that worked for me:
The idea is to use the k-rebind directive. From the docs:
Widget Update upon Option Changes
You can update a widget from controller. Use the special k-rebind attribute to create a widget which automatically updates when some scope variable changes. This option will destroy the original widget and will recreate it using the changed options.
Apart from setting the array of columns in the GridOptions as we normally do, we have to hold a reference to it:
vm.gridOptions = { ... };
vm.gridColumns = [{...}, ... ,{...}];
vm.gridOptions.columns = vm.gridColumns;
and then pass that variable to the k-rebind directive:
<div kendo-grid="vm.grid" options="vm.gridOptions" k-rebind="vm.gridColumns">
</div>
And that's it when you are binding the grid to remote data (OData in my case). Now you can add or remove elements to/from the array of columns. The grid is going to query for the data again after it is recreated.
When binding the Grid to local data (local array of objects), we have to somehow postpone the binding of the data until the widget is recreated. What worked for me (maybe there is a cleaner solution to this) is to use the $timeout service:
vm.gridColumns.push({ ... });
vm.$timeout(function () {
vm.gridOptions.dataSource.data(vm.myArrayOfObjects);
}, 0);
This has been tested using AngularJS v1.5.0 and Kendo UI v2016.1.226.
I'm use this code for change columns dynamic:
kendo.data.binders.widget.columns = kendo.data.Binder.extend({
refresh: function () {
var value = this.bindings["columns"].get();
this.element.setOptions({ columns: value.toJSON });
this.element._columns(value.toJSON());
this.element._templates();
this.element.thead.empty();
this.element._thead();
this.element._renderContent(this.element.dataSource.view());
}
});
Weddin
Refresh your grid
.success(function (data) {
grid.columns = data;
grid.refresh();
})
Here is what i use
var columns = [];//add the columns here
var grid = $('#grid').data('kendoGrid');
grid.setOptions({ columns: columns });
grid._columns(columns);
grid._templates();
grid.thead.empty();
grid._thead();
grid._renderContent(grid.dataSource.view());
I think a solution for what you are asking is to call the equivalent remote DataSource.read() method inside of the function. This is what I used to change the number of columns dynamically for local js data.
$("#numOfValues").change(function () {
var columnsConfig = [];
columnsConfig.push({ field: "item", title: "Metric" });
// Dynamically assign number of value columns
for (var i = 1; i <= $(this).val(); i++) {
columnsConfig.push({ field: ("value" + i), title: ("201" + i) });
}
columnsConfig.push({ field: "target", title: "Target" });
columnsConfig.push({ command: "destroy", title: "" });
$("#grid").data("kendoGrid").setOptions({
columns: columnsConfig
});
columnDataSource.read(); // This is what reloads the data
});
Refresh the grid
$('#GridName').data('kendoGrid').dataSource.read();
$('#GridName').data('kendoGrid').refresh();
Instead of looping through all the elements. we can remove all the data in the grid by using a single statement
$("#Grid").data('kendoGrid').dataSource.data([]);
If your grid is simple and you don't need to configure special column-specific settings, then you can simply omit the columns argument, as suggested in the API reference.
Use autogenerated columns (i.e. do not set any column settings)
... and ....
If this [column] setting is not specified the grid will create a column for every field of the data item.
var newDataSource = new kendo.data.DataSource({data: dataSource}); $("#grid").data("kendoGrid").setDataSource(newDataSource);
$("#grid").data("kendoGrid").dataSource.read();
After fighting this for a day and seeing hints in this thread that Kendo had simplified this problem, I discovered you can just use setOptions with a single property.
.success(function (data) {
grid.setOptions({
columns: data,
});
})
Grid Set Options
I have a jqgrid with certain columns and I need hyperlink in one of the columns, clicking on the hyperlink should open a new window, basically call a window.open().
Also when I call the window.open(), I need the hyperlink column value.
Please provide me with some sample code.Anyhelp would be highly appreciated.
Thanks
Oleg, I tried the below code and it is throwing error "object expected" in load().
{name:'FileName', FileName:'price', width:60, align:"center", formatter:returnMyLink}
function returnMyLink(cellValue, options, rowdata)
{
return "<a href='javascript:load();'>Open Window</a>";
}
function load()
{
var guid = 'CEF9C407-2500-4619-95E3-8E6227B65954';
window.open ('/irj/servlet/prt/portal/prtroot/com.medline.medpack.ExcelViewerPL.ExcelViewer?report=CustomerBenefit&reportId='+guid );
}
I did try the document.delegate to capture the a href event.
$(document).delegate('#CustomerSavingsView .jqgrow td a[href="#"]', 'click',function()
{
alert('test');
}
I was not able to capture this event either.
Sorry Im new to Jquery. Please correct me if Im wrong.
Thanks
This is how I solved it. In the grid complete event added the following code.
hl = "<a href='#Test' target='_blank' id='hlink"+cl+"'>Test</a>";
And then added a event handler for it.
$(document).delegate('#CustomerSavingsView .jqgrow td a[href*="#Test"]', 'click', function ()
{
var guid = 'CEF9C407-2500-4619-95E3-8E6227B65954';
window.open('/irj/servlet/prt/portal/prtroot/com.medline.medpack.ExcelViewerPL.ExcelViewer?report=CustomerBenefit&reportId='+guid );
}
This solved the purpose. Thanks again Oleg and Walter.
maybe this will be help:
in colModel,define a col: {name:'test',formatter:linkformatter}
and in javascript create a function named linkformatter which returns a link;
like:
function linkformatter( cellvalue, options, rowObject){
return '<a href='xxxxxx' />';
}
The predefined formatter 'showlink' can be used to create the link in the grid column. You can use target property of the formatoptions options to define target of the link.
First declare the Jquery JQGrid column definition as follows
colModel: [{ name: 'Notes/Memos', width: "5", sortable: true, classes: 'ellip', resizable: false, formatter: MethodFormatter }]
The formatter property takes the method name which is invoked with the three parameters which internally having the cells value and its id and the following method returns the hyperlink.
function MethodFormatter(cellValue, options, rowObject) {
var selectedRowId = options.rowId;
return '<a href="javascript:MethodJS(' + selectedRowId + ')" style="color: #3366ff" id="' + selectedRowId + '" >' + cellValue + '</a>';}
The following JS Function is invoked after clicking the hyperlink which opens up another page in a window.
function MethodJS(selectedRowId) {
document.location.href = "ViewContact.aspx?NoteID=" + selectedRowId;
}
My approach involves fewer lines of code and gives the solution asked for. In my grid, a column called Project Number is formatted as a hyper link. It opens a new page and passes the project number as a parameter.
colNames: ["Project #", ...],
colModel: [
{ name: 'Project Number', index: 'Project Number', width: 80, key: true, formatter: 'showlink', formatoptions: { baseLinkUrl: 'Details.aspx', target: '_new' } },
Note where I have key: true. Without this, the url returns the row number. The url returned is http://localhost:57631/Details.aspx?id=2103
I'm using jqGrid version 5.0.1
This is my pattern. As I said, it is much more code than Oleg's suggestion of using the showlink formatter, but it is more customizable.
// bind a live event handler to any elements matching the selector 'a.linkWindowOpener'
$('a.linkWindowOpener').live('click', linkWindowOpener);
// colModel settings
{ name: 'ItemDescription', index: 'ItemDescription', formatter: itemDescription_formatter, unformat: itemDescription_unformatter },
// custom formatter to create the hyperlink
function itemDescription_formatter(cellvalue, options, rowObject) {
var html = '';
var itemID = rowObject.itemID;
var itemDescription = cellvalue;
var a = $('<a>')
.attr('href', '/Forms/WorkOrder/ViewItem.aspx?ItemID=' + itemID)
.attr('data-itemDescription', itemDescription )
.html(itemDescription)
.addClass('linkWindowOpener');
html = a.getHtml();
return html;
}
// unformatter to return the raw value
function itemDescription_unformatter( cellvalue, options, cell) {
return $('a', cell).attr('data-itemDescription');
}
// event handler to call when clicking the hyperlink
function linkWindowOpener(event) {
event.preventDefault();
event.stopPropagation();
var o = $(event.currentTarget);
var url = o.attr('href');
window.open(url);
return false;
}
// jQuery extenision function I wrote to get the HTML of an element
// returns the HTML of an element. It works by wrapping the element
// inside a DIV and calling DIV.html(). It then returns the element back to
// it's original DOM location
jQuery.fn.getHtml = function () {
var elm = $(this[0]);
// create a div
var div = $('<div>');
// append it to the parent of the target element
elm.parent().append(div);
// append the element to the div
div.append(elm);
// get the html of the div
var html = div.html();
// move element back to its parent
div.parent().append(elm);
div.remove();
return html;
}
while selecting the checkbox in the jqgrid i need to sum the values of row data in jqgrid and i need to display those data in the footer of the jqgrid.Please help me out how to achieve that.
Thanks in Advance,
Silambarasan,
You can use footerData method. See here and here for details and demo examples.
I got the answer ,i solved that issue.
The Answer is.
footerrow:true,
userDataOnFooter:true,
onSelectRow: function(rowId)
{ handleSelectedRow(rowId); },
function handleSelectedRow(id) {
var jqgcell = jQuery('#list1').getCell(id, 'headerId');
var amount = jQuery('#list1').getCell(id, 'amount');
var cbIsChecked = (jQuery("#jqg_list1_"+jqgcell).attr('checked'));
if(cbIsChecked==true)
{
if(amount!=null)
{
totalAmt = parseInt(totalAmt) + parseInt(amount);
}
}else
{
if(amount!=null)
{
totalAmt = parseInt(totalAmt) - parseInt(amount);
}
}
myGrid.jqGrid('footerData','set',{needbydate:'Total Amount:',amount:totalAmt});
}
The above function is used to get the values of the selected row by clicking the checkbox you will get the value from that by calling the external function like "handleSelectedRow" you pass your row object from that you do your operation and finally update your answer by using the jqGrid function like "myGrid.jqGrid('footerData','set',{needbydate:'Total Amount:',amount:totalAmt}); "
It will update in your footer.