Confirm overwrite/delete? (appengine jinja2 python) - google-app-engine

I'm developing an app for production planning in a factory using appengine/jinja2 and am stuck with how to ask the user to confirm if the app should overwrite existing data or delete an entity in the NDB.
Maybe someone can suggest a course of action?
In product_edit.py I do the following (simplified):
RequestHandler
...
execute query and find given product
template_values = {
'prod_id': query.prod_id,
'prod_desc': query.prod_desc,
}
template = JINJA_ENVIRONMENT.get_template('/html/product_edit.html')
self.response.write(template.render(template_values))
The product_edit.html file looks like below (I'm using w3.css).
...
<form class="w3-container" action="/products-save" method="post">
<label class="w3-text-blue"><b>Product ID</b></label>
<input value="{{prod_id}}" name="prod_id_txt" size="15" class="w3-input w3-border">
<br>
<label class="w3-text-blue"><b>Product Description</b></label>
<input value="{{prod_desc}}" name="prod_(I'm using w3.css)desc_txt" size="50"
<input class="w3-btn w3-blue" type="submit" value="Save">
</form>
It populates two inputs with the product ID and description coming from the NDB and provides a "Save" button.
The save invokes the appropriate request handler to write to the NDB. So I can overwrite the existing NDB entity, no probs.
But how can I ask the user to confirm before overwriting (or deleting) existing data?
In the product-save request handler I can of course display a page asking the user to confirm, but in doing this I lose the data from the original POST.
One option would be to send the data to the new Jinja2 template via hidden fields, and upon user confirmation save the data from the hidden fields. However, this would not win a code beuty contest and is prone to coding errors. Is there anything more elegant I could do?
For the delete form I could do something with a pop-up to ask for confirmation, but I would like to use the same method as for the edit so that they are visually similar.
Thanks in advance!

There are many ways to accomplish this. The most straightforward way is to wire the form submit through a javascript function before submitting. Change:
<input class="w3-btn w3-blue" type="submit" value="Save">
to
<div id="saveWithConfirm">
<input class="w3-btn w3-blue" type="button" value="Save" onclick="confirmOverwrite('ask');" />
</div>
then:
function confirmOverwrite(confirm) {
confirmDiv = document.getElementById("saveWithConfirm");
if ( confirm == "confirmed" ) {
document.getElementById("ID-of-Form-Here").submit();
} else if ( confirm == "ask" ) {
//... if you need to check the database first, do an ajax call here...
confirmDiv.innerHTML = '<input class="w3-btn w3-blue" type="button" value="No" onclick="confirmOverwrite(\'no\');" /><input class="w3-btn w3-blue" type="button" value="Yes" onclick="confirmOverwrite(\'confirmed\');" /> ';
} else {
confirmDiv.innerHTML = '<input class="w3-btn w3-blue" type="button" value="Save" onclick="confirmOverwrite(\'ask\');" /> ';
}
}
This way, you never leave the form.

Related

Making the Bootstrap navbar searchbox work

I am trying to make a search function which works if I put in the query params into my URL directly but I don't know how to make it work so that it picks it up from the search box and executes it. I have used ng-model to map the text itself to the controller which works but the execution isn't working.
The navbar form:
<form ng-submit="doSearch()" class="navbar-form">
<div class="form-group" style="display:inline;">
<div class="col-md-offset-4 input-group" style="display:table;">
<input ng-model="search.text" class="form-control" name="search" placeholder="Search Here" autocomplete="off" autofocus="autofocus" type="text">
<span class="input-group-addon" style="width:1%;">
<span class="glyphicon glyphicon-search"></span>
</span>
</div>
</div>
By the way, my doSearch() function works just fine when I run it manually and so is the search itself. I have also validated that search.text comes through. I guess what I am asking is how do I make the icon (glyphicon-search) execute ng-submit="doSearch()" when the user clicks on it or presses enter.
Sorry if this is very obvious. I was always more on the backend side of things so am sorta new to HTML and Angular.
Thanks
You could place the icon inside a <button> element instead of <span>, tweak a bit of css to integrate it to the form field.
In regards to trigger search on enter, with jQuery something like this could be used:
$('input').keypress(function (e) {
var key = e.which;
if(key == 13) // the enter key code
{
doSearch();
}
});
did you try using <button type="submit"> before your search icon
<span class="glyphicon glyphicon-search"></span>
to specify that clicking on that button is equivalent to a submit event for that form.
So this worked in the end. First, the proper HTML which works:
<form ng-submit="doSearch()" class="navbar-form">
<div class="form-group" style="display:inline;">
<div class="col-md-offset-4 input-group" style="display:table;">
<input ng-model="search.text" class="form-control" name="search" placeholder="Search Here" autocomplete="off" autofocus="autofocus" type="text">
<span ng-click="doSearch()" class="input-group-addon" style="width:1%;">
<span class="glyphicon glyphicon-search"></span>
</span>
</div>
</div>
</form>
Furthermore, there was an issue with the view not connecting to the controller. Actually, let me rephrase that - it was connecting to the controller but only when the whole page loaded and for my test, I had a console.log('I have loaded') put in there. So when I saw "I have loaded", I thought my controller was invoked properly.
However, the doSearch() was in the controller which was connecting via angular routing, so the ng-View was not connecting to the right controller.
I am not sure if this means anything to anyone but I am writing this in case someone else comes across an issue like mine.
So just to summarise the issue was not with the HTML as I originally thought. ng-submit (for form submission when pressing enter) and ng-click (for clicking the glyphicon) does the trick.

Validate field count in angular form

I have a form where a model contains an array of sub-models, like this:
<form name="form1">
<div ng-repeat="sub in model.submodels">
<input ng-model="sub.name" required>
<button ng-click="delSubmodel($index)">x</button>
</div>
<button ng-click="addSubmodel()">+</button>
<button ng-disabled="form1.$invalid" type="submit">Save</button>
</form>
How can I make form invalid when there are no input fields (or, in general, when the count of input fields is less than/greater than some value)
Update: Thanks for responses, I hope this can be done outside of controller.
Okay, I just got what you want to achieve, you will had to add a constraint to the form, which is the size of the subModel, so in your submit method:
Before doing anything
$scope.form1.$setValidity('size', model.subModels.length <= 0);
This will set the validity of the form to false in case your condition is false, or viceversa, you can also show a message to notify it to the user, adding this:
<form name="form1">
<div ng-repeat="sub in model.submodels">
<input ng-model="sub.name" required>
<button ng-click="delSubmodel($index)">x</button>
</div>
<input type="hidden" name="size" ng-model="model.subModels.length" />
<button ng-click="addSubmodel()">+</button>
<button ng-disabled="form1.$invalid" type="submit">Save</button>
You can check this example if you don't feel you didn't understood well my point, which is doing the same, just changing the validity for a single input.
Hope it helps you.

Translated form validation in AngularJS

What's the easiest way of changing the default error messages in form validation provided by Angular to another language?
If I'm not mistaken, you think about html5 validation.
Something like this:
<b>HTML5 validation</b>
<form>
First name:
<input type="text" name="firstName" required="" />
<br />
Last name:
<input type="text" name="lastName" required="" />
<br />
<input type="submit" value="Submit" />
</form>
If user click on the Submit button he will see:
I think that this error comment you cannot change because it depends on the user browser/computer settings.
Maybe you should try to use angularjs validation (first add to form novalidate to switch off HTML5 validation):
HTML
<div ng-controller="PersonController">
<b>AngularJS validation</b>
<form novalidate name="myForm">
First name:
<input type="text" name="firstName" ng-model="newPerson.firstName" required="" />
<span style="color: red" ng-show="myForm.firstName.$dirty && myForm.firstName.$invalid">First name is required</span>
<br />
Last name:
<input type="text" name="lastName" ng-model="newPerson.lastName" required="" />
<span style="color: red" ng-show="myForm.lastName.$dirty && myForm.lastName.$invalid">Last name is required</span>
<br />
<button ng-click="resetPerson()">Reset</button>
<button ng-click="addPerson()" ng-disabled="myForm.$invalid">Save</button>
</form>
</div>
JavaScript
var myApp = angular.module('myApp', []);
myApp.controller('PersonController', ['$scope',
function($scope) {
var emptyPerson = {
firstName: null,
lastName: null
};
$scope.addPerson = function() {
alert('New person added ' + $scope.newPerson.firstName + ' ' + $scope.newPerson.lastName);
$scope.resetAdvert();
};
$scope.resetPerson = function() {
$scope.newPerson = angular.copy(emptyPerson);
// I don't know why not work in plunker
//$scope.myForm.$setPristine();
};
$scope.resetPerson();
}
]);
If user fill the field and erase he will see the error info:
The submit button will be disabled if user don't fill the required fields.
Plunker example
Why don't you try something easy for a change... :) Well here is my Angular-Validation. I made a project on Github and I think you can't be simpler than that...and yes I also support translation localization, those are saved into an external JSON file:
<!-- example 1 -->
<label for="input1">Simle Integer</label>
<input type="text" name="input1" validation="integer|required" ng-model="form1.input1" />
<span class="validation text-danger"></span>
<!-- example 2 -->
<label for="input2">Alphanumeric + Exact(3) + required</label>
<input type="text" name="input2" validation="alpha|exact_len:3|required" ng-model="form1.input2" />
<span class="validation text-danger"></span>
JSON external file for translation locales
// English version, JSON file (en.json)
{
"INVALID_ALPHA": "May only contain letters. ",
"INVALID_ALPHA_SPACE": "May only contain letters and spaces. ",
...
}
// French version, JSON file (fr.json)
{
"INVALID_ALPHA": "Ne doit contenir que des lettres. ",
"INVALID_ALPHA_SPACE": "Ne doit contenir que des lettres et espaces. ",
...
}
On top of supporting multiple translations, the directive is so crazy simple for validation, that you'll just love it. I can define whatever amount of validation rules (already 25+ type of validators available) under 1 attribute. validation="min_len:2|max_len:10|required|integer" and the error message will always be displayed in the following <span> isn't it beautiful? I think so too hehe... 1 line of code for your input, 1 line of code for the error display, can you beat that? oh and I even support your custom Regex if you want to add. Another bonus, I also support whichever trigger event you want, most common are probably onblur and onkeyup. I really added all the imaginable features I wanted into 1 crazy simple directive.
No more clustered Form with 10 lines of code for 1 input (sorry but always found that ridiculous) when the only little piece you need is 2 lines of code, nothing more, even for an input of 5 validators on it. And no worries about the form not becoming invalid, I took care of that as well, it's all handled the good "Angular" way.
Take a look at my Github project Angular-Validation... I'm sure you'll love it =)
DEMO
Added a live demo on Plunker

