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.
Related
My main page renders a list of data coming from controller with foreach
#foreach ($sales as $sale)
<button id="{{$sale->id}}" #click="editClicked({{$sale}})">
#endforeach
I have an edit component placed on the page like this, I display it modally via showEditModal conditional
<edit v-if="showEditModal" #hide="showEditModal=false"></edit>
The component in brief is declared in Edit.vue:
<template name="edit">
...
</template>
This is simply a standard form with input fields, bound via v-model to the sale.
Essentially it is an update form, I intend to load the data from the main page into each input field to be edited.
My app.js simply sets showEditModal = true, in order to display the edit form on top of the main page.
Basically i don't want to have to call controller via GET method on loading the modal since i already have the data in the main page as $sale object, so im just wondering how do I pass in the $sale to the Edit.vue component ?
I thought that in the <edit> component usage, it would need to bind the sale object, however I'm unsure how that would work since it comes from the foreach loop.
I do, also have the data in the app.js method as passed in via #click="editClicked({{$sale}})", but again, i'm unsure how to use that to pass through ?
You're right, you would want to pass the current sale item as a property to the edit modal. What I would do is add a data property to your main Vue called selectedSale.
data:{
selectedSale: null
}
Then in your editClicked method, set selectedSale
methods:{
editClicked(sale){
this.selectedSale = sale
...
}
}
Finally, pass it as a property.
<edit :sale="selectedSale" v-if="showEditModal" #hide="showEditModal=false"></edit>
Is it possible to insert a view using javascript?
I wish to perform an ajax call, get the data, then insert a view in to a page and provide the data from the ajax call to that view?
Is this possible?
Yes you can use the render method on a view. Like so;
$view = View::make('your.view')->render();
And then return the html (which is the output) from your controller method by returning the data stored in $view.
If you need to add any data to the view just add the second parameter to the view make.
alternatively you can do this,
set the route for pages you want to call.
e.g.,
Route::get('callajax','PagesController#showAjax');
and then in PagesController#showAjax you return the view.
e.g.,
public function showAjax()
{
return View::make('ajaxpages');
}
and then in ajax call you code this
$.ajax({
url:'callajax',
});
I have a section of a form that dynamically loads different sets of fields based on the user's selection in a control. I'm using a javascript event handler to detect when the selection changes, and using AJAX (with HTML payload) to pull in the proper set of fields.
I would like to be able to use Laravel's Form::getValueAttribute() method to automatically fill in the form fields' values in both the static and dynamic form parts. However, the partial view that is loaded by my AJAX call does not have the same instance of the Form class as the view with my main Form, so I can't simply call getValueAttribute() in the partial.
My thought is to make the AJAX call a POST, and serialize the necessary data (a subset of Input::old() or the model data depending whether the page is loaded as the result of validation errors, or an UPDATE request) to send along with the POST so that the HTML fragment I get back has the values set properly.
Is this the best way to get what I want? If so, does Laravel have any tools to help with the serialization of form data? If not, what might be a better approach?
I've found an approach I like better. When the view is loaded normally I use AJAX as usual to load the partial. But when the view is loaded for a validation post-back or for editing, I use Laravel's Views' nest method to nest the partial view containing the proper fields directly into the response. The partial then has access to all the Input and error data I need. The user is still able to change the field set as usual but I put up a confirm prompt for them if they have already set some values in a field set they previously selected. If they decide to proceed anyway, the field set is cleared and a new field set is brought in via AJAX as usual.
My code looks something like this:
Controller:
public function newThing() {
if ( Request::session()->has('errors') ) {
// this is a validation post-back
return View::make('thing')
->nest('fields', 'fields_partial');
} else {
// just a normal unfilled form
return View::make('thing');
}
}
public function editThing() {
return View::make('thing')
->nest('fields', 'fields_partial');
}
View: thing.blade.php (just a snip of it)
...
<form>
...
<select id="picker">...</select>
<div class="sub-fields">
{{ isset($fields) ? $fields : '' }}
</div>
...
</form>
...
<script>
$('#picker').change(function() {
// if any .sub-fields inputs have been changed, get confirmation from the user
// if user confirms, do ajax stuff to replace .sub-fields contents with new field set
// otherwise cancel the change
});
</script>
Inside a component's view, I have something like this:
<?php echo TestcompHelperFind::loadStates(...); ?>
<?php echo TestcompHelperFind::loadCounties(...); ?>
The above static functions load <select> dropdowns with the state names and countries respectively.
The class TestcompHelperFind is located in the file /administrator/components/com_testcomp/helpers/find.php.
How do I load States dropdown list based on the country selected using AJAX? I'm not sure what url I should provide in the ajax function.
On the client, you will need a function that watches the country select for changes, and when it happens calls the appropriate url with a callback that will populate the counties select.
On the server, you need to output the select content.
Since you have the html output already working, let's use this approach. As an alternative you could have your server method return a json object and use the javascript to parse it and populate the select. But let's stick to html communication, i.e. the server returns the html contents of the select.
1. On the server
1.a. Output the counties select
We only need to return the result of the TestcompHelperFind::loadCounties(...); to the ajax call. This is achieved easily writing a new method in the component's controller, i.e. the controller.php in the root of the component folder or one of the sub-controllers if appropriate. It's up to you to place it in a meaningful spot.
Inside the controller simply add a new public task such as
class SomethingController extends JController
{
public function getCountiesHTML() {
$input = JFactory::getApplication()->input;
$country = $input->getCMD('filter_country');
// load helper if necessary, then:
echo TestcompHelperFind::loadCounties($country);
exit; // this will stop Joomla processing, and not output template modules etc.
}
Please note the exit; at the end, this will make Joomla output only the component's output (our echo) and not the whole template/modules etc.
1.b Add an ID to the country and county selects so that it will be possible to manipulate them on the client; I'll assume filter_country and filter_county ;
2. On the client
you will want to invoke the url
index.php?option=com_something&action=getCountiesHTML&filter_country=UK
when the country select is changed. It will also need to cancel any pending requests to avoid overlapping messages. To keep things simple, let's assume you use a library to handle Ajax, I'll write an example for jQuery:
<script>
var xhr;
jQuery(function($) {
$('#filter_country').change(function(){
var filterCountry = $('#filter_country').val();
if (xhr && xhr.abort) {xhr.abort();xhr=false;}
xhr = jQuery.ajax(
url: 'index.php',
data: 'option=com_something&task=getCountiesHTML&filter_country='+filterCountry,
success: function(data){
jQuery('#filter_county').replaceWith(data);
}
);
});
});
</script>
For cancelling the previous request, please see a dedicated answer such as this one.
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.