Select2 Selected item becomes empty on re-select - html

I have select element inside a modal form configured as single selection, I load my data using ajax call. The problem is when I select item1 then hide the modal, when I show the modal again and select item1 again the select field text becomes empty.
First selection:
Second selection:
I tried logging the value and selected object changed.
First selection logged value:
Second selection logged value:
So basically the selected object is changed on the second selection. I tried re-initializing my select2 but still the problem persist. I also checked the response json on my second selection and the content is correct.
my html code:
<div class="modal fade" id="my-modal" tabindex="-1" role="dialog" aria-labelledby="modal-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<form class="w-100" id="my-form">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modal-title" >Modal</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button>
</div>
<div class="modal-body">
<div class="form-group">
<div class="d-flex w-100">
<div class="w-50 d-flex flex-column pr-1">
<div class="d-flex">
<select id="my-select" class="form-control" data-style="select-with-transition">
<option></option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
my javascript code:
$('#my-modal').on('shown.bs.modal', function () {
$('#my-select').select2({
placeholder: "select item",
allowClear: true,
dropdownParent: $('#my-modal'),
ajax: {
url: "/my-url",
dataType: "json",
delay: 250,
data: function(param) {
return {
search: param.term
}
},
processResults: function(data) {
return {
results: data.items
};
},
cache: true
},
escapeMarkup: function(e) {
return e
},
minimumInputLength: 1,
templateResult: function(repo) {
if (repo.loading) {
return repo.text;
}
return `<option value="${repo.id}">${repo.name}</option>`
},
templateSelection: function(item) {
console.log(item);
return item.name
}
});
});

Related

Unable to set value to select2 drop down

To do: Add a city under a country. Then attempt to edit the city record.
I have: City name as a textbox and Country as a Select2 dropdown in the bootstrap modal which is accessed using a Edit button on the page.
Issue - I am unable to set the value of the country in the select2 dropdown retrieved from database using ajax call. I tried all possible combinations to set value. I am able to set value if its a normal dropdown box, but not when it is a select2 box.
This is the html of the select 2 box in the bootstrap
<div class="modal fade" id="edit">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick = "location.reload(true);">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title"><b>Edit City</b></h4>
</div>
<div class="modal-body">
<form class="form-horizontal" method="POST" action="city_edit.php">
<input type="hidden" class="catid" name="id">
<input type="text" name="cityid" id="cityid" hidden>
<div class="form-group">
<label for="name" class="col-sm-3 control-label">City</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="cityname" name="cityname" required>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Country</label>
<div class="col-md-8">
<select data-plugin-selectTwo class="form-control" name="country" id="country" required>
<option value = "">Select Country</option>
<?php
$conn = $pdo->open();
try{
$stmt = $conn->prepare("SELECT country_id,country FROM country where del_flg = 'N' and status = 1");
$stmt->execute();
foreach($stmt as $row)
{
$countryid = $row['country_id'];
$country = $row['country'];
echo "
<option value='".$countryid."'>".$country."</option>
";
}
}
catch(PDOException $e){
echo $e->getMessage();
}
$pdo->close();
?>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-flat pull-left" data-dismiss="modal" onclick = "location.reload(true);"><i class="fa fa-close"></i> Close</button>
<button type="submit" class="btn btn-success btn-flat" name="edit"><i class="fa fa-check-square-o"></i> Update</button>
</form>
</div>
</div>
</div>
JQUERY:
$(document).ready(function() {
$('.js-example-basic-single').select2();
});
$(document).on('click', '.edit', function(e){
e.preventDefault();
$('#edit').modal('show');
var id = $(this).data('id');
getRow(id);
});
function getRow(id){
$.ajax({
type: 'POST',
url: 'city_row.php',
data: {id:id},
dataType: 'json',
success: function(response){
$("input[type=text][name=cityname]").val(response.city);
$('#country').val("1").trigger("change");
}
});
}
inside your ajax, you add option following your country like that
(i suppose response.country is country, either you adapt):
function(response){
var idx=1;
countries=[];
for(var i = 0;i< response.length;i++){
if(countries.includes(response.country) continue;//country already in option?
countries.push(response.country);//i keep the country in array
$("#country").append(new Option(response.country, idx++));//add option to select
}
$("#country").select2();//initialize the select2
}

Load modal html in success ajax response

I have a view controller that is returning ViewComponent which returns a View (.cshtml) containing everthing I need.
In another view I want to use that, so i make ajax call to the controller to get raw html in the response.
Modal
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-
dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data
dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
JS:
$.ajax({
url: 'getModal/blabla',
type: 'GET',
data: {
Id: id
},
success: function (data) {
$('#myModal').modal('show').html(data);
},
error: function (error) {
console.error(error);
},
});
In my ViewComponent I return View like this:
return View("~/Views/MyModal.cshtml", new MyViewModel()
{
Id = obj.id
});
Here is a demo:
TestViewComponent.cshtml(you want to pass data to controller,so you need to use type: 'POST' in ajax):
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-
dismiss="modal">
×
</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data
dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
#section scripts{
<script>
$(function () {
var Id = 1;
$.ajax({
url: '/Test1/RetunSample1ViewComponent',
type: 'POST',
data: {
Id: Id
},
success: function (data) {
$('#myModal').modal('show').html(data);
},
error: function (error) {
console.error(error);
},
});
})
</script>
}
Controller:
public IActionResult TestViewComponent() {
return View();
}
public IActionResult RetunSample1ViewComponent(int Id) {
return ViewComponent("Sample1", new Sample1Model { Id = Id , Name="sample1"}); ;
}
ViewComponents/Sample1:
public class Sample1:ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(Sample1Model s)
{
return View("~/Views/Shared/Default.cshtml",s);
}
}
Views/Shared/Default.cshtml:
#model Sample1Model
Id:<input asp-for="Id" />
Name:<input asp-for="Name" />
result:
You can also use partial view:
Controller:
public IActionResult ReturnPartialView(int Id) {
return PartialView("~/Views/Shared/Default.cshtml", new Sample1Model { Id = Id, Name = "sample1" });
}
View:
$(function () {
var Id = 1;
$.ajax({
url: '/Test1/ReturnPartialView',
type: 'POST',
data: {
Id: Id
},
success: function (data) {
$('#myModal').modal('show').html(data);
},
error: function (error) {
console.error(error);
},
});
})

