4

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.

IvanH
  • 5,039
  • 14
  • 60
  • 81

1 Answers1

0

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.

Julien Grégoire
  • 16,864
  • 4
  • 32
  • 57