angular ng-repeat on input from json - javascript

I am trying to pull all the forms for my page from a json object with values to plug into the ng-required, max-values min-values and type fields. But these values aren't being inserted into the dom. How would I go about repeating over a number of input elements and control whether or not they were text boxes or file uploads and whether or not they are required? I did up a fiddle based on what I was hoping to accomoplish but cant figure out why this doesn't work. see the jsfiddle.
HTML
<form novalidate name="form1" ng-controller="step1">
<div ng-repeat="field in json">
<label>
{{field.label}}
</label>
<input type="field.type" ng-model="field.model">
</div>
</form>
Javascript
function step1($scope) {
$scope.json = [
{
"error": "Must be more then 3 letters",
"label": "store Name 1",
"model": "storeName"
},
{
"error": "Must be more then 3 letters",
"label": "store Name 1",
"model": "storeName"
}
];
}

Setting input type dynamically is bit tricky, but may be achived with custom directive that appends input to the DOM. From the other hand, inserting inputs to the form dynamically from custom directive you can't enjoy things like myForm.myInput.$error.requred. Besides of it you probably want to add error message and some styling to invalid inputs, therefore you need some CSS.
Here is an example of dynamic form created from JSON with ng-required, ng-maxlength and ng-minlength enabled:
Plunker: http://plnkr.co/edit/F7BGq0sfSLvKE48eDTzQ?p=preview
HTML
<!DOCTYPE html>
<html ng-app="demo">
<head>
<script src="http://code.angularjs.org/1.2.10/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="demoController">
<form name="demoForm">
<div demo-directive ng-repeat="input in inputs"></div>
</form>
</body>
</html>
CSS
.error .required,
.error .minlength,
.error .maxlength {
display: none;
}
.ng-invalid-required + .error .required,
.ng-invalid-minlength + .error .minlength,
.ng-invalid-maxlength + .error .maxlength {
display: inline;
}
.ng-invalid {
outline: 1px solid red;
}
.error {
color: red;
}
JavaScript
angular.module('demo', []).
controller('demoController', function($scope) {
$scope.inputs = [{
inputType: 'checkbox',
name: 'f1',
checked: true,
label: 'input 1',
required: true
}, {
inputType: 'text',
name: 'f2',
value: 'some text 1',
label: 'input 2',
required: true
}, {
inputType: 'file',
name: 'f3',
label: 'input 3'
}, {
inputType: 'text',
name: 'f4',
value: 'some text 2',
label: 'input 2',
min: 2,
max: 15
}];
}).
directive('demoDirective', function($compile) {
return {
template: '<div><label>{{input.label}}: </label></div>',
replace: true,
link: function(scope, element) {
var el = angular.element('<span/>');
switch(scope.input.inputType) {
case 'checkbox':
el.append('<input type="checkbox" name="{{input.name}}" ng-model="input.checked" ng-required="{{input.required}}"/><span class="error"><span class="required">Required!</span></span>');
break;
case 'text':
el.append('<input type="text" name="{{input.name}}" ng-model="input.value" ng-required="{{input.required}}" ng-minlength="{{input.min}}" ng-maxlength="{{input.max}}" /><span class="error"><span class="required">Required!</span><span class="minlength">Minimum length is {{input.min}}!</span><span class="maxlength">Maximum length is {{input.max}}!</span></span>');
break;
case 'file':
el.append('<input type="file" name="{{input.name}}" ng-model="input.value" ng-required="{{input.required}}"/><span class="error"><span class="required">Required!</span></span>');
break;
}
$compile(el)(scope);
element.append(el);
}
}
});

Related

Select2 mimetype error

