简体   繁体   中英

How can I insert text via button click at the cursor in the most recent textbox used?

I have a form with multiple text boxes and a set of buttons. Using the Javascript below, I am able to click a button and insert text into one of the named boxes.

Is it possible to insert text into the most recent/active textbox when a button is clicked?

Currently I have this, but it's using the specific ID of a text box, rather than the most recently used/active one;

   $( 'input[type=button]' ).on('click', function(){
      var cursorPos = $('#my_text_box').prop('selectionStart');
      var v = $('#my_text_box').val();
      var textBefore = v.substring(0,  cursorPos );
      var textAfter  = v.substring( cursorPos, v.length );
      $('#my_text_box').val( textBefore+ $(this).val() +textAfter );
    });

Example on JSFiddle for more clarity;

http://jsfiddle.net/bd1xf0sj/1/

The idea being that depending upon which text box you're in when the button is clicked, instead of using the ID of a certain textbox. The idea being that the buttons can be clicked and any textbox can be used.

You can create a variable to store the most recent textbox and update it whenever a textbox is focused like this:

let currentInput = $('#text1');
$(document).on('focus', 'textarea', function() {
  currentInput = $(this);
})

Then use this variable to update text just like you're doing with your #my_text_box :

$( 'input[type=button]' ).on('click', function(){
  let cursorPos = currentInput.prop('selectionStart');
  let v = currentInput.val();
  let textBefore = v.substring(0,  cursorPos );
  let textAfter  = v.substring( cursorPos, v.length );
  currentInput.val( textBefore + $(this).val() + textAfter );
});

Fiddle

Update : Some modification to preserve the cursor position after insert text:

 let currentInput = document.getElementById('text1'); $(document).on('focus', 'textarea', function() { currentInput = this; }) $( 'input[type=button]' ).on('click', function(){ let cursorPos = currentInput.selectionStart; let v = currentInput.value; let textBefore = v.substring(0, cursorPos ); let textAfter = v.substring( cursorPos, v.length ); currentInput.value = textBefore + this.value + textAfter; cursorPos += this.value.length; currentInput.focus(); currentInput.setSelectionRange(cursorPos, cursorPos); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form> <textarea id="text1" cols="40" rows="3"></textarea> <textarea id="text2" cols="40" rows="3"></textarea> <textarea id="text3" cols="40" rows="3"></textarea> <textarea id="text4" cols="40" rows="3"></textarea> <br> <input type="button" value="one" /> <input type="button" value="two" /> <input type="button" value="three" /> </form>

You can track the current state of the inputs focus using a data-attribute set to a boolean value true or false within the input elements HTML.

Start by defining the first data-current attribute to true , every other one to false . This way there is a default setting to true . Then we run an event to check focus on the textarea elements. If the textarea is focused on, we remove all instances of the selectors data-current values and set them all to false , we then set our current event targets data-current value to true .

Then on the click event for the buttons , we check our textarea element iterating over them and run a conditional that checks their data-current value , we find the one set to true and then assign its value to the buttons value .

 $('textarea').focus(e => { let $this = e.target; $('textarea').each((i, el) => { if(el.dataset.current === 'true'){ el.dataset.current = false; } $this.dataset.current = true; }) console.log(`Selected TextArea's id: ${$this.id}`) }) $('input[type=button]').click(function(){ const $this = $(this); const $ta = $('textarea'); $ta.each((i, el) => { // do not retain previously set values when a new button // is selected on a different focused textarea el.dataset.current === 'true'? el.value = $this.val(): el.value = ''; /* // retain previously set values in TA's on button click // when new textarea is focused el.dataset.current === 'true'? el.value = $this.val(): null; */ }) })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form> <textarea id="text1" data-current="true" cols="40" rows="3"></textarea> <textarea id="text2" data-current="false" cols="40" rows="3"></textarea> <textarea id="text3" data-current="false" cols="40" rows="3"></textarea> <br> <input type="button" value="one" /> <input type="button" data-current="false" value="two" /> <input type="button" data-current="false" value="three" /> </form>

It's actually a simple and fun exercise to solve, there are many approaches to solve this particular problem, though I will suggest mine.

Here's the link to solved jsFiddle example.

Explanation:

Step 1: Add focus event listener on all textarea .

Step 2: On textarea focused, remove the class last-focused from existing last-focused.textarea elements.

Step 3: Add last-focused class to currently focused textarea element.

Step 4: Add click listener on button

Step 5: On button clicked, select last-focused.textarea element, and replace its content with the button's value.

Note: we can use any name for class, just given the name as last-focused , as it relates to the current context.

HTML:

<form>
  <textarea id="text1" cols="40" rows="3"></textarea>
  <textarea id="text2" cols="40" rows="3"></textarea>
  <br>
  <input type="button" value="one" />
  <input type="button" value="two" />
  <input type="button" value="three" />
</form>

JS + JQuery:

// Step 1
$('textarea').on('focus', function() {
    // Step 2
    $('textarea.last-focused').removeClass('last-focused');
    // Step 3
    $(this).addClass('last-focused');
});

// Step 4
$('input[type=button]').on('click', function() { 
    // Step 5
    $('textarea.last-focused').html($(this).val());
});

You can track last focused input element with focus event of textarea elements and append last active element's value when button clicked:

var mostrecent=$('textarea')[0];
$('textarea').each(function(i,item){
  $(item).focus(function(){
    mostrecent=this;
  });
});

 var mostrecent=$('textarea')[0]; $('textarea').each(function(i,item){ $(item).focus(function(){ mostrecent=this; }); }); $( 'input[type=button]' ).on('click', function(){ var cursorPos = $('#text1').prop('selectionStart'); var v = $('#text1').val(); var textBefore = v.substring(0, cursorPos ); var textAfter = v.substring( cursorPos, v.length ); $(mostrecent).val( textBefore+ $(this).val() +textAfter ); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form> <textarea id="text1" cols="40" rows="3"></textarea> <textarea id="text2" cols="40" rows="3"></textarea> <br> <input type="button" value="one" /> <input type="button" value="two" /> <input type="button" value="three" /> </form>

Hook into form events to mark the most recent input as "recent" (using some class) and unmark all other inputs. On click modify the "recent" input.

Most likely you'll need onfocus , but might be onchange depending on your specific use case.

The currently selected field is document.activeElement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM