Handlebars.js : How to embed the view inside a partial? - javascript

this may be a little confusing, but let me show you the problem.
I am using express-handlebars in a NodeJs web app. I have to get user input in forms. To get that done, let's say I have two separate forms in two different views 1. Login 2. Book. What I want to achieve is code-reuse of the following partial/template:
<div class="row justify-content-sm-center">
<div class="col-sm-auto">
<div id="form-panel" class="card" style="margin-top:15%">
<div id="form-header" class="card-header">
<div class="card-title">
<h4>{{ formTitle }}</h4>
</div>
</div>
<div id="form-body" class="card-body">
{{{ formBody }}}
</div>
</div>
</div>
Can anyone guide me how do I use the above template in a form like below:
{{> entry_form }} <!-- start of the form -->
<form class="form-horizontal" method="post" action="/login">
<div class="form-group">
<label for="email_address" class="label">Email Address:</label>
<input type="email" name="email_address" id="email_address" class="form-control"
placeholder="Email Address" autofocus required maxlength="250" value="{{email}}"/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Password"
required maxlength="250" value="{{password}}"/>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" name="remember_me" id="remember_me" checked="{{rememberMe}}"/>
Remeber me!
</div>
</div>
<div class="form-group text-danger">
{{ errorMessage }}
</div>
<div class="form-group text-center">
<input type="submit" value="Sign-in" class="btn btn-success"/>
</div>
</form> <!-- end of the form -->
I want to get the following output after compilation. Assuming that {{variables}} will be replaced by the provided values in the context:
<div class="row justify-content-sm-center">
<div class="col-sm-auto">
<div id="form-panel" class="card" style="margin-top:15%">
<div id="form-header" class="card-header">
<div class="card-title">
<h4>Sing in</h4>
</div>
</div>
<div id="form-body" class="card-body">
<form class="form-horizontal" method="post" action="/login">
<div class="form-group">
<label for="email_address" class="label">Email Address:</label>
<input type="email" name="email_address" id="email_address" class="form-control"
placeholder="Email Address" autofocus required maxlength="250" value=""/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Password"
required maxlength="250" value=""/>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" name="remember_me" id="remember_me" />
Remeber me!
</div>
</div>
<div class="form-group text-danger">
</div>
<div class="form-group text-center">
<input type="submit" value="Sign-in" class="btn btn-success"/>
</div>
</form>
</div>
</div>
</div>

