ui-sref does not produce correct href with parameter - angular-ui-router

I'm trying to use ui-router to change state and pass a GUID parameter to my controller. I have this working using Kendo (different syntax) so I know what I'm aiming for. I cannot for the life of me figure out what the deal is. I have searched far and wide and I believe that I have the correct syntax for the ui-sref. Here it is:
<a ui-sref="clientEdit({ clientId: '{{vm.clientModel.id}}' })">Edit Link</a>
Produces this output in the rendered view (notice missing id):
<a ui-sref="clientEdit({ clientId: 'bfd50b6c-6542-48c5-adf7-8c1a21caf421' })" href="#/clientEdit/">Edit Link</a>
Here is my state:
.state("clientEdit", {
url: "/clientEdit/:clientId",
templateUrl: "/CompanyDashboard/ClientsCrud",
controller: "DashboardClientsCtl",
controllerAs: "vm"
})
When I hardcode the ID into the ui-sref it works as expected and produces the correct href for the tag. Like this:
<a ui-sref="clientEdit({clientId:'bfd50b6c-6542-48c5-adf7-8c1a21caf421'})">Hard code Edit Link</a>
The hard-coded ID tag produces this output in the rendered view (exactly as I would expect):
<a ui-sref="clientEdit({clientId:'bfd50b6c-6542-48c5-adf7-8c1a21caf421'})" href="#/clientEdit/bfd50b6c-6542-48c5-adf7-8c1a21caf421">Hard code Edit Link</a>
So, my question is: Am I missing something here? I really believe this should work as I'm already doing this successfully using a Kendo template for a different route.
Just in case you care, here is the working kendo template code:
template: "<a ui-sref='clientDetails({clientId:\"#=id#\"})'>#=customerNumber#</a>"
I have tried changing quotes to double as in the Kendo example, removing the quotes, removing the {{ }} from the Id expression. No Joy.
Thanks for any and all help.

Solution here is to NOT wrap the param with {{}}
// instead of this
<a ui-sref="clientEdit({ clientId: '{{vm.clientModel.id}}' })">Edit Link</a>
// use this
<a ui-sref="clientEdit({ clientId: vm.clientModel.id})">Edit Link</a>
The content of a vm.clientModel.id is already a string, and will be correctly passed as string (it is GUID for JS it is string)

So, I thought I had tried this yesterday before I posted the question, but I had not. Here is the correct syntax:
<a class="btn btn-sm btn-primary" ui-sref="clientEdit({ clientId: {{'vm.clientModel.id'}} })">Edit Client Test</a>
Notice that the single quotes are INSIDE the {{ }} and not on the outside. Simple eh?
This HTML produces the correct HREF like this:
<a class="btn btn-sm btn-primary" ui-sref="clientEdit({ clientId: vm.clientModel.id })" href="#/clientEdit/bfd50b6c-6542-48c5-adf7-8c1a21caf421">Edit Client Test</a>

Related

Use Vue-Router route information to generate page headers

This is probably really easy and I'm just missing something. I have a vue router page with links that all load up correctly and display correctly.
Hard part out of the way (well it was for me).
I would like to utilise some meta style data attached to each route to provide the page heading title.
So for example:
{
path: '/scenarios',
meta: {
title: "Scenarios!"
},
name: 'Scenarios',
component: Scenarios
}
The route with a meta title.
I would like to pull this data from here within the route declaration
Stick it on a vue page like this:
<template>
<span>
{{ $route.name }}
</span>
</template>
<script>
export default {
name: "PageTitle"
}
</script>
(this actually works to show the route name at the moment)
And I would like to plug it into my template like this:
<h1 class="h2">#yield('page-name')
<page-title></page-title>
</h1>
(I am using Laravel (5.8 I think))
This similar post might help (using a directive) Pass var to vue router in meta but it would be nice to know if its simpler than that. Thoughts?
Screw it, ive answered my own question
changed:
<template>
<span>
{{ $route.name }}
</span>
</template>
to:
<template>
<span>
{{ $route.meta.title }}
</span>
</template>

VueJS routing on click to chapter quiz

I am new to vuejs. I need to create a router link quiz with path /chapter/{{id}}/quiz. it will open another component
Path
{ path: '/chapter/:id(\\d+)/quiz', component: require('./components/Quiz.vue') },
router link
<a href="#" #click="editModal(chapter)">
<i class="fa fa-edit blue"></i>
</a>
/
<router-link :to="/chapter/{{chapter.id}}/quiz">
<i class="fa fa-question-circle blue"></i>
</router-link>
Currently I am getting error
Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of <div id="{{ val }}">, use <div :id="val">
You cannot use {{ }} for attribute values. So for your router-link component you will have to use javascript string concatenation to add the chapter.id or use a computed property to generate the url.
<router-link :to="'/chapter/' + chapter.id + '/quiz'">
Or if you are using es6 you can use template literals:
<router-link :to="`/chapter/${chapter.id}/quiz`">