Create a form for each checkbox in the foreach loop with Laravel

I am trying to create a form for each item (checkboxes) inside the foreach item and save the item to the database whenever the item is checked.
My problem is even I created a form inside the foreach loop, so every item has its own form; when I do inspect the element I find that all item are included in the same form and only the first checked element is saved to the database
here is my code in order to create a form for each item
#foreach($sessions as $session)
<h1> {{$session->quarter}} {{$session->year}} </h1>
#foreach($courses as $course)
#if($session->id== $course->quarterIDFk)
<form action="{{route('course.add')}}" method="POST" id="report" >
<div class="aa">
<div class="dd">
<button >
<section class="checkboxFour">
<input hidden type="checkbox" id="{{ $course->id}}" name="{{$course->id}}" onclick="showComboBox(id)"; />
<label for="{{ $course->id}}"></label>
</section>
</button>
<label class="class_name" value ="{{ $course->id}}" >{{ $course->courseNumber}}</label>
<input hidden type="number" value="{{ $course->id}}" name ="course"/>
</div>
<div class="select-style" id="check{{ $course->id}}" hidden >
<select name="a">
<option value="" selected disabled hidden>Taken on </option>
<option value="Summer">Summer</option>
<option value="Fall">Fall</option>
<option value="Winter">Winter</option>
<option value="Spring">Spring</option>
</select>
</div>
</div>
<!-- The Modal -->
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
Modal body..
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal" >Close</button>
<button type="button" class="btn btn-success" onclick="hideComboBox({{ $course->id}})" data-dismiss="modal">Yes</button>
</div>
</div>
</div>
</div>
#endif
#endforeach
</from>
#endforeach
and i used this ajax script so the page doesn't load whenener i click the submit button
<script>
$(function () {
$('#report').submit(function (e) {
e.preventDefault() // prevent the form from 'submitting'
var url = e.target.action // get the target
var formData = $(this).serialize() // get form data
$.post(url, formData, function (response) { // send; response.data will be what is returned
// alert('report sent')
})
})
})
</script>
and here is the controller function to store checked items to the database
public function store(Request $request)
{
if(!empty($request->a))
{
$claass = new Taken_classes ;
$claass->idUser = Auth::user()->id ;
$claass->idCourse = $request->course;
// $claass->idCourse = 12;
$claass->taken_session = $request->a;
$claass->save() ; }
I expect to save each checked item to the database but just the first checked item is saved

Angular2 Bootstrap modal user inputs + image

I am using a bootstrap model to create and update groups. on the backend side, there are no issues. Below I have my ts and HTML code I used. the modal works fine, but I don't know how to return any values from my form to my ts file so i can use it in an API call.
also for an image I need formdata
in short:
What's the issue: Returning user inputs(+image) in angular 2
!edit! the error i get is:
_co.save is not a function
html:
<app-modal #modal>
<div class="app-modal-header">
header
</div>
<div class="app-modal-body">
<form #modalform="ngForm" (ngSubmit)="save(modalform.value)" >
First name: <input type="text" name="FirstName" ngModel><br>
Last name: <input type="text" name="LastName" ngModel><br>
image: <input type="file" name="image" ngModel><br>
</form>
</div>
<div class="app-modal-footer">
<button type="button" class="btn btn-default" (click)="modal.hide()">Close</button>
<button type="button" class="btn btn-primary" (click)="modal.hide()">Save changes</button>
</div>
</app-modal>
TS:
#Component({
selector: 'app-modal',
template: `
<div (click)="onContainerClicked($event)" class="modal fade" tabindex="-1" [ngClass]="{'in': visibleAnimate}"
[ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}" style=" background: rgba(0,0,0,0.6);">
<div class="modal-dialog" style="padding-top: 25%;">
<div class="modal-content">
<div class="modal-header">
<ng-content select=".app-modal-header"></ng-content>
</div>
<div class="modal-body">
<ng-content select=".app-modal-body"></ng-content>
</div>
<div class="modal-footer">
<ng-content select=".app-modal-footer"></ng-content>
</div>
</div>
</div>
</div>
`
})
export class ModalComponent {
public visible = false;
public visibleAnimate = false;
public show(): void {
this.visible = true;
setTimeout(() => this.visibleAnimate = true, 100);
}
public save(): void{
}
public hide(): void {
this.visibleAnimate = false;
setTimeout(() => this.visible = false, 300);
}
public onContainerClicked(event: MouseEvent): void {
if ((<HTMLElement>event.target).classList.contains('modal')) {
this.hide();
}
}
}
fixed it by placing the save function in the other component

