Reputation: 22652
I tried to add a button inside a jqGrid column, with an icon – but it is coming as undefined
. What is the correct way to do this?
CODE
colModel: [
{ name: 'RoleID', index: 'RoleID', width: 100 },
{ name: 'RoleName', index: 'RoleName', width: 250 },
{ name: 'RoleRequestedDate', index: 'RoleRequestedDate', formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' }, width: 125 },
{ name: 'RoleApprovedDate', index: 'RoleApprovedDate', formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' }, width: 125 },
{
name: 'Request', index: 'RoleID', width: 120,
formatter: function (cellvalue, options, rowObject) {
//return '<span class="ui-icon ui-icon-circle-plus app-custom-button-create" title="Create";"></span>';
if (rowObject["UserRoleID"] == "0") {
if (rowObject["RoleRequestID"] == "0") {
//return '<span class="ui-icon ui-icon-circle-plus app-custom-button-request" title="Request";"></span>';
//return '<button id="btnRequest" class="ui-icon ui-icon-circle-plus app-custom-button-request" type="submit" return false;>Request</button>';
return
'<button class="ui-button ui-widget ui-state-default">' +
'<span class="ui-button-icon-primary ui-icon ui-icon-star">Request</span>' +
'</button>';
}
else {
return '<span class="ui-icon ui-icon-folder-collapsed" title="Already Requested";"></span>';
}
}
else {
return '<span class="ui-icon ui-icon-check" title="Has Role";"></span>';
}
}
}
],
Upvotes: 0
Views: 1408
Reputation: 221997
It looks that your main computer language is C# and you try to use JavaScript in the same style like you write your C# program. It's an important error! You create in the way the code which looks correct, but it works in the wrong way. I developed many years before the code in C/C++/C# and many other non-C-like languages. So I did the same errors like you. Only after understanding that JavaScript have absolutely another semantic I changed my style for JavaScript programs and all become good.
Back to your code. You wrote the statement
return
'<button class="ui-button ui-widget ui-state-default">' +
'<span class="ui-button-icon-primary ui-icon ui-icon-star">Request</span>' +
'</button>';
which looks correctly, and it would be correctly in C#, but it will be interpreted as the following in JavaScript:
return;
'<button class="ui-button ui-widget ui-state-default">' +
'<span class="ui-button-icon-primary ui-icon ui-icon-star">Request</span>' +
'</button>';
So you have two statements because of auto-inserting of semicolon. The first line return undefined
and the second like will be never executed at all and it will be removed it you would minimize your JavaScript code.
I strictly recommend you to use the following simple rule: if you need to continue the statement on another line you should end the line with the part of the symbol like +
or {
or any other which can't be as the last symbol of the statement. You should not know exactly all rules of auto-inserting of semicolon. The rules will be never works in the case at all.
In your case you need just write
return '<button class="ui-button ui-widget ui-state-default">' +
'<span class="ui-button-icon-primary ui-icon ui-icon-star">Request</span>' +
'</button>';
By the way I personally prefer to use "
in strings and use '
inside of string. The rule is a little better because the same rule hold the most JavaScript frameworks/libraries.
The next example from your code: you use the line
if (rowObject["UserRoleID"] == "0") {
...
The main problem here is the usage of equality operator ==
, typical for C#, instead of strict equality operator ===
which is strictly recommended to use in JavaScript. The problem is that the code which use ==
looks not like it do in reality. JavaScript uses type conversion in case of ==
usage which can produce very strange effects. For example 0 == "0"
is true
and false == "0"
is true. It's not what one want in the most cases. The classical example which shows how dangerous is the operator ==
: 0 == ''
is true
and 0 == '0'
is true
, but '' == '0'
is of cause false
. So the usage of ==
can easy break the main mathematical rules.
More simple and non-critical changes which I recommend you to do is the usage of rowObject.UserRoleID
instead of rowObject["UserRoleID"]
. You should use ["..."]
syntax only with variables or if you use the properties which contains either special characters like rowObject["User.Role.ID"]
or rowObject["User Role ID"]
or it the property name is reserved word in some JavaScript dialect like rowObject["class"]
or rowObject["if"]
.
The next remark: you should verify the quotes ("
) in the strings '... title="Has Role";"></span>'
and '... title="Already Requested";"></span>';
. The part ;"
should be probebly removed.
Finally, small remarks specific for jqGrid. First of all I recommend you to remove unneeded index
property from colModel
. You will have the same results after removing of index
, but your code will be shorter and easy to read. The next advice: you should consider to add key: true
to the column RoleID
if it contains unique values. It informs jqGrid to use the values as rowids (the values for id
attribute of <tr>
elements).
The last remark: you should confider to use column templates. In simplest form you can define the object
var myDateTemplate = { formatter: 'date',
formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' }, width: 125 };
somewhere above the code which creates jqGrid and to define RoleRequestedDate
and RoleApprovedDate
as the following
{ name: 'RoleRequestedDate', template: myDateTemplate },
{ name: 'RoleApprovedDate', template: myDateTemplate },
It reduces your code, makes it more readable and easy to maintain. See here or here for more information about column templates.
Upvotes: 1