implementing checkboxes with multiple select in django admin and modelform? - django-forms

i'm fairly new to django, so couldn't find a way to implement the checkboxes with multiple select in to my custom modelforms and django admin. tried the django docs but still couldnt find solution?the image is my project form wherein the technologies field should have a checkbox with multiple select.
TIA
views.py
class ProjectCreate(CreateView):
model = Project
fields = ['projectid', 'title', 'description', 'startdate', 'enddate', 'cost', 'Project_type',
'employeeid', 'technologies', 'clientid', 'document']
class ProjectUpdate(UpdateView):
model = Project
fields = ['projectid', 'title', 'description', 'startdate', 'enddate', 'cost', 'Project_type',
'employeeid', 'technologies', 'clientid']
form-template.py
{% for fields in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ fields.errors }}</span>
</div>
<label class="control-label col-sm-2">{{ fields.label_tag }}</label>
<div class="col-sm-10">{{ fields }}</div>
</div>
{% endfor %}

We can implement is using django-multiselectfield
First install django-multiselectfield.
pip install django-multiselectfield
In Models.py, we need to import multiselectfield then use MultiSelectField as modal field & pass required arguments.
from django.db import models
from multiselectfield import MultiSelectField
MY_CHOICES = ((1, 'Value1'),
(2, 'Value2'),
(3, 'Value3'),
(4, 'Value4'),
(5, 'Value5'))
#choices can be a list also
class MyModel(models.Model):
#....
my_field = MultiSelectField(choices=MY_CHOICES,
max_choices=3,
max_length=3)
Now in admin panel when you open MyModel form you will see 5 check boxes out of which you can only select a maximum of 3 as defined max_choices=3
If you are rendering modelform using templates then you only need to specify the fields in Forms.py.
If you're getting dropdown data from another table then refer to this question

Related

Select/Multiselect using choice.js in laravel livewire not working

I have using livewire and now I need to create select dropdown with a search option, and I came across choices.js choice.js link and follow this livewire with choice.js link I can make with work (but I have to use wire:ignore) for the select when the data is not dependent on others select (like fetch district after state is selected)
Now I need to fetch district after state is change, and of course i use wire:ignore because of styling and the district cannot display in the option list. If I didn't use wire:ignore then the style is breaking. For the very first time the district display based on state select without breaking any styles, after that district cannot updated even state is changed.
Below are my code for select state and district
<x-input.select wire:model="state" prettyname="state" :options="$allState" selected="('State')" placeholder="Select State*"/>
#if(!is_null($state))
<x-input.select wire:model="district" prettyname="district" :options="$allDistrict" selected="('District')" placeholder="Select District*"/>
#endif
and in Component
public function updatedState($state)
{
$this->allDistrict = District::where('state_id', $state)->pluck('id','name')->toArray();
}
The function updatedState() is trigger but the districts value cannot display in the blade file except the first time
the view component for <x-input.select /> is below
<div x-data wire:ignore x-init="() => {
var choices = new Choices($refs.{{ $attributes['prettyname'] }}, {
itemSelectText: '',
});
choices.passedElement.element.addEventListener(
'change',
function(event) {
values = event.detail.value;
#this.set('{{ $attributes['wire:model'] }}', values);
},
false,
);
let selected = parseInt(#this.get{!! $attributes['selected'] !!}).toString();
choices.setChoiceByValue(selected);
}"
>
<select id="{{ $attributes['prettyname'] }}" wire-model="{{ $attributes['wire:model'] }}" wire:change="{{ $attributes['wire:change'] }}" x-ref="{{ $attributes['prettyname'] }}">
<option value="">{{ isset($attributes['placeholder']) ? $attributes['placeholder'] : '-- Select --' }}</option>
#if(count($attributes['options'])>0)
#foreach($attributes['options'] as $key=>$option)
<option value="{{$key}}" >{{$option}}</option>
#endforeach
#endif
</select>
</div>
My question is how to get district value based on state data, and not breaking style and which can be searchable?
Thanks in advance

Getting id value from url in controller and displaying values associated laravel

I'm trying to create a ticket management system with laravel jetstream and livewire. In the user page there's a table with all tickets that the user created. When the user clicks on the button to open one specific ticket, it should pass the id of the ticket and redirect to another page where it receives the data of that ticket he clicked, like title, message, etc..
The id is passed through the url, but my main problem is that whenever I try to display that data in the view, nothing shows, no errors either. I think that something might be wrong with my controller.
Here's my route:
Route::get('tickets.answers/{id}', [TicketsController::class, 'answers']);
The button to redirect to that specific ticket:
<a href="{{ url('tickets.answers' . '/'. $ticket->id ) }}" > <x-jet-secondary-button >
See Answer
</x-jet-secondary-button></a>
AnswersController:
public function render(Request $request)
{
$tickets = Ticket::where('id', $request->url('id'));
return view('livewire.tickets.answers', [
'tickets' => $tickets,
]);
}
And how I'm trying to display in my blade:
#foreach($tickets as $key => $ticket)
<!-- This example requires Tailwind CSS v2.0+ -->
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
<div class="px-4 py-5 sm:px-6">
<h3 class="text-lg leading-6 font-medium text-gray-900">
Ticket nº {{$ticket->id}} - {{$ticket->title}}
</h3>
</div>
</div>
#endforeach
In your TicketsController you can fetch the id like this
public function answer(Request $request, int $id)
{
// Use the find() method, instead of where(), when searching for the primary key
$tickets = Ticket::find($id);
// .. more
}
In your routes files you specify an answer method, so use this in your TicketsController.
// See how to name a route
Route::get('tickets.answers/{id}', [TicketsController::class, 'answers'])->name('tickets.answers');
Then use the named route in your view like this:
<a href="{{ route('tickets.answers', ['id' => $ticket->id]) }}">
You can see a similar example in the Laravel docs.

Ordering laravel form::select by already selected values

Is it possible to order the form list by previously already selected values? these values are already selected when the page is loaded.
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Role:</strong>
{!! Form::select('roles[]', $roles, $userRole, array('class' => 'form-control form','multiple')) !!}
</div>
</div>
Outputs my list with the values in a non ordered fashion.
It is not possible to order the list because it is essentially an select list with options, which makes it impossible to order automatically based in value.
Your select is populated with data from $roles variable, I think that you should have ordered your list in that variable before render the template.

How to change language of the django form

I have a basic django form template and it's in english. I would like to change the whole form to finnish. How do i do that?
forms,py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class rekkausform(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
register.html
{%extends "blogi/base.html"%}
{% load crispy_forms_tags %}
{%block content%}
<div class="content-section">
<form method="POST">
{%csrf_token%}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Liity</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Rekkkaa</button>
</div>
</form>
<div class="border-top pt-3">
<a class="text-muted">Joko sinulla on tili? Kirjaudu tästä </small>
</div>
</div>
{%endblock content%}
If you are going to create a register form
It's possible to use django-registration
Install django-registration and add it to INSTALLED_APPS setting.
Setting up the URLs.
Create the templates.
and in registration_form.html add your code, like what you have done in your register.html
Then in settings.py change LANGUAGE_CODE to the proper language
All the form, its labels, errors and helpers will translate to chosen language.
you just have to change the labels you need . for example you need to change the label of the username:
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
username = forms.CharField(
label = 'نام کاربری', #username in persion
required = True,
)
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']

Laravel: How to create link buttons on a view dynamically?

I'm making a College Administration website where a professor can log in.
I have a dashboard, where my dynamically generated button should be placed: (right now it just has dummy buttons!)
Generated by this view file, which I will have to modify soon:
<div class="container d-flex flex-column align-items-center justify-content-center">
<h1>IA DASHBOARD</h1>
<br>
<div class="grid2">
SUBCODE 1</button>
SUBCODE 2</button>
SUBCODE 3</button>
</div>
Tables in the Database:
the table iamarks contains the data (student info, and marks) that is to be displayed after /subcode/{subcode} narrows it down to records of just the students that are in the class assigned to current logged-in professor.
classroom_mappers is a table used to map a professor to a classroom with a subject. It makes sure that one classroom only has one professor for a particular subject.
the routes currently in my web.php:
route::get('/ia', 'IAController#show')->middleware('auth');
Route::get('/subcode/{subcode}', 'IAController#showTable')->middleware('auth');
...and these are the methods inside my controller:
//shows buttons to the user:
public function show(){
$subcodes = DB::table('classroom_mappers')
->select('subcode')
->where([['PID','=', auth()->user()->PID]])
->get();
return view('ia',compact('subcodes'));
}
//when user clicks a button, subcode is to be generated and a table is to be shown:
//it works, I tried it by manually typing in subcode value in URL.
public function showTable($subcode){
$sem = DB::table('classroom_mappers')
->where([['PID','=', auth()->user()->PID],
['subcode','=',$subcode]])
->pluck('semester');
$division = DB::table('classroom_mappers')
->where([['PID','=', auth()->user()->PID],
['semester','=',$sem],
['subcode','=',$subcode]])
->pluck('division');
$data = DB::table('iamarks')
->where([['semester','=',$sem],
['division','=',$division],
['subcode','=',$subcode]])
->get();
return view('subcode',compact('data'));
}
My Problem:
To be able to generate the {subcode} in the URL dynamically, I want to create buttons in the dashboard using the data $subcodes. The controller hands over the $subcodes (an array of subject codes which belong to logged in professor) which are to be made into buttons from the show() method.
The buttons should have the name {subcode} and when clicked, should append the same subject code in the URL as {subcode}.
How do I make use of $subcodes and make the buttons dynamically?
How do I make sure the buttons made for one user are not visible to another user?
I managed to find the solution, thanks to Air Petr.
Apparently, you can't nest blade syntax like {{some_stuff {{ more_stuff }} }} and it generates a wrong php code. I modified the solution by Air Petr to:
<div class="grid2">
#foreach ($subcodes as $subcode)
<a href="<?php echo e(url('/subcode/'.$subcode->subcode));?>">
<button class="btn btn-outline-primary btn-custom-outline-primary btn-custom">
<?php
echo e($subcode->subcode);
?>
</button>
</a>
#endforeach
</div>
It generates the buttons perfectly. The buttons for one user are not visible to another, since I'm using PID constraint in a query (['PID','=', auth()->user()->PID]).
Pass the passcodes array to view:
$subcodes = []; // Array retrieved from DB
return view('subcode', compact('subcodes'));
And in subcode.blade.php, loop through each subcode:
<div class="grid2">
#foreach($subcodes as $subcode)
<a href="{{ url('/subcode/' . $subcode->subcode) }}">
<button class="btn btn-outline-primary btn-custom-outline-primary btn-custom">SUBCODE {{ $subcode->subcode }}</button>
</a>
#endforeach
</div>
You can loop your codes to create buttons. Something like this (it's for "blade" template engine):
<div class="grid2">
#foreach ($subcodes as $subcode)
{{ $subcode->subcode }}</button>
#endforeach
</div>
Since you're using PID constrain in a query (['PID','=', auth()->user()->PID]), you'll get buttons for that specific PID. So there's no problem.

Resources