I have this inbox or mails which I needed to mark using checkbox for multiple deletions. The problem is that when I click the checkbox it always go to method read() because of onclick inside the tag. All I want is simple marking. Please see the code below:
#foreach ($messages as $message)
<tr onclick="document.location='{{route('account.message.read', array($message->id))}}'">
<td> <input type="checkbox" name="msg" value="{{$message->id}}"></td>
<td><strong>{{Str::words($message->subject, 5, '...')}}</strong> {{Str::words($message->message, 20, '...')}}</td>
</tr>
#endforeach
Now how can I mark each row without going inside that method? I am a newbie btw.
All you need to is attach handler to checkbox and use stopPropagation from bubbling up into trees, see below example :
HTML
Supposed we have table rows with onclick inline javascript and inside it have input:
<table>
<tr onclick="return alert('Hai')">
<td>
<input type="checkbox" />Click Me
</td>
</tr>
<table>
And here the handler :
$('input').click(function(e){
// normally if we removed this line of code
// alert will getting called as checkbox is checked/unchecked
// was inside table rows
// but with this propagation, we disabled it
// from bubbling up into tree
e.stopPropagation();
});
DEMO
you could put the onclick inside the tags excluding the checkbox cell
otherwise you could call an actual onclick function while capturing the click event and check that x is greater than lets say 50px!
<script type="text/javascript">
document.getElementById('emailRow1').addEventListener("click",function(e){
var x=e.pageX-this.offsetLeft;
if(x>50){
rowClicked();
}
},true);
</script>
<table><tbody><tr id='emailRow1'><td style="width:50px;">This area wont trigger onclick</td><td>I trigger onclick</td><td>i trigger onclick</td>
Then you can set custom parameters on your object and recall them using this.customPropertyName to determine what row was clicked! hope this helps
Related
I have the following function, which is used to expand and collapse child tr rows from parent rows within a table, and also changes the text style of a tr to normal:
$( document ).ready(function() {
$('.parent').on('click', function(){
$(this).next('.child').toggle();
$(this).css('font-weight', 'normal');
<<< ADD COMMAND TO TOGGLE BUTTON HERE >>>
});
});
I also have the following hidden button within each tr, which I want to submit when a tr is clicked:
<button type="submit" name="read-button" formmethod="POST" value="{{ message.message_id }}" style="display: none;"></button>
Which command should I include alongside the JavaScript function, in order to achieve this? I believe it will be one of the following (provided by this answer), however I've only been using JS for a few days so I'm not sure how to include these in my code:
document.getElementById('read-button').submit();
changeAction('read-button','loginForm');
document.forms['read-button'].submit();
Sample html:
<form method=['POST']>
<table>
<tr class="parent">
<td>
<button type="submit" name="read-button" formmethod="POST" value="{{ message.message_id }}" style="display: none;"></button>
<a>Heres a cell</a>
</td>
<td>
<a>
Heres one more cell
<a>
</td>
</tr>
<tr class="child">
<td>
<a>
Some hidden info
</a>
</td>
<td>
<a>
More hidden info
</a>
</td>
</tr>
<table>
</form>
To answer the specific question of how to trigger a button within a td via clicking on the tr:
$('.parent').on('click', function() {
$(this).find("button").click();
that can be improved by giving the button a class (incase you add additional buttons in future), eg:
<button class='readbutton' ..`
then
$('.parent').on('click', function() {
$(this).find("button.readbutton").click();
In this scenario, it seems that you don't need a hidden button as you can call the functionality of the hidden button directly.
So rather than:
$("button").click(handleClick);
use
$('.parent').on('click', function() {
.. other functionality ...
handleClick();
as you're new to js, note the difference between handleClick and handleClick() - with () it calls the function, without it passes it as a function variable.
$("button").click(handleClick);
is the same as
$("button").click(function() { handleClick(); });
If you're trying to submit a form, then you would use $(form).submit() - but there's no form in the code as pointed out in the comments and an ajax call would seem more appropriate here than submitting a form.
Finally, consider using classes rather than setting the css directly as adding/removing classes it quite simple in jquery eg for your tr click event add:
$(this).addClass("selected").siblings().removeClass("selected");
I have a <td> which contains a <span> tag. The td tag has a click event and the <span> tag has an id. On clicking the span, I want to disconnect the click event of the <td> tag. How do I do by referring to the span tag?
<Table>
<tr>
<td onClick="disconnectHandler();"><span id="testin">Hello</span></td>
</tr>
</Table>
This is what my JavaScript has :
function disconnectHandler()
{
alert("Hi Hello");
$("#testin").parent().unbind();
}
It keeps showing the alert box. What is wrong with this code?
Additionally, i want to attach the click event to it later too after removing it!
The first unbind scenario doesn't work, because of jQuery's event model. jQuery stores every event handler function in an array that you can access via $("#foo").data('events'). The unbind function looks just for given function in this array. So, you can only unbind() event handlers that were added with bind()
Reference.
Working fiddle.
You couldn't use unbind but you could remove the onclick attribute using prop():
function disconnectHandler()
{
alert("Hi Hello");
$("#testin").parent().prop('onclick',null);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td onClick="disconnectHandler();"><span id="testin">Hello</span></td>
</tr>
</table>
If you want to disable the click after first click it will be better to use one(), check the example below.
Description : one() Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
Hope this helps.
$(function(){
$('body').one('click', '#testin', function(){
alert("Hi Hello");
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><span id="testin">Hello</span></td>
</tr>
</table>
This will bind a click event only once on the td element
$(document).ready(function() {
$('#testin').one('click', function(){
alert('Hello there');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><span id="testin">Hello</span>
</td>
</tr>
</table>
EDIT
The main difference between my answer and Zakaria's reside in the fact the he can add more span later on (if you use class instead of id that is).
$('body').one('click', '#testin', function(){}); Binds all #testin inside body to a click event.
$('#testin').one('click', function{}); Binds all #testin that are already on the document to a click event.
EDIT 2
to answer your question:
It keeps showing the alert box. What is wrong with this code?
You haven't binded an event to the td element, every time it is clicked it call a function name disconnectHandler().
function doSomething() {
alert('alerted')
}
function removeEvent() {
document.getElementById('doer').removeEventListener('click', doSomething);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="doer" onclick="doSomething()">Click me</p>
<p id="undoer" onclick="removeEvent()">Remove his event</p>
As you can see, the so-called event is part of his DOM. You are not removing the attribute, that is why it still call the function
this can also be tried
function disconnectHandler()
{
alert("Hi Hello");
$("#testin").parent().attr('onclick',"")
}
Firstly a bit of background: I'm modifying Drupal's backend (Node creation form) to dynamically add an html to a dynamically created element.
So, this is not a strictly Drupal question, as I believe what I want to know is within the realm of jQuery rather than Drupal.
In my form, I have a repeater (initially I have 1 textarea element, when I click on 'Add more' I'll have 2 textarea elements, and so on).
What I'd like to achieve is, trigger an event (hide elements, add others) when the 'Add more' button is clicked.
So I wrote this:
(function($) {
'use strict';
$(document).ready(function() {
var $container = $('#edit-field-updates tbody .draggable td div.form-item');
$container.find('textarea').hide();
var select = '<select><option value="template_1">Template One</option><option value="template_2">Template Two</option><option value="custom">Custom</option></select>';
$container.append(select);
$('html').click(function (event) {
$container.find('textarea').hide();
$container.append(select);
});
});
})(jQuery);
Note that the I achieve what I want on page load, which is to modify the element. The problem appears when the user click on 'Add more' to add more items.
PS: Ideally I'd like to post the original code that generates the repeater however I still haven't found it yet. This admin theme is based on the Rubik theme, but its a child theme developed internally by someone who's left so can't figure it out where it is.
I've also tried:
...
$('html').on('click', 'input', function (event) {
alert('OI');
$container.find('textarea').hide();
$container.append(select);
});
...
Which does trigger the alert when I click on the page for the second time (I click on 'Add more', then click again anywhere on the page. I guess because I used 'html' rather than a element), however when I used a specific element rather than 'html' it didn't work.
Any ideas?
EDIT:
I've also tried:
$('#edit-field-updates-und-add-more').click(function() {
$container.find('textarea').hide();
$container.append(select);
});
Which didn't work. Here's the html:
<div class="field-type-text-long field-name-field-updates field-widget-text-textarea form-wrapper" id="edit-field-updates"><div id="field-updates-add-more-wrapper"><div class="form-item"><table id="field-updates-values" class="field-multiple-table sticky-enabled">
<thead><tr><th colspan="2" class="field-label"><label>Updates </label></th><th>Order</th> </tr></thead>
<tbody>
<tr class="draggable odd"><td class="field-multiple-drag"></td><td><div class="form-item form-type-textarea form-item-field-updates-und-0-value">
<div class="form-textarea-wrapper resizable"><textarea class="text-full form-textarea" name="field_updates[und][0][value]" id="edit-field-updates-und-0-value" cols="60" rows="5"></textarea></div>
</div>
</td><td class="delta-order"><div class="form-item form-type-select form-item-field-updates-und-0--weight">
<label class="element-invisible" for="edit-field-updates-und-0-weight">Weight for row 1 </label>
<select class="field_updates-delta-order form-select" id="edit-field-updates-und-0-weight" name="field_updates[und][0][_weight]"><option value="0" selected="selected">0</option></select>
</div>
</td> </tr>
</tbody>
</table>
<div class="clearfix"><input class="field-add-more-submit button-add form-submit" type="submit" id="edit-field-updates-und-add-more" name="field_updates_add_more" value="Add another item"></div></div></div></div>
Use...
$("#AddMoreButton").click(function() {
Your Code Here
});
To add the click event only onto the button rather then the whole page. You can wrap that button .click() function with a document.ready() function so that the click event is set on the button when the page loads.
$(document).ready(function() {
$("#AddMoreButton").click(function() {
Your Code Here
});
});
When you set...
$('html').on('click', 'input', function (event) {...
It causes the entire HTML doc to have the click event set on it.
Things to note: #AddMoreButton corresponds to the ID set on the button so it would look like this.
<button id="AddMoreButton">Add More</button>
<table class='generic'>
<script>
$('#select_bh').click(
function(){
if($('#select_bh')[0].checked){
$('#hide_box_bh_s').show();
}
else{
$('#hide_box_bh_s').hide();
}
}
);
</script>
<tr>
<td>
<b><input type="checkbox" id="select_bh" name="pj_boilerhouse" value="Boiler_House"/>Boiler House</b>
</td>
</tr>
<tr>
<td>
<span id='hide_box_bh_s' style='display:none'>
<b><input type="checkbox" class="case_bh_s" name="pj_bh_s" value="Structural"/> Structural</b>
</span>
</td>
</tr>
</table>
the show show/hide in JavaScript is not functioning.. some advice pls, thx.. some how it goes like this when i check the checkbox it will have a new row under the existing row
its working here you can see the code http://jsfiddle.net/damian_silvera/9ym5Y/
You should put your codes inside document ready handler, your code doesn't work as you have bound the event handler to an element that is not added to the DOM yet. The codes that are within the ready handler are executed after the DOM is fully loaded. Also note that Java is not JavaScript.
$(document).ready(function(){
$('#select_bh').click(function(){
$('#hide_box_bh_s').css('display', this.checked ? 'block' : 'none');
});
})
I have used conditional operator which is a shortcut for if statement, if the checkbox is checked it sets the value of display property to block otherwise it sets it to none.
ready()
css()
conditional operator
This is a bit of a long question so please bear with me guys.
I needed to make a form submit automatically when a checkbox was ticked. So far I have the code below and it works perfectly. The form must submit when the check box is either checked or unchecked. There is some PHP that reads a database entry and shows the appropriate status (checked or unchecked) on load.
<form method="post" id="edituser" class="user-forms" action="--some php here--">
<input class="lesson" value="l101" name="flesson" type="checkbox" />
</form>
<script>
$('.lesson').change(function() {
$('.user-forms').submit();
});
</script>
However, when I introduce a fancy checkbox script which turns checkboxes into sliders it no longer works. The checkbox jQuery script is below:
<script src="'.get_bloginfo('stylesheet_directory').'/jquery/checkboxes.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$("input[type=checkbox]").tzCheckbox({labels:["Enable","Disable"]});
});
</script>
The contents of the checkboxes.js called to above is as follows:
(function($){
$.fn.tzCheckbox = function(options){
// Default On / Off labels:
options = $.extend({
labels : ['ON','OFF']
},options);
return this.each(function(){
var originalCheckBox = $(this),
labels = [];
// Checking for the data-on / data-off HTML5 data attributes:
if(originalCheckBox.data('on')){
labels[0] = originalCheckBox.data('on');
labels[1] = originalCheckBox.data('off');
}
else labels = options.labels;
// Creating the new checkbox markup:
var checkBox = $('<span>',{
className : 'tzCheckBox '+(this.checked?'checked':''),
html: '<span class="tzCBContent">'+labels[this.checked?0:1]+
'</span><span class="tzCBPart"></span>'
});
// Inserting the new checkbox, and hiding the original:
checkBox.insertAfter(originalCheckBox.hide());
checkBox.click(function(){
checkBox.toggleClass('checked');
var isChecked = checkBox.hasClass('checked');
// Synchronizing the original checkbox:
originalCheckBox.attr('checked',isChecked);
checkBox.find('.tzCBContent').html(labels[isChecked?0:1]);
});
// Listening for changes on the original and affecting the new one:
originalCheckBox.bind('change',function(){
checkBox.click();
});
});
};
})(jQuery);
There is also some CSS that accompanies this script but I am leaving it out as it is not important.
Finally, this is what the jQuery script does to the checkbox:
<input id="on_off_on" class="lesson" value="lesson11-1" name="forexadvanced[]" type="checkbox" style="display: none; ">
<span classname="tzCheckBox checked" class=""><span class="tzCBContent">Disable</span><span class="tzCBPart"></span></span>
When the checkboxes are changed into sliders the .change() function no longer detects the change in the checkboxes status.
How can I make the .change() function work or is their an alternative function I can use?
This plugin changes your checkboxes to span elements and hides the actual checkboxes themselves. Thus, when you click on them, nothing happens. Since span elements don't have onchange events, you can't bind change events to these.
However, span elements do have click events, meaning that you could instead bind a click event to the generated spans, using Firebug or Chrome Debugger to locate the correct element to bind to.
Your click-handler can then take the same action your change event would normally take if the plugin weren't being used.
Here is an example:
HTML (Source):
<!-- This is a checkbox BEFORE running the code that transforms the checkboxes
into sliders -->
<li>
<label for="pelda1">OpciĆ³ 1:</label>
<input class="pelda" type="checkbox" id="pelda1" name="pelda1" />
</li>
HTML (Generated From Chrome Debugger):
NOTE: This is the generated HTML after running the JavaScript that converts checkboxes to sliders! You must bind your click event AFTER this code is generated.
<li>
<label for="pelda1">Option 1:</label>
<!-- The hidden checkbox -->
<input class="pelda" type="checkbox" id="pelda1" name="pelda1" style="display: none; " />
<!-- the "checked" class on the span gets changed when you toggle the slider
if it's there, then it's checked. This is what you're users are actually
changing.
-->
<span class="tzCheckBox checked">
<span class="tzCBContent">active</span>
<span class="tzCBPart"></span>
</span>
</li>
JavaScript:
NOTE: This must be bound AFTER converting the checkboxes to sliders. If you try it before, the HTML won't yet exist in the DOM!
$('.tzCheckBox').click(function() {
// alert the value of the hidden checkbox
alert( $('#pelda1').attr("checked") );
// submit your form here
});
Listen for change like this:
$('.lesson').bind("tzCheckboxChange",function() {
$('.user-forms').submit();
});
Modify the plugin by adding the line:
$(originalCheckBox).trigger("tzCheckboxChange");
after
checkBox.find('.tzCBContent').html(labels[isChecked?0:1]);
This way, anytime you use this plugin, you can listen for tzCheckboxChange instead of just change. I don't really know what's going on with the plugin, but seems kinda funky for it to be listening for a change event when it would only be fired through trigger (unless it doesn't hide the original checkbox).