angularjs data binding not working on string variable? - string

I have 2 versions of my code, one is not working and the other it is.
My question is "why the not working one is not working?"
here is the JSfiddle http://jsfiddle.net/fhjF7/
The not working version:
Controller:
function Ctrl($scope) {
$scope.username = "username";
$scope.users = [ "Matteo", "Marco", "Michele" ];
};
HTML:
<h1> Not working example</h1>
<div ng-controller="Ctrl">
<div ng-repeat="user in users">
<input type="radio" ng-model="username" name="usern" ng-value="user" />
<strong>{{user}}</strong>
</div>
<div>selected: {{username}}</div>
</div>
and here is the working one, which is almost identical but replacing the string variable with an object:
Controller:
function usersCtrl($scope) {
$scope.names = {username: "username"};
$scope.users = [ "Matteo", "Marco", "Michele" ];
};
HTML:
<h1> Working example</h1>
<div ng-controller="usersCtrl">
<div ng-repeat="user in users">
<input type="radio" ng-model="names.username" name="username" ng-value="user" />
<strong>{{user}}</strong>
</div>
<div>selected: {{names.username}}</div>
</div>

It is because of the way javascript manages function parameters.
The easy way to understand it is that String, Number, and Boolean parameters are always sent byValue, while Objects and Functions are always sent byRef, that is why when you use the dot inside an ng-model it means you are doing a reference to an object which will propagate, while if you don't use a dot inside the ng-model, you are referencing a String, Number or Boolean which is actually a copy of the real variable.
More information here https://egghead.io/lessons/angularjs-the-dot and https://github.com/angular/angular.js/wiki/Understanding-Scopes

Ng-repeats create their own isolate scopes, so that's why the string is not being preserved as it's not pass by reference. If you want to update the model use
<input type="radio" ng-model="$parent.username" name="usern" ng-value="user" />
$parent gives you access to the parents scope which is outside the ng-repeat and should be the one you want.

The answer for your not working code : http://jsfiddle.net/ashuslove/fhjF7/30/
HTML :
<h1> Not working example</h1>
<div ng-controller="Ctrl">
<div ng-repeat="user in users">
<input type="radio" ng-model="names.usern" name="usern" ng-value="user" />
<strong>{{user}}</strong>
</div>
<div>selected: {{names.usern}}</div> //Changed line here
</div>
The function :
function Ctrl($scope) {
$scope.names = {usern: "usern"}; //Also need to change this
$scope.users = [ "Matteo", "Marco", "Michele" ];
};

Related

How to get structured object using POST endpoint in SvelteKit?

