jqGrid | add-edit-delete buttons not working - javascript

sorry if my questions are simple , i'm totaly new to jqGrid :)
1- i want to use (add,edit,delete) feature of jqGrid , as you see there are buttons on the footer part of my grid but when i click just a dialog box comes and no fields to enter !! i want it just like this page
see my screen picture of what happens !
2- what happens when i click on submit button ( after fixing part 1 ) , i want to know how datas post to server!
no matter what language , i want to not for example they sent as object or sth , to know how to process them !
tnx alot
my source code :
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index Page</title>
<!-- external scripts -->
<!-- jQuery & Bootstrap -->
<script type="text/javascript" src="{% static "js/jquery.js" %}"/></script>
<script type="text/javascript" src="{% static "js/jquery.jqGrid.min.js" %}"/></script>
<link rel="stylesheet" type="text/css" media="all" href="{% static "css/bootstrap.min.css?id=1" %}"/>
<script type="text/javascript" src="{% static "js/bootstrap.min.js" %}"/></script>
<!-- jQuery & Bootstrap -->
<!-- jqGrid -->
<link rel="stylesheet" type="text/css" media="screen" href="{% static "css/ui.jqgrid.css" %}" />
<link rel="stylesheet" type="text/css" media="screen" href="{% static "css/ui-lightness/jquery-ui.min.css" %}" />
<script type="text/javascript" src="{% static "js/grid.locale-en.js" %}"/></script>
<!-- jqGrid -->
<!-- own implemented scripts -->
<script type="text/javascript" src="{% static "js/script.js" %}"/></script>
<!-- own implemented scripts -->
<!-- external scripts-->
<script type="text/javascript">
$(function () {
$("#list").jqGrid({
url: "http://localhost:8000/getdata",
datatype: "json",
mtype: "GET",
colNames: ["شناسه", "کد","نام", "عنوان" ,"عنوان انگلیسی", "ظرفیت", "ظرفیت اضافه","قیمت روز"],
colModel: [
{ name: "id", index:"id", width: 60 , editable:true,editoptions: {readonly: "readonly"}},
{ name: "code", width: 60 , editable:true},
{ name: "name", width: 90 , editable:true},
{ name: "title", width: 90 ,editable:"true", editable:true},
{ name: "english_title", width: 100, align: "left", editable:true },
{ name: "capacity", width: 90, align: "left", editable:true },
{ name: "extra_capacity", width: 90, align: "left", editable:true },
{ name: "today_price", width: 80, align: "left" , editable:true},
],
rowNum:10,
rowList:[10,20,30],
pager: '#pager',
loadonce:true,
sortname: 'id',
viewrecords: true,
sortorder: "desc",
rownumbers: true,
rownumWidth: 40,
gridview: true,
multiselect: false,
caption: "اتاق ها",
onSelectRow: function(ids) {
if(ids == null) {
ids=0;
if(jQuery("#list_d").jqGrid('getGridParam','records') >0 )
{
jQuery("#list_d").jqGrid('setGridParam',{url:"getpricelist?q=1&id="+ids,page:1}).trigger('reloadGrid');
}
} else {
jQuery("#list_d").jqGrid('setGridParam',{url:"getpricelist?q=1&id="+ids,page:1}).trigger('reloadGrid');
jQuery("#list_d").jqGrid('setCaption',"لیست قیمت اتاق شماره : "+ids)
}
}
});
jQuery("#list").jqGrid('navGrid','#pager',{edit:true,add:true,del:true,search:false},
/* {
recreateForm: true,
beforeShowForm: function ($form) {
$form.find(".FormElement[readonly]")
.prop("disabled", true)
.addClass("ui-state-disabled")
.closest(".DataTD")
.prev(".CaptionTD")
.prop("disabled", true)
.addClass("ui-state-disabled")
},
}, */
//edit options
{ // Edit option (parameters of editGridRow method)
recreateForm:true,
reloadAfterSubmit:true,
closeOnEscape:true,
savekey: [true,13],
closeAfterEdit:true,
url:'/edit',
ajaxEditOptions: {
beforeSend: function(jqXHR) {
var csrf_token = getCookie('csrftoken');
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
afterSubmit: function () {
jQuery("#list").jqGrid("setGridParam", {datatype: 'json'});
console.log('changed data type');
return [true];
},
editData: {
csrfmiddlewaretoken: getCookie('csrftoken')
}
},
//add options
{
recreateForm:true,
reloadAfterSubmit:true,
closeOnEscape:true,
savekey: [true,13],
closeAfterAdd: true,
url:'/add',
ajaxEditOptions: {
beforeSend: function(jqXHR) {
var csrf_token = getCookie('csrftoken');
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
afterSubmit: function () {
jQuery("#list").jqGrid("setGridParam", {datatype: 'json'});
console.log('changed data type');
return [true];
},
editData: {
csrfmiddlewaretoken: getCookie('csrftoken')
}
},
//delete options
{
recreateForm:true,
reloadAfterSubmit:true,
closeOnEscape:true,
savekey: [true,13],
url:'/delete',
ajaxEditOptions: {
beforeSend: function(jqXHR) {
var csrf_token = getCookie('csrftoken');
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
afterSubmit: function () {
jQuery("#list").jqGrid("setGridParam", {datatype: 'json'});
console.log('changed data type');
return [true];
},
editData: {
csrfmiddlewaretoken: getCookie('csrftoken')
}
}
);
jQuery("#list").jqGrid('filterToolbar',{stringResult: true,searchOnEnter : false});
jQuery("#list_d").jqGrid({
height: 100,
width:345,
url:'getpricelist?q=1&id=2',
datatype: "json",
colNames:['از','تا', 'قیمت'],
colModel:[
{name:'from',index:'from', width:100},
{name:'to',index:'to', width:100},
{name:'price',index:'price', width:80, align:"right"},
],
rowNum:5,
rowList:[5,10,20],
pager: '#pager_d',
sortname: 'item',
viewrecords: true,
sortorder: "asc",
multiselect: false,
caption:"لیست قیمت"
}).navGrid('#pager_d',{add:false,edit:false,del:false});
});
</script>
</head>
<body>
<table id="list"><tr><td></td></tr></table>
<div id="pager"></div>
<table id="list_d"></table>
<div id="pager_d"></div>
</body>
</html>
views.py
from django.shortcuts import render
from django.utils import simplejson
from django.http import HttpResponse
from rooms.models import *
from django.db.models import Q
from django.core import serializers
def index(request):
return render(request, 'index.html')
def getdata(request):
data=room_type.objects.all()
json=[]
for o in data:
json.append({'id':o.id, 'code':o.code,'name':o.name,'title':o.title,
'english_title':o.english_title, 'capacity':o.capacity,
'extra_capacity':o.extra_capacity, 'today_price':o.today_price })
return HttpResponse(simplejson.dumps(json), mimetype='application/json',content_type='application/json' )
def getpricelist(request):
requested_room_id = request.GET.get('id', '')
room = room_type.objects.get(id = requested_room_id)
price_list_set = room.price_list_set.all()
json=[]
for price_list in price_list_set:
json.append({'from':price_list.from_date, 'to':price_list.to_date, 'price':price_list.price})
return HttpResponse(simplejson.dumps(json), mimetype='application/json',content_type='application/json' )
def edit(request):
print "################ediit#################"
return render(request, 'index.html')
def add(request):
print "################addddddddddd#################"
return render(request, 'index.html')
def delete(request):
print "################deeeeeeeeeeeeeel#################"
return render(request, 'index.html')

The first problem is very easy to solve. The editing form (Add and Edit) includes only the information about editable columns. So you need include editable: true property in every column of colModel which you want to allow the user to edit.
It's important to understand that there are default value for every known property of colModel. I recommend you to examine the last ("Default") column of the table on the place of the documentation. You will find that default value of align is "left", so you can remove align: "left" from all colModel items. In the same way you can see that default value of editable property is false. It way the reason why you had empty editing form. If you need to set editable: true to more as the half of columns of colModel I would recommend you to use cmTemplate option of jqGrid (see the answer for more details). After including cmTemplate: {editable: true} option for example you will need to include editable: false in all columns which you want don't make editable. All other columns will be editable.
If you need to include some column information in Add/Edit form, but don't permit the user to edit it you can use editable: true together with editoptions: {readonly: "readonly"} or editoptions: {disabled: "disabled"}. The option will include the information in the edit form, but set additional readonly="readonly" or disabled="disabled" attribute on the corresponding editing field. One can add additional "ui-state-disabled" class on such filed like described in the answer. In the way you can make some fields editable, but only for example in Add dialog and hold it disabled/readonly in Edit dialog. Don't forget to use recreateForm: true option.
To make editing successful it's very important to fill rowid of the grid correctly. If you have column with name: "id" or if some column have key: true property then the corresponding value will be used as rowid. The information which will be send to the server is described here (about Edit), here (about Add) and here (about Delele). The information contains always id=rowidvalue property. Add/Edit form post additionally information about all (inclusive hidden) editable columns in the form: name=value, where the name is the value of name property of the column definition in the colModel.

Related

jtable not triggering to clicks made on custom action buttons

My site is code in ASP.NET MVC 3.0.
with libraries:
jQuery 3.0.0,
jQuery Validation 1.17.0,
(I'm not sure which others can be useful mentioning).
My problem happens when testing in Internet Explorer 11, exactly when user press a button created as a "Custom Action" using jTable.org. This test happens in a Windows 2012 Server.
The same site tested on Firefox in same server is working without this or any other issue.
In IE, the regular buttons created by jTable for Create, Edit and Delete actions, are working.
This is the code for the View:
#model SuperSBL2.WebMVC3.ViewModels.HTEList
#{
ViewBag.Title = "Administrar HTEs";
}
#section CssImport{
<style>
div.filtering
{
border: 1px solid #999;
margin-bottom: 5px;
padding: 10px;
background-color: #EEE;
}
</style>
}
<h2>Administrar HTEs</h2>
<div class="filtering">
<form>
<label>Línea de Producción: <input type="text" name="ProductionLineName" id="ProductionLineName" /></label>
<label>Area: <input type="text" name="AreaName" id="AreaName" /></label>
<label>Operación: <input type="text" name="OperationName" id="OperationName" /></label>
<br /><label>Modelo: <input type="text" name="ModelName" id="ModelName" /></label>
<label>Tipo (ensameble/subensamble): <input type="text" name="HTETypeName" id="HTETypeName" /></label>
<button type="submit" id="LoadRecordsButton" class="btn btn-primary">Buscar registros</button>
</form>
</div>
<div id="HTEContainer" style="width: 1200px; "></div>
<br />
<button type="submit" id="GoBack" class="btn btn-default">REGRESAR</button>
<script type="text/javascript">
$(document).ready(function () {
//Localization texts
var spanishMessages = {
serverCommunicationError: 'Error de comunicación con el servidor, no puedo conectarme a la API.',
loadingMessage: 'Obteniendo datos...',
noDataAvailable: 'No hay datos disponibles!',
addNewRecord: 'Nuevo HTE',
editRecord: 'Editar HTE',
areYouSure: 'Estás seguro?',
deleteConfirmation: 'Estás a punto de borrar éste registro. Por favor confirma.',
save: 'Guardar HTE',
saving: 'Grabando',
cancel: 'Cancelar',
deleteText: 'Borrar HTE',
deleting: 'Borrando',
error: 'Error',
close: 'Cerrar',
cannotLoadOptionsFor: 'No puedo cargar opciones para campo {0}',
pagingInfo: 'Mostrando {0} a {1} de {2} registros',
pageSizeChangeLabel: 'Registros',
gotoPageLabel: 'Ir a página',
canNotDeletedRecords: 'No puedo borrar {0} de {1} registros!',
deleteProggress: 'Borrado {0} de {1} registros, procesando...'
};
$('#HTEContainer').jtable({
messages: spanishMessages, //Localizacion
title: 'Lista de HTEs',
paging: true,
pageSize: 10,
sorting: true,
defaultSorting: 'AreaName ASC',
selecting: true,
actions: {
listAction: '#Url.Action("HTEListForGrid")',
deleteAction: '#Url.Action("DeleteHTE")',
updateAction: '#Url.Action("UpdateHTE")',
createAction: '#Url.Action("CreateHTE")'
},
fields: {
HTEHeaderId: {
key: true,
create: false,
edit: false,
list: false
},
HTETypeID: {
title: 'Tipo',
list: true,
edit: false,
create: true,
options: '#Url.Action("GetHTETypeOptions","HTE")'
},
LineID: {
title: 'Línea de Producción',
//width: '35%',
list: true,
options: '#Url.Action("GetProductionLinesOptions","MasterData")'
},
AreaId: {
title: 'Area',
dependsOn: 'LineID', // jTable builds cascade dropdowns!
//width: '35%',
list: true,
options: function (data) {
if (data.source == 'list') {
//Return url of all countries for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/MasterData/GetAreasOptionsByProductionLineID?productionLineId=0';
}
//This code runs when user opens edit/create form or changes continental combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/MasterData/GetAreasOptionsByProductionLineID?productionLineId=' + data.dependedValues.LineID;
}
},
OperationID: {
title: 'Operación',
dependsOn: 'AreaId', // jTable builds cascade dropdowns!
//width: '35%',
list: true,
options: function (data) {
if (data.source == 'list') {
//Return url of all countries for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/MasterData/GetOperationOptionsByAreaID?areaId=0';
}
//This code runs when user opens edit/create form or changes continental combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/MasterData/GetOperationOptionsByAreaID?areaId=' + data.dependedValues.AreaId;
}
},
ModelID: {
title: 'Modelo',
dependsOn: 'LineID', // jTable builds cascade dropdowns!
//width: '35%',
list: true,
options: function (data) {
if (data.source == 'list') {
//Return url of all countries for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/MasterData/GetModelOptionsByProductionLine?productionLineId=0';
}
//This code runs when user opens edit/create form or changes continental combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/MasterData/GetModelOptionsByProductionLine?productionLineId=' + data.dependedValues.LineID;
}
},
OperationAvailableTime: {
title: 'Tiempo disponible',
//width: '35%',
list: true,
edit: false,
create: false
} ,
Effiency: {
title: 'Effciencia',
//width: '35%',
list: true
} ,
RevisionNumber: {
title: '# Revisión',
//width: '35%',
list: true,
edit: false,
create: false,
defaultValue: '0'
},
RevisionDate: {
title: 'Fecha Revisión',
//width: '15%',
type: 'date',
list: true,
edit: false,
create: false,
displayFormat: 'yy-mm-dd'
},
ProductionRate: {
title: 'Producción Diaria',
//width: '35%',
list: true
},
Taktime: {
title: 'Taktime',
//width: '35%',
list: true
},
RequiredHeadCount: {
title: 'Head Count',
//width: '35%',
list: true
},
HTEStatus: {
title: 'Status',
//width: '35%',
list: true,
edit: false,
create: false,
options: '#Url.Action("GetHTEStatusOptions","HTE")'
},
Active: {
title: 'Activo?',
//width: '12%',
type: 'checkbox',
list: true,
edit: false,
create: false,
values: { 'false': 'No Activo', 'true': 'Activo' },
defaultValue: 'true'
},
Overspeed: {
title: 'OverSpeed',
create: true,
edit: true,
list: true
//, defaultValue: #Html.Raw(Json.Encode(ViewBag.OverSpeed))
},
CustomActionAdmin: {
title: '',
//width: '1%',
sorting: false,
create: false,
edit: false,
list: true,
display: function (data) {
if (data.record) {
return '<button title="" id="btnAdmin" class="jtable-command-button glyphicon glyphicon-cog" onclick="transferAdmin(' + data.record.HTEHeaderId + '); return false;"></button>';
}
}
},
CustomActionActivities: {
title: '',
//width: '1%',
sorting: false,
create: false,
edit: false,
list: true,
display: function (data) {
if (data.record) {
return '<button title="" id="btnAdmin" class="jtable-command-button glyphicon glyphicon-wrench" onclick="transferHTEDetails(' + data.record.HTEHeaderId + '); return false;"></button>';
}
}
}
}
});
//Re-load records when user click 'load records' button.
$('#LoadRecordsButton').click(function (e) {
e.preventDefault();
$('#HTEContainer').jtable('load', {
ProductionLineName: $('#ProductionLineName').val(),
AreaName: $('#AreaName').val(),
OperationName: $('#OperationName').val(),
ModelName: $('#ModelName').val(),
HTETypeName: $('#HTETypeName').val()
});
});
//Load all records when page is first shown
$('#LoadRecordsButton').click();
$('#GoBack').click(function (e) {
e.preventDefault();
window.location.replace("/HTE");
});
});
function transferAdmin(hteHeaderId) {
window.location.replace("/HTE/AdminSettings/" + hteHeaderId);
};
function transferHTEDetails(hteHeaderId) {
window.location.replace("/HTE/HTEActivitiesList/?HTEHeaderId=" + hteHeaderId);
};
</script>
<br />
#section scripts {
}
Now, this is the code for the _Layout.cshtml in use:
<!DOCTYPE html>
#{
var jTableStyle = "metro/blue/jtable.css";
if (!string.IsNullOrEmpty(Request["jTableStyle"]))
{
jTableStyle = Request["jTableStyle"];
}
}
<html lang="es-mx">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Super Sistema Balanceo de Líneas - #ViewBag.Title - </title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/metroblue/jquery-ui.css")" rel="stylesheet" type="text/css" />
#*<link href="#Url.Content("~/Content/highlight.css")" rel="stylesheet" type="text/css" />*#
<link href="#Url.Content("~/Scripts/jtable/themes/" + jTableStyle)" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Scripts/syntaxhighligher/styles/shCore.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Scripts/syntaxhighligher/styles/shThemeDefault.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/core.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/datepicker.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/theme.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/bootstrap-theme.min.css")" rel="stylesheet" type="text/css" />
#RenderSection("CssImport", false)
<script src="#Url.Content("~/Scripts/jquery-3.0.0.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-migrate-3.0.0.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.12.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui.unobtrusive-3.0.0.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.date.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#* <script src="#Url.Content("~/Scripts/jquery.validate-vsdoc.js")" type="text/javascript"></script>*#
<script src="#Url.Content("~/Scripts/modernizr-2.8.3.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shCore.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushJScript.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushXml.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushCSharp.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushSql.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/bootstrap.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/moment.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/respond.min.js")" type="text/javascript"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jtable/jquery.jtable.js")"></script>
<script src="#Url.Content("~/Scripts/jtablesite.js")" type="text/javascript"></script>
</head>
<body>
#Html.Partial("_NavBar")
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - Super Sistema Balanceo de Líneas</p>
</footer>
</div>
#RenderSection("scripts", required: false)
#RenderSection("CustomScripts", required: false)
</body>
</html>
This is a picture of system in Internet Explorer, displayed as expected:
page displayed in Internet Explorer
You can see the rendering is as expected, not issue on this area with Internet Explorer.
Red arrows indicates the buttons created as Custom Action, once pressed up, nothings happens. When the IE developer tools are displayed, I press the buttons indicated with Read arrows, nothing happens: not even an error in console, not even an error in Network tab, nothing at all. This is error I'm having.
Green arrows indicates the buttons created by jTable for EDIT, CREATE and DELETE actions as part of the grid. These buttons are working perfect. No issue on this area. See these pictures:
Page in IE showing modal for New record
Page in IE showing modal for Edit record
I hopes you guys can provide any idea.
Thanks,
Gerardo.
This a complex senario, so I cannot replicate it.
I observe from your code, that you are adding click handlers via javascript in the button definitions. Have you tried applying the click handler via jQuery
display: function (data) {
var $but = '';
if (data.record) {
$but = $('<button title="" class="jtable-command-button glyphicon glyphicon-cog" ></button>');
$but.click(transferAdmin(data.record.HTEHeaderId));
}
return $but;
}
I would also point out your original code was creating a button using the same id btnAdmin on every row of the table which is neither good practice or useful, so I have omitted that, as it is possibly another reason why IE gets confused.
Thanks #misterP for his reply. After having bad times with this, I managed to understand what was wrong, and fixed it.
Let me try to explain fixes to issue I was having.
1) Main problem was that in IE, my jQuery logic was not working, when it worked in Firefox and Chrome. I was not aware of IE compatilibity modes that are fixed with the meta tag at level. So, on file _layout.chtml, I set the following:
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
...
2) Regarding how I managed the functionality on the custom action, I read online that when working with jQuery targeting dynamic elements, we should start the filtering against a fixed tag --- hence I used ContainerForJTable. I declare a custom attribute seleccionable on the dynamic object:
display: function (data) {
if (data.record) {
return '<button id="' + data.record.FileID + '" class="jtable-command-button glyphicon glyphicon-eye-open seleccionable"></button>';
}
}
3) I wrote a function (outside of the jtable object creation --- $('#ContainerForJTable').jtable({..) to add an event to objects matching a filter using my custom attribute:
$('#ContainerForJTable').on('click', '.seleccionable', function () {
var theID = $(this).attr("id");
//console.log("The id is " + theID);
viewFiles(theID);
});
After these changes, the jtables objects had been working without any issues.
thanks,

Edit master column Title in kendo grid on clicking column headers in detailInit

Following is a kendo grid sample with detailInit:
My requirement is that on sorting a column in a particular sub-grid(detailInit), its header i.e. FirstName field should be changed like shown below:
Just that particular sub-grid's header should be changed. I have tried by registering onclick event in databound function of detailInit but unable to find the column header and change it :
$("th[role='columnheader']").on("click", function (ev) {
// access clicked column in sub- grid
// change master row's title
};
Please someone suggest me a solution as I am new to kendo grid, js, HTML, so not aware of many functions.
Any help would be much appreciated.
Please find my code below :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.rtl.min.css" />
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.silver.min.css" />
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.mobile.all.min.css" />
<script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.3.1028/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script>
var element = $("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Employees"
},
pageSize: 6,
serverPaging: true,
serverSorting: true
},
height: 450,
sortable: true,
pageable: true,
detailInit: detailInit,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "FirstName",
title: " "
}
]
}).on("click", ".btn-refresh", function (e) {
debugger;
var childGrid = $(e.target).closest(".k-grid").data("kendoGrid");
childGrid.dataSource.read();
});
function detailInit(e) {
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 6,
filter: { field: "EmployeeID", operator: "eq", value: e.data.EmployeeID }
},
scrollable: false,
sortable: true,
pageable: true,
toolbar: [{ text: "Refresh", className: "btn-refresh" }],
columns: [
{ field: "OrderID", width: 70 },
{ field: "ShipCountry", title: "Ship Country", width: 100 },
{ field: "ShipAddress", title: "Ship Address" },
{
field: "ShipName", title: "Ship Name", width: 200
}
]
});
}
</script>
</body>
</html>
There are, at least, two main ways to do this. However, I didn't understand if you want to:
a) Clear all the "updated" texts, letting only the last clicked with it
b) Keep all them tracked, putting the text as the user sorts the grids
Anyway, let's see both strategies.
Using jQuery only
a)
element.on('click', "th[role='columnheader']", function(e) {
// always remove all, to put again in the right place
$("strong[attr-id=updated]").remove();
var firstNameCell = $(this)
.closest("tr.k-detail-row") // Finds the closest detail row ...
.prev("tr.k-master-row") // ... in order to get the first previous row of class "k-master-row" (which stores the FirstName)
.find("td[role='gridcell']"); // and, then, get the td gridcell
firstNameCell.append("<strong attr-id='updated'> - Address updated</strong>");
});
b)
element.on('click', "th[role='columnheader']", function(e) {
var firstNameCell = $(this)
.closest("tr.k-detail-row")
.prev("tr.k-master-row")
.find("td[role='gridcell']");
// Check if the msg already exits, to not duplicate it
if (!(firstNameCell).find('strong[attr-id=updated]').length) {
firstNameCell.append("<strong attr-id='updated'> - Address updated</strong>");
}
});
The attr-id helps to identify the text element along the page, once it's not a good practice using id (only once per page).
Using KendoUI JavaScript objects
That's not the best way, since you cannot append HTML like we did with jQuery approach. Also, you'll have to refresh the whole table every time a sort is made.
That's why I'll show only case b)
element.on('click', "th[role='columnheader']", function(e) {
var masterRow = $(this)
.closest("tr.k-detail-row")
.prev("tr.k-master-row"); // Finds the closest master row ...
var rowIndex = $("tr.k-master-row").index(masterRow); // ... gets the index of it among all the others
kendoGrid = element.data('kendoGrid');
var firstName = kendoGrid.dataSource._data[rowIndex].FirstName; // gets current name based on the index
if (!firstName.includes('Address updated')) {
selectedCell = rowIndex; // sets the index to be used when grid refreshes
kendoGrid.dataSource._data[rowIndex].FirstName = firstName + " - Address updated";
kendoGrid.refresh(); // refreshed the whole grid
}
});
Still, in order to make KendoUI to expand the right row every time its grids are refreshed, you have to create the global variable selectedCell and check at dataBound function whether it has a value or not:
dataBound: function () {
if (selectedCell) {
this.expandRow(this.tbody.find("tr.k-master-row:eq(" + selectedCell + ")"));
} else {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
},
Here, you can see more about Kendo Grid refreshing: Reloading/refreshing Kendo Grid
Hope it helps! :)

