I wonder how do I get the input value from the form in ExtJS.
I have tried several ways "see comments", but none of them gave me a value, i get an error mostly - "undefined".
Another thing that is unclear is where is form name defined ?
Here's my code:
Ext.onReady(function() {
Ext.create('Ext.form.Panel', {
renderTo: document.body,
title: 'Convert Roman characters to Arabic',
height: 150,
width: 300,
bodyPadding: 10,
defaultType: 'textfield',
items: [
{
fieldLabel: 'Enter Roman Character',
name: 'char'
}
],
buttons: [
{
text: 'Submit',
handler: function() {
//var form = formPanel.getForm();
//var value = form.findField('char');
//var form = this.up('form'); // get the form panel
//var value = Ext.getCmp('char').getValue();
// var field = Ext.getCmp('char');
Ext.Msg.alert('Success', "value");
}
}
]
});
});
In the end the application should alert the inputed value.
Thanks in Advance.
text: 'Submit',
handler: function(btn) {
Ext.Msg.alert('Success',btn.up('form').down('[name=char]').getValue());
//var form = formPanel.getForm();
//var value = form.findField('char');
//var form = this.up('form'); // get the form panel
//var value = Ext.getCmp('char').getValue();
// var field = Ext.getCmp('char');
There are multi ways to get value of char field.
1) To get value like this as you used, you have to give id property for this field :
{
fieldLabel: 'Enter Roman Character',
name: 'char',
id : 'char' // or give any name
}
now used below code to get value
var field = Ext.getCmp('char');
var value = field.getValue();
2) You can also use itemId property same :
{
fieldLabel: 'Enter Roman Character',
name: 'char',
itemId : 'char' // or give any name
}
now used below code to get value
var field = Ext.ComponentQuery.query('#char')[0];
var value = field.getValue();
3) another way, you can get value from form values;
var form = this.up('form'),
formValues = form.getForm().getValues();
charValue = formValues.char;
Related
I have a dynamic input which will have checkbox to hide the inputs when you tick the checkbox, at the moment I'm trying to add click="getChk() to the checkbox however it was only giving me the last index inputName.
Say I have input Ids (code, sku, id).
My dynamic inputs and checks code line is
for (var x = 0; x < searchParams.length; x++) {
var container = $('#checkBox');
var inputs = container.find('input');
var id = inputs.length + 1;
var inputName = searchParams[x].name;
$('<textarea />', { id: inputName, name: inputName, placeholder: inputName, rows: "2", class: "search-area-txt col-sm-12" }).appendTo(searchbox);
$('<input />', { type: 'checkbox', id: 'x' + id, name: inputName }).appendTo(checkBox);
$('<label />', { 'for': 'x' + id, text: inputName, id: inputName, name: inputName }).appendTo(checkBox);
}
But this will need to be saved in the localStorage so when refresh it will persist the input to be hidden when its exists in the localStorage.
Edit: the code below should save the name in the localStorage in array form.
var inputNames = [];
getChk(id){
var indexOfItem = inputNames.indexOf(name)
if (indexOfItem >= 0) {
inputNames.splice(indexOfItem, 1);
} else {
inputNames.push(name);
}
localStorage.setItem('chked', JSON.stringify(inputNames))
}
My attempt is by adding .click(function(){})
$('<input />', { type: 'checkbox', id: 'x' + id, name: inputName }).appendTo(checkBox).click(function(){
getChk(id); // only gives me the id name
});
HTML inputs and checkbox html
The issue is because when the click event handler runs the for loop has completed, therefore the id variable holds the last value.
To fix this, amend your click handler to read the id attribute directly from the element which raised the event:
$('<input />', { type: 'checkbox', id: 'x' + id, name: inputName }).appendTo(checkBox).click(function() {
getChk(this.id);
});
Also, as spotted by #guest271314, the correct method when setting localStorage data is setItem(), not set():
localStorage.setItem('checked', id);
you can try below code
getChk(e){
localStorage.set('checked', this.id);
console.log('input id>> ', this.id);
}
.click(getChk);
This is my form view:
and this is my dynamic input form code:
...
let subJudulInput = []; // this variable will render
for (var i = 0; i < this.props.subtitleInput.index; i++) {
let index = i + 1;
subJudulInput.push(
<div key={'formgroup' + index} class="form-group">
{(i === 0) ? <label for="subJudulInput">Sub Judul</label>:false}
<input key={'input' + index} type="text" class="form-control" placeholder={`Masukan Sub Judul ${index}`}/>
</div>
);
}
...
If I click the plus button, the new input form will show:
This is my form handler:
onAddingTitle(event) { // if the submit button get pressed
let formData = {subJudul:[]};
event.preventDefault();
console.log(event.target.elements);
}
How I can grab all of that dynamic input value? (Best ways) to formData object; like this:
let formData = {subJudul:[
'sub judul 1 value here',
'sub judul 2 value here',
'sub judul 3 value here',
'next new input'
]};
Add name attribute to the text field: name={"textbox-"+index}
Try the below code to get your expected values
onAddingTitle(event) {
event.preventDefault();
let formElements = event.target.elements;
let formData = {
subJudul: []
};
Object.keys(formElements).forEach((key) => {
if (formElements[key].type == 'text') {
formData.subJudul.push(formElements[key].value)
}
});
console.log('formData', formData);
}
Explanation:
Get the form elements (which is a object)
loop through the object elemets using keys
Check the type of the field, if its a textbox(add as per your need) push the value of the field to array.
I have a dynamic table, which each row contains country and numberOfState fields. Currently I am able to add new record and validate the country and numberOfState field separately (e.g. required) after click the "AddNewRecord" button, which is below code that generate dynamic table unique field name, i.e. name="country_0", "numberOfState_0" for 1st row, and ="country_1", "numberOfState_1" for 2nd row and etc.
Would like to check whether can validate the dynamic country and numberOfState fields together (i.e. Country is US and NumberOfState must be 50), using dynamic rule code as per below addRowRule function. Thanks in advance.
$(document).ready(function(e){
var rowindex = 0;
$("#AddNewRecord").click(function(){
var row =
"<tr><td>input name=country_"+rowindex+" type=text class='countryRule'/></td>
<tr><td>input name=numberOfState_"+rowindex+" type=text class='stateRule'/></td></tr>";
$("#table").append(row);
rowindex++;
addRowRule(rowindex);
});
jQuery.validate.addClassRules({
countryRule:{required:true},
stateRule:{required:true}
});
$('form').validate();
function addRowRule(i) {
var country = '#country_' + i,
var numberOfState = '#numberOfState_' + i;
$(country).rules('add', {
required: true,
numberOfState:{
required: {
depend: function(element){
if ($(country).val() == 'US' &&
$(numberOfState).val() !=50){
return false;
}
return true;
}
messages: {
numberOfState: "Number of state not match with country",
}
},
messages: {
required: "Required input",
}
});
});
Updated code to share with all:
$( document ).ready(function() {
$("#myForm").validate(); //sets up the validator
var rowindex = 0;
$("#AddNewRecord").click(function(){
var row = "<tr><td>input name=country_"+rowindex+" type=text /></td>" +
"<tr><td>input name=numberOfState_"+rowindex+" type=text /></td></tr>";
$("#table").append(row);
addRowRule(rowindex);
rowindex++;
});
function addRowRule(row_index) {
var country = '#country_' + row_index;
var numberOfState = '#numberOfState_' + row_index;
$(country).rules('add', {
required: true,
messages: {
required: "Pls input country."
}
});
$(numberOfState).rules('add', {
required: true,
checkCountryAndState: [country, numberOfState],
messages: {
required: "Pls input number of state."
}
});
}
jQuery.validator.addMethod("checkCountryAndState", function(value, element, params){
var varCountry = params[0];
var varNumberOfState = params[1];
if ($(varCountry).val() === 'America' && $(varNumberOfState).val() !== 50){
return false;
}
return true;
}, jQuery.format("Country is not match with Number of State."));
});
You can specify validation rules with the rules property. This should do what you specified in the question as an example:
$(".selector").validate({
rules: {
field2: {
required: true,
field1: {
depends: function(element) {
if ($('#field1').val() === 'A' && $('#field2').val() === 'Z') {
return false;
}
return true;
}
}
}
}
});
After this, you need to assign a message if the validation fails with the messages property.
Part of your problem is putting invalid objects inside of the .rules() method. Since the .rules() method is already attached to a selector (representing a SINGLE field), you cannot declare rules for additional fields inside of it...
function addRowRule(i) {
var country = '#country_' + i,
var numberOfState = '#numberOfState_' + i;
$(country).rules('add', {
required: true,
numberOfState: { // <- you can NOT put this here
required: { ...
The only objects allowed inside of .rules() is a key: value list of various rules/methods and/or the messages object.
You would have to attach other fields to different instances of .rules()....
function addRowRule(i) {
var country = '#country_' + i,
var numberOfState = '#numberOfState_' + i;
$(country).rules('add', {
required: true,
....
});
$(numberOfState).rules('add', {
required: true,
....
});
....
I found a file called copyShipping.js that allows me to copy form elements from one form to another by the click of a checkbox. However, it copies by name of each field rather than ID. Below is the code. How do I get it to copy by ID? I know there's a getElementByID on Javascript but I don't know how to implement it. Ideally I would just like the code changed for me. Thanks.
function eCart_copyBillingToShipping(cb){
if(cb.checked){ // Only copy when the checkbox is checked.
var theForm = cb.form;
// The number of elements must match in billingFields and shippingFields. The type of input element must also match between the arrays.
var billingFields = new Array('firstname', 'lastname', 'email', 'phone', 'fax', 'street1', 'street2', 'city', 'state_province', 'StateOther', 'other_state_province', 'postcode', 'other_postcode', 'country');
var shippingFields = new Array('shipping_firstname', 'shipping_lastname', 'shipping_email', 'shipping_phone', 'shipping_fax', 'shipping_street1', 'shipping_street2', 'shipping_city', 'shipping_state_province', 'ShippingStateOther', 'other_shipping_state_province', 'shipping_postcode', 'other_shipping_postcode', 'shipping_country');
for(var i=0;i<billingFields.length;i++){
var billingObj = theForm.elements[billingFields[i]];
var shippingObj = theForm.elements[shippingFields[i]];
if(billingObj && shippingObj){
if(billingObj.tagName){ // non-radio groups
var tagName = billingObj.tagName.toLowerCase();
if(tagName == 'select'){
shippingObj.selectedIndex = billingObj.selectedIndex;
}
else if((billingObj.type && shippingObj.type ) && (billingObj.type == 'checkbox' || billingObj.type == 'radio')){
shippingObj.checked = billingObj.checked;
}
else{ // textareas and other inputs
shippingObj.value = billingObj.value;
}
}
else if(billingObj.length){ // radio group
for(var r=0;r<billingObj.length;r++){
shippingObj[r].checked = billingObj[r].checked;
}
}
}
}
}
}
It is always recommended to access the elements using Id. Also it is recommended to have id and name same.
Try this.
function eCart_copyBillingToShipping(cb){
if(cb.checked){ // Only copy when the checkbox is checked.
var theForm = cb.form;
// The number of elements must match in billingFields and shippingFields. The type of input element must also match between the arrays.
var billingFields = new Array('firstname', 'lastname', 'email', 'phone', 'fax', 'street1', 'street2', 'city', 'state_province', 'StateOther', 'other_state_province', 'postcode', 'other_postcode', 'country');
var shippingFields = new Array('shipping_firstname', 'shipping_lastname', 'shipping_email', 'shipping_phone', 'shipping_fax', 'shipping_street1', 'shipping_street2', 'shipping_city', 'shipping_state_province', 'ShippingStateOther', 'other_shipping_state_province', 'shipping_postcode', 'other_shipping_postcode', 'shipping_country');
for(var i=0;i<billingFields.length;i++){
//assuming that now array contains id (not name)
var billingObj = theForm.getElementById(billingFields[i]);
var shippingObj = theForm.getElementById(shippingFields[i]);
if(billingObj && shippingObj){
if(billingObj.tagName){ // non-radio groups
var tagName = billingObj.tagName.toLowerCase();
if(tagName == 'select'){
shippingObj.selectedIndex = billingObj.selectedIndex;
}
else if((billingObj.type && shippingObj.type ) && (billingObj.type == 'checkbox' || billingObj.type == 'radio')){
shippingObj.checked = billingObj.checked;
}
else{ // textareas and other inputs
shippingObj.value = billingObj.value;
}
}
else if(billingObj.length){ // radio group
for(var r=0;r<billingObj.length;r++){
shippingObj[r].checked = billingObj[r].checked;
}
}
}
}
}
}
so I am trying to get the fields in my backbone model being called in the view, editable and validated by the model. How do I go about doing that? I know there is an html way of doing contenteditable="true" but I am looking for a more backbone oriented way or a way to actually make that validate too.
Here is my current code for my main.js file (but I am not trying to .append it I want it to stay in place and also trying to figure out how to get the field to be called specifically depending on which text they clicked on. Ultimately the button should change too (to save changes).
The main.js
App.Models.User = Backbone.Model.extend({
defaults: {
firstName: 'first',
lastName: 'last',
email: 'Email',
phone: '222',
birthday: 'date'
},
validate: function (attrs) {
if (!attrs.firstName) {
return 'You must enter a real first name.';
}
if (!attrs.lastName) {
return 'You must enter a real last name.';
}
if (attrs.email.length < 5) {
return 'You must enter a real email.';
}
if (attrs.phone.length < 10 && attrs.phone === int) {
return 'You must enter a real phone number, if you did please remove the dash and spaces.';
}
if (attrs.city.length < 2) {
return 'You must enter a real city.';
}
}
});
App.Views.UserUpdate = Backbone.View.extend({
model: App.Models.User,
events: {
'click .edit': 'editUserProfile'
},
editUserProfile: function(field) {
var field =
$('#user').append('<input type="text" class="edit" placeholder="' + field+'" /> ' );
},
initialize: function() {
this.model.on('change', function() {
this.render();
}, this);
},
render: function() {
this.$el.html(this.model.get('email'));
}
});
This is the jade file:
extends layout
block content
div.centerContent
script(type="text/javascript", src="/js/main.js")
h4 User goes here with equal before it no space
div(contenteditable="true")
form#user
- var firstName = "John"
- var lastName = "Smith"
label #{firstName} #{lastName}
- var email = "test#test.com"
label.edit #{email}
- var phone = "555-555-5757"
label #{phone}
- var pin = "PIN: LIO20001"
label #{pin}
- var birthday = "07/28/1982"
label #{birthday}
button Post
hr
div.user User
p
button.edit Edit
I have created a fiddle for this: http://jsfiddle.net/LTGjT/18/
You should assign the contenteditable and id for each editable label:
- var firstName = "John"
- var lastName = "Smith"
label #{firstName} #{lastName}
- var email = "test#test.com"
label(contenteditable="true", id="email") #{email}
- var phone = "555-555-5757"
label(contenteditable="true", id="phone") #{phone}
- var birthday = "07/28/1982"
label(contenteditable="true", id="birthday") #{birthday}
The reason is to recognize what label is being edited by getting the event.target, in your old code the event.target will always be the parent div.
Then in backbone listen to the input event for the change of the label then update the model:
App.Models.User = Backbone.Model.extend({
defaults: {
firstName: 'first',
lastName: 'last',
email: 'abc#abc.com',
phone: '222',
birthday: '01/01/2001'
},
initialize: function() {
},
validate: function (attrs) {
if (!attrs.firstName) {
return 'You must enter a real first name.';
}
if (!attrs.lastName) {
return 'You must enter a real last name.';
}
if (attrs.email.length < 5) {
return 'You must enter a real email.';
}
if (attrs.phone.length < 10 && attrs.phone === int) {
return 'You must enter a real phone number, if you did please remove the dash and spaces.';
}
if (attrs.city.length < 2) {
return 'You must enter a real city.';
}
}
});
App.Views.UserUpdate = Backbone.View.extend({
model: App.Models.User,
events: {
'click button' : 'saveHandler'
},
initialize: function() {
var self = this;
self.render();
console.log(this.model);
$('[contenteditable=true]').on('input', function(e){
var field = e.target.id;
var value = e.target.innerText;
self.model.set(field, value);
logUser(self.model);
});
self.model.on('change', function(){
$('button').show();
});
},
saveHandler: function(e) {
//Validate & Save logic
//this.model.save()
e.preventDefault();
$(e.target).hide();
},
render: function() {
var template = _.template($('#user-view').html());
this.$el.html(template({user: this.model.toJSON()}));
$('body').prepend(this.$el);
logUser(this.model);
}
});