AngularJS not validating email field in form

I have the html below where I have a form that I want to submit to the AngularJS Controller.
<div class="newsletter color-1" id="subscribe" data-ng-controller="RegisterController">
<form name="registerForm">
<div class="col-md-6">
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required class="subscribe">
</div>
<div class="col-md-2">
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block">Subsbcribe</button>
</div>
</form>
</div>
And the controller is below
app.controller('RegisterController', function ($scope,dataFactory) {
$scope.users = dataFactory.getUsers();
$scope.register = function () {
var userEmail = $scope.userEmail;
dataFactory.insertUser(userEmail);
$scope.userEmail = null;
$scope.ThankYou = "Thank You!";
}
});
The problem is that no validation is taking place when I click the button. It is always routed to the controller although I do not supply a correct email. So every time I click the button I get the {{ThankYou}} variable displayed. Maybe I do not understand something.
AngularJS does not disable enable any functionality for form validations. What is does is, it makes the state of the form and its control in terms of validation available on the current scope. You are required to implement the behaviour yourself.
In your case if you need to check user email is valid your html input should have a name attribute like
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required class="subscribe" name='userEmail'>
Then on your controller you can check
$scope.registerForm.userEmail.$invalid property.
You can use the same property to disable the button on the form using ng-disabled
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block" ng-disabled='registerForm.userEmail.$invalid'>Subsbcribe</button>
Basically the registerForm object is a ngFormController and userEmail is ngModelController. Please read the developer guide for forms
You are missing some part to achieve what you want. Normally you will need to add some code to enable disable the submit button base on the state of the form i.e valid/invalid. In your case this can be done like that :
<button data-ng-click="register()" class="btn btn-primary pull-right btn-block" ng-disabled="registerForm.$invalid">Subsbcribe</button>
Notice the ng-disabled="registerForm.$invalid".
You can as well provided inline feedback to the user with something like :
<input type="email" placeholder="your#e-mail.com" data-ng-model="userEmail" required="" class="subscribe" name="userName"/>
<span ng-show="registerForm.userName.$error.required">Please enter a name</span>
Or with CSS like that :
input.ng-invalid-required {
background-color: #FA787E;
}
You have a working plunker here

Angular JS Forms submit not sending model data

In the following example, message is undefined when I display it in the controller after the event is fired. Why?
<form>
<input type="text" ng-model="message.Title" />
<textarea ng-model="message.Content"></textarea>
<input type="submit" value="Send Message" ng-click="sendMessage(message)" />
</form>
Controller:
$scope.sendMessage = function(message) {
console.log(message);
}
My code seems identical to the documentation here except my controller manages the entire "page" not just the form.
Wow nevermind, apparently when you submit with blank values it doesn't even create the object.
I see you've found your problem, but I'd like to propose a solution to prevent your problem anyway:
<form name="messageForm" ng-submit="sendMessage(message)">
<input type="text" ng-model="message.Title" required/>
<span ng-show="messageForm.title.$error.required && messageForm.title.$dirty">required</span><br/>
<textarea ng-model="message.Content"></textarea>
<input type="submit" value="Send Message" ng-disabled="messageForm.$invalid" />
</form>
The above will make the Title required, display an error message, and disable your submit button if the form isn't valid.

Resources