I'm using ABP 2.1.2 and on a form I have some controls hidden in a <div> with an *ngIf but when the <div> is revealed the floating labels don't animate so the user's text is badly merged with the label text.
component.html
<div bsModal #createServiceProviderModal="bs-modal" class="modal fade" (onShown)="onShown()" tabindex="-1" role="dialog"
aria-labelledby="createDigitalAssetModal" aria-hidden="true" [config]="{backdrop: 'static'}">
<div class="modal-dialog">
<div #modalContent class="modal-content">
<div class="modal-header">
<button type="button" class="close" (click)="close()" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">
<span>{{l("CreateNewServiceProvider")}}</span>
</h4>
</div>
<div id="identify" *ngIf="step == 'identify'">
<div class="modal-body">
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input materialInput id="emailAddress" type="email" name="EmailAddress" [(ngModel)]="serviceProvider.emailAddress" required class="validate form-control">
<label for="emailAddress" class="form-label">{{l("EmailAddress")}}</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
{{l("Cancel")}}
</button>
<button class="btn btn-info waves-effect" (click)="findServiceProvider()">
{{l("Next")}}
</button>
</div>
</div>
<form *ngIf="active" #createServiceProviderForm="ngForm" id="frm_create_serviceProvider" novalidate (ngSubmit)="save()">
<div id="add" *ngIf="step == 'create'">
<div class="modal-body">
<div class="row clearfix">
<div class="col-sm-12">
<div class="form-group form-float">
<div class="form-line">
<input id="companyName" type="text" name="CompanyName" [(ngModel)]="serviceProvider.companyName" required class="validate form-control">
<label for="companyName" class="form-label">{{l("CompanyName")}}</label>
</div>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-sm-6">
<div class="form-group form-float">
<div class="form-line">
<input id="name" type="text" name="Name" [(ngModel)]="serviceProvider.name" required class="validate form-control">
<label for="name" class="form-label">{{l("Name")}}</label>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group form-float">
<div class="form-line">
<input id="surname" type="text" name="Surname" [(ngModel)]="serviceProvider.surname" required class="validate form-control">
<label for="surname" class="form-label">{{l("Surname")}}</label>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group form-float">
<div class="form-line">
<input id="emailAddress" type="text" name="emailAddress" [(ngModel)]="serviceProvider.emailAddress" disabled class="validate form-control">
<label for="emailAddress" class="form-label">{{l("EmailAddress")}}</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
{{l("Cancel")}}
</button>
<button [disabled]="!createServiceProviderForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
{{l("Save")}}
</button>
</div>
</div>
<div id="identify" *ngIf="step == 'confirm'">
<div class="modal-body">
<span class="text-success">{{l('ServiceProviderAlreadyExists')}}</span>
<br>
<table class="table">
<tr>
<td class="col-span-3"><label class="pull-right">{{l('Name')}}</label></td>
<td>{{serviceProvider.name}}</td>
</tr>
<tr>
<td><label class="pull-right">{{l('Surname')}}</label></td>
<td>{{serviceProvider.surname}}</td>
</tr>
<tr>
<td><label class="pull-right">{{l('Company')}}</label></td>
<td>{{serviceProvider.companyName}}</td>
</tr>
<tr>
<td><label class="pull-right">{{l('Email Address')}}</label></td>
<td>{{serviceProvider.emailAddress}}</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button [disabled]="saving" type="button" class="btn btn-default waves-effect" (click)="close()">
{{l("Cancel")}}
</button>
<button [disabled]="!createServiceProviderForm.form.valid || saving" type="submit" class="btn btn-primary waves-effect">
{{l("Save")}}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
component.ts
import { Component, ViewChild, Injector, Output, EventEmitter, ElementRef } from '#angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { ServiceProviderServiceProxy, ServiceProviderDto } from '#shared/service-proxies/service-proxies';
import { AppComponentBase } from '#shared/app-component-base';
#Component({
selector: 'create-service-provider-modal',
templateUrl: './create-service-provider.component.html'
})
export class CreateServiceProviderComponent extends AppComponentBase {
#ViewChild('createServiceProviderModal') modal: ModalDirective;
#ViewChild('modalContent') modalContent: ElementRef;
#Output() modalSave: EventEmitter<any> = new EventEmitter<any>();
serviceProvider: ServiceProviderDto = new ServiceProviderDto({id: 0, isUser: false});
step: string = "identify";
active: boolean = false;
saving: boolean = false;
constructor(
injector: Injector,
private serviceProviderService: ServiceProviderServiceProxy,
) {
super(injector);
}
show(): void {
this.active = true;
this.modal.show();
this.serviceProvider = new ServiceProviderDto({id: 0, isUser: false});
this.step = "identify";
}
onShown(): void {
$.AdminBSB.input.activate($(this.modalContent.nativeElement));
}
save(): void {
this.saving = true;
this.serviceProviderService.create(this.serviceProvider)
.finally(() => { this.saving = false; })
.subscribe(() => {
this.notify.info(this.l('SavedSuccessfully'));
this.close();
this.modalSave.emit(null);
});
}
close(): void {
this.active = false;
this.modal.hide();
}
findServiceProvider(): void {
this.saving = true;
abp.ui.setBusy();
this.serviceProviderService.getUserAsProvider(this.serviceProvider.emailAddress)
.finally(() => {
this.saving = false;
abp.ui.clearBusy();
})
.subscribe((next) => {
console.log(next);
if (next.id !== undefined) {
this.serviceProvider = next;
this.step = "confirm";
}
else {
this.step = "create";
}
})
}
}
Issue
When this modal is displayed the variable step is set to "identify" and the first section is displayed where the user must capture the service provider's email address. When the user clicks 'Next' I check if the service provider already exists and then change step to either "create" or "confirm". When the div for creating a service provider is displayed the labels for the input don't animate
Presumably I must re-run some kind of animation script but I cannot figure out what. Please help!
I think the problem was that I needed to call onShown() after revealing the div
Related
I want to update multiple record related to project and I have already made logic for store data in controller; it's perfectly adding multiple record but I have no idea how to do so.
I want to also update multiple record that already exist in database.
https://ibb.co/sjNKMzJ
Model Issue
public function project()
{
return $this->hasOne('App\Project','project_id',id)
}
Model Project
public function issue()
{
return $this->hasMany('App\Issue','id','project_id')
}
return response
// http://localhost/hourlog/cms/public/projects/43/issues/update
{
"_token": "S6typbw0hywPqaUdxCTqWeJNieyl3VieQhCHqDZ7",
"date": [
"2020-07-06",
"2020-07-22",
"2020-07-11"
],
"issue": [
"edit issue",
"delete issue on web",
"update issue on cms"
]
}
Controller
public function issuesUpdate(Request $request, Project $project)
{
$issues =Issue::where('project_id',$project->id)->get();
//for add new record
foreach($request->date as $key2 => $val){
$issue = new Issue;
$issue->date = $val;
$issue->issue = $request->issue[$key2];
$issue->project_id = $project->id;
$issue->save();
}
return redirect()->route('project');
}
html view
<form action="{{ route('project.issues.update',[$project->id])}}" method="POST">
#csrf
<div class="portlet">
<div class="portlet-heading bg-light-theme">
<h3 class="portlet-title">
<span class="ti-user mr-2">
</span>Add Issues
</h3>
<div class="portlet-widgets">
<span class="divider">
</span>
<button type="submit" class="btn btn-white waves-effect btn-rounded">
<span class="btn-label">
<i class="fa fa-save">
</i>
</span> Save
</button>
</div>
<div class="clearfix">
</div>
</div>
<div id="bg-inverse" class="panel-collapse collapse show" style="">
<div class="portlet-body">
<div class="card-box">
<div class="row">
<div class="col-md-12 mt20">
<div class="addMore">
<div class="addmore_cont">
<div class="addMore_btn">
<div class="mt12 pull-right">
<button type="button" title="Add More" class="btn btn-success waves-effect
waves-light btn-sm add_more" data-key="">
<i class="fa fa-plus">
</i>
</button>
</div>
<div class="row addmore_issues">
<div class="col-md-12">
#if(count($issues))
#foreach($issues as $key => $details)
<div class="row">
<div class="col-md-5">
<div class="form-group">
<input required type="date" value="{{$details->date}}"
name="date[]" class="form-control"
aria-describedby="emailHelp" >
</div>
</div>
<div class="col-md-5">
<div class="form-group">
<input required type="text" value="{{$details->issue}}"
name="issue[]" class="form-control"
aria-describedby="emailHelp" placeholder="Issue...">
</div>
</div>
<div class="col-md-1 mt12">
<button type="button" class="btn btn-danger waves-effect waves-
light btn-sm delete">
<i
class="fa fa-times">
</i>
</button>
</div>
</div>
#endforeach
#else
<div class="row">
<div class="col-md-5">
<div class="form-group">
<input required type="date" value="" name="date[]" class="form-control"
aria-describedby="emailHelp" >
</div>
</div>
<div class="col-md-5">
<div class="form-group">
<input required type="text" value="" name="issue[]" class="form-control"
aria-describedby="emailHelp" placeholder="Issue...">
</div>
</div>
</div>
#endif
</div>
</div>
<!--end row-->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
Route
Route::post('/projects/{project}/issues/update', "ProjectController#issuesUpdate")-
>name('project.issues.update');
First change your data format from
"date": [
"2020-07-06",
"2020-07-22",
"2020-07-11"
],
"issue": [
"edit issue",
"delete issue on web",
"update issue on cms"
]
To
[
["date"=>"2020-07-06","issue"=>"edit issue"],
["date"=>"2020-07-22","issue"=>"delete issue on web"],
["date"=>"2020-07-11","issue"=>"update issue on cms"]
]
And you can make it by using like below html format
<input required type="date" value="{{$details->date}}"
name="issues[{{$key}}][date]" class="form-control"
aria-describedby="emailHelp" >
Inside Controller
public function issuesUpdate(Request $request, Project $project)
{
$issues = $request->issues;
$insertData = [];
foreach($issues as $key=>$issue){
$issue["project_id"] = $project->id;
$insertData[] = $issue;
}
Issue::where('project_id',$project->id)->delete();// to not insert duplicate issues for the same project
Issue::insert($insertData);
return redirect()->route('project');
}
Im pretty new to web development, im creating basic CRUD for my intern project. My client asked me to make a single create form where i need to upload those input to database, lets say i have 3 table : Shops,Fruits (one shop has many fruits), and Vegetables (one shop has many vegetables)
I ended up making multiple forms, which one main form for the shop input, and some additional form inside modal for fruits and vegetables input (forms are separated).
After submitting and passing to controller, i can only get input from shop form and not the others.
Scripts and styles:
<link rel="stylesheet" href="/css/bootstrap.min.css">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<script type="text/javascript">
$(document).ready(function(){
//Adding and removing fruit table row
$(".fruit-add").click(function(){
var fruit_pic = $("#fruit_pic").val();
var fruit_pic_name = $("#fruit_pic").val().replace(/C:\\fakepath\\/i, '')
var fruit_name = $("#fruit_name").val();
var markup = "<tr><td>" + fruit_pic_name + "</td><td>" + fruit_name + "</td><td>" + "<button type='button' class='fruit-remove'> Delete </button>" + "</td></tr>";
$(".fruit-table").append(markup);
});
$("body").on("click",".fruit-remove",function(){
$(this).parents("tr").remove();
});
//Adding and removing vegetable table row
$(".vegetable-add").click(function(){
var vegetable_pic = $("#vegetable_pic").val();
var vegetable_pic_name = $("#vegetable_pic").val().replace(/C:\\fakepath\\/i, '')
var vegetable_name = $("#vegetable_name").val();
var markup = "<tr><td>" + vegetable_pic_name + "</td><td>" + vegetable_name + "</td><td>" + "<button type='button' class='vegetable-remove'> Delete </button>" + "</td></tr>";
$(".vegetable-table").append(markup);
});
$("body").on("click",".vegetable-remove",function(){
$(this).parents("tr").remove();
});
});
</script>
My shop form:
<form method="post" action="/add-shop/store" id="addShop" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<label for="shop_name">Shop name</label>
<input type="text" class="form-control" name="shop_name" id="shop_name" aria-describedby="shop_name">
#if($errors->has('shop_name'))
<div class="text-danger">
{{ $errors->first('shop_name')}}
</div>
#endif
</div>
<div class="form-group">
<label> Fruits </label>
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th>Picture</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody class="fruit-table">
</tbody>
</table>
</div>
<!-- Button trigger fruit modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addFruit">
Add fruit
</button>
</div>
<div class="form-group">
<label> Vegetables </label>
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th>Picture</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody class="vegetable-table">
</tbody>
</table>
</div>
<!-- Button trigger vegetable modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addVegetable">
Add vegetable
</button>
</div>
<div class="form-group text-right">
<button type="button" class="btn btn-secondary">Cancel</button>
<button type="submit" class="btn btn-success">Save</button>
</div>
</form>
My forms on popup modal:
<!-- Fruit Modal -->
<div class="modal fade" id="addFruit" tabindex="-1" role="dialog" aria-labelledby="addFruit" aria-hidden="true">
<div class="modal-dialog" role="document">
<form id="form_fruit">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addFruit">Fruit</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="fruit_pic">Picture</label>
<input type="file" accept="image/*" name="fruit_pic[]" id="fruit_pic" class="form-control">
</div>
<div class="form-group">
<label for="fruit_name">Name</label>
<input type="text" name="fruit_name[]" class="form-control" id="fruit_name">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary fruit-add" data-dismiss="modal">Add</button>
</div>
</div>
</form>
</div>
</div>
<!-- Vegetable Modal -->
<div class="modal fade" id="addVegetable" tabindex="-1" role="dialog" aria-labelledby="addVegetavle" aria-hidden="true">
<div class="modal-dialog" role="document">
<form id="form_vegetable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addVegetable">Vegetable</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="vegetable_pic">Picture</label>
<input type="file" accept="image/*" name="vegetable_pic[]" id="vegetable_pic" class="form-control">
</div>
<div class="form-group">
<label for="vegetable_name">Name</label>
<input type="text" class="form-control" name="vegetable_name[]" id="vegetable_name" placeholder="Deskripsi">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary vegetable-add" data-dismiss="modal">Add</button>
</div>
</div>
</form>
</div>
</div>
controller functions:
public function add()
{
return view('add-shop');
}
public function storeTest(Request $request)
{
echo "test\n"; //works
echo $request->fruit_name; //doest work
if($request->hasfile('fruit_pic')){ //doesnt work
foreach($request->file('fruit_pic') as $image){
echo $request->fruit_name;
}
}
echo $request->shop_name; //work
}
When i try to submit the form, i get the shop_name but not all the other form attributes (fruits and vegetables)
I have the feeling that my method is not quite right, what is wrong and is there a better way to applicate this?
just taking a quick look at the form you should use at the action
{{url(}}
{{route()}}
your not getting the shop form because the model it self is not in the form make sure to put it in the same form where you submit the original form tag. alternative if you really want to have it outside you can make a hidden input in the form and put there your data in with java script from the model and then submit the form
do this also to the --vegetable modal--:
<!-- Fruit Modal -->
<div class="modal fade" id="addFruit" tabindex="-1" role="dialog" aria-labelledby="addFruit" aria-hidden="true">
<div class="modal-dialog" role="document">
<form id="form_fruit" method="post" action="{{ url('/add-fruits') }}">
{{ csrf_field() }}
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addFruit">Fruit</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="fruit_pic">Picture</label>
<input type="file" accept="image/*" name="fruit_pic[]" id="fruit_pic" class="form-control">
</div>
<div class="form-group">
<label for="fruit_name">Name</label>
<input type="text" name="fruit_name" class="form-control" id="fruit_name">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary fruit-add" data-dismiss="modal">Add</button>
</div>
</div>
</form>
</div>
</div>
controller
public function addFruits(Request $request)
{
$this->validate($request, [
'fruit_name' => 'required|string',
'fruit_pic.*' => 'mimes:jpeg,jpg,gif,png,bmp|max:8300',
]);
$fruitname=$request->input('fruit_name');
if($request->hasfile('fruit_pic'))
{
foreach($request->file('fruit_pic') as $file)
{
$name=$file->getClientOriginalName();
$file->move(public_path().'/../../example.com/images', $name);
DB::table('tblfruits')->insert([
'fruit_name' => $fruitname,
'fruit_pic' => $name,
]);
}
}
}
route
Route::post('/add-fruits','Controller#addFruits');
i was creating vue file for inpute Excel or csv file laravel 5.7
i was using Maatwebsite/Laravel-Excel
dont know how to route there things it if my first time to make app like laravel with vue JS
Don't know what to doo
there is Vue file
<template>
<div class="container">
<div class="row mt-5">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Students</h3>
<div class="card-tools">
<button class="btn btn-success" data-toggle="modal" data-target="#exampleModal">Add New <i class="fas fa-user-plus"></i></button>
<button class="btn btn-primary" data-toggle="modal" data-target="#importModel">Import <i class="fas fa-file-excel"></i></button>
<button class="btn btn-warning" data-toggle="modal" data-target="#export">Export <i class="fas fa-file-excel"></i></button>
</div>
</div>
</div>
<!-- /.card -->
</div>
</div><!-- /.row -->
<!-- Modal -->
<div class="modal fade" id="importModel" tabindex="-1" role="dialog" aria-labelledby="importModelLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="importModelLabel">Import Excel</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form method="POST" enctype="multipart/form-data">
<div class="modal-body">
<div class="form-group">
<label>Import</label>
<input type="file" name="excel_file"
class="form-control" :class="{ 'is-invalid': form.errors.has('excel_file') }">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save Student</button>
</div>
</form>
</div>
</div>
</div>
<!--Exit Modal-->
</div>
</template>
<script>
export default {
data(){
return{
form: new Form({
first_name:'',
last_name:'',
email:'',
password:'',
designation:''
})
}
},
mounted() {
console.log('Component mounted.')
}
}
</script>
set a post route to import data in web.php file
that will route the things as pr laravelExcel
Route::post('importExcel', 'API/StudentMasterController#import');
in a controller file
public function import()
{
Excel::import(new StudentImport, request()->file('excel_file'));
//return redirect('/')->with('success', 'All good!');
}
and in a APP/import/studentmaster.php file
public function model(array $row)
{
return new Student_master([
'EnrollmentNo' => $row[22],
]);
}
this is vue views and js my code :
<form method="POST" action="#" class="form-horizontal" #submit.prevent="createUpload" enctype="multipart/form-data">
<div class="box-body">
<div class="form-group row"><label for="name" class="col-sm-2 form-control-label">Parameter</label>
<div class="col-sm-10">
<input type="file" class="form-control" id="result_file" ref="myFiles" placeholder="Name Parameter" required="required" #change="previewFiles($event)">
<input type="hidden" name="result_file2" class="form-control" id="title" v-model="datafileupload.result_file3" placeholder="Name Parameter" required="required">
<input type="hidden" name="hasilcek" class="form-control" id="hasilcek" v-model="datafileupload.hasilcek3" placeholder="Name Parameter" required="required">
<input type="hidden" class="form-control" v-model="datapush.filename">
<input type="hidden" class="form-control" v-model="datapush.size">
</div><br><br><br>
<div v-if="this.hasilcekexcel > 0" class="alert alert-warning">File {{ namafile }} exists , do you want to replace it ?</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" #click="doSomethingOnHidden" >Close</button>
<input type="submit" class="btn btn-primary" id="submit_upload2" v-if="this.hasilcekexcel > 0" value="Replace">
<input type="submit" class="btn btn-primary" id="submit_upload" v-if="this.hasilcekexcel == 0" value="Upload">
</div>
</form>
js upload :
createUpload () {
var data = new FormData();
var file = this.$refs.myFiles.files[0];
var size = this.$refs.myFiles.files[0].size;
data.append('filenya', file);
data.append('namasifile', this.datafileupload.result_file3);
data.append('angkacek', this.datafileupload.hasilcek3);
axios.post('excelupload/upload', data)
.then(response => {
this.pesertas.push(response.data.data);
this.showModal =false;
});
},
controller :
$excelupload = new Exceluploads;
$hasilcek = $request->angkacek;
$requestfile = $request->namasifile;
if ($request->filenya != '') {
$input = Input::all();
$size = $request->file('filenya')->getClientSize();
$file = array_get($input,'result_file');
$userID = Auth::user()->id;
$uploaded_by = Auth::user()->name;
$destinationPath = 'excel';
// GET THE FILE EXTENSION
$extension = 'xls';
$fileName = $requestfile.'.'.$extension;
if ($hasilcek > 0) {
File::delete($destinationPath.'/'.$fileName);
$upload_success = $request->filenya->move($destinationPath, $fileName);
return response()->json(['data' => Exceluploads::find($excelupload->id)]);
}else if ($hasilcek == 0) {
$upload_success = $request->filenya->move($destinationPath, $fileName);
$excelupload->filename = $fileName;
$excelupload->directory = $destinationPath.'/'.$fileName;
$excelupload->size = $size;
//1 = not custome
$excelupload->type = 1;
$excelupload->uploaded_by = $uploaded_by;
$excelupload->save();
return response()->json(['data' => Exceluploads::find($excelupload->id)]);
}
}
I just learned vuejs with bootstrap 4 and I tried to display modal provided that when the create button was not clicked then the HTML modal tag is not displayed in the inspect element, and after the create button click bootstrap modal displayed. When the button create first time click HTML modal tag display on inspect element but bootstrap modal cannot be displayed on the browser page and the second time the bootstrap modal can be displayed. Here is the source code that I made with Laravel, can you help me on this issue, thank you.
User.vue
HTML
<template>
<div class="container">
<div class="row">
<div class="col-sm">
<div class="card-deck mb-3">
<div class="card mb-4 box-shadow">
<div class="card-header bg-success text-white">
<h4 class="my-0 font-weight-bold">
<!-- Button create user -->
<button #click="initAddUser()" class="btn btn-danger btn-sm"><i class="fa fa-plus"></i> Create New User</button>
<span class="float-right">User</span>
</h4>
</div>
<div class="card-body">
<!-- Bootstrap modal -->
<div v-if="showModal" class="modal fade" id="add_user_model" tabindex="-1" role="dialog" aria-labelledby="add_user_model_label" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-info text-white">
<h5 class="modal-title" id="add_user_model_label"><i class="fa fa-plus"></i> Add New User</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<!-- Message errors create user -->
<div class="alert alert-danger" v-if="errors.length > 0">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<h5>{{ messages }}</h5>
<ul>
<li v-for="error in errors">{{ error }}</li>
</ul>
</div>
<div class="form-group">
<label class="font-weight-bold" for="name">Name :</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Name" v-model="user.name">
</div>
<div class="form-group">
<label class="font-weight-bold" for="name">Email :</label>
<input type="email" class="form-control" id="email" name="email" placeholder="E-mail" v-model="user.email">
</div>
<div class="form-group">
<label class="font-weight-bold" for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Password" v-model="user.password">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-sm btn-primary" #click="createUser()">Submit</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
Js
<script>
export default {
data() {
return {
user: {
name: '',
email: '',
password: ''
},
errors: [],
users: [],
showModal: false,
}
},
mounted() {
this.readUsers();
},
methods: {
initAddUser() {
this.errors = [];
$("#add_user_model").modal("show");
this.showModal = true;
},
reset() {
this.user.name = '';
this.user.email = '';
this.user.password = '';
},
readUsers() {
axios.get('/user/show')
.then(response => {
this.users = response.data.users;
});
},
createUser() {
axios.post('/user', {
name: this.user.name,
email: this.user.email,
password: this.user.password,
})
.then(response => {
this.reset();
this.users.push(response.data.user);
this.readUsers();
$("#add_user_model").modal("hide");
})
.catch(error => {
this.errors = [];
this.messages = error.response.data.message;
if (error.response.data.errors.name) {
this.errors.push(error.response.data.errors.name[0]);
}
if (error.response.data.errors.email) {
this.errors.push(error.response.data.errors.email[0]);
}
if (error.response.data.errors.password) {
this.errors.push(error.response.data.errors.password[0]);
}
});
}
}
}
</script>
Result images inspect element
This image button first time click https://ibb.co/jKENbU
This image button second time click https://ibb.co/nRy4qp
downloaded latest(3.0) boilerplate with zero.
Followed up the task creator application implementation on codeproject.com
I have added simple entity (Clients) instead of tasks.
The displaying of tasks work fine. However, when I try to add a new client the it seems that the dynamic api is not available and I get the following error:
ClientsController:
`[AbpMvcAuthorize]
public class ClientsController : MyAppControllerBase
{
private readonly IClientAppService _clientService;
public ClientsController(IClientAppService clientService)
{
_clientService = clientService;
}
public async Task<ViewResult> Index(GetAllClientsInput input)
{
var output = await _clientService.GetAll(input);
var model = new Web.Models.Clients.IndexViewModel(output.Items);
return View("Index", model);
}
public async Task Create(CreateClientInput input)
{
await _clientService.Create(input);
}
public async Task Delete(CreateClientInput input)
{
await _clientService.Create(input);
}
}`
Index.js:
(function() {
$(function() {
var _clientService = abp.services.app.client;
var _$modal = $('#ClientCreateModal');
var _$form = _$modal.find('form');
_$form.validate();
_$form.find('button[type="submit"]').click(function (e) {
e.preventDefault();
if (!_$form.valid()) {
return;
}
var client = _$form.serializeFormToObject(); //serializeFormToObject is defined in main.js
abp.ui.setBusy(_$modal);
_clientService.create(client).done(function () {
_$modal.modal('hide');
location.reload(true); //reload page to see new user!
}).always(function () {
abp.ui.clearBusy(_$modal);
});
});
_$modal.on('shown.bs.modal', function () {
_$modal.find('input:not([type=hidden]):first').focus();
});
});
})();
Index.cshtml
#section scripts
{
<environment names="Development">
<script src="~/js/views/clients/Index.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="~/js/views/clients/Index.min.js" asp-append-version="true"></script>
</environment>
}
<div class="row clearfix">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="card">
<div class="header">
<h2>
#L("Clients")
</h2>
<ul class="header-dropdown m-r--5">
<li class="dropdown">
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">more_vert</i>
</a>
<ul class="dropdown-menu pull-right">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
</ul>
</li>
</ul>
</div>
<div class="body table-responsive">
<table class="table">
<thead>
<tr>
<th>#L("UserName")</th>
<th>#L("FullName")</th>
<th>#L("EmailAddress")</th>
<th>#L("IsActive")</th>
</tr>
</thead>
<tbody>
#foreach (var user in Model.Clients)
{
<tr>
<td>#user.FirstName</td>
<td>#user.LastName</td>
<td>#user.Email</td>
<td>#user.Mobile</td>
</tr>
}
</tbody>
</table>
<button type="button" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" data-toggle="modal" data-target="#ClientCreateModal">
<i class="material-icons">add</i>
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="ClientCreateModal" tabindex="-1" role="dialog" aria-labelledby="ClientCreateModalLabel" data-backdrop="static">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form name="userCreateForm" role="form" novalidate class="form-validation">
<div class="modal-header">
<h4 class="modal-title">
<span>#L("CreateNewClient")</span>
</h4>
</div>
<div class="modal-body">
<div class="form-group form-float">
<div class="form-line">
<input class="form-control" type="text" name="FirstName" required maxlength="#AbpUserBase.MaxUserNameLength" minlength="2">
<label class="form-label">#L("FirstName")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="LastName" class="form-control" required maxlength="#AbpUserBase.MaxNameLength">
<label class="form-label">#L("LastName")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" name="Mobile" class="form-control" required maxlength="#AbpUserBase.MaxSurnameLength">
<label class="form-label">#L("Mobile")</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="email" name="Email" class="form-control" required maxlength="#AbpUserBase.MaxEmailAddressLength">
<label class="form-label">#L("Email")</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default waves-effect" data-dismiss="modal">#L("Cancel")</button>
<button type="submit" class="btn btn-primary waves-effect">#L("Save")</button>
</div>
</form>
</div>
</div>
</div>
client service :
[AbpAuthorize(PermissionNames.Pages_Tenants)]
public class ClientAppService : ApplicationService, IClientAppService
{
private readonly IRepository<Client> _clientRepository;
public ClientAppService(IRepository<Client> clientRepository)
{
_clientRepository = clientRepository;
}
public async Task<ListResultDto<ClientListDto>> GetAll(GetAllClientsInput input)
{
var clients = await _clientRepository
.GetAll().ToListAsync<Client>();
return new ListResultDto<ClientListDto>(
ObjectMapper.Map<List<ClientListDto>>(clients));
}
public async Task Create(CreateClientInput input)
{
var task = ObjectMapper.Map<Client>(input);
await _clientRepository.InsertAsync(task);
}
}
the server does not get hit at all on the create action.
any idea what I am missing?
I think there's a misunderstanding with IMustHaveTenant interface. When you derive an entity from IMustHaveTenant you cannot use that entity in host environment. The host has no tenant id. As far as i understand clients are belonging to tenants. So what you have to do is, remove the Clients page from host menu. Whenever you want to see clients of tenants, just use impersonation.
To show/hide specific menu items you can use requiredPermissionName. A permission can be configured to use just for tenants/host/both. So create a new permission which is configured to be used for tenants. Set that permission while you create new MenuItemDefinition for clients page. That's it!
Read => https://aspnetboilerplate.com/Pages/Documents/Navigation?searchKey=navigation#registering-navigation-provider