jekyll passing variable to form page - variables

I try to find a way to create a single booking form with jekyll.
I got for instance a button for booking at my tour details page.
When user click that button, I would love to know if there's a way to pass parameters to the booking page in order to display for example the name -- prices -- etc... of the tour.
I can't figure out how or even if its possible. Anyone clever enough for pointing me the right direction( if there's one) ?

Yes, it's possible, but as Jekyll is static, you have to do this on client side.
Explanation.
The tour page (tour.html):
---
title: tours
layout: page
tour:
name: Flying with eagles
description: text here
price: 120€
---
{% capture url %}n={{ page.tour.name | uri_escape }}&p={{ page.tour.price | uri_escape }}{% endcapture %}
<h2>{{ page.tour.name }} ({{ page.tour.price }}) - Book me for this tour!</h2>
<p>{{ page.tour.description }}</p>
Note that we use page variables to store values like name and price, but you can hard code this in the page body:
<h2>{{ page.tour.name }} ({{ page.tour.price }}) - Book me for this tour!</h2>
then becomes :
<h2>Flying with eagles (120€) - Book me for this tour!</h2>
the form (tour_form.html) :
---
title: tour form
layout: page
---
<form accept-charset="UTF-8" action="" method="POST">
<input type="text" name="tourName" value="">
<input type="text" name="tourPrice" value="">
<input type="email" name="email" placeholder="Your Email">
<input type="text" name="name" placeholder="Your Name">
<button type="submit">Submit</button>
</form>
<script>
// this script will automatically fill name and price fields
// depending on what's passed in the url
var fillForm = function () {
var queryString = document.location.search.split("+").join(" ");
var params = {}, tokens, re = /[?&]?([^=]+)=([^&]*)/g;
while (tokens = re.exec(queryString)) {
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
}
if (params.n == undefined && params.p == undefined){
// no value in the query string
// here you have to manage this use case : redirect or print a message to user
}else{
// filling form fields with query string values
document.getElementsByName('tourName')[0].value = params.n;
document.getElementsByName('tourPrice')[0].value = params.p;
}
} ();
</script>
This form is automatically filled with parameters passed from tour.html.
It can then be pointed to a form service like http://forms.brace.io/, http://www.jotform.com/ or any form service to deliver submitted datas.
Note: some services need a callback page to redirect to when the form is submitted.
You then need to make another page (eg: thankyou.html) in witch you'll have to parse and present url passed datas to user.

Related

Push and Insert at a time in Vuejs and PHP

I want to push the value in Array. It will show the value instantly. There is no need to refresh the whole page.
app.todoList.push(this.todo)
With this line I am doing that.
At the same time I want to insert this value to Database. Here is the problem. Differently they are working perfectly. But combined it is problem.
Here is the problem snipet.
Data:
todo: null,
todoList: []
Form to submit:
<form class="w-100" #submit="createTodo">
<div class="form-group w-100">
<input type="text" class="form-control w-100" placeholder="What needs to be done? " v-model="todo">
</div>
</form>
Todo Print:
<ul>
<li v-for="todo in todoList">
{{ todo.todo_title }}
</li>
</ul>
Method of inserting data into db:
createTodo(e) {
// Pushing dot only
app.todoList.push(this.todo)
let formData = new FormData();
formData.append('todo_title', this.todo)
axios({
method: 'POST',
url: 'api/todos.php',
data: formData
}).then(function(res){
}).catch(function(res){
console.log(res)
});
this.todo = null
e.preventDefault();
}
What can I do to do it perfectly.
For starters I would say that a more standard way of doing it is pushing the todo in the Axios promise callback. This way you could also include the ID that is created from the backend in the object.
It's not entirely clear what the issue is, if the issue is that you get the li but empty name, the problem is that when you're doing app.todoList.push(this.todo) you're printing the 'todo_title'. What you need to do is push it with the key app.todoList.push({ todo_title: this.todo }).

Why do I get empty string from req.body.newItem?

