I have an input type="text" in a table. https://jsfiddle.net/L0vx0hck/
$('#myGrid').selectable({
filter: ".dataItemColumn,.dataText",
cancel: null,
distance: 10
});
td {
padding: 5px;
border: 1px solid black
}
.ui-selected {
background-color: lightblue
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myGrid">
<tr>
<td class="dataItemColumn">
<input class="dataText" type="text" value="focusable" onclick="this.focus()" />
</td>
<td class="dataItemColumn">
<input type="text" class="dataText" value="aa" />
</td>
</tr>
<tr>
<td class="dataItemColumn">
<input type="text" value="focusable" onclick="this.focus()" />
</td>
<td class="dataItemColumn">
<input type="text" value="aa" />
</td>
</tr>
</table>
<input type="text" value="test" />
<table id="myGrid">
<tr>
<td class="dataItemColumn">
<input type="text" class="dataText" value="aa" />
</td>
</tr>
I am making it selectable
$('#myGrid').selectable({
filter: ".dataItemColumn,.dataText",
cancel: null,
distance: 10
});
After this it is not possible to click into an input to start editing. As a partial workaround I am setting onclick="this.focus()" on the input. It is also possible to omit cancel: null. The first option allows to start editing only on the begging of text and disallows selecting part of text. The other option gives full editing capabilities but disallows starting selection by dragging over a textbox.
So what I need:
be able to select textboxes (or their containers td) by dragging
even if dragging starts on a textbox
be able to start editing by
clicking to any place of a textbox
Selecting a part of a text with the mouse would be also useful but not necessary.
The problem is that most jquery-ui widget have the same mouseDown handler that has a preventDefault() command. While this is ok for most widgets, it's true that selectable could be activated a bit later.
You could override the mouse events for selectable and put more conditions. Based on your requirement you have these 2 conditions:
if the mousedown is on an input element, default shouldn't be
prevented.
if the mouse drag is happening only on an input, the selectable
drag event shouldn't be triggered.
Something like this should give you some ideas:
$.ui.selectable.prototype._mouseMove = function(event) {
...
// you add the target vs mousedown selection condition here.
// Baiscally if the mousedrag target is the same as mouse down target
// And the target was an input, then you dont run mouseStart()
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event) && (this._selection !== event.target || !this._targetIsInput)) {
this._mouseStarted =
(this._mouseStart(this._mouseDownEvent, event) !== false);
(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
}
...
}
$.ui.selectable.prototype._mouseDown = function(event) {
....
this._selection = event.target;
this._targetIsInput = event.target.tagName === 'INPUT';
if(!this._targetIsInput){
event.preventDefault();
}
...
}
https://jsfiddle.net/z1rjnspt/2/
I left out the mouseHandled here to simplify, but you could handle it as well.
Obviously this changes a lot selectable, so if you have a limited set it might work, but if you want to make this safer, you should maybe create a new widget.
Related
I have a table, with 2 labels/inputs (i use a ng-show/ng-hide which works with the edit button), and 2 buttons (1 button is edit, and 1 button is delete). What i want to do is when the user clicks the edit button, it should hide the spans and shows the inputs(textboxes) and focus on the first input. If the user clicks outside of either inputs, (in my opinion, loses focus which mean using blur method), then the inputs should turn back to span with the updated values. Here is what I have created, but I can't figure out the rest. New to angular so any help will be appreciated and voted.
This is the html code:
<table class="tableGV">
<tbody>
<tr>
<td class="DisplayRowData">
<span class="LabelText" data-ng-hide="data1">{{data1}}</span>
<input class="DataText" type="text"data-ng-show="showEditMode" maxLength="1" data-ng-model="editData1" ng-change="cs.ClassCode"/>
</td>
<td class="DisplayRowData">
<span class="LabelText" data-ng-hide="data2">{{data2}}</span>
<input class="DataText" type="text" data-ng-show="data2" maxlength="50" data-ng-model="data2" />
</td>
<td align="right">
<button type="button" id = "btnEditClassService{{$index}}" data-ng-click="edit(cs, $index)" class="editButton"></button>
<button type="button" id = "btnDeleteClassService{{$index}}" data-ng-click="delete(cs, $index)" class="deleteButton"></button>
</tr>
</tbody>
</table>
after this, i am not sure where to go. Thanks for anyone to help me.
you can check this plnkr. The solution is not elegant but I think it sastify your requirement.
function onEdit(){
vm.isEdit = true;
executeAfterDOMRender(function(){
document.getElementById('txt1').focus()
});
}
function onBlur(){
executeAfterDOMRender(function(){
var txtIds = ['txt1', 'txt2'];
var activeElementId = document.activeElement.id;
if(~txtIds.indexOf(activeElementId)){
//txt boxes is focued, do nothing here
} else {
vm.isEdit = false;
}
});
}
function executeAfterDOMRender(callback){
$timeout(callback);
}
I have a shopping cart that contains a form field and a checkbox in each row. The form field controls the quantity, which can be edited, if the customer wants to modify the quantity of the product they order, and the checkbox selects the item, either to toss the item in a wish list, or to remove it. The Add To Wish list and Remove Functions are separated out of this particular question.
What, I am looking at doing, is detecting when the form has been changed, and then targeting EVERY anchor tag and button on the page, so if the items have been modified, the script stops the click through and pops up a bootstrap modal, alerting the user that something in their cart has been modified.
HTML (the shopping cart row, run through a JSTL forEach loop, but the markup is this):
<table>
<form id="shoppingCart" action="updateTheCart.action">
<c:forEach var="item" items="${shoppingCart.items}" varStatus="status">
<tr class="cart-row">
<td class="remove" data-label="Remove">
<label>
<input type="checkbox" name="removeFlag(<c:out value="${status.count}"/>)" value="true"/>
</label>
</td>
<td class="title" data-label="Title">
${item.value.sellableGood.name}
</td>
<td class="qty" data-label="Quantity">
<input type="num" class="form-control qty-input" name="quantity(<c:out value="${status.count}" />)" value="<c:out value="${item.value.quantity}" />"/>
</td>
<td class="subtotal" data-label="Line Total">
<fmt:formatNumber type="currency" pattern="$#,##0.00" value="${item.value.itemExtendedTotal}" />
</td>
</tr>
</c:foreach>
</table>
<p>Checkout</p>
<p><button type="submit" id="checkout">Update Cart</button></p>
<p><button id="addToWishlist" type="submit" id="wish-list">Add To Wish List</button></p>
<p>Chontinue Shopping</p>
</form>
JS:
$("#shoppingCart :input").change(function() {
$("#shoppingCart").data("changed",true);
});
I know I am missing a LOT, but I really don't know where to begin at this point.
You can try the onbeforeunload Event
$('input').change(function() {
if( $(this).val() != "" )
window.onbeforeunload = "Are you sure you want to leave?";
});
Javascript:
;[].forEach.call(document.querySelectorAll('a, button'), function(element) {
//do something with buttons and links, for example:
element.setAttribute('data-changed', true')
});
The jquery equivalent is:
$('a, button').each(function(element) {})
To watch the form for changes, I would use the blur event, it's the reverse of focus:
;[].forEach.call(document.querySelectorAll('#myForm input'), function(element) {
element.addEventListener('blur', function(event) {
//something has changed
})
});
Jquery:
$('#myForm input').on('blur', function(event) {})
I have a long form that is broken into sections that are in jquery accordion panels. When the user is done filling in the form in one panel they go to the next panel and fill in the form there. The accordion breaks the long form into steps. But, when the user completes the last input on one panel pressing the tab key won't take them to the next field, in the next panel, unless I do it programmaticly. For the inputs that are type text, the following code works well. But, where the inputs are type radio it is not working. This following code first assigns the keydown function to a text box, then fails to assign it to a set of three radio buttons, then succeeds again to assign it to a text box.
What's frustrating is that if I copy and paste the middle block into the chrome javascript console then it will work like a charm.
So, what's the problem?
document.onReady(function(){
$('#f-phone').keydown(function(e){
var code = e.keyCode || e.which;
if ( code === 9) {
my_accordion.accordion("option", "active", 3);
}
});
$('input[name=shipping_method]').keydown(function(e){
var code = e.keyCode || e.which;
console.log('code is '+code);
});
$('#f-special_instructions').keydown(function(e){
var code = e.keyCode || e.which;
if ( code === 9) {
my_accordion.accordion("option", "active", 5);
}
});
});
HTML follows:
<div class="row">
<label class="req" for="f-shipping_phone" id="label-shipping-phone">Phone (Recipient)<span style="color:red;">*</span> </label>
<input type="text" name="shipping_phone" size="35" maxlength="35" autocomplete="telephone-full" class="addr_phone" id="f-shipping_phone" />
</div>
<h2 id="ship-options" id="h2_shipping">Shipping Options</h2>
<div class="rowSet" id="checkout-shipping-level">
<div class="row" id="shipping_type">
<table cellpadding="0" cellspacing="0" style="width:300px">
<caption>Times are estimates once shipped.</caption>
<tr align="center" valign="top">
<td>
<input name="shipping_method" type="radio" value="4" id="ship4" >
</td> <td>
<label for="ship4">Standard</label>
</td>
</tr>
<tr align="center" valign="top">
<td>
<input name="shipping_method" type="radio" value="7" id="ship7" checked="checked">
</td> <td>
<label for="ship7">Saver</label>
</td>
</tr>
<tr align="center" valign="top">
<td>
<input name="shipping_method" type="radio" value="2" id="ship2" >
</td> <td>
<label for="ship2">Expedited</label>
</td>
</tr>
</table>
</div>
Here is the updated jQuery script:
$(document).ready(function(){
$('#f-phone').keydown(function(e){
var code = e.keyCode || e.which;
if ( code === 9) {
my_accordion.accordion("option", "active", 3);
}
});
$('input:radio[name=shipping_method]').keydown(function(e){
var code = e.keyCode || e.which;
console.log('code is '+code);
alert('code is '+code);
});
$('#f-special_instructions').keydown(function(e){
var code = e.keyCode || e.which;
if ( code === 9) {
my_accordion.accordion("option", "active", 5);
}
}); });
You can check it in fiddler: here
You are attaching only "keydown" event to the radio buttons. You might as well attach "click" or "change" events to the radio buttons.
I noticed that even when I apply the handler via the javascript console it will disappear upon closing that accordion panel. So, I believe there is no solution to this one unless it is handling the keystrokes at a different level, as one commenter posted.
I have a problem with a form in IE. I have disabled fields in form i,e. field having property disabled="disabled". These fields show the input text in grey color and that looks very dull/blurred and if i try apply css changes to such fields, it will not work for IE, but works for other browsers like chrome, firefox.
Is there any way to make the text to better font color here?
I thought one way of doing this is removing property disabled="disabled" and add property readonly="readonly" with javascript. If this is possible then how can i do this with Javascript. I am new to Javascript, so please help me
Below HTML to explain the behaviour. Run this in both IE and other browser to see the difference.
<html>
<head>
<style type="text/css">
.col {
background-color: yellow;
color: red;
}
</style>
</head>
<body>
<table>
<tr>
<td>Editable field: </td>
<td>
<input type="text" id="editable-field-id" value="Editable field" class="col"/>
</td>
</tr>
<tr>
<td>Disabled field: </td>
<td>
<input type="text" disabled="disabled" id="disabled-field-id" value="Disabled field" class="col" />
</td>
</tr>
<tr>
<td>Readonly field: </td>
<td>
<input type="text" readonly="readonly" id="readonly-field-id" value="Readonly field" class="col"/>
</td>
</tr>
</table>
</body>
</html>
I am testing this in IE9.
You can change disabled input fields into readonly ones by using the .prop() method available in jQuery. I typically discourage the use of .attr(), and this is why.
$(function (){
$('input').prop({
'disabled': false,
'readonly': true
});
});
Although the method .removeProp() is available, documentation encourages refrain when using it, because, to quote, it "will remove the property completely and, once removed, cannot be added again to element. Use .prop() to set these properties to false instead."
View demo here: http://jsfiddle.net/teddyrised/tE98z/
document.getElementById("your_field").readOnly=true;
or, with jQuery:
$('#your_field').attr('readonly', true);
<html>
<head>
<style type="text/css">
.col {
background-color: yellow;
color: red;
}
</style>
</head>
<body>
<table>
<tr>
<td>Editable field: </td>
<td>
<input type="text" id="editable-field-id" value="Editable field" class="col"/>
</td>
</tr>
<tr>
<td>Disabled field: </td>
<td>
<input type="text" disabled="disabled" id="disabled-field-id" value="Disabled field" class="col" />
</td>
</tr>
<tr>
<td>Readonly field: </td>
<td>
<input type="text" readonly="readonly" id="readonly-field-id" value="Readonly field" class="col"/>
</td>
</tr>
</table>
<script type = "text/javascript">
document.getElementById("disabled-field-id").disabled = false;
document.getElementById("disabled-field-id").readOnly = true;
</script>
</body>
</html>
Use the setAttribute property. Note in example that if select 1 apply the readonly attribute on textbox, otherwise remove the attribute readonly.
http://jsfiddle.net/baqxz7ym/2/
document.getElementById("box1").onchange = function(){
if(document.getElementById("box1").value == 1) {
document.getElementById("codigo").setAttribute("readonly", true);
} else {
document.getElementById("codigo").removeAttribute("readonly");
}
};
<input type="text" name="codigo" id="codigo"/>
<select id="box1">
<option value="0" >0</option>
<option value="1" >1</option>
<option value="2" >2</option>
</select>
if you disable the inputs programmatically can set style as you want
try it:
//bloqueo todos los radiobuttons y checkboxs
//block all radiobuttons and checkbox
jQuery(document).on("change", 'input:checkbox.yourClass,input:radio.yourClass', function () {
jQuery(this).prop("checked", false);
});
//bloqueo campos de texto
//block all text fields
jQuery(document).on("focusin", 'input.yourClass, textarea.yourClass', function () {
jQuery(this).blur();
});
//bloqueo selects
//block all selects
jQuery(document).on("focusin", 'select.yourClass', function (event) {
var $selectDiabled = jQuery(this).attr('disabled', 'disabled');
setTimeout(function(){ $selectDiabled.removeAttr("disabled"); }, 30);
});
if you want set style they aren't technically disabled
here can see the original code: https://jsfiddle.net/9kjqjLyq/
You need to depend on a pure javascript(preferrably jQuery) solution.
Add a custom attribute to all your controls:
<input type="text" disabled="true" />
Now you can check if they are disabled and you can proceed to block them using javascript:
var value = yourTextBox.value; //the last value that the control holds,
//before it was disabled?
$('yourTextBox').click(function() {
value = $(this).value;
});
$('yourTextBox').blur(function() {
if($(this).attr('disabled') == 'true')
$(this).value = value;
});
To add more strictness, add another function:
$('yourTextBox').keypress(function() {
if($(this).attr('disabled') == 'true')
$(this).value = value;
});
If you want something simple, I would recommend this:
$('yourTextBox').keypress(function() {
if($(this).attr('disabled') == 'true')
return false;
});
I have a fairly long form on a page with various checkboxes and text boxes. There is one point where I want a text box to become available if a corresponding checkbox is ticked. I almost have it working with this code:
<tr class= "formspace">
<td class="formleft" valign="top" style="line-height:22px">Extra bed(s)?</td>
<td colspan="2"><input name="extrabed" type="checkbox" value="1" onChange="jsextrabed()"><?php echo $lang["extraadultx"]." ".$lang["notsingleoccx"];?>
<div id="extrabednumber"></div>
<script type="text/javascript">
function jsextrabed() {
if(document.roomnew.extrabed.checked == 1) {
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="1">';
}else{
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="0">';
}
}
</script>
</td>
</tr>
When the page first opens, only the checkbox shows.
When I tick the checkbox, the text box opens with a value of 1. So far, so good.
When I click again the checkbox is unticked and the value in the text box changes to 0. Still good.
When I click yet again the checkbox is ticked (good) but the value in the text box stays at 0 (bad!).
Further clicking toggles the checkbox but has no effect on the value in the text box.
What have I done wrong?
use this code for check:
if(document.roomnew.extrabed.checked) {
Just check with
if(document.roomnew.extrabed.checked){
}
else
{
}
There is no problem in the displayed code.
Here's a working demonstration : http://jsfiddle.net/dystroy/u6mtW/
HTML :
<tr class= "formspace">
<td class="formleft" valign="top" style="line-height:22px">Extra bed(s)?</td>
<td colspan="2"><input name="extrabed" id=checkextra type="checkbox" value="1" >some php
<div id="extrabednumber"></div>
</td>
</tr>
Javascript :
<script>
window.onload=function(){
document.getElementById('checkextra').onchange = function() {
if(this.checked) {
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="1">';
}else{
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="0">';
}
};
};
</script>
I made a few changes to
adapt to the fact that we don't have the whole DOM. Your problem may be there, in the parts we don't see.
ensure the function is correcly hooked on the checkbox (you may have a problem of not fully loaded DOM, depending on your page)
Problem solved!
I was using the same name for two elements: both the checkbox input and the text box input (in the innerHtml were called "extrabed". Changing one of those has fixed it.
Thanks to all of you who offered help.