Validation of dynamic created form (AngularJS) - validation

I try to made nested form with validation. All works fine, but when I remove one of nested form, validation continue to use removed form. I made jsfiddle example http://jsfiddle.net/sokolov_stas/VAyXu/
When example runs, form are valid. If click "+" button, nested form will be added and valid will be false. Then click "-" button, and valid will be false all the same.
The question is: How to remove dynamic created form from validation processing.

Well, for one thing, a <form> inside of a <form> is not valid HTML.
Second, you're not supposed to be doing DOM manipulation from inside the controller. The controller is for "business" logic. See the section on controllers here
For what you're doing, you'd probably be better off using one form, with an ng-repeat inside of it, and adding additional elements to an array:
<form name="myForm" ng-controller="FormCtrl" ng-submit="doSomething()">
<div ng-repeat="item in items">
<input ng-model="item" type="text" required/>
</div>
<a ng-click="addItem()">+</a>
<a ng-click="removeItem()">-</a>
<button type="submit">Submit</button>
<div>Form valid: {{myForm.$valid}}</div>
</form>
and the controller:
function FormCtrl($scope) {
$scope.items = [];
$scope.addItem = function() {
$scope.items.push(null);
};
$scope.removeItem = function() {
$scope.items.pop();
};
$scope.doSomething = function () {
//your submission stuff goes here.
};
}

Related

Laravel: Two form with one submit button

I want to submit two form into two url and want to submit from two another functions of a Controller.
<form method="post" url="{ '/url1' }">
</form>
<form method="post" url="{ '/url2' }">
</form>
<button type="submit">Submit</button>
Is it possible to do without AJAX??
Simple answer : no, without ajax you can't send two requests.
Complicated answer: unless the first one carries the data for both then in the first response, it sends the second request with the data for it. Which is so complicating things, you should just do it in one request.
You can use jQuery to submit both forms like in the example below:
First of all, add an id to your button like this
<button type="submit" id="submitBtn">Submit</button>
Add ID to your forms:
form method="post" id="form1" url="{ '/url1' }">
form method="post" id="form2" url="{ '/url2' }">
I don't know what is wrong with the stakoverflow editor, that is why i deleted the "<" sign.
3. Now handle the jQuery click event:
$(document).ready(function(){
$('#submitBtn').on('click',function(){
$('#form1').submit();
$('#form2').submit();
});
});
You could give the forms different ids but same action.
Then in the controller called by the submit button, let IF statements check for the form ids and return the respective view desired eg
$requests = $request->all();
$form_Id = $requests['form1_Id'];
if($form_Id != 'id_of_first_form') {
return view('url2');
}else{
return view('url1');
}
If you have a main page form and a modal form and you wanna submit both in order, you can do it with javascript like this
// cause double submits at once
function doubleSubmit()
{
$.post($('#recordPaymentForm').attr("action"), $('#recordPaymentForm').serialize(), function(response) {
$('#submitEditOrderButton').trigger('click');
});
return false;
}
Leave your main page form as it is and change your modal form on submit attribute like this
<form id="recordPaymentForm" method="POST" action="/orders/{{$order->id}}/payments" onsubmit="return doubleSubmit(event)">
Please not that we first submit modal form and then we trigger on click event of submit button (submitEditOrderButton) on the main page. In this example, we first submit payment form and then we trigger click event of main page form which cause a form submit on the main page.

If search don't return values from database show an empty form