I solved the problem myself. Posting here the solution just to help others if they run into such issues.
What I have done is, I have used inline partials as following.
enclose the login form into inline partial:
{{#*inline loginForm}}
<form class="form-horizontal" method="post" action="/login">
<!-- form contorls -->
</form>
{{/inline}}
{{#> entry-form}}
{{> (lookup . 'loginForm')}}
{{/entry-form}}
Define form container partial as following:
<div class="row justify-content-sm-center">
<div class="col-sm-auto">
<div id="form-panel" class="card" style="margin-top:15%">
<div id="form-header" class="card-header">
<div class="card-title">
<h4>{{ formTitle }}</h4>
</div>
</div>
<div id="form-body" class="card-body">
{{> (dataform) }}
</div>
</div>
</div>
</div>
Please note that I have kept the form container partial in views/partials/entry-from.hbs file, and have loaded them by using:
const express = require('express');
let app = express();
app.engine('hbs', hbs({
extname:'hbs',
defaultLayout:'layout',
layoutsDir:join(__dirname,'views/layouts/'),
partialsDir: [
join(__dirname,'views/partials/')
]
}));

I seem to have arrived a bit late, but I would like to propose an alternative to #Nadeem Jamali's solution for those who have run into the same problem.
Reading the documentation I found the following: https://handlebarsjs.com/guide/partials.html#partial-blocks
You can use {{#partial-block}} in order to represent the content that will be embeded into your partial. Let me give you an example:
container-partial.hbs
<h1>Welcome to the container partial!</h1>
<div style="background-color: red">
<h2>This is the content of the partial</h2>
{{#partial-block}}
<!-- More code here... -->
</div>
Now, in every handlebars file you can use this partial like this:
foobar.hbs
{{#> container-partial }}
<h1>And here you can write the content of "container-partial", in other words, what is going to be replaced in #partial-block</h1>
{{/container-partial}}
And the output after compilation will be:
<h1>Welcome to the container partial!</h1>
<div style="background-color: red">
<h2>This is the content of the partial</h2>
<h1>And here you can write the content of "container-partial", in other words, what is going to be replaced in #partial-block</h1>
<!-- More code here... -->
</div>
In this case, we can find a solution to #nadeem-jamali's question by doing the following:
form-container.hbs
<div class="row justify-content-sm-center">
<div class="col-sm-auto">
<div id="form-panel" class="card" style="margin-top:15%">
<div id="form-header" class="card-header">
<div class="card-title">
<h4>{{ formTitle }}</h4>
</div>
</div>
<div id="form-body" class="card-body">
{{> #partial-block }}
</div>
</div>
</div>
</div>
Now, we can use the partial like this:
login-form.hbs
{{#> form-container formTitle="FooBar"}}
<form class="form-horizontal" method="post" action="/login">
<!-- Form content -->
</form>
{{/form-container}}
And the result will be:
<div class="row justify-content-sm-center">
<div class="col-sm-auto">
<div id="form-panel" class="card" style="margin-top:15%">
<div id="form-header" class="card-header">
<div class="card-title">
<h4>FooBar</h4>
</div>
</div>
<div id="form-body" class="card-body">
<form class="form-horizontal" method="post" action="/login">
<!-- Form content -->
</form>
</div>
</div>
</div>
</div>
Hope it helps :D !

Related

how to display form with div correctly?

I have this part of form field
When user click on the Add button will copy the above form field and user can add more in this field .
but when I add <div id="ownership"> above the code form it start to look like this
I need to put id=ownership because I want to use it in my jQuery function
<div id="ownership">
<div class="col-lg-12 mb-30 ">
<label for="add_owner"><b><span style="color:#e60000;">*</span> Name</b></label><br>
<input class="from-control" type="text" id="name" >
</div>
<div class="col-lg-6 mb-30" >
<label for="add_owner"><b><span style="color:#e60000;">*</span> Phone number</b></label><br>
<div class="input-group-prepend">
<input class="from-control" type="text" id="phone" >
</div>
</div>
<div class="col-lg-6 mb-30" >
<label for="add_owner"><b><span style="color:#e60000;">*</span> Emailn</b></label><br>
<div class="input-group-prepend">
<input class="from-control" type="email" id="email">
</div>
</div>
</div>
<div id="owner"></div>
<br>
<div class="col-md-12">
<button type="button" class="btn btn-success w-30 add_info f-r">Add</button>
</div>
<script>
$(document).ready(function(){
$(".add_info").click(function(){
var newForm = $("#ownership").clone();
$('input', newForm).val('');
$('owner').append(newForm);
});
});
</script>
How do I fix the code in order to achieve the image in number 1 ?
try this
<div class="row">
<div class="col-sm-6"> Text</div>
<div class="col-sm-6"> Text</div>
</div>
you need to apply this format then design will be properly according your desirable.
Try this way. Always use bootstrap col class inside row class then it will not cause unexpected result.
<div class="row">
<div class="col-md-12"></div>
<div class="col-md-6"></div>
<div class="col-md-6"></div>
</div>

Why tinymce looks ugly if I put it inside <div class="row"></div>?

I have a problem with TinyMCE, it looks like in the picture:
enter image description here
my HTML is:
<form action="#" method="post" id="create-product">
<div class="row">
<div class="col-4">
<label for="#product-name">Product name</label>
</div>
<div class="col-8">
<input type="text" name="product-name" class="form-control" id="product-name" placeholder="Product name" required>
</div>
<div class="col-4">
<label for="#product-category">Product category</label>
</div>
<div class="col-8">
<select name="product-category" class="selectpicker form-control" id="product-category" required>
<option value="null">--none--</option>
</select>
</div>
<div class="col-4">
<label for="#product-description">Product description</label>
</div>
<div class="col-8">
<textarea name="product-description" id="product-description"></textarea>
</div>
<div class="col-12">
<button type="submit" class="btn btn-success create-product-btn w-25 m-auto"><i class="far fa-save"></i>Save</button>
</div>
</div>
</form>
But if I remove tag, it will fix the issue whitout knowing the reason.
I'm Using Tinymce 4.7.13 and bootstrap 4,
Thanks.
It was this style who caused the problem:
.col-4 ,.col-8{
display:flex;
align-item:center
}

JQuery fadeToggle jumps up and down

I Made a switch to toggle between 2 contact forms. Everytime when using the button, the second form jumps.
Take a look here:
https://imgur.com/G4kGqjl
Here is my js:
$("#phone-form").hide();
$("input[name=checkbox]").click(function(){
$("#mail-form, #phone-form").fadeToggle();
});
And here my HTML:
<div class="div_switch">
<label>
<h1 class="switch_text">Email</h1>
</label>
<label class="switch">
<input name="checkbox" type="checkbox" value="checkbox">
<span class="slider round"></span>
</label>
<label>
<h1 class="switch_text">Rückruf</h1>
</label>
</div>
<div id="mail-form" class="mail-form">
<form class="" action="index.html" method="post">
<div class="contact-selector">
</div>
<div class="form-row">
<div class="input-group col-md">
<div class="input-group-prepend">
<div class="input-group-text"><i class="fas fa-signature"></i></div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Dein Name">
</div>
<div class="input-group col-md">
<div class="input-group-prepend">
<div class="input-group-text"><i class="fas fa-envelope"></i></div>
</div>
<input type="email" class="form-control" id="inlineFormInputGroup" placeholder="Deine E-Mail-Adresse">
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="exampleFormControlTextarea1"></label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" placeholder="Deine Nachricht..."></textarea>
</div>
</div>
<div class="email-btn-holder">
<button type="submit" class="reshape_btn email-submit">Senden</button>
</div>
</form>
</div>
<div id="phone-form" class="phone-form">
<form class="" action="index.html" method="post">
<div class="contact-selector">
</div>
<div class="form-row">
<div class="input-group col-md">
<div class="input-group-prepend">
<div class="input-group-text"><i class="fas fa-signature"></i></div>
</div>
<input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Dein Name">
</div>
<div class="input-group col-md">
<div class="input-group-prepend">
<div class="input-group-text"><i class="fas fa-envelope"></i></div>
</div>
<input type="email" class="form-control" id="inlineFormInputGroup" placeholder="Deine E-Mail-Adresse">
</div>
</div>
<div class="email-btn-holder">
<button type="submit" class="reshape_btn email-submit">Senden <span><i class="fas fa-arrow-right"></i></span></button>
</div>
</form>
</div>
I tried a couple of things. Setting the display of the parent div to absolute and some other css stuff i found on the webs but cant remember. But nothing helped.
I would really appreciate some help.
Thanks in advance!!
You should separate both forms and set a callback on your fadetoggle function (there's a completion event, use that to your favor). Try something like:
$("#phone-form").hide();
$("input[name=checkbox]").click(function(){
if($("#mail-form").is(':visible')){
$("#mail-form").fadeToggle(function(){
$("#phone-form").fadeToggle();
});
} else {
$("#phone-form").fadeToggle(function(){
$("#mail-form").fadeToggle();
});
}
});
Also, check out the api:
http://api.jquery.com/fadetoggle/
I would go with #Mauricio Cárdenas' answer, but if you absolutly must have them fade at the same time, you can do this:
<style>
#parentDiv{position:relative}
#mail-form, #phone-form{position:absolute;top:0}
</style>
<div ID="parentDiv">
<div id="mail-form" class="mail-form">
//Your form code
</div>
<div id="phone-form" class="phone-form">
//Your form code
</div>
</div>
This sets both forms to absolute and places them at the same position. Adding the parent div set to relative assures the forms position won't be set by the body.

Bootstrap 4 Form Validation

I'm a beginner with bootstrap and I have seen a lot of bootstrap 3 form validation plugins etc, but I haven't found any for bootstrap 4.
I'm trying to validate multiple forms, and here is my code:
<!-- Contact -->
<div class="container white">
<div class="row">
<div class="container white percent100">
<div class="col-lg-12">
<div class="padder-t2">
<h1>Contact</h1>
<div class="horiz-divider"></div>
</div>
</div>
</div>
</div>
<div class="row padder-t padder-b">
<div class="container white">
<div class="col-lg-12">
<!-- Form -->
<form class="form-horizontal" action=" " method="post" id="contact_form">
<fieldset>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>First Name</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-user"></i></span>
<input id="firstname" name="firstname" placeholder="First Name" class="form-control" type="text">
</div>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>Last Name</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-user"></i></span>
<input id="lastname" name="lastname" placeholder="Last Name" class="form-control" type="text">
</div>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>E-Mail</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
<input id="email" name="email" placeholder="E-Mail Address" class="form-control" type="email">
</div>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>Phone #</h4></label>
</div>
<div class="col-md-4 col-lg-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-phone"></i></span>
<input id="phone" name="phone" placeholder="Phone" class="form-control" type="text">
</div>
</div>
</div>
</div>
<!-- Text area -->
<div class="form-group">
<div class="row">
<div class="col-md-4 col-lg-4">
<label class="control-label pull-right"><h4>Message</h4></label>
</div>
<div class="col-md-4 col-lg-5 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-pencil"></i></span>
<textarea id="comment" class="form-control" name="comment" placeholder="Your Message"></textarea>
</div>
</div>
</div>
</div>
<!-- Success message -->
<div class="alert alert-success" role="alert" id="success_message">Success <i class="fa fa-thumbs-up"></i> Thanks for contacting us, we will get back to you shortly.</div>
<!-- Button -->
<div class="form-group">
<div class="row">
<label class="col-md-4 col-lg-4 control-label"></label>
<div class="col-md-4 col-lg-4">
<button type="submit" class="btn btn-danger raised">Send <i class="fa fa-paper-plane"></i></button>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
<div class="row padder-b">
<div class="row col-lg-12">
<div class="col-md-3 col-lg-3"></div>
<h4 class="col-md-9 col-lg-9">Contact us directly:</h4>
</div>
<div class="row col-lg-12">
<div class="col-md-3 col-lg-3"></div>
<h4 class="col-md-2 col-lg-2 padder-lr">Mail:</h4>
<a class="col-md-6 col-lg-6 padder-lr" href="mailto:lorem#ipsum.com">
<h4 id="mail">lorem#ipsum.com</h4>
</a>
</div>
<div class="row col-lg-12">
<div class="col-md-3 col-lg-3"></div>
<h4 class="col-md-2 col-lg-2 padder-lr">Adress:</h4>
<h4 class="col-md-6 col-lg-6 padder-lr" id="adress">2 LoremIpsum Road, 67000 City - Country</h4>
</div>
</div>
</div>
I have tried to modify existing js, but I had no luck.
Here is the rendered form:
jsfiddle of the form
First I solved my issue with an external library like Jonathan Dion suggested. But recently I came across this :
Bootstrap v4.0 introduced their own form validation that you can still pair with backend php validation. From the Doc :
<form class="needs-validation" novalidate>
<div class="form-row">
<div class="col-md-4 mb-3">
<label for="validationCustom01">First name</label>
<input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Doesn't look good!
</div>
</div>
</div>
</div>
Then using JS :
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script>
This provides input border colorating and displays the valid / invalid feedback blocks according to the given pattern or properties. It is applied via CSS’s two pseudo-classes, :invalid and :valid. It applies to <input>, <select>, and <textarea> elements.
Update 2020 - Bootstrap 4.4.x
Here's another option (modern JS) if you want to validate each input one at a time (live or real-time) instead of waiting for the entire form to be submitted...
(function() {
'use strict';
window.addEventListener('load', function() {
// fetch all the forms we want to apply custom style
var inputs = document.getElementsByClassName('form-control')
// loop over each input and watch blur event
var validation = Array.prototype.filter.call(inputs, function(input) {
input.addEventListener('blur', function(event) {
// reset
input.classList.remove('is-invalid')
input.classList.remove('is-valid')
if (input.checkValidity() === false) {
input.classList.add('is-invalid')
}
else {
input.classList.add('is-valid')
}
}, false);
});
}, false);
})()
<form class="container" novalidate="" action="/echo" method="POST" id="myForm">
<div class="form-group">
<label class="form-control-label" for="input1">Enter some input</label>
<input type="text" class="form-control" name="input1" id="input1"
autocomplete="no" required>
<div class="valid-feedback">Success! You've done it.</div>
<div class="invalid-feedback">No, you missed this one.</div>
</div>
<div class="form-group">
<label class="form-control-label" for="input2">Enter password</label>
<input type="text" class="form-control"
pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$"
autocomplete="no" name="input2" id="input2">
<div class="valid-feedback">Nice! You got this one!</div>
<div class="invalid-feedback">At least 6 chars: 1 uppercase, 1 lowercase and numeric</div>
</div>
<div>
<button type="submit" class="btn btn-secondary" id="btnSubmit">Submit</button>
</div>
</form>
https://codeply.com/p/mzBNbAlOvQ
You can use any library available on the web. You may try jqueryvalidation. It's pretty easy to use, just read the documentation.
Add the required attribute on your input and jqueryvalidation will do the job. For styling, you can add your own CSS and make it look like bootstrap.
Hopes it help
$(document).ready(function(){
$('#contact_form').validate()
})
Demo
I found a simpler and a bit more modern way to implement Bootstrap 4 JS Form validation:
Note: Keep in mind that each <form> element must have the novalidate attribute and at the same time, each <input> element in it must have the required attribute.
// Upon load..
window.addEventListener('load', () => {
// Grab all the forms
var forms = document.getElementsByClassName('needs-validation');
// Iterate over each one
for (let form of forms) {
// Add a 'submit' event listener on each one
form.addEventListener('submit', (evt) => {
// check if the form input elements have the 'required' attribute
if (!form.checkValidity()) {
evt.preventDefault();
evt.stopPropagation();
console.log('Bootstrap will handle incomplete form fields');
} else {
// Since form is now valid, prevent default behavior..
evt.preventDefault();
console.info('All form fields are now valid...');
}
form.classList.add('was-validated');
});
}
});
<!-- Load necessary libraries -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<!-- Add form -->
<div class="container" style="padding-top: 40px;">
<form class="student-search needs-validation" novalidate>
<div class="form-row">
<div class="form-group col-6">
<label for="input-name-search" class="sr-only">Name</label>
<input type="text" class="form-control" id="input-name-search" placeholder="Name" required>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">Enter a name please.</div>
</div>
<div class="col-6">
<button id="btn-search" type="submit" class="btn btn-success btn-block">Search student</button>
</div>
</div>
</form>
</div>
I just figured out the reason my code wasn't validating: I didn't have a submit button to trigger the validation. Make sure to have it.
<button type="submit" class="btn btn-primary">Save</button>
There's no real need for a library here, you can use the native reportValidation() method: MDN. You can call it on individual inputs or on the entire form itself.

Export to pdf with same bootstrap style

I created one form with bootstrap. Now i want to export the form to pdf with the same style. please help me to solve out this issue
Here is the file jsfiddle
<div class="row">
<div class="col-sm-8 center">
<h3>Fill Your Form</h3>
<div class="row">
<div class="col-sm-4">
First Name:
<input type="text" class="form-control" />
</div>
<div class="col-sm-4">
Middle Name:
<input type="text" class="form-control" />
</div>
<div class="col-sm-4">
Last Name:
<input type="text" class="form-control" />
</div>
</div>
<br>
<div class="row">
<div class="col-sm-12">
<button id="button" class=" btn btn-danger">Generate PDF</button>
</div>
</div>
PDF Result want to be like this
Your solution is on this link , I am not sure if you want to generate pdf without any library.

Categories

Resources