How to pass the phone number from Intl-Tel-Input to an input on Ruby-on-rails? - ruby-on-rails

I have a simple_form with a phone number. I'm using Intl-Tel-Input to get the entire phone_number and confirm SMS in different countries (twilio). In console.log, I succeed to display the entire number. When I submit, I just get the phone_number without the country indicator (dial_code)
I read the doc, tried to get it by other way (.value, .data, etc...), but impossible to save the entire phone_number (for example, +33612345678, I just get 61234567).
Here's my code :
<div class="userphonenumber">
<%= f.input :phone_number, label: 'N° de téléphone', required: true, autofocus: true ,
input_html: { autocomplete: "intlNumber" }, wrapper_html: { id: 'userphonenumber' }%>
</div>
<script>
$("#user_phone_number").intlTelInput({
formatOnInit: true,
separateDialCode: true,
onlyCountries: ['fr', 'at', 'be', 'bg', 'cz', 'dk', 'de', 'ee', 'ie', 'el', 'es', 'hr', 'it', 'cy', 'lv', 'lt', 'lu', 'hu', 'mt', 'nl', 'pl', 'pt', 'ro', 'si', 'sk', 'fi', 'se', 'uk'],
initialCountry: "fr"
});
const flag = document.querySelector(".flag-container")
flag.addEventListener("click", () => {
var intlNumber = $("#user_phone_number").intlTelInput("getNumber");
console.log("intlNumber", intlNumber)
var input = document.querySelector("#user_phone_number");
window.intlTelInput(input);
});
</script>
I'm expecting to get +33612345678 to use the phone_number with twilio. Beginner on RoR and JS. Did I miss something ?
Thanks for your help.

Finally fix with this solution :
<script>
$("#user_phone_number").intlTelInput({
formatOnInit: true,
separateDialCode: true,
onlyCountries: ['at', 'be', 'bg', 'cz', 'dk', 'de', 'ee', 'ie', 'el', 'es', 'fr', 'hr', 'it', 'cy', 'lv', 'lt', 'lu', 'hu', 'mt', 'nl', 'pl', 'pt', 'ro', 'si', 'sk', 'fi', 'se', 'uk'],
initialCountry: "fr",
});
var phone = document.getElementById('user_phone_number')
phone.addEventListener('keyup', (event) => {
console.log(event)
});
$("form").submit(function() {
$('#user_phone_number').val($(phone).intlTelInput("getNumber"));
});
</script>

$(".form").submit( function(eventObj) {
$("<input />").attr("type", "hidden")
.attr("name", "ccode")
.attr("value", $(this).find(".selected-dial-code").text())
.appendTo(".form");
return true;
});

Related

Consumption of an api data into ant-design table react-typescript

interface DataType {
id: string;
first_name: string;
last_name: string;
email: string;
phone: string;
ip_address: string;
is_active: Boolean;
Avatar: string;
}
const columns: ColumnsType<DataType> = [
{
title: 'First Name',
dataIndex: 'first_name',
key: 'first_name',
render: (first_name, data) => {
return (
<div>
<img className='customers-avatar' src={data.Avatar} alt="" />
{first_name}
</div>
)
},
},
{
title: 'Last Name',
dataIndex: 'last_name',
key: 'last_name',
},
{
title: 'Email Address',
dataIndex: 'email',
key: 'email',
},
{
title: 'Phone Number',
dataIndex: 'phone',
key: 'phone',
},
{
title: 'Last Login',
render: () => {
return (
<p>April 2, 2022</p>
)
},
},
{
title: '',
key: 'action',
render: () => (
<Space size="middle">
<Link to="/shipments" className='space-action' >Shipment</Link>
<Link to="/" className='space-action-green'>Edit</Link>
</Space>
),
},
];
const Customers: React.FC = () => {
const [customersData, setCustomersData] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
getCustomers();
});
const getCustomers = () => {
setLoading(true);
return makeAPICall({
path: `get_customers`,
method: "GET",
})
.then((data) => {
setCustomersData(data);
setLoading(false);
console.log(data);
})
.catch((err) => {
setLoading(false);
console.log(err);
});
}
return (
<SiderLayout>
<div className="site-layout-background" style={{ padding: "40px 40px", minHeight: 710 }}>
<button type='submit'>Add Customer {" "} +</button>
{loading ? 'loading...' : (
<div>
{!customersData ? ("No data") : (<Table columns={columns} dataSource={customersData} />)}
</div>
)}
</div>
</SiderLayout>
)
}
export default Customers;
I've consumed the get_customers api, which I think I did it correctly, but the data is not displaying on the browser.
When I went to inspect element, I thought is as a result of CORS, so I turned on CORS, but it wasn't still working, it would fetch all the data in that process of loading the state, it would display a blank screen at the end.