So i got a page that have a search form, and when the user search for a value if there are no records on database the form returns empty, but if there are records the form is populated with data.
What i was thinking was this
var db = Database.Open("myDataBase");
var selectCommand = "SELECT * FROM exportClient";
var searchTerm = "";
if(!Request.QueryString["searchField"].IsEmpty() ) {
selectCommand = "SELECT * FROM exportClient WHERE clientAccount = #0";
searchTerm = Request.QueryString["searchField"];
}
if(IsPost){
var selectedData = db.Query(selectCommand, searchTerm);
}
And Then:
<body>
<div class="col_12">
<form method="get">
<label>search</label><input type="text" class="col_3" name="searchField" />
<button type="submit" class="button red" value="search">search</button>
</form>
</div>
#if(!Request.QueryString["searchField"].IsEmpty() ){
foreach(var row in db.Query(selectCommand, searchTerm)) {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM POPULATED
</form>
</div>
}
} else {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM NOT POPULATED
</form>
</div>
}
</body>
But what is happening is that the form that is not populated is always showing up when i enter the page, and i need that the only thing that user see when enter the page is the input field to do the search.
What am i doing wrong ?
I'm not sure of having understood your goal, but in my opinion your main problem is to detect if either exists or not a query string.
I think that your code should be like this
#if(Request.QueryString.HasKeys())
{
if(!Request.QueryString["searchField"].IsEmpty() ){
<p>searchField has value</p>
} else {
<p>searchField hasn't value</p>
}
}
There are a number of potential issues I can see with your code, hopefully you can put these together to achieve what you wanted:
As Selva points out, you are missing the action attribute on your forms.
The selectedData variable you create inside your IsPost() block goes out of scope before you do anything with it. Perhaps you didn't include all your code though, so ignore this if it just isn't relevant to the question.
To answer the main question: if you don't want the empty form to appear when the user hasn't yet performed a search, surely you just need to completely remove the else block - including the empty form - from your HTML?
Hope that helps.

Multiple views for one model in AngularJS

I'm learning AngularJS framework and my background is BackboneJS and it seems I can not figure
out conventional way to do next thing:
I have a readonly list of elements each of which has 'edit' button that switches this
particular element to an edit mode. In edit mode I need to render input elements instead
of spans, p's etc.
The way to do this in Backbone.js is simply create EditView and pass model to it, but I don't have any idea how this works in Angular.
I pass data to the scope and render the readonly list and when user clicks on 'edit' button
in the element how should I change view for the element?
Thanks!
Angular makes this task simpler than Backbone by using a model for editing, then you update the original list and clear the edit model.
The view:
<div ng-app='App'>
<div ng-controller='mainCtrl'>
<div ng-controller='childCtrl'>
<strong>Controller</strong>
<ul>
<li ng-repeat='item in list'>{{item.name}} <button ng-click='edit($index)'>+</button></li>
</ul>
<div ng-show='editModel.name'>
Name: <input type="text" ng-model='editModel.name'/> <button ng-click='save()'>Save</button><button ng-click='cancelEdit()'>Cancel</button>
</div>
</div>
</div>
The angular app:
angular.module('App', [])
.controller('mainCtrl', ['$scope', function($scope){
$scope.list = [ {name:'item 1'}, {name:'item 2'}, {name:'item 3'} ];
}])
.controller('childCtrl', ['$scope', function($scope){
$scope.editModel = {};
$scope.edit = function(index){
$scope.editModel.index = index;
$scope.editModel.name = $scope.list[index].name;
};
$scope.cancelEdit = function(){
$scope.editModel = {};
};
$scope.save = function(){
if($scope.editModel.hasOwnProperty('index')){
$scope.list[$scope.editModel.index] = $scope.editModel;
}
else if($scope.editModel.name && $scope.editModel.name.length){
$scope.list.push($scope.editModel);
}
$scope.cancelEdit();
};
}]);
JsFiddle: http://jsfiddle.net/guilhermenagatomo/Bp6bY/
I'm using the controller nesting so the list can be used by other controllers you have in the app, or maybe you can create a controller just to take care of the editing.

How to rerender part of page after ajax submit of form in Lift (Scala)