Populate input using #Input inside Bootstrap 4 modal

I have a main page with a table that when a row is clicked on, it uses #Output to send out that row's data (I've already confirmed the data is being sent properly by using it in another place in the project). I then have a Bootstrap 4 modal that pops up when I click the button on the left below where it says "Data Point Information". What I need to do is take the data from the row that was clicked on, and populate the form inside the modal with it.
Main Page:
Modal:
HTML for the modal:
<div class="modal fade" id="myModal2" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog bodyWidth">
<div class="modal-content wide">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Update Data Point</h4>
</div>
<div class="modal-body">
<form class="form-inline" [formGroup]="updateForm" (ngSubmit)="submitForm(updateForm.value)">
<div class="row">
<div class="form-group" [ngClass]="{'has-error':!updateForm.controls['dataPoint'].valid && updateForm.controls['dataPoint'].touched}">
<label>Data Point:</label>
<input class="form-control special" type="text" [formControl]="updateForm.controls['dataPoint']">
</div>
<div class="form-group move" [ngClass]="{'has-error':!updateForm.controls['ICCP'].valid && updateForm.controls['ICCP'].touched}">
<label >ICCP:</label>
<input type="text" class="form-control special" [formControl]="updateForm.controls['ICCP']">
</div>
<div class="form-group" [ngClass]="{'has-error':!updateForm.controls['startDate'].valid && updateForm.controls['startDate'].touched}">
<label>Start Date:</label>
<input [value]="getDate('start')" class="form-control special" type="text" [formControl]="updateForm.controls['startDate']" style="margin-right: 4px;">
</div>
<div style="display:inline-block">
<ngb-datepicker id="special" *ngIf="startCheck;" [(ngModel)]="startDate" (ngModelChange)="showDatePick(0)" [ngModelOptions]="{standalone: true}"></ngb-datepicker>
</div>
<button type="button" class="btn icon-calendar closest" (click)="showDatePick(0)"></button>
<div class="form-group" [ngClass]="{'has-error':!updateForm.controls['endDate'].valid && updateForm.controls['endDate'].touched}">
<label >End Date:</label>
<input [value]="getDate('end')" class="form-control special" type="text" [formControl]="updateForm.controls['endDate']">
</div>
<div style="display:inline-block">
<ngb-datepicker id="special" *ngIf="endCheck;" [(ngModel)]="endDate" (ngModelChange)="showDatePick(1)" [ngModelOptions]="{standalone: true}"></ngb-datepicker>
</div>
<button type="button" class="btn icon-calendar closer" (click)="showDatePick(1)"></button>
</div>
</form>
</div>
<div class="modal-footer">
*All Fields Are Required. End Date must be after Start Date
<button type="submit" class="btn" [disabled]="!updateForm.valid" data-dismiss="modal">Update</button>
<button type="button" (click)="resetForm()" class="btn" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
Typescript for the modal:
#Component({
selector: 'update-validation',
styleUrls: ['../app.component.css'],
templateUrl: 'update.component.html',
providers: [DatePipe]
})
export class UpdateComponent {
#Input() receivedRow:DataTable;
public dt: NgbDateStruct;
public dt2: NgbDateStruct;
public startCheck: boolean = false;
public endCheck: boolean = false;
updateForm : FormGroup;
constructor(fb: FormBuilder, private datePipe: DatePipe){
this.updateForm = fb.group({
'dataPoint' : [DPS[0].tDataPoint, Validators.required],
'ICCP' : [DPS[0].tICCP, Validators.required],
'startDate' : [DPS[0].tStartDate, Validators.required],
'endDate' : [DPS[0].tEndDate, Validators.required]
}, {validator: this.endDateAfterOrEqualValidator})
}
resetForm(){
location.reload();
//this.updateForm.reset();
}
submitForm(value: any){
console.log(value);
}
public getDate(dateName: string) {
let workingDateName = dateName + 'Date';
let timestamp = this[workingDateName] != null ? new Date(this[workingDateName].year, this[workingDateName].month-1, this[workingDateName].day).getTime() : new Date().getTime();
this.updateForm.controls[dateName + 'Date'].setValue(this.datePipe.transform(timestamp, 'MM/dd/yyyy'));
}
public showDatePick(selector):void {
if(selector === 0) {
this.startCheck = !this.startCheck
} else {
this.endCheck = !this.endCheck;
}
}
endDateAfterOrEqualValidator(formGroup): any {
var startDateTimestamp, endDateTimestamp;
for(var controlName in formGroup.controls) {
if (controlName.indexOf("startDate") !== -1) {
startDateTimestamp = Date.parse(formGroup.controls[controlName].value);
}
if (controlName.indexOf("endDate") !== -1) {
endDateTimestamp = Date.parse(formGroup.controls[controlName].value);
}
}
return (endDateTimestamp < startDateTimestamp) ? { endDateLessThanStartDate: true } : null;
}
}
HTML from the main page that places modal there using it's selector (toSend is of type DataTable which is the data from the row I am sending from the main page's Typescript):
<update-validation [receivedRow]='toSend'></update-validation>
Since I'm using #Output and #Input, I'm not sure why receivedRow in my Typescript is undefined.
The reason is that when your component of modal initialized, there were not any receivedRow. You should control it with *ngIf directive and ngOnChange method like that;
//xyz is just any field on your parent component
//in html
<div *ngIf="xyz">
<update-validation [receivedRow]="xyz"></update-validation>
</div>
//in component of modal
ngOnChanges(){
if(receivedRow){
//do whatever you want
}
}