when I'm using the POST endpoint from Sveltekit, I get a "flat" object as output. How can I get a "structured" Object instead ?
Let's assume the following code:
index.svelte
<div class="container">
<form method="post">
<label for="firstname">Firstname</label>
<input type="text" name="firstname" />
<label for="lastname">Lastname</label>
<input type="text" name="lastname" />
<label for="dog">Dog 1</label>
<input type="text" name="dog" />
<label for="dog">Dog 2</label>
<input type="text" name="dog" />
<!-- ... -->
<button>Save</button>
</form>
</div>
index.js
export async function post({request}){
const data = Object.fromEntries(await request.formData());
console.log(data);
return{}
}
Ouput (what I'm calling "flat" object)
{ firstname: 'foo', lastname: 'bar', dog: 'teckel', dog: 'labrador' }
Instead of that output, how should I proceed to get the following one in my index.js
Expected output:
{
firstname: 'foo',
lastname: 'bar',
dogs: [ { dog: 'teckel' }, { dog: 'labrador' } ]
}
There are libraries that can perform a transform like this more or less automated. Some use conventions in the field names to parse the data into arrays and nested structures, others additionally use schemas to do type conversions or validation. E.g. to achieve an array of objects like this, one might set the names like this:
<label for="dog">Dog 1</label>
<input type="text" name="dogs[][dog]" />
<label for="dog">Dog 2</label>
<input type="text" name="dogs[][dog]" />
The [] Indicates that the field is part of an array, [dog] indicates that a property called dog is set on the element (.dog would also be reasonable).
So instead of calling Object.fromEntries you have to either parse the data yourself or find a library that does it for you. (Note that StackOverflow is not a place for library recommendations.)
Personally, I would avoid the synchronous form post and send JSON asynchronously instead, that way you can send in a fixed structure and receive that exact structure. Of course this requires binding/reading the form values yourself.

access test data after test area in cypress

I have an html code with contains
<div class="form-card">
<h2 class="fs-title" test-data="area_1">
About DigCompEdu
</h2>
<p></p>
<label for="academic_teaching" class="question" test-data="question_1">
<b>1- </b>
</label>
<small id="academic_teachingHelp" class="form-text text-muted">
</small>
<div class="form-check question-form-check ">
<div class="row">
<div class="col-1">
<input class="radio" type="radio" value="0" id="3" name="2" test-data="answer_1" />
</div>
</div>
So, I have h1 with testdata name after that i have a form, this form contains question with multin check radio .. i want to access this check , not by just call ([test-data="answer_2"])
because i have another tips and don't want to check them as this one ,
i did smth like this but it's not working :
cy.get('[test-data="area_1"]~[test-data="answer_2"]').check({force: true})
Any one have another idea ?
It might be the ~ between the selectors, I haven't seen that before.
Does it work with a space between instead?
cy.get('[test-data="area_1"] [test-data="answer_2"]').check({force: true})
If the heading is followed by the form like this
<h2 class="fs-title" test-data="area_1">
About DigCompEdu
</h2>
<div class="form-check question-form-check ">
...
then you would query like this
cy.get('[test-data="area_1"]')
.next('.form-check') // next element on page
.find('[test-data="answer_2"]') // this looks inside '.form-check'
.check({force: true})

Cannot pass variables to Django 3 method from HTML template

I am a Django newbie who is trying to convert an existing HTML based website to Django 3. The only complex piece of this page is a call to a Django method that uses the django.core.mail package and everything works, but, I am trying to pull some data off of the HTML template and pass it to this method.
The method works, only it sends a blank email. I am trying to pass contact information that the end user would fill out on the form. If I hard code the data into the method it works.
I have tried passing the data through urls.py, but, everything I try fails to even parse when I call the method. When I use a request.GET.get everything seems to work, just no data.
I was hoping to use something similar to JQuery like the following in the method.
name = str(request.GET.get('Name:', '').strip())
email = str(request.GET.get('Email:', '').strip())
msg1 = str(request.GET.get('Message:', '').strip())
with the fields being in the HTML form.
I am going to include some of the relevant configuration items below.
urls.py
from django.urls import path
from django.conf import settings
from django.conf.urls import url
from django.conf.urls.static import static
from . import views
app_name = 'willdoit'
urlpatterns = [
path('', views.index),
#url(r'^contact/(?P<name>\.+)/(?P<email>\.+)/(?P<msg1>\.+)/?$', views.contact, name='contact'),
path('contact/', views.contact, name='contact'),
]
views.py
def contact(request):
name1 = request.GET.get('name', '')
email1= request.GET.get('email', '')
msg1 = request.GET.get('message1', '')
subject = 'Work needed'
from_email = settings.DEFAULT_FROM_EMAIL
message = name + ' ' + email + ' ' + msg1
recipient_list = ['pkustra914#gmail.com']
send_mail(subject, message, from_email, recipient_list, fail_silently=False)
return HttpResponse('Success')
Relevant HTML Template section
<div class="contact_content">
<div class="col-md-6 col-sm-6 col-xs-12">
<div class="contact_message wow fadeInLeft" data-wow-duration="1.5s">
<form action="#" id="formid">
<form action="#" id="formid">
<div class="form-group"> <input class="form-control" name="name"
placeholder="Name" required="" type="text"> </div>
<div class="form-group"> <input class="form-control" name="email"
placeholder="Email" required="" type="email"> </div>
<div class="form-group">
<div class="Descrizione"> <label for="InserisciDescrizione"
class=""><b>Message</b></label> <textarea class="form-control"
id="message" placeholder="Type message:" name="message1" rows="6" cols="50"
title="Message"></textarea> </div>
<a id="submit" href="{% url 'willdoit:contact' %}" class="btn btn-primary">Submit</a>
I would prefer to use the request.GET.get method, but, there is a lot more documentation passing it through the urls.
Thanks.
Your code request.GET.get('Name:', '') returns empty string when the key 'Name:' is not found.
To fix this, use request.GET.get('name', '') request.GET.get('email', '') request.GET.get('message', '') instead.
Details
I see that you are using a with template tag for nothing. The following line of code does not change the name attribute string to PascalCase. See with template tag (Docs)
{% with Name=name Email=email Message=message %}
Even if it worked, your code should be calling request.GET.get('Name', '') instead of request.GET.get('Name:', ''). But it won't work, as with would not modify the attribute names in the GET request.
#EDIT1
There are apparently more bugs in your html code. I have reformatted your code and listed up some obvious bugs.
<!--REFORMATTED CODE-->
<form action="#" id="formid"> <--------------DUPLICATES, remove one
<form action="#" id="formid"> <--------------DUPLICATES, remove one
<div class="form-group"> <input class="form-control" name="name"
placeholder="Name" required="" type="text"> </div>
<div class="form-group"> <input class="form-control" name="email"
placeholder="Email" required="" type="email"> </div>
<div class="form-group">
<div class="Descrizione">
<label for="InserisciDescrizione" class=""><b>Message</b></label>
<textarea class="form-control" id="message"
placeholder="Type message:" name="message1" rows="6" cols="50"
title="Message"></textarea>
</div>
<a id="submit" href="{% url 'willdoit:contact' %}"
class="btn btn-primary">Submit</a>
<-------- MISSING DIV END TAG
<-------- MISSING FORM END TAG
Furthermore, you are calling the server by url directly using the following code:
<a id="submit" href="{% url 'willdoit:contact' %}" class="btn btn-primary">Submit</a>
This does not tell the page which form you want to submit (there are cases where there are multiple forms).
You have two choices:
Replace the tag with standard html form submit button <input type="submit">, and add the url to the action attribute of the form. Use the following code to do so:
<form action="{% url 'willdoit:contact' %} id="formid">
...
...
<input id="submit" type="submit" class="btn btn-primary" value="Submit"/>
</form>
This solution will by default use the GET method to send a request to the server, and you will be able to get the inputted values by calling request.GET.get(name).
If you are using JQuery, you can replace the with the following:
Submit
This is however not recommended. Please use the standard html form input tag for the submit button.
Great. Moving the method call to the form tag worked great.
Thanks! You guys are the best.

How do you implement a HTML form which accepts text input meant for tag/hashtag values?

Update 1
I managed to locate a solution called Tagify but I have problems implementing it.
As a start, I am trying to implement only the simplest version of Tagify.
Below is the content of my show.ejs file.
As you might expect, I also have a routes folder containing the CRUD routes and logic but I do not think that should be touched for this purpose?
I also ran the command to install the Tagify module in my node_modules folder but I am not exactly clear where I should import the contents of that folder, and whether I should be doing this
import tagify from ....
or
var Tagify = require("...")
Though I believe it is the latter.
<% include ../partials/header %>
<div class="container">
<div class="row">
<h1 style="text-align: center">Create a New Entry</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/events" , method="POST">
<div class="form-group">
<input class="form-control" type="text" name="name" placeholder="Name">
</div>
<div class="form-group">
<input class="form-control" type="number" name="price" placeholder="Price" min="0.01" step="0.01">
</div>
<div class="form-group">
<input class="form-control" type="text" name="image" placeholder="image url">
</div>
<div class="form-group">
<input class="form-control" type="text" name="description" placeholder="Describe the place">
</div>
<div class="form-group">
<textarea name='tags2' placeholder='Movie names'>The Matrix, Pulp Fiction, Mad Max</textarea>
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Submit!</button>
</div>
</form>
View all events
</div>
</div>
</div>
<script type="text/javascript">
var input = document.querySelector('textarea[name=tags2]'),
tagify = new Tagify(input, {
enforceWhitelist: true,
whitelist: ["The Shawshank Redemption", "The Godfather", "The Godfather: Part II", "The Dark Knight", "12 Angry Men", "Schindler's List", "Pulp Fiction", "The Lord of the Rings: The Return of the King", "The Good, the Bad and the Ugly", "Fight Club", "The Lord of the Rings: The Fellowship of the Ring", "Star Wars: Episode V - The Empire Strikes Back", "Forrest Gump", "Inception", "The Lord of the Rings: The Two Towers", "One Flew Over the Cuckoo's Nest", "Goodfellas"],
callbacks: {
add: console.log, // callback when adding a tag
remove: console.log // callback when removing a tag
}
});
</script>
<% include ../partials/footer %>
Original question
For example, if I create a restaurant reviews website and am creating the page with a form so I can add new restaurants to the site, I would like to include fields like:
Restaurant name
Address
Average price per pax
Further to this, let's say I want to add a field where every semi-colon separated string can become something like a tag. Examples: "italian" "western" "family-friendly". How are possible ways I can implement this? It seems the standard HTML forms do not allow this and I need to import something - Am I wrong?
Currently learning & experimenting on a MEN stack (MEAN less Angular)
Much thanks in advance.

cant make the gmaps.js search functions

i have made this simple app with gmaps.js but i need the search functions like they show it here:
http://hpneo.github.io/gmaps/examples/geocoding.html
i looked at the source code and all but it aint working.. The search button reloads the page...
my code is a follows:
<script>
$('#geocoding_form').submit(function(e){
e.preventDefault();
GMaps.geocode({
address: $('#address').val().trim(),
callback: function(results, status){
if(status=='OK'){
var latlng = results[0].geometry.location;
map.setCenter(latlng.lat(), latlng.lng());
}
}
});
});
</script>
<form method="post" id="geocoding_form">
<label for="address">Address:</label>
<div class="input">
<input type="text" id="address" name="address" />
<input type="submit" class="btn" value="Search" />
</div>
</form>
<div id="map"></div>
the rest is loaded in from scripts.js you can see it in sourcecode. Why is this happening and how can i fix this?
The web app is located here, http://travelers.work/trein/
You need to change
map.setCenter(latlng.lat(), latlng.lng());
to
map.setCenter(latlng);
because the search returns a LatLng object as a result, and that's what is needed as an input for setCenter.
Here's a JS demo with your code: http://jsfiddle.net/DuRhR/3/
EDIT after comments:
Alternatively, you can pass to setCenter a LatLngLiteral
map.setCenter({lat: latlng.lat(), lng: latlng.lng()});

Resources