I have an Alpaca JS form comprised of an array of items which each consist of a textbox and a checkbox. For some reason, when I change the order using the dynamic controls, it successfully renumbers the textbox but doesn't change the number of the checkbox. This also results in a duplicate name assigned if the same top button to dynamically add new fields is pressed. The end result is incorrect data being passed when the form is submitted. How can I fix this to properly renumber the checkboxes?
Here's a sample of the Alpaca configuration:
$("#form1").alpaca({
"schema": {
"title": "Testing checkbox array IDs",
"description": "Testbox checkbox array test.",
"type": "object",
"properties": {
"form-fields": {
"title": "Fields",
"description": "These are the fields.",
"type": "array",
"items": {
"type": "object",
"properties": {
"field-name": {
"type": "string",
"title": "Field Name",
"description": "Enter the name for this field.",
"required": true
},
"field-box": {
"type": "boolean",
"title": "Field Box",
"description": "Check this box.",
"default": false
}
}
}
}
}
}
});
I couldn't find a way to correct the behavior itself but I was able to work around it by adding a postRender event to the Alpaca definition as follows:
"postRender": function(control) {
control.childrenByPropertyId["form-fields"].on("move", function() { $('input[type=checkbox]').each(function(index) { $(this).attr("name", $(this).closest("div:has(*[name])").first().attr("name")) }); });
control.childrenByPropertyId["form-fields"].on("add", function() { $('input[type=checkbox]').each(function(index) { $(this).attr("name", $(this).closest("div:has(*[name])").first().attr("name")) }); });
control.childrenByPropertyId["form-fields"].on("remove", function() { $('input[type=checkbox]').each(function(index) { $(this).attr("name", $(this).closest("div:has(*[name])").first().attr("name")) }); });
}
This is a bit of a hack but it works because the parent object does get assigned the correct name value and the form will post with those values if the name is just copied down into the input elements.
Related
Hi I'm using the Adaptive card SDK in a web page, using a Sample Card like this:
var card = {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Present a form and submit it back to the originator"
},
{
"type": "Input.Text",
"id": "firstName",
"placeholder": "What is your first name?"
},
{
"type": "Input.Text",
"id": "lastName",
"placeholder": "What is your last name?"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Action.Submit"
}
]};
and rendering using the usual rubric. I'd like to get the inputs back with the submit so I tried this
// Set the adaptive card's event handlers. onExecuteAction is invoked
// whenever an action is clicked in the card
adaptiveCard.onExecuteAction = function (action) { console.log(action.toJSON()) }
which just gives me:
Object title: "Action.Submit" type: "Action.Submit" __proto__: Object
How do I get the values of the input fields on the submit action?
TIA for any comments, advice and answers
You can use the data property of the action object just like this:
adaptiveCard.onExecuteAction = function (action) {
alert(`Hello ${action.data.firstName} ${action.data.lastName}`);
}
Here's a full jsfiddle.
There are many other interesting properties on the action object, but I haven't found good documentation.
However, the source code of the adaptive card visualizer contains some usage examples.
I have html that is dynamically generated from JSON and I would like to implement some validation logic.
To clarify, here is an example:
<div ng-switch on="field.type" ng-hide="{{ field.hide }}">
<div ng-switch-when="input" class= "col-md-6" ng-class="{'has-error': reqField(field.name, entity[field.name]) }">
<input
ng-model="entity[field.name]" id="{{field.name}}" class="form-control"
type="text" ng-style="setStyle(field.style)" ng-change="{{field.change}}" />
</div>
</div>
{
"title": "Json Title",
"id": "j_id",
"groupfields": [
{
"name": "jsonname",
"title": "JSON Title",
"type": "jsonselect",
"namevalue": "jsonvalue",
"combo": "jsondropdown",
"change" : "jsonChanged()"
},
{
"name": "jsonEmail",
"title": "JSON Email Address",
"type": "display"
},
{
"name": "jsonPhone",
"title": "JSON Phone Number",
"type": "display"
}
]
}, {
"title": "Json Title",
"id": "j_id",
"groupfields": [
{
"name": "jsonname",
"title": "JSON Title",
"type": "jsonselect",
"namevalue": "jsonvalue",
"combo": "jsondropdown",
"change" : "jsonChanged()"
},
{
"name": "jsonEmail",
"title": "JSON Email Address",
"type": "display"
},
{
"name": "jsonPhone",
"title": "JSON Phone Number",
"type": "display"
}
]
},
if (entityName) {
return false;
} else {
return true;
}
So for clarification, ex: 'field.type' in the ng-switch on is the "type" in the JSON - and we can determine which html div to display the content based on different JSON keys/values.
This implies that one html div could potentially be used to generate hundreds of input fields so this needs to be dynamic.
I would like to add validation for when a required field is empty. At the moment, I've tried adding the ng-class="{has-error': } which points to my function reqField. However, because this function is getting fired for EVERY field with "type": jsonselect, this function is checking whether or not the field is empty - which is really inefficient in terms of speed and usability (super laggy).
The javascript you see above is more or less the logic that the function reqField() does in order to check whether or not the field is empty (very inefficient since we're checking hundreds).
What I would like to use is something along the lines of ng-required={{field.required}} and make a new key/value in the JSON to determine whether or not I want this field to be a required field (sort like this):
{
"title": "Json Title",
"id": "j_id",
"groupfields": [
{
"name": "jsonname",
"title": "JSON Title",
"type": "jsonselect",
"namevalue": "jsonvalue",
"combo": "jsondropdown",
"change" : "jsonChanged()"
},
{
"name": "jsonEmail",
"title": "JSON Email Address",
"type": "display",
"required": true
},
{
"name": "jsonPhone",
"title": "JSON Phone Number",
"type": "display",
"required": true
}
]
},
~ and somehow pass that information to the ng-class="{has-error': } so that we can highlight - or do whatever we want once we know the field has been filled in/or is empty.
Form validation is built in to AngularJS. The ng-required directive will add error state to the form object, so that you can set up your ng-class like so:
<div ng-switch-when="input" class= "col-md-6" ng-class="{'has-error': myForm[field.name].$error.required }">
Your form and input must have name attributes for this to work:
<form name="myForm">
...
<input name="{{field.name}}" ng-required="field.required">
I'm working on creating my own schematics. This schematics will be responsible for creating a component (container) with some code. Template of this component will contain a few other components. One of this component will be banner component that will be optional. This banner will display text that will be translated into other languages, so I also should ask the user to provide (default) translation text if the banner will be included in the component.
Here is an example of this template:
name#dasherize.component.html.template:
<% if (includeBanner) { %>
<app-banner [title]="'<%= translationModuleKey %>.banner.title' | translate"
[description]="'<%= translationModuleKey %>.banner.description' | translate">
</app-banner>
<% } %>
<app-other-component>
</app-other-component>
Here is my schema.json:
{
"$schema": "http://json-schema.org/schema",
"id": "MySchematics",
"title": "My schematics",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the container",
"x-prompt": "Container name"
},
"includeBanner": {
"type": "boolean",
"description": "Include banner",
"default": "true",
"x-prompt": "Include banner"
},
"bannerTitle": {
"type": "string",
"description": "Banner title",
"x-prompt": "Banner title"
},
"bannerDescription": {
"type": "string",
"description": "Banner description",
"x-prompt": "Banner description"
},
"translationModuleKey": {
"type": "string",
"description": "Root key for translations"
}
},
"required": [
"name", "includeBanner", "bannerTitle", "bannerDescription"
]
}
My problem is that when user will set includeBanner to true, fields bannerTitle and bannerDescription should be required and there should be displayed prompt if those properties were not provided, but if includeBanner will be false, bannerTitle and bannerDescription shouldn't be required and there shouldn't be displayed prompt to fill these properties if those properties were not provided.
Any idea how to achieve that?
I was struggling with the same problem. What I've discovered - if you need conditional prompts, then you can't rely on declarative schema.json file (it doesn't support conditions).
Instead, you should use the askConfirmation function from #angular/cli/utilities/prompt.
So your example could look like this:
import { askConfirmation } from '#angular/cli/utilities/prompt';
export function yourSchematicsFn(options: Schema): Rule {
return async (tree: Tree, context: SchematicContext) => {
const includeBanner = await askConfirmation('Include Banner?', true);
if(includeBanner) {
// ask for bannerTitle and bannerDescription
}
else {
// do something else
}
return chain(/* chain your rules here */);
}
}
I've discovered this in Angular CLI ng-add schematics source code: askConfirmation.
Is there a way to replace the Star symbol with an asterisk on a 'required' field label on Alpaca?
Here is the schema:
var Schema = {
"title": "Lista controlli",
"type": "array",
"items": {
"type": "object",
"title": "Controllo Lavorazione",
"properties": {
...
"Nome": {
"title": "Nome",
"type": "string",
"required": true
}
}
}
}
Thanks in advance.
You can deal with that using css like this:
.alpaca-icon-required::before {
content: "*"
}
You could also change it's font-size because it will be kinda big.
Hope this works for you. I this isn't what you're looking for don't hesitate to comment.
In the latest version, 1.5.24, the star preceding the field label has been replaced with the text '(required)' following the field label.
I have a scenario where I want to fill some of the kendo grid columns by program. So I assume that I have to catch the row and fill data in the columns.
I am able to fetch the row ID based on some event(click for example). But I have no Idea how to update the value of a column bases on row id pragmatically.
http://jsfiddle.net/xojke83s/4/
above is the JS fiddle where I am able to get the row ID of a particular row. I want to know the way fill some data in any of the column by program. In the above example that column should be operationContext.
following is the code for same -
<div id="grid"></div>
$("#grid").kendoGrid({
"dataSource": {
"schema": {
"model": {
"id": "id",
"fields": {
"OperationContext": {
"type": "string",
"editable": "false"
}
}
}
}
},
"editable": "popup",
"toolbar": [
{
"name": "create",
"text": "Add a New Record"
}
],
"columns": [
{
"field": "Name",
"title": "Name"
},
{
"field": "Age",
"title": "Age"
},
{
"field": "OperationContext",
"title": "Operation Context"
},
{ command: ["edit", "destroy"], title: " ", width: "250px" }
]
});
$(".k-grid-add").on("click", function () {
var grid = $("#grid").data("kendoGrid").dataSource.data([{OperationContext: "IsAdded"}]);
});
//bind click event to the checkbox
var grid = $("#grid").data("kendoGrid");
grid.bind("edit", grid_edit);
function grid_edit(e){
console.log(e.model.uid);
}
Thanks in advance.
Answer made from comment as requested
I have updated your fiddle with this: updated js fiddle
I have modified the edit code to do this:
function grid_edit(e){
console.log(e.model);
if(!e.model.isNew() || e.model.id === 0){
e.model.set("OperationContext","I am being updated");
}
}
It will only add the inserting (defaultValue) and updating text in for new items or where an id is greater than 0.
I can see the logic for newly created items and maybe for edited items if the value is blank or if it is being used as a status tracker.
But if you delete an item then surely that is deleted from your datasource and you will no longer have access to that item so why store an update/indicate an update to a value when it is to be deleted.