Angular JS Multiple Inputs in Form - ruby-on-rails

Would there be any reason that multiple inputs aren't being passed from an Angular form to the controller. Either one of the inputs will submit. The problem is both of them won't submit in the same form.
<form name="myForm" ng-controller="PostIndexCtrl" class="my-form">
<input type='text' ng-model="entry.question_id" name="question_id" value="1">
<input type='text' ng-model="entry.answer" name="answer"><br/>
<button class="btn btn-primary" ng-click="saveEntry()">Save</button>
</form>
Here is the controller
.controller("PostIndexCtrl", function($scope, Post, $resource, $http) {
Post.query(function(data) {
$scope.posts = data;
});
var data = $resource('/api/answers/', {answer: '#answer', question_id: '#question_id'});
$scope.saveEntry = function() {
data.save($scope.entry);
}
});

Related

_this.testFormEl.nativeElement.submit is not a function for Form Post

I have a hidden form in a dialog which I want to submit automatically.
HTML Code :
<form #formVal method="POST" [action]="urlvalue">
<p *ngFor="let item of redirectData.RedirectData.Form.Parameter;
let pindex = index;">
<input type="hidden" [name]="item.name" [value]="item.value">
</p>
</ form>
`
In my previous angular 1.5 code I was doing
$timeout(() => {
angular.element('#3DSForm').submit();
}, 100);
and it was working but here in Angular 6 I tried using ViewChild in ngAfteronInit but still no luck I am getting error for native element, I even used ngNoform in my HTML but didn't work out.
#ViewChild('formVal') form: ElementRef;
setTimeout(() => {
this.form.nativeElement.submit();
}, 200);
Kindly suggest what am I missing
You probably have some element called submit.
Example:
<input type="hidden" name="submit">
Rename it to something else, e.g btnSubmit.
You should call click event for submit button like this,
<form #formVal method="POST" [action]="urlvalue">
<div *ngFor="let item of redirectData.RedirectData.Form.Parameter; let pindex = index;">
<input type="hidden" [name]="item.name" [value]="item.value">
</div>
<input type="hidden" name="submit" #submitBtn>
</ form>
in ts file
#ViewChild('submitBtn') submitBtn: ElementRef;
submitForm() {
this.submitBtn.nativeElement.click();
}
after that call the submitForm() function from where you want to submit the function.
I was able to achieve it using HTMLFormElement.
<form ngNoForm name="myForm" id="myForm" [action]="urlvalue" method="POST">
<button type="submit" class="test" style="visibility: hidden;"></button>
</form>
This code in the component.
const form: HTMLFormElement = document.getElementById('myForm');
form.submit();

How to prevent redirect to new page on form submit

I am trying to upload a form containing multiple files to my server, request is going to correct Action and I am also getting some data but all the files are coming with null values.
var file = function(){
this.submitForm = function () {
$("#addBrtForm").ajaxSubmit(function (response) {
if (response === "Barter Uploaded Successfully") {
alert(response);
$.mobile.changePage("#p-afterUpload");
t.somefunction();
} else {
alert("Try Again!! Barter Not Uploaded");
}
});
};
};
hm.files = new file();
//other thing that I tried
$(function(){
$('#addBrtForm').ajaxForm({
type: 'POST',
beforeSubmit: function () {
return false;
},
success: function (response) {
return false;
if (response === "Barter Uploaded Successfully") {
alert(response);
$.mobile.changePage("#p-barter");
t.setBarterpageTitle('My Barter');
} else {
alert("Try Again!! Barter Not Uploaded");
}
}
});
});
<form method="post" action="http://localhost:xxxx/Mobile/Home/FileUpload" enctype="multipart/form-data" data-ajax="false" id="addBrtForm" name="addBrtForm" >
<input type="text" name="Title" data-role="none" />
<input type="text" name="Description" data-role="none" />
<input type="file" name="files" data-role="none" multiple />
<input type="file" name="files" data-role="none" multiple />
<input type="file" name="files" data-role="none" multiple />
<input type="file" name="files" data-role="none" multiple />
<input type="file" name="files" data-role="none" multiple />
<input type="Submit" name="" value="submit" data-role="none" multiple />
<input type="Button" name="" value="submit" data-role="none" multiple onclick="hm.files.submitForm()"/>
</form>
It is working perfectly without "ajaxSubmit" but page is redirecting to "http://localhost:xxxx/Mobile/Home/FileUpload", I don't want that page to come up, I just wanted to catch my response and do something based on that
My controller
public ActionResult FileUpload(FormCollection fc, List<HttpPostedFileBase> files)
{
//some functionilty to save data working perfectely
return Json(SuccesMessage, JsonRequestBehavior.AllowGet);
}
*Note - as I am using jquery mobile so there is no views in my project
thanks to accepted answer on this post and Stephen Muecke for suggesting me to look on that question.
what I did-
removed action attribute from my form tag
used on click instead of submit
used ajax to post data as given in the reference link.
My edited js is shown below
var formdata = new FormData($('#addBrtForm').get(0));
$.ajax({
url: "http://localhost:xxxx/Mobile/Home/FileUpload",
type: 'POST',
data: formdata,
processData: false,
contentType: false,
dataType: "json",
success: function (response) {
if (response === "File Uploaded Successfully") {
alert(response);
$.mobile.changePage("#p-afterUpload");
t.someFunction();
} else {
alert("Try Again!! File Not Uploaded");
}
},
error: function (e) {
alert("Network error has occurred please try again!");
}
});
changed controller action to this -
public ActionResult FileUpload(UploadModel fm, List<HttpPostedFileBase> files)
{
//some functionilty to save data working perfectely
return Json(SuccesMessage, JsonRequestBehavior.AllowGet);
}
- UploadModel is my model having same Name as I used in my form
Add id to the submit button.
<input type="Button" name="" id="submit" value="submit" data-role="none" multiple/>
Then in the javascript do like this
$(function(){
$('#submit').click(function(e){
Do Your stuf here
e.preventDefault();
});
}

Knockout + Blueimp Fie upload

I'm trying to marry my knockout VM into Blueimp File Upload using ASP.NET MVC.
What i'm trying to achieve is:
bind form data with KO view model
upload a file along with the form data, on button click
in teh action, receive the form data as parameters, and access the file data in any possible way
It would also be desirable to upload multiple files
The sequence is as follows:
This is why I have so far:
HTML
<form action="/Test/Post" method="post" enctype="multipart/form-data">
<div>
<label for="Id" >Id</label>
<input data-bind="value: Id" class="text-box single-line"
data-val="true" data-val-number="The field Id must be a number."
data-val-required="The Id field is required." id="Id"
name="Id" type="number" value="" />
</div>
<div>
<label for="ImageUpload">Image Upload</label>
<input id="ImageUpload" name="ImageUpload" type="file" value="" />
</div>
</form>
<button type="submit" data-bind="click: upload">Create</button>
<script>
$(document).ready(function() {
ko.applyBindings(new myVm({Id: 0, Something: 0}));
});
</script>
FileUpload Init
$('input:file').fileupload({
dataType: 'json',
autoUpload: false, // do not auto upload on file select
});
KO Script
function myVm(data) {
var self = this;
// Write mapping config
var mappingConfig = {};
// Perform mapping
ko.mapping.fromJS(data, mappingConfig, self);
// Upload
self.upload = function () {
$('#ImageUpload').bind('fileuploadsubmit', function (e, data) {
// Bind JS form
data.formData = ko.mapping.toJS(self);
});
// this doesn't trigger the binding to fileuploadsubmit
$('form').submit();
};
};

How to get text box value in ember.js

i have started to work on ember.js just day before.
i don't know how to get text box value while submitting. i have tried like this
this is html
<script type="text/x-handlebars" data-template-name="index">
<div >
<p>{{view Ember.TextField valueBinding="fname"}}</p>
</div>
<div>
<p>{{view Ember.TextField valueBinding="lname"}}</p>
</div>
<button {{action save}}>submit</button>
</script>
this is my ember.js file
App = Ember.Application.create();
App.IndexController = Ember.ObjectController.extend({
save:function()
{
var fname=this.get('fname');
var lname=this.get('lname');
alert(fname+','+lname);
}
});
whenever i am clicking on submit button, i am getting undefined in alert.so how to get value? i hope anyone will help me for to continue in ember.js
in js like this
App.WebFormController = Ember.Controller.extend({
fname: null,
lname: null,
save: function () {
var fname = this.get('fname');
var lname = this.get('lname');
alert(fname + ',' + lname);
}
});
without need a model
in template like this
<script type="text/x-handlebars" data-template-name="web_form">
<form {{action save on="submit"}}>
<div >
<p>{{input type="text" valueBinding="fname"}}</p>
</div>
<div>
<p>{{input type="text" valueBinding="lname"}}</p>
</div>
<button>submit</button>
</form>
</script>
Your problem is that your form doesn't have a model. You can provide it using model or setupController hook.
App.IndexRoute = Ember.Route.extend({
model: function() {
return {};
},
// or
setupController: function(controller) {
controller.set('model', {});
}
});
In addition some tips:
Use the action name on="submit" in the form, instead of action name in submit button. So you can execute the action when the user press enter key, in input.
And the input type="text" helper is a shortcut for view Ember.TextField
<script type="text/x-handlebars" data-template-name="index">
<form {{action save on="submit"}}>
<div >
<p>{{input type="text" valueBinding="fname"}}</p>
</div>
<div>
<p>{{input type="text" valueBinding="lname"}}</p>
</div>
<button>submit</button>
<form>
</script>
Here a live demo
That is really nice tutorial by mavilein.
We can do it at controller level also.
App.IndexController = Ember.ObjectController.extend({
content:function(){
return {fname:null,lname:null}
}.property(),
save:function()
{
var fname=this.get('fname');
var lname=this.get('lname');
alert(fname+','+lname);
}
});
Or we can do it
App.IndexController = Ember.ObjectController.extend({
fname:null,
lname:null,
save:function()
{
var fname=this.get('fname');
var lname=this.get('lname');
alert(fname+','+lname);
}
});
Below code is working for me:
cshtml: In script on tag specify data-template-name="text"
<script type="text/x-handlebars" data-template-name="text">
{{view Ember.TextField value=view.message}}
{{view Ember.TextField value=view.specy}}
{{textarea value=view.desc id="catdesc" valueBinding="categor" cols="20" rows="6"}}
<button type="submit" {{action "submit" target=view}}>Done</button>
</script>
app.js:
App.TextView = Ember.View.extend({
templateName: 'text',
message:'',
specy: '',
desc:'',
actions: {
submit: function (event) {
var value = this.get('specy');
var spc = this.get('message');
var de = this.get('desc');
}
}
});

jQuery Mobile and Knockout.js templating, styling isnt applied

Ok so this is beginning to drive me insane. I have for several hours now searched and searched, and every single solution doesnt work for me. So yes, this question might be redundant, but i cant for the life of me get solutions to work.
I have a bunch of checkboxes being generated by a jquery template that is databound via knockout.js. However, it turns up unstyled. Afaik, it is something about jquery mobile does the styling before knockout renderes the template, so it ends up unstyled.
I have tried numerous methods to no avail, so i hope someone here can see what i am doing wrong.
(i am using jquery mobile 1.2.0 , jquery 1.8.2 and knockout 2.2.1)
This is the scripts:
<script type="text/javascript">
jQuery.support.cors = true;
var dataFromServer = "";
// create ViewModel with Geography, name, email, frequency and jobtype
var ViewModel = {
email: ko.observable(""),
geographyList: ["Hovedstaden","Sjælland","Fyn + øer","Nordjylland","Midtjylland","Sønderjylland" ],
selectedGeographies: ko.observableArray(dataFromServer.split(",")),
frequencySelection: ko.observable("frequency"),
jobTypes: ["Kontor (administration, sekretær og reception)","Jura","HR, Ledelse, strategi og udvikling","Marketing, kommunikation og PR","Handel og service (butik, service, værtinde og piccoline)","IT","Grafik og design","Lager, chauffør, bud mv.","Økonomi, regnskab og finans","Kundeservice, telefoninterview, salg og telemarketing","Sprog","Øvrige jobtyper"],
selectedJobTypes: ko.observableArray(dataFromServer.split(",")),
workTimes: ["Fulltid","Deltid"],
selectedWorkTimes: ko.observableArray(dataFromServer.split(","))
};
// function for returning checkbox selection as comma separated list
ViewModel.selectedJobTypesDelimited = ko.dependentObservable(function () {
return this.selectedJobTypes().join(",");
}, ViewModel);
var API_URL = "/webapi/api/Subscriptions/";
// function used for parsing json message before sent
function omitKeys(obj, keys) {
var dup = {};
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (keys.indexOf(key) === -1) {
dup[key] = obj[key];
}
}
}
return dup;
}
//Function called for inserting new subscription record
function subscribe() {
if($("#jobmailForm").valid()=== true){
//window.alert("add subscriptiooncalled");
var mySubscription = ko.toJS(ViewModel);
//var json = JSON.stringify(mySubscription);
var jsonSmall = JSON.stringify(omitKeys(mySubscription, ['geographyList','jobTypes','selectedJobTypesDelimited','workTimes']));
//window.alert(jsonSmall);
$.ajax({
url: API_URL,
cache: false,
type: 'POST',
contentType: 'application/json',
data: jsonSmall,
success: function (data) {
window.alert("success");
},
error: function (error) {
window.alert("ERROR STATUS: " + error.status + " STATUS TEXT: " + error.statusText);
}
});
}
}
function initializeViewModel() {
// Get the post from the API
var self = this; //Declare observable which will be bind with UI
// Activates knockout.js
ko.applyBindings(ViewModel);
}
// Handle the DOM Ready (Finished Rendering the DOM)
$("#jobmail").live("pageinit", function() {
initializeViewModel();
$('#jobmailDiv').trigger('updatelayout');
});
</script>
<script id="geographyTmpl" type="text/html">
<input type="checkbox" data-role="none" data-bind="attr: { value: $data }, attr: { id: $data }, checked: $root.selectedGeographies" />
<label data-bind="attr: { for: $data }"><span data-bind="text: $data"></span></label>
</script>
<script id="jobTypeTmpl" type="text/html">
<label><input type="checkbox" data-role="none" data-bind="attr: { value: $data }, checked: $root.selectedJobTypes" /><span data-bind="text: $data"></span></label>
</script>
Note, "jobmail" is the surrounding "page" div element, not shown here. And this is the markup:
<div data-role="content">
<umbraco:Item field="bodyText" runat="server"></umbraco:Item>
<form id="jobmailForm" runat="server" data-ajax="false">
<div id="jobmailDiv">
<p>
<label for="email">Email</label>
<input type="text" name="email" id="email" class="required email" data-bind="'value': email" />
</p>
<fieldset data-role="controlgroup" data-mini="true" data-bind="template: { name: 'geographyTmpl', foreach: geographyList, templateOptions: { selections: selectedGeographies } }">
<input type="checkbox" id="lol" />
<label for="lol">fkfkufk</label>
</fieldset>
<fieldset data-role="controlgroup" data-mini="true">
<p data-bind="template: { name: 'jobTypeTmpl', foreach: jobTypes, templateOptions: { selections: selectedJobTypes } }"></p>
</fieldset>
<fieldset data-role="controlgroup" data-mini="true">
<input type="radio" id="frequency5" name="frequency" value="5" data-bind="checked: frequencySelection" /><label for="frequency5">Højst 5 gange om ugen</label>
<input type="radio" id="frequency3" name="frequency" value="3" data-bind="checked: frequencySelection" /><label for="frequency3">Højst 3 gange om ugen</label>
<input type="radio" id="frequency1" name="frequency" value="1" data-bind="checked: frequencySelection" /><label for="frequency1">Højst 1 gang om ugen</label>
</fieldset>
<p>
<input type="button" value="Tilmeld" class="nice small radius action button" onClick="subscribe();">
</p>
Tilbage
</div>
</form>
Alternate method of invoking the restyling (doesnt work either):
$(document).on('pagebeforeshow', '#jobmail', function(){
// Get the post from the API
var self = this; //Declare observable which will be bind with UI
// Activates knockout.js
ko.applyBindings(ViewModel);
});
// Handle the DOM Ready (Finished Rendering the DOM)
$("#jobmail").live("pageinit", function() {
$('#jobmail').trigger('pagecreate');
});
Use a custom binding (Knockout) to trigger jQuery Mobile to enhance the dynamically created content produced by Knockout.
Here is a simple custom binding:
ko.bindingHandlers.jqmEnhance = {
update: function (element, valueAccessor) {
// Get jQuery Mobile to enhance elements within this element
$(element).trigger("create");
}
};
Use the custom binding in your HTML like this, where myValue is the part of your view model that changes, triggering the dynamic content to be inserted into the DOM:
<div data-bind="jqmEnhance: myValue">
<span data-bind="text: someProperty"></span>
My Button
<input type="radio" id="my-id" name="my-name" value="1" data-bind="checked: someOtherProperty" /><label for="my-id">My Label</label>
</div>
In my own case, myValue was part of an expression in an if binding, which would trigger content to be added to the DOM.
<!-- ko if: myValue -->
<span data-bind="jqmEnhance: myValue">
<!-- My content with data-bind attributes -->
</span>
<!-- /ko -->
Every dynamically generated jQuery Mobile content must be manually enhanced.
It can be done in few ways, but most common one can be done through the jQuery Mobile function .trigger( .
Example:
Enhance only page content
$('#page-id').trigger('create');
Enhance full page (header + content + footer):
$('#page-id').trigger('pagecreate');
If you want to find more about this topic take a look my other ARTICLE, to be more transparent it is my personal blog. Or find it HERE.

Resources