Laravel 4 PHP pagination inside view - php

I use PHP to load XML files. Can I paginate it through the view?
Here's the code I use. When I pull the names from the XML file, I need to paginate them. Could I use the laravels ->paginate();
I use:
#extends('base')
#section('title', 'Monsters')
#stop
#section('main')
<div class="container">
<div class="doc-content-box">
<legend>Monsters</legend>
<?php
$monstersdir = 'C:\Users\E1\Desktop\theforgottenserver-v0.2.15-win64console\Mystic Spirit\data\monster';
if(is_dir($monstersdir)) {
$list = simplexml_load_file($monstersdir.'\monsters.xml');
?>
<table class="table table-striped table-condensed table-content">
<tbody>
<?php
foreach($list as $monster) {
if ($monster['name'] > null) {
echo '
<tr>
<td style="">'.$monster['name'].'</td>
</tr>';
}
}
}
else{
echo '<div class="alert alert-danger"><span class="label label-important">Error parsing your Monsters XML file</span><br /><br /> Invalid path!</div> ';
}
?>
</tbody>
</table>
</div>
</div>
#stop
Any hints? It's really needed. :P

You can create a paginator manually in Laravel by calling Paginator::make(). Invoke the method with 3 arguments, i.e: the items want to display, the total number of items, and how many of those items should be displayed per page. See the docs for an example.

Related

AlpineJS x-for templates