jqGrid custom editfunc doesn't work when custom search parameters are specified

Version jqGrid used here:
#license Guriddo jqGrid JS - v5.2.0 - 2016-11-27 Copyright(c) 2008, Tony Tomov, tony#trirand.com
The first block of code below is an entire self contained implementation of jqGrid. It is in fact mostly taken from one of the examples on the jqGrid site. In it I added a snippet, the part between the comment lines with the clip markings.
That added snipped adds a custom editfunc. It works nicely (in the example it is of course more or less a stub, only doing an alert). Also, searching works, with all of its default parameters. For both, select a row and click on the respective icon of Edit or Search.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- The jQuery library is a prerequisite for all jqSuite products -->
<script type="text/ecmascript" src="./lib/jquery/jquery.min.js"></script>
<!-- This is the Javascript file of jqGrid -->
<script type="text/ecmascript" src="./lib/jqGrid-js-free/js/jquery.jqGrid.js"></script>
<!-- This is the localization file of the grid controlling messages, labels, etc.-->
<!-- We support more than 40 localizations -->
<script type="text/ecmascript" src="./lib/jqGrid-js-free/js/i18n/grid.locale-en.js"></script>
<!-- A link to a jQuery UI ThemeRoller theme, more than 22 built-in and many more custom -->
<link rel="stylesheet" type="text/css" media="screen" href="./lib/jquery-ui/jquery-ui.css" />
<!-- The link to the CSS that the grid needs -->
<link rel="stylesheet" type="text/css" media="screen" href="./lib/jqGrid-js-free/css/ui.jqgrid.css" />
<meta charset="utf-8" />
<title>jqGrid without PHP - Loading Data - JSON Live</title>
</head>
<body>
<table id="jqGrid"></table>
<div id="jqGridPager"></div>
<script type="text/javascript">
$(document).ready(function () {
$("#jqGrid").jqGrid({
colModel: [
{
label: 'Title',
name: 'Title',
width: 150,
formatter: formatTitle
},
{
label: 'Link',
name: 'Link',
width: 80,
formatter: formatLink
},
{
label: 'View Count',
name: 'ViewCount',
width: 35,
sorttype:'integer',
formatter: 'number',
align: 'right'
},
{
label: 'Answer Count',
name: 'AnswerCount',
width: 25
}
],
viewrecords: true, // show the current page, data rang and total records on the toolbar
width: 780,
height: 200,
rowNum: 15,
datatype: 'local',
pager: "#jqGridPager",
caption: "Load live data from stackoverflow"
});
fetchGridData();
function fetchGridData() {
var gridArrayData = [];
// show loading message
$("#jqGrid")[0].grid.beginReq();
$.ajax({
url: "http://api.stackexchange.com/2.2/questions?order=desc&sort=activity&tagged=jqgrid&site=stackoverflow",
success: function (result) {
for (var i = 0; i < result.items.length; i++) {
var item = result.items[i];
gridArrayData.push({
Title: item.title,
Link: item.link,
CreationDate: item.creation_date,
ViewCount: item.view_count,
AnswerCount: item.answer_count
});
}
// set the new data
$("#jqGrid").jqGrid('setGridParam', { data: gridArrayData});
// hide the show message
$("#jqGrid")[0].grid.endReq();
// refresh the grid
$("#jqGrid").trigger('reloadGrid');
}
});
}
function formatTitle(cellValue, options, rowObject) {
return cellValue.substring(0, 50) + "...";
};
function formatLink(cellValue, options, rowObject) {
return "<a href='" + cellValue + "'>" + cellValue.substring(0, 25) + "..." + "</a>";
};
/*---- 8< ------*/
// editfunc here works (an alert is popped up), although the format of the function parameters is not according to spec:
// searchfunc also works (it is the default)
$('#jqGrid').jqGrid( 'navGrid', '#jqGridPager',{
add:false, del:false, view:false,
editfunc: function(){alert('EDIT');}
});
/*---- >8 ------*/
});
</script>
</body>
</html>
Now take the same file, remove the small snippet between the snip lines, and replace it with the following snippet, that looks more like something I need to implement:
/*---- 8< ------*/
// editfunc does NOT work as desired here (no alert)
// search function works, WITH the parameters as specified here
// from the file jquery.jqGrid.js (): navGrid : function parameters: (elem, p, pEdit, pAdd, pDel, pSearch, pView)
// (=jqGrid-free #license Guriddo jqGrid JS - v5.2.0 - 2016-11-27 Copyright(c) 2008, Tony Tomov, tony#trirand.com)
$('#jqGrid').jqGrid( 'navGrid', '#jqGridPager',
{ add:false, del:false, view:false }, // p
{ editfunc: function(r){alert('EDIT');} }, // pEdit (does NOT work)
{ }, // pAdd
{ }, // pDel
{ multipleSearch: true, closeAfterSearch:true, closeOnEscape:true, searchOnEnter:true, showQuery:true }, // pSearch (works with these options)
{ } // pView
);
/*---- >8 ------*/
Here, alas the editfunc does not work at all, I get the default edit function. Search now works though, as desired with the custom specified parameters.
In short: I cannot seem to get both a customized editfunc and search with custom parameters working!
I cannot see anything wrong with the second snippet. It is btw. also per some examples on the jqGrid wiki.
Any hints to get both working together would be appreciated.
The problem is very easy: you placed editfunc in the wrong place in your last snippet. The editfunc should be specified as the property of the second parameter of navGrid (together with add:false, del:false, view:false). You used the editfunc correctly in the first part of your code, but you placed it in the second part of the code on the wrong place. You can fix your code by usage
$('#jqGrid').jqGrid( 'navGrid', '#jqGridPager',
{ add:false, del:false, view:false, editfunc: function(r){alert('EDIT');} }, // p
{ }, // pEdit
{ }, // pAdd
{ }, // pDel
{ multipleSearch: true, closeAfterSearch:true, closeOnEscape:true,
searchOnEnter:true, showQuery:true }, // pSearch (works with these options)
{ } // pView
);
By the way, you placed the code of commercial product Guriddo jqGrid JS in the directory jqGrid-js-free, which sounds strange. Guriddo jqGrid JS can't be used for free. You can see the current prices here. I started development of free jqGrid fork of jqGrid, which can be used completely free of charge, exactly because of that. Free jqGrid implemented many new features, which can be helpful for you. The demo https://jsfiddle.net/OlegKi/odvxefra/3/ is a small modification of your code, which displays
I used additionally
url: "https://api.stackexchange.com/2.2/questions",
// add sending of custom parameters to the URL
postData: {
order: "desc",
sort: "activity",
tagged: "jqgrid",
site: "stackoverflow"
},
datatype: "json",
// below prmNames remove sending all standard jqGrid paranmeters
prmNames: {
page: null,
rows: null,
sort: null,
order: null,
search: null,
nd: null,
id: "question_id"
},
jsonReader: {
root: "items",
repeatitems: false,
id: "question_id"
},
loadonce: true,
forceClientSorting: true,
sortname: "creation_date",
sortorder: "desc"
The data will be loaded from the same URL "http://api.stackexchange.com/2.2/questions?order=desc&sort=activity&tagged=jqgrid&site=stackoverflow", sorted locally by creation_date property in the desc order and displayed in the grid. One can use other properties in the custom formatter by adding the properties in additionalProperties. For example you can add additionalProperties: ["owner", "is_answered", "score", "last_activity_date"] to save the properties locally and to have access to the properties inside of, for example, custom formatter.

