Issue when trying to populate a drop-down with database values - mysql

I am using the following HTML to show a selected drop down with values from the database and rest of the others in the list. It shows the selected name correctly but the selected is also displayed in the list.
How to remove the second time show selected name in the drop down list? Is this a good way to use drop down menu? Here Jobcategory and Jobdetails are associated.
Im using Laravel 4.2 and this is the HTML:
// view drop down form to save data
<div class="large-6 columns">
<label>Job Category
<select name="category[]">
<option value="">Select Category</option>
#foreach(JobCategory::all() as $jcat)
<option value="{{ $jcat->id }}">{{ $jcat->name }}</option>
#endforeach
</select>
</label>
</div>
// Edit drop down form to update the selected value
<div class="large-6 columns">
<label>Job Category
<select name="category[]">
<option value="{{$jobedit->jobcategory->id}}">{{$jobedit->jobcategory->name </option>
#foreach(JobCategory::all() as $jcat)
<option value="{{ $jcat->id }}">{{ $jcat->name }}</option>
#endforeach
</select>
</label>
</div>
// database table for jobcategories
id | name
1 | Accounting/Finance
2 | Advertisement/Event Mgt.
3 | .....
// after save into jobdetails table
id | jobcategory_id | .......
1 | 5 | ...
I can retrieve the value of jobcategory in the edit form but it shows twice one in the selected value and other in the listed value of all jobcategory. This is the problem and i want only show the selected value and then rest of the others from jobcategory table without duplicate value of selected in the drop down. plz help.
// controller to to edit
public function getJobEdit($id)
{
$jobedit = JobDetail::find($id);
return View::make('employers.edit_single_jobs')->with('jobedit', $jobedit);
}
// JobDetail --model
public function jobcategory()
{
return $this->belongsTo('JobCategory');
}
// JobCategory --model
public function jobdetails()
{
return $this->hasMany('JobDetail', 'jobcategories');
}

Have a look at the Forms & HTML helper of laravel.
Generating A Drop-Down List With Selected Default
echo Form::select('size', array('L' => 'Large', 'S' => 'Small'), 'S');
where the first argument is the name of the select box. The second argument is an array of all entries in the box and the last argument determines which of the array elements is the selected one.
in your case it could look something like this:
{{ Form::select(
'categoryName',
array(
'Accounting/Finance' => 'Accounting/Finance',
'Advertisement/Event Mgt.' => 'Advertisement/Event Mgt.',
// to be continued ...
),
'$cat->category_name'
); }}
//Edit
<div class="large-6 columns">
<label>Job Category
{{ Form::select('category[]', ['' => 'Select a category'] + $all_categories, $jobedit->jobcategory->id) }}
</select>
</label>
</div>
where $all_categories should be an array of all categories as in the first example. You can get this from JobCategory::all().

This is how I set up drop-downs in my projects. I prepare the data in my controller (you'd obviously need a route and controller set up for this, I'm assuming you've done that):
Controller
public function index()
{
$categories = \Category::lists('name', 'id')->orderBy('name'); // assuming you have a Category model
view('categories', compact('categories'));
}
Then you can use the Forms and HTML helper as Peh mentioned, this isn't available as a default in Laravel 5 so you'd need to add it into your project using composer. To do so either run composer install illuminate/html or add "illuminate/html": "~5.0" to your composer.json file and then run composer install. You'd then need to add 'Illuminate\Html\HtmlServiceProvider' to config/app.php in the providers array then add 'Form' => 'Illuminate\Html\FormFacade' and 'HTML' => 'Illuminate\Html\HtmlFacade' to the aliases array in the same file. Once that's sorted you can use the Form and HTML helper in your view, as so:
View
{{ Form::select('categoryName', ['' => 'Select a category'] + $categories) }}
Your view would need to be saved as filename.blade.php if using the handlebars, otherwise echo it within <?php ?> tags.
Hope that helps you on your way.

Related

Can't figure out a way to add two values from a select element in react

Scenario: I have a react component that allows users to select through different shipping rates. Once a user selects one I want the onChange to get the ID and the amount and I can only figure out how to get just the ID. The select element iterates through an array of rates that is structured like this:
rates = [ {id: 'r8f8hd8', amount: 45}, ...]
Here is the select element:
<select onChange={(e) => console.log(e.target.value)} className='w-8/12 h-14 rounded p-2'>
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate, index) => (
<option value={{ id: rate.rateId, amount: rate.amount }} key={index}>
{rate.service} {''}(${rate.amount})
</option>
))}
</select>
I tried setting the option value to an object with the rateId and amount but it just gives me a blank [Object object]
This should fix the issue. A word of advice I wouldn't set the key to just the index. Instead you should use the id that you assigned to the object.
The issue was you we're storing an object as the value. This lead to an issue because value automatically stores a string so your object is converted into a string hence [Object Object]. Mapping already sets its own pre defined object {value:someVal,key:someID}.
Taking your current case into account I believe this is a cleaner way to achieve what you wanted. I've added working code below. Also the extra item in rates was just for testing.
Feel free to comment any questions you have and i'll do my best to answer them.
let rates = [ {id: 'r8f8hd8', amount: 45},{id: 'r8f8hd', amount: 450}]
return (
<select onChange={(e) => console.log(e.target.value)} className='w-8/12 h-14 rounded p-2'>
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate) => (
<option value={rate.amount } key={rate.id}>
{rate.service} {''}(${rate.amount})
</option>
))}
</select>
)
Just incase your just dead set on storing multiple values here's a solution to that as well but I would go as far as saying this is just bad code but it does what you wanted. Since map has its own object as I mentioned we can mutate it and give it more characteristics hence id and trueVal that I added. We can use the index and store that as our value and instead of accessing our data through e.target.value we can instead utilize the e.target.options and simply cross reference the index value we stored to make sure we are always accessing the correct position in the array. However please take note of the +1 this is to take the first position into account which is held by the, "Pick a shipping rate".
let rates = [ {id: 'r8f8hd8', amount: 45},{id: 'r8f8hd', amount: 450}]
return (
<select onChange={(e) => console.log(e.target.options[e.target.value])} className='w-8/12 h-14 rounded p-2'>
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate, index) => (
<option value={index+1} trueVal={rate.amount} id={rate.id} key={index}>
{rate.service} {''}(${rate.amount})
</option>
))}
</select>
)
}
In html value prop is a string, so value={{ id: rate.rateId, amount: rate.amount }} is converted to string, that's why you are getting [Object object] .
Solution : change your component like this :
.....
const [option, setOption] = React.useState({});
const handlechange = (e)=>{
for (let i = 0; i < rates.length; i++) {
if (e.target.value === rates[i].id) {
setOption({ id: rates[i].id, amount: rates[i].amount });
}
}
}
return (
<select onChange={handlechange} className="w-8/12 h-14 rounded p-2">
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate, index) => (
<option value={rate.id} key={index}>
{rate.service} {""}(${rate.amount})
</option>
))}
</select>
);
Now your id and amount of selected option will be stored in option state
this is a demo in codesandbox