I have a problem with AlpineJS in my complicated app, and I'm finding it very difficult to replicate under a simplified example. This may well mean that it's a bug in Alpine, but I'll ask here for help on the off-chance anyway. I've tried to reduce the code below to only the bare essentials that are necessary to explain the problem, and doing so may have lead to some typos. Therefore please excuse me in advance for any errors that are not related to the problem itself.
I'm using Livewire to synch data between my PHP classes and my AlpineJS front-end. The two variables that are relevant in the PHP class are:
public $colOrder; // users are able to "re-order" columns on their table-view. This preference is saved into their profile and stored in this variable as a 1D array of the column-IDs
public $datasourceData; // contains a 2D data that is pulled from a database with: Model->get()->toArray(); [0 => ['col1'=>'data1,1', 'col2'=>'data1,2'], 1 => ['col1'=>'data2,1', 'col2'=>'data2,2']];
These arrays are then entangled with Alpine variables, and the template is generated from those arrays of data as follows. Ostensibly, this template works fine:
<div x-data="{
eColOrder: #entangle('colOrder').defer,
eData: #entangle('datasourceData').defer
}">
<table class="table" x-cloak>
<thead>
<tr>
<template x-for="(col, ix) in eColOrder" :key="'th-'+ix">
<th x-text="col"></th>
</template>
</tr>
</thead>
<tbody>
<template x-if="eData.length==0">
<tr>
<td :colspan="eColOrder.length" style="padding: 1em">No data found</td>
</tr>
</template>
<template x-if="eData.length>0">
<template x-for="(rec, ix) in eData" :key="'row-'+ix">
<tr>
<td class="action"></td>
<template x-for="(col, pos) in eColOrder" :key="'td-'+ix+'-'+pos">
<td x-text="rec[col]"></td> <!-- I also tried `eData[ix][col]`, but it produced errors in the browser console, even though the on-screen display was fine -->
</template>
</tr>
</template>
</template>
</tbody>
</table>
In this screen-shot, you can see that the user's search (in the top-row) has produced a tabulated grid of data below. Happy days.
The problem arises when the user re-submits a different search. They do so by updating the search fields, and pressing the "search" button again. This re-submits the search (through a Livewire JSON call), refreshing the $datasourceData array with new data, entangling itself with the eData variable in Alpine, and producing the following result:
What appears to be happening, is that the results of the new search are correctly pulled through. But for whatever reason, Alpine hasn't cleared the screen from the last set of search-results. It's interesting that only the data-level of the HTML table is corrupted (that is to say, the <td> cells). Note that the <th> cells have (correctly) not been duplicated above the right-hand-half of the new table.
I've debugged and checked that the data returned from the Eloquent models is correct, and that the structure of the data in the entangled JavaScript variable eData is also correct. This problem is not data-related, it's the rendering that's at fault.
My gut-feel is that this is an Alpine bug, but I haven't been able to prove it yet.
My problem stops there. However, in an attempt to replicate the issue and narrow down the cause of the issue, what I've done is to create a simplified Livewire/Blade/Alpine page. Strictly speaking, I wasn't able to replicate the problem there either directly, but I did (accidentally) manage to replicate a similar output when I entered a deliberate "bug" into my code.
Take the following PHP/Livewire component:
<?php
namespace App\Business\Tbd;
use Livewire\Component;
class StartLw extends Component
{
public array $data = [];
public array $headings = [];
public int $count = 0;
public function mount() {
for ($i=1; $i <= 6; $i++) {
$this->headings[] = "col{$i}";
}
$this->data = [];
}
public function formSubmit() {
$src = 1;
$this->data = [];
for ($i=0; $i < 10; $i++) {
$this->data[$i] = [];
for ($y=1; $y <= 6; $y++) {
$this->data[$i]["col{$y}"] = "source {$src} ({$i},{$y})";
}
}
$this->count++;
}
public function relatedToButSeparateFromForm() {
$src = 2;
$this->data = [];
for ($i=0; $i < 4; $i++) {
$this->data[$i] = [];
for ($y=1; $y <= 6; $y++) {
$this->data[$i]["col{$y}"] = "source {$src} ({$i},{$y})";
}
}
$this->count++;
}
public function render()
{
return view('components.tbd.lw-start-lw')
->layout('layouts.tbd.lw');
}
}
And this cut-down HTML to render the page:
<div class="container" x-data="{
eData: #entangle('data').defer,
eHeadings: #entangle('headings').defer
}">
<div class="row">
<div class="col"><p>{{ $count }}</p></div>
</div>
<div class="row">
<div class="col">
<form method="post" wire:submit.prevent="formSubmit">
<p>
<button type="submit">Load data source 1</button>
<button type="button" wire:click="relatedToButSeparateFromForm">Load data source 2</button>
</p>
</form>
</div>
</div>
<div class="row">
<div class="col">
<table>
<thead>
<tr>
<template x-for="hd in eHeadings">
<th x-text="hd" style="padding: 0.5em; background-color:rgb(220,220,230); border: 1px solid rgb(210,210,230)"></th>
</template>
</tr>
</thead>
<tbody>
<template x-for="(row, ix) in eData" :key="ix">
<tr>
<template x-for="(col, pos) in eHeadings" :key="'td-'+ix+'-'+pos">
<td x-text="row[col]" :class="id" style="padding: 0.5em; background-color:rgb(240,240,255); border: 1px solid rgb(210,210,230)"></td>
</template>
</tr>
</template>
</tbody>
</table>
</div>
</div>
</div>
Note the deliberate error! On the <td> element, :class="id" should really say :class="col". Now if I take out the error, the page works as I would expect it to. But with the error re-introduced into the code (together with a bunch of error messages in the browser console saying: Uncaught ReferenceError: id is not defined), after toggling the two buttons back and forth a bit, I get this:
As I think you'll agree, that picture is spookily reminiscent of the situation I get in my real world application (except that in the real-world-app, I don't end up with any errors in the browser's console).
This leads me to the strong belief that there is a silent bug being triggered somewhere in the Alpine engine which triggers the same net result. I will go and log this on their GitHub support pages too, but I have always found the Stack community to be super useful in the past too. I hope that someone out there is able to help validate that I'm not missing anything obvious!
Posted the issue on the Alpine bug-report pages, and got the response I wanted. See >> https://github.com/alpinejs/alpine/discussions/2523#discussioncomment-1860670
Apparently, it's not an Alpine issue at all. The problem is that Livewire is treading on Alpine's toes. Livewire "watches" the DOM for updates, and it seems that it's then failing to release (or clean-up, or whatever the correct term is) certain subsections of the DOM as Alpine refreshes it with the new load of data. This explains why earlier incarnations of the DOM are hanging about for longer than they are required.
Resolution is to force Livewire to not-watch the DOM for differences by using the wire:ignore directive. This can be put on the <table> itself, or any parent element thereof. In my example I put it on the immediately encapsulating <div>:
<div class="whoopsie" wire:ignore>
<table>
<!-- etc -->
<tbody>
<template x-for="(col, pos) in eColOrder" :key="'td-'+ix+'-'+pos">
<td x-data="row[col]"></td>
</template>
</tbody>
<!-- etc -->
</table>
</div>

