Is there a "simple" way to ensure that ALL the inputs in a form have "an entry". I need/want to disable the submit button unless all inputs have a value they are all input type=text. I assume it is something like for each but I am not very good at the for each in JQuery. Possible problem is that the inputs are "dynamically" generated by sortables? All I need to know is is there a value in every input field. The "real" validation is done elsewhere.
So is it something like:
$j('#button').click(function (){
each(function(:input){
//check the length in here?
});
});
Is this post useful http://forum.jquery.com/topic/enable-disable-submit-depending-on-filled-out-form?
$("#button").click(function(event) {
var valid = true;
$(":input").each(function(index) {
if ($(this).val().length == 0) {
valid = false;
}
});
if (!valid) {
event.preventDefault();
}
});
Should work.
First part grabs the element with id of button, then assigns a function to the onclick event. Second part grabs all input fields, and run a function on each of them. Then you get the length of the value for each.
The $(this) works since the function is being applied to a specific element on the page, and will always get you the current element.
Related
I have a input field that is formatted with the data-format HH:mm:ss PP. When the timepicker is clicked the focus on the input field don't appear that's why I couldn't use onblur event. What i want is like keydown or keyup event but it seems doesn't work in my case because focus is out in the input field so what jQuery event should i used?
change seems to work fine:
Fiddle
$("#datepicker").datepicker()
.on("change", function () {
console.log("Changed");
});
Example is with datepicker(), I'm not sure what your timepicker implementation is as it's not in the jquery(ui) api. But it should work as well.
Edit: after looking at the datetimepicker you are using, based on the DOM I'm seeing as a result of datetimepicker() - I think this should work for you:
Fiddle
$('#datetimepicker1').closest(".well").next(".bootstrap-datetimepicker-widget").on("click", "*", function () {
console.log("Changed");
});
Just make sure this is after your datetimepicker() call. Note that this will be triggered on any click within your calendar/time picker even if it is a click on something that is already selected (no change).
If you want, you could store the last value of your input and then check that if it changed before continuing with this event callback function. If it did change, be sure to update the variable you are holding the "last value" in... something like this.
If possible, the best option would actually be to modify datetimepicker()'s js to call a function or trigger an event from the same place it updates the text input. Looking at the code:
set: function () {
var formatted = "";
if (!this._unset) formatted = this.formatDate(this._date);
if (!this.isInput) {
if (this.component) {
var input = this.$element.find("input");
input.val(formatted);
input.trigger("change"); // added this
this._resetMaskPos(input)
}
this.$element.data("date", formatted)
} else {
this.$element.val(formatted);
this.$element.trigger("change"); //added this
this._resetMaskPos(this.$element)
}
},
With the two lines I added above, you should be able to rely on a change event bound to the input element.
I know how to grab the index, but that doesn't appear to be what I need to post into the tab itself.
This is a continuation, but different question, from my previous post: Submiting jQuery form results back into dynamic tab
My tab form is submitting now with 100% success, internal to my jQuery validate, but I want my reply to appear in the tab it came from.
At the end of my jQuery validation I have:
submitHandler: function(form) {
var thisTab = $tabs.tabs('option', 'selected'); // what index are we?
var options = {
target: '#thisTab',
};
$(form).ajaxSubmit(options);
return false;
}
It's close, but what I'm doing is actually grabbing the index of the selected tab, this does not appear to be what I need for the ajaxSubmit to post into.
As I understand you want to set target to thisTab, but you are setting target as a jQuery selection string #thisTab,
this means target is the element with id "thisTab".
From Jquery Form Plugin API
target
Identifies the element(s) in the page to be updated with the
server response. This value may be specified as a jQuery selection
string, a jQuery object, or a DOM element. Default value: null
So you should set thisTab as the target.
Update : The main problem is that you are trying to set tab as target element, you should set the selectedPanel as target.
submitHandler: function(form) {
var thisPanel = $tabs.tabs('option', 'selectedPanel'); // what index are we?
var options = {
target: thisPanel,
};
$(form).ajaxSubmit(options);
return false;
}
Hum, maybe I wasn't clear and I'm not explaining it.
What I want is for the output of update.cfm to be shown in the same dynamic tab body that held the details I just updated. I tried what you suggested and all it does when I hit submit is blink. It does submit, I can use firebug to see the post and response, but the response is not shown. So I do want the tab as the target.
What you did do however is show me a new term "selectedPanel" that I did not know, and that lead me to this post which I had not seen before: How to get the selected tab panel element in Jquery UI Tabs?
And that led me to make the following change:
submitHandler: function(form) {
var selectedPanel = $("#tabs div.ui-tabs-panel:not(.ui-tabs-hide)");
var options = {
target: selectedPanel
};
$(form).ajaxSubmit(options);
return false;
}
I have buttons that trigger jQuery validation. If the validation fails, the button is faded to help draw attention away from the button to the validation messages.
$('#prev,#next').click(function (e)
{
var qform = $('form');
$.validator.unobtrusive.parse(qform);
if (qform.valid())
{
// Do stuff then submit the form
}
else
{
$('#prev').fadeTo(500, 0.6);
$('#next').fadeTo(500, 0.6);
}
That part works fine.
However, I would like to unfade the buttons once the invalid conditions have been cleared.
Is it possible to hook into jQuery Validation to get an appropriate event (without requiring the user to click a button)? How?
Update
Based on #Darin's answer, I have opened the following ticket with the jquery-validation project
https://github.com/jzaefferer/jquery-validation/issues/459
It might sound you strange but the jQuery.validate plugin doesn't have a global success handler. It does have a success handler but this one is invoked per-field basis. Take a look at the following thread which allows you to modify the plugin and add such handler. So here's how the plugin looks after the modification:
numberOfInvalids: function () {
/*
* Modification starts here...
* Nirmal R Poudyal aka nicholasnet
*/
if (this.objectLength(this.invalid) === 0) {
if (this.validTrack === false) {
if (this.settings.validHandler) {
this.settings.validHandler();
}
this.validTrack = true;
} else {
this.validTrack = false;
}
}
//End of modification
return this.objectLength(this.invalid);
},
and now it's trivial in your code to subscribe to this event:
$(function () {
$('form').data('validator').settings.validHandler = function () {
// the form is valid => do your fade ins here
};
});
By the way I see that you are calling the $.validator.unobtrusive.parse(qform); method which might overwrite the validator data attached to the form and kill the validHandler we have subscribed to. In this case after calling the .parse method you might need to reattach the validHandler as well (I haven't tested it but I feel it might be necessary).
I ran into a similar issue. If you are hesitant to change the source as I am, another option is to hook into the jQuery.fn.addClass method. jQuery Validate uses that method to add the class "valid" to the element whenever it is successfully validated.
(function () {
var originalAddClass = jQuery.fn.addClass;
jQuery.fn.addClass = function () {
var result = originalAddClass.apply(this, arguments);
if (arguments[0] == "valid") {
// Check if form is valid, and if it is fade in buttons.
// this contains the element validated.
}
return result;
};
})();
I found a much better solution, but I am not sure if it will work in your scenario because I do not now if the same options are available with the unobtrusive variant. But this is how i did it in the end with the standard variant.
$("#form").validate({
unhighlight: function (element) {
// Check if form is valid, and if it is fade in buttons.
}
});
Edit formatter action button is placed to jqgrid column:
colModel: [{"fixed":true,"label":" change ","name":"_actions","width":($.browser.webkit == true? 37+15: 32+15)
,"align":"center","sortable":false,"formatter":"actions",
"formatoptions":{"keys":true,"delbutton":false,"onSuccess":function (jqXHR) {actionresponse = jqXHR;return true;}
,"afterSave":function (rowID) {
cancelEditing($('#grid'));afterRowSave(rowID,actionresponse);actionresponse=null; }
,"onEdit":function (rowID) {
if (typeof (lastSelectedRow) !== 'undefined' && rowID !== lastSelectedRow)
cancelEditing($('#grid'));
lastSelectedRow = rowID;
}
}}
New row is added to jqgrid in loadcomplete event
var newRowData = {};
var newRowId = '_empty' + $.jgrid.randId();
$('#grid').jqGrid('addRowData', newRowId, newRowData);
and its id is updated if save action button is clicked:
function aftersavefunc(rowID, response) {
restoreActionsIcons();
$('#grid').jqGrid('resetSelection');
var json = $.parseJSON(response.responseText);
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
}
After clicking save action button edit action button clicks are ignored. It is not possible to re-enter to edit mode after first editing.
How to fix this so that row can edited by edit button click again after saving ?
Update
I added $(this).focus() as suggested in Oleg answer and also wrapped id change into setTimeout as Oleg recommends in other great answer:
function aftersavefunc(rowID, response) {
restoreActionsIcons();
$(this).focus();
$('#grid').jqGrid('resetSelection');
var json = $.parseJSON(response.responseText);
setTimeout(function () {
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
}, 50);
}
Problem persists. The problem may related to row id change since:
It occurs only in last row (where id is changed after save). It does not occur for saved rows where responseText returns same id and row id is actually not changed.
It does not occur if cancel action button is pressed.
Maybe row id needs additional reset id addition to resetSelection or needs updated in somewhere other place also.
Update2
I added code form updated answer to errorfunc and used only english characters and numbers id ids. This allows to click multiple times but introduces additional issue:
extraparam is no more passed. If rowactions() calls are commented out, extraparam is passed with with rowactions calls extraparam is not passed.
I changed jqGrid source code and added alert to rowactions method:
alert( cm.formatoptions);
if (!$.fmatter.isUndefined(cm.formatoptions)) {
op = $.extend(op, cm.formatoptions);
}
In first clicks alert outputs 'Object'. In succeeding clicks to Save button it outputs undefined. So for unknown reason formatoptions is cleared.
Remarks to comment:
Absolute url in testcase is not used. Datasource is set to localarray.
I verified that testcase works in IE and FF without external url access.
For extraparam issue I can create new testcase.
Without image directory buttons are shown in cursor is moved over them.
Missing image directory still allows to reproduce the issue.
FormData function is defined in js file.
Since new issue occurs after adding rowactions() calls and does not occur if those calls are removed, this seems to be related to the code proposed in answer.
I suppose that the problem exist because one hide a button which has currently focus. Look at the code from the answer. If one remove the line $(this).focus(); // set focus somewhere one has the same problem as you describes. So I suggest that you just try to set somewhere, for example in restoreActionsIcons the focus to any the table element of the grid after hiding the button having currently the focus. I can't test this, but I hope it will help.
UPDATED: I examined your problem one more time and I hope I can suggest you a solution.
You problem can be divided on two sub-problems. The main your problem is the the changing of the id of the row. So it is not common problem which everybody has.
The problem is that "actions" formatter create onclick functions directly in the HTML code (see for example here):
ocl = "onclick=$.fn.fmatter.rowactions('"+rowid+"','"+opts.gid+"','edit',"+opts.pos+");..."
So the functions will contains the original rowid. To fix the problem you can modify the code fragment of your aftersavefunc inside of setTimeout from
$("#" + rowID).attr("id", json.Id);
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
to something like the following:
var $tr = $("#" + rowID),
$divEdit = $tr.find("div.ui-inline-edit"),
$divDel = $tr.find("div.ui-inline-del"),
$divSave = $tr.find("div.ui-inline-save"),
$divCancel = $tr.find("div.ui-inline-cancel");
$tr.attr("id", json.Id);
if ($divEdit.length > 0) {
$divEdit[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','edit',0);
};
}
if ($divDel.length > 0) {
$divDel[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','del',0);
};
}
if ($divSave.length > 0) {
$divSave[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','save',0);
};
}
if ($divCancel.length > 0) {
$divCancel[0].onclick = function () {
$.fn.fmatter.rowactions(newId,'grid','cancel',0);
};
}
lastSelectedRow = json.Id;
$("#grid").jqGrid('setSelection', lastSelectedRow);
The second problem is that you use special characters inside of ids. I found a bug in the $.fn.fmatter.rowactions which need be fixed to support special characters in ids. The problem is that in the line 407 of jquery.fmatter.js the original rowid parameter rid will be changed:
rid = $.jgrid.jqID( rid )
and later everywhere will be used modified id. For example in the id is my.id the encoded version will be my\\.id. It's correct for the most places of the $.fn.fmatter.rowactions code (see here), but it' s incorrect as the rowid parameter of the editRow, saveRow, restoreRow, delGridRow, setSelection and editGridRow (see the lines 433-453). So the code must be fixed to use the original not escaped (not encoded) rid value with which the $.fn.fmatter.rowactions was called.
I think I will post tomorrow the corresponding bug report with the suggestions in the trirand forum.
UPDATED 2: The code $.fn.fmatter.rowactions(newId,'grid','edit',0); which I wrote above is just an example. I took it from the test demo which you send me. You should of course modify the code for your purpose. How you can see for example from the line the second parameter of the $.fn.fmatter.rowactions in the id of the grid which you use: 'grid', 'list' of something like myGrid[0].id. The last parameter should be the index of the column having formatter:'actions' in the colModel. You can use getColumnIndexByName function from the answer on your old question to get the index by column name.
I have textbox whose value if entered needs to be validated using some regularexpression
I need to validate the value as user is entering the data.
Which is suitable event can be used for this ? some sample example of using onfocus event on textbox will be helpful
Use onKeypress or onKeyup.
Beginners often think that onChange will do what you want, but that only fires when the input loses the focus.
OnFocus is irrelevant - that is when the box first gets the focus, not when the user types.
Typically you would do this when the text input loses focus, so it would be using the blur event. The reason is that many inputs aren't valid until some sufficient number of characters has been typed. It can be very annoying to the user to put up a validation error while they are still typing a valid string. For example, when doing email validation, the input cannot be valid until the # sign has been entered. Note that you'd also need to validate when the form is submitted to catch the case where the field has never had focus.
Using jQuery it might look like:
$('.klass').blur( function() {
if (!$(this).val().match( /your-regular-expression/ )) {
$(this).next('.validation-message').show();
return false; // keep focus on field
}
return true;
});
This assumes some HTML like
<input type="text" class="klass" name="myInput" />
<span class="validation-message" style="display: none;">This is not valid</span>
To stop the user from writing invalid characters, or to validate the fields as he types you can use .onkeypress.
document.getElementById(fieldId).onkeypress = onkeypressHandler;
var onkeypressHandler = function (event) {
var eKey = event.charCode;
var str = String.fromCharCode(eKey);
var pattern = /[^0-9]/g;
var strTmp = str.replace(pattern, "");
if (str!== strTmp) {
return false;
}
return true;
}
In this example the only valid characters are numbers, if the pressed key is not a number then the function will return false and the key will be ignored.
Also validate a field after the user is done typing you can use .onchange
document.getElementById(fieldId).onchange= onChangeHandler;