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>
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 have a list that takes values from server and i want that whenever an item of the list gets clicked it will change a textarea text to the appropriate variable on the list,
I am getting the user using redux:
function ProfilePage() {
const dispatch = useDispatch();
const authObj = useSelector(state => state.auth);
const { user, token, expiredAt } = authObj;
I am generating the list like this:
<ul className="SentencesList">
{
user.approvedPatterns.map((el, i) => (
<div key={i}>
<li>{el.name || ''}</li>
<hr className="profilePageSentenceListHr" />
</div>
))
}
</ul>
And what i want is that when a li on the list get clicked i will take the appropriate value in the JSON object and show i
<textarea rows="5" cols="60" className="centerPageLargeInputBox" type="text" />
The JSON list looks like that:
const userList = [
{
_id: "1",
username: "****",
password: "*",
approvedPatterns:[
{
"name":"title 1",
"text":"some text"
},
{
"name":"title 2",
"text":"some text1"
},
{
"name":"title 3",
"text":"some text 2"
}
]
}
]
How can i accomplish that?
I am really lost.
I have created the demo here: https://stackblitz.com/edit/react-f5q3n8?file=src/App.js
So when anyone clicks on the li, the textarea will show the value of that li's text property.
I'm using Tabulator to implement search
Here's my html -- no problems until I try to search, then, I receive the above-captioned error:
<div>
<select id="filter-field">
<option></option>
<option value="custId">Customer ID</option>
<option value="custType">Customer Type</option>
<option value="custName">Customer Name</option>
<option value="groupId">Group ID</option>
</select>
<select id="filter-type">
<option value="=">=</option>
<option value="<"><</option>
<option value="<="><=</option>
<option value=">">></option>
<option value=">=">>=</option>
<option value="!=">!=</option>
<option value="like">like</option>
</select>
<input id="filter-value" type="text" placeholder="value to filter">
</div>
<div id="example-table"></div>
I'm receiving an error in the JavaScript:
````<script>
var table;
function handleCellUpdated(cell) {
console.log(cell);
console.log(cell.getRow());
console.log(cell.getRow().getData());
var record = cell.getRow().getData();
$.ajax({
url: "api/SalesTrackerCustomers/" + record.id,
data: JSON.stringify(record),
contentType: 'application/json',
type: "PUT",
success: function (response, textStatus, xhr) {
console.log("success")
},
error: function (XMLHttpRequest, textStatus, error) {
console.log("error")
}
});
}
function initTable() {
//Build Tabulator
table = new Tabulator("#customers", {
height: "90vh",
placeholder: "Loading...",
addRowPos: "bottom",
columns: [
{ title: "Customer ID", field: "custId", width: 150, editor: "input" },
{ title: "Customer Type", field: "custType", width: 130, editor: "input" },
{ title: "Customer Name", field: "customerName", editor: "input" },
{ title: "Group ID", field: "groupId", editor: "number" }
],
cellEdited: handleCellUpdated
});
loadCustomers();
}
function loadCustomers() {
console.log("loading data");
$.ajax({
url: "/api/SalesTrackerCustomers",
method: "GET"
}).done(function (result) {
table.setData(result);
});
}
// javascript for add/delete
//Add row on "Add Row" button click
document.getElementById("add-row").addEventListener("click", function () {
table.addRow({});
});
//Delete row on "Delete Row" button click
document.getElementById("del-row").addEventListener("click", function () {
table.deleteRow(1);
});
// javascript for search
//Define variables for input elements
var fieldEl = document.getElementById("filter-field");
var typeEl = document.getElementById("filter-type");
var valueEl = document.getElementById("filter-value");
//Custom filter example
function customFilter(data) {
return data.car && data.rating < 3;
}
//Trigger setFilter function with correct parameters
function updateFilter() {
var filterVal = fieldEl.options[fieldEl.selectedIndex].value;
var typeVal = typeEl.options[typeEl.selectedIndex].value;
var filter = filterVal == "function" ? customFilter : filterVal;
if (filterVal == "function") {
typeEl.disabled = true;
valueEl.disabled = true;
} else {
typeEl.disabled = false;
valueEl.disabled = false;
}
if (filterVal) {
table.setFilter(filter, typeVal, valueEl.value);
}
}
//Update filters on value change
document.getElementById("filter-field").addEventListener("change", updateFilter);
document.getElementById("filter-type").addEventListener("change", updateFilter);
document.getElementById("filter-value").addEventListener("keyup", updateFilter);
//Clear filters on "Clear Filters" button click
document.getElementById("filter-clear").addEventListener("click", function () {
fieldEl.value = "";
typeEl.value = "=";
valueEl.value = "";
table.clearFilter();
});
Can anyone add insight on this error? I have tried moving JavaScript around, and I think it may have to do with the placement of the JavaScript. It is displaying above captioned error on on //Clear filters on "Clear Filters" button click; it could also be on the load tabulator javascript function on table
The error you are receiving is because you are trying to add an eventListener to a null value. When using document.getElementById(''), if it does not find an element it returns null. Because you are not checking that you found an element, your .addEventListener tries to attach to a null value, so the error is thrown.
Looking at your code, there are three areas that do not have an html element (from what is included in the question)
There is not a filter-clear, add-row, or del-row element in your HTML. Based on you seeing the error above the document.getElementById('filter-clear').addEventListener(), it looks like your filter-clear element does not exist.
Here is an example that catches the error and appends the error to the body.
https://jsfiddle.net/nrayburn/58he2jr6/6/
I'd like to display the columns that are defined in Tabulator with editor: false differently than the cells where editing is enabled.
I currently have columns defined like so:
this.tabAuthorizations = new Tabulator('#myTab', {
data: data,
columns: [
// 0
{
title: 'Id',
field: 'Id',
visible: false
},
{
title: 'User',
field: 'UserId',
formatter: (c) => {
return directReports.find(x => x.EmployeeListID === c.getValue()).EmployeeName;
},
editor: false
}, {
title: 'Type',
field: 'AuthTypeId',
formatter: c => {
return authTypes.find(x => x.AuthTypeId === Number(c.getValue())).AuthType;
},
editor: 'autocomplete',
editorParams: {
showListOnEmpty: true,
values: authTypes.reduce((a, c) => Object.assign( {[c.AuthTypeId]: c.AuthType}, a), {})
}
},
// etc
]
});
currently this generates cells with the same css classes applied.
<div class="tabulator-cell" role="gridcell" style="width: 542px; height: 28px;" tabulator-field="TaskListID" title="">My readonly field<div class="tabulator-col-resize-handle"></div><div class="tabulator-col-resize-handle prev"></div></div>
I would like to apply a -readonly or -editable class to the cells depending on the setting for editor: in the column definition. There doesn't appear to be a class applied either to the editable or non-editable cells by Tabulator itself, is there a better way of doing this other than in the cell formatter? I'd rather not have to define formatters simply to change the cell style.
you can add a CSS class to any column with the cssClass property in the column definition:
{
title: 'Type',
field: 'AuthTypeId',
cssClass: 'editable', //add custom css class to cell
}
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