How to acces class attributes from another file in PHP

I want to access class attributes from another of my files but I don't know how.
I am creating a class whose goal is to generate a CRUD table with the data passed in the parameters (table name, ID and table fields).
I have created the class in the file main.php, but I am also using an external file called res.php, this file will be in charge of making the calls to the database and building the table.
Once the class is finished and ready to be used, its function will be that in any file of all of my projects. If I instantiate an object of that class, a CRUD table will be created using the following:
$test = new GenerateCrud('users_test', 'id', ['usuario', 'apellido1', 'apellido2', 'email']);
$test->showTable();
My problem: To create the table, I have to access the attributes of the class, since I need to print the table name, fields, etc.
What happens to me? I don't know how to do it.
My class file main.php:
<?php
class GenerateCrud {
// Properties.
public $tableName;
public $id;
public $tableFields = array();
// Constructor.
function __construct($tableName, $id, $tableFields){
$this->tableName = $tableName;
$this->id = $id;
$this->tableFields = $tableFields;
}
}
?>
My external file res.php:
<?php
include_once('main.php');
?>
<div class="container caja">
<div class="row">
<div class="col-lg-12 col-sm-12">
<div>
<table id="tablaUsuarios" class="table table-striped table-bordered table-condensed" style="width:100%" >
<thead class="text-center">
<tr>
<!-- CREATE FOR EACH TO SHOW THE TABLE FIELDS -->
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
var tableName = "<?php echo $this->tableName; ?>"; // HEREEEEEEEEEEEEEEEEEEE
console.log(tableName);
});
</script>
<?php
}
?>
I am aware that the variable $this does not point to anything, since I have not instantiated an object, but, then, is it as easy as instantiating an object and that's it? I won't get the information wrongly altered or anything like that? Won't it cause me problems later when I instantiate the object again?
I know I'm not describing the problem very well and I'm aware that I lack knowledge, that's obvious, that's why I'm here asking to try to learn.
If someone can explain to me the reason for their explanation to get to understand this, I would appreciate it very much.
Thank you and have a nice day.
in order to access property tableName you have to initialize GenerateCrud object first. Nor in main.php nor in res.php I don't see object initialization.
You said that to generate CRUD table you use
$test = new GenerateCrud('users_test', 'id', ['usuario', 'apellido1', 'apellido2', 'email']);
$test->showTable();
but where it is added in your code?
is it in main.php or res.php
I will suggest to you that you will add this peace of code to the top part of your main.php file and then you will be able to get tableName property
something like this
<?php
include_once('main.php');
$test = new GenerateCrud('users_test', 'id', ['usuario', 'apellido1', 'apellido2', 'email']);
?>
<div class="container caja">
<div class="row">
<div class="col-lg-12 col-sm-12">
<div>
<table id="tablaUsuarios" class="table table-striped table-bordered table-condensed" style="width:100%" >
<thead class="text-center">
<tr>
<!-- CREATE FOR EACH TO SHOW THE TABLE FIELDS -->
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
var tableName = "<?= $test->tableName; ?>"; // HEREEEEEEEEEEEEEEEEEEE
console.log(tableName);
});
</script>
Assuming this code:
$test = new GenerateCrud('users_test', 'id', ['usuario', 'apellido1', 'apellido2', 'email']);
$test->showTable();
is in your res.php file (or in a file which is included from it), then try
echo $test->tableName;
$test is the name of the object you instantiated. $this is only used inside the class, to allow it to self-reference.

Laravel Destroy Option not deleting

