I have a react componente like this
var Task = React.createClass({
render: function () {
return (
<div className="task" id={ this.props.task.uid }>
<div className="header">
<span>task #{ this.props.task.uid }</span>
</div>
</div>
)
}
});
and when a task is created, I add this task to the task list inside an create.js.erb
<% if #task.errors.any? %>
$("#error-alert").removeClass('hidden')
<% else %>
$('#task-modal').modal('hide')
$('#tasks-list').prepend(React.renderToString(Task({ task: '<%= #task.to_react %>' })))
<% end %>
turns out that when the task component is prepended, he is prepended empty (just a box, without any text).
I tried <%= #task.to_react.to_json.html_safe %> and also had no success
My Task#to_react method:
def to_react
{
role: role,
need: need,
result: result,
uid: uid
}
end
Not that familiar with rails but unless it's doing some magic here you're embedding the object in a string.
Try
task: <%= ... %>
Instead of:
task: '<%= ... %>'
Related
I followed this tutorial to implement drag and drop. https://www.driftingruby.com/episodes/drag-and-drop-with-hotwire
I am getting an error on drop that says Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'dataset'). Any thoughts on why this is happening?
Project model:
acts_as_list scope: :project
_project.html.erb
<div id="projects" data-controller="position">
<%= content_tag :div, data: { sgid: project.to_sgid_param, id: "#{dom_id project}" }, class: 'table-row' do %> <div><%= project.name %> </div>
<div><%= project.description %> </div>
<div><%= project.status %> </div>
<div><%= project.user.email %> </div>
<div class="flex justify-end">
<%= link_to "View", project_path(project) , data: {turbo: false} %>
<%= button_to "Delete", project, method: :delete, form: {data: {turbo_confirm: "Are you sure?"}} %> </div>
</div>
<% end %>
</div>
position_controller.js
import { Controller } from "#hotwired/stimulus";
import Sortable from "sortablejs"
import { put, get, post, patch, destroy } from "#rails/request.js"
export default class extends Controller {
connect() {
this.sortable = Sortable.create(this.element, {
animation: 150,
onEnd: this.updatePosition.bind(this)
})
}
async updatePosition(event) {
const response = await put('/projects', {
body: JSON.stringify({
sgid: event.project.dataset.sgid,
position: event.newIndex + 1
})
})
if (response.ok) {
console.log(event.project.dataset.sgid)
}
}
}
well event doesn't have a method project. You may have meant event.target. Anyway it looks as if the target of the event is probably the #projects element (but you need to check this in dev tools and see where the event is being captured).
Let's suppose that the event is being captured by the #projects element, well that element has an empty dataList. So wherever the capture is occurring, you need to put data: {sgid: project.to_sgid_param} on that element.
Finally, you should be able to populate the ajax request with the value sgid: event.target.dataset.sgid.
Got a partial view successfully interacting with my coffee script. Collection_Select change triggers script & resulting value is correct, Controller does hit def new successfully.
Only question remaining is how to access the results of the coffee script in the controller.
Partial View:
<% #modName = locals[:moduleName] %>
<% #id = locals[:id] %>
<%= form_with url: admin_command_path() do |f| %>
<%= collection_select(:refcode, :Code, Command.where(FLD: #modName), :Code, :Definition, options ={prompt: true}) %>
<br /><br />
<button class="btn_new">
<%= link_to "Execute", new_admin_command_path(mod: #modName, id: #id) %>
</button>
<% end %>
Coffee Script:
get_SubModule = ->
$('#refcode_Code').change (e) ->
com_value = $('#refcode_Code').val()
console.log 'COFFEEE IS LIFE', com_value
str = $('#refcode_Code :selected').text()
data: {sub_mod_str: com_value}
return
return
So now what.
ActiveAdmin.register Command do
def new
[need to access sub_mod_str here however possible]
end
I think when you Change value you need call Ajax and request controller
get_SubModule = ->
$('#refcode_Code').change (e) ->
com_value = $('#refcode_Code').val()
console.log 'COFFEEE IS LIFE', com_value
str = $('#refcode_Code :selected').text()
data: {sub_mod_str: com_value}
$.ajax(
type: 'POST'
url: your_url
data: data
dataType: 'json'
success: (data) =>
console.log(data)
error: (er) =>
console.log(er)
)
return
return
Controller
def new
byebug // check params
end
Got a (hopefully) easy one:
Ruby partial view with a collection_select, need the value of that selection (var name = 'submod') passed as a param up to controller. Literally just stuck on how to get from collection_select/onchange() to named param.
html.erb code:
<% #modName = locals[:moduleName] %>
<% #id = locals[:id] %>
<%= form_with url: admin_command_path() do |f| %>
<%= collection_select(#refcode, :Code, Command.where(FLD: #modName), :Code, :Definition, options ={prompt: true}, html_options = {:onchange => "updateSubMod(this.value)"}) %>
<br /><br />
<button class="btn_new">
<%= link_to "Execute", new_admin_command_path(mod: #modName, submod: #refcode, id: #id) %>
</button>
<% end %>
The onchange function works as expected, so feel free to make use of that to solve for param:
<script>
function updateSubMod(Code) {
var submod = Code
console.log(submod, '********************')
}
</script>
I'm trying to make a Job descriptions (JD) page to compare between a choose JDs.
My main page will have a field to select some jobs, and a button/link to show the selected jobs details in a table below the selection field using select2 with RoR, as in the image
Job descriptions Viewer .
My issue is that I cannot pass the selected Jobs IDs to the controller, and I get this message:
Completed 406 Not Acceptable in 20ms (ActiveRecord: 0.0ms)
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/job_descriptions_controller.rb:81:in `updateJobs'
My controller method :
def updateJobs
#selected = JobDescription.where(id: params[:selectJdField2])
respond_to do |format|
format.js
format.html
end
end
The main View (jdComparison.html.erb) will render two partials
<h1>Listing Job Descriptions</h1>
<%= render 'sidebar' %>
<div class="clearfix"></div>
<div>
<%= render partial: 'item_list', locals: { job_desc: #job_descriptions} %>
</div>
The _sidebar.html.erb partial has selet2 field and a link to refresh the Jds that called "Find Link":
<div class="col-sm-8">
list of JDs:
<%= select_tag "selectJdField", options_from_collection_for_select(#job_descriptions, :id, :job_title), { :multiple => true } %>
</div>
<%= link_to "Find Link", updateJobs_path(#job_descriptions), :remote => true %>
<script>
$(document).ready(function() { $("#selectJdField").select2(); });
</script>
The _item_list.html.erb partial will view all JDs have been chosen in the select2 field:
<div>
<table>
<thead>
<tr>
<th>Job title</th>
<th>Department</th>
</tr>
</thead>
<tbody>
<% job_desc.each do |job_description| %>
<tr>
<td><%= job_description.job_title %></td>
<td><%= job_description.department %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
updateJobs.js.erb, should refresh the JDs list when I click the "Find Link" button (I think my first issue is here)
$("#div_id").html("<%= escape_javascript(render partial: 'item_list', locals: { job_desc: #selected}) %>")
The JS file (I think my second issue is here):
$ ->
updateLists = () ->
$.ajax
url:'updateJobs'
type: 'post'
dataType: 'html'
format: 'js'
data: {
selectJdField2 : $('#selectJdField').val()
}
The routes:
get 'updateJobs' => 'job_descriptions#updateJobs'
post 'updateJobs' => 'job_descriptions#updateJobs'
When I replace the controller method with this:
def updateJobs
#selected = JobDescription.where(id: 1)
end
it will give me the details of JD number 1 after clicking the Find Link. Kindly, I need your help..
This what I've done to make it works:
I have relapsed the "Find Link" with a normal button:
<button id="btnFind">Find</button>
I added "id" to the first div in _item_list.html.erb partial
<div id = "div_id">
In js file:
$ ->
$(document).on 'change', '#selectJdField', (evt) ->
updateLists()
$(document).on 'click', "#btnFind", (evt) ->
updateLists()
updateLists = () ->
$.ajax '/updateJobs',
type: 'GET'
dataType: 'script'
data: {
selectJdField2 : $('#selectJdField').val()
}
and I didn't need (post 'updateJobs') in the routes file.. Now, everything work fine...Thank you "Venkat Ch"
I am trying to use the Quicksand jQuery plugin to decorate the response of an AJAX call in Rails:
Link:
<% Project.services.each_with_index do |service, index| %>
<%= link_to_function(service, "regatherProjects('#{service}', #{index})", :id => "service_link_#{index}") %>
<%= " / " if !index.eql?(Project.services.length - 1) %>
<% end %>
JS:
function regatherProjects(service_name, service_id) {
$.get("/index_project_update", { service: service_name }, function(data) {
$('#home_projects').quicksand($(data), {
adjustHeight: 'dynamic'
});
});
$('#home_services').find('a').removeClass("on");
$('#service_link_' + service_id).addClass("on");
};
Controller:
def index_project_update
if params[:service] && !params[:service].blank?
#projects = Project.highlighted.where(:service => params[:service])
else
#projects = Project.highlighted
end
end
View:
$("#home_projects").replaceWith("<%= j(render('projects')) %>")
Projects:
<div id="home_projects">
<% if #projects.empty? %>
<p>No projects. <%= link_to_function("View All", "regatherProjects('')") %>.</p>
<% else %>
<ul class="all_projects">
<% #projects.each_with_index do |project, index| %>
<li data-id="<%= project.customer.name.underscore.downcase %>_<%= project.name.underscore.downcase %>">
<%= link_to(image_tag(project.project_images.first.image.home), project) %>
</li>
<% end %>
</ul>
<% end %>
</div>
I think the problem is that the data returned by the AJAX request (see below) is not in the format that Quicksand expects it to be in but I'm not sure how to extrapolate the relevant information from the response. The response from my AJAX request is something like:
$("#home_projects").replaceWith("<some><html><that><i><need>")
So, the problem is that it's using the above code as the destination code for the Quicksand call when it should be using the replacement HTML:
<some><html><that><i><need>
The AJAX request works perfectly fine, but I need to integrate Quicksand into here.
I need:
a better way to do this or;
a way to extrapolate the argument for replaceWith() in the aforementioned code to use as the destination code for Quicksand.
If I've omitted any information you think you need to help, please ask.
This is the first question I've asked on Stack Overflow so I feel obligated to apologise for any misusage.
If anyone runs into a similar issue, the following worked for me in Chrome, Firefox, IE9, IE8 and IE7.
Link:
<% Project.services.each_with_index do |service, index| %>
<%= link_to_function(service, "regatherProjects('#{service}', #{index})", :id => "service_link_#{index}") %>
<%= " / " if !index.eql?(Project.services.length - 1) %>
<% end %>
JS:
function regatherProjects(service_name, service_id) {
$.get("/index_project_update.html", { service: service_name }, function(data) {
$('.all_projects').quicksand($(data).find('li'), {
adjustHeight: 'dynamic'
});
});
$('#home_services').find('a').removeClass("on");
$('#service_link_' + service_id).addClass("on");
};
Route:
match '/index_project_update' => 'application#index_project_update', :defaults => { :format => 'html' }
Controller:
def index_project_update
if params[:service] && !params[:service].blank?
#projects = Project.highlighted.where(:service => params[:service])
else
#projects = Project.highlighted
end
render :layout => false
end
View:
<%= render('application/index/projects') %>
Projects:
<div id="home_projects">
<% if #projects.empty? %>
<ul class="all_projects">
<li data-id="project">No projects. <%= link_to_function("View All", "regatherProjects('')") %>.</li>
</ul>
<% else %>
<ul class="all_projects">
<% #projects.each_with_index do |project, index| %>
<li data-id="project_<%= project.id %>">
<%= link_to(image_tag(project.project_images.first.image.home, :alt => (project.customer.name + " - " + project.name), :title => (project.customer.name + " - " + project.name)), project) %>
</li>
<% end %>
</ul>
<% end %>
</div>