I am trying to use the "onreset" option but I am having issues. I have a field that is meant for users to enter 10 numbers only. I want to make the 10 numbers display in a phone format ie. (310) 490-1235. So far I can do this, and the HTML of the field gets set to 3104901235 while the text is (310) 490-1235, but when a user cancels or goes to another field, the current field closes, and displays the HTML (3104901235) instead of the text (310) 490-1235.
I have a function set in the "onreset" option for it to set the text but it doesnt apply.
//Phone field
// Set the fields 10 digits to phone format
set_phone();
function isNumeric(value) {
if (value == null || !value.toString().match(/^[-]?\d*\.?\d*$/)) return false;
return true;
}
$('.edit-phone').editable('<?php echo base_url(); ?>home_resume/builder/ajax_save_field', {
onsubmit: function(settings, td) {
rm_class();
var input = $(td).find('input');
var original = input.val().trim();
if (isNumeric(original) && original.length == 10) {
$('#notification-saved').miniNotification({opacity: 1.0});
return true;
} else {
$('#notification-phone').miniNotification({opacity: 1.0});
input.css('background-color','#c00').css('color','#fff');
return false;
}
},
type : 'text',
cancel : 'Cancel',
onreset : function(value, settings){
$(this).closest("li").removeClass("active");
// Since the HTML is now just 10 digits, set it back to phone format with
set_phone();
},
style : 'display: inline',
select : 'true',
submit : 'OK',
event : "edit-phone",
indicator : '<img src="<?php echo base_url(); ?>themes/resume-builder/images/fb-indicator.gif">'
});
$(".edit-phone-trigger").on("click", function() {
strip_phone();
$(this).closest("li").addClass('active');
var edit_id = $(this).attr("id").split("-");
$('#' + edit_id[1]).trigger("edit-phone");
return false;
});
// Format the 10 digit phone number
function set_phone() {
var num = $("#7").text();
var num_1 = num.slice(0,3);
var num_2 = num.slice(3,6);
var num_3 = num.slice(6,11);
var new_num = "("+num_1+") "+num_2+"-"+num_3;
$("#7").text(new_num);
}
// Remove characters from phone number input
function strip_phone() {
var pnum = $("#7").text();
pnum = pnum.replace(/\(/g, "");
pnum = pnum.replace(/\)/g, "");
pnum = pnum.replace(/-/g, "");
pnum = pnum.replace(/\s/g, "");
$("#7").html(pnum);
}
You can try using the data and callback options for changing the way the text is displayed inside the input, this way you also avoid the need to use your custom event.
data will be called when the element is first clicked and can be used to alter the text before editing. Here you strip the phone to just numbers to be displayed on the input.
callback will run after after the form has been submitted. Here you format the submitted content to a phone number and change the text of the original element. (Inside function this refers to the original element)
$('.edit-phone').editable('<?php echo base_url();?>home_resume/builder/ajax_save_field', {
type : 'text',
cancel : 'Cancel',
style : 'display: inline',
select : 'true',
submit : 'OK',
event : 'click',
indicator : '<img src="<?php echo base_url(); ?>themes/resume-builder/images/fb-indicator.gif">',
data : function(value, settings) {
return strip_phone(value);
},
callback : function(value, settings){
$(this).text(set_phone(value));
}
onsubmit : function(settings, td) {
rm_class();
var input = $(td).find('input');
var original = input.val().trim();
if (isNumeric(original) && original.length == 10) {
$('#notification-saved').miniNotification({opacity: 1.0});
return true;
} else {
$('#notification-phone').miniNotification({opacity: 1.0});
input.css('background-color','#c00').css('color','#fff');
return false;
}
},
});
// Format the 10 digit phone number
function set_phone(text) {
var num = text;
var num_1 = num.slice(0,3);
var num_2 = num.slice(3,6);
var num_3 = num.slice(6,11);
var new_num = "("+num_1+") "+num_2+"-"+num_3;
return new_num;
}
// Remove characters from phone number input
function strip_phone(text) {
var pnum = text;
pnum = pnum.replace(/\(/g, "");
pnum = pnum.replace(/\)/g, "");
pnum = pnum.replace(/-/g, "");
pnum = pnum.replace(/\s/g, "");
return pnum;
}
Note that I updated your set_phone() and strip_phone() functions to return the value instead of setting it directly to the element so they can be called dynamically
Related
I try to learn SAPUI5 with Samples frpm Demo kit Input - Checked. I get an error message: oInput.getBinding is not a function
I have a simple input field xml:
<Label text="Name" required="false" width="60%" visible="true"/>
<Input id="nameInput" type="Text" enabled="true" visible="true" valueHelpOnly="false" required="true" width="60%" valueStateText="Name must not be empty." maxLength="0" value="{previewModel>/name}" change= "onChange"/>
and my controller:
_validateInput: function(oInput) {
var oView = this.getView().byId("nameInput");
oView.setModel(this.getView().getModel("previewModel"));
var oBinding = oInput.getBinding("value");
var sValueState = "None";
var bValidationError = false;
try {
oBinding.getType().validateValue(oInput.getValue());
} catch (oException) {
sValueState = "Error";
bValidationError = true;
}
oInput.setValueState(sValueState);
return bValidationError;
},
/**
* Event handler for the continue button
*/
onContinue : function () {
// collect input controls
var that = this;
var oView = this.getView();
var aInputs =oView.byId("nameInput");
var bValidationError = false;
// check that inputs are not empty
// this does not happen during data binding as this is only triggered by changes
jQuery.each(aInputs, function (i, oInput) {
bValidationError = that._validateInput(oInput) || bValidationError;
});
// output result
if (!bValidationError) {
MessageToast.show("The input is validated. You could now continue to the next screen");
} else {
MessageBox.alert("A validation error has occured. Complete your input first");
}
},
// onChange update valueState of input
onChange: function(oEvent) {
var oInput = oEvent.getSource();
this._validateInput(oInput);
},
Can someone explain to me how I can set the Model?
Your model is fine and correctly binded.
The problem in your code is here, in the onContinue function
jQuery.each(aInputs, function (i, oInput) {
bValidationError = that._validateInput(oInput) || bValidationError;
});
aInput is not an array, so your code is not iterating on an array element.
To quickly fix this, you can put parentheses around the declaration like this:
var aInputs = [
oView.byId("nameInput")
];
Also, you could remove the first two lines of the _validateInput method since they are useless...
Usually, we set the model once the view is loaded, not when the value is changed. For example, if you would like to set a JSONModel with the name "previewModel", you can do as mentioned below.
Note that onInit is called when the controller is initialized. If you bind the model properly as follows, then the oEvent.getSource().getBinding("value") will return the expected value.
onInit: function(){
var oView = this.getView().byId("nameInput");
oView.setModel(new sap.ui.model.json.JSONModel({
name : "HELLO"
}), "previewModel");
},
onChange: function(oEvent) {
var oInput = oEvent.getSource();
this._validateInput(oInput);
},
...
Also, for validating the input text, you can do the following:
_validateInput: function(oInput) {
var oBinding = oInput.getBinding("value");
var sValueState = "None";
var sValueStateText = "";
var bValidationError = false;
if(oBinding.getValue().length === 0){
sValueState = "Error";
sValueStateText = "Custom Error"
}
oInput.setValueState(sValueState);
if(sValueState === "Error"){
oInput.setValueStateText(sValueStateText);
}
return bValidationError;
},
Please note that the code above is not high quality and production ready as it's a quick response to this post :)
I've been sweating over this the last three days, I am baffled!
The input html launches an xml scan of a web site to gather text, images and links which populate a form for the user to select what they want to save. (The output eventually becomes a bookmark stored at greenfloyd.org.) The problem began a month or so ago, the scan started crashing with a "Forbidden 403" error pointing to my php code file, on the gf server (dir/file permission at 0644). The problem revolves around the links (url and text) gathered and placed into a box , the url is put in the value, and the link text into the innerHTML. The default is that none of the links are selected, the user can then select one or more links from this box, or manually add a link via two fields that get put into the select box, and become part of the form.
<form id = "bmInputForm" onsubmit = "bmSub(); return false;" onreset = "bmInputFormReset();" action = "http://greenfloyd.org/greenfloyd/php/bm_input_xml.php" method = "post" enctype = "multipart/form-data" class = "readerBox">...
<code><input type = "url" id = "link1Url" class = "input_size" size = "40" maxlength = "250" value ="" onclick = "this.select();" title = "Enter a standard url for this related link.">
<input id = "link1Title" class = "input_size" size = "40" maxlength = "150" value = "" onclick = "this.select();" title = "Enter a short title for this related link.">
<button type = "button" onclick = "relatedAdd()" title = "Add to related links list.">[+]</button>
<hr style="width:25%;">
<select id = "relatedSelect" name = "related_select[]" multiple title = "To select/unselect hold down the Ctrl key and click an option." onchange = "relatedCheck();" style = "width:80%;"></select></code>
The scan is an ajax xml call and returns elements from the target url, including the following:
<code>//echo "<related url='".rawurlencode($valid_url)."' txt='".htmlspecialchars($related_text, ENT_QUOTES,'UTF-8')."'></related>";
err = false;
try { var relatedNode = ( xmlDoc.getElementsByTagName("related") ) ? xmlDoc.getElementsByTagName("related") : false; }
catch(err) { err = true; relatedNode = false; }
result += ( !relatedNode ) ? "<li>Scanner unable to retrieve relatedNode || "+err+"</li>" : "<li>Link scan found: "+relatedNode.length+" entries.</li>";
if( relatedNode.length > 0 )
{
clearCache("relatedSelect");
var selObj = document.getElementById("relatedSelect");
for(var i = 0; i < relatedNode.length; i++)
{
val = unescape(relatedNode[i].getAttribute("url"));
str = unescape(relatedNode[i].getAttribute("txt"));
opt = document.createElement("option");
opt.value = val;
opt.innerHTML= ( str.length > 50 ) ? str.substring(0,48)+"..." : str;
selObj.appendChild(opt);
}
}
</code>
All the above is working fine. But everything goes south at submit time when the urls, (the value), are external relative to greenfloyd.org. Then, I get the "Go away and don't come back message..." On the other hand, if the urls point to greenfloyd there's no problem and the bookmark is published, with links. It's almost like I were trying to call the local script from some other domain. The uls are not in any linkable context, they are treated as plain text in the value attribute of the option. Although I do combine the url with the text using a seperator (,) between them so that php can unpack the value to produce seperate url and text fields that are stored on msqli... it's hacky, but it works, or at least it use to and I've yet to find a better alternative. One other odd thing: when I gather the links in greenfloyd.org there are a couple external links and they are accepted!?
<code>
function bmSub()
{
...
var selObj = document.getElementById("relatedSelect");
var url, txt, val, sendCt=0;
for ( var i = 0; i < selObj.options.length; i++ )
{
if ( selObj.options[i].selected )
{
url = selObj.options[i].value.trim();
txt = selObj.options[i].innerHTML;
val = url+"*,*"+txt; // pack url and txt into the value attribute, php unpacks it into 2 db fields
selObj.options[i].value = val;
sendCt +=1;
}
}
resultDisplay("Link count: "+sendCt);
var formElement = document.getElementById("bmInputForm");
var formData = new FormData(formElement);
var urlX = encodeURI("http://greenfloyd.org/greenfloyd/php/bm_input_xml.php?sid="+Math.random());
xmlObj = GetXmlHttpObject();
xmlObj.open("POST", urlX, false);
xmlObj.send(formData);
// pause echo "<return err='$err' msg='$msg'></return>";
try
{
xmlDoc = xmlObj.responseXML;
var returnNode = xmlDoc.getElementsByTagName("return");
err = ( returnNode[0].getAttribute("err") == "1" ) ? true : false;
msg = unescape(returnNode[0].getAttribute("msg"));
}
catch(e)
{
msg = "bmSub status : "+e+"<br>xml: "+xmlObj.statusText+", "+xmlObj.status+", size: "+xmlObj.responseText.length;
err = true;
}
resultDisplay(msg);
if ( err ) return;
</code>
In my entity (A) has 50 option set. If the user select 10 optionsset value and not selected remaining one, and he/she click save button. In that situation i need to alert user "To fill all the option set". I don't want to get the Schema name for the optionset individually, i need to get all the option set schema name dynamically.
Is it possible? Help me.
I have not tested this function, but you can try this and make changes if needed.
function IsFormValidForSaving(){
var valid = true;
var message = "Following fields are required fields: \n";
Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
if (attribute.getRequiredLevel() == "required") {
if(attribute.getValue() == null){
var control = attribute.controls.get(0);
// Cheking if Control is an optionset and it is not hidden
if(control.getControlType() == "optionset" && control.getVisible() == true) {
message += control.getLabel() + "\n";
}
valid = false;
}
}
});
if(valid == false)
{
alert(message);
}
}
Ref: Microsoft Dynamics CRM 2011 Validate required form javascript
Required fields individual alert fire before the on save event. If you wish to prevent the single alert routine for all unfilled option sets you need to remove the requirement constraint and manage the constraint yourself, probably in your on save handler. I’m just writing the idea here (not tested).
// enter all optionsets ids
var OptionSets50 = ["new_optionset1","new_optionset2","new_optionset50"];
var dirtyOptions = [];
function MyOptionSet(id) {
var mos = this;
var Obj = Xrm.Page.getAttribute(id);
var Ctl = Xrm.Page.getControl(id);
Obj.addOnChange(
function () {
if (Obj.getValue() != null)
delete dirtyOptions[id];
else
dirtyOptions[id] = mos;
});
this.GetLabel = function() {
return Ctl.getLabel();
}
if (Obj.getValue() == null)
dirtyOptions[id] = mos;
}
function OnCrmPageLoad() {
for(var x in OptionSets50) {
OptionSets50 [x] = new MyOptionSet(OptionSets50 [x]);
}
Xrm.Page.data.entity.addOnSave(OnCrmPageSave);
}
//check for dirty options and alert
function OnCrmPageSave(execContext) {
var sMsg = "The following Optinsets Are Required: ";
var sLen = sMsg.length;
for(var os in dirtyOptions) {
sMsg += dirtyOptions[os].GetLabel() + "\n";
}
if (sMsg.length > sLen) {
execContext.getEventArgs().preventDefault();
alert(sMsg);
}
}
I am using below code to validate hexadecimal numbers in a text box
$(document).ready(function () {
$('#vbus-id').keyup(function () {
var text_value = document.getElementById("vbus-id").value;
if (!text_value.match(/\b[0-9A-F]\b/gi)) {
document.getElementById("vbus-id").value = "";
// document.getElementById("vbus-id").focus();
var message = "You have entered a invalid id.Vbus id ranges from 0 to F in hexadecimal";
test.innerHTML = message;
}
});
});
If any numbers entered other than 0 to 9 and A to F it will clear the textbox and show a warning message below. But if I add a correct number after that, the warning mesage is not clearing. How to clear the warning message if I enter a valid entry after a wrong entry ?
jsFiddle
You've defined what happens if the form doesn't validate (set the message), but you also need the define what to happens in the opposite case (else):
$(document).ready(function () {
$('#vbus-id').keyup(function () {
var text_value = document.getElementById("vbus-id").value;
if (!text_value.match(/\b[0-9A-F]\b/gi)) {
document.getElementById("vbus-id").value = "";
// document.getElementById("vbus-id").focus();
var message = "You have entered a invalid id.Vbus id ranges from 0 to F in hexadecimal";
test.innerHTML = message;
} else test.innerHTML = '';
});
});
You could try always setting the message to blank first on keyup...
$('#vbus-id').keyup(function () {
test.innerHTML = "";
var text_value = document.getElementById("vbus-id").value;
...
I'm trying to validate different parts of a form separately. Unfortunately, the form is generated by a CMS, so I'm limited in my manipulation.
I've tried creating an array of validate objects, using the current form section as an index. Ie:
//initialize validation
validators = [
$('#donation_amount').validate({ rules:{ amount: { required: true } } }),
$('#personal_information').validate({ rules:{ Street: { required: true } } })
];
and shifting through the sections like so:
$('#btn-next').click(function() {
//if validation is true, show next page
if (validators[curOrder].valid()) {
var old = $('.active');
var oldOrder = old.attr('data-order');
var newOrder = parseInt(oldOrder) + 1;
old.removeClass('active');
$("[data-order='" + newOrder + "']").addClass('active');
curOrder = newOrder;
}else{
console.log("invalid");
}
});
The validation, however, is always returning true.
Here's the page in question: https://salsa3.salsalabs.com/o/50388/p/salsa/donation/common/public/?donate_page_KEY=8461
Why are you even using .validate plugin when you are writing a little javascript yourself. On click, just check the value of the inputs (like $('#myInput').val().trim() == "") and show/hide the respective error div against each input.
Further, for multipart validation, validate only the required fields and continue what is supposed to.
$('#btn-next').click(function() {
var amountValid = $('#donation_amount').val().trim() == '' ? false : true;
var infoValid = $('#personal_information').val().trim() == '' ? false : true;
if (amountValid && infoValid) {
var old = $('.active');
var oldOrder = old.attr('data-order');
var newOrder = parseInt(oldOrder) + 1;
old.removeClass('active');
$("[data-order='" + newOrder + "']").addClass('active');
curOrder = newOrder;
}else{
console.log("invalid");
}
});