axios.post automatically splice url with my params - vue.js

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>

Related

Binding getter array to checkbox group

I have a two page form so I am trying to mix submitting data to the server as well as making use of vuex. So on page one, I have a simple form which contains a group of checkboxes (removed layout and styling to reduce code)
<b-form #submit.stop.prevent="onSubmit">
<b-form-group>
<input v-model="$v.form.checkboxGroup.$model" type="checkbox" name="checkbox1" value="1">
<input v-model="$v.form.checkboxGroup.$model" type="checkbox" name="checkbox2" value="2">
<input v-model="$v.form.checkboxGroup.$model" type="checkbox" name="checkbox3" value="3">
</b-form-group>
<button class="btn try-btn" type="submit">Submit</button>
</b-form>
Essentially, when submitted, I send the form data to my repository so it can be saved on the backend. If this is successful, I call the following method
handleSubmitSuccess (response) {
if (response.data.action === 'next_step') {
this.$store.dispatch('createCheckboxData', this.$v.form.$model)
return
}
}
This method sets the checkbox data in my store and routes the user to the next page (removed this part). So all of this is fine, seems to work well.
So when on page two, I have a button that can take you back to page one. My idea is that if this happens, I use the previously checked data in the store to auto check the previously selected checkbox. As such, on page one I added a computed method
computed: {
checkboxData () {
return this.$store.getters.checkboxData
}
}
Now if I output checkboxData to the console, it seems to be an Observer object
[{…}, __ob__: Observer]
0:
checkboxData: Array(2)
0: "1"
1: "3"
length: 2
So the above shows that previously, the first and second checkboxes were checked.
My question is how can I now use this data to auto-check my checkboxes. I have seen some examples online, but they do not seem to work.
Thanks
The way you use Vue is a little different to me so you might have to change this but, basically, you can set your v-model to whatever array is set in the Vuex store and it will set those checkboxes to true:
new Vue({
el: "#app",
data: {
checkbox: [],
vuexData: ['1', '3']
},
mounted() {
this.checkbox = this.vuexData;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input v-model="checkbox" type="checkbox" name="checkbox1" value="1">
<input v-model="checkbox" type="checkbox" name="checkbox2" value="2">
<input v-model="checkbox" type="checkbox" name="checkbox3" value="3">
{{ checkbox }}
</div>

Pass UTC offset into controller route

Fairly new to ASP.NET CORE, come from WPF background.
Having some trouble understanding how to pass local variables around.
I have a form:
<span id="clock"></span>
<form asp-action="Create" asp-controller="Session" method="post" asp-route-session="#Model.Session">
<input asp-for="#Model.Session.ClientId" class="form-control" style="display: none" />
<ejs-dropdownlist id="clinics" dataSource="#Model.LinkableClinics" placeholder="Select Clinic" popupHeight="220px" ejs-for="#Model.Session.ClinicId">
<e-dropdownlist-fields text="Name" value="ClinicId"></e-dropdownlist-fields>
</ejs-dropdownlist>
<ejs-dropdownlist id="employees" dataSource="#Model.LinkableEmployees" placeholder="Select Employee" popupHeight="220px" ejs-for="#Model.Session.EmployeeId">
<e-dropdownlist-fields text="Name" value="EmployeeId"></e-dropdownlist-fields>
</ejs-dropdownlist>
<ejs-datetimepicker id="startdatetimepicker" placeholder="Select a date and time" ejs-for="#Model.Session.StartTime"></ejs-datetimepicker>
<ejs-datetimepicker id="enddatetimepicker" placeholder="Select a date and time" ejs-for="#Model.Session.EndTime"></ejs-datetimepicker>
<div class="form-group">
<input type="submit" value="Create Session" class="btn btn-primary" />
</div>
</form>
and I would like to add asp-route-offset to my form but I can't figure out how to pass a locally calculated variable into this routing.
This is a post, so I can't just use Url.Redirect() custom url builder.
I've also tried to add a hidden field and run a calculation inside the "value"
<input asp-for="#Model.Session.Offset" class="form-control" style="display: none" value="getValue()"/>
I'm calculating my offset in my <script> section as follows:
<script type="text/javascript">
window.onload = loaded;
function loaded() {
var clockElement = document.getElementById("clock");
function updateClock(clock) {
clock.innerHTML = new Date().getTimezoneOffset() / 60;
}
}
</script>
I've tried setting variables or the #Model object here, but nothing seems to want to stick.
Anyone have experience trying to pass a variable like this? Or a better way to pass UTC offset into my timestamp?
You're trying to mix and match things happening server-side and client-side. Your script which gets the offset runs client-side, after the server has sent the response. Your Razor code runs server-side, before the client has even received the page.
Long and short, if you want to update the value, you have to do it via client-side means, namely JavaScript:
document.getElementById('#Session_Offset').value = new Date().getTimezoneOffset();
You can't use something like asp-route-offset at all, because the offset is coming from the client and can't be used to generate the post URL. As a result, you'll need to stick with the hidden input approach.

vee-validate validation message not working in Laravel 5.6.7

I am using Laravel 5.6.7 with vue.js for form validation. I have successfully installed using npm install vee-validate#next --save
<form role="form">
<select name="Role_ID" v-validate data-vv-rules="required">
<option :value="-1" selected>Please select Role</option>
<option v-for="RoleRecord in RoleRecords" :value="RoleRecord.Role_ID">
{{RoleRecord.Role}}
</option>
</select>
<p v-if="errors.has('Role_ID')">{{ errors.first('Role_ID') }}</p>
<!-- UserName -->
<div>
<label>UserName</label>
<div class="col-md-9">
<input name="User Name" v-validate data-vv-rules="required" type="text"
v-model="createForm.UserName">
<p v-if="errors.has('User Name')">{{ errors.first('User Name') }}</p>
</div>
</div>
<button type="button" #click="validateBeforeSubmit()">
Save Changes
</button>
</form>
<script>
export default {
methods: {
validateBeforeSubmit() {
this.$validator.validateAll();
}
}
}
</script>
My findings
Due to some reasons the option is not being validated.
There is UserName field which is working perfectly.
I am expecting that it should show the error message if the option selected value is less then 0
Am I missing anything? Please let me know if you need more info.
in the vee-validate doc,
The field under validation must have a non-empty value. By default,
all validators pass the validation if they have "empty values" unless
they are required. Those empty values are: empty strings, undefined,
null.
-1 is still considered a valid value for required validation. Use specified empty values instead. (Namely: empty strings, undefined, null)
e.g.
<option :value="null" selected>Please select Role</option>
This should trigger the required validation.
Example: https://codepen.io/jacobgoh101/pen/geaqwr?editors=1011
There's a difference between your naming:
<input name="User Name" v-validate data-vv-rules="required" type="text" v-model="createForm.UserName">
<p v-if="errors.has('User Name')">{{ errors.first('User Name') }}</p>
v-model uses UserName (without spacing). The name-attribute in your input and errors.has + errors.first are using User Name (with spacing). Please make sure you're naming things exactly the same, both in front-end as well as in back-end (and preferably without whitespace).

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();

How to stay in Current Page

I have one form of user name and password fields followed by submit button. How do I stay in current page after clicking submit button without reloding page?
Any help is appreciated.
Try tis if you need a sumit button.
<input type="submit" onclick="return false" />
But you may want to use a simple clickable button if you don't wan't to sumbit your form on click... in this case, this should do the trick:
<input type="button" />
There are a couple of options. First of all in the markup for the submit button you can return false:
<input type="submit" onclick="return false;" />
The problem with the approach above is that it will cancel the submit, not sure if that's desired or not. Another approach you can take is to use something like jQuery to do an ajax request.
To do that you'd need to include jQuery:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
Then change your submit button to a regular button:
<input type="button" onclick="doAjaxCall();" />
The javascript function doAjaxCall would then be something like:
<script type="text/javascript">
function doAjaxCall() {
$.ajax({ url: "destinationurl.aspx", success: function(){
alert('success! insert success javascript code here');
}});
}
</script>