Why do this occurs? This is my index lists of all accounts. I want to just delete a specific category by that category.destroy route but it's
index.blade.php
#extends('layouts.master')
#section('title','All Categories')
#section('contents')
<div class="row">
<div class="col-md-8 col-sm-4 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">All Categories</div>
<div class="panel-body">
<article>
<div class="table-responsive-vertical shadow-z-1">
<!-- Table starts here -->
<table id="table" class="table table-hover table-mc-light-blue">
<thead>
<tr>
<th>ID No</th>
<th>Category</th>
<th>Edit/Delete</th>
<th>Status</th>
</tr>
</thead>
#foreach($categories as $category)
<tbody>
<tr>
<td data-title="ID">{{$category->id}}</td>
<td data-title="Name">{{$category->name}}</td>
<td>Edit
&nbspDelete
</td>
</tr>
</tbody>
#endforeach
</table>
</div>
</article>
</div>
</div>
</div>
</div>
#endsection
#section('js')
{!!Html::script('assets/js/jquery.min.js')!!}
{!!Html::script('assets/js/bootstrap.min.js') !!}
<script>
$('#flash-overlay-modal').modal();
</script>
<script>
$('div.alert').not('.alert-important').delay(3000).fadeOut(350);
</script>
#endsection
CategoryController.php
public function destroy($id){
$category = Category::findOrFail($id);
$category->delete();
Session::flash('flash_message', 'Task successfully deleted!');
return redirect()->route('category.index');
}
instead it just displays the view specific entry of the category. It's not deleting or something
To access your destroy route, you have to use the DELETE HTTP request verb. HTML links only allow GET requests.
You should either change your HTML link to an HTML form that spoofs the DELETE method, or look into using something like restfulizer.js that will automatically convert your delete links to delete forms.
As has been suggested, you could also create a GET route for the delete functionality, but there are potential consequences to this. GET and HEAD requests should generally be thought of as "read only" requests, and should not modify any data. POST, PUT, PATCH, and DELETE requests are generally thought of as "write" requests. A web spider may crawl your delete links and end up deleting all your data, or a web browser may pre-fetch all the GET requests on a page, so the delete link is accessed even though no one clicked the delete button. There are a lot of potential nasty things that can happen when you start allowing GET requests to modify data. There is some good information in this answer.
Try with this route:
Route::get('category/{category}/destroy',[
'uses'=>'CategoryController#destroy',
'as' => 'category.destroy'
]);

Yii2 rendering in a specific div

I'm using Yii2-advanced-template. I've 2 divisions on my form as follows - When I'll click on any of the radio button in 2nd div, the details of respective entry should be loaded in 1st div. That is, the form in 1st div will remain as is, but loads some values for update operation. But I'm getting it as - which is not what I expect. It is loading the whole page layout in that div.
I already used 'renderPartial()' in my controller. But it solved only the half of the problem, that is, the navigation bar & other layout is hidden after using renderPartial().
My form is as follows-
<div class="col-sm-12">
<div class="col-sm-6 fillitemform">
...
Enter Item Details form
...
</div>
<div id="item_details" class="col-sm-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Item details</h3>
</div>
<div class="panel-body">
<div class="table-responsive" >
<table class="table">
<thead>
<tr><th></th>
<th>PO No.</th>
<th>SKU</th>
<th>Order Type</th>
<th>Expected Qty</th>
<th>Received Qty</th>
<th>Weight</th>
</tr>
</thead>
<tbody>
<?php
for($itr = 0, $ro = $modelRO, $rod = $modelROD; $itr < count($modelROD); ++$itr){
echo '<tr onclick="placeitemdtls('.$rod[$itr]['id'].')">';
echo '<td><input type="radio" name="item"></td>';
echo '<td>'.$ro[0]['ro_po_no'].'</td>';
echo '<td>'.$rod[$itr]['rod_sku'].'</td>';
echo '<td>'.$ro[0]['ro_order_type_id'].'</td>';
echo '<td>'.$rod[$itr]['rod_expected_qty'].'</td>';
echo '<td>'.$rod[$itr]['rod_received_qty'].'</td>';
echo '<td>'.$rod[$itr]['rod_weight'].'</td>';
echo '</tr>';
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
My JS/jQuery function-
function placeitemdtls(id){
$.post("index.php?r=receiving-order-details/update&id="+id, function(response) {
jQuery(".fillitemform").html(response);
});
}
My Controller function-
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelRO = ReceivingOrders::find()->where(['id' => $id])->all();
$modelROD = ReceivingOrderDetails::find()->where(['receiving_order_id' => $id])->all();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['create', 'id' => $id]);
} else {
return $this->renderPartial('update', [
'model' => $model, 'modelRO' => $modelRO, 'modelROD' => $modelROD,
]);
}
}
Please note that, I'm getting the correct form with proper values, but having rendering problem as I showed in 2nd image. Please help me to solve it. So that my output should look like -