ANT design 4 table input filed validate

Im adding my react project for ant design4 table and ant design input fields. any one know to how can validate that input required
Thanks
stackablitz here
code here
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a>{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
{
title: 'Tags',
key: 'tags',
dataIndex: 'tags',
render: tags => (
<>
{tags.map(tag => {
let color = tag.length > 5 ? 'geekblue' : 'green';
if (tag === 'loser') {
color = 'volcano';
}
return (
<Tag color={color} key={tag}>
{tag.toUpperCase()}
</Tag>
);
})}
</>
),
},
{
title: 'Action',
key: 'action',
render: (text, record) => (
<Space size="middle">
<a>Invite {record.name}</a>
<a>Delete</a>
</Space>
),
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: <input/>,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: <input/>,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: <input/>,
address: 'Sidney No. 1 Lake Park',
tags: ['cool', 'teacher'],
},
];
const onFinish = values => {
console.log(values);
};
ReactDOM.render(
<div>
<Form name="control-hooks" onFinish={onFinish}>
<Table columns={columns} dataSource={data} /> <div><Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button> </Form.Item>
Just enclose the <input/> in <Form.Item> and use the rules prop of it. You can see all the possible rules here. I suggest use the <Input/> of antd and set a width on it.
const data = [
{
key: "1",
name: "John Brown",
age: (
<Form.Item
name="age1"
rules={[{ required: true, message: "Age is required" }]}
>
<Input style={{ width: 150 }} />
</Form.Item>
),
address: "New York No. 1 Lake Park",
tags: ["nice", "developer"],
},
...
];
see this working link

Twitter's typeahead

I am trying to add twitter's typeahead plugin to my rails application. I have downloaded the typeahead.bundle.js and placed it in vendor/assets/javascripts directory. And I have added //= require typeahead.bundle to app/assets/javascripts/application.js. Then I put the first example given there
<div id="the-basics">
<input class="typeahead" type="text" placeholder="States of USA">
</div>
on one of my views and the following javascript on
app/assets/javascripts/example.js
but nothing happens when i try to type characters, not even on the logs. Thanks for your help
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substrRegex;
matches = [];
substrRegex = new RegExp(q, 'i');
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push({ value: str });
}
});
cb(matches);
};
};
var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];
$('#the-basics .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
displayKey: 'value',
source: substringMatcher(states)
});

How can I use a custom sortFunction with a Grails gui:datatable tag?

