Creating a child domain object from gsp page - ajax

Is it possible to use the Grails remoteFunction to call the create method on a child domain object?
I'm trying to call the create function in the child controller from a remoteFunction call on my gsp page, but keep getting an error
Message: Provided id of the wrong type for class XXX.YYY. Expected: class java.lang.Long, got class java.lang.String
And the remoteFunction code looks like so:
$.ajax({
type: 'POST',
url: "${remoteFunction(controller:'childController' action:'create' )}"
});
I've searched the Google all morning, and the only thing I can find is remoteFunctions for cascading a select statement.

Remember, the create method gives you the create gsp view. That view still has a save button on it which posts to the save controller method. I think you need to write a custom method that instantiates your new class and saves it all in one shot.

So what I have working so far is this:
<script type="text/javascript">
function someFunction(){
var id = ${parentInstance.id};
var $element = $('#elements ul li.selectedAdd');
$element.removeClass('selectedAdd');
$('#right-side ul').append($element);
${remoteFunction(
action:'createChild',
update:'right-side',
params:'\'id=\'+ escape(id) +\'&childType=\' + escape(childType)'
)}
};
Which works with this controller method:
def createChildBlock = {
def parent = Parent.get(params.id)
def childBlockInstance = new ChildBlock(childType:params.childType,parent:parent)
childBlockInstance = myService.saveChildBlock(parent,params)
render (template:"childBlock", model:[childBlockInstance:childBlockInstance])
}
And it works. Both domain objects are persisted to the database, and the view is updated. But, how can I keep the previous objects in the right-side div that is getting the update? Whenever I run the function, the previous child is removed and replaced with the new one, I just want to append the new one to the end of the list.

Related

How to pass variables from view to controller without using forms in Laravel?