keep data in codeigniter without flash data

I created a management system in codeigniter that loads data from the database in datatables for specific suppliers. When the user clicks at any of these data rows he is navigating to each supplier's company products. My problem is that I want to find a session or something else that will keep the data of the previous selected rows when the page reloads. At the moment I am using flashdata but when I go back a step or return to the previous page all the data from the database disappear. What I want is something that will keep my data even if I am reloading the page or if I go back a step.
That's my controller:
public function __construct() {
parent::__construct();
$this->load->library('form_validation');
$this->load->model('dash_match_model');
$this->session->keep_flashdata('supplier_id');
$this->session->keep_flashdata('segment');
$this->session->keep_flashdata('class');
$this->session->keep_flashdata('commodity');
$this->load->library('session');
$this->load->helper('url');
}
public function index() {
$arr['page']='dash1';
$user_id = $this->session->userdata('id');
$supplier = $this->dash_match_model->dash_present_all_suppliers($user_id);
$arr['dash_present_all_suppliers'] = $supplier;
$this->load->view('clients/clDashboard',$arr);
}
public function select_supplier()
{
$supplier_name = $this->input->get('name', TRUE);
$supplier_sel = $this->dash_match_model->selected_supplier_id($supplier_name);
foreach ($supplier_sel->result() as $row){
$this->session->set_flashdata('supplier_id', $row->supplier_id);
}
$selected_supplier = $this->dash_match_model->unspsc_matched_skus($this->session->flashdata('supplier_id'));
$arr['dash_present_all_selected_suppliers'] = $selected_supplier;
$this->load->view('clients/unspscSegment', $arr);
}
public function select_segment(){
$segment = $this->input->get('segment', TRUE);
$supplier_id = $this->session->flashdata('supplier_id');
$this->session->set_flashdata('segment', $segment);
$segment_sel =$this->session->flashdata('segment');
$selected_segment = $this->dash_match_model->unspsc_class($supplier_id, $segment_sel);
$arr['dash_present_all_selected_segments'] = $selected_segment;
$this->load->view('clients/unspscClass', $arr);
}
public function select_class(){
$class = $this->input->get('class', TRUE);
$supplier_id = $this->session->flashdata('supplier_id');
$segment_sel =$this->session->flashdata('segment');
$this->session->set_flashdata('class', $class);
$class_sel = $this->session->flashdata('class');
$selected_class =$this->dash_match_model->unspsc_commodity($supplier_id, $segment_sel, $class_sel);
$arr['dash_present_all_selected_class'] = $selected_class;
$this->load->view('clients/unsspscCommodity', $arr);
That's one of my first table view file with suppliers:
<div class="row-fluid sortable">
<div class="box span12">
<div class="box-header" data-original-title>
<div class="box-icon">
<i class="halflings-icon wrench"></i>
<i class="halflings-icon chevron-up"></i>
<i class="halflings-icon remove"></i>
</div>
</div>
<div class="box-content">
<table id="suppliertable" class="table table-striped table-bordered bootstrap-datatable datatable">
<thead>
<tr>
<th>Supplier</th>
<th>Open Range</th>
<th>Fill Content</th>
<th>Total Match</th>
</tr>
</thead>
<tbody>
<?php foreach($dash_present_all_suppliers as $v): ?>
<tr>
<td class="center" style="color:#0c595b;"><?php echo $v['supplierCompany']?> </td>
<td class="center">70%</td>
<td class="center">12%</td>
<td class="center">82%</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div><!--/span-->
</div>
Instead of using $this->session->flashdata() user the normal session i.e. $this->session->userdata() to store the temp browse data and write a cron which will delete this session in a regular interval or at the time of logout or any desired specific action.
Hope this will give better approach n help you in solving your problem

Categories