Passing a variable into Python from Jinja2 Drop-down menu - google-app-engine

I'm a programming newbie. How do I pass a variable from a drop-down menu with Jinja2 templating into my Python 2.7 code? I'm using the webapp2 framework on Google App Engine.
My code currently looks like this:
class AccountNew(Handler):
def get(self):
activities = ['Select one', 'Camping', 'Hiking', 'Fishing']
self.render('account-new.html', activities = activities)
def post(self):
acct_name = self.request.get('acct_name')
activity = self.request.get('activity')
self.write(acct_name)
self.write(activity)
My Jinja2 template is named "account-new.html" and looks like this:
<form method="post">
<label>
<div>Account Name</div>
<input type="text" name="acct_name" value="{{ acct_name }}">
</label>
<label>
<div>Parent</div>
<select>
{% for activity in activities %}
<option value="{{ activity }}">{{ activity }}</option>
{% endfor %}
</select>
</label>
<input type="submit">
</form>
The acct_name string gets passed back, but the activity string seems to come back as an empty string. Any insights would be greatly appreciated.

You have left the 'name' attribute off the select element. Should be like this:
<select name="activity">
{% for activity in activities %}
<option value="{{ activity }}">{{ activity }}</option>
{% endfor %}
</select>

Related

Shopify liquid nested product variant selection problem

I am working on a shopify theme project. On the product page the customer will need to selection the color then after the size. Which mean that every product got 2 option with 2 to 3 value.
I need to use variant to generate a ID for each different variants. Looping option1 and nesting option2 loop.
But sadly option 1 is not even looping. Is my syntax wrong ?
<header class="c-modal__header">
<h2 class="c-modal__title">Please select your{{ product.options[0] }}and{{ product.options[1] }}Before check out !</h2>
</header>
{% for option1 in product.variants.option1 %}
<p class="c-modal__caption">{{ product.option1 }}</p>
<ul class="c-modal__content-list">
{% for option2 in product.variants.option2 %}
<li class="c-modal__content--item c-modal__content--item--sku"><span class="c-modal__content__lineup">{{ variant.option2 }}</span>
<div class="c-modal__content__buttonarea">
<form class="c-modal__content__button c-button" method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
<input type="submit" value="In the cart!" class="btn" />
</form>
</div>
</li>
{% endfor %}
</ul>
{% endfor %}
Thanks a lot !
option1 or option2 do not exist as properties, as far as I know.
You're looking for something like this
{% for product_option in product.options_with_values %}
<label>
{{ product_option.name }}
<select>
{% for value in product_option.values %}
<option {% if product_option.selected_value == value %}selected{% endif %}>
{{ value }}
</option>
{% endfor %}
</select>
</label>
{% endfor %}
Or if you know the name of the option
<label>
Color
<select>
{% for color_option in product.options_by_name['Color'].values %}
<option>{{ color_option }}</option>
{% endfor %}
</select>
</label>

Show variable outside for loop shopify

I am trying to show the selected value in Shopify outside the for loop.
How do I show the selected radio option in the label after "Color:"? I want to display it where it says "SHOW SELECTED OPTION".
Does anyone know how to solve this?
<label>Color: SHOW SELECTED OPTION</label>
<fieldset class="single-option-color-selector"
id="ProductSelect-option-{{ forloop.index0 }}">
{% assign option_index = forloop.index %}
{% for value in option.values %}
{% assign variant_label_state = true %}
{% if product.options.size == 1 %}
{% unless product.variants[forloop.index0].available %}
{% assign variant_label_state = false %}
{% endunless %}
{% endif %}
<input type="radio"
{% if option.selected_value == value %} checked="checked"{% endif %}
value="{{ value | escape }}"
data-index="option{{ option_index }}"
name="color"
class="single-option-selector__radio"
id="ProductSelect-option-{{ option.name | handleize }}-{{ value | escape }}">
<label class="option-color-{{ value | escape }}" for="ProductSelect-option-{{ option.name | handleize }}-{{ value | escape }}" title="{{ value | escape }}">{{ value | escape }}</label>
{% endfor %}
</fieldset>
Based on the code you shared, it looks like you can try this:
<label>Color: {{ option.selected_value }}</label>