How to iterate two separate arrays in handlebars Nodejs with {{#each}}?

I am creating a Risk Management System using Nodejs and Express with Handlebar views. Using SQL, I am extracting two queries in my GET router and rendering them to the handlebar view. This is how it looks:
const parametro = await pool.query('select * from parametro where parid = ?', [parid]);
const tipoParametros = await pool.query('select distinct tipoparid from tipoparametro order by tipoparid');
res.render('parametros/modificar', {parametro, tipoParametros});
I consoled logged both arrays and they look like these:
- parametro: [
RowDataPacket {
parid: 22,
parcodigo: 'TEST',
tipoparid: 11,
pardescripcion: 'Just a Test',
parexplicacion: 'Test',
parclasificacion: 3,
parvalor: 'Test 1',
parusrcreaid: null,
parfechacrea: 2022-06-25T21:58:19.000Z,
parusrmodid: null,
parfechamod: null
}
]
- tipoParametros: [ RowDataPacket { tipoparcodigo: 'SYS', tipoparid: 11 } ]
However, since my POST for this view needs :id, I am iterating with each parametro because that's how I keep track of each row in my database, with parid. The .hbs view looks like this:
{{#each parametro}}
<form class = "row g-3 needs-validation" method = "POST" action = "/parametros/modificar/{{this.parid}}" novalidate>
{{> formparametro}}
</form>
{{/each}}
and inside "formparametro" there is a form-floating section where I try to iterate with each tipoParametro but nothing is coming out. Looks like this:
<div class="col-6">
<div class="form-floating">
<select class="form-select" id="floatingSelect" name="tipoparid" aria-label="Floating label select example" required>
{{#each tipoParametros}}
<option value={{this.tipoparid}}>{{this.tipoparcodigo}}</option>
{{/each}}
</select>
<label for="floatingSelect">Tipo Parametro</label>
</div>
</div>
How can I have access to the query and columns of tipoParametro?
As your formparametro partial is rendered within your {{#each parametro}} block, the context for each time the partial is rendered is the currently iterated item from parametro. Therefore, the partial has no access to tipoParametros.
What we want to do is provide a context to our partial that does contain tipoParametros. This is very simple. The Handlebars documentation covers Partial Contexts and it states that a context can be supplied to the partial as the second parameter within the mustache brackets, as in:
{{> myPartial myOtherContext }}
As your tipoParametros object belongs to your root context, I would recommend using the #root data variable to pass the root context to your partial. The line in your template invoking your partial thus becomes:
{{> formparametro #root}}
I have created a fiddle for your reference.

How to display data in a drop down corresponding to the data from another dropdown in html page?

I am trying to create a web page using Python DJANGO, in which I have two dropdowns out of which one is for category and another for subcategory, for which data is getting fetched from database. In DB, there are two columns for category and another for subcategory respectively.
For example, there are 2 Categories, i.e boys and girls. and for boys there are 3 names under SubCategory column, similarly for girls. So my want is that, in drop down 1, it should show 'boys' and 'girls'. When user chooses any of them, the corresponding names should appear in the second drop down(i.e only boys names should appear in dropdown 2 when "boys" is selected in dropdown1).
But the way I have written, its showing all the data irrespective of the selection in dropdown1. How can I make the subcategory data appear categorically?
View.py:
def createTicketView(request):
if request.method == 'POST':
taskName=request.POST.get('title')
taskDescription=request.POST.get('description')
Category=request.POST.get('category')
SubCategory=request.POST.get('type')
user_id=request.user.id
task=UserTaskDetails.objects.create(user_id=user_id,
taskName=taskName,taskDescription=taskDescription,
Category=Category,SubCategory=SubCategory)
task.save()
return redirect('home')
category =ServiceCategoryDetails.objects.values('category').distinct()
subcategory=ServiceCategoryDetails.objects.values('SubCategory').distinct()
return render(request,'custws/ticket.html',{'title':'create ticket',
'category':category,
'subcategory':subcategory,
'})
Html code:
<div class="form-group col-md-6">
<label for="category" class="font-weight-bold">Category</label>
<select name="category" id="category" class="form-control">
{% for type in category %}
<option value={{type.category}}>{{type.category}}</option>
{% endfor %}
</select>
</div>
<div class="form-group col-md-6">
<label for="subcat" class="font-weight-bold">Sub Category</label>
<select name="subcat" id="subcat" class="form-control">
{% for type in subcategory %}
<option value={{type.SubCategory}}>{{type.SubCategory}}</option>
{% endfor %}
</select>
</div>
You could use ajax. When user changes 1st input, ajax will update options of your 2nd input.
You could use django-select2 with dependent_fields option.
HTML
<form>
...
<select id='subcat'></select>
</form>
$('#sub-btn').click(function(e){
e.preventDefault();
var data = {cat_id: <get_your_selected_id>}
$.ajax(
{
type:"POST",
beforeSend: function (xhr) {
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader("X-CSRFToken", csrf_token);
},
url: "<your-url>",
data:data,
success: function(data){
// on success, dynamically append the select drop down list
$('#subcat').html(data)
}
});
})
VIEW
def myview(request):
...
if request.method == 'POST':
cat_id = request.POST.get('cat_id')
# create options, note: 'subcategories' should be replaced with your category related name
options = [f"<option value='{i.pk}'>{i.value}</option>"+'\n'
for i in Category.objects.get(id=cat_id).subcategories.all()]
return HttpResponse(options)
Then, the success callback is called and the options are dynamically appended. You can also return JsonResponse of the data and construct the option element in frontend.
Besides, take a look of django-autocomplete-light, which is very convenient for doing autocomplete stuff and gracefully handles with all kinds of relations between fields

Conditionally deciding which option is selected in blade

Im displaying a form as a representation of data in my database. Im using a form because the data is editable by certain users.
The form contains a dropdown list:
<select name="Status" id="Status">
<option id="confirmed" value="Confirmed">Confirmed</option>
<option id="completed" value="Completed">Completed</option>
<option id="released" value="Released">Released</option>
<option id="deleted" value="Deleted">Deleted</option>
</select>
When loading the view I pass in a variable '$status' which is from the database. How do I set the 'selected' attribute for which ever option $status is equal to?
Im using blade tempting engine
if you're using blade template you may want to use the Form helper to build your form fields, pass an array of items to be listed as dropdown options on the 2nd parameter and at the 3rd parameter pass your selected value, see the code below for reference
From controller:
$selectedValue = "confirmed";
$statuses = array(
array("id"=> "confirmed", "value" => "Confirmed"),
array("id"=> "completed", "value" => "Completed"),
array("id"=> "released", "value" => "Released"),
array("id"=> "deleted", "value" => "Deleted"),
);
return view("yourview")->with("statuses", $statuses)->with("selectedValue", $selectedValue);
On your view you could do something like below:
{!! Form::select('status', $statuses , $selectedValue, ['class' => 'form-control', 'id' => 'status']) !!}
Note: the code is untested but should work in your case.
Also please check https://laravelcollective.com/docs/5.2/html

ng-selected not working on option element with ng-repeat

I am using a select combobox with dynamic values from an OData response. Beccause of this I need to identify the 'highest' existing period in my response and set the selectedattribute for the relevant option item.
This selectis used as a period filter. That's why I also added an entry for 'all' periods. This can be removed in the sample and makes no difference in the behaviour.
Angular seems to evaluate the conditions etc. correct, so the element which should be selected gets the attribute selected="selected" and ng-select="true".
Nevertheless the browser selects '' by default rather than the selected element. Even if I remove the option for all periods, the browser takes the 'empty' element and not the element with the selectedattribute.
I checked other answer so similiar questions, but none of them worked and many reference ng-options instead of ng-repeat.
More information
I am using AngularJS v1.4.9 and Chrome 48.0.2564.103 m
I am using a rather large OData response in JSON format as data source, so I'd need to rewrite the code here to provide an executable example.
I'll do this if it's necesary or required.
For other reasons, which I don't want to discuss here I cannot use ng-options, so please don't suggest this.
HTML snippet - commented and indented afterwards
The other logic for sorting, ordering etc. is working fine.
<select class="semester-selection" ng-model="selectedPeriod.Period_Nav.PeriodName">
<!-- This 'empty' option can be removed. ng-selected won't work then either -->
<option ng-selected="false" value=""><Alle></option>
<option ng-selected="{{examResult.Period == getHighestPeriod()}}"
ng-repeat="examResult in examResultData.results | uniquePeriod:'Period' | orderBy:'-Period'"
value="{{examResult.Period_Nav.PeriodName}}">
<!-- Debug information -->
{{examResult.Period_Nav.PeriodName}}
{{examResult.Period == getHighestPeriod()}}
{{getHighestPeriod()}}
</option>
</select>
Generated HTML via Angular JS
The generated code looks okay, because selected="selected" and ng-select="true" as in there for the desired element.
<select class="semester-selection ng-pristine ng-valid ng-touched"
ng-model="selectedPeriod.Period_Nav.PeriodName">
<option value=""><Alle></option>
<!-- ngRepeat: examResult in examResultData.results | uniquePeriod:'Period' | orderBy:'-Period' -->
<option selected="selected" ng-selected="true" ng-repeat="examResult in examResultData.results | uniquePeriod:'Period' | orderBy:'-Period'" value="WiSe 2011/12" class="ng-binding ng-scope">
WiSe 2011/12
true
15014000
</option>
<!-- end ngRepeat: examResult in examResultData.results | uniquePeriod:'Period' | orderBy:'-Period' -->
<option ng-selected="false" ng-repeat="examResult in examResultData.results | uniquePeriod:'Period' | orderBy:'-Period'" value="SoSe 2007" class="ng-binding ng-scope">
SoSe 2007
false
15014000
</option><!-- end ngRepeat: examResult in examResultData.results | uniquePeriod:'Period' | orderBy:'-Period' -->
</select>
Result in the browser
When I open the page in the browser the combobox has still not the selected value as active, but the first or empty one.
Reduced sample for testing / fiddling around
Oh. This reduced sample works, so I need to find the issue somewhere else in the code.
var app = angular.module('ExamResultList', [ ]);
app.controller('ExamResultController', ['$scope', function ($scope) {
// Simplified sample data -> this can contain 'duplicates'
$scope.examResultData = [
{PeriodName:'WiSe 15/16', Period:8}, // fake OData OrderBy -> Highest period is the first elem
{PeriodName:'SoSe 12', Period:1},
{PeriodName:'WiSe 12/13', Period:2},
{PeriodName:'WiSe 12/13', Period:2},
{PeriodName:'WiSe 12/13', Period:2},
{PeriodName:'SoSe 13', Period:3},
{PeriodName:'WiSe 13/14', Period:4},
{PeriodName:'SoSe 14', Period:5},
{PeriodName:'WiSe 14/15', Period:6},
{PeriodName:'SoSe 15', Period:7}
];
$scope.highestPeriod = 0;
$scope.getHighestPeriod = function() {
// first element has the highest period, because the OData request has a orderby expression
return $scope.examResultData[0].Period;
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExamResultList" id="examResultListWrapper">
<div ng-controller="ExamResultController as ExamResCtrl" id="examResultList">
<select class="semester-selection">
<option ng-selected="false" value=""><Alle></option>
<option ng-selected="{{examResult.Period == getHighestPeriod()}}"
ng-repeat="examResult in examResultData"
value="{{examResult.PeriodName}}">
{{examResult.PeriodName}}
<!-- Debug info
{{examResult.Period == getHighestPeriod()}}
{{getHighestPeriod()}}
-->
</option>
</select>
</div>
</div>
ng-selected does not take expression brackets. Use
ng-selected="examResult.Period == getHighestPeriod()"