I have an action which is showing a form for some user input. The inputs are plain text field. I wonder how can I pre fill the input field.
All the tutorials and blog posts I found are quite old and all of them are taking into account only one field. It is my understanding that I need a custom .ftl with a call to a web script in it.
<field id="myprop">
<control template="/org/alfresco/components/form/controls/mycustomfield.ftl"/>
</field>
The problem in my case is that I will end up doing at least six call to the same web script. Because that's the number of fields I currently have in my form.
Well I guess it could be implemented by using a form filter as well. Maybe not the nicest solution, but it should get the job done. https://wiki.alfresco.com/wiki/Forms_Developer_Guide#Form_Filter
There is only one better way... You don't need to use Share Form Engine. Take a look at "create site" dialog, this form doesn't use share form engine
You need to create custom share component that will return form with filled parameters and initialize this form in your front-end js that is executed while clicking on the action.
You can add new component to Share by the following way:
1) Create new descriptor my-form.get.desc.xml in web-extension/site-webscripts/com/pizdez/form
<webscript>
<shortname>my-form</shortname>
<description>Get HTML form</description>
<url>/pizdec/components/form</url>
</webscript>
2) Create new controller my-form.get.js in the same folder where you can call alfresco to get all needed information
var connector = remote.connect("alfresco");
var response = connector.get("/my/alfresco/webscript");
if (response.status == 200)
{
// Create javascript objects from the repo response
var obj = eval('(' + response + ')');
if (obj)
{
model.param1 = obj.param1;
}
}
3) Create ftl template my-form.get.html.ftl in the same folder
<#markup id="css" >
<#-- CSS Dependencies -->
<#link href="${url.context}/res/components/form/my.css" />
</#>
<#markup id="js">
<#script src="${url.context}/res/components/form/my.js" />
</#>
<#markup id="widgets">
<#createWidgets/>
</#>
<#markup id="html">
<#uniqueIdDiv>
<#assign el=args.htmlid?html>
<div id="${el}-dialog">
<div class="hd">TITLE</div>
<div class="bd">
<form id="${el}-form" method="POST" action="">
<div class="yui-gd">
<div class="yui-u first"><label for="${el}-title">Title:</label></div>
<div class="yui-u"><input id="${el}-title" type="text" name="title" tabindex="0" maxlength="255"/> *
</div>
</div>
<div class="yui-gd">
<div class="yui-u first"><label for="${el}-param1">Param1:</label></div>
<div class="yui-u"><input id="${el}-param1" type="text" name="title" tabindex="0" maxlength="255" value="${param1}"/> *
</div>
</div>
<div class="bdft">
<input type="submit" id="${el}-ok-button" value="${msg("button.ok")}" tabindex="0"/>
<input type="button" id="${el}-cancel-button" value="${msg("button.cancel")}" tabindex="0"/>
</div>
</form>
</div>
</div>
</#>
</#>
4) After that you need to get this component from ui js
var myForm = new Alfresco.module.SimpleDialog(this.id + "-dialog");
myForm.setOptions(
{
width: "50em",
templateUrl: Alfresco.constants.URL_SERVICECONTEXT + "/pizdec/components/form",
actionUrl: null,
destroyOnHide: true,
doBeforeDialogShow:
{
fn: doBeforeDialogShow,
scope: this
},
onSuccess:
{
fn: function (response)
{
},
scope: this
},
onFailure:
{
fn: function(response)
{
},
scope: this
}
}).show();
I just wanted to show you direction to research
Related
I'm trying to implement a reset password Page on my website using firebase auth. I got the send email to reset password page working. Now from what I understand you get an email with a link that you need to click and on this email there will be a code that is needed to reset the password. Now I'm at a loss on how to grab said code from the url and already display it for the user on the field. Is it possible to have the code come in the body of the email and have the user input the code? If not, how do I grab the code from the url and input it for the user so the user can only input the password? My website is using vue and this is what I have so far
<template>
<div class="container">
<h3>reset pw page</h3>
<div class="row">
<form #submit.prevent="ResetPw()" class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="password" id="password" v-model="password" />
<label>Password</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input type="text" id="code" v-model="code" />
<label>Code</label>
</div>
</div>
<button type="submit" class="btn">Submit</button>
</form>
</div>
</div>
</template>
<script>
import firebase from "firebase/app";
export default {
data() {
return {
password: "",
code: ""
};
},
methods: {
ResetPw() {
firebase
.auth()
.confirmPasswordReset(this.code, this.password)
.then(() => {
console.log(`Password Changed!`);
})
.catch(err => console.log(err));
}
}
};
</script>
I think I got everything done, I just need to understand how to grab the oobcode from the link https://my-project.firebaseapp.com/__/auth/action?mode=&oobCode=
If you are using react-router, it does not parse the query any more, but you can access it via location.search
const params = new URLSearchParams(this.props.location.search);
const code = params.get('oobCode')
const email = await firebase.auth().verifyPasswordResetCode(code)
Alternatively, instead of using this.props.location.search, you can do new URLSearchParams(window.location.pathname)
Not sure how to grab the oobCode from the body of the email but to grab the code from the URL once the page loads, you can refer to this question: how-can-i-get-query-string-values-in-javascript. In your form, create a hidden input for the code with an empty string value. Once window loads, code will be grabbed from URL and then you can pass the code and password into the function
<body>
<form>
<input type="text" id='newPass' name='newPass' placeholder='New password'>
<input type="hidden" id='code' name='code' value="">
<button type='submit'>Submit</button>
</form>
</body>
<script>
$(window).load(function () {
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
var code = getParameterByName('oobCode')
document.getElementById('code').value = code;
</script>
Hope this helps!
I'm trying to integrate Jquery File Upload plugin in my aspx page (asp.net website). I followed the guide, including all required scripts and stylesheets, but in the index.html it's used a form tag to initialize the plugin and with the tag are also specified action and method attributes. Since I'm using asp.net, I am not allowed to insert the form tag because asp.net wrap the whole website with another form tag and it doesn't allow to insert another form tag inside it.
How can I initialize the plugin in a different way?
You don't actually have to have a form to use jQuery file upload plugin. Because the plugin is using jQuery ajax under the hood. use the bellow code inside your page, keep in mind you have to code an API on the server side.
$(function () {
'use strict';
// Change this to the location of your server-side upload handler:
var url = 'your server api or handler';
$('#fileupload').fileupload({
url: url,
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo('#files');
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css(
'width',
progress + '%'
);
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});
and your html as follows:
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Select files...</span>
<!-- The file input field used as target for the file upload widget -->
<input id="fileupload" type="file" name="files[]" multiple>
</span>
<br>
<br>
<!-- The global progress bar -->
<div id="progress" class="progress">
<div class="progress-bar progress-bar-success"></div>
</div>
<!-- The container for the uploaded files -->
<div id="files" class="files"></div>
I am using a template based form in angular. I also use bootstrap (v4) and I wish to show some validation messages when the form was submitted.
This is my form:
<form [ngClass]="{'was-validated': wasValidated}">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" class="form-control" [(ngModel)]="category.name" #name="ngModel" required maxlength="100"/>
<div *ngIf="name.invalid" class="invalid-feedback">
<div *ngIf="name.errors.required">
Name is required.
</div>
</div>
</div>
<button type="submit" class="btn btn-success" (click)="save()">Save</button>
</form>
My component looks as follows:
category: Category;
wasValidated: boolean = false;
ngOnInit() {
this.reset();
}
save() {
this.wasValidated = true;
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
}
reset() {
this.wasValidated = false;
this.category = {} as Category;
}
This works, but I have a feeling it's overly complex and more like a workaround rather than the right way. What is the best way to accomplish this?
Note: the class was-validated must be present on the form element in order to show the div with class invalid-feedback. I'm using this: https://getbootstrap.com/docs/4.0/components/forms/#validation
Note 2: I have currently no mechanism yet to prevent form submission on error. I'd like to know a good solution for that as well!
With the answer from #Chellappan V I was able to construct the solution I wanted.
I have applied to following changes:
First added #form="ngForm" to the form tag in the template. Secondly I changed the ngClass expression to reference the submitted state of the form, rather than referring to a boolean which was set to true manually when form was submitted. Last but not least I pass the form in the submit method on the save button.
<form novalidate #form="ngForm" [ngClass]="{'was-validated': form.submitted}">
<!-- form controls -->
<button type="submit" class="btn btn-success" (click)="submit(form)">Save</button>
</form>
In the component I injected the template variable in the component with #ViewChild.
#ViewChild("form")
private form: NgForm;
The submit method now takes a form parameter of type NgForm which is used to check if the form was valid before sending a request to the backend:
submit(form: NgForm) {
if (form.valid) {
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
} else {
this.notificationService.add(notifications.validation_errors);
}
}
Finally the reset method resets the form and the model so it can be re-entered to submit a next instance:
reset() {
this.form.resetForm();
this.category = {} as NewCategoryDto;
}
The code below is trying to grab the username and password from input elements on a template.login and createUser when a button which is in template.footer is clicked.
Being new to javascript and Meteor, my code below probably butchered both.
I thought to make a method call from the footer click event, this call gets the username and password and fires Meteor accounts create and store the returned userId in a local session to be used later. blah..blah..
But how can I get access to input values in one template from another?
so I need your help. Thanks
Template.footer.events({
'click .myClass': function (event, template) {
Meteor.call('loginUser', username,password);
}
});
Meteor.methods({
//store the useId returned from createUser in a local session userId
loginUser: function (username, password) {
Accounts.createUser(username, password, function () {
Session.set(userId, this.value);
});
}
});
<template name="footer">
<footer>
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="container">
<div class="row">
{{#each footerButtons}}
<h2>
<button class="col-xs-{{footerButtonsScaling}} myClass" type="button">{{text.toUpperCase}}</button>
</h2>
{{/each}}
</div>
</div>
</nav>
</footer>
</template>
<template name="login">
<form action="">
<input type="text" name="username" placeholder="type your ID" value="{{username}}">
<input type="password" name="password" placeholder="type your PIN" value="{{password}}">
</form>
</template>
You can just use jQuery to access field values anywhere in the DOM:
var username = $('[name="username"]').val();
var password = $('[name="password"]').val();
I have this HTML code in my view
#using (Ajax.BeginForm("AddJoke", "Home", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "MyfriendsJokes" , InsertionMode= InsertionMode.InsertAfter}))
{
<div style="display:block">
<textarea placeholder="Post New Joke" id="newJoke" name="joke" rows="3" cols="50" style="float:left;position"></textarea>
<button type="submit" id="postnewjoke" style="float:left"> Post </button>
#Html.TextBoxFor(model => model.fileContent, new { type = "file", id = "fileuploaded", name = "fileuploaded" })
<div style="display:inline-block">
<input type="checkbox" name="geo" id="geo" style="width: 100%; float: left; display: block">
<input name="longitude" style="display:none"/>
<input name="latitude" style="display:none" />
<input name="user" style="display:none" value="#Model.user.Id"/>
<span>Include Location</span>
</div>
<span id="jokeError" style="color:red;font-size:14px;"></span>
</div>
}
<article id="MyfriendsJokes">
#Html.Partial("_NewJoke")
</article>
and this code in my controller
[HttpPost]
public PartialViewResult AddJoke(string joke, string user, HomePage page,HttpPostedFileBase fileuploaded, string longitude, string latitude)
{
Joke newJ = new Joke();
newJ.Key = Guid.NewGuid();
newJ.body = joke;
newJ.facebookID = user;
newJ.rank = 0;
newJ.time = DateTime.Now;
newJ.longitude = longitude;
newJ.latitude = latitude;
db.Jokes.Add(newJ);
HomePage page1 = new HomePage();
page1.user = Session["user"] as MyAppUser;
//db.SaveChanges();
return PartialView("_NewJoke", page1);
}
but instead of adding elements to the targeted div, it reload the page with a new whole page with just the elements of the partial view which is this
#using Jokes.Models
#using Microsoft.AspNet.Mvc.Facebook.Models
#model HomePage
<div style="display:block">
#Model.user.Name
</div>
can someone help and say what's wrong here to append elements to div instead of loading a new whole page?
Make sure that the jquery.unobtrusive-ajax.js script is referenced in your page. This is what AJAXifies all the output generated by the Ajax.* helpers. Without this script you only get a standard <form> element generated by the Ajax.BeginForm with a bunch of data-* attributes. The jquery.unobtrusive-ajax.js script analyzes those data-* attributes and subscribes to the submit event of the form, canceling the default action of making a full postback and sending an AJAX request to the server based on the data-* attributes.
It's important to mention that this script must be included AFTER jquery.js because it depends on it.
Also you seem to have some file input in your form and your controller action is taking an HttpPostedFileBase parameter. You should realize that you cannot upload files using an AJAX request and once you include this script your file uploads will simply stop working. In order to be able to upload files using AJAX you could either use some plugin such as jquery.form and Blueimp file upload or you could directly use the new XMLHttpRequest object that's built into modern browsers. The advantage of the plugins is that they do feature detection and will fallback to other techniques depending on the capabilities of the client browsers.