Can we use a constructed dynamic jQuery selector? - javascript

I want to contruct a jquery selector as a string and pass its value to the selector.
$(document).on( 'keyup', function( e ) {
if( e.keyCode == 9 ) {
//console.log( e.target );
console.log(e.target.id);
var preTabIndex = document.getElementById(e.target.id).tabIndex;
var nextTabIndex = preTabIndex + 1;
console.log(preTabIndex);
console.log(nextTabIndex);
//console.log($('[tabindex=3]')[0].id);
var selector = "[tabindex=" + nextTabIndex + "]";
console.log(selector);
console.log($(selector)[0].Id);
//document.getElementById($("[tabindex=3]")[0].id).focus();
document.getElementById($(selector)[0].id).focus();
}
} );
Can this be done? I couldn't find it on my initial googling.
With this i am getting an undefined when i do
console.log($(selector)[0].Id);

Yes, you can. Make sure you use the . or # to denote the target. For example,
In your HTML:
<p id="header">hello</p>
In your JS:
var my_selector = "#header";
$(my_selector).html('wow');

Related

How to remove some item based on ID

I am getting all file upload control through the following code
var fileuploadControls = $( "input[type='file']" );
Now I want to loop thorugh the fileuploadControls and remove if ID is not matching something like this
for(var i=0;i<fileuploadControls .length;++i)
{
if(fileuploadControls[i].id != "A")
{
//remove the item and fileUploadcontrols should be same type of abject as returned by the jquery not an array
}
}
I have tried splice it works but it returns an array which I don't want after removal of item fileuploadControls should of same type of object as it was before removal only one item should be less
Can someone help in coding this
I am using the following celltemplate in Angular ui-grid
cellTemplate: '<div class="ui-grid-cell-contents"> <input name="curfewRegularizationFile" id="curfewRegularizationFile" type="file" class="k-state-disabled" /></div>',
and in javascript file I am doing this
fileuploadControls[i].kendoUpload({ // Do something as per kendo});
You can can create a function to remove element
for(var i=0;i<fileuploadControls .length;++i)
{
if(fileuploadControls[i].id != "A")
{
remove(fileuploadControls[i].id);
}
}
function remove(id) {
return (el=document.getElementById(id)).parentNode.removeChild(el);
}
Remove from DOM too:
In your loop you can do it this way:
for(var i = 0; i < fileuploadControls.length; ++i ) {
if( fileuploadControls[i].id !== "A" )
fileuploadControls.eq(i).remove();
}
But I would do it in the jQuery way, in a loop with jQuery objects you can do it with each. But this is even the slowest option to choose.
fileuploadControls.each(function() {
if( $(this).attr("id") !== "A" )
$(this).remove();
});
Or directly as a sub-selector:
fileuploadControls.not("#A").remove();
Remove only from Object:
By better initial selector:
var fileuploadControls = $("input[type=file]:not(#A)");
By trim down the jQuery object:
fileuploadControls = fileuploadControls.not("#A");
By filter:
fileuploadControls = fileuploadControls.filter(function() {
return $(this).attr("id") !== "A";
});

get index of input element in javascript

If I have 3 input boxes on a web page and the user clicks the second input, I need to get the input index, the position of the input on the page. I need it in pure javascript. This is what I have so far but it doesn't work...
document.querySelector('html').onclick = function (e) {
log(e);
}
function log(obj) {
var nodeName = obj.target.nodeName
var idx = nodeName.length
console.log(nodeName, idx);
}
Any help would be appreciated!
Pure javascript:
function getIndexFromSet(set, elm){
var setArr = [].slice.call(set);
for( var i in setArr )
if( setArr[i] == elm )
return i;
}
The above function can be used like so:
function checkInputFocus(e){
if(e.target && e.target.nodeName == 'input' )
index = getIndexFromSet(inputs, e.target);
}
var inputs = document.querySelectorAll('input');
document.addEventListener("click", checkInputFocus);
using jQuery, if you run this on this page (in your console)
var inputs = $('input'); // get all input elements on the page
inputs.index( $('#save-pinned-sites-btn') ); // find the index of spesific one
you will get a number representing the index of an $('#save-pinned-sites-btn') element
Inline:
<input onclick="for(i=0;i<this.parentNode.getElementsByTagName('input').length;i++){if(this==this.parentNode.getElementsByTagName('input')[i]){alert(i);}}">
Or change that to
onclick="show_index(this)"
And Add:
function show_index(which) {
for(i=0;i<which.parentNode.getElementsByTagName('input').length;i++){
if(which==which.parentNode.getElementsByTagName('input')[i]){
alert(i);
}}

Minimal JavaScript wysiwyg - remove tag from selected text if already exists

I am making a minimal JavaScript WYSIWYG control.
I don't want to use document.execCommand because it doesn't allow arbitrary HTML, it's inconsistent across browsers etc.
Here is what I have so far stripped down to minimum working code:
http://jsfiddle.net/2WxQn/1/
<button data-action="strong"><strong>b</strong></button>
<button data-action="em"><em>i</em></button>
<button data-action="u"><u>u</u></button>
<p contenteditable>The quick brown fox jumps over the lazy dog.</p>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$( function(){
$( 'button' ).on( 'click', function(){
var selection = window.getSelection();
var range = selection.getRangeAt( 0 );
var action = $( this ).attr( 'data-action' );
var node = document.createElement( action );
var frag = range.extractContents();
node.appendChild( frag );
range.insertNode( node );
return false;
});
});
</script>
If some of the selection already contains strong tags (or whatever), how do I make it so that clicking the button a second time removes these tags instead of wrapping the selection with a new strong tag?
Writing this question has given me an idea. I will try it now and answer my own question if it works - that way this question is here in case anybody else comes up against this. Otherwise I shall await your assistance with baited breath :)
EDIT: obviously if somebody else posts a working solution, I will accept their answer rather than mine if it is better.
EDIT(2): so my idea didn't pan out. It turns out that something (probably range.insertNode) will magically balance the tags for you. I don't seem to have enough information from selection, range or frag to always know if the selection is inside a given tag. Any ideas?
EDIT : This is not a good solution. It completely breaks down with anything more complex than a single line of simple text. I have worked out and will be posting a better solution soon.
Figured it out.
I build an array containing each text node in the wysiwyg area, and a list of its parent tags.
Then I wrapped the selection in a custom element so it would be easy to remove later, and so as not to conflict with any existing HTML elements, using the x- prefix as recommended.
I then rebuilt the contents of the wysiwyg element from that list, removing the tag for the clicked button from all nodes in the selection if they all already had it, which is how most wywiwyg editors handle it.
http://jsfiddle.net/x7WRZ/
<button data-action="B"><b>b</b></button>
<button data-action="I"><i>i</i></button>
<button data-action="U"><u>u</u></button>
<p contenteditable>The quick brown fox jumps over the lazy dog.</p>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script>
$( function(){
var selectionWrapper = 'X-SELECTION';
function getTextData( element ) {
function getTextNodesIn( root ) {
var textNodes = [];
var parents = [];
function getTextNodes( node ) {
if( node.nodeType === 3 ){
var text = node.textContent;
textNodes.push({
text: text,
parents: parents.slice( 0 )
});
} else {
if( node !== root ){
parents.push( node.tagName );
}
for( var i = 0, len = node.childNodes.length; i < len; ++i ){
getTextNodes( node.childNodes[ i ] );
}
parents.pop();
}
}
getTextNodes( element );
return textNodes;
}
return getTextNodesIn( element );
}
function handleSelection( container, action ) {
var textData = getTextData( container );
container.innerHTML = '';
//if every textNode in the selection has action as a parent, we want
//to remove it from all of them.
var selection = _( textData ).filter( function( data ){
return _( data.parents ).contains( selectionWrapper );
});
var remove = _( selection ).every( function( data ) {
return _( data.parents ).contains( action ) || data.text.trim() === '';
});
_( selection ).each( function( data ){
if( remove ) {
data.parents = _( data.parents ).without( action );
} else {
data.parents.push( action );
}
});
//rebuild each text node
_( textData ).each( function( data ){
//no need to add empty text nodes
if( data.text === '' ) {
return;
}
//remove duplicates of the same parent tag and remove the selection wrapper
var parents = _( data.parents ).chain().uniq().without( selectionWrapper ).value();
var target = container;
_( parents ).each( function( parent ){
var node = document.createElement( parent );
target.appendChild( node );
target = node;
});
var text = document.createTextNode( data.text );
target.appendChild( text );
});
}
$( 'button' ).on( 'click', function(){
var action = $( this ).attr( 'data-action' );
var selection = window.getSelection();
for( var i = 0; i < selection.rangeCount; i++ ){
var range = selection.getRangeAt( i );
var node = document.createElement( selectionWrapper );
node.appendChild( range.extractContents() );
range.insertNode( node );
handleSelection( $( 'p' )[ 0 ], action );
}
return false;
});
});
</script>

Use Javascript / JQuery to dynamically create multiple HTML buttons with different click event handlers

I am trying to use Javascript / JQuery to dynamically create several HTML buttons, each of which does something different when it is clicked.
My first attempt looked like this:
function myFunc( target_div, num_buttons ) {
var buttons="";
for ( var i=0; i<num_buttons; i++ ) {
buttons += '<input type="button" id="button_'+i+'" value="button_'+i+'"></input>';
}
target_div.html( buttons );
var doButtonPress = function( i ) {
alert( i ); // I actually do something more complicated here, but it's not important now
}
for ( var i=0; i<num_buttons; i++ ) {
$('#button_'+i).click( function() { doButtonPress(i); } );
}
}
Unfortunately this doesn't work because (I think) when the click event happens, doButtonPress is always passed the current value of i in myFunc's scope, not - as I intended - the value i had when the click event was defined. Thus the value passed to doButtonPress is always equal to num_buttons regardless of which button is pressed. So I then tried this instead:
$('#button_'+i).click( new Function( "doButtonPress("+i+");" ) );
Unfortunately this doesn't work either - I get a message "ReferenceError: Can't find variable: returnResult". I assume that's because the Function constructor's arg value isn't parsed until the click event happens, and at that time I'm already outside of myFunc's scope so doButtonPress is undefined? Am I getting this right so far?
So ... what do I do? :-)
Your code didn't work because of the scope of variable i which would be num_button always inside the handler. You can fix it by wrapping it inside a closure but how about simplifying it by adding a class and making use of the id of the button.
function myFunc( target_div, num_buttons ) {
var buttons="";
for ( var i=0; i<num_buttons; i++ ) {
// added class ----------------v
buttons += '<input type="button" id="button_'+i+'" class="mybuttons" value="button_'+i+'"></input>';
}
target_div.html( buttons );
var doButtonPress = function( i ) {
alert( i ); // I actually do something more complicated here, but it's not important now
}
//yes, mybuttons exist
$('.mybuttons').click(function () {
doButtonPress(this.id.replace('button_', ''));
//this.id.replace('button_', '') <- returns i value
});
}
My suggestion would be to assign a data attribute to each button which can then be read when the button is clicked. This will then avoid the need for unnecessary (and ugly) incremental id attributes. Something like this:
function myFunc($target_div, num_buttons) {
var buttons = [];
for (var i = 0; i < num_buttons; i++) {
buttons.push($('<input type="button" class="button" data-id="' + i + '" value="button ' + i + '" />'));
}
$target_div.append(buttons);
var doButtonPress = function() {
alert($(this).data('id'));
}
$(".button").click(doButtonPress);
}
Example fiddle

Check First Char In String

I have input-box. I'm looking for a way to fire-up alert() if first character of given string is equal to '/'...
var scream = $( '#screameria input' ).val();
if ( scream.charAt( 0 ) == '/' ) {
alert( 'Boom!' );
}
It's my code at the moment. It doesn't work and I think that it's because that browser doesn't know when to check that string... I need that alert whenever user inputs '/' as first character.
Try this out:
$( '#screameria input' ).keyup(function(){ //when a user types in input box
var scream = this.value;
if ( scream.charAt( 0 ) == '/' ) {
alert( 'Boom!' );
}
})
Fiddle: http://jsfiddle.net/maniator/FewgY/
You need to add a keypress (or similar) handler to tell the browser to run your function whenever a key is pressed on that input field:
var input = $('#screameria input');
input.keypress(function() {
var val = this.value;
if (val && val.charAt(0) == '/') {
alert('Boom!');
}
});

Categories