Select from array based on variants in shopify

By the end of the code, i have a button which value="{{ product.selected[0].id }}" , it does select only the first value [0] of the array no matter what i select, please what should i change to make sure it selects a value based on vaiant ?
<div>
{% if section.settings.show_quantity_selector %}
<div id="error-quantity-{{ section.id }}" class="form-message form-message--error product__quantity-error hide" tabindex="-1">
{% include 'icon-error' %} {{ 'products.product.quantity_minimum_message' | t }}
</div>
{% endif %}
{% form 'product', product, class:form_classes, novalidate: 'novalidate' %}
{% unless product.has_only_default_variant %}
{% for option in product.options_with_values %}
<div class="selector-wrapper js product-form__item">
<label {% if option.name == 'default' %}class="label--hidden" {% endif %}for="SingleOptionSelector-{{ forloop.index0 }}">
{{ option.name }}
</label>
<select class="single-option-selector single-option-selector-{{ section.id }} product-form__input" id="SingleOptionSelector-{{ forloop.index0 }}" data-index="option{{ forloop.index }}">
{% for value in option.values %}
<option value="{{ value | escape }}"{% if option.selected_value == value %} selected="selected"{% endif %}>{{ value }}</option>
{% endfor %}
</select>
</div>
{% endfor %}
{% endunless %}
<!-- Partie Product select -->
<select name="id" id="ProductSelect-{{ section.id }}" class="product-form__variants no-js">
{% for variant in product.variants %}
{% if variant.available %}
<option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">
{{ variant.title }}
</option>
{% endif %}
{% endfor %}
</select>
<!-- END Partie Product select -->
<div>
<form class="product-form" action="/cart/add" data-productid="{{product.id}}" method="post" style="padding-top: 0px; padding-bottom: 50px">
<input type="hidden" name="id" data-productid="{{product.id}}" class="product-select" value="{{ product.selected[0].id }}" data-variant-title="{{ product.variants[0].title }}"/>
<input type="submit" value="Add To Cart" class="btn btn btn-default"/>
</form>
</div>
{% endform %}
</div>
Thank you !!
At the moment you have a form in a form, which is a big NO NO!
{% form 'product', product, class:form_classes, novalidate: 'novalidate' %}
...
<form class="product-form" action="/cart/add" data-productid="{{product.id}}" method="post" style="padding-top: 0px; padding-bottom: 50px">
In addition you have two fields with a name="id".
<select name="id" id="ProductSelect-{{ section.id }}"
and
<input type="hidden" name="id"
Remove the inner form and the hidden field with name="id" and you should be good to go.

Login button won't fire

