I have the following row element with a double click event atached to it.
<tr ondblclick="onLabelDoubleClicked(this)">
<td><label id="labelId" >My Label</label></td>
<td><input type="text" id="myInput" data-bind="kendoDropDownList: { data: source, value: myValue, enable: true }" /></td>
</tr>
On double click I need to set the enable property of kendoDropDownList in input element to toggle true/ false.
javascript:
onLabelDoubleClicked = function (event) {
}
I searched through the event properties but could not find anything useful to get the enable property and manipulate it. Any help with working example will be greatly appreciated. Thank You!
Instead of inlining the doubleclick event, it’s easier if you put the handler in the JS code and traverse/change the DOM from there.
I’m not sure about the Kendo stuff in the data-bind property, but it looks like a string to me so you’ll need to do string replaces unless you have a better way.
try this:
$('tr').dblclick(function() {
var $el = $(this).find(':text'),
data = $el.data('bind');
if (/true/.test(data)) {
data = data.replace(/true/,'false');
} else if (/false/.test(data)) {
data = data.replace(/false/,'true');
}
$el.prop('data-bind', data);
});
If you can use jQuery (and tag sets implies you're), why not just use jQuery (and Kendo) methods?
$('tr').dblclick(function() {
var $kd = $(this).find('input').data("kendoDropDownList");
$kd.enable( $kd.element.is(':disabled') );
});
Related
I have several buttons contain some values:
<button class="Hotspot" onclick="ChangeView()" slot="hotspot-1" camera.Orbit='2.895deg 85deg 27.92m' ;>
and I need to create function that read camera.Orbit value from button's container after click on it:
function ChangeView() {
const modelViewer = document.querySelector('#orbit-demo');
modelViewer.cameraOrbit = camera.Orbit ???
}
I have no idea how to solve this. I do not use getElementbyId because it has to work for all buttons (not specific one).
I barely can JS.
Thank you for help.
You can use Element.getAttribute:
function ChangeView() {
const modelViewer = document.querySelector('#orbit-demo');
let orbit = modelViewer.getAttribute('camera.Orbit')
console.log(orbit)
}
<button class="Hotspot" onclick="ChangeView()" slot="hotspot-1" camera.Orbit='2.895deg 85deg 27.92m' id="orbit-demo">Click</button>
The onclick function passes the click event to the method. You can take the target of this event (the button element) and acquire tha attribute like that.
onclick(e => changeView(e))
ChangeView(e) {
// do things with e.target.???
}
I am facing a problem that i have multiple DIVs with almost same ID but having increments from 0 to any number in the end, I want to use this username check function for every different username field and show its results in its specific related div. I tried all the possible ways but its not working.
Here is my Fiddle
Here is my Code
$(document).ready(function() {
$('[id^=Loading]').hide();
});
function check_username(){
var username = $("[id^=username]").val();
if(username.length > 1){
$('[id^=Loading]').show();
$.post("username-Check.php", {
username: $('[id^=username]').val(),
}, function(response){
$('[id^=Info]').fadeOut(2100);
$('[id^=Loading]').fadeOut(2100);
setTimeout("finishAjax('Info', '"+escape(response)+"')", 2000);
});
return false;
}
}
function finishAjax(id, response){
$('#'+id).html(unescape(response));
$('#'+id).fadeIn(2000);
}
Incremental/dynamic id attributes are almost always an anti-pattern and should be avoided where possible as they create more problems than they solve.
A much better solution would be to use DOM traversal to find the elements related to the one which raised the event - in your case the blur on the input.
To do this, firstly use unobtrusive event handlers instead of the outdated on* event attributes. Then change the id attributes to classes. To find the elements, use the this keyword to reference the element that raised the event, then prev() and prevAll().first() to find the required element by its class. Finally, provide an anonymous function to setTimeout() over hacking together a string to be run through eval(). Try this:
<div class="info"></div>
<span class="loading"></span>
<input class="username form-control" type="text" name="txtengine" placeholder="914899" value="" /><br>
<div class="info"></div>
<span class="loading"></span>
<input class="username form-control" type="text" name="txtengine" placeholder="914899" value="" /><br>
$(document).ready(function() {
$('.loading').hide();
});
$('.username').on('blur', function() {
var username = $(this).val();
if (username.length) {
var $loading = $(this).prev('.loading').show();
var $info = $(this).prevAll('.info').first();
$.post("username-Check.php", {
username: username,
}, function(response) {
$info.fadeOut(2100);
$loading.fadeOut(2100);
setTimeout(function() {
$info.html(response).fadeIn(2000);
}, 2000);
});
}
})
Working example
Note that the example in the fiddle had the AJAX request logic amended to fit jsFiddles' JSON response logic, but the functionality is the same.
Before I start answering I would strongly suggest you to use a class and then select via class name. As it seems your case is textbook for when to use jquery class-selectors.
You cannot use the attribute selector without specifying what you are using it on. I.e. you cannot say:
$('[id^=Loading]')
you need to give the tag name, the id, or the class i.e.
$('span[id^=Loading]')
I have made a jfiddle for you:
https://jsfiddle.net/acc069me/6/
I build a method that allow me to return the clicked element by the user, something like this:
$('#button2').on('mouseover', function()
{
console.log(this);
}
this return:
<tr id="res-7" class="entry border-bottom" rel="popover" data-original-title="" title="">
<td style="padding-left: 10px">
<div class="name"><strong>Test</strong></div>
<div class="description">Foo</div>
</td>
</tr>
essentially my target is get the content of div name and div description, someone could explain how to do this? Thanks.
Something like this: jsfiddle
$(document).on("mouseover","tr", function(){
var name = $(this).find(".name").text();
var description = $(this).find(".description").text();
console.log("Name: "+name+"\nDecsription: "+description);
})
Don't forget ID of each element must be unique so your code is not correct because "#button2" must be unique, so this is always #button2 in your function.
Note the difference between text() and html(). I used .text() to get just the text without "strong" code. If you need it use html().
You could use innerHTML
$(this).find('name').innerHTML; //returns "test"
$(this).find('description').innerHTML; //returns "foo"
This will find the class within the current element, and return the values you need.
Since you already have an id on your element, accessing the name and description attributes is easy:
$('#button2').on('mouseover', function() {
var $res7 = $('#res-7');
// Access the two divs
var name = $res7.find('.name').text(); // or .html()
var description = $res7.find('.description').text(); // or .html()
// Print them out
console.log(name);
console.log(description);
});
Of course, this block of code should be inside a jQuery ready event handler.
I'm sure there is a cleaner way, but this should get you what you want.
$('#button2').on('mouseover', function()
{
console.log($(this).find(".name").html());
console.log($(this).find(".description")).html());
}
The title isn't very descriptive but I couldn't find a better one. Feel free to edit it.
Basically what I'm looking for is the best way to do the following:
When the user clicks "Add New Item", a new row is added with an indentical text box and drop down as above. The options I can think of are the following:
Hardcode the HTML in the JavaScript code. This is obviously a hideously ugly solution.
Assemble the HTML from DOM nodes (or jQuery objects). This is very ugly too.
Use a client-side template system. I used one of those once and it was pretty weird (it used <script language="html"> tags to define the templates).
Make an ad-hoc client-side "template" and hide it somehow with CSS.
Make an AJAX request to fetch the HTML. This is slow and uses server resources unnecessarily.
What do you suggest? I'm not completely satisfied with any of the above solutions.
Assuming the super-simple approach and that your format is in a table:
<table>
<tr>
<td><input type="text" name="item_name" placeholder="item name" /></td>
<td><select name="item_type"><option value="" selected="selected">Type</option></select></td>
</tr>
<tr>
<td><input type="text" name="item_name" placeholder="item name" /></td>
<td><select name="item_type"><option value="" selected="selected">Type</option></select></td>
</tr>
<tr>
<td colspan="2" id="add">+ Add new item</td>
</tr>
</table>
You can use the following:
$('#add').on('click',function(e){
var $this = $(this);
var $newRow = $this.closest('table').find('tr:first').clone();
$newRow.find(':input').val('');
$newRow.insertBefore($this.parent());
});
Broken down:
We give the last item an ID to make it easier to bind a click event to.
Use jQuery and bind the click event to that ID which:
Grabs the current table we're clicking within ($this.closest('table'))
Locates the first row within that table and duplicates it (.clone())
Remove any populated values that may be present (.find(':input').val(''))
Append this new cloned row to the table just above the "add new item" row ($newRow.insertBefore(...))
You can also take the template approach, but that's really up to you and how much control you'd like over the output.
If you're already using a framework like jquery or sencha on your page, you might as well make use of it.
Otherwise, i'd keep it as simple as possible. This does't look like a very important core functionality, so don't create something that requires extra https requests or even entire libraries to be loaded. Cloning or generating the html might not look elegant, but it'll be:
fast to implement
easy to read, and therefore easy to debug
waste few resources, and extremely fast
stable
doesn't need server side code or extra http requests
it'll be easy to change the implementation later on if needed
Don't create something that's overkill for somerhing as trivial as this.
While I realise you already have an accepted answer, I thought I'd offer a plain JavaScript means of achieving the same:
function closest(el, tag) {
if (!el || !tag) {
return false;
}
else {
var curTag = el.tagName.toLowerCase();
return curTag == tag.toLowerCase() && curTag !== 'body' ? el : closest(el.parentNode, tag);
}
}
function addRow(el) {
if (!el) {
return false;
}
else {
var tr = closest(el, 'tr').previousElementSibling,
newRow = tr.cloneNode(true);
tr.parentNode.insertBefore(newRow, tr.nextSibling);
}
}
document.getElementById('add').onclick = function() {
addRow(this);
}
JS Fiddle demo.
Revised the above a little, to add a simple shim to cope with those browsers that don't implement previousElementSibling:
function closest(el, tag) {
if (!el || !tag) {
return false;
}
else {
var curTag = el.tagName.toLowerCase();
return curTag == tag.toLowerCase() && curTag !== 'body' ? el : closest(el.parentNode, tag);
}
}
function prevElementSiblingShim(el) {
if (!el) {
return false;
}
else {
var prevSibling = el.previousSibling;
return prevSibling.nodeType == 1 ? prevSibling : prevElementSiblingShim(prevSibling);
}
}
function addRow(el) {
if (!el) {
return false;
}
else {
var par = closest(el, 'tr'),
tr = par.previousElementSibling || prevElementSiblingShim(par),
newRow = tr.cloneNode(true);
tr.parentNode.insertBefore(newRow, tr.nextSibling);
}
}
document.getElementById('add').onclick = function() {
addRow(this);
}
References:
cloneNode().
insertBefore.
nextSibling.
nodeType.
parentNode.
previousElementSibling Compatibility.
previousSibling.
tagName.
toLowerCase().
Inserting HTML from a string into the DOM is the most efficient way. Unless you're inserting hundreds at once, it doesn't really matter.
I found a response in a jquery forum and they made a function to do this but the result is not the same.
Here is an example that I created for an image button:
var buttonField = $('<input type="image" />');
buttonField.attr('id', 'butonFshi' + lastsel);
buttonField.val('Fshi');
buttonField.attr('src', 'images/square-icon.png');
if (disabled)
buttonField.attr("disabled", "disabled");
buttonField.val('Fshi');
if (onblur !== undefined)
buttonField.focusout(function () { onblur(); });
buttonField.mouseover(function () { ndryshoImazhin(1, lastsel.toString()); });
buttonField.mouseout(function () { ndryshoImazhin(0, lastsel.toString()); });
buttonField.click(function () { fshiClicked(lastsel.toString()); });
And I have this situation:
buttonField[0].outerHTML = `<INPUT id=butonFshi1 value=Fshi src="images/square-icon.png" type=image jQuery15205073038169030395="44">`
instead the outer function I found gives buttonField.outer() = <INPUT id=butonFshi1 value=Fshi src="images/square-icon.png" type=image>
The function is:
$.fn.outer = function(val){
if(val){
$(val).insertBefore(this);
$(this).remove();
}
else{ return $("<div>").append($(this).clone()).html(); }
}
so like this I loose the handlers that I inserted.
Is there anyway to get the outerHTML with jquery in order to have it cross-browser without loosing the handlers ?!
You don't need convert it to text first (which is what disconnects it from the handlers, only DOM nodes and other specific JavaScript objects can have events). Just insert the newly created/modified node directly, e.g.
$('#old-button').after(buttonField).remove();`
after returns the previous jQuery collection so the remove gets rid of the existing element, not the new one.
Try this one:
var html_text = `<INPUT id=butonFshi1 value=Fshi src="images/square-icon.png" type=image jQuery15205073038169030395="44">`
buttonField[0].html(html_text);
:)
Check out the jQuery plugin from https://github.com/darlesson/jquery-outerhtml. With this jQuery plugin you can get the outerHTML from the first matched element, replace a set of elements and manipulate the result in a callback function.
Consider the following HTML:
<span>My example</span>
Consider the following call:
var span = $("span").outerHTML();
The variable span is equal <span>My example</span>.
In the link above you can find more example in how to use .outerHTML() plug-in.
This should work fine:
var outer = buttonField.parent().html();