Laravel 7 - Trouble retrieving old value of dynamic select when validation fails - javascript

The form has a select for Customer with populates from a variable in the controller. I can easily retrieve the old input value using old('customer_id').
My problem comes from the second select. The second select uses javascript to populate the Customer Contact based on which Customer is chosen. When validation fails, I lose that value.
Here is the controller code for the store method:
$rules = [
'number' => 'required',
'customer_id' => 'required',
'contact_id' => 'required',
'payment_type' => 'nullable',
'department_id' => 'required',
'requested_ship_date' => 'required|after:yesterday',
];
$customMessages = [
'number.required' => 'The Sales Order number is required.',
'customer_id.required' => 'Please choose a customer.',
'contact_id.required' => 'Please choose a contact.',
'requested_ship_date.required' => 'You must enter a ship date.',
'requested_ship_date.yesterday' => 'The requested ship date must be today or after.',
'department_id.required' => 'Please choose a department.'
];
$salesorder = \request()->validate($rules, $customMessages);
SalesOrder::create($salesorder);
return redirect('/salesorders');
Here is Customer Select:
<select
name="customer_id"
class="shadow text-sm">
#if (old('customer_id'))
<option
value>
</option>
#else
<option
selected
value>
</option>
#endif
#foreach($customers as $customer)
#if (old('customer_id'))
<option
value="{{ $customer->id }}" {{ old('customer_id') == $customer->id ? 'selected' : '' }}>
{{ ucfirst($customer->name) }}
</option>
#else
<option
value="{{ $customer->id }}">
{{ ucfirst($customer->name) }}
</option>
#endif
#endforeach
</select>
Here is the select for the Customer Contact:
<select
name="contact_id"
class="shadow text-sm text-center"
>
<option>
</option>
</select>
And here is the javascript:
$('select[name="customer_id"]').on('change', function () {
var customerId = $(this).val();
if (customerId) {
$.ajax({
url: '/customer/contacts/get/' + customerId,
type: "GET",
dataType: "json",
beforeSend: function () {
$('#loader').css("visibility", "visible");
},
success: function (data) {
$('input[name="email"]').val('');
$('select[name="contact_id"]').empty();
$('select[name="contact_id"]').append('<option value="Choose">Choose Contact</option>');
$.each(data, function (key, value) {
$('select[name="contact_id"]').append('<option value="' + key + '">' + value + '</option>');
});
},
complete: function () {
$('#loader').css("visibility", "hidden");
}
});
} else {
$('select[name="customer_id"]').empty();
}
});

Related

Laravel 7: How to get name instead of id in dependent dropdown?

I have a dependent dropdown and it gets values by comparing ID's, the issue here is when I am trying to save the form values I am getting the ID's instead of names of the select fields. Can anyone tell me how can I get the NAME instead of ID.
My blade view with the javascript: index.blade.php`
<div class="container">
<h2>Region</h2><br>
<form action="details" method="POST">
{{ csrf_field() }}
<div class="form-group">
<label for="title">Select Country:</label>
<select id="country" name="country" class="form-control" style="width:350px" required>
<option value="" selected disabled>Select</option>
#foreach($countries as $key => $country)
<option value="{{$key}}">{{$country}}</option>
#endforeach
</select>
</div>
<div class="form-group">
<label for="title">Select State:</label>
<select name="state" id="state" class="form-control" style="width:350px" required>
</select>
</div>
<div class="form-group">
<label for="title">Select City:</label>
<select name="city" id="city" class="form-control" style="width:350px" required>
</select>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<script type="text/javascript">
$('#country').change(function() {
var countryID = $(this).val();
if (countryID) {
$.ajax({
type: "GET",
url: "{{url('get-state-list')}}?country_id=" + countryID,
success: function(res) {
if (res) {
$("#state").empty();
$("#state").append('<option value="">Select</option>');
$.each(res, function(key, value) {
$("#state").append('<option value="' + key + '">' + value + '</option>');
});
} else {
$("#state").empty();
}
}
});
} else {
$("#state").empty();
$("#city").empty();
}
});
$('#state').change(function() {
var stateID = $(this).val();
if (stateID) {
$.ajax({
type: "GET",
url: "{{url('get-city-list')}}?state_id=" + stateID,
success: function(res) {
if (res) {
$("#city").empty();
$("#city").append('<option value="">Select</option>');
$.each(res, function(key, value) {
$("#city").append('<option value="' + key + '">' + value + '</option>');
});
} else {
$("#city").empty();
}
}
});
} else {
$("#city").empty();
}
});
</script>
My Controller for the dropdown: DropdownController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class DropdownController extends Controller
{
public function index()
{
$countries = DB::table("countries")->pluck("name", "id");
return view('index', compact('countries'));
}
public function getStateList(Request $request)
{
$states = DB::table("states")
->where("country_id", $request->country_id)
->pluck("name", "id");
return response()->json($states);
}
public function getCityList(Request $request)
{
$cities = DB::table("cities")
->where("state_id", $request->state_id)
->pluck("name", "id");
return response()->json($cities);
}
public function show(Request $request)
{
dd(request()->all());
}
}
The payload I am getting after data dump is the ID's:
array:4 [▼
"_token" => "xxxxxxxxxxxxxxxxxxxxxxxxx"
"country" => "1"
"state" => "5"
"city" => "124"
]
What I want is to get Names:
array:4 [▼
"_token" => "xxxxxxxxxxxxxxxxxxxxxxxxx"
"country" => "country_name"
"state" => "state_name"
"city" => "city_name"
]
You should change the name of your select from name to name[]

How to remove unwanted option value from dropdown?

example 1
<select id="BillTypeId" name="BillTypeId" required="" class="form-control">
<option value=""></option>
<option value="9" tax-groupid="1" data-price="1500.00" data-isfixed="False">LAUNDRY</option>
<option value="1064" tax-groupid="1" data-price="0.00" data-isfixed="False">DEBIT</option>
<option value="1065" tax-groupid="1" data-price="0.00" data-isfixed="False">CREDIT</option>
</select>
Let's suppose I have a dropdown with dynamic option values.
I have a function to retrieve these value from controller.
$.ajax({
url: '/cash/bill/PostingBillTypeCombo',
dataType: 'html',
data: {
name: "BillTypeId",
required: true,
currencyId: selectedCurrencyId
},
method: 'POST',
success: function (data) {
debugger;
if (data.op == "DEBIT" || data.op== "CREDIT")
{
$('#PostingBillTypeComboContainer').html("");
$('#PostingBillTypeComboContainer').html(data);
}
},
});
In my dropdown it has 3 values -credit , debit and laundry.
Within the function (data) I use the data.op to check whether its debit or credit if (data.op == "DEBIT" || data.op== "CREDIT")
(check example 1) if it contain those names remove the rest of the option values eg:LAUNDRY and only show the debit and credit values in the dropdown.
I'm new to this please help me sorry for my poor English
You can do something like this :
if (data.op == "DEBIT") {
$("#BillTypeId option:not(:contains('DEBIT'))").hide();
} else if (data.op == "CREDIT") {
$("#BillTypeId option:not(:contains('CREDIT'))").hide();
}
$("#BillTypeId option:not(:contains('DEBIT'))").hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<select id="BillTypeId">
<option value=""></option>
<option value="9">LAUNDRY</option>
<option value="1064">DEBIT</option>
<option value="1065">CREDIT</option>
</select>
Let's do it with CSS:
.debit-credit option:not(.debit-credit) {
display: none;
}
Let's apply this on the structure:
<select id="BillTypeId" name="BillTypeId" required="" class="form-control">
<option class="debit-credit" value=""></option>
<option value="9" tax-groupid="1" data-price="1500.00" data-isfixed="False">LAUNDRY</option>
<option class="debit-credit" value="1064" tax-groupid="1" data-price="0.00" data-isfixed="False">DEBIT</option>
<option class="debit-credit" value="1065" tax-groupid="1" data-price="0.00" data-isfixed="False">CREDIT</option>
</select>
Then you add debit-credit class to BillTypeId if you want to hide LAUNDRY and remove that class if you want to show it:
$.ajax({
url: '/cash/bill/PostingBillTypeCombo',
dataType: 'html',
data: {
name: "BillTypeId",
required: true,
currencyId: selectedCurrencyId
},
method: 'POST',
success: function (data) {
debugger;
if (data.op == "DEBIT" || data.op== "CREDIT")
{
$('#PostingBillTypeComboContainer').html("");
$('#PostingBillTypeComboContainer').html(data);
$('#BillTypeId').addClass("debit-credit");
} else {
$('#BillTypeId').removeClass("debit-credit");
}
},
});
Here's a proof of concept: https://jsfiddle.net/hz6vqnbj/
$("#BillTypeId option[value=1064]").hide();
if you know which one to hide then use this code to hide the corresponding option by passing its value.

clone form include dependent fields by vuejs

I have a form in which there should be submitting a price for various health care services. Treatments are already categorized. Now, I want to first select a treatment group from a selector and then select the treatment list for that category in the next selector. When I have just one form on the page, I have no problem. But I need to clone this form and the user can simultaneously record the price of some treatments. In this case, all the second selectors are set according to the last selector for the categories. While having to match their category's selector. I searched for the solution very well and did not get it. My code in vuejs is as follows. Please guide me. Thank you in advance.
<template>
<div>
<div id="treatment_information">
<div class="col-md-3">
<select id="category_name" class="form-control show-tick"
v-on:change="getTreatmentList($event)"
name="treatment_rates[]category_id" v-model="treatment_rate.category_id"
>
<option value="0"> -- select category --</option>
<option class="form-control main"
v-for="item in vue_categories" :id="item.id+1000" :value="item.id"
:name="item.name">
{{ item.name }}
</option>
</select>
</div>
<div class="col-md-3">
<select id="treatment_id" class="form-control show-tick"
name="treatment_rates[]treatment_id" v-model="treatment_rate.treatment_id"
>
<option value="0"> -- select treatment --</option>
<option class="form-control main"
v-for="item in vue_treatments" :value="item.id">
{{ item.value }}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
vue_temp: [],
vue_categories: [],
vue_treatments: [],
vue_category: '',
//for clone form
treatment_rate: {
category_id: 0,
treatment_id: 0,
hospital_id: 0,
dollar: 'دلار',
rial: 'ریال'
},
treatment_rates: [],
};
},
mounted() {
console.log('Component mounted.');
this.getList();
},
methods: {
getList() {
var self = this;
axios.get('/vueDashboard/get/categories').then(function (response) {
self.vue_temp = response.data;
const len = self.vue_temp.length;
self.vue_temp.forEach(function (item) {
if (self.vue_right.length > 0) {
while (self.vue_right[self.vue_right.length - 1] < item['rgt']) {
self.vue_right.pop();
if (self.vue_right.length == 0)
break;
}
}
self.vue_categories.push({
'id': item['id'],
'name': '---'.repeat(self.vue_right.length) + ' ' + item['name']
});
self.vue_right.push(item['rgt'])
var str = "---";
});
}).catch(function (error) {
console.log(error);
});
axios.get('/vueDashboard/get/treatments?category=' + JSON.stringify(self.treatment_rates)).then(function (response) {
console.log(response.data);
self.vue_treatments = response.data;
}).catch(function (error) {
console.log(error);
});
},
addForm(event) {
var self = this;
self.vue_increment_id[self.vue_counter++]=self.vue_counter;
console.log(self.vue_increment_id);
self.treatment_rates.push(Vue.util.extend({}, self.treatment_rate));
},
}
}
</script>

Dynamic drop down menu node js

I'm new to node. I need to make a dependent dropdown menu which gets the address data of the selected user from another dropdown menu in the same page..The proplem is that the hole page is updated not only the second dropdown menu.. I think it's the same problem as dynamically dropdown in nodejs mysql, but it didn't help me much.
<select name="selectUser" id="user" >
<option disabled selected> Select User..</option>
<% users.forEach((users) => { %>
<option value="<%= users.id %>" > <%=users.name %> </option>
<% }) %>
</select>
<br>
<label>Address :</label>
<select name="selectAddress" id="address">
<option disabled selected> Select Address..</option>
<% address.forEach((address) => { %>
<option value="<%= address.addressId %>" > <%=address.addressName %> </option>
</select>
<% }) %>
my ajax request:
$(document).ready(function(){
$('#user').change(function(){
var item = $('#user').val();
var add = $('#address').val();
$.ajax({
type:'GET',
data: {selectedId : item },
url:'/order/new',
success: function(result1){
$('#body').html(result1);
}
});
});
});
order.js
module.exports = {
addOrderPage: (req, res) => {
let query1 = "SELECT * FROM users";
getConnection().query(query1, (err, result1) => {
let query2 = "SELECT * FROM address WHERE userId = '" +req.query.selectedId + "'";
getConnection().query(query2, (err, rows, fields) => {
if (err) {
return res.status(500).send(err);
}
console,log(rows)
res.render('newOrder.ejs', {
address : rows,
users: result1
});
});
});
}
}
app.js
app.get('/order/new', addOrderPage)
Your success function has missing the data that is return from request update your success function
$(document).ready(function(){
$('#user').change(function(){
var item = $('#user').val();
$.ajax({
type:'GET',
data: { selectedId: item },
url:'/users/address',
success: function(data){
console.log(data);
$('#address').empty();
$('address').append("<option disabled selected> Select Address..</option>");
$.each(data, function (index, addressObj) {
$('#address').append("<option value = '" + addressObj.id + "' > " + addressObj.first_name + ". </option > ");
});
}
});
});
And in your order.js you need create one call for users and one call is for usersaddress data:-
module.exports = {
addOrderPage: (req, res) => {
var selecteduser = req.query.selectedId;
let query1 = "SELECT * FROM users";
db.query(query1, (err, result1) => {
if (err) {
return res.status(500).send(err);
}
res.render('newOrder.ejs', {
players: result1,
});
});
},
getUserAddress: (req, res) => {
var selecteduser = req.query.selectedId;
let query1 = "SELECT * FROM address WHERE userId = '" + selectedId + "'";
db.query(query1, (err, result1) => {
if (err) {
return res.status(500).send(err);
}
res.send(result1);
});
}
}
neworder.js
<select name="selectUser" id="user" >
<option disabled selected> Select User..</option>
<% users.forEach((users) => { %>
<option value="<%= users.id %>" > <%=users.name %> </option>
<% }) %>
</select>
<br>
<label>Address :</label>
<select name="selectAddress" id="address">
<option disabled selected> Select Address..</option>
</select>
And in your app.js or index.js you need to add its route
app.use("/users/address", order.getUserAddress);

jQuery select2 dynamic options

I have a multiselect that I want to use as a search box so that the user can search by category, event type, location and keywords. It has the following structure:
<select name="search-term[]" multiple="multiple">
<optgroup label="Categories">
<option value="category_4">Internal</option>
<option value="category_2">Business</option>
<option value="category_5">External</option>
<option value="category_1">Science</option>
<option value="category_6">Sports and Social</option>
</optgroup>
<optgroup label="Event Types">
<option value="eventtype_2">Meeting</option>
<option value="eventtype_3">Social Activity</option>
<option value="eventtype_4">Sporting Activity</option>
<option value="eventtype_1">Symposium</option>
</optgroup>
<optgroup label="Locations">
<option value="location_2">Office 1</option>
<option value="location_3">Office 2</option>
<option value="location_1">Office 3</option>
</optgroup>
</select>
I have initialised select2 with the tags option set to true so like so:
$('select').select2({
tags : true,
createTag: function (params)
{
return {
id: 'keyword_' + params.term,
text: params.term,
newOption: true
}
}
});
This allows users to enter a new option if it doesn't exist and takes care of the keywords requirement. Any new tags are appended with keyword_ so that the server knows how to handle them when the form is submitted.
This is all working as I expected however the issue I've come across is if someone wants to search for a keyword that is called the same as one of the other options then they aren't able to create a new keyword tag it will only let them select the existing option. For example if I search Office 1 I may want to search for events that are located at office 1 or I may want to do a keyword search so that I am searching for events that have office 1 in the title. The problem is currently I'm only able to select the location option I'm not able to create a new tag. Does anyone know how I could achieve this?
I achieved this in the end by using an AJAX datasource which gives you much more control over what options are shown to the user. Here is my code:
$('select').select2({
ajax: {
url: "/server.php",
dataType: 'json',
type: "GET",
delay: 0,
data: function (params) {
var queryParameters = {
term: params.term
}
return queryParameters;
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.text,
id: item.id,
children: item.children
}
})
};
},
cache: false
},
templateSelection: function(item)
{
return item.parent+': '+item.text;
}
});
Contents of server.php:
<?php
$term = !isset($_GET['term']) ? null : ucfirst($_GET['term']);
$categories = array('Meeting', 'Seminar', 'Sports and Social');
$locations = array('Cambridge', 'London', 'Northwich');
$matching_categories = array();
$matching_locations = array();
foreach($categories as $i => $cat) {
if(is_null($term) || stripos($cat, $term)!==false) {
$matching_categories[] = array(
'id' => 'category_'.$i,
'text' => $cat,
'parent' => 'Category'
);
}
}
foreach($locations as $i => $loc) {
if(is_null($term) || stripos($loc, $term)!==false) {
$matching_locations[] = array(
'id' => 'location_'.$i,
'text' => $loc,
'parent' => 'Location'
);
}
}
$options = array();
if(!empty($matching_categories)) {
$options[] = array(
'text' => 'Category',
'children' => $matching_categories
);
}
if(!empty($matching_locations)) {
$options[] = array(
'text' => 'Location',
'children' => $matching_locations
);
}
if(!is_null($term)) {
$options[] = array(
'text' => 'Keyword',
'children' => array(
array(
'id' => 'keyword_'.$term,
'text' => $term,
'parent' => 'Keyword'
)
)
);
}
echo json_encode($options);

Categories