Laravel how to make that id would not be shown through inspect

I have form like this
<form action="{{ url('/reviews/delete', ['id' => $review->id]) }}"method="POST">
{{ method_field('DELETE') }}
{!! csrf_field() !!}
<a class="delete right-button"> <i class="fa fa-trash-o" aria-hidden="true"></i> </a>
</form>
When I use inspect I see the id and if I change it I can delete different record depends on which id I fill into inspection. How to avoid this?
You can check in the controller like so
abort_if($user->id !== $review->user_id, 404)
personally I like using policies https://laravel.com/docs/5.6/authorization#writing-policies
$this->authorize('delete', $review);
The thing is that HTML already renders the form and when you submit it, request reads the URL inside the action and goes there, so there is no 'real' answer on how to prevent it, but you can put some validation in the FormRequest.
If you want to go further you can create Model Policy and check if the review belongs to the user which is trying to remove it, or some other kind of validation.

django form wizard ajax next step

I am creating a 9-step proposal form using django form wizard. All is well, until I wanted to use ajax to load the next step. I'm having a hard time configuring the ajax call in jquery because django forms don't have action url included in the form tag. Why is it like that anyway? A win-win situation for me is to have a loading screen for next step and if there is an upload file process in the step, show percentage loading for the uploaded file. Thanks!
I'm using this code, and It's working for me. I don't put any action inside the form, as you can see. I use the jquery 'on' function when the form is submited because all the form is reloading and changing inside the div#creation. Then the ajax url must be the one that displays your form.
In my case, the first step of the form is rendered also through ajax with get, when I click on some button. That's why there's isn't any form in the div at first. (I'm using bootstrap's modals).
<div id="creation">
<!-- form to be display through ajax -->
</div>
The template that is reload in the FormWizard Class in views is the following html:
template_name = 'creation_form.html'
Code por creation_form.html:
<form id="creation-form" action="#" method="post">
{% csrf_token %}
<table>
{{ wizard.management_form }}
{{ wizard.form }}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" class="btn btn-primary" aria- hidden="true" type="submit" value="{{ wizard.steps.first}}">First</button>
<button name="wizard_goto_step" class="btn btn-primary" aria-hidden="true" type="submit" value="{{ wizard.steps.prev}}">Previous</button>
{% endif %}
<input id="create-submit" class="btn btn-primary" type="submit" value="submit" />
</form>
Here is my ajax call:
$('#creation').on('submit', '#creation-form' , function(e){
e.preventDefault();
var fd = new FormData($('#creation-form').get(0));
$.ajax({
url: '/create/',
data: fd,
type: "POST",
success: function(data){
$('#creation').html(data);
},
processData: false,
contentType: false
});
});
Hope this is a proper response for your answer.
I'm currently having a hard time going to the first/previous step, if you figure it out please tell me how.
This is what you're looking for?
Here's what I did-
Created separate model forms for each step.This helped in easy server side validation.
Made ajax calls for each step to validate form on the server side and on success render the next form and hide the previous form.
On submit of last form async POST the data for persistence and processing and render the response asynchronously below the last step.
Also maintained a progress bar for each step.
This is how I created my async form wizard using django forms. Not neat but works! :)

Django Forms: Why doesn't boolean field work as I expect it?

I have a form:
class myForm(forms.Form):
myBoolField = forms.BooleanField(
label='myLabel',
required=True,
)
Here is the corresponding template:
<form action="." method="post" enctype="application/x-www-form-urlencoded">
{% csrf_token %}
{{ form.as_p }}
<div class="form-actions">
<button type="submit" class="btn btn-primary">Submit</button>
<a class="btn" href="{{ secondary_action_url }}">{{ secondary_action_text }}</a>
</div>
</form>
When Django renders this template myField shows up as an empty checkbox.
If I check the box, hitting the submit button yields "True" for the cleaned value of myField.
However, If I leave the box empty and hit the submit button, instead of getting "False", I get None. That's not at all what I want. I want this check box to return True or False.
What do I do to make it work like I want (and expect)? Is my expectation that a Required Boolean field returns True or False misplaced?
class myForm(forms.Form):
myBoolField = forms.BooleanField(
label='myLabel',
required=False,
initial=False
)
this prevents any further error, if you don't want to go deeper into this subject
edit after edit after edit: by marking required=True, you explicitly request an input from the user. by default, an unchecked checkbox doesn't get submitted (that's where the None value comes from) and your validation would fail everytime, because of the required.

Resources