I've got a table in my page wrapped up in Datatables. The data is being grabbed from a php file perfectly and there is no problem with the code in that part. However, I've got a problem with buttons inside the table.
The followings are the columns inside my Datatables table:
columns: [
{"data": "id"},
{"data": "name"},
{data: null, render: function(data, type, row) {
return '<span class="fa fa-pen"></span>'
}},
],
As you can see, I have defined three columns, the first of which is 'id', the second 'name' and the third a column including a button. My problem is related to this button. In fact, I want to call a function, for instance, edit(), whenever this button is clicked. The edit() function gets the value of 'name' (second column) as its parameter. Now the question is this: how can I pass the value of the second column to the function edit() when the button is clicked;
as a result, the onClick call of the third column shall be something like this: onclick="edit(name.val)"... I have left this onClick="" empty, because I don't know how to do this.
Millions of thanks in advance.
After dealing with the problem for a couple of hours, I came to know that with a simple javascript concatenation, the problem could be solved.
Previously, the block was like the following:
<span class="fa fa-pen"></span>
and I had problems with onclick call where I could not pass a parameter for the functions.
To solve the problem, I changed the block a little bit and used concatentation, and voila, the problem was gone.
This should turn into
return '<span class="fa fa-times-circle"></span>'
Here is a working example. It uses the data function described on this page. The relevant part is this:
{ "data": function ( row, type, val, meta ) {
return "the data in column 1 is '" + row[0] + "'";
}
}
In the three-column table (below), the third column is populated based on data from the first column.
Here is the full sample - you should be able to adapt this technique to your situation:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Animals</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>
<body>
<div style="margin: 20px;">
<table id="animals" class="display dataTable cell-border" style="width:100%">
<thead>
<tr><th>Animal</th><th>Collective Noun</th><th>Customized Data</th></tr>
</thead>
<tbody>
<tr><td>antelopes</td><td>herd</td><td></td></tr>
<tr><td>elephants</td><td>herd</td><td></td></tr>
<tr><td>hounds</td><td>pack</td><td></td></tr>
<tr><td>kittens</td><td>kindle</td><td></td></tr>
<tr><td>lions</td><td>pride</td><td></td></tr>
<tr><td>ravens</td><td>unkindness</td><td></td></tr>
<tr><td>whales</td><td>pod</td><td></td></tr>
<tr><td>zebras</td><td>herd</td><td></td></tr>
</tbody>
</table>
</div>
<script type="text/javascript">
$(document).ready(function() {
var table = $('#animals').DataTable({
"columns": [
null,
null,
{ "data": function ( row, type, val, meta ) {
//console.log(row);
//console.log(type);
//console.log(val);
//console.log(meta);
return "the data in column 1 is '" + row[0] + "'";
}
}
]
});
});
</script>
</body>
The (commented-out) console logging statements are there so you can take a closer look at how the function works, if you wish.
make use the edit method is placed outside jquery initiation in golobal level
function edit(){
//content
}
jQuery(document).ready(function() {
//data-tables script here
}
Related
let's say I have a very simple setup using data() and a function written in the methods part. With the function I'm returning a random number between 1 and 3, while the data contains an list of blog elements.
When displaying the result from randomNumber directly on the page using <p>{{randomNumber()}}</p> the value (1-3) get's printed. In my case I'm printing all posts from blogs using v-for on the parent div.
When however, trying to alter a css class with said number the number does not get printed. For this particular test I have made .g1, .g2 and .g3 with different style attributes. When inspecting the source code directly in the browser the .blog-thumb class has g{{randomNumber()}} as a second class.
i tried to call randomNumber() within the blogs item but I'm still unable to add the generated class to the css class section.
Thank you for your help or suggestions.
HTML:
<div class="col" v-for="blog in blogs" :key="blog.id">
<div class="blog-thumb g{{randomNumber()}}"> <!-- DOES NOT GET PRINTED -->
{{randomNumber()}} <!-- GETS PRINTED -->
<p class="date">{{ blog.date }}</p>
</div>
<h2>{{blog.title}}</h2>
<p>{{blog.content}}</p>
</div>
Vue:
methods : {
randomNumber : function(){
return Math.floor(Math.random() * 3+1);
}
},
data() {
return{
blogs: [
{
id: '1',
title: 'Amet consectetur adipisicing',
date: 'March 3rd 2022',
content: 'Lorem ipsum...'
},
{...}
]
}
}
after fiddling with it for quite a while today I found this solution:
I changed the function to return a complete classname (in this case, g with a random number between 1 and 3)
randomNumber : function(){
return 'g' + Math.floor(Math.random() * 3+1);
}
in the html part I added the v-bind to the class and passed the function (v-bind:class="randomNumber()")
<div class="col" v-for="blog in blogs" :key="blog.id">
<div class="blog-thumb" v-bind:class="randomNumber()">
<p class="date">{{ blog.date }}</p>
</div>
<h2>{{blog.title}}</h2>
<p>{{blog.content}}</p>
</div>
with this, now every col blog-thumb class got another generated class added to it.
I have two vue properties firstName and lastName. Let's say the value of these properties are Tim and Smith. When I display them as a complete name, I display these properties and include a space between them if they both contain values. However, Vue omits the space in the output and displays TimSmith. But if I change to code to output a comma space if both properties have values then it properly ouputs Tim, Smith. Feels like a bug. Can anyone explain how to achieve my goal with Vue of only including a space between the two properties if they both contain values and explain why I'm seeing what I am?
<html>
<head>
</head>
<body>
<div id="appTemplate">
{{firstName}}<template v-if="firstName!='' && lastName!=''"> </template>{{lastName}}<br />
{{firstName}}<span v-if="firstName!='' && lastName!=''"> </span>{{lastName}}<br />
{{firstName}}<template v-if="firstName!='' && lastName!=''">, </template>{{lastName}}<br />
{{firstName}} {{lastName}}<br />
</div>
<script src="https://unpkg.com/vue#2.2.5/dist/vue.min.js"></script>
<script type="text/javascript">
var app = new Vue({
el: '#appTemplate',
data: {
firstName: "Tim",
lastName: "Smith"
}
});
</script>
</body>
</html>
The above code produces the output below. Why isn't there a space between Tim and Smith in the first two lines?
You should use symbol as space.
Also as a one of ways to get the same result
{{(firstName + ' ' + lastName).trim()}}
I'm trying to create a grid from json data. Each cell will be editable eventually. One column contains type dependant data and based on the type I want to show either a pair of date pickers (start/end date) or Textarea or some other widget.
I'm using renderCell to attempt to render this type dependent column, but whenever I introduce Textarea to my code I get an error "TypeError: subRows is undefined" & just can't seem to shake it.
I'm quite new to dojo so I think I'm missing something obvious. I've read all the docs and in particular this post which didn't help in my case. Unfortunately many of the docs are slices of code & whatever it is I'm not getting means those code slices are too short to get started with.
Can someone help me out. Textarea is the one I'd like to solve as that seems simple & I've not attempted to configure the DateTextBox properly yet anyway. I figure get the Textarea working & that will explain the rest...
My code is below - whole page posted in case my error is missing a file somewhere;
<html>
<head>
<meta charset="utf-8">
<title>Role assignment</title>
<link rel="stylesheet" href="/library/js/dojo/dojo/resources/dojo.css">
<link rel="stylesheet" href="/library/js/dojo/dgrid/css/dgrid.css">
<link rel="stylesheet" href="/library/js/dojo/dgrid/css/skins/claro.css">
<link rel="stylesheet" href="/library/js/dojo/dijit/themes/dijit.css">
<LINK href="/library/css/custom.css" type="text/css" rel="stylesheet">
<LINK href="/favicon.ico" rel="shortcut icon" type="image/x-icon">
<script type="text/javascript" language="javascript" src="/library/js/script_main.js"></script>
</head>
<body class="claro">
<form>
<div id="grid"></div>
</form>
<!-- load Dojo -->
<script src="/library/js/dojo/dojo/dojo.js"></script>
<script>
require([
'dojo/_base/declare',
'dgrid/Grid',
"dgrid/Selection",
"dgrid/editor",
"dgrid/Keyboard",
"dijit/form/Button",
"dijit/form/Textarea",
"dijit/form/DateTextBox",
"dojo/domReady!"
], function (declare, Grid, Selection, editor, Keyboard, Button, Textarea, DateTextBox) {
var renderRoleData = function(object, value, node, options) {
if (object.role_type == "TIME_RANGE") {
return new DateTextBox();
// no attempt to initialise this yet
}
else if (object.role_type == "MULTI_STRING") {
return new Textarea({
name: "myarea",
value: object.role_data.text,
style: "width:200px;"
});
}
//....more types
}
var columns = [
{
field: 'role_name',
label: 'Role name'
},
{
field: 'role_type',
label: 'Role type'
},
{
field: 'role_enabled',
label: 'Role enabled'
},
{
field: 'role_data',
label: 'Role data',
renderCell: renderRoleData
}
];
var grid = new (declare([ Grid, Selection, editor, Keyboard, Textarea, DateTextBox ]))({
columns: columns,
postCreate: function() {
var data = [
{
"role_dn": "some_ldap_dn1,dc=com",
"role_name": "Water Controller",
"role_type": "TIME_RANGE",
"role_enabled" : true,
"role_data" : {"start_date" : "20150601", "end_date" : "20150701"}
}, {
"role_dn": "some_ldap_dn1,dc=com",
"role_name": "Waste Controller",
"role_type": "MULTI_STRING",
"role_enabled" : true,
"role_data" : { "text": "The reason I need this is very long and complicated. The big long reason is just big and long and honestly you wouldn't care if I told you anwyay" }
}
];
this.renderArray(data);
}
}, 'grid');
});
</script>
</body>
</html>
Initially, I notice a few issues which might be causing this problem. Try the following instead:
// Dijit widgets should not be mixed into the grid with declare.
// If you're using 0.3, editor should not be mixed in either,
// intended to be applied to specific columns (in 0.4 this is now a mixin).
// Only dgrid mixins should be mixed in via declare.
var CustomGrid = declare([ Grid, Selection, Keyboard ], {
postCreate: function () {
// Call this.inherited to run any postCreate logic in
// previous mixins first
this.inherited(arguments);
var data = [
{
"role_dn": "some_ldap_dn1,dc=com",
"role_name": "Water Controller",
"role_type": "TIME_RANGE",
"role_enabled" : true,
"role_data" : {"start_date" : "20150601", "end_date" : "20150701"}
}, {
"role_dn": "some_ldap_dn1,dc=com",
"role_name": "Waste Controller",
"role_type": "MULTI_STRING",
"role_enabled" : true,
"role_data" : { "text": "The reason I need this is very long and complicated. The big long reason is just big and long and honestly you wouldn't care if I told you anwyay" }
}
];
this.renderArray(data);
}
});
var grid = new CustomGrid({
columns: columns
}, 'grid');
I removed things from the declare array that didn't belong in it, which may have been causing the problem.
Note that postCreate is now defined in an object passed straight to declare. This object's properties will be mixed in after the constructors in the array, as opposed to properties of the object passed to the constructor when instantiating, which will simply override those properties straight on the instance. This also gives it access to call this.inherited(arguments) which will run any previous mixins' postCreate function first.
I am using Struts 2 dojo plugin to make html tree. It generate some dojo-html code for tree node
<div dojoType="struts:StrutsTreeNode" id="2" title="car">
I want to process tree node click by this
<script language="JavaScript" type="text/javascript">
dojo.event.topic.subscribe("treeSelected", function treeNodeSelected(message) {
dojo.io.bind({
url: "<s:url value='../roseindia/objectsList2.action'/>?categoryId="+message.node.title,
load: function(type, data, evt) {
var divDisplay = dojo.byId("displayIt");
divDisplay.innerHTML=data;
},
mimeType: "text/html"
});
});
I can pass title(car) as message.node.title . I need to pass id not title, but where is not propertie message.node.id.
How can I get access to id(of treenode) in JavaScript function?
oohhkay, so youre in a 0.4.3 dojo.version!? im not sure how API works in that old a version, however the simplest current api hook is the onClick.
As i recall, with tree.onClick override you will get the item and the TreeNode, both being objects where the item is reference to your store json data and the treenode is the currently clicked row (dijit Widget, meaning you should have .getChildren, .domNode etc).
So in terms of code, try
<div dojoType="struts:StrutsTreeNode" id="2" title="car">
<script type="dojo/method" event="onClick" args="item, treeNode">
alert(treeNode.id);
alert(treeNode.domNode.tagName);
alert(treeNode.domNode.innerHTML.substr(0,30);
</script>
</div>
The Google Custom Search integration only includes numbered page links and I cannot find a way to include Next/Previous links like on a normal Google search. CSE used to include these links with their previous iframe integration method.
I stepped through the javascript and found the undocumented properties I was looking for.
<div id="cse" style="width: 100%;">Loading</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en'});
google.setOnLoadCallback(function() {
var customSearchControl = new google.search.CustomSearchControl('GOOGLEIDGOESHERE');
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
customSearchControl.setSearchCompleteCallback(null,
function() { searchCompleteCallback(customSearchControl) });
customSearchControl.draw('cse');
}, true);
function searchCompleteCallback(customSearchControl) {
var currentPageIndex = customSearchControl.e[0].g.cursor.currentPageIndex;
if (currentPageIndex < customSearchControl.e[0].g.cursor.pages.length - 1) {
$('#cse .gsc-cursor').append('<div class="gsc-cursor-page">Next</div>').click(function() {
customSearchControl.e[0].g.gotoPage(currentPageIndex + 1);
});
}
if (currentPageIndex > 0) {
$($('#cse .gsc-cursor').prepend('<div class="gsc-cursor-page">Previous</div>').children()[0]).click(function() {
customSearchControl.e[0].g.gotoPage(currentPageIndex - 1);
});
}
window.scrollTo(0, 0);
}
</script>
<link rel="stylesheet" href="http://www.google.com/cse/style/look/default.css" type="text/css" />
I've been using this to find the current page:
ctrl.setSearchCompleteCallback(null, function(gControl, gResults)
{
currentpage = 1+gResults.cursor.currentPageIndex;
// or, here is an alternate way
currentpage = $('.gsc-cursor-current-page').text();
});
And now it's customSearchControl.k[0].g.cursor ... (as of this weekend, it seems)
Next time it stops working just go to script debugging in IE, add customSearchControl as a watch, open the properties (+), under the Type column look for Object, (Array) and make sure there is a (+) there as well (i.e. contains elements), open[0], and look for Type Object, again with child elements. Open that and once you see "cursor" in the list, you've got it.