I'm using Vuetify data table and need to search in it. but the search in vuetify documentation is String. can I set the search to array? I wanna set filters and multiple data to search in the data table.
for example, I wanna search x and y at the same time. is it possible to put both in search: [] and bind it to v-data-table search?
<v-data-table v-show="!map"
:custom-filter="customSearch"
id="mytable"
:search="search"
:headers="headers"
:items="getcartables.data"
style="white-space: nowrap; cursor: pointer"
#dblclick:row="showDetails"
v-model="selectedRows"
class="box-shadow mx-5 border-radius-2"
>
<template v-slot:item="{ item, index }">
<tr
:class="selectedRows.indexOf(item.refrenceEid) > -1 ? 'active' : ''"
#click="rowClicked(item)"
#dblclick="showDetails($event, item)"
>
<td>
{{ index + 1 }}
</td>
<td>{{ item.demandNumber }}</td>
<td>{{ item.folderNumber }}</td>
<td>{{ item.workflowTitle }}</td>
</tr>
</template>
</v-data-table>
my custom-search(I'm not really using it):
customSearch(value, search, item) {
return Object.values(item).some(
(v) => v && v.toString().toLowerCase().includes(search)
);
},
one of the things I wanna search in cartable is fetched like this from my v-model(I want the search to be like an array to search this renewcode and other v-models at the same time and render table based on these filters) :
async renewWallPorMishe() {
let area = this.mantaghe ? this.mantaghe : 0
let local = this.hoze ? this.hoze : 0
let block = this.boluk ? this.boluk : 0
let property = this.melk ? this.melk : 0
let building = this.sakhteman ? this.sakhteman : 0
let apartment = this.apartman ? this.apartman : 0
let guild = this.senf ? this.senf : 0
this.renewcode =
area +
"-" +
local +
"-" +
block +
"-" +
property +
"-" +
building +
"-" +
apartment +
"-" +
guild;
this.search = this.renewcode
this.renew = true
},
Related
I want to show images from the database in an Excel file downloaded using the Laravel Maatwebsite package.
Controller
$data['company_names'] = Company::where('id', Auth::user()->com_id)
->first(['company_name']);
$data['companies'] = $companies;
$data['users'] = $users;
$data['regions'] = $regions;
$data['roles'] = $roles;
$exl = Excel::download(new EmployeeReportExport($data),
'Employee-Report.xlsx');
ob_end_clean();
return $exl;
Export Code
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
class EmployeeReportExport implements FromView
{
public function __construct($data)
{
$this->data = $data;
}
public function view(): View
{
return view('back-end.premium.hr-reports.employee-report.employee-bulk-report-excel', [
'data' => $this->data
]);
}
}
Blade
<td>{{ $i++ }}</td>
<td>{{ $usersData->company_assigned_id ?? '' }}</td>
<td>{{ $usersData->first_name . ' ' . $usersData->last_name }}</td>
<td><img src="{{ asset($usersData->profile_photo) ?? '' }}" alt=""></td>
<td>{{ $usersData->email ?? null }}</td>
<td>{{ $usersData->phone }}</td>
But it's not showing in the Excel file; it returns the following error.
file_get_contents(http://127.0.0.1:8000/uploads/profile_photos/1667727818.jpg):
failed to open stream: HTTP request failed!
So I know that I can use the N/render to generate a template and I can use the addRecord to add record objects to the print template to make them available in the FTL.
My question is if I can do something similar when the native print button is clicked and prints a Advanced PDF/HTML Template. I know that I can catch the PRINT event in the User Event script but beyond that I am stuck.
I know the question is a little general I will add context on request. I just don't know which way to go.
EDIT: I am familiar with the option of adding a custpage field to the form and then extracting the JSON in the FTL.
In this specific situation it would be much more convenient if I could simply add a full record. Meaning I am on a Item Fulfillment print and want to add the FULL parent Sales Order record to the print so that I can access it in the FTL by salesorder.memo etc. Something similar to:
require(['N/render'], function(render) {
var renderer = render.create();
renderer.addRecord('customer', record.load({ type: record.Type.CUSTOMER, id: customer }));
})
The issue is that I only know how to do this for completely custom prints but not prints that are printed from the Native print buttons on transactions.
I need this to do line matching from the Sales Order lines to the Item Fulfillment lines and would rather do it this way if possible instead of creating a custpage and inserting a custom made object.
I refer to one of my previous answer.
Use the beforeLoad hook in a UserEventScript to set extra data on the context.form. You'll be able to access this data on the template.
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
*/
define(['N/ui/serverWidget'], function(serverWidget) {
function beforeLoad(context) {
// var request = context.request;
// var newRecord = context.newRecord;
var form = context.form;
var type = context.type;
var UserEventType = context.UserEventType;
// only execute during printing...
if (type != UserEventType.PRINT) return
var customData = {
hello: 'world'
}
var field = form.addField({
id : 'custpage_custom_data',
label: 'Custom Data',
type : serverWidget.FieldType.LONGTEXT
});
field.defaultValue = JSON.stringify(customData);
}
return {
beforeLoad: beforeLoad
};
})
You can access the data within the template through:
<#if record.custpage_custom_data?has_content>
<#assign custom_data = record.custpage_custom_data?eval />
</#if>
As per your question you want to add item sublist data also from sales order on print of item fulfillment. if it is so, then here I have used for same situation.
Steps:
Write a user event before load script on print mode only and then create a saved search to get the data of item and save it in custom field with long text type with space as label.
Customize your standard pdf template that is attached to item fulfillment record.
GoTo- customization- forms- Advanced pdf template-Customize preferred template for item fulfillment.
Add a table there with that custom field.
It will work on standard print button. I have done it for work order record. You may edit in search using sales order saved search.
UserEvent
/**
*#NApiVersion 2.x
*#NScriptType UserEventScript
*/
define(['N/record', 'N/search', 'N/ui/serverWidget'], function (record, search, serverWidget) {
function beforeLoad(scriptContext) {
try {
if (scriptContext.type == 'print') {
var currentRec = scriptContext.newRecord;
var recid = currentRec.id;
columns[0] = search.createColumn({
name: "sequence",
join: "manufacturingOperationTask",
sort: search.Sort.ASC,
label: "Operation Sequence"
});
columns[1] = search.createColumn({
name: "custevent_custom_op_name",
join: "manufacturingOperationTask",
label: "Operation Name(Instruction)"
});
columns[2] = search.createColumn({
name: "manufacturingworkcenter",
join: "manufacturingOperationTask",
label: "Manufacturing Work Center"
});
columns[3] = search.createColumn({
name: "formulanumeric",
formula: "Round({manufacturingoperationtask.runrate}*{quantity}/60,2)",
label: "BudgetHours"
});
//Creating search to get all the values for work order
var mySearch = search.create({
type: "workorder",
filters:
[
["type", "anyof", "WorkOrd"],
"AND",
["internalid", "anyof", recid],
"AND",
["mainline", "is", "T"]
],
columns: columns
});
var searchResultCount = mySearch.runPaged().count;
mySearch.run().each(function (result) {
// .run().each has a limit of 4,000 results
results.push(result);
return true;
});
//populate current printout with custom record entries
var customRecords = { columns: columns, results: results };
var columns = customRecords.columns, results = customRecords.results;
var custrecord = scriptContext.form.addField({ id: 'custpage_custrecord_to_print', type: serverWidget.FieldType.LONGTEXT, label: " " }),
custrecordArray = [];
if (results && results instanceof Array) {
for (var i = 0; i < results.length; i++) {
var singleLine = {};
for (var j = 0; j < columns.length; j++) {
if (i == i && j == 2) {
var value = results[i].getText(columns[j]);
} else {
var value = results[i].getValue(columns[j]);
}
if (j == 0 || j == 1 || j == 2) {
if (value.indexOf('.') == 0 || value.indexOf(',') == 0 || value.indexOf('-.') == 0 || value.indexOf('-,') == 0) {
value = '0' + value;
}
}
singleLine["col" + j] = (value) ? value : '';
}
custrecordArray.push(singleLine);
}
custrecord.defaultValue = JSON.stringify(custrecordArray);
}
}
} catch (e) {
log.error("ERROR", e);
}
}
return {
beforeLoad: beforeLoad,
};
});
In Advanced Pdf Template:-
<#if record.custpage_custrecord_to_print?has_content>
<#assign customrecord = record.custpage_custrecord_to_print?eval />
<table width="100%" class="second_table" style="page-break-inside: auto; width: 100%; margin-top: 2px; padding-top: 0px">
<#list customrecord as customrecord_line>
<tr width="100%" border-top="solid black" margin-top="10px" style="margin-top:10px; page-break-before: auto;">
<th width="25%" align="left" style="padding: 2px 2px;">Step</th>
<th width="25%" align="center" style="padding: 2px 2px;">Activity</th>
<th width="25%" align="center" style="padding: 2px 2px;">Run Rate(Min/Unit)</th>
<th width="25%" align="center" style="padding: 2px 2px;">BudgetHours</th></tr>
<tr width="100%" style="page-break-inside: auto;">
<td width="25%" align="left" style="padding: 2px 2px;">0${customrecord_line.col0}</td>
<td width="25%" align="center" style="padding: 2px 2px;">${customrecord_line.col2}</td>
<td width="25%" align="center" style="padding: 2px 2px;">${customrecord_line.col3}</td>
<td width="25%" align="center" style="padding: 2px 2px;">${customrecord_line.col4}</td>
</tr>
</list>
</table>
</#if>
It will be helpful.
Thanks,
I have an array of elements composed of key => value for example:
arr = { 156 : 'one', 99 : 'tow' }
I want to remove an element from the array depending on the key. Like doing unset() in php ? Is it possible ?
You can also use the filter pipe like this:
{% set arr = arr | filter((v, k) => k != '99') %}
You can extend twig to do this
<?php
class Project_Twig_Extension extends \Twig\Extension\AbstractExtension {
public function getFunctions(){
return [
new \Twig\TwigFunction('unset', [$this, 'unset'], [ 'needs_context' => true, ]),
];
}
/**
* $context is a special array which hold all know variables inside
* If $key is not defined unset the whole variable inside context
* If $key is set test if $context[$variable] is defined if so unset $key inside multidimensional array
**/
public function unset(&$context, $variable, $key = null) {
if ($key === null) unset($context[$variable]);
else{
if (isset($context[$variable])) unset($context[$variable][$key]);
}
}
}
Usage inside twig:
<h1>Unset</h1>
{% set foo = 'bar' %}
{% set bar = { 'foo' : 'bar', } %}
<h2>Before</h2>
<table>
<tr>
<td>foo</td><td>{{ foo | default('not applicable') }}</td>
</tr>
<tr>
<td>bar.foo</td><td>{{ bar.foo | default('not applicable') }}</td>
</tr>
</table>
{% do unset('foo') %}
{% do unset('bar', 'foo') %}
<h2>After</h2>
<table>
<tr>
<td>foo</td><td>{{ foo | default('not applicable') }}</td>
</tr>
<tr>
<td>bar.foo</td><td>{{ bar.foo | default('not applicable') }}</td>
</tr>
</table>
output
Before
|------------------------------|------------------------------|
| foo | bar |
| bar.foo | bar |
|------------------------------|------------------------------|
After
|------------------------------|------------------------------|
| foo | not applicable |
| bar.foo | not applicable |
|------------------------------|------------------------------|
I'm building a webscraper with nodejs and pupeteer.
Everthing works fine, but now im stuck on how to get structured data from a table without classes. Here's an example:
I don't know how to iterate thru the table and extract the data in json format which should like this:
<table class="tableclass">
<tbody>
<tr>
<td>
<b>
<strong>
<span>A</span></strong> & B <strong><span>C</span></strong>Name</b>
</td>
<td >
Street No<br>
Zip City
</td>
<td >
Map | Website
</td>
</tr>
<tr>
<td>
<b>
<strong>
<span>A</span></strong> & B <strong><span>C</span></strong>Name</b>
</td>
<td >
Street No<br>
Zip City
</td>
<td >
Map | Website
</td>
</tr>
</table>
Obj ={
"content":[
{
"name":"A&B C Name",
"adress":[
"Street No",
"Zip",
"City"
],
"link":"http://www.websiteB.de"
},
]
}
Does the table have a consistent structure in each case? If so, you just need to figure out how to get to each element from the root of of table. For instance, to get the name, assuming that the above table structure is the same for all tables:
const table = document.querySelector('.tableclass')
Obj ={
"content":[
{
"name": table.querySelectorAll('tr')[0].querySelectorAll('td')[0].innerText;
....
]
}
Here, I get the table element I am interested in using document.querySelector('.tableclass') - which will return the first instance of .tableclass on the page. If you have multiple, you will have to use document.querySelectorAll and perform these operations on each table in a for-loop.
Then, I use the querySelector but limited to this table, and I grab the first element, because that's where the name is. (table.querySelectorAll('tr')[0]). Here I could have just used (table.querySelector('tr')) as I wanted the first element, but this is just to show you how you can access any of the s by their index. Finally, following the same logic, I need to select the first element as that is the element that contains all the 'name' text, then I just use its .innerText attribute to extract the text.
innerText will be your friend here - just traverse the DOM nodes using node.querySelector until you get to one that contains all the text you want and no more, then get the .innerText attribute on that node. If the table has consistent structure, you should just be able to figure this out for one table and it should work on all of them.
let data = await page.evaluate(() => {
var i = 0;
for (var i = 0; i < 5; i++) {
const table = document.querySelector('#tableclass');
let dealer = table.querySelectorAll('tr')[i].querySelectorAll('td')[0].innerText;
let adress = table.querySelectorAll('tr')[i].querySelectorAll('td')[1].innerText;
let link = table.querySelectorAll('tr')[i].querySelectorAll('td')[2].querySelectorAll('a')[1].getAttribute("href");
return {
dealer,
adress,
link
}
}
I want to loop thru the table/ each row in it. I know this is wrong, but I don't know how to loop in this case. Thanks for help!
So the way I am building pagination in Reactjs is a bit odd, but it works for me, I, How ever would like to say show me the first 5 (1-5) on the 5th page show me 5-max. But I am unclear on how to do that.
this is what I currently have:
render: function() {
// Do we have more then one page?
if (this.props.maxPages > 0){
// We have to add one to the max pages that come back.
var pageLink = this.props.maxPages + 1;
var currentPage = this.props.currentPage;
var liElements = []
// Build [<<][<] for the user.
if (pageLink > 1) {
liElements.push(<li><<</li>);
liElements.push(<li><a href={this.pageSubtraction(currentPage, pageLink)}><</a></li>);
}
// Build the individual [x][y][z] links.
for (var i = 1; i <= pageLink; i++) {
liElements.push(<li key={i} id={i}><a href={"#posts?page="+i}>{i}</a></li>);
}
// Build the [>][>>] for the user.
if (pageLink > 1) {
liElements.push(<li><a href={this.pageAddition(currentPage, pageLink)}>></a></li>);
liElements.push(<li><a href={"#posts?page="+pageLink}>>></a></li>);
}
return (<ul className="pagination">{liElements}</ul>);
}else{
// Return nothing.
return ( <div></div> );
}
}
This will build me [<<][<][1][2][3] ... [>][>>] which is great but their is no limit on it.
At this time:
pageLink = 6 (the max number of pages - I know horrible variable name)
currentPage = 1 (the current page you are on)
So what I need is:
[<<][<][1][2][3][4][5][>][>>] Select Page 5 [<<][<][5][6][>][>>] But I am not sure if my current set up will allow me to do that.
This is a somewhat complicated algorithm (and not all of the details are provided). Rather than worrying about markup here, it might be simpler to start with a pure data structure representing what should be drawn.
Pagination = function(props){
var pages = props.maxPages + 1;
var current = props.currentPage;
var links = [];
// leading arrows
if (current > 0) {
links.push([0, "<<"]);
links.push([current - 1, "<"]);
}
for (var i=current-3; i<current+4; i++) {
if (i > 0 && i < pages) {
links.push([i, i]);
}
}
// tailing arrows
if (current < pages) {
links.push([current + 1, ">"]);
links.push([pages - 1, ">>"]);
}
return JSON.stringify(links, null, 4);
};
Now we get something like this (jsbin). You could also easily write unit tests to ensure this gives the correct results.
[
[
0,
"<<"
],
[
1,
"<"
],
[
1,
1
],
[
2,
2
],
[
3,
3
],
[
4,
4
],
[
5,
5
],
[
3,
">"
],
[
7,
">>"
]
]
Once you're getting the right data here, you can map that data through a presentation function.
function PageLink(i, char){
character = character || String(i);
return (
<li key={char}>
<a href={"#posts?page="+i}>{char}</a>
</li>
);
}
Pagination = function(props){
/* same code as before */
return links.map(function(x){
return PageLink(x[0], x[1]);
});;
};
P.s. when you do get it to match your requirements, please post an answer here so others can use it as a base for their pagination.
Below is the complete code for creating a paging option.Full post is available here.
var pager = React.createClass({
render : function(){
var li = [];
var pageCount = props.Size;
for(var i = 1; i <=pageCount; i++){
if(props.currentPage == i){
li.push(<li key={i} className="active">{i}</li>);
}
else{
li.push(<li key={i} ><a href="#" onClick={props.onPageChanged.bind(null,i)}>{i}</a></li>);
}
}
return (<ul className="pagination">{li}</ul>);
}
});
var dataGrid = React.createClass({
render : function(){
return (
<tr>
<td>{props.item.Name}</td>
<td>{props.item.Address}</td>
<td>...</td>
.....
</tr>
);
}
});
var EmployeeGridTable = React.createClass({
getInitialState : function(){
return {
Data : {
List : [],
totalPage : 0,
sortColumnName : null,
sortOrder : null,
currentPage : 1,
pageSize : 3
}
}
},
componentDidMount : function(){
this.populateData();
},
populateData: function(){
var params = {
pageSize : this.state.Data.pageSize,
currentPage : this.state.Data.currentPage
}
if(this.state.Data.sortColumnName){
params.sortColumnName = this.state.Data.sortColumnName;
}
if(this.state.Data.sortOrder){
params.sortOrder = this.state.Data.sortOrder;
}
$.ajax({
url : this.props.dataUrl,
type : 'GET',
data : params,
success : function(data){
if(this.isMounted()){
this.setState({
Data : data
});
}
}.bind(this),
error: function(err){
alert('Error');
}.bind(this)
});
},
pageChanged:function(pageNumber,e){
e.preventDefault();
this.state.Data.currentPage = pageNumber;
this.populateData();
},
sortChanged : function(sortColumnName, order , e){
e.preventDefault();
this.state.Data.sortColumnName = sortColumnName;
this.state.Data.currentPage = 1;
this.state.Data.sortOrder = order.toString().toLowerCase() == 'asc' ? 'desc':'asc';
this.populateData();
},
_sortClass : function(filterName){
return "fa fa-fw " + ((filterName == this.state.Data.sortColumnName) ? ("fa-sort-" + this.state.Data.sortOrder) : "fa-sort");
},
render : function(){
var rows = [];
this.state.Data.List.forEach(function(item){
rows.push(<dataGrid key={item.EmployeeID} item={item}/>);
});
return (
<div>
<table className="table table-responsive table-bordered">
<thead>
<tr>
<th onClick={this.sortChanged.bind(this,'FirstName',this.state.Data.sortOrder)}>First Name
<i className={this._sortClass('FirstName')}></i></th>
<th onClick={this.sortChanged.bind(this,'LastName',this.state.Data.sortOrder)}>
Last Name
<i className={this._sortClass('LastName')}></i></th>
<th onClick={this.sortChanged.bind(this,'EmailID',this.state.Data.sortOrder)}>
Email
<i className={this._sortClass('EmailID')}></i>
</th>
<th onClick={this.sortChanged.bind(this,'Country',this.state.Data.sortOrder)}>
Country
<i className={this._sortClass('Country')}></i>
</th>
<th onClick={this.sortChanged.bind(this,'City',this.state.Data.sortOrder)}>
City
<i className={this._sortClass('City')}></i>
</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
<pager Size={this.state.Data.totalPage} onPageChanged={this.pageChanged} currentPage={this.state.Data.currentPage}/>
</div>
);
}
});
ReactDOM.render(<EmployeeGridTable dataUrl="/home/getEmployeeList"/>, document.getElementById('griddata'));