this is probably a stupid question but I cannot figure out how to do it.
So I'm new to Scala/Lift and I read the ajax form chapter in http://simply.liftweb.net/index-4.8.html#toc-Section-4.8 but the "RedirectTo" in the example does not seem to be very "ajaxian" to me. Often in case of submitting a form via ajax, you would just partially rerender the same page, right?
So that's what I'm trying to do and am completely failing right now.
How do I let Lift rerender just a part of the same page after I submit the form via ajax?
Any hints would be appreciated. Thanks.
Basically, what I have looks like this:
<div id="main" class="lift:surround?with=default;at=content">
<h2>Welcome to your project!</h2>
<div class="lift:Test">
<div>
<form class="lift:form.ajax">
<fieldset>
<label for="name">Name:</label>
<input id="name" name="name" type=text>
<p></p>
<input id="save" type="submit" value="Save">
</fieldset>
</form>
</div>
<div>
<span id="theName">Name</span>
</div>
</div>
</div>
class Test {
def render = {
var name = ""
def process(): JsCmd = {
Thread.sleep(500)
S.notice("Entered name is: %s".format(name))
Noop
}
"#theName " #> "This shall be updated with the name given in the form above" &
"#name" #> (SHtml.text(name, name = _) ++ SHtml.hidden(process))
}
}
How would I update "theName" when submitting the form?
Have a look at http://lift.la/shtmlidmemoize-simple-ajax-updating (Example Code). There is SHtml.memoize and SHtml.idMemoize which automatically caches the HTML code. Not sure why it is not used in this example in the Simply Lift book.
You have a 2 step form right? The above poster is correct.
Save your transformation in a RequestVar.
in your above example, the method you want to save is render, so 1st memoize the transform:
private def renderTest= SHtml.memoize { render }
Then, you can save this memoized transformation in a RequestVar (lasts for 1 request), or maybe a TransientRequestVar depending on your needs.
private object testTemplate extends RequestVar(renderTest)
When you want to replay the transform, from an ajax event - testTemplate.is.applyAgain.
I might have misunderstood the original question, b/c if you want to do a 2 step form, you don't really need the memoize. The memoize is if something changes on your current form, and you want to update it via an ajax event, i.e. on click or on change, b/c normally the form wouldn't update unless you did an ajax submit.

MVC 3: Why is jquery form.serialize not picking up all the controls in my form?

I am trying to create a situation where if a user clicks on an "edit" button in a list of text items, she can edit that item. I am trying to make the "edit" button post back using ajax.
Here's my ajax code:
$(function () {
// post back edit request
$('input[name^="editItem"]').live("click", (function () {
var id = $(this).attr('id');
var sections = id.split('_');
if (sections.length == 2) {
var itemID = sections[1];
var divID = "message_" + itemID;
var form = $("#newsForm");
$.post(
form.attr("action"),
form.serialize(),
function (data) {
$("#" + divID).html(data);
}
);
}
return false;
}));
});
But the form.serialize() command is not picking up all the form controls in the form. It's ONLY picking up a hidden form field that appears for each item in the list.
Here's the code in the view, inside a loop that displays all the items:
**** this is the only control being picked up: ******
#Html.Hidden(indexItemID, j.ToString())
****
<div class="datetext" style="float: right; margin-bottom: 5px;">
#Model.newsItems[j].datePosted.Value.ToLongDateString()
</div>
#if (Model.newsItems[j].showEdit)
{
// *********** show the editor ************
<div id="#divID">
#Html.EditorFor(model => model.newsItems[j])
</div>
}
else
{
// *********** show the normal display, plus the following edit/delete buttons ***********
if (Model.newsItems[j].canEdit)
{
string editID = "editItem_" + Model.newsItems[j].itemID.ToString();
string deleteID = "deleteItem_" + Model.newsItems[j].itemID.ToString();
<div class="buttonblock">
<div style="float: right">
<input id="#editID" name="#editID" type="submit" class="smallsubmittext cancel" title="edit this item" value="Edit" />
</div>
<div style="float: right">
<input id="#deleteID" name="#deleteID" type="submit" class="smallsubmittext cancel" title="delete this item" value="Delete" />
</div>
</div>
<div class="clear"></div>
}
It's not picking up anything but the series of hidden form fields (indexItemID). Why would it not be picking up the button controls?
(The ID's of the edit button controls, by the way, are in the form "editItem_x" where x is the ID of the item. Thus the button controls are central to the whole process -- that's how I figure out which item the user wants to edit.)
UPDATE
The answer seems to be in the jquery API itself, http://api.jquery.com/serialize/:
"No submit button value is serialized since the form was not submitted using a button."
I don't know how my action is supposed to know which button was clicked, so I am manually adding the button to the serialized string, and it does seem to work, as inelegant as it seems.
UPDATE 2
I spoke too soon -- the ajax is not working to update my partial view. It's giving me an exception because one of the sections in my layout page is undefined. I give up -- I can't waste any more time on this. No Ajax for this project.
You could try:
var form = $('#newsForm *'); // note the '*'
Update
Did you change the argument to $.post() as well? I think I may have been a little too simple in my answer. Just change the second argument within $.post() while continuing to use form.attr('action')
New post should look like this:
$.post(
form.attr("action"),
$('#newsForm *').serialize(), // this line changed
function (data) {
$("#" + divID).html(data);
}
);

Resources