Admin page Product gallery livewire full page multi image upload - laravel-livewire

I'm trying to make a product gallery for the e-commerce page on the admin side, while uploading bulk products, the row in the table provides two times again.
$this->validate([
'title' => 'required',
'NewsImage.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'product_id' => 'required',
]);
if(!empty($this->NewsImage)) {
foreach ($this->NewsImage as $image) {
$imageName = $image->hashName();
$image->store('public/products');
Image::create([
'title' => $this->title,
'image' => $imageName,
'product_id' => $this->product_id,
]);
}
}
$this->modalFormVisible = false;
$this->reset();
$this->resetFields();
#if(count($NewsImage))
#foreach($NewsImage as $image)
<td class="px-6 py-4 text-sm whitespace-no-wrap">
<img class="w-8 h-8 rounded-full" src="{{ \Illuminate\Support\Facades\Storage::url($Image->image) }}" />
</td>
#endforeach
#endif
I want to list it side by side but I couldn't do it can you help me thank you very much in advance
I shared a related photo, I'm trying to sort the image side by side, but when I add it, it adds an extra row.

Related

Livewire: create and update in two tables

First to say that I am a newbie in Laravel. I have started to develop the frontend of an APP in Laravel Nova with Livewire. The problem is that before, I was able to do operations in my controller but I don't know how to do it in the Livewire resource.
I have a simple form:
<form wire:submit.prevent="submit" class="rounded px-8 pt-6 pb-8 mb-4">
<input type="text" placeholder="Introduzca código" wire:model="code" class="md:inline-block ktext-gray-700 text-sm font-bold mb-2">
<br>
#error('code')
{{$message}}
#enderror
<br>
<input type="text" placeholder="Introduzca tipo" wire:model="access" class="md:inline-block ktext-gray-700 text-sm font-bold mb-2">
<br>
#error('access')
{{$message}}
#enderror
<br><br>
<x-jet-button type="submit">Crear Asistencia</x-jet-button>
</form>
Which inserts three data into a table:
public function submit()
{
//validate
$this->validate();
Attendance::create([
'code' => $this->code,
'ip' => $_SERVER['REMOTE_ADDR'],
'access' => $this->access,
]);
But I want that in a second table, when the "code" field matches (it is in both tables and is a boolean) the code is update in this second table.
How would you do it? Thanks in advance.
Im not a pro laravel but a think any like the code below can help with yout question:
// If you have more than one register with same code:
$infos = SecondTableModel::where('code', $this->code)->get();
foreach ($infos as $info) {
SecondTableModel::find($info->id)->update([
'ip' => $_SERVER['REMOTE_ADDR'],
'access' => $this->access,
// ... OTHERS FIELSDS
]);
}
// If you have only one register on the second table with the same code
SecondTableModel::where('code', $this->code)->first()->update([
'ip' => $_SERVER['REMOTE_ADDR'],
'access' => $this->access,
// ... OTHERS FIELSDS
]);

How to hook event of validation error in livewire 2?

Reading how validations work at https://laravel-livewire.com/docs/2.x/input-validation
I did not find if there is a way in livewire 2 when I have
validation error to hook event as I need to send dispatchBrowserEvent event
to show message with toastr ?
My form is rather big and val;idation field can be out of screen
and I want to pay attention of user that there are validation errors...
Updated Block # 1:
You propose to get rid of livewire validate method and use laravel validate methods, which are written here
https://laravel.com/docs/8.x/validation, like :
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
...
In my conmponent I define all variables under 1 variable $form :
public $form
= [
'name' => '',
'state_id' => '',
...
public function firstStepSubmit()
{
$rules = [
'name' => 'required',
'state_id' => 'required',
];
$validation = Validator::make( $this->form, $rules, Hostel::getValidationMessagesArray());
$failed = $validation->fails();
if ($failed) {
$errorMsg = $validation->getMessageBag();
$focus_field = array_key_first($errorMsg->getMessages());
$this->dispatchBrowserEvent('PersonalPageMessageWarning', [
'title' => 'Personal Hostel',
'message' => 'Your hostel has invalid data !',
'focus_field' => str_replace('form.', '', $focus_field ),
]);
$validation->validate(); // What for this line ? Looks like we really need it ?
return;
}
$this->currentStep = 2;
} // public function firstStepSubmit()
// What for is
$validation->validate();
line inside of failed block ? Do we really need it ?
2) moving to laravel original methods sems for me as step back... Are there some livewire hooks/methods for it ?
Thanks in advance!
I got a solution to that. Let's say you have next:
// in blade
<div class="col-md-6 flex-row">
<label for="name">Name</label>
<input id="name" type="text" class="form-control flex-row" wire:model="name">
#error('name') <span class="error" style="color: #ff0000">{{ $message }}</span> #enderror
</div>
<div class="col-md-6 flex-row">
<label for="last_name">Name</label>
<input id="last_name" type="text" class="form-control flex-row" wire:model="last_name">
#error('last_name') <span class="error" style="color: #ff0000">{{ $message }}</span> #enderror
</div>
.... // all the rest of elements
//in component
public $name, $last_name;
// the rest of properies
public function store()
{
$validation = Validator::make([
'name' => $this->name,
'last_name' => $this->last_name,
.....
], $this->rules());
if ($validation->fails()) {
$errorMsg = $validation->getMessageBag();
$this->dispatchBrowserEvent('focusErrorInput',['field' => array_key_first($errorMsg->getMessages())]);
$validation->validate();
}
//... other code
now, if validation fails, the above validation checks dispatch and event with all the non-validated fields and in the blade's script tag handle the element focus in order of the error bag field. So, if the element is out of windows this will be focused
<script>
window.addEventListener('focusErrorInput', event => {
var $field = '#' + event.detail.field;
$($field).focus()
})
</script>

How to transform PrestaShop 1.7 checkout accordion steps into steps progress bar?

I'm pretty new to PrestaShop and PHP, I was asked to transform the current accordion checkout steps of PrestaShop 1.7 (classic theme) into a steps progress bar. I've got some good enough notions of CSS and a bit of JavaScript but I'm totally at lost when I look at the PrestaShop files. :(
Here some code (what's in comment is what I tried to add to create the steps progress bar).
The checkout-process.tpl is a mystery:
{foreach from=$steps item="step" key="index"}
{render identifier = $step.identifier
position = ($index + 1)
ui = $step.ui
{* steps = $steps *}
}
{/foreach}
Then I've got the checkout-step.tpl:
{block name='step'}
{* <div id="checkout-steps">
<ul id="checkout-steps__bar">
{foreach from=$steps item="step" key="index"}
<li id="{$step.identifier}" class="step-title h3">{$step.title}</li>
{/foreach}
</ul>
</div> *}
<section id="{$identifier}" class="{[
'checkout-step' => true,
'-current' => $step_is_current,
'-reachable' => $step_is_reachable,
'-complete' => $step_is_complete,
'js-current-step' => $step_is_current
]|classnames}">
<h1 class="step-title h3">
<i class="material-icons rtl-no-flip done"></i>
<span class="step-number">{$position}</span>
{$title}
<span class="step-edit text-muted">
<img src="{$urls.img_url}/icn/edit.png" alt="{l s='Update' d='Shop.Theme.Actions'}" class="icn-16" />
{l s='Edit' d='Shop.Theme.Actions'}</span>
</h1>
<div class="content">
{block name='step_content'}DUMMY STEP CONTENT{/block}
</div>
</section>
{/block}
I managed to got the title by editing CheckoutProcess.php:
public function render(array $extraParams = array())
{
$scope = $this->smarty->createData(
$this->smarty
);
$params = array(
'steps' => array_map(function (CheckoutStepInterface $step) {
return array(
'identifier' => $step->getIdentifier(),
'ui' => new RenderableProxy($step),
// Add title to steps array
'title' => $step->getTitle(),
);
}, $this->getSteps()),
);
$scope->assign(array_merge($extraParams, $params));
$tpl = $this->smarty->createTemplate(
$this->template,
$scope
);
return $tpl->fetch();
}
I don't think I'm doing the right thing but if I almost understood what's happening there, I've got no clue where to begin. -_-"
If anybody got some advices or even better (one can always dream) already attempt this kind of modification, I'll be glad for any information, help, code example!!
Thanks in advance.
It took me a while and it's probably not the best way to go, but I managed the transformation by adding my progress bar then overriding the default behaviour with custom CSS and JavaScript.
It's a lot of code, I'm not sure it's useful I post it there but if anyone want some information or the code, I will share it gladly!

Kendo UI External Editing Form

I'm Working on a project in which i have implemented Kendo Grid and when i click the edit button a popup for editing is displayed. But what i want is a separate panel alongside of kendo grid which i have made using [bootstrap][1] and i want to populate it with the editing detail of particular row clicked in the Kendo grid. I have attached the image below to give you an idea what i want. the help bordered area is where i want to populate it showing editable detail of selected row. Any Help??
#(Html.Kendo().Grid<UserItem>()
.Name("usergrid")
.HtmlAttributes(new { style = "width:100%" })
.Columns(columns =>
{
columns.Bound(o => o.FirstName);
columns.Bound(o => o.LastName);
columns.Bound(o => o.EmailAddress);
columns.ForeignKey(o => o.RoleId, (System.Collections.IEnumerable)ViewData["Roles"], "Id", "Description")
.Title("Role");
columns.ForeignKey(o => o.SystemRoleId, (System.Collections.IEnumerable)ViewData["SystemRoles"], "Id", "Description")
.Title("Sys Role");
columns.ForeignKey(o => o.TimeZoneId, (System.Collections.IEnumerable)ViewData["TimeZones"], "Id", "Description")
.Title("Time Zone");
columns.Bound(e => e.DefaultPageSize).Title("Default Page Size");
columns.Bound(o => o.IsActive).Title("Is Active");
columns.Bound(o => o.LastLoginDate).Format("{0:d}").Title("Last Login");
columns.Command(command => { command.Edit().Text("Edit"); });
})
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
<span id="divCompany" style='#(roleName == Constants.SystemRoles.FifthMethod?"":"display:none;")'>
<label class="category-label" for="ddlCompany">Companies :</label>
#(Html.Kendo().DropDownList()
.Name("ddlCompany")
.DataTextField("Name")
.DataValueField("Id")
.AutoBind(true)
.Events(e => e.Change("CompanyChange"))
.HtmlAttributes(new { style = "width: 150px;" })
.BindTo(ViewBag.Companies)
.Value(Convert.ToString(ViewBag.CurrentCompanyID))
)
</span>
#Html.Kendo().Button().Name("btnNewUser").Content("New User").HtmlAttributes(new { #class = "k-button k-button-icontext k-grid-add pull-right" })
<button type="button" data-toggle="modal" data-target="#importUser-pop" class="k-button k-button-icontext pull-right">Import Users</button>
</div>
</text>);
})
.Editable(editable =>
{
editable.Mode(GridEditMode.PopUp);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model =>
{
model.Id(c => c.UserId);
model.Field(c => c.LastLoginDate).Editable(false);
})
.Create(create => create.Action("User_Create", "User").Data("GetCompanyId"))
.Read(read => read.Action("User_Read", "User").Data("GetCompanyId"))
.Update(update => update.Action("User_Update", "User"))
)
.Pageable()
.Sortable()
.Filterable()
.Events(e => e.Edit("grid_Edit"))
)
A complete example already exists in Kendo Docs how to edit records using external forms
A mvvm bounded section <div id="editForm"> to grid row using kendo.bind($("#editForm"), viewModel)