I'm using Django and AngularJS in a log in form. In this case, the username is in email format. My login form's button will only become un-disabled when the user enters a string formatted like an email address and a password of at least eight characters. But clicking the login button does nothing. Nothing fires. No POST request is made.
forms.py:
class LoginForm(AuthenticationForm):
'''
Form to log in a user
'''
error_messages= {
"invalid_login": _("Incorrect %(username)s/password combo")
}
title= "Sign in"
username= forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={"id":"id_login_username", "type":"email", "placeholder":"Email", "ng-model":"login.email"}))
password= forms.CharField(label=_("Password"), widget=forms.PasswordInput(attrs={"placeholder":"Password", "ng-model":"login.pw", "ng-minlength":settings.MIN_PW_LENGTH}))
urls.py:
urlpatterns += [url("^login-register/$", views.login_register, name="login_register"),]
views.py:
def login_register(request, template="pages/login_register.html"):
registration_form= RegisterForm()
return render(request, template, {"registration_form":registration_form})
login_register.html:
{% extends "base.html" %}
{% load i18n mezzanine_tags staticfiles %}
{% block meta_title %}{% trans "Register or log in" %}{% endblock %}
{% block title %}{% trans "Register or log in" %}{% endblock %}
{% block extra_head %}
<meta name="robots" content="noindex">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
{% compress js %}
<script src="{% static "js/login-register.js" %}"></script>
{% endcompress %}
{% endblock %}
{% block main %}
<div id="login-register-wrapper" ng-app="app" ng-controller="Ctrl">
<form id="login-form" name="loginForm" method="post">
{% csrf_token %}
{% if login_form.non_field_errors %}
<p class="text-danger" role="alert">{{ login_form.non_field_errors.as_text|cut:"* "|escape }}</p>
{% endif %}
{% for field in login_form %}
<p>{{ field }}</p>
{% if field.errors %}
<small class="text-danger" role="alert">{{ field.errors.as_text|cut:"* "|escape }}</small>
{% endif %}
{% endfor %}
<button id="login-button" class="btn btn-primary" type="submit" ng-disabled="!loginForm.username.$valid || !login.pw">Log in</button>
</form>
</div>
{% endblock main %}
login-register.js:
var app= angular.module("app",[]);
app.config(function($interpolateProvider){
$interpolateProvider.startSymbol("[[[");
$interpolateProvider.endSymbol("]]]");
});
app.controller("Ctrl",function($scope, $rootScope){
});
Why does the form not submit when I click the login button after I properly fill out the "Email" and "Password" fields? And why does the button successfully submit when I remove all AngularJS from my files?
Update: And here's what the form HTML looks like in the browser.
<form method="post" name="loginForm" class="ng-invalid ng-dirty ng-valid-email ng-valid-parse ng-valid-required ng-invalid-minlength ng-submitted">
<input type="hidden" name="csrfmiddlewaretoken" value="aHUiUqU1EDmTcqgr5SpyELLnR8dsNh6mTExN7FqmiwX1ykPYlZBcrOBWjRA9YlBj"> <p><input id="id_login_username" name="username" ng-model="login.email" placeholder="Email" type="email" required="" class="ng-not-empty ng-dirty ng-valid-required ng-valid ng-valid-email ng-touched"></p>
<p><input id="id_password" name="password" ng-minlength="8" ng-model="login.pw" placeholder="Password" type="password" required="" class="ng-invalid ng-not-empty ng-dirty ng-valid-parse ng-valid-required ng-invalid-minlength ng-touched"></p>
<button class="btn btn-primary" type="submit">Log in</button>
</form>
The form data won't go anywhere unless you tell it where to go. Your form does not submit because it lacks an action or ng-submit.
The action attribute is a form handler that you put on the form element, e.g.
<form id="login-form" name="loginForm" method="post" action="/your-endpoint">
But the angular way is to specify an ng-submit function.
<form id="login-form" name="loginForm" method="post" ng-submit="foo()">
$scope.foo = function() {
// ...
// do whatever extra logic you need to, then
// $http.post('./your-endpoint', formdata)
}

$index inside ng-model is not printing index in blade template

I am using angular js in blade template. I used ng-repeat to populate a form using data from $http.
When i inspect html then i get
ng-model="newProp[$index].display_name"
but i want like
ng-model="newProp[0].display_name"
I mean I want value of $index. It is printing index value when i print like #{{ $index }} but inside ng-model it is printing as it is. I want integerd so that i can send them back in server.
Plese help
<div class="form-group" ng-repeat="erp in eachRoleProperties">
<label for="" class="col-sm-8 control-label">#{{erp.display_name}} #{{$index}}</label>
<div class="col-sm-4">
<select ng-model="newProp[$index].access">
<option value="1">Yes</option>
<option value="0">No</option>
</select>
</div>
<input type="hidden" value="#{{erp.display_name}}" ng-model="newProp[$index].display_name">
<input type="hidden" value="#{{erp.db_name}}" ng-model="newProp[$index].db_name">
</div>

Resources