I have quite a few input elements on a page that a user can change. I don't want to submit a form. I just want the database value to be changed after the user changes the value inside one of the elements.
I'm currently experimenting with binding focusout to each of the inputs. Is this the way it's usually done (facebook, etc..)?
$('input').focusout(function() {
var current_val = $(this).val();
var preset_val = $(this).attr('rel');//attribute set with original value
if (current_val !== preset_val) {
alert ('Value changed.');//where I would post to php page to update database
}
});"
The way it is "usually done" is to wait until the user clicks a button to save or commit the changes. If you're going to update each change, you should make sure to be very clear about that to the user.
The appropriate event to use will be dictated by how aggressive you want to be in capturing changes. For per-keystroke updates, keyup would be appropriate for inputs, click for selects and radios/checkboxes. Less aggressive would be blur or change.
One way to be extremely proactive about capturing any possible change is to attach a click and a keyup to the form element itself. This will also save the overhead of adding a listener to every element. Each time an event is fired on the form, you can either a) check the original target, or b) ajax the entire form, or c) loop all the elements and detect changes, only ajax changed fields.
onbeforeupload can be used to do a final check of the form in case the window is closed, as well, but that's probably being a little too hyper.
Documentation
https://developer.mozilla.org/en-US/docs/DOM/HTMLFormElement
https://developer.mozilla.org/en-US/docs/DOM/element.onkeyup
https://developer.mozilla.org/en-US/docs/DOM/element.onchange
https://developer.mozilla.org/en-US/docs/DOM/element.onblur
https://developer.mozilla.org/en-US/docs/DOM/element.onclick
Related
I added some js code when html loaded. Like below
var form = $('form');
$(':input').change(function() {
if ($('[name=form-update-detector]', form).length == 0) {
$(form).prepend('<input type="hidden" name="form-update-detector"/>')
}
$('[name=form-update-detector]', form).val('true');
});
It works.
My question is when I detect form values have changed, how can I warn users when they click other elements (bound a redirect event) without saving this form?
The elements which bind the event may be <a></a>, <p></p> or any others. The code may be onclick="someEvent()" or $('#someId').on('click',function(){}) or a href etc.
You can store the initial values (when the form is loaded) in a variable say cleanData and the when the user clicks the other element on which you have some other action attached, you can first take the form data in another variable say dirtyData, then compare these two and if equal then proceed to the action attached on the element clicked, else show a warning.
I'm working with jQuery.payment on a credit card number text input field. When the user enters any 4th number (4, 8, 12) the plugin automatically puts in a space for a nice look. Because of this, only the keyup event fires, not the input event. However, if the user were to right-click and paste a value in, then only the input event fires. So we have cases where it's one or the other, or both events firing.
I have a bound anonymous function for change keyup input to ensure all use-cases are covered, but I want the function to only run once each time the key is pressed, but normal key presses fire both keyup and input. jQuery's .one() is not an option because this function needs to run more than once, just not twice for one key press. How can I make sure this function only runs once even when both events are fired from one key press?
I know I could edit jQuery.payment and trigger the input event, but I don't want to modify vendor plug-ins, in case I decide to change versions or something down the road.
You could play around with attaching/detaching event handlers all day and never hit on a successful formula.
If your event handler was idempotent (for a given input state), then you wouldn't need to worry about triggering it twice.
If the handler is not naturally idempotent, then you can include a condition which ensures that a second successive call, with the same input value, does nothing. It's slightly contrived, but this can be regarded as "forced idempotence".
To achieve this, the input element's "last state" (its value) needs to be stored, read back and tested.
You could store the state in some outer/global javascript var but it's neater to use a '.data()' property of the element itself (which is actually 100% js, not pushed into the DOM).
$(function() {
$("#myInput").on("keyup input", function(e) {
var $this = $(this),
$lastState = $this.data('lastState') || '',//read back the element's previous state (or empty string if this is the first call)
val = $this.val();//current state
if(val !== $lastState) {//the all-important test.
$this.data('lastState', val);//store current state to be read back at next call
//here do whatever is required of your event handler.
}
});
});
I would use jQuery change event and always make sure the event was not binded before. And i would not follow a logic like "when user presses the 4th digit". Instead i would format the whole text every time.
function MyInputChanged(){
var currentText = $("#myInput").val();
var newText = someFunctionToFormatText(currentText);
$("#myInput").val(newText);
}
$("#myInput").unbind("change", MyInputChanged);
$("#myInput").bind("change", MyInputChanged);
I'm new to CRM 2011 so I apologize if the answer is obvious. The entity I made is a form where the user fills out information, some fields are hidden until the meets certain requirements to have them visible.
Example: Were you late? Yes/No
(hidden until yes is selected)Reason:
I used javascript to make them invisible at the start and then make them visible if the requirements are met. After the user presses the save button, the field "Reason" would go back to being invisible, is there a way to make it stay visible?
Thanks
You'll have to write javascript code in the onLoad event to see if the field's values are already in a state that would result in the fields being visible. After the entity is saved, it reloads itself, incase a plugin happened to edit an attribute.
If you already attached your function to the attribute onchange event you need to add the following to your onload event:
//Will fire all functions connected to the attribute change event
Xrm.Page.getAttribute("attribute_name").fireOnChage();
Or directory call the function that implements the code i.e.
//Will only call the specified function.
ShowHideField();
Also you might find it easier to attach to onchange handlers
directly from onload code instead of the form UI i.e.
Xrm.Page.getAttribute("attribute_name").addOnChange(ShowHideField);
And to summarize:
function OnCrmPageLoad() {
var attrObj = Xrm.Page.getAttribute("attribute_name");
attrObj.addOnChange(ShowHideField);
attrObj.fireOnChage(); // OR ShowHideField();
//… more code here
}
function ShowHideField() {
// hide fields depending on yes/no questions …
}
I have a search form that has different elements in it, checkboxes, selects, text fields etc. Each change is accompanied by an ajax call that gets the number of results as a sort of counter. I would like to reset only the previous element that caused the counter to return a value of 0.
I was thinking about keeping track of each change in a variable, and each time the counter evaluates to 0, I would then reset the element that caused the change. I however fear that this could force me to handle all the different elements differently with a lot of code and jumping around.
Is there a possible more elegant solution to the problem that anybody can think of? I would appreciate the help.
I cannot comment your question, but : if I understand correcty, there is a big form, and each change on any element, triggers an ajax call, that returns a resultset.
If this resultset size is zero, then, you want the form to reset to previous value.
That would mean, that only the last-changed value has to be tracked down, and reset ?
In this case, your onchange event callback should use this value to get current form element value, and ID. Then, as the resultset comes back, set back the stored value to that element if there are no rows.
Otherwise, if the form is managed globally, you could always store it with a .clone() call, then .remove() it and .insert() the clone back if the resultset is empty.
PS : i know this solution not really elegant :)
Your AJAX module could return a JSON-Encoded string with the data causing this event to occur (PHP-Function: JSON_encode) and from there on, you can cycle through the erroneous values resetting them and displaying further informations. i.e. "Your E-Mail seems to be invalid".
PHP: See JSON_encode
JavaScript: See getElementsByTagName('input') (or textarea or select)
Note: In case of a select item, you may rather want to change the Attribute "selectedIndex" than "value".
I solved the problem by recording each change to the form with
$("#form_id").on("change", function(event) {
//Event bubbling
type = $(event.target).get(0).type;
selector = $(event.target);
}
Then using the Strategy design pattern (Javascript Strategy Design Pattern), I reset each possible field type accordingly. Example for text field,
var Fields = {
"text": {
resetAction: function(fieldSelector) {
fieldSelector.val('');
}
}
};
//To call the reset action for the type of field,
Fields[type].resetAction(selector);
I had to trigger a change event for hidden fields to have their changes also bubble.
Our webapp has a form with fields and values that change depending on values entered. Each time there is a change event on one of the form elements, we use an expensive AJAX call to update other elements on the page.
This works great for selects, radio buttons and checkboxes. The issue comes in when a user adds content to a text field, and then clicks a link without taking the focus from the text field. The browser moves to a new page, and the contents of the text field are never saved. Is there an easy way to code around this? The AJAX call is too expensive to call with each key press.
Here's an example of my Prototype code at the moment:
$$('.productOption input.text').invoke('observe', 'change', saveChangeEvent);
Have you considered hooking into the window unload() event? Here is a c/p jQuery example using .unload().
$(window).unload(function() {
var input = $("#MyInput"); // Text field to check for
if(input.length > 0)
{
//Ajax call to save data, make sure async:false is set on ajax call.
}
});
This lets you work around making a call on each key press, by making one if they leave the page.
using prototype, you can have a PeriodicExecuter listen while you're typing and sending off an ajax query when nothing has happened for e.g. 2 seconds and value has changed since the last AJAX request. Start the executor using a focus event and shut it down using a blur event, that way you only need one executor at a time