I have a Liferay-AUI databable, for which I would like to allow single row selection, and further invoke a script as each row is selected. The script would need to identify which row was just selected and take some action.
Here is an example of current implementation. Suggestions on how to add the above requirements would be appreciated.
<div id="productsTable"></div>
<aui:script use="datatable,datatable-sort,datatable-scroll,datatable-highlight,datatable-selection,liferay-portlet-url">
var roleColumns = [ {
label : 'Providing Role Name',
key : 'providerRoleName',
sortable : true,
allowHTML : true,
formatter : function(o) {
var renderURL = Liferay.PortletURL
.createURL('<%= productDetailUrl %>');
renderURL.setParameter('productId', o.data.productId);
return '<a href="' + renderURL.toString() + '">'
+ o.data.providerRoleName + '</a>';
}
}, {
label : 'Cardinality',
key : 'cardinality',
sortable : true
} ];
new A.DataTable({
columns : roleColumns,
rowSelect: 'mousedown',
data : <%=renderRequest.getAttribute("roles")%>,
scrollable : "xy",
height : "400px",
width : '100%',
sort : 'true',
highlightRows : true
}).plug(A.Plugin.DataTableSelection, {
selectRow : true
}).render('#productsTable');
</aui:script>
I have a strong suspicion this is not the "correct" way to do it - however I was able to isolate DOM node of the row being clicked on this this code.
<aui:script use="datatable,datatable-sort,datatable-scroll,datatable-highlight,datatable-selection,liferay-portlet-url">
var roleColumns = [ {
label : 'Providing Role Name',
key : 'providerRoleName',
sortable : true,
allowHTML : true,
formatter : function(o) {
var renderURL = Liferay.PortletURL
.createURL('<%= productDetailUrl %>');
renderURL.setParameter('productId', o.data.productId);
return '<a href="' + renderURL.toString() + '">'
+ o.data.providerRoleName + '</a>';
}
}, {
label : 'Cardinality',
key : 'cardinality',
sortable : true
} ];
new A.DataTable({
columns : roleColumns,
rowSelect: 'mousedown',
data : <%=renderRequest.getAttribute("roles")%>,
scrollable : "xy",
height : "400px",
width : '100%',
sort : 'true',
highlightRows : true
}).plug(A.Plugin.DataTableSelection, {
selectRow : true
}).render('#productsTable');
A.delegate('click', function(e) {
console.log(e.currentTarget.getDOMNode());
}, '#productsTable', 'tr', myDataTable);
</aui:script>
All is the same except for my addition at the bottoms
A.delegate('click', function(e) {
console.log(e.currentTarget.getDOMNode());
}, '#productsTable', 'tr', myDataTable);
You can also isolate the dataset
A.delegate('click', function(e) {
console.log(e.currentTarget.getData("yui3-record"));
}, '#productsTable', 'tr', myDataTable);
The purpose of this exercise has been to allow for master/detail display within the same page, where the detail changes as a row in the master table is selected. I chose to put a radio button in the first column of the table, as depicted below, and clicking on the radio buttons invokes an action method within the portlet to update row selection and associated detail.
var columns = [
{
label : ' ',
sortable : false,
allowHTML : true,
formatter : function(o) {
if (o.data.isSelected)
return '<img src="/html/icons/radiobutton-checked.png" width="15" height="15" border="0" />';
var renderURL = Liferay.PortletURL.createURL('<%= partnerDetailUrl %>');
renderURL.setParameter('productLineItemRoleId', o.data.id);
return '<img src="/html/icons/radiobutton-unchecked.png" width="15" height="15" border="0" />';
}
},
....
];
I understand the best solution is to use javascript to dynamically update only certain parts of the page, not to perform a form-post with each radio button click. But this works for now, and I can move on to more pressing issues ;).
Thanks,
Randy
Related
Using vue v2.5 with vueCLI 3 trying to have a v-data-table that on each row have a button, when this button clicked should make it appear as loading.
v-btn has loading property by default, really I don't know why is not working...
<v-data-table
:headers="headers"
:items="records"
#dblclick:row="editRowCron_jobs">
<template v-slot:[`item.actions`]="props">
<v-btn color="blue-grey" :loading="props.item.createloading" fab dark small #click="ManuralRun(props.item)">
<v-icon dark>mdi-google-play</v-icon>
</v-btn>
</template>
</v-data-table>
On the click method, I can read but not set the item
export default {
data() {
return {
headers: [
{ text: "id", value: "id", align: " d-none" },
{ text: "actions", value: "actions" }
],
records: [] //grid rows filled by API
}
},
methods: {
ManuralRun(item){
this.records[2].createloading=true; //even I set it like that, nothing happens
item.createloading = true; //property changed here - ok
console.log(item); //here outputs the clicked item - ok
},
so, according to this
the property MUST pre-exist in the array, that means, when we get the result from the API, we have to add the property as:
this.records = data.data.map(record => {
return {
createloading: false,
...record
}
})
I am using a webGrid to display data. Two columns are checkboxes. Instead of displaying the checkboxes, I want to display two .png images.
As you can see in the code, I've tried three different ways to do it.
I created a variable to hold the path, I used the string.Format, and I also put the path as a parameter in Html.Raw. None of them work.
I also added a Web.config file to the images folder, but it doesn't seem to work either.
Am I missing something? How can I make it work?
I'll appreciate your help.
#{
var checkboxEmpty = "<img src=\"~/Modules/Mime.Picor/Content/images/CheckboxEmpty.png\" />";
var grid = new WebGrid(Model, canPage: false);
}
<div>
#grid.GetHtml(
tableStyle: "table table-striped table-condensed table-hover table-bordered",
headerStyle: "success",
columns: grid.Columns(
grid.Column("Name", format: (item) => Html.ActionLink((string)item.Name, "Details", "LoadList", new { id = item.Id }, null)),
grid.Column("DateIssued", header: "Issued Date", format: (item) => item.DateIssued.ToShortDateString()),
grid.Column("DateRevised", header: "Revised Date", format: (item) => item.DateRevised == null ? "" : item.DateRevised.ToShortDateString()),
grid.Column("DateSchedShip", header: "Schedule Ship Date", format: (item) => item.DateSchedShip == null ? "" : item.DateSchedShip.ToShortDateString()),
grid.Column("TruckingCompany", header: "Trucking Company"),
grid.Column("Comments", header: "Special Instructions", style: "col-lg-2"),
grid.Column("Complete", header: "Cmp", format: (item) =>
{
if (item.Complete == 1)
{
return Html.Raw(string.Format("<text><img src=\"{0}\" alt=\"Image\"/></text>", Url.Content("~/Modules/Mime.Picor/Content/images/CheckboxFull.png")));
}
else
{
return Html.Raw(checkboxEmpty);
}
}, style: "text-align-center"),
grid.Column("MakeReady", header: "Mk. Rdy", style: "text-align-center", format: (item) => (item.MakeReady == 1) ? Html.Raw("<img src='~/Content/images/CheckboxFull.png' />") : Html.Raw("<img src='~/Content/images/CheckboxEmpty.png' />")),
grid.Column("AllDistributors", header: "Distributors", canSort: false, style: "col-lg-4"),
grid.Column("DEL", format: (item) => Html.ActionLink("Delete", "Delete", "LoadList", new { id = item.Id }, new { #class = "delete16image" }))
))
Here is the rendered HTML for the picture path:
<text>
<img src="~/Modules/Mime.Picor/Content/images/CheckboxEmpty.png></img>
</text>
Still trying to work with Dgrid (0.4) and dojo (1.10), I have now another issue with the selection.
My web page contain a Dialog opened when you click on a button.
Inside this dialog, we have the following code which display a grid with data coming from a database through a Json HTTP page. This is working fine, even sorting and query filtering.
What I want to do know is to allow the user to double click on a row, get the selected row Id contains in the first column to update the form in the main page. I use the dgrid/selection for this. However, it always return the last row of the grid instead of the one the user selected.
The selection code is based on this :
http://dgrid.io/tutorials/0.4/hello_dgrid/
Any idea?
Thanks
<script language="javascript">
require
(
[
"dojo/_base/declare",
"dojo/_base/array",
"dgrid/OnDemandList",
"dgrid/OnDemandGrid",
"dgrid/Keyboard",
"dgrid/Selection",
"dgrid/Editor",
"dgrid/extensions/ColumnHider",
"dstore/Memory",
"dstore/RequestMemory",
"dojo/_base/lang",
"dojo/dom-construct",
"dojo/dom",
"dojo/on",
"dojo/when",
"dojo/query",
"dojo/store/Observable",
"dstore/Rest",
"dojo/_base/Deferred",
"dojo/store/Cache",
"dojo/domReady!",
],
function(
declare, arrayUtil, OnDemandList, OnDemandGrid, Keyboard, Selection, Editor, ColumnHider, Memory, RequestMemory, lang, ObjectStore, dom, on, when, query, Observable, Rest, Deferred
){
var fform = dom.byId("filterForm");
var ContactColumns = [
{ label: "", field: "contact_id", hidden: true, unhidable: true},
{ label: "Company Name", field: "company_name", unhidable: true },
{ label: "Contact Name", field: "contact_name", unhidable: true },
{ label: "Email", field: "contact_email", unhidable: true }
];
var ContactGrid=declare([OnDemandGrid, Keyboard, Selection,ColumnHider]);
var contactlist = new Observable(new Rest({ target: './ajax.contactsLoader.php' }));
var selection = [];
window.contactgrid = new ContactGrid(
{
className: "dgrid-selectors",
collection: contactlist,
maxRowsPerPage:10,
selectionMode: 'single',
cellNavigation: false,
columns: ContactColumns
}, "contacttable"
);
on(fform, "submit", function (event) {
var cpy_filter = fform.elements.fcompany_name.value;
var ct_filter = fform.elements.fcontact_name.value;
var email_filter = fform.elements.fcontact_email.value;
contactgrid.set('collection',contactlist.filter({contact_name: ct_filter, company_name: cpy_filter, contact_email: email_filter }));
contactgrid.refresh();
event.preventDefault();
});
contactgrid.on('dgrid-select', function (event) {
// Report the item from the selected row to the console.
console.log('Row selected: ', event.rows[0].data);
});
contactgrid.on('dgrid-deselect', function (event) {
console.log('Row de-selected: ', event.rows[0].data);
});
contactgrid.on('.dgrid-row:click', function (event) {
var row = contactgrid.row(event);
console.log('Row clicked:', row.data);
});
}
);
</script>
<div class="dijitDialogPaneContentArea" style="width:96%;margin-left:5px">
<form id="filterForm">
<div class="dijitDialogPaneActionBar" >
<button data-dojo-type="dijit.form.Button" type="submit">Filter</button>
<button
data-dojo-type="dijit.form.Button"
data-dojo-attach-point="submitButton"
type="submit"
>
Select
</button>
<button
data-dojo-type="dijit.form.Button"
data-dojo-attach-point="cancelButton"
>
Close
</button>
</div>
<div data-dojo-attach-point="contentNode" >
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcompany_name" id="fcompany_name" style="width:33%">
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcontact_name" id="fcontact_name" style="width:32%">
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcontact_email" id="fcontact_email" style="width:33%">
<div id="contacttable">
</div>
</div>
</form>
</div>
Just found the reason.
the columns need to have a 'id' column called ID. I just change the 'contact_id' column to 'id' and it works fine.
thanks
I am new to using backbone in parse.com environment. I simply want to edit the second model object but I dont know how to open the edit box for the second object.
The current working model is the following, I have added "dblclick label.todo-job" : "edit1" and can get it started by double clicking it.
events: {
"click .toggle" : "toggleDone",
"dblclick label.todo-content" : "edit",
"dblclick label.todo-job" : "edit1",
"click .todo-destroy" : "clear",
"keypress .edit" : "updateOnEnter",
"blur .edit" : "close"
},
The following is the function to allow editing my object.
edit1: function() {
$(this.el).addClass("editing");
this.input.focus();
},
However, it only opens this object "label.todo-content" to edit while I want to edit "label.todo-job". How can I change the focus to the new object.
Thats the whole code if you need.
// The DOM element for a todo item...
var TodoView = Parse.View.extend({
//... is a list tag.
tagName: "li",
// Cache the template function for a single item.
template: _.template($('#item-template').html()),
// The DOM events specific to an item.
events: {
"click .toggle" : "toggleDone",
"dblclick label.todo-content" : "edit",
"dblclick label.todo-job" : "edit1",
"dblclick label.todo-phone" : "edit2",
"dblclick label.todo-email" : "edit3",
"dblclick label.todo-website" : "edit4",
"dblclick label.todo-address" : "edit5",
"click .todo-destroy" : "clear",
"keypress .edit" : "updateOnEnter",
"blur .edit" : "close"
},
// The TodoView listens for changes to its model, re-rendering. Since there's
// a one-to-one correspondence between a Todo and a TodoView in this
// app, we set a direct reference on the model for convenience.
initialize: function() {
_.bindAll(this, 'render', 'close', 'remove');
this.model.bind('change', this.render);
this.model.bind('destroy', this.remove);
},
// Re-render the contents of the todo item.
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.input = this.$('.edit');
return this;
},
// Toggle the `"done"` state of the model.
toggleDone: function() {
this.model.toggle();
},
// Switch this view into `"editing"` mode, displaying the input field.
edit: function() {
$(this.el).addClass("editing");
this.input.focus();
},
edit1: function() {
$(this.el).addClass("editing");
this.input.focus();
},
edit2: function() {
$(this.el).addClass("editing");
this.input.focus();
},
edit3: function() {
$(this.el).addClass("editing");
this.input.focus();
},
edit4: function() {
$(this.el).addClass("editing");
this.input.focus();
},
edit5: function() {
$(this.el).addClass("editing");
this.input.focus();
},
// Close the `"editing"` mode, saving changes to the todo.
close: function() {
this.model.save({content: this.input.val()});
$(this.el).removeClass("editing");
},
// If you hit `enter`, we're through editing the item.
updateOnEnter: function(e) {
if (e.keyCode == 13) this.close();
},
// Remove the item, destroy the model.
clear: function() {
this.model.destroy();
}
});
Below is the objects added in the HTML.
<script type="text/template" id="item-template">
<li class="<%= done ? 'completed' : '' %>">
<div class="view">
<li><label class="todo-content"><%= _.escape(content) %></label></li>
<li><label class="todo-job"><%= _.escape(job) %></label></li>
<li><label class="todo-phone"><%= _.escape(phone) %></label></li>
<li><label class="todo-email"><%= _.escape(email) %></label></li>
<li><label class="todo-website"><%= _.escape(web) %></label></li>
<li><label class="todo-address"><%= _.escape(address) %></label></li>
<li><label class="todo-postcode"><%= _.escape(postcode) %></label></li>
<button class="todo-destroy"></button>
</div>
<input class="edit" value="<%= _.escape(content) %>">
<input class="edit" value="<%= _.escape(content) %>"> /*I need to edit this instead of the object above this*/
</li>
</script>
An event triggers on the deepest possible element.which means this of Event handler function is not element you select for event listener but element where the actual event occurs.
I don't know about parse.com though,I assume that label.todo-content is inside of label.todo-job. And that makes Event handler's callback this into label.todo-content.
So If you explicitly select element to focus,It should work.
FYI, Backbone View has $(http://backbonejs.org/#View-dollar) and $el (http://backbonejs.org/#View-$el) parameters to use jQuery methods for elements in side of the View.Since global $ is able to edit any elements over each controller's View area, using this.$ is always recommended.
edit1: function() {
this.$el.addClass("editing");
this.$("label.todo-job").focus();
},
EDITED
I got what you asked about.
I do not know how you wrote your HTML code but the code you provided is pointing first input if your input tags have class name,
edit1: function() {
this.$el.addClass("editing");
this.$(".yourClassNameForInput").focus();
},
or if you do know have class/id name,You can also do this.
edit1: function() {
this.$el.addClass("editing");
this.$("input").eq(0).focus();
},
....
edit5: function() {
this.$el.addClass("editing");
this.$("label.todo-job").eq(4).focus();
}
I am opening a popup in liferay with a portlet in it. I want to pass a value in it so that the variable will be available in the doView() method.
$('#<portlet:namespace/>myInfo').on('click', function(event) {
url = '<%=myUrl%>';
Liferay.Util.openWindow({
title : "My Info",
uri : url,
id : 'myWindow',
dialog : {
destroyOnClose : true,
cache : false,
modal : true,
width : 1070,
height : 800
}
});
});