I'm using RESTful controller and passing variables (using forms) works just fine here.
Now for some reason I need to use simple link, created with action() and dedicated route for #create action.
My view creates few similar links with different parameters:
<a href="{!! action('\App\Http\Controllers\Admin\Franch\Category\SubCategoryController#create', array('mainCategoryName' => $mainCategoryName)) !!}">
It works, because I can see this in URL:
/create?mainCategoryName=some_sample_name
But the route doesn't pass variables to the #create action OR controller doesn't recieve it for somereason:
Route::get('admin/franch/sub_categories/create', ['uses' => 'Admin\Franch\Category\SubCategoryController#create');
I wonder how can I pass variables from views to specific controllers, using GET and POST methods?
And this is my #create controller:
public function create($mainCategoryName = false)
{
dd($mainCategoryName);
....
Which is always gives false.
Well You can create a function on the link and in that function user Ajax
$.ajax({
type: "POST",//Or Get
url: url,
data: {"var_name":variable},
success: success,
dataType: dataType
});
Now you can send you variables in the data. and then you can get value of the variable in your controller by:
Input::get('var_name');
It would be much better if you make all your "calculations" in the controller and pass a resulting value to the view like so
class SomeController() extends Controller
{
public function getView():View
{
$mainCategoryName = "fix";
$formUrl = action('\App\Http\Controllers\Admin\Franch\Category\SubCategoryController#create', array('mainCategoryName' => $mainCategoryName));
return view('view.show', compact('formUrl'));
}
...
Your mistake is in keeping meaningful data in the view, when the view should only have processed values:
<a href="{!! $formUrl !!}">
And if you really want to go "nuts", you can create a class that would generate HTML using a blade-view and the controller data and then you can execute this class in the controller to have your "partial" ready to be incorporated in a view as HTML. But not the other way round. Keep the calculations out of your views.

Grails Render Partial Template to Div

I have a form page where the user selects a filter and a table on the bottom of the page updates. Each line in the table has a hyperlink in column one that associates a line item to an item in the database. I am not using GORM.
I need to be able to send the current filters to the controller via AJAX (functioning). Then I need to render a partial template (to a div) that loads the data created by a query based on the client's request parameters.
GSP:
....
<button onClick="generate_table()" class="pure-button">Generate Table</button>
...
<div id="selection_table">This should load with data</div>
...
JS:
//Link for AJAX
var url = "${g.createLink(action:'generate_table', controller: "statusReports")}";
//The actual call
$.getJSON(url, {
period: JSON.stringify($("#period").val()),
...
...
}, function(data) {
$('#selection_table').empty();
}).done(function(data) {
//I need to load the template at this point?
})
Controller:
def generate_table(){
def table_data = statusReportsService.generate_titles(params)
// Table data is already a map
// What do I need to render here? The template is named _selectionTable.gsp and should use table_data to generate html.
}
Partial:
I still haven't written the code for this yet. For now it is just some random text to see if I can even load the template when I press the button
In your controller:
render(template: 'selectionTable', model: table_data)
In your GSP/HTML you need to use $.get and use the following:
$('#selection_table').html(data)
That should do the trick!

In coffeescript how do I make a variable available in my controller and return the results via ajax to fill a datatable?

So I have a view with a datatable (javascript library to create pretty tables) that is generated like in this RailsCast
Briefly, the datatable is created in the server side and a new class creates a json response that is rendered in the view
So in my generated view I have a link that I want to trigger an ajax event when clicked and has a data attribute,
link_to( "#{sir.sir_id}" , '#', :data => {'sir-id' => sir.id}, remote: true )
I fetch the value of that data attribute in coffeescript this way:
$("a[data-sir-id]").click ->
data_sir_id = $(this).data("sir-id")
which works fine
I want to make that value (sir-id) available in my controller so I can get the associated model objects and show them in the same view via ajax, it would fill the content of another datatable (this one would not need server-side processing)
How do I create and feed this new datatable with ajax source?
I think I could return some other json object to the view if I manage to use sir_id in my controller but the view has already rendered json when first created.
You can send the data to the controller using a post method.
$("a[data-sir-id]").click ->
data_sir_id = $(this).data("sir-id")
$.ajax
type: 'POST'
url: '/some-path'
data: {sir_id: data_sir_id}
success: console.log('success posting sir-id')
dataType: 'json'
#config/routes.rb
Rails.application.routes.draw do
post "/some-path", to: "some_controller#some_view"
end
#app/controllers/some_controller.rb
class SomeController < ApplicationController
def some_view
SomeModel.find_by_sir_id(params[:sir_id])
end
end
I would like to say that if you can form a link_to with "#{sir.sir_id}" in your view file it seems to me that the sir_id should already be available to you in your controller and you wouldn't need to use ajax. Nevertheless, I hope this ajax solution is what you were looking for :)

Codeigniter: jquery not passing its 'load' value to the controller

The issue is what I say in the title. The parameter of the index selected in the first dropdown box is not sent to the controller. Therefore the controller cannot pass any value to the model etc. If I harcode saying $pais_id = 1 and send that to the Model it works, so this means, the issue is in the controller not getting it from the jquery.
VIEW
<script type="text/javascript">
//jquery code for source list
$(document).ready(function(){
$('#country').change(function() {
if ($(this).val()!='') {
$("#source").load("/CI-3/controllers/control_form.php",{pais_id: $(this).val()});
}
});
}); // end of country and city function
</script>
The problem must be there because I don't visualize the process:
Jquery detects the changing in the select dropdown list and fetches the selected id. Alright, but what happens next ? it sends it to the controller, yes, and? the controller forwards it to the model, the model does a sql search and returns an array back to the controller and the controller forwards it to the view, but, how does #source in the line above get affected after all that?, so it will not modify itself
$source['source'] = $this->model_form->get_source($pais_id);
should be
$data['source'] = $this->model_form->get_source($pais_id);
in controller. third parameter in view is if it's returned or echo'd. all values are passed in the 2nd parameter as an array.

spine.js: "Uncaught Unknown record"

I use spine.js in conjunction with the Spine.Ajax Module to load stuff via JSON from the Server. I've probably run into some syncronisation problem. I have a sidebar which just binds to the refresh and change events and then is rendered:
Survey.bind 'refresh change', #render
I also have set up some routes, which display a survey when the user accesses it via #/survey/:id. This is my controller:
class App.Surveys extends Spine.Controller
className: 'surveys'
constructor: ->
super
#append(#sidebar = new App.Sidebar) # Sidebar to select surveys
#append(#surveys = new App.SurveysStack) # Show survey details survey
#routes
'/surveys/:id': (params) ->
#sidebar.active(params)
#surveys.show.active(params)
Survey.fetch()
As you see, Survey.fetch() is called after the initialization, which does not pose a problem to the sidebar. However, it seems, that it poses a problems to the surveys Show controller (which is called by a Spine.Stack called App.SurveyStack):
class Show extends Spine.Controller
constructor: ->
super
#active #change
change: (params) =>
# There is a bug! If Survey is not fetched when we run this,
# this throws an error.
#item = Survey.find(params.id)
#render()
render: ->
#html #view("surveys/show")(#item)
I keep getting errors from the commented part of the source: Uncaught Unknown record. Can I make the Survey.find() function block until Survey.fetch() is done?
You are correct in your diagnosis that you can't find an item before you've fetched it from the server.
The easiest solution is to bind an event to the Survey.fetch() call like so:
Survey.bind 'refresh change', #method_to_call
Let me know if that helps!
Actually the solution that worked for me is to initialize the Spine.Route.setup() after the object has refreshed. Instead of the standard call in app/index.js.coffee, it would be:
App.Survey.one 'refresh', ->
Spine.Route.setup()

Resources