I have a datatable in Grails with several sortable columns. Unfortunately, the sort is case-sensitive by default, such that "Zed" is shown before "alice". So I want to add a custom case-insensitive sort function. I'll start by sorting the username column in this manner.
I have read about the sortOptions and sortFunction at http://developer.yahoo.com/yui/datatable/ but I can't seem to get it to work.
I added the following JavaScript to list.gsp:
var caseInsensitiveSortFunction = function(a, b, desc, field) {
// See http://developer.yahoo.com/yui/datatable/ and look for 'sortFunction'
// Set this function name as the sortFunction option
// Deal with empty values
if (!YAHOO.lang.isValue(a)) {
return (!YAHOO.lang.isValue(b)) ? 0 : 1;
} else if (!YAHOO.lang.isValue(b)) {
return -1;
}
return YAHOO.util.Sort.compare(String(a).toLowerCase(), String(b).toLowerCase(), desc);
};
And here is the datatable definition on that same page:
<gui:dataTable id="userTable"
controller="user" action="listJSON"
rowsPerPage="20"
sortedBy="username"
columnDefs="[
[key:'username', label:'Username', resizeable: false, sortable: true, sortOptions: { sortFunction: 'caseInsensitiveSortFunction' }],
[key:'email', label:'Email', resizeable: false, sortable: true],
[key:'firstName', label:'First Name', resizeable: false, sortable: true],
[key:'lastName', label:'Last Name', resizeable: false, sortable: true],
[key:'enabled', label:'Enabled', resizeable: false, sortable: true],
[key:'accountLocked', label:'Locked', resizeable: false, sortable: true],
[key:'roleDescription', label:'Role', resizeable: false, sortable: true]
]"
draggableColumns="true"
rowClickNavigation="true"
paginatorConfig="[
template:'{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {CurrentPageReport}',
pageReportTemplate:'{totalRecords} total record(s)',
alwaysVisible:true,
containers:'dt-paginator'
]"/>
<div id="dt-paginator" class="yui-skin-sam yui-pg-container"></div>
Changing the 'username' key to the following (sans quotes) does not help.
[key:'username', label:'Username', resizeable: false, sortable: true, sortOptions: { sortFunction: caseInsensitiveSortFunction }],
Both approaches create the following source. Note that the sortOptions for the username is blank.
<div id="dt_div_userTable"></div>
<script>
YAHOO.util.Event.onDOMReady(function () {
var DataSource = YAHOO.util.DataSource,
DataTable = YAHOO.widget.DataTable,
Paginator = YAHOO.widget.Paginator;
var userTable_ds = new DataSource('/admin/gpupUser/listJSON?');
userTable_ds.responseType = DataSource.TYPE_JSON;
userTable_ds.connMethodPost=true;
userTable_ds.responseSchema = {
resultsList : 'results',
fields : ["username","email","firstName","lastName","enabled","accountLocked","roleDescription","dataUrl"],
metaFields : {
totalRecords: 'totalRecords'
}
};
userTable_ds.doBeforeCallback = function(oRequest, oFullResponse, oParsedResponse, oCallback) {
return GRAILSUI.util.replaceDateStringsWithRealDates(oParsedResponse);
};
var userTable_paginator = new Paginator(
{'template': '{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {CurrentPageReport}',
'pageReportTemplate': '{totalRecords} total record(s)',
'alwaysVisible': true,
'containers': 'dt-paginator',
'rowsPerPage': 20}
);
var registerEditorListener = function(editor, field, url,successCallback,failureCallback) {
editor.subscribe("saveEvent", function(oArgs) {
GRAILSUI.userTable.loadingDialog.show();
var editorCallback = {
success: successCallback,
failure: function(o) {
// revert the cell value
GRAILSUI.userTable.updateCell(oArgs.editor.getRecord(), field, oArgs.oldData);
// alert user
if (failureCallback)
failureCallback(o);
else
alert('Received an error during edit: ' + o.responseText);
}
};
YAHOO.util.Connect.asyncRequest('POST', url, editorCallback, 'id=' + oArgs.editor.getRecord().getData('id') + '&field=' + field + '&newValue=' + oArgs.newData);
});
};
var myColumnDefs = [{'key': 'username',
'label': 'Username',
'resizeable': false,
'sortable': true,
'sortOptions': }, {'key': 'email',
'label': 'Email',
'resizeable': false,
'sortable': true}, {'key': 'firstName',
'label': 'First Name',
'resizeable': false,
'sortable': true}, {'key': 'lastName',
'label': 'Last Name',
'resizeable': false,
'sortable': true}, {'key': 'enabled',
'label': 'Enabled',
'resizeable': false,
'sortable': true}, {'key': 'accountLocked',
'label': 'Locked',
'resizeable': false,
'sortable': true}, {'key': 'roleDescription',
'label': 'Role',
'resizeable': false,
'sortable': true}, {'key': 'dataUrl',
'type': 'dataDrillDown',
'hidden': true}];
GRAILSUI.userTable = new GRAILSUI.DataTable('dt_div_userTable', myColumnDefs, userTable_ds, '', {
initialRequest : 'max=20&offset=0&sort=username&order=asc&',
paginator : userTable_paginator,
dynamicData : true,
sortedBy : {key: "username", dir: YAHOO.widget.DataTable.CLASS_ASC},
'draggableColumns': true,
'selectionMode': 'single',
'rowClickNavigate': false,
'rowClickMode': 'navigate',
'formatter': 'text'
});
// Update totalRecords on the fly with value from server
GRAILSUI.userTable.handleDataReturnPayload = function(oRequest, oResponse, oPayload) {
oPayload.totalRecords = oResponse.meta.totalRecords;
return oPayload;
};
// Set up editing flow
var highlightEditableCell = function(oArgs) {
var elCell = oArgs.target;
if(YAHOO.util.Dom.hasClass(elCell, "yui-dt-editable")) {
this.highlightCell(elCell);
}
};
GRAILSUI.userTable.subscribe("cellMouseoverEvent", highlightEditableCell);
GRAILSUI.userTable.subscribe("cellMouseoutEvent", GRAILSUI.userTable.onEventUnhighlightCell);
GRAILSUI.userTable.subscribe("cellClickEvent", GRAILSUI.userTable.onEventShowCellEditor);
});
</script>
<div id="dt-paginator" class="yui-skin-sam yui-pg-container"></div>
Is there any way to get the datatable to use a custom sortFunction when configured as a tag?
In listJSON action, add ignoreCase: true parameter to list(). See doc. It's probably the only easy way.
You cannot push a totally custom function from Javascript level to database level, if you're going to support paging - custom function will sort current page only, but paging will be based on default (by id) ordering. In other words, custom function works correctly for no more then 1-page tables.
You can customize sorting to certain extent if you use a Criteria or SQL in listJSON action - but still, you're limited to Hibernate or SQL level.
After digging into the code base, I finally realized that the sorting was being done on the server side, so I was able to address the issue there.

