I need to open Semantic-UI-Calendar within a loop but nothing works, which it should. The logic is, when I click data-id="expensecal", it should give me the id which is expense_date2 or expense_date1 but instead it give me the id of the input:
Rails View:
#---Loop----#
<div class="required field">
<label>Claim date</label>
<div class="ui calendar" data-id="expensecal" id="expense_date<%= contract.id %>">
<div class="ui input left icon">
<i class="calendar icon"></i>
<%= f.text_field :date, id: "expense_date_input", placeholder: "Expense date" %>
</div>
</div>
</div>
JavaScript:
$( "[data-id=expensecal]" ).click(function(e) {
e.preventDefault();
let id = '#' + e.target.id;
console.log(id); // Shows the field input id. Why?
$(id).calendar({
type: 'date'
});
});
I use this method to open up a semantic modal in a loop and it works ok but not sure why not with the calendar.
Initialize all the elements at page ready using a class, remove the click event
Try using the following code:
$('.ui.calendar').calendar({
type: 'date'
});
demo:https://jsbin.com/kenaqiyuqe/1/edit?html,js,output
Related
I would like to add dynamically fields to a form in a ERB file and I'm getting an issue that I don't know how to fix.
Basically, a user clicks a btn on a form and a new input text field is added via javascript. Right now, my code looks like this:
<div class="form-group row">
<button type="button" class="btn onclick="addManualInputFieldBtnPressed()">Add a manual input field</button>
</div>
<div id="manual_input_fields">
</div>
and my javascript looks like this:
<script>
var fields_index = -1;
function addManualInputFieldBtnPressed() {
fields_index += 1;
$("#manual_input_fields").append('<div class="form-group row">\
<%= form.label :new_text, class:"col-lg-3" %>\
<div class="col-lg-9">\
<%= form.text_area :new_text, class:"form-control", size: "20x5" %>\
</div>\
</div>');
}
</script>
If I add simple text it works, but as if I have the code above, I'm getting...
undefined local variable or method `form' for #<#<Class:0x00007fbf5c719940>:0x00007fbf5cc13108>
Did you mean? for
fork
I also tried with this code on my javascript part and I get a different error (related to rendering) but it didn't work either.
$("#manual_input_fields").append('<%= escape_javascript(<div class="form-group row">\
<%= form.label :description, class:"col-lg-3 font-weight-bold text-dark col-form-label form-control-label text-2" %>\
<div class="col-lg-9">\
<%= form.text_area :description, class:"form-control", size: "20x5" %>\
</div>\
</div>).html_safe %>');
Can someone point me to the right direction? I suppose that it must be something obvious but I'm a newbie on RoR.
I'm loading flatpickr using this:
<script type="text/javascript">
jQuery(document).ready(function($){
$('#Mydatetime').flatpickr({
altInput: true,
altFormat: "M j, Y # H:i",
enableTime: true,
dateFormat: 'Y-m-d\\TH:i'
});
});
<input type="text" id="Mydatetime" class="MyDate" name="my_expire_date" value="' . $variable . '"/>
The variable is just my datetime. It works, but I'd like to add a clear button similar to this. No matter what I do the button doesn't clear the date.
The example:
<a class="input-button" title="clear" data-clear>
<i class="icon-close"></i>
</a>
Seems straightforward, but I'm clearly missing something. Anyone got one of these close buttons working properly?
Use the following method:
const $flatpickr = $("#flatpickr_id").flatpickr();
$("#some_button_id").click(function() {
$flatpickr.clear();
})
$(function() {
$(".input_button").click(function() {
$('#Mydatetime')[0]._flatpickr.clear();
});
});
Just add this button to your HTML:
<button class="clear_button" title="clear" data-clear>
Clear
</button>
And add this code to the inside of "document ready" function
$(".clear_button").click(function() {
$('#Mydatetime').flatpickr().clear();
})
Here is an working example: https://codepen.io/anon/pen/pxKOGP
If not using jQuery, you can try this:
const my_fp = document.querySelector("#fp_field")._flatpickr;
my_fp.clear();
You can achieve it using CoffeeScript/JS. Unfortunately, there is no option provided by the flatpickr to clear the field after selection.
Envoirenment: Rails & coffeescript
View:
<div class="form-group flatpicker">
<%= f.label :start_time_gt_eq, 'Starting at', class: 'form-control-label font-weight-bold' %>
<div class="row d-flex justify-content-between ml-1">
<%= f.text_field :start_time_gt_eq, class: 'form-control active position-relative col-md-11' ,
data: {
behavior: 'flatpickr_time',
enable_time: true,
alt_input: true,
} %>
<button type="button" id="appointment-start-from" class="close" data-dismiss="alert">×</button>
</div>
</div>
CoffeeScript file
(->
window.Appointments or (window.Appointments = {})
Appointments.init = ->
$ ->
$('#appointment-start-from').click ->
$('#q_start_time_gt_eq').flatpickr().clear();
return
).call this
And make sure to initialize the JS in the view file
<% content_for :js_init do %>
Appointments.init();
<% end %>
I'm using Ruby on Rails and I'm trying to hide/show an individual div from a collection of dynamically generated items by using the dynamically generated id which I then insert in a data attribute. This is what I've come up with so far, I think I'm on the right track but can't figure out what I'm missing. Without the if statement it works but shows the hidden div of every item instead of that specific one, and with the if statement, nothing happens.
Link and hidden div
<span class="options" data-ovly=<%= activity.targetable.id %>>
<i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" data-ovly=<%= activity.targetable.id %>>
<span class="shu_e">
<%= link_to "Edit", edit_medium_path(activity.targetable), :title => "Edit", :alt => "Edit", class: '' %>
</span>
<span class="shu_d">
<%= render :partial => "activities/delete", :locals => {:activity => activity} %>
</span>
</div>
jquery
$('.options').click(function(){
var $ovly = $(this).attr("data-ovly");
if ($('.ed_ovly').data("ovly") === $ovly) {
$('.ed_ovly').toggleClass("none");
}
});
TL;DR
Use id attributes instead of data-ovly in your div tags and avoid the if statement in your script:
html
<span class="options" data-ovly=<%= activity.targetable.id %>>
<i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" id="<%= activity.targetable.id %>">
<span class="shu_e">
<%= link_to "Edit", edit_medium_path(activity.targetable), :title => "Edit", :alt => "Edit", class: '' %>
</span>
<span class="shu_d">
<%= render :partial => "activities/delete", :locals => {:activity => activity} %>
</span>
</div>
script
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
Check this snippet:
$(document).ready(function() {
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
});
.none {
display: none;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="options" data-ovly="1">
ovly#1 <i class="fa fa-ellipsis-h"></i>
</span>
<br><br>
<span class="options" data-ovly="2">
ovly#2 <i class="fa fa-ellipsis-h"></i>
</span>
<div class="ed_ovly none" id="1">
<span class="shu_e">
<a title="Edit ovly # 1" alt="Edit" href="#">Edit</a>
</span>
<span class="shu_d">
"Your rendered partial for ovly # 1"
</span>
</div>
<div class="ed_ovly none" id="2">
<span class="shu_e">
<a title="Edit ovly # 2" alt="Edit" href="#">Edit</a>
</span>
<span class="shu_d">
"Your rendered partial for ovly # 2"
</span>
</div>
Explanation
The first problem is in your if statement: You are using === to compare your values, but, since you are getting those values with different methods (attr and data), you are getting different data types.
Look closely at your code (i added a couple of comments):
$('.options').click(function(){
var $ovly = $(this).attr("data-ovly"); // Returns a string: "1"
if ($('.ed_ovly').data("ovly") === $ovly) // Returns a number: 1
{
$('.ed_ovly').toggleClass("none");
}
});
So your if returns false every time (since you are comparing string with number). To fix this, just use the same method1 to get data in both lines, like this:
$('.options').click(function(){
var $ovly = $(this).data("ovly"); // Returns a number: 1
if ($('.ed_ovly').data("ovly") === $ovly) // Returns a number: 1
{
$('.ed_ovly').toggleClass("none");
}
});
Now that you are getting same data types, your if statement will work as expected. But you are not out of the woods yet, there is another issue with your code, look how you are identifying each unique <div>:
if ($('.ed_ovly').data("ovly") === $ovly)
{
$('.ed_ovly').toggleClass("none");
}
You are using $('.ed_ovly'), that is, you are using the class, and all divs have that class, so with
$('.ed_ovly').data("ovly")
you will always get the value of the first div with class ed_ovly; and in
$('.ed_ovly').toggleClass("none")
you apply toggleClasss("none") to all divs with ed_ovly class (and, as a result, you will hide/show all divs every time).
So, you want to target only one div at a time, and the best way to do it is assigning an id to each div (also dynamically), something like this:
<div class="ed_ovly none" data-ovly="<%= activity.targetable.id %>" id="<%= activity.targetable.id %">
<!-- Your div code... -->
</div>
And on your script, refer only to the div you want to show/hide using its id, and that can be done by changing $('.ed_ovly') to $('#' + $ovly). Now your script should look like this:
if ($('#' + $ovly).data("ovly") === $ovly) {
$('#' + $ovly).toggleClass("none");
}
Your script now should be working fine, but something is off: with the changes we made, now the if is not necessary at all! Since we now get a unique id for each div, its safe to delete it:
$('.options').click(function() {
var $ovly = $(this).data("ovly");
$('#' + $ovly).toggleClass("none");
});
And, while we are at it, lets get rid also of that unnecessary data tag in your div (i assume you don't need it for anything else):
<div class="ed_ovly none" id="<%= activity.targetable.id %">
<!-- Your div code... -->
</div>
Note
1 You could still get away using both methods by comparing them with ==, but i prefer sticking with ===. Check this question for more information.
I am partially rendering data from an endpoint in a list using underscore, each list item has a link to "learn more...". Clicking on that link opens up a text modal/lightbox that shows the rest of the info for that particular element. I would like to add prev and next arrows to see the additional info on the items on the list, without having to close the modal and click on the next item.
I am thinking the way to approach this would be to add a class of "current" to my selected element, and remove/assign this class to each element as needed. But I am stuck thinking how to go about this... (newbie here, be kind).
HTML
<script type="text/template" id="event-template">
<div class="event row no-gutter">
<div class="col-md-12 info">
<div class="col-md-3">
<p class="day"><%= day %></p>
</div>
<div class="col-md-9">
<%= month %> at <%= time %>, <%= storename %> <br> <%= city %> <%= state %>
<a class="show-panel" data-id=<%=entry_id%> href="#_"> Learn More...</a>
</div>
<div class="lightbox-panel" id="lightbox-panel-<%=entry_id%>">
<h2><%= storename %></h2>
<p><%= month %>, <%= desc %></p>
<p align="center"><a class="close-panel" href="#_">Close window</a></p>
<div class="col-md-10" id="prev">Previous</div>
<div class="col-md-2" id="next">Next</div>
</div>
</div>
</div>
</script>
JS
// Open lightbox
$("#events-placeholder").on("click", ".show-panel", function(e) {
var entry_id = $(this).attr("data-id");
$("#lightbox-panel-"+entry_id).fadeIn(300);
$("body").css("background-color", "black");
});
//Close lightbox
$("#events-placeholder").on("click", "#close-panel", function(e) {
$(".lightbox-panel").fadeOut(300);
$("body").css("background-color", "white");
});
// Prev Info
$(".events-placeholder").on("click", "#prev", function(e) {
// ???
var current = $(this).attr("data-id");
var previous = current - 1;
$("#lightbox-panel-"+entry_id-1).fadeIn(300);
});
// Next Info
$("#events-placeholder").on("click", "#next", function(e) {
// ???
});
I am working on a dynamic form input display where if the users clicks something to show "advanced options" in the form, the input vectors will be displayed, but otherwise (the default) they will not be shown. I have the following pieces in my form partial:
UPDATED 1x:
<div class="form-inputs">
<%= f.input :message, label: 'Write message'%>
</div>
<div class="form-inputs">
<%= f.check_box :advanced, {}, :id => "advancedbox" %>
</div>
<div class="form-inputs" id="advancedopts" style="display:none;">
<%= f.input :startdatetime, label: 'Specify', :as => :datetime_picker %>
<%= f.input :expirationdatetime, label: 'Specify', :as => :datetime_picker %>
</div>
And the JS in the head of the form partial:
UPDATED 1x:
<head><script type="text/javascript">
var checkbox = document.getElementById('advancedbox');
checkbox.onchange = function() {
if (checkbox.checked) {
document.getElementById("advancedopts").style.display = "block;";
} else {
document.getElementById("advancedopts").style.display = "none;";
}
}
</script></head>
I took the inspiration for this from the following post: show rest of a form if a checkbox is ckecked in ruby on rails
But I cannot get it to work: the checkbox shows, but clicking it on or off does not show my advanced form inputs. Can anyone help me debug?
Thanks!!
Your problem is that there is no event being listened for. In the example you linked, checkbox.onchange is an event that triggers a function (action) that displays the div. As yours is all namespaced within a function with no event to fire it, nothing happens as it is not evaluated when the state of your checkbox changes.
So if you move the line
var checkbox = document.getElementById('advancedbox');
outside your show function and then key the onchange event to that variable as in the example you linked, it should work.
EDIT: jQuery solution...
$(document).ready(function(){
$("#advancedbox").change(function(){
if( $(this).is(':checked') ){
$('#advancedopts').show(); // you could instead animate using .fadeIn() or .slideDown() if that was preferable
} else {
$('#advancedopts').hide(); // ditto above, using .fadeOut(), .slideUp() etc.
}
});
});
Your problem is here:
<div class="form-inputs" name="advancedopts" style="display:none;">
Changing the name attribute to id should do the trick:
<div class="form-inputs" id="advancedopts" style="display:none;">
Because I do not need to save the user selection, I use the following which works well for my purposes (inspired by changing DIV visibility with JavaScript):
in form partial:
<input type="button" value="Show advanced" onClick="show()">
<div class="form-inputs" id="advancedopts">
... </div>
in application.js:
function show(){
document.getElementById("advancedopts").style.visibility= 'visible' ;
}
in scaffolds.css:
#advancedopts{
visibility:hidden;
}
And works sufficiently for me without the use of a listener. Just in case anyone has a similar simple need and starts off on a track-more-complicated-than-necessary like me.