I am trying to use Select2 and Chrome is refusing to execute the script because the mimetype is text/html. I am using 4.0.3. Here is my html:
<link href="static/js/common/select2/css/select2.min.css" rel="stylesheet" />
<script src="static/js/common/select2/js/select2.js"></script>
<script src="static/js/controllers/common/SelectAgency.js"></script>
<select id="auto"></select>
The code for SelectAgency.js is this:
var data = [{ id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 2, text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' }];
$("#auto").select2({
placeholder:'Test'
})
The select box appears, but it does not contain anything. Also this message appears in the console
select2.min.js:233 Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:8080/foiaonline/action/public/request/static/js/common/select2/js/static/js/controllers/common/select2/css/select2.min.css".
I was using an older version of select2(3.5.1). In 3.5.1 select2 is initialized with:
$(panel).select2({
placeholder:placeholderStr,
data: items
});
<input id="panel" type="text", class="auto"/></td>

Remove selected option from select2 multiselect on change.

I have the following code. The aim is to style a select2 box with textbox as the searchbox. So I have implemented it as multiselect , but I only want one option to be selected.
One option is to restrict using maximumSelectionLength: 1. But in this case the limit message will be shown which i do not want to happen. (Even if i hide it some space will be taken up ).
Other option is to hide everything other than last-child , in that case multiple values will be send to backend when form is submitted.
So is there a way to remove the currently selected value when the new value is selected in multiselect ?
I'm using select2 version 3.5.2
$('#placeSelect').select2({
width: '100%',
allowClear: true,
multiple: true,
placeholder: "Click here and start typing to search.",
data: [
{ id: 1, text: "Honolulu" },
{ id: 2, text: "Tokyo" },
{ id: 3, text: "Delhi" },
{ id: 4, text: "Zurich" }
]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.jsdelivr.net/select2/3.4.8/select2.js"></script>
<link href="http://cdn.jsdelivr.net/select2/3.4.8/select2.css" rel="stylesheet"/>
<h3>Select a value</h3>
<input type="text" id="placeSelect"/>
You can only keep the last selected item and remove all other. Like this way :
$('#placeSelect').click(function () {
var t = $("#placeSelect").val().substr($("#placeSelect").val().length - 1);
$("#placeSelect").val(t).trigger("change");
});
$('#placeSelect').select2({
width: '100%',
allowClear: true,
multiple: true,
placeholder: "Click here and start typing to search.",
data: [
{ id: 1, text: "Honolulu" },
{ id: 2, text: "Tokyo" },
{ id: 3, text: "Delhi" },
{ id: 4, text: "Zurich" }
]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.jsdelivr.net/select2/3.4.8/select2.js"></script>
<link href="http://cdn.jsdelivr.net/select2/3.4.8/select2.css" rel="stylesheet"/>
<h3>Select a value</h3>
<input type="text" id="placeSelect"/>
$('#placeSelect').select2({
width: '100%',
allowClear: true,
multiple: false,
placeholder: "Click here and start typing to search.",
data: [
{ id: 1, text: "Honolulu" },
{ id: 2, text: "Tokyo" },
{ id: 3, text: "Delhi" },
{ id: 4, text: "Zurich" }
]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.jsdelivr.net/select2/3.4.8/select2.js"></script>
<link href="http://cdn.jsdelivr.net/select2/3.4.8/select2.css" rel="stylesheet"/>
<h3>Select a value</h3>
<input type="text" id="placeSelect"/>
You are using a multi option select, I suggest you to do the following:
multiple: false,
just add the following code in your query and it will work as you need it
$('ul.select2-choices').on("click", function() {
$("ul.select2-choices li .select2-search-choice-close").click();
});

Dojo - Input fields are not Appending to the grid

I Created a grid using dojo.I 'm having a form with input fields while i entered the values and click the "Add Row" button the input fields are not appending to the grid. Delete Option is working fine but add row is not working. I have attached the link of jsfiddle kindly refer for more.
form = new Form({
onSubmit: function(evt) {
evt.preventDefault();
var formValue = this.get("value");
dataStore.newItem(formValue);
}
}, "formContainer");
form.startup();
});
jsfiddle
Fully agree with #Himanshu.
You HTML is strange.
If you want to use a submit button, you must put it inside the <form> element.
Also, still like #Himanshu said, you must provide an id in order to user newItem
See the following working jsfiddle example:
https://jsfiddle.net/xzkc7hbs/8/
For better records, here is a working snippets.
(ignore the script error, those are security warnings, and run it in full page. Otherwise the script errors are over the textboxes)
require([
'dojo/_base/lang',
'dojox/grid/DataGrid',
'dojo/data/ItemFileWriteStore',
'dojo/dom',
'dijit/form/Button',
'dojo/dom-class',
"dojo/dom-construct",
"dojo/on",
"dijit/form/Form",
"dijit/form/TextBox",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dijit/registry",
'dojo/domReady!',
'dojox/grid/_CheckBoxSelector'
], function(lang, DataGrid, ItemFileWriteStore, dom, Button, domClass, domConstruct, on, Form, TextBox, Memory, ObjectStore, request, registry) {
var data = {
identifier: 'id',
items: []
};
var data_list = [{
fname: "Boy",
lname: "Mayer",
email: "boy#mayer.com",
num: 54526
}, {
fname: "Paul",
lname: "Taucker",
email: "paul#taucker.com",
num: 12345
}, {
fname: "Steven",
lname: "Spil",
email: "steven#spil.com",
num: 87654
}, {
fname: "computer",
lname: "Tech",
email: "comp#tech.com",
num: 45158
}, {
fname: "User",
lname: "Interface",
email: "user#inter.in",
num: 94979
}];
var rows = data_list.length;
for (i = 0, l = rows; i < rows; i++) {
data.items.push(lang.mixin({
id: i + 1
}, data_list[i % l]));
}
var dataStore = new dojo.data.ItemFileWriteStore({
data: data
});
var layout = [{
type: "dojox.grid._CheckBoxSelector",
width: '30px'
},
[{
'name': 'Sl',
'field': 'id',
'width': '20px',
'editable': 'false'
}, {
'name': 'Firstname',
'field': 'fname',
'width': '140px',
'editable': 'true'
}, {
'name': 'Lastname',
'field': 'lname',
'width': '130px',
'editable': 'true'
}, {
'name': 'Email',
'field': 'email',
'width': '140px',
'editable': 'true'
}, {
'name': 'Number',
'field': 'num',
'width': '80px',
'editable': 'true'
}]
];
var grid = new DataGrid({
store: dataStore,
query: {
id: "*"
},
queryOptions: {},
structure: layout
});
grid.placeAt("gridDiv");
grid.startup();
var button = new Button({
label: "Add Row",
}, "addRow");
button.startup();
var button = new Button({
label: "Delete",
}, "deleteBtn");
button.startup();
dojo.connect(deleteBtn, "onclick", function() {
var items = grid.selection.getSelected();
if (items.length) {
dojo.forEach(items, function(selectedItem) {
if (selectedItem !== null) {
dataStore.deleteItem(selectedItem);
}
});
}
});
var form = new Form({
onSubmit: function(evt) {
evt.preventDefault();
var formValue = form.get("value");
console.debug(formValue);
dataStore.fetch({
onComplete: function(allItems) {
var newId = allItems.length + 1;
dataStore.newItem({
id: newId,
fname: formValue.first,
lname: formValue.last,
email: formValue.dob,
num: formValue.mobile
});
}
})
}
}, "myForm");
form.startup();
});
*,
th {
font: 14px'verdana', sans-serif;
}
td {
font: 13px'verdana', sans-serif;
}
#gridDiv {
height: 14em;
margin-bottom: 15px;
width: 42em;
}
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="parseOnLoad:true"></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css">
<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css">
<div class="claro">
<div id="gridDiv"></div>
<button id="deleteBtn"></button>
<form id="myForm">
<div id="formContainer">
<input type="text" id="first" name="first" data-dojo-type="dijit/form/TextBox" value="" placeholder="Firstname" required/>
<input type="text" id="last" name="last" data-dojo-type="dijit/form/TextBox" value="" placeholder="Lastname" required />
<input type="text" id="email" name="dob" data-dojo-type="dijit/form/TextBox" value="" placeholder="Email" required />
<input type="text" id="mobile" name="mobile" data-dojo-type="dijit/form/TextBox" value="" placeholder="Mobile Number" required />
</div>
<button type="submit" value="submit" data-dojo-type="dijit/form/Button" id="submitForm">Add Row</button>
</form>
</div>
There are some problems with your HTML code. There is no need for the form element. You just need a div and place your dijit.form.Form in the div element. And, the submit button needs to be inside that div. It will automatically get triggered.
See the updated fiddle: JSFiddle
There is one more thing, to add data to the store, you have to provide an id to the newItem. Store will not accept an element without an id.

Set "val" not working(pre selecting)

I have looked at multiple questions on SO and on Git hub:
Set multiple Select2 options
Select2 can't set multiple value
Is initSelection used for select2(val)
But I still cant seem to figure out why the values is not being set.
I am using a jinja2 template, so Ill give the generated html/js:
<div class="form-group">
<label class="control-label col-sm-4" for="message_type">Meassage Type</label>
<div class="col-sm-5">
<input type="hidden" name="message_type" id="message_type" readonly />
</div>
</div>
and the js:
$(function () {
$("#message_type").select2({
placeholder: "Email/SMS/PIMS Modal",
multiple: true,
width: "300px",
tokenSeparators: [',', ' '],
data: [{
id: "email",
text: "Email"
}, {
id: "pims modal",
text: "PIMS Modal"
}, {
id: "sms",
text: "SMS"
}, ],
});
$("#message_type").select2("val", "pims modal");
});
I have also managed to reproduce the result, see example.
The issue occurs because you have set the multiple property to true. In this case to set a value you need to use an array instead of a string.
For example:
$(function () {
$("#message_type").select2({
placeholder: "Email/SMS/PIMS Modal",
multiple: true,
width: "300px",
tokenSeparators: [',', ' '],
data: [{
id: "email",
text: "Email"
}, {
id: "pims modal",
text: "PIMS Modal"
}, {
id: "sms",
text: "SMS"
}, ],
});
$("#message_type").select2("val", ["email"]);
});
A working demo here: http://jsfiddle.net/nww22qoj/19/
Edit: Here is a working jsfiddle using the 4.0.1 version of the plugin http://jsfiddle.net/nww22qoj/20/ (using the full version of the plugin)

Select2 load related data into second select2?

I am working with Cakephp 2.4, Select2 3.4 and Jquery 1.10.
In my app, I have a table with 3 columns - product code, product description and product price.
I have Select2 set up so that the user can select either via product code or via product description. What I want to achieve is:
if the users selects via product code, set the product description and price and if he selects via description, set product code and price.
My data gets returned as follows:
[{"id":1,"text":"10001","description":"Test Product Name","unitPrice":"1.25"}, {"id":2,"text":"10002","description":"product 2","unitPrice":"5.00"}, {"id":3,"text":"10003","description":"Product 3","unitPrice":"2.74"}]
I am able to set the value of the second select2 box using plain jQuery:
$(".productCode").on('change', function (product){
$(".description").select2("data", {id: '1', text: 'Test'});
});
What do I have to use to set the .description select2 value to the "description" value returned?
You forget initialize the select elements. Do it like this:
<!DOCTYPE html>
<html>
<head>
<title>jquery select2 test</title>
<script type="text/javascript" src="jquery-1.9.1.js"></script>
<link href="select2/select2.css" rel="stylesheet"/>
<script src="select2/select2.js"></script>
</head>
<body>
<input type="hidden" class="productCode" />
<select class="description" >
</select>
<script type="text/javascript">
$(document).ready(function() {
var $productCode = $(".productCode"),
$description = $(".description"),
product = [{"id":1,"text":"10001","description":"Test Product Name","unitPrice":"1.25"},{"id":2,"text":"10002","description":"product 2","unitPrice":"5.00"},{"id":3,"text":"10003","description":"Product 3","unitPrice":"2.74"}];
//should initilize two select first
$productCode.select2({
'placeholder' : 'input to search',
"width" : '200px',
"query": function(query){
var data = {results: product};
query.callback(data);
}
});
$description.select2({
'width' : '200px'
});
$productCode.on('change', function (product){
$description.select2("data", {id: '1', text: 'Test'});
});
});
</script>
</body>
</html>
If you use hidden inputs to back your Select2 controls, like this:
<input type="hidden" class="product" id="productCode" data-text="text" data-placeholder="code" />
<input type="hidden" class="product" id="description" data-text="description" data-placeholder="description" />
<input type="hidden" class="product" id="unitPrice" data-text="unitPrice" data-placeholder="unit price" />
And you have data like this:
var PRODUCTS = [
{ id: 1, text: '10001', description: 'Product 1', unitPrice: '1.25' },
{ id: 2, text: '10002', description: 'Product 2', unitPrice: '5.00' },
{ id: 3, text: '10003', description: 'Product 3', unitPrice: '2.74' }
];
You can populate your Select2 controls using the "data" option, like this:
$('.product').each(function() {
var $this = $(this);
$this.select2({
allowClear: true,
data: { results: PRODUCTS, text: $this.attr('data-text') }
});
});
And you can use the Select2 "val" function to get and set the values, like this:
$('.product').change(function() {
var selecteId = $(this).select2('val');
$('.product').select2('val', selecteId);
});
jsfiddle demo

Categories

Resources