Enable tabs with jquery ui tabs issue

I am trying to enable the next tab at the end of the function below.
Here is my function (UPDATED)
var $signup = $('#signup-content').tabs({disabled: [1,2],
show: function(event, ui) {
// Validates Form on Slide # 1
$("#createAccount").validate({
meta: "validate",
errorElement: "em",
errorClass: "error",
validClass: "success",
highlight: function(element, errorClass, validClass) {
$(element).closest("div.required").removeClass(validClass);
$(element).closest("div.required").addClass(errorClass);
$(element).addClass(errorClass);
},
unhighlight: function(element, errorClass, validClass) {
$(element).closest("div.required").removeClass(errorClass);
$(element).closest("div.required").addClass(validClass);
$(element).removeClass(errorClass);
},
errorPlacement: function(error, element) {
if (element.attr("name") == "month"
|| element.attr("name") == "day"
|| element.attr("name") == "year")
error.insertAfter("#year");
else
error.addClass("hide");
},
debug:true,
groups: {birthday: "month day year"
},
rules: {
firstname:{required:true},
lastname:{required:true},
email: {required: true, email: true},
confirm_email: {required: true, equalTo: "#email"},
password:{required: true},
confirm_password:{required: true,equalTo: "#password"},
zipcode: {required:true, min:5},
month:{required:true},
day:{required:true},
year:{required:true},
gender:{required:true},
agree:{required:true}
},
messages: {
month: {required: "Month Is Missing"},
day: {required: "Day Is Missing"},
year: {required: "Year Is Missing"}
},
submitHandler: function(form) {
$(form).ajaxSubmit({
beforeSubmit: function showRequest(formData, jqForm, options) {
var queryString = $.param(formData);
alert('About to submit: \n\n' + queryString);
return true;
},
success: function showResponse(formData) {
$('html, body').animate({scrollTop:'0px'}, 500);
$signup.tabs('option', 'enabled', [1]);
$signup.tabs('select', 1); // Go To Slide # 2
$('#message-container').addClass("notice").append('<h3>Your Account Has Been Created!</h3><img src="/assets/images/close.png" alt="Close" title="Close"/>');
$('#message-container').fadeIn(1200, function(){
$('#close').click(function(){$('#message-container').fadeOut(1200);});});
return false;}});}});
this worked for me, at least with version 1.7 :
$signup.tabs('enable', 1);
According to the instructions, you can't use:
$signup.tabs('option', 'enabled', [1]);
but instead use:
$signup.data('disabled.tabs', []);
what that does is clear the list of disabled tabs.

Resources