load jqGrid on button click but it fails on second time

I'm using jqGrid to display data from database. There are 2 textboxes to input the criteria. After inputting the criteria and clicking the Show button, jqGrid is shown to the page.
The second time I clicked the Show button with a different set of criteria entered nothing happens. It still shows data from the first click. How do I solve this?
View:
#section styles {
<link href="~/Content/themes/redmond/jquery-ui.css" rel="stylesheet" />
<link href="~/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" />
}
<h2>Index</h2>
<p class="form-inline">
Ext: <input type="text" class="form-control" id="extUsed" />
Date: <input type="text" class="form-control" id="startOfCall" readonly="readonly" />
<button class="btn btn-primary" id="btnShow">Show</button>
</p>
<table id="grid"></table>
<div id="pager"></div>
#section scripts {
<script src="~/Scripts/i18n/grid.locale-en.js"></script>
<script src="~/Scripts/jquery.jqGrid.min.js"></script>
<script>
var firstClick = true;
$(function () {
$("#startOfCall").datepicker();
$("#btnShow").click(function (e) {
e.preventDefault();
if (!firstClick) {
$("#grid").trigger("reloadGrid");
} else {
$("#grid").jqGrid({
mtype: "GET",
url: "#Url.Content("~/CallTransaction/GetCallTransactionList")",
datatype: "json",
colNames: ["Ext Used", "Start of Call", "Destination Number"],
colModel: [
{ name: "ExtUsed", index: "ExtUsed" },
{ name: "StartOfCall", index: "StartOfCall", formatter: "date", formatoptions: { srcformat: 'd/m/Y', newformat: 'd/m/Y' } },
{ name: "DestinationNumber", index: "DestinationNumber" }
],
postData: {
"CallTransaction.ExtUsed": $("#extUsed").val(),
"CallTransaction.StartOfCall": $("#startOfCall").val()
},
pager: jQuery("#pager"),
rowNum: 10,
rowList: [10, 25, 50],
height: "100%",
caption: "Call Transaction",
autowidth: true,
//sortname: "ExtUsed",
sortable: true,
viewrecords: true,
emptyrecords: "No records to display",
});
$("#grid").jqGrid('navGrid', '#pager', { edit: false, add: false, del: false, search: false });
}
firstClick = false;
});
});
</script>
}
Controller:
public JsonResult GetCallTransactionList(CallTransaction callTransaction, string sidx, string sord, int page, int rows)
{
int pageIndex = page - 1;
int pageSize = rows;
var callTransactionResult = db.Search(callTransaction);
int totalRecords = callTransactionResult.Count();
var totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
if (sord.ToUpper() == "DESC")
{
callTransactionResult = callTransactionResult.OrderByDescending(ct => ct.ExtUsed).ToList();
callTransactionResult = callTransactionResult.Skip(pageIndex * pageSize).Take(pageSize).ToList();
}
else
{
callTransactionResult = callTransactionResult.OrderBy(ct => ct.ExtUsed).ToList();
callTransactionResult = callTransactionResult.Skip(pageIndex * pageSize).Take(pageSize).ToList();
}
var jsonData = new
{
total = totalPages,
page,
records = totalRecords,
rows = callTransactionResult
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
It's important to understand that the current code set one value of postData during creating the grid. The value of postData parameter will be object with properties evaluated at the moment of creating of the grid.
To fix the code you need use function as the value of postData properties:
postData: {
"CallTransaction.ExtUsed": function () { return $("#extUsed").val(); },
"CallTransaction.StartOfCall": function () { return $("#startOfCall").val(); }
}
See the answer for more details. For understanding: jqGrid uses jQuery.ajax internally and jQuery.ajax uses jQuery.param helper function to process the data parameter (construction using postData) and jQuery.param execute functions if it is the properties of data (postData).
Additionally I would strictly recommend you to use gridview: true option in all your grids (see the answer), add autoencode: true to interpret the input data as the data instead of HTML fragments (it's the default behavior) and to use pager: "#pager" instead of pager: jQuery("#pager").
I recommend you to remove all index properties from colModel and to consider to include additional id property in the data returned from the server with an unique values which come from the database. If some column of the grid already contains the unique value you can add key: true property to the definition of the corresponding column. The reason of such changes is easy to understand if you know that jqGrid have to assign id attribute to every row of grid. The value of id attribute must be unique. The value, used as rowid in the documentation, will be used in the most callbacks of jqGrid to identify the row. The same value will be send to the server if you will implement editing of data later. If you don't specify any rowid in the input data jqGrid have to assign some other value to id. The default value will be 1,2,3... On the other side if you load the data from the database you have native ids of the rows. The usage of the native ids can "simplify your live" in the future.

First extjs example doesn't work

I'm want to learn extjs so I'm a newbie, so sorry for any stupid question here..
Here is my index.html page :
<html>
<head>
<meta charset="UTF-8">
<title>Test Hello</title>
<script type="text/javascript" src="extjs-4.2.1-gpl/ext-all.js"></script>
<script type="text/javascript" src="extjs-4.2.1-gpl/ux/form/LoginForm.js"></script>
<!-- <link href="extjs-4.1.1a/KitchenSink-all.css" rel="stylesheet" type="text/css" /> -->
<link href="extjs-4.2.1-gpl/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div align="center" id= "content" >
<script type="text/javascript">
var loginForm = Ext.create("test.view.form.LoginForm", {
id : "panellogin",
renderTo : 'content'
});
</script>
</div>
</body>
</html>
And LoginForm :
Ext.define('test.view.form.LoginForm', {
extend: 'Ext.form.Panel',
xtype : "test.view.form.LoginForm",
title: 'Login',
frame:true,
width: 320,
bodyPadding: 20,
defaultType: 'textfield',
defaults: {
anchor: '100%'
},
initComponent: function() {
var me = this;
me.items = [me.contentPanel];
me.contentPanel = Ext.create("Ext.grid.Panel", {
border: true,
align :"center",
layout: {
type: "hbox",
align: "center"
},
items: [
{
allowBlank: false,
fieldLabel: 'User ID',
name: 'user',
emptyText: 'user id'
},
{
allowBlank: false,
fieldLabel: 'Password',
name: 'pass',
emptyText: 'password',
inputType: 'password'
},
{
xtype:'checkbox',
fieldLabel: 'Remember me',
name: 'remember'
}
]
});
}
});
What did I exactly is:
Downloaded extjs 4.2.1-gpl from sencha website (about 65 Mo compressed)
When I found the huge size I delete things like examples, docs
Moved src inside a directory named ux inside 4.2.1-gpl directory
Kept resources, images and locale folders.
I need advice please, is this a good way to do? I can't put the whole content since it is more than 300 Mio! What to keep, please?
Firebug is showing me this error : TypeError: c is undefined (in ext-all.js line 21)
Google chrome is showing this : Uncaught TypeError: Cannot read property 'length' of undefined
Kind regards,
Could you please tell what's happen
Execute your code after the extjs sources are loaded (Ext.onReady...):
Ext.onReady(function () {
var loginForm = Ext.create("test.view.form.LoginForm", {
id : "panellogin",
renderTo : 'content'
});
});
This is not like you should have done. Especially deleting stuff and renaming src to ux. Also a class definition of test.view.form.LoginForm should be in the file app/view/form/LoginForm.js, not ux/form.
Read the doc how to get started, especially MVC Application Architecture and the App Architecture Series.

Categories

Resources