How to do I pass unique identifier from button to Modal in Handlebars? - node.js

I'm creating a Accounting Web System using Nodejs and Express with Handlebars (.hbs), while using Bootstrap as my main Frontend toolkit. I have a dynamic table with each row consisting of information and three buttons. With delete button ("eliminar"), I'm adding a modal to verify that the user actually wants to delete information instead of by accident.
However, when inserting the modal into my handlebar, the information no longer belongs to its appropriate row but rather the first row from the query object rendered into the handlebar. My code looks like this:
<table class="table table-bordered">
<thead class="thead-dark text-center">
<tr>
<th scope="col">Tipo ID</th>
<th scope="col">Tipo Codigo</th>
<th scope="col">Tipo Descripcion</th>
<th scope="col">Acciones</th>
<th scope="col">Usuario</th>
{{!-- <th scope="col">Tiempo Creado:</th> --}}
</tr>
</thead>
<tbody class="text-center">
{{#each tipoparametro}}
<tr>
<th scope="row">{{this.tipoparid}}</th>
<td>{{this.tipoparcodigo}}</td>
<td>{{this.tipodescripcion}}</td>
<td class="text-center">
<a href="/viewuser/{{this.tipoparid}}" type="button" class="btn btn-outline-info btn-small"><i
class="bi bi-eye"></i>Ver</a>
<a href="/edituser/{{this.tipoparid}}" type="button" class="btn btn-outline-primary btn-small"><i
class="bi bi-pencil"></i>Modificar</a>
<a href="/delete/{{this.tipoparid}}" type="button" class="btn btn-outline-danger btn-small"
value={{this.tipoparid}} data-bs-toggle="modal" data-bs-target="#staticBackdrop"
data-target={{this.tipoparid}}><i class="bi bi-person-x"></i>Eliminar - {{this.tipoparid}}</a>
</td>
{{!-- New --}}
<!-- Modal -->
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
aria-labelledby="staticBackdropLabel" aria-hidden="true" value={{this.tipoparid}}>
<div class="modal-dialog text-center">
<div class="modal-content">
<div class="modal-header text-center">
<h5 class="modal-title w-100" id="staticBackdropLabel">Eliminar
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body ">
Estas seguro que quieres eliminar este Tipo Parametro:
<hr>
<p class="card-text"><strong>Id:</strong> {{this.tipoparid}}</p>
<p class="card-text"><strong>Codigo de Parametro:</strong> {{this.tipoparcodigo}}</p>
<p class="card-text"><strong>Usuario:</strong> {{this.usuarionombre}}</p>
<p class="card-text"><strong>Descripcion:</strong> {{this.tipodescripcion}}</p>
</div>
<div class="modal-footer d-flex justify-content-between">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<a type="button" class="btn btn-outline-danger yes" href="/delete/{{this.tipoparid}}">Eliminar</a>
</div>
</div>
</div>
</div>
{{!-- New --}}
<td>{{this.usuarionombre}}</td>
</tr>
{{/each}}
</tbody>
</table>
Is there a simplified way to pass the unique identifier this.tipoparid into the modal so I can obtain the correct info from each row and not from the first all the time?
It's important for me to output the information inside the modal according to its row.

Related

Sending Data to other route

Hello guys I'm working on a project with Nodejs, Handlebars and Mysql and i want to ask something. I have 2 routes, /page1 and /page2. In /page1 im doing UPDATE and SELECT queries. One of table's column i want it to redirect to /page2 in a label without refresing, is it possible to do that?
Page 1 is 'home'
<script src="/socket.io/socket.io.js"></script>
{{#if removedUser}}
<div class="alert alert-success alert-dismissible fade show" role="alert">
User has been removed.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{{/if}}
<div class="row">
<div class="col-6">
<h1>Users</h1>
</div>
<div class="col-6 d-flex justify-content-end">
+ add user
</div>
</div>
<table class="table table-bordered">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Email</th>
<th scope="col">Credits</th>
<th scope="col" class="text-end">Action</th>
</tr>
</thead>
<tbody>
{{#each rows}}
<tr>
<th scope="row">{{this.id}}</th>
<td>{{this.first_name}}</td>
<td>{{this.last_name}}</td>
<td>{{this.email}}</td>
<td>{{this.credits}}</td>
<td class="text-end" id="text-end">
<div class="input-group input-group-sm mb-3 credits_container">
<form action="/credits/{{this.id}}" method="post" id="form_container">
<input type="number" class="form-control" placeholder="Credits" name="input_credits" id="input_credits"
aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm">
<div class="col-12 d-grid">
<button class="bi bi-plus" id="post_credits" type="submit">Add</button>
</div>
</form>
</div>
{{!-- <i class="bi bi-plus"></i> Add --}}
<i class="bi bi-eye"></i> View
<a href="/edituser/{{this.id}}" type="button" class="btn btn-light btn-small"><i class="bi bi-pencil"></i>
Edit</a>
{{!-- <a href="/{{this.id}}" type="button" class="btn btn-light btn-small"><i class="bi bi-person-x"></i>
Delete</a> --}}
</td>
</tr>
{{/each}}
Label {{this.credits}}
</tbody>
</table>
Page 2 is 'label'
{{#each rows}}
<div class="row">
<label class="label label-default" id="set_input" name="set_input"> {{this.credits}}</label>
</div>
{{/each}}

How to sent an id outside the loop of handlebars to the form inside the handlebars?

<form method="POST" action="/admin/update-blog/{{blogs._id}}">
<div class="form-group">
<label for="exampleInputPassword1">HEADING</label>
<input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value="{{blogs.heading}}" name="heading">
</div>
<br><br>
<div class="form-group">
<label for="exampleInputPassword1">BLOG</label>
<input type="text" class="form-control" id="exampleInputPassword1" value="{{blogs.blog}}" name="blog">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<br><br>
<h2><i><b>Comments</b></i></h2>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Email</th>
<th scope="col">Message</th>
</tr>
</thead>
<tbody>
{{#each blogs.comments}}
<tr>
<th scope="row"></th>
<td>
<form method="POST" action="/admin/delete-comment">
<div class="form-group">
<label for="exampleInputEmail1"></label>
<input type="email" class="form-control" id="myInput"readonly aria-describedby="emailHelp" placeholder="Enter email" value="{{this.email}}" name="email">
</div>
<button type="submit" class="btn btn-danger">delete</button>
</form>
</td>
<td>{{this.message}}</td>
</tr>
{{/each}}
</tbody>
</table>
How can i pass the {{blogs._id}} to a form which is inside a loop called {{#each blogs.comments}} .Is that possible.I am trying to delete a comment based on the email and the id of blog.Here the blog id is there in the top of code which is the first form where it displays the blog .And in the second form it displays the comments for the blog.
For me it is not possible to pass the id from blog to second loop(display comment).
I want to pass the id of blog to the action of the form in second loop(display comment)
THANKS IN ADVANCE😊
<option value="{{id}}">{{title}} {{../externalValue}}</option>
//The ../ path segment references the parent template scope that should be what you want.

Laravel 8 Livewire refresh data after click|model events

I'm trying to create a simple table list view with laravel and livewire component. I can show the component but when I fire an event (change, wiremodel, click) the dataset is not updating, for example, I have an input text to filter my table, when I write on input the request is firing and component is getting it but component nor re-render with the new information
That's my full view
<header class="header py-6">
<div class="flex justify-between">
<h2 class="font-bold text-2xl text-blue-dark leading-tight">
{{ __('messages.Seizures') }}
</h2>
<div class="flex items-end">
<div class="cursor-pointer">
<i class="fas fa-plus-circle text-blue-light text-3xl"></i>
</div>
<div class="pl-8 flex items-center">
<i class="fas fa-filter text-blue-light text-lg"></i>
<input type="text" name="search" id="search-seizure" class="border border-blue-light rounded-full h-8 ml-1 px-4 text-blue-light" wire:model="filter">
</div>
<div class="pl-8 cursor-pointer" wire:click.prevent="toggleTrash()">
#if( $trash )
<i class="fas fa-trash text-blue-light text-xl"></i><i class="fas fa-toggle-on text-blue-light text-xl"></i>
#else
<i class="fas fa-trash text-gray-400 text-xl"></i><i class="fas fa-toggle-off text-xl text-gray-400"></i>
#endif
</div>
</div>
</div>
</header>
<div class="seizure-page">
<table class="table">
<thead>
<tr>
<th>#sortablelink('date', __('messages.Date'), [], ['class' => 'pr-2'])</th>
<th>{{ __('messages.Duration') }}</th>
<th>#sortablelink('location', __('messages.Location'), [], ['class' => 'pr-2'])</th>
<th>{{ __('messages.Notes') }}</th>
<th width="100px" class="text-right">{{ __('messages.Actions') }}</th>
</tr>
</thead>
<tbody>
#foreach($seizures as $seizure)
<tr class="cursor-pointer">
<td>{{ $seizure->date }}</td>
<td class="w-64">{{ $seizure->duration }}</td>
<td>{{ $seizure->location }}</td>
<td class="truncate-cell">{{ $seizure->note }} </td>
<td class="end">
<div class="flex justify-end">
<button wire:click="" class="btn btn-danger btn-sm px-1"><i class="fas fa-info"></i></button>
<button wire:click="edit({{ $seizure }})" class="btn btn-primary btn-sm px-1"><i class="fas fa-pen"></i></button>
<button wire:click="delete({{ $seizure }})" class="btn btn-danger btn-sm px-1"><i class="fas fa-trash text-warm-red"></i></button>
</div>
</td>
</tr>
#endforeach
</tbody>
</table>
<div class="flex justify-center pt-4">
{{ $seizures->links('vendor.pagination.neurons-unchained') }}
</div>
</div>
And this is the component logic
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Seizure;
use Carbon\Carbon;
use Livewire\WithPagination;
class Seizures extends Component
{
use WithPagination;
public $trash = false;
public $filter;
public function render()
{
//TODO: Get paginate number from user settings
$seizures = Seizure::sortable(['date' => 'desc'])
->whereNull('deleted_at')
->where('note', 'like', '%' . $this->filter . '%')
->paginate(10);
if( $this->trash) {
$seizures = Seizure::sortable(['date' => 'desc'])
->whereNotNull('deleted_at')
->where('note', 'like', '%' . $this->filter . '%')
->paginate(10);
}
return view('livewire.seizure.index')
->with('seizures', $seizures->appends(\Request::except('page')))
->layout('layouts.dashboard');
}
public function delete(Seizure $seizure) {
$seizure->deleted_at = Carbon::now();
$seizure->save();
$this->gotoPage(1);
}
public function toggleTrash () {
$this->trash = !$this->trash;
}
}
The toggle button for show elements in trash has same problem
Many thanks

Bootstrap 4 - showing a list of items with texts and icons correctly

Using Bootstrap 4 I can create a list of list-items. Each list-item contains a text and a button with an icon. The icon is taken from Fontello.
On mobile screens (XS media) sometimes the button does not take the icon as button-content. The result is a very small button that does not contain the icon. This looks like on a mobile device:
On Chrome on my Desktop (F12, XS device) the result is as expected.
A diagnosis is: When I add a number of rows, then vertical size of the list-item gets smaller. Adding 10 items, and the list-item is just a few mm high! So, the size of the list-item gets less high, the button gets less high. Has this to do with 'flexbox'?
Why is this so? I know that when you omit to put anything (or any text) in the button, the button will remain very small. How to repair this?
The code for the button (inside Angular 6)
<ul class="list-group" id="cachesOnHikeList">
<li class="list-group-item d-flex flex-row" *ngFor="let cacheonhike of cachesonhike">
<div class="flex-grow-1">{{ cacheonhike.name| slice:0:22 }}</div>
<button type="button" class="btn btn-warning btn-sm" (click)="removeGeocache( cacheonhike.gcid)"><i class="icon-cancel-circled"></i></button>
</li>
</ul>
The 'cachesOnHikeList' CSS class is:
#cachesOnHikeList {
/*max-height: 250px;*/
max-height:35vh;
overflow:auto;
overflow-y:scroll;
}
Plan-B does not work either. This code (with 2 characters added as button text) produces the same results:
<button type="button" class="btn btn-warning btn-sm px-1"
(click)="removeGeocache( cacheonhike.gcid)"> <i class="icon-cancel-circled"></i> </button>
Plan-C: Adding a 'real' character as button text does not help. The 'X' is shown below the small button. The button is similar to the ones on the screenshot.
<button type="button" class="btn btn-warning btn-sm px-1 font-weight-bold"
(click)="removeGeocache( cacheonhike.gcid)">X</button>
The problem of the small buttons may be caused by (my/the) use of flexbox in combination with a scrollable list-groups
Solution 1:
Replace the flexbox solution with the BS4 grid.
<ul class="list-group" id="cachesOnHikeList">
<li class="list-group-item" *ngFor="let cacheonhike of cachesonhike">
<div class="row">
<div class="mr-auto">{{ cacheonhike.naam | slice:0:22 }}</div>
<button type="button" class="btn btn-warning btn-sm font-weight-bold col-2 col-sm-1 px-1" (click)="removeGeocache( cacheonhike.gcid)">X</button>
</div>
</li>
</ul>
Solution 2: responsive BS4 table
Using a Bootstrap 4 table that is Responsive. In this case the width of the columns is determine automatically by Bootstrap.
<div class="row mt-2">
<div class="listMaxEntries">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>GcId</th>
<th>Naam</th>
<th class="d-none d-sm-table-cell">Type</th>
<th class="d-none d-md-table-cell">Actief</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let geocache of geocachesPage.geocaches"
(click)="saveGeocacheInApplicationDataAndEditIt( geocache)">
<td>{{ geocache.gcid | slice:0:9 }}</td>
<td>{{ geocache.naam }}</td>
<td class="d-none d-sm-table-cell">{{ geocache.type }}</td>
<td class="d-none d-md-table-cell">{{ geocache.actief }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Solution 3: BS4 table with Flexbox.
Using this solution you can specify the column widths. In this case the row height is good!
<div class="row mt-2">
<div class="listMaxEntries">
<table id="productSizes" class="table">
<thead>
<tr class="d-flex">
<th class="col-3 col-md-2">GcId</th>
<th class="col-9 col-sm-7 col-md-5">Name</th>
<th class="col-sm-3 d-none d-sm-table-cell">Type</th>
<th class="col-md-2 d-none d-md-table-cell">Actief</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let geocache of geocachesPage.geocaches" class="d-flex"
(click)="saveGeocacheInApplicationDataAndEditIt( geocache)">
<td class="col-3 col-md-2">{{ geocache.gcid | slice:0:9 }}</td>
<td class="col-9 col-sm-7 col-md-5">{{ geocache.naam }}</td>
<td class="col-sm-3 d-none d-sm-table-cell">{{ geocache.type }}</td>
<td class="col-md-2 d-none d-md-table-cell">{{ geocache.actief }}</td>
</tr>
</tbody>
</table>
</div>
</div>
Enjoy Bootstrap 4 -- what a very nice package!

MODX: display elements in groups by two with wrapper for every group

Imagine situation when you need to have output like this
<table>
<tr class="row">
<td class="cell">First resource</td>
<td class="cell">Second resource</td>
</tr>
<tr class="row">
<td class="cell">Third resource</td>
<td class="cell">Fourth resource</td>
</tr>
<tr class="row">
<td class="cell">Fifth resource</td>
<td class="cell">Sixth resource</td>
</tr>
</table>
or like this
<div class="container">
<div class="row"><!--groups-->
<div class="col-md-6">
First resource
</div>
<div class="col-md-6">
Second resource
</div>
<div class="clearfix"> </div>
</div>
<div class="row"><!--group-->
<div class="col-md-6">
Third resource
</div>
<div class="col-md-6">
Fourth resource
</div>
<div class="clearfix"> </div>
</div>
<div><!--group-->
...
</div>
...
...
</div>
As for me this structures are similar for my purpose. I was looking for examples of the usage of placeholders, but do not get it. Please write the example with getResources or PDOTools or similar.
[[pdoResources?
&parents=`0`
&depth=`1`
&tplFirst=`tplFirst`
&tpl=`tpl`
&tplOdd=`tplOdd`
&tplLast=`tplLast`
&tplWrapper=`tplWrapper`
]]
tplFirst
<tr class="row">
<td class="cell">[[+pagetitle]]</td>
tpl
<td class="cell">[[+pagetitle]]</td>
tplOdd
<td class="cell">[[+pagetitle]]</td>
</tr>
<tr class="row">
tplLast
<td class="cell">[[+pagetitle]]</td>
</tr>
tplWrapper
<table>
[[+output]]
</table>

Resources