How to create a horizontal form in Phalcon - html

A very basic question. I studied the examples & tutorials like INVO & Vokuro provided by Phalcon. The Vokuro example uses forms but all the examples use vertical forms (one field below other). They use forms.render() function using volt template and the form itself. If I want to create Phalcon form with fields arranged in two or more columns, how do I do it. Is the only way to use html tables or is there some other way.
Here is code from Vokuro "Users form" example which creates a vertical form:
<div class="clearfix"> <label for="name">Name</label>
{{ form.render("name") }}
</div>
<div class="clearfix"> <label for="email">E-Mail</label>
{{ form.render("email") }}
</div>
<div class="clearfix"> <label for="profilesId">Profile</label>
{{ form.render("profilesId") }}
</div>
And corresponding form code is:
$name = new Text('name', array('placeholder' => 'Name' ));
$name->addValidators(array(
new PresenceOf(array('message' => 'The name is required'
)) ));
$this->add($name);
$email = new Text('email', array('placeholder' => 'Email' ));
$email->addValidators(array(
new PresenceOf(array('message' => 'The e-mail is required' )),
new Email(array( 'message' => 'The e-mail is not valid'
)) ));
$this->add($email);
$this->add(new Select('profilesId', Profiles::find('active = "Y"'), array(
'using' => array('id', 'name' ),.....some more code.......)));
This creates a form as given below:
Create a User
Name
[Text Box]
E-Mail
[Text Box]
Profile
[List Box]
If I try to use style="float:left" in the div tags, it doesn't help much neither removing them. I want a form like:
label: [input field] -gap- label: [input field]
label: [input field] -gap- label: [input field]
If space permits, create three columns instead of two as shown above.
Thanks

That is because they have every element in a separate div
<div class="clearfix"> <label for="name">Name</label>
{{ form.render("name") }}
</div>
<div class="clearfix"> <label for="email">E-Mail</label>
{{ form.render("email") }}
</div>
But you can arrange that any way you want. For example in one row:
<div class="clearfix">
<label for="name">Name</label>
{{ form.render("name") }}
<label for="email">E-Mail</label>
{{ form.render("email") }}
</div>

use it
<div class="form-group">
<label for="name">Name</label>
{{ form.render("name",['class': 'form-control']) }}
</div>
<div class="form-group">
<label for="email">Email</label>
{{form.render("email",['class': 'form-control'])}}
</div>

Related

How can I solve " Invalid datetime format: 1366 Incorrect integer value" Exception in Laravel 7?