Github repo: https://github.com/tomkovladko/goormProblem
I posted my Todolist App(from Colt's lecture on Udemy) on Goorm and everything works just fine except one thing.
I tried to make a POST method so that if you press enter it goes to /addItem and creates and add new <li> to the body.
that unfortunately doesn't work and i just get this:
{ newItem: '' }
I compared it to PostRequestDemo that Colt did and it's almost the same code, here:
Mine
app.post("/newItem", function(req,res){
var newItem = req.body.newItem
console.log(newItem) #here is where i get the empty string... it should print something i inputed to the form (for example "banana")
res.redirect("/")
})
---------------------
<form action="/newItem" method="POST">
<input type="text" name="newItem" placeholder="Add New Todo">
</form>
Colt's
app.post("/addFriend", function(req, res){
var newFriend = req.body.newFriend
friends.push(newFriend)
res.redirect("friends")
})
---------------------
<form method="POST" action="/addFriend">
<input type="text" name="newFriend" placeholder="Name" required>
<button>Submit</button>
</form>
if you need more code just let me know bum I'm very very confused because I just started using goorm and express and all of that

axios.post automatically splice url with my params

I want to implement an api with vue and axios in my front-end:
methods:{
startSpider:function(event){
alert("spider is ready to run!");
let data = {'searchKey':this.searchKey,
'category':this.category,
'num':this.num};
axios.post("{% url 'main:getCommodityInfo'%}",
data,
{headers:{'X-CSRFToken': this.getCookie('csrftoken')}})
.then(response=>{
console.log(response.data)
})
.catch(error=>{
console.log(error);
alert("connection has error")
})
},
When I call this function, I expect to get data from the back-end and stay at the inital url. It does receive data but the url quickly changed.
After some exploration, I find the browser implement two request! First, POST, and next GET:
Using 'searchKey':'switch', 'category':'electronic','num':60 as an example.
and My browser url subsequently changes to
Why it happens? I have just used POST not GET. The axios post seems to automatically splice inital url with the params. I have tried a lot of ways but failed. Even I have writed a small demo with the similiar structure like this to test, but the demo runs well! What happened? Help me please...
Updated I: Give my server behavior(django-view) and my router related is path('getCommodityInfo/',views.getCommodityInfo, name = 'getCommodityInfo')
def getCommodityInfo(request):
print(request.body)
return JsonResponse({"data":True}, safe=False)
Updated II: Give my front-end form:
<form>
<label for="searchKey">KeyWords</label>
<input v-model="searchKey" placeholder="Input Search Key" type="string" class="form-control" id="searchKey" name="searchKey">
<label for="category">Commodity Category</label>
<select v-model="selected" id="category" name="category">
<option v-for="option in options" v-bind:value="option.value">
${option.text}
</option>
</select>
<br>
<label for="num">Amount</label>
<input v-model="num" placeholder="Input amount needed" type="string" class="form-control" id="num" name="num" >
<button v-on:click="startSpider" class="btn btn-default">Submit</button>
<p>KeyWords : ${ searchKey }</p>
<p>Category : ${ selected }</p>
<p>Amount: ${ num }</p>
</form>
The bug happened because of not setting button type.
We could check this:
The missing value default is the Submit Button state.
And in the front-end form there is no type for the button, so the button type will be submmit button. When click on the button, it will automatically send a get request.
Modify the button like this:
<button v-on:click="startSpider" class="btn btn-default" type='button'>Submit</button>

Shopify PLUS - additional checkout custom field

I was trying to add additional custom field in the checkout screen and here is my code:
<div class="additional-checkout-fields" style="display:none">
<div class="fieldset fieldset--address-type" data-additional-fields>
<div class="field field--optional field--address-type">
<h2 class="additional-field-title">ADDRESS TYPE</h2>
<div class="field__input-wrapper">
<label>
<input data-backup="Residential" class="input-checkbox" aria-labelledby="error-for-address_type" type="checkbox" name="checkout[Residential]" id="checkout_attributes_Residential" value="Residential" />
<span>Residential</span>
</label>
<label>
<input data-backup="Commercial" class="input-checkbox" aria-labelledby="error-for-address_type" type="checkbox" name="checkout[Commercial]" id="checkout_attributes_Commercial" value="Commercial" />
<span>Commercial</span>
</label>
</div>
</div>
</div>
</div>
<script type="text/javascript">
if (window.jQuery) {
jquery = window.jQuery;
} else if (window.Checkout && window.Checkout.$) {
jquery = window.Checkout.$;
}
jquery(function() {
if (jquery('.section--shipping-address .section__content').length) {
var addType = jquery('.additional-checkout-fields').html();
jquery('.section--shipping-address .section__content').append(addType);
}
});
</script>
It returns the checkout page like this -
The problem is - once I click continue button and comes back to this page again, I don't see the checkbox checked. I feel the values are not being passed or may be something else.
What am I missing?
From the usecase, it looks like you want the user to select the Address Type either Residential or Commercial so a raido button group seems more suitable. I have edited the HTML to create the Radio Button instead of Checkbox. To maintain the state, I have used Session Storage. You may also replace Session Storage with Local Storage if you want to do so. For explanation check code comments.
<div class="additional-checkout-fields" style="display:none">
<div class="fieldset fieldset--address-type" data-additional-fields>
<div class="field field--optional field--address-type">
<h2 class="additional-field-title">ADDRESS TYPE</h2>
<div class="field__input-wrapper">
<label>
<input class="input-radio" aria-label="" type="radio" name="checkout[address_type]" id="checkout_attributes_Residential" value="residential" checked>
<span>Residential</span>
</label>
<label>
<input class="input-radio" aria-label="" type="radio"name="checkout[address_type]" id="checkout_attributes_Commercial" value="commercial">
<span>Commercial</span>
</label>
</div>
</div>
</div>
</div>
JavaScript part
<script type = "text/javascript" >
if (window.jQuery) {
jquery = window.jQuery;
} else if (window.Checkout && window.Checkout.$) {
jquery = window.Checkout.$;
}
jquery(function() {
if (jquery('.section--shipping-address .section__content').length) {
var addType = jquery('.additional-checkout-fields').html();
jquery('.section--shipping-address .section__content').append(addType);
// Get saved data from sessionStorage
let savedAddressType = sessionStorage.getItem('address_type');
// if some value exist in sessionStorage
if (savedAddressType !== null) {
jquery('input[name="checkout[address_type]"][value=' + savedAddressType + ']').prop("checked", true);
}
// Listen to change event on radio button
jquery('input[name="checkout[address_type]"]').change(function() {
if (this.value !== savedAddressType) {
savedAddressType = this.value;
sessionStorage.setItem('address_type', savedAddressType);
}
});
}
});
</script>
You are responsible for managing the state of your added elements. Shopify could care a less about stuff you add, so of course when you flip around between screens, it will be up to you to manage the contents. Use localStorage or a cookie. Works wonders. As a bonus exercise, ensure that your custom field values are assigned to the order when you finish a checkout. You might find all your hard work is for nothing as those value languish in la-la land unless you explicitly add them as order notes or attributes.

OctoberCMS frontend image upload

I'm trying to upload profile phoho in front end of OctoberCMS but with no luck.
Cannot catch it in the backend to save within the user.
Made everything exactly like in documentation of the CMS.
Need to make this work without any eternal plugins.
<form data-request="onCreateUser" data-request-update="user:'.res_user'" >
<input name="file_input" type="file" >
<button type="submit" class="subBtn">Create User</button>
</form>
In User i have:
public $attachOne = [
'avatar' => 'System\Models\File'
];
and this code:
$file = new System\Models\File;
$file->data = Input::file('file_input');
$file->is_public = true;
$file->save();
$model->avatar()->add($file);
Record stored in DB, but its empty. filesize = 0
Can anyone please help me with this?
Asked the big Bro, but found that this problem is very common, and have no solution.
Thanks
Update:
This is working, when I use this:
{{ form_open({files: true, request: 'onCreateConcert'}) }}
<!--File Input-->
<input type="file" name="file-upload" required="required">
<!--File Input-->
<!--Submit/Upload Button-->
<button type="submit">Upload</button>
{{ form_close() }}
but not with my form. whats i'm missing here?
I added as well token and session_key
{{ form_sessionKey() }}
{{ form_token() }}
It because you don't add enctype="multipart/form-data" to your form attribute.
When you use twig like {{ form_open({files: true, request: 'onCreateConcert'}) }}, the files: true will add attribute to your form to handle upload file. So the twig above will generate tag like below,
<form data-request="onCreateConcert" enctype="multipart/form-data">
try this:
use System\Models\File;
use Input;
[...]
if (Input::file("file_input")) {
$model->avatar = Input::file("file_input");
}
model->save();