Rails 4 live streaming updates to a bootstrap table row updated with in-place editing

Although I have probably bookmarked every question on this site, I pretty much never post my own questions because I’m afraid of a snarky response. So, apologies in advance if I’m overlooking something totally obvious or simply approaching this the wrong way, but I’ve gotten to the end of the Internet and my head is officially spinning so I’m calling for reinforcements from the Rails community.
I would appreciate any advice on a good way to continually refresh rows in a data table in my Rails 4 app.
The original problem I was trying to remedy is that my coworkers needed simultaneous access to a monthly-generated Excel document. I strongly dislike Excel so I created a better version of those documents in a Rails 4 app that my coworkers now edit simultaneously.
The problem I am currently trying to fix is that they need to see each other’s updates in real time. Table cells are updated by my coworkers (40 simultaneous users max) on my company’s internal webapp. (A Google Spreadsheet is not a viable solution because the data is relational and is much better maintained in my mySql database.)
This is one of my first Rails apps but it’s come a long way since Hello World. At its current state I’m using Rails 4.1.6 and JQuery dataTables combined with the best_in_place gem for in-place editing.
The app is working fine for now but I keep getting emails about dependent cells not updating when new data is entered in other cells in the same row (my coworkers are used to their data being in Excel format and seeing one cell update instantly based on whatever formula). I’m tired of (and honestly embarrassed by) telling them to “refresh the page” to fix their problems. Moreover, I want everyone to be able to see the updates in real time.
I’ve tried the sync gem (using Faye and Thin), but I cannot for the life of me get it to work in any environment and there are literally only two tutorials (sync_example and RailsConf video with no code), neither of which explain how to implement it in a production environment.
I’m currently using Server-Sent Events/EventSource via ActionController::Live (with Puma and Nginx) per TenderLove's Is it live? blog post. The problem with this approach is that I'm not able to close the connection after the client disconnects or navigates to another page so all my database connections are being used up and then the db connection is blocked. This seems to be a known issue for many others but I'm wondering if maybe I'm approaching this the wrong way altogether.
Could the constant looping be a problem? If I changed it back to n.times, won't I lose the connection and just be back at square one??
Here’s my code. #products is my jQuery dataTable and each row is rendered in a partial with unique id.
in my products/show view:
<tbody>
<% #products.each do |product| %>
<%= render partial: '/products/product', :collection => #products %>
<% end %>
</tbody>
</table>
. . .
<script type='text/javascript'>
jQuery(document).ready(function() {
setTimeout(function() {
var source = new EventSource('/application/events');
source.addEventListener('refresh_product_row', function(event) {
var id = JSON.parse(event.data).id;
$.getScript('/products/show.js?id=' + id);
$('#products').dataTable();
});
}, 1);
});
</script>
show.js.erb
$('#products tbody #product_row_<%= #product.id %>').hide();
$('#products tbody #product_row_<%= #product.id %>').replaceWith('<%= escape_javascript(raw render(:partial => "products/product", :object => #product))%>');
$('#products tbody #product_row_<%= #product.id %>').fadeIn('slow');
// Re-activating Best In Place
$('.best_in_place').best_in_place();
in my application controller:
def events
unless ENV['RAILS_ENV'] == 'development'
# SSE expects the `text/event-stream` content type
response.headers['Content-Type'] = 'text/event-stream'
sse = Reloader::SSE.new(response.stream)
start = Time.zone.now
begin
# 10.times do
loop do
Product.uncached do
Product.where('updated_at > ?', start).each do |product|
# data will be streamed to the client every time we call the write method.
sse.write({ :id => product.id }, :event => 'refresh_product_row')
sleep 0.0001
start = product.updated_at
end
end
sleep 1
end
render nothing: true
rescue IOError
# When the client disconnects, we'll get an IOError on write
logger.info "Client disconnected. Stream closed"
ensure
sse.close
end
end
end
and in /lib/reloader/sse.rb
require 'json'
module Reloader
class SSE
def initialize io
#io = io
end
def write object, options = {}
options.each do |k,v|
#io.write "#{k}: #{v}\n"
end
#io.write "data: #{JSON.dump(object)}\n\n"
end
def close
#io.close
end
end
end
Please let me know if you need any more info. Thank you!!
there are lots of code to paste here so check this code out, I just paste the table code of mine, the rest you do as in the tutorial
https://melvinchng.github.io/rails/ActionCable.html#21-initial-setup
index.html.erb
<h1>All Leaderboard Entries</h1>
<div class='container-fluid'>
<div class='row py-3 px-3'>
<div class='col-12 col-sm-8'>
<table id='entry-table' class="table table-hover">
<thead class="thead-light">
<tr>
<th>Leaderboard</th>
<th>Username</th>
<th>Score</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody id="leaderboard_entries">
<%= render #leaderboard_entries.presence || 'leaderboard_entry' %>
</tbody>
</table>
</div>
</div>
</div>
_leaderboard_entries.html.erb
<tr>
<td><%= leaderboard_entry.leaderboard.name%></td>
<td><%= leaderboard_entry.username %></td>
<td><%= leaderboard_entry.score %></td>
<td><%= link_to '<i class="fa fa-eye" style="color:blue"></i> Show '.html_safe, leaderboard_entry %></td>
<td><%= link_to '<i class="fa fa-edit" style="color:orange"></i> Edit '.html_safe, edit_leaderboard_entry_path(leaderboard_entry, :return_to=>"leaderboard_entries") %></td>
<td><%= link_to '<i class="fa fa-trash" style="color:red"></i> Destroy'.html_safe, leaderboard_entry, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>