I'm quite new to Laravel, I would like to update a column in mySQL database named "client_id" the name of the table is "projects" I would like to insert this column when a Client creates a new Project, because the project belongs to the Client who created it. "client_id" is the Primary Key (id) in the table called "clients". There is a relationship between "clients" table and "projects" table. I have written some code to solve this problem but I'm getting this Exception and the "client_id" column is not updated.
Please help.
Store Method in my Controller:
/**
* Store a newly created Project in storage.
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'description' => 'required|string|max:255',
'start_date' => 'required|date',
'start_time' => 'required|string|max:10',
]);
$project = Project::create([
'name' => $request->name,
'description' => $request->description,
'start_date' => $request->start_date,
'start_time' => $request->start_time,
]);
$loggedinId = Auth::id();
$project->update(['created_by' => $loggedinId]);
$userId = $loggedinId;
$clientId = Client::where('user_id', '=', $userId)->pluck('id')->all();
DB::table('projects')->where('created_by', '=', $loggedinId)->update([ 'client_id' => $clientId]);
return redirect()->back()->with('message', 'You have successfully submitted your Job Card');
}
Relationship in my Client Model:
/**
* #return HasMany
*/
public function projects()
{
return $this->hasMany(Project::class);
}
Relationship in my Project Model:
/**
* #return BelongsTo
*/
public function client()
{
return $this->belongsTo(Client::class, 'client_id');
}
Form In my Blade View:
<form method="POST" action="{{ route('client-jobcard.store') }}">
#csrf
<div class="form-group row">
<div class="col-sm-8">
<label for="name">{{ __('Job Card Name') }}</label><span class="required">*</span>
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autofocus>
#if ($errors->has('name'))
<span class="invalid-feedback">
<strong>{{ $errors->first('name') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<div class="col-sm-8">
<label for="description">{{ __('Job Card Description') }}</label><span class="required">*</span>
<textarea class="form-control{{ $errors->has('description') ? ' is-invalid' : '' }}" id="description" rows="4" style="height: 150px;" name="description" value="{{ old('description') }}" required autofocus></textarea>
#if ($errors->has('description'))
<span class="invalid-feedback">
<strong>{{ $errors->first('description') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
<label for="start_date">Start Date</label><span class="required">*</span>
<input type="date" class="form-control" id="start_date" name="start_date" value="{{ old('start_date') }}" required>
</div>
<div class="col-sm-4">
<label for="submission_date">Start Time</label><span class="required">*</span>
<input type="text" class="form-control" id="start_time" name="start_time" value="{{ old('start_time') }}" required>
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
<button type="submit" class="btn btn-primary">
{{ __('Submit') }}
</button>
</div>
</div>
</form>
This line:
$clientId = Client::where('user_id', '=', $userId)->pluck('id')->all();
will return a column, not the single ID ("2") that you want.
Then, when you assign it to client_id which is an integer, the ORM will render it as the string [2] instead of the number 2, and that will give you an error.
Either retrieve just the first tuple from Client, or extract $clientId[0] manually (wasteful and not recommended).
You also have a second error I had overlooked:
'created_by', '=', $loggedinId
The above means that created_by must be an integer value, but the text of the error implies SQL expects it to be a datetime. You seem to have a wrong definition in the database.
your time field is in string , it has to be changed , it is not the same format
can you try this instead

Keyerror when doing a json post request on sqlalchemy

I am working on a project for class where I have to edit starter Code. I keep getting a KeyError code and I am not sure what the issue is.
line 250, in create_venue_submission
name = request.get_json()['name']
KeyError: 'name'
Code Below from new_venue.html
I added id="name", city, etc.. for all the divs . I'm not sure if that is the correct way to do it but thats the only way i figured to pull all the data from the form.
{% extends 'layouts/main.html' %}
{% block title %}New Venue{% endblock %}
{% block content %}
<div class="form-wrapper">
<form id="venueInfo" method="post" class="form">
<h3 class="form-heading">List a new venue <i class="fa fa-home pull-right"></i></h3>
<div id='name' class="form-group">
<label for="name">Name</label>
{{ form.name(class_ = 'form-control', autofocus = true) }}
</div>
<div class="form-group">
<label>City & State</label>
<div class="form-inline">
<div id='city' class="form-group">
{{ form.city(class_ = 'form-control', placeholder='City', autofocus = true) }}
</div>
<div id='state' class="form-group">
{{ form.state(class_ = 'form-control', placeholder='State', autofocus = true) }}
</div>
</div>
</div>
<div id='address' class="form-group">
<label for="address">Address</label>
{{ form.address(class_ = 'form-control', autofocus = true) }}
</div>
<div id='phone_num' class="form-group">
<label for="phone">Phone</label>
{{ form.phone(class_ = 'form-control', placeholder='xxx-xxx-xxxx', autofocus = true) }}
</div>
<div id="genres" class="form-group">
<label for="genres">Genres</label>
<small>Ctrl+Click to select multiple</small>
{{ form.genres(class_ = 'form-control', autofocus = true) }}
</div>
<div id="fb_link" class="form-group">
<label for="genres">Facebook Link</label>
{{ form.facebook_link(class_ = 'form-control', placeholder='http://', autofocus = true) }}
</div>
<input type="submit" value="Create Venue" class="btn btn-primary btn-lg btn-block">
</form>
<script type="text/javascript">
document.getElementById("venueInfo").onsubmit=function(e){
e.preventDefault();
fetch('/venues/create',{
method:'POST',
body:JSON.stringify({
'name': document.getElementById('name').value,
'city': document.getElementById('city').value,
'state': document.getElementById('state').value,
'address': document.getElementById('address').value,
'phone_num': document.getElementById('phone_num').value,
'genres': document.getElementById('genres').value,
'fb_link': document.getElementById('fb_link').value,
}),
headers: {'Content-type': 'application/json'}
})
.then(function(){
})
}
</script>
</div>
{% endblock %}
Code below is from app.py
#app.route('/venues/create', methods=['GET'])
def create_venue_form():
form = VenueForm()
return render_template('forms/new_venue.html', form=form)
#app.route('/venues/create', methods=['POST'])
def create_venue_submission():
name = request.get_json()['name']
print(name)
flash('Venue ' + request.form['name'] + ' was successfully listed!')
return render_template('pages/home.html')
Looks like you're using Flask-WTF to make those form fields, then using a JS function to grab the values from these with getElementById.
The problem is you don't set an id on the form fields. To get a better visualization of this, have a look at the rendered HTML, rather than the template code itself.
So instead of:
{{ form.name(class_ = 'form-control', autofocus = true) }}
You're looking for someting like:
{{ form.name(id='name', class_ = 'form-control', autofocus = true) }}
Then verify that renders to something like:
<input autofocus class="form-control" id="name" name="name" type="text" value="">
Note this now has an id attribute, which should allow your JS function to grab the value.
You'll need to appy this same concept to the other form fields.
I added id="name", city, etc.. for all the divs . I'm not sure if that is the correct way to do it but thats the only way i figured to pull all the data from the form.
Doing this for the divs is no use... document.getElementById('name').value takes the value of an input field, so that's what you'd have to add the id attribute to, as above.
EDIT regarding comment
In your create_venue_submission route, the request.get_json method receives the values submitted by the javascript Fetch request. On the other hand, request.form contains the values if the form is submitted without Javascript.
With the Javascript method: e.preventDefault() prevents that traditional form submission when the button is clicked, and instead submits the Fetch request, with the header {'Content-type': 'application/json'}.
Either by removing that script tag, or running in a browser with javascript disabled it will fall back to the traditional submission method.
So you should probably do some logic in your flask route to test this condition. You can also use request.is_json boolean for this. Remember to do from flask import jsonify. Something like:
if request.is_json:
# Request came in via javascript based on the header provided.
name = request.get_json()['name']
# Add data to database or something
return jsonify({'message':f'{name} was sucessfully listed.'})
else:
# handle traditional form submission
name = request.form['name']
# Add data to database or something
flash('Venue ' + request.form['name'] + ' was successfully listed!')
return render_template('pages/home.html')
Of course you'll then need to handle the returned JSON in your frontend. So insead of:
.then(function(){
})
Something like:
.then(response => response.json())
.then(data => {
console.log(data);
});
Now with the browser's dev tools Console open you should see something like this when submitted:
Object { message: "Burning Man Festival was sucessfully listed." }
Of course you could then swap that console.log line out with anything to manipulate the dom, and access for example data['message'] to get the success string itself.

How to render multiple times to same template in a single function block

I want to render multiple times in each if statement to same template. But in the HTML template it's only taking the last rendered statement.
I passed the context in the form of dictionary in the return render statement.
views.py
if not match :
#messages.info(requests,'Invalid')
return render(requests, 'validate/home1.html', {'title' : 'Invalid mail'})
if not country_code:
return render(requests, 'validate/home1.html', {'title3' : 'Enter correct country code'})
if not pwd_match :
return render(requests, 'validate/home1.html', {'title1' : 'Enter password again'})
if not phone :
return render(requests, 'validate/home1.html', {'title2' : 'Enter 10 digit number'})
home1.html
<form id="waterform" method="post" autocomplete="off">
{% csrf_token %}
<div class="formgroup" id="name-form">
<label for="name">Country Code*</label>
<input type="text" id="name" name="name" required />
</div>
<div>
<p style="color: red; margin-left: 10px">{{ title3 }}</p>
</div>
<div class="formgroup" id="email-form">
<label for="email">Your e-mail*</label>
<input type="text" id="email" name="email" required />
</div>
<div>
<p style="color: red; margin-left: 10px">{{ title }}</p>
</div>
<div class="formgroup" id="email-form">
<label for="password">Your password*</label>
<input type="text" id="pwd" name="pwd" required />
</div>
I want to display each condition (title, title1, title2) which satisfies the if blocks.
Something like this. It will put all the errors in one dictionary and when rendering, if the error doesn't exist, will just display an empty ''.
a=''
b=''
c=''
d=''
if not match :
a = 'invalid mail'
if not country_code:
b = 'Enter correct country code'
if not pwd_match :
c = 'Enter password again'
if not phone :
d = 'entire ten digit number'
errors = {'title':a, 'title1': b, 'title2': c, 'title3':d}
return render(requests, 'validate/home1.html', errors)
The execution will stop in the first match.
You should make all the validations before rendering and send the errors to the view, then write all those conditions on the template side.

Cakephp 3 form input div in div

I recently start a new project using cakephp 3. I have to generate a particular form for input box, as I am using AdminLTE V2.
Admin LTE required HTML is as following
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input class="form-control" id="inputEmail3" placeholder="Email" type="email">
</div>
</div>
I have generate it as following
<div class="form-group input text required">
<label class="col-sm-3 control-label" for="full-name">Full Name</label>
<input type="text" name="full_name" class="form-control" required="required" maxlength="100" id="full-name">
</div>
I need to generate the inner <div>. How I can do this? Please help.
For this CakePhp provide Customizing the Templates FormHelper. Like many helpers in CakePHP, FormHelper uses string templates to format the HTML it creates. While the default templates are intended to be a reasonable set of defaults. You may need to customize the templates to suit your application.
Below i have customize the input field according to AdminLTE.
echo $this->Form->input('email', [
'label' => ['text' => 'Email','class' => 'col-sm-2'],
'templates' => [
'label' => '<label{{attrs}}>{{text}}</label>',
'input' => '<div class="col-sm-10"><input type="{{type}}" name="{{name}}" {{attrs}}/></div>',
'inputContainer' => '<div class="form-group {{type}}{{required}}">{{content}}</div>',
'inputContainerError' => '<div class="form-group {{type}}{{required}} has-error">{{content}}{{error}}</div>',
],
]);
The output of this in AdminLTE theme is following.
<div class="form-group text">
<label class="col-sm-2" for="email">Email</label>
<div class="col-sm-10">
<input type="text" name="email" placeholder="Email" id="first-name">
</div>
</div>
Use the friends of cake bootstrap plugin available at https://github.com/friendsofcake/bootstrap-ui
It already includes full support for bootstrap based themes.
You can just use plain html, as #Manohar said. But if you really prefer cakephp's syntax, I use this type of syntax in my projects (same theme):
<div class="form-group">
<?php echo $this->Form->label('descricao', 'Descrição'); ?>
<div class="col-sm-10">
<?php echo $this->Form->input('descricao', ['label' => false, 'class' => 'form-control', 'placeholder' => "myPlaceHolder"]); ?>
</div>
</div>
You might need some additional parameters to do exactly what is written in the pure html version of your code. You can check out other options for cakephp's forms in it's documentation: http://book.cakephp.org/3.0/en/views/helpers/form.html#creating-form-inputs

how to change form field container div class?

I using symfony2.5. I change form field container div class.
generated form fields:
<div>
<label for="ddd" class="required">lname</label>
<input type="text" id="acme_demobundle_default_lname" name="acme_demobundle_default[lname]" required="required">
</div>
<div>
<label for="dddd" class="required">fname</label>
<input type="text" id="acme_demobundle_default_fname" name="acme_demobundle_default[fname]" required="required">
</div>
I add class to there are input`s container div.
any idea thanks
You can set attributes using the form builder inside your controller
$builder->add('lname', 'text', array('attr' => array('class'=>'something')))
If you have this in your form:
$builder->add('name')
In your template you should use the functions:
{{ form_label(form.name) }} {# access the label #}
{{ form_widget(form.name) }} {# access the input field #}
You can wrap that up with your div and style it however you want:
<div class="your-class">
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
</div>
You can check more on How to Customize Form Rendering