javascript is not working in rails4.2? - javascript

i am changing my rails application 2.3.2 to 4.2 but its not working in 4.2 please help me? addwelllisteners in separate .js file function.and it is loaded when form will loded but in form it is not called?
<script type="text/JavaScript">
document.observe("dom:loaded", function() {
addWellListeners();
// Make sure we have no drag selection
$$(".plate").each(removeDragSelection);
Ajax.Responders.register({
onComplete: function() {
$$(".plate").each(removeDragSelection);
}
});
// Add right click context menu stuff
Event.observe(document, "contextmenu", function(event) {
// Only display context menu if inside the well area
if (Event.findElement(event, 'div').hasClassName('well')) {
event.stop();
showContextMenu(event.pointerX(), event.pointerY());
}
});
});
</script>
<% end %>
<% content_for :contextmenu do %>
<div id="context_menu" class="context_menu" style="display: none;">
Add<br />
<hr></hr>
Replace<br />
<hr></hr>
Delete<br />
</div>
<div id="context_menu_dis" class="context_menu" style="display: none;">
<span class="disabled">Add</span><br />
<hr></hr>
<span class="disabled">Replace</span><br />
<hr></hr>
Delete<br />
</div>
<% end %>

Related

How to render a partial within javascript

I have two forms on a page which have mostly the same inputs. I have tabs on the screen that switch between each form. However when i submit one of the forms, i recieve a 'cant be blank' on the same input fields on the other form. I understand why this is happening. I tried to stop this by using a if statement to only render either form depending on which tab is clicked. This did not work as you cant target html id's in an if statement. Then i tried to use javascript which used a 'show' and 'hide' methods depending on which tab was clicked which also didnt work as i believe that that even though the form is still hidden, it is still actually there. Now im not sure what to do. My only idea is to render the forms within javascript?
<input id="tab1" type="radio" name="tabs" checked>
<label class="label-header" for="tab1"> UK Address</label>
<input id="tab2" type="radio" name="tabs">
<label class="label-header"for="tab2"> International Address </label>
<!-- <section id="content1"> -->
<%# if %>
<%= f.simple_fields_for :address do |fields| %>
<%# raise %>
<section id="content1">
<%= render "address/fields", fields: fields, addressable: addressable %>
</section>
<% end %>
<%# else %>
<%= f.simple_fields_for :address do |fields| %>
<section id="content2">
<%= render "address/international_fields", fields: fields, addressable: addressable %>
</section>
<% end %>
$(document).ready(function() {
var uk_address = $('#content1');
var international_address = $('#content2');
$('#tab1').on('click', function() {
uk_address.show();
international_address.hide();
});
$('#tab2').on('click', function() {
uk_address.hide();
international_address.show();
});
});
You should be able to enable/disable the items inside the javascript you have with this modification:
$(document).ready(function() {
var uk_address = $('#content1');
var international_address = $('#content2');
$('#tab1').on('click', function() {
uk_address.removeAttr("disabled").show();
international_address.attr("disabled", "disabled").hide();
});
$('#tab2').on('click', function() {
uk_address.attr("disabled", "disabled").hide();
international_address.removeAttr("disabled").show();
});
});

Change div class on click in Rails app

I have a rails app which displays steps and substeps in rows. I'm looking to create an action where clicking on a step row will change it's class from 'step_container' to 'step_container active', and then show the corresponding substep rows for that step. I have had a difficult time figuring out how to use AJAX (or understanding if that is the best tool) to accomplish this.
<% #steps.each do |step| %>
<div class="step_container"> <!-- add 'active' if clicked-->
<div class="medium-8 columns"><!-- add 'active_container' if clicked-->
<div class="medium-5 columns step_info">
<div class="step_number">
<span><%= step.order %></span>
</div>
<div class="custom_step">
<span class="step_title"><%= step.title %> (custom step)</span>
<span class="step_desc"><%= step.description %></span>
</div>
</div>
</div>
<!-- Only show this div if top div is clicked -->
<div class="medium-4 columns sub_steps_container">
<% #substeps.where(step_id: step.id).each do |substep| %>
<div class="sub_steps">
<div class="step_number">
<span><%= substep.order %></span>
</div>
<div class="">
<span class="step_title"><%= substep.action %></span>
<span class="step_desc"><%= substep.description %></span>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
Thanks in advance for assistance. This has taken me most of the day with limited results.
There is no need for AJAX here, just little bit of javascript and css.
JavaScript:
$('.step_container').click(function() {
$(this).addClass('active');
}
CSS (sass):
.step_container {
.sub_steps_container {
display: none;
}
&.active {
.sub_steps_container {
display: block;
}
}
}
If I understand you correctly, you won't actually need Ajax for this. This could be pretty simple:
Hide the sub_step_container div initially via css.
.sub_steps_container {
display: none;
}
Add this to your HTML code (or better yet, don't use script tags and use in separate JS file).
<script>
$('.step_container').on('click', function(){
$(this).addClass('active');
$('.sub_steps_container').show()
});
</script>

Cleaning up a form from a remote modal

I am triggering a remote modal like this:
<li><a data-toggle="modal" href="/login" data-target="#modal">Sign in</a></li>
I build the 'route' variable on Javascript, and then load the Modal:
$('#modal').modal({
show: true,
remote: route
});
... where route is a variable that depending on its value, tells me where to fetch the data from.
These pages I am loading for the most part contain forms for sign in, user registration, etc... They load successfully.
The problem arises when I try to close this window and open it up again. The form is not cleared. This means, if I tried to login and the login failed and error messages were shown, they will appear when I click on the sign in button again.
For this example, the login HTML that is loaded contains the following:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<%= csrf_meta_tags %>
<title>Sign in to Chocolatechix</title>
</head>
<body>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<%= form_for #user_session, url: user_session_path, method: :post, html: { class: 'form-horizontal', role: 'form' } do |f| %>
<div class="modal-body">
<div class="row lower-space">
<div class="col-xs-10 col-xs-offset-1">
<%= f.text_field :email, class: 'form-control email_field', placeholder: 'E-mail Address' %>
</div>
</div>
<div class="row lower-space">
<div class="col-xs-10 col-xs-offset-1">
<%= f.password_field :password, class: 'form-control password_field', placeholder: 'Password' %>
</div>
</div>
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<%= f.submit 'Sign In', class: 'btn btn-primary full-width' %>
</div>
</div>
<div class="row lowest-space">
<div class="col-xs-10 col-xs-offset-1">
Forgot password?
</div>
</div>
<div class='row'>
<div class="col-xs-4 col-xs-offset-1 center new-text bold">
New user?
</div>
<div class="col-xs-4 col-xs-offset-1 center">
<a class="btn btn-success" href="/become">Create account</a>
</div>
</div>
<div class="row">
<div class="col-xs-12" id="error_messages">
</div>
</div>
</div>
<div class="modal-footer">
</div> <!-- /modal-footer -->
<% end %>
<script type="text/javascript">
$( document ).ready(function(){
// process the form
$('form').submit(function(event) {
// get the form data
// there are many ways to get this data using jQuery (you can use the class or id also)
var formData = {
'user_session[email]' : $('.email_field').val(),
'user_session[password]' : $('.password_field').val(),
'authenticity_token': $('input[name=authenticity_token]').val(),
'utf8': $('input[name=utf8]').val()
};
// process the form
$.ajax({
type : 'POST', // define the type of HTTP verb we want to use (POST for our form)
url : '/user_session', // the url where we want to POST
data : formData, // our data object
dataType : 'json', // what type of data do we expect back from the server
encode : true
}).done(function(data) {
console.log(data);
if(!data.logged_in){
$('#error_messages').html('<span class="label label-danger">' + data.error+ '</span>');
}
else {
window.location.replace("/");
}
});
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
});
});
</script>
</body>
</html>
So in this case, the error messages keep showing.
Any ideas?
Edit: So I'm thinking that trying to invoke a hide event and try to clean it up from there might work. (See Bind a function to Twitter Bootstrap Modal Close)
I am trying to call this event this way:
$('#modal').modal({
show: true
});
$('#modal').on('hidden.bs.modal', function () {
alert('Foo');
});
... but this is not triggered.
Ideas?
Edit 2: Yet another attempt:
$(document).on('hide.bs.modal','#modal', function () {
alert('Foo');
}).modal({
show: true,
remote: route;
});
The alert does not fire.
you can do like this
<li><a data-toggle="modal" href="/login" onclick="test()">Sign in</a></li>
function test(){
$("#formid")[0].reset();
$('#modal').modal({
show: true
});
}

Backbone load a view within a view (as partial)

Hope someone can help me with,
I have a Backbone view, that is basically a skeleton of HTML, the HTML builds a tabbed interface, each tab obviously has a link and content area. What I am wanting to is for each content render an individual Backbone template specific to that tab.
So for example in the tab #briefs I would want to render app.projectBriefsView. I cannot for the life of figure how I would go about doing this, here is my "base/master" view that I want to load everything else into.
app.ProjectsTabsView = Backbone.View.extend({
el: "header.project",
template: _.template($("#tpl-projects-tabs").html()),
events: {
'click .js-tab-link': 'showTab',
},
initialize: function() {
this.render();
var briefView = new app.projectBriefView;
briefView.render().el;
},
render: function() {
this.$el.append(this.template());
return this;
},
showTab: function(el) {
var tabRequired = $(el.currentTarget).attr("href");
console.log(tabRequired);
$(".tab-content.active").css("display", "none").removeClass("active");
$(".tab-content"+tabRequired).addClass("active").css("display", "block");
el.preventDefault();
}
});
Template
<script type="text/template" id="tpl-projects-tabs">
<div class="tabs">
<ul>
<li>Brief + Notes</li>
<li>Dates</li>
<li>Files</li>
<li>Tasks</li>
<li>Messages</li>
<li>Comments</li>
</ul>
<div class="tab-content js-tab-content active" id="brief">Briefs</div>
<div class="tab-content js-tab-content" id="dates">Dates</div>
<div class="tab-content js-tab-content" id="files">Files</div>
<div class="tab-content js-tab-content" id="tasks">Tasks</div>
<div class="tab-content js-tab-content" id="messages">Messages</div>
<div class="tab-content js-tab-content" id="comments">Comments</div>
</div>
</script>
and here is the view I am wanting to load into the .tab-content#brief area.
app.projectBriefView = Backbone.View.extend({
el: ".tab-content",
template: _.template($("#tpl-brief-notes").html()),
events: {
},
initialize: function() {
this.render();
},
render: function() {
this.$el.append(this.template({
p: app.project.toJSON()
}));
return this;
}
});
Template
<script type="text/template" id="tpl-brief-notes">
<div class="project_info_content">
<!-- New brief form -->
<div class="brief">
<h4>Brief</h4>
<% if (p.is_owner) { %>
<div class="js-brief-text">
<% if (p.brief == undefined || p.brief == '') { %>
<p class="add-text">No Brief, Click to add</p>
<% }
} else { %>
<div>
<% }
if (p.brief != undefined || p.brief != '') { %>
<% //p.brief %>
<?= nl2br(str_replace(' ', ' ', htmlspecialchars($project['brief']))); ?>
<% } %>
</div>
<div class="inline-edit">
<% if (p.is_owner) { %>
<form action="<?= base_url(); ?>projects/edit_brief/<%= p.id %>" method="post" accept-charset="utf-8" class="inline_edit edit_brief" novalidate="novalidate">
<p>
<textarea name="brief" class="brief_edit"><%= p.brief %></textarea>
<input type="submit" name="submit" value="Update"><a class="cancel" href="#">Cancel</a>
</p>
</form>
<% } %>
</div>
</div>
<!-- End of new brief form -->
<!-- New additional notes form -->
<div class="additional_notes">
<h4>Additional notes <span class="instructions">(Editable by other users)</span></h4>
<div class="js-notes-text">
<%
if (p.additional_info == undefined || p.additional_info == '') { %>
<p class="add-text">No Notes, Click to add</p>
<% } else { %>
<% // p.additional_info %>
<?= nl2br(str_replace(' ', ' ', htmlspecialchars($project['additional_info']))); ?>
<% } %>
</div>
<div class="inline-edit">
<form action="<?= base_url(); ?>projects/edit_additional_info/<%= p.id %>" method="post" accept-charset="utf-8" class="inline_edit edit_notes" novalidate="novalidate"> <p>
<textarea name="text_details" class="notes_edit"><%= p.additional_info %></textarea>
<input type="submit" name="submit" value="Update"> <a class="cancel" href="#">Cancel</a>
</p>
</form>
</div>
</div>
</div>
<!-- End of new additional notes form -->
</div>
</script>
I thought that in the app.ProjectTabsView in the render function I would be able to do something like,
var brief = new app.projectBriefView();
brief.render().el();
to throw the output to the browser but this does not seem to work. Is there a better way to work with what I would call partial views in Backbone? How can I get my partial to the browser?
Since Backbone views can populate the browser with html dynamically, you only need to have one div element for content. This div element will then serve as a placeholder for the nested view generated by the view managing the tabs.
I had to solve a very similar problem and here is what I did:
First, define a control structure to bind a tab title to a view constructor:
var Tab = function( title, viewConstructor ) {
this.title = title;
this.viewConstructor = viewConstructor;
};
_.extend( Module.prototype, {
render : function( options ) {
this.view = new this.viewConstructor( options );
return this.view.render();
},
close : function() {
if( this.view ) {
this.view.close();
}
}
});
Then, define all your tabs in an array:
var tabs = [
new Tab('brief', app.projectBriefView),
new Tab('dates', app.projectDatesView),
//...
]
You need to clean up a little bit your template:
<script type="text/template" id="tpl-projects-tabs">
<div class="tabs">
<ul>
<li>Brief + Notes</li>
<li>Dates</li>
<li>Files</li>
<li>Tasks</li>
<li>Messages</li>
<li>Comments</li>
</ul>
<div class="tab-content js-tab-content" id="tab-content">Briefs</div>
</div>
</script>
Finally, you just have to use them in your events:
//...
showTabs : function( event ) {
event.preventDefault();
var clicked = $(el.currentTarget),
title = clicked.attr("href").replace("#", ""),
tab = _.findWhere( tabs, { title : title });
// always cleanup the preceding tab.
if ( this.activeTab ) {
this.activeTab.close();
}
this.activeTab = tab;
this.$('ul > li > .active').removeClass('active');
this.$('#tab-content').html( tab.render().el );
clicked.addClass('active');
}

How to hide/show back/next button with JavaScript in a Rails from wizard?

I've created a wizard form with this gem: https://github.com/stephenbaldwin/fuelux-rails
Everything is working in terms of getting to the next and previous steps. However, what's a 'rails way' to hide the 'prev' button on first step and show only the 'submit' button on last step? Is this something I'd do do in js?
_form.html.erb
<%= form_for(#wizard) do |f| %>
<div>
<div id="MyWizard" class="wizard">
<ul class="steps">
<li data-target="#step1" class="active"><span class="badge badge-info">1</span>Step 1<span class="chevron"></span></li>
<li data-target="#step2"><span class="badge">2</span>Step 2<span class="chevron"></span></li>
<li data-target="#step3"><span class="badge">3</span>Step 3<span class="chevron"></span></li>
</ul>
</div>
<div class="step-content">
<div class="step-pane active" id="step1">
<div class="field">
<%= f.label :field1 %><br />
<%= f.text_field :field1 %>
</div>
</div>
<div class="step-pane" id="step2">
<div class="field">
<%= f.label :field2 %><br />
<%= f.text_field :field2 %>
</div>
</div>
<div class="step-pane" id="step3">
<div class="field">
<%= f.label :field3 %><br />
<%= f.text_field :field3 %>
</div>
</div>
<input type="button" class="btn btn-mini" id="btnWizardPrev" value="prev">
<input type="button" class="btn btn-mini" id="btnWizardNext" value="next"></br>
<div>
<%= f.submit :class => 'btn btn-mini btn-primary' %>
</div>
</div>
</div>
<% end %>
application.js file:
$(function() {
$('#MyWizard').on('change', function(e, data) {
console.log('change');
if(data.step===3 && data.direction==='next') {
// return e.preventDefault();
}
});
$('#MyWizard').on('changed', function(e, data) {
console.log('changed');
});
$('#MyWizard').on('finished', function(e, data) {
console.log('finished');
});
$('#btnWizardPrev').on('click', function() {
$('#MyWizard').wizard('previous');
});
$('#btnWizardNext').on('click', function() {
$('#MyWizard').wizard('next','foo');
});
$('#btnWizardStep').on('click', function() {
var item = $('#MyWizard').wizard('selectedItem');
console.log(item.step);
});
});
Side note/question - is there a way to put this .js in my asset pipeline without storing it in application.js? I tried to create a separate .js under javascripts but it dosen't pull in.
In your javascript file replace this block
$('#MyWizard').on('change', function(e, data) {
console.log('change');
if(data.step===3 && data.direction==='next') {
// return e.preventDefault();
}
});
with following block: (UPDATED)
$('#MyWizard').on('change', function(e, data) {
console.log('change');
$('#wizard-submit').hide(); //hide the submit button on each step.
if(data.step === 3 && data.direction === 'next') {
// return e.preventDefault();
$('#wizard-submit').show(); //show the submit button only on last(3rd in your case) step.
}
switch(data.step) {
case 1:
if(data.direction === 'next')
$('#btnWizardPrev').show();
else
$('#btnWizardPrev').hide();
$('#btnWizardNext').show();
break;
case 2:
if(data.direction === 'next') {
$('#btnWizardPrev').show();
$('#btnWizardNext').hide();
}
else {
$('#btnWizardPrev').hide();
$('#btnWizardNext').show();
}
break;
case 3:
// I would recommend to show the prev button on last step but hide the next button.
if(data.direction === 'next')
$('#btnWizardNext').hide();
else
$('#btnWizardNext').show();
$('#btnWizardPrev').show();
break;
default:
$('#btnWizardPrev').show();
$('#btnWizardNext').show();
}
});
The above code will show/hide the buttons based on the step you're in.
And for you second question: are you specifying the //= require_tree . in the application.js. If yes then try enclosing the code in $(document).ready(function(){..code goes here..})
UPDATE See the updated code above. I am not sure if this is the correct way, but I am able to get it working this way.
Also add #btnWizardPrev { display: none; }
Assumption: There are three steps in the form. If there are more you would need to add more cases in switch statement. Basically you'll need to break the case 2: statement in that case. In case 2: the next condition is for removing the next button, so in case there are more steps, move the next condition to second last step.
UPDATE Replace your submit button code with <%= f.submit :class => 'btn btn-mini btn-primary', :id => 'wizard-submit' %>. This will simply add id attribute to your submit button. You can use any value to be its id. Then just hide the submit button by adding this css #wizard-submit { dispay: none } and then use the above updated jquery code in your javascript file.
The wizard plugin already disables the previous button on the first step. It looks for a button.btn-prev located in the wizard container
<div id="myWizard" class="wizard">
<div class="actions">
<button class="btn btn-mini btn-prev"> <i class="icon-arrow-left"></i>Prev</button>
<button class="btn btn-mini btn-next" data-last="Finish">Next<i class="icon-arrow-right"></i></button>
</div>
If you'd like to hide the disabled previous button you could target it with css to avoid javascript
.wizard button.btn-prev[disabled] {
display: none;
}

Categories

Resources