how to show a response in Razor view - model-view-controller

my index view displays the IEnumberable inside an html table. with the links like edit and delete. delete links is create like below.
#* #Html.ActionLink("Delete", "Delete", new { id= SomeId })*#
Inside the controlelr action methods i am calling a service that gives me delete functionality.
CustomResponseObject resp = someService.DeleteSomething(id);
Now this CustomResponseObject has a bool indicating success or failure. and a string mentioned which business rule was negated if any. I want to propagate this message to the Razor in order to show an alert box.
what will be an ideal solution in this case. ?

I would make an ajax call and than display the message depending on the result as you indicated you wanted display the message in an alert box.
$.get("~/Delete", { id: someId }).done(function(data) {
var result = data.IsSuccess ? "success" : "failure";
alert("Your operation was a " + result);
});
Sorry I just noticed you wanted to have it available in Razor. In this case I would add a field to your Model. Than in the Razor view you can access it.
As for displaying it maybe have your JS pick up on the hidden field created using
Html.HiddenFor(m => m.IsSuccess)

Related

Spring-Boot: Redirect and Refresh model and page

I have a spring-boot application, with theyemleaf. I repeatedly update the page, and redirect it to the same page, so i expect that the elements of the page get updated:
#GetMapping("/suggested-events/vote/{eventId}")
public String voteForEvents(Model model,
#PathVariable("eventId") Long eventId,
#RequestParam(value = "message", required = false) String message ) {
log.info("The message is: "+message);
SuggestedEvent event = suggestedEventService.findSuggestedEventById(eventId);
ArrayList<SuggestedEvent> events = suggestedEventService.findSuggestedEventsByArea(event.getArea());
model.addAttribute("mainEvent",event);
model.addAttribute("events",events);
model.addAttribute("message",message);
return "/suggested-event/vote";
}
and when a button get pushed in the view it triggers the below post method:
#PostMapping("/suggested-events/vote")
public String voteForASuggestedEvent(RedirectAttributes redirectAttributes){
log.info("You have made a vote");
redirectAttributes.addAttribute("message", "Success");
return "redirect:/suggested-events/vote/1";
}
This second controller method, performs an operation an makes a message, and redirects it to the first method. So, it successfully redirected to the first method and it logs
log.info("The message is: "+message);
but it does not refresh my page, and i do not get the message as model?
When i redirect to the first method, i expect it adds the message to my models:
model.addAttribute("message",message);
But it does not added to my page
and when a button get pushed in the view it triggers the below post
method:
It sounds like this trigger is using AJAX, rather than a form submit. Doing so would match the symptoms you describe.
If you POST to /suggested-events/vote using AJAX, the server will return a 302, and the browser will follow it. However, the response for that 302 is still the result of an AJAX call. You have access to it in your success callback, but the browser isn't going to render it for you.
but it does not refresh my page
If a 302 doesn't cause your page to re-render, this also suggests you're using AJAX.
If you actually use a form submit instead, the browser will re-render using the markup returned by the successful redirect.
This can be verified by using the following two buttons in your vote.html:
<form action="http://localhost:8080/suggested-events/vote" method="POST">
<input type="submit" text="Submit" />
</form>
<button onclick="postmessage();" >Button</button>
<script>
function postmessage() {
$.ajax({
method: 'POST',
data: {},
url: 'http://localhost:8080/suggested-events/vote'
});
}
</script>
The first button will work as expected, and the second button matches the symptoms you describe.
If you are already using a form, please update the question with it (or better yet, the entire Thymeleaf template).
I had the same problem as OP described and Mike's explanation brought me in the right direction.
I am reading a db-table and populating it with thymeleaf using th:each. I wanted to add a javascript-confirmation before deleting an item. Sending an ajax GET without an event-listener and reloading with location.reload(true) didn't reach the #GetMapping("/delete/{id}") in the controller.
This SO-thread gave me the answer to the ajax-call.
<a class="btn btn-danger" href="#" th:onclick="|confirmDeletion('${u.id}')|"></a>
<script th:inline="javascript">
function confirmDeletion(id) {
if (confirm("Delete this id? " + id)) {
var http = new XMLHttpRequest();
http.open("GET", "/delete/" + id, true);
http.addEventListener("readystatechange", function() {
if (http.readyState === 4 && http.status === 200) {
window.location.reload(true);
}
});
http.send();
}
}
</script>
there are many ways to redirect page in Spring, but be sure if the model attribute off message its passing correctly to FrontEnd or passing like parameter to another handler , you can see this document : http://javainsimpleway.com/spring-mvc-redirecting-model-attributes-from-one-controller-to-other-controller/ , hope this is useful !!

show success message on same page after adding recording without reloadin the site in cakephp 2.x

I want to add a show sucess message using :-
session->flash(); ?> in view and added the message in controller :-
Session->setFlash("Record has been saved successfully."); ?>
But I donot want to reload the whole page.
I am just inserting the new record using ajax.. and refreshing the div having list of all record.
session->flash(); ?> this works if i reload the whole page.
how can I show message once the record is saved using ajax.
Solutions (i recommend the first one):
Create AJAX method in controller that return 200 code with JSON/HTML record's data or any other error code if sth goes wrong. Then in js do:
$.ajax({ ... }).done(function( data ) {
// Success, show the record and message
$('#flash').text('Success!').show();
// ...
}).error( function() {
// Error
$('#flash').text('Error!').show();
});
Refresh the records list by calling ajax method and return not only the view with list of all records, but also a flash message (in the same view). Then show it or move using javascript.

Django / Closure: How to validate AJAX form via AJAX?

I'm using Django and Google's Closure javascript library, and I want to do some form processing via AJAX.
Currently, I have a button on the page that says "Add score." When you click it, it fires off a goog.net.Xhrio request to load another URL with a form on it and display the contents in a little pop up box, via a call to loadForm().
loadForm = function(formId) {
var form = goog.dom.getElement(formId);
goog.style.setElementShown(goog.dom.getElement('popup-box'), true);
goog.net.XhrIo.send(form.action, displayForm, form.method);
}
displayForm = function(e) {
goog.dom.getElement('popup-box').innerHTML = e.target.getResponseText();
}
The Django form that gets loaded is a very basic model form, with a simple "score" attribute that gets validated against a number range. Here's the code I have to process the form submission:
def Score(request):
obj = ScoreModel.get(pk=request.POST['obj_id'])
form = ScoreForm(request.POST, instance=obj)
if form.is_valid():
form.save()
messages.success(request, 'Score saved!')
return shortcuts.redirect('index')
else:
context_vars = {'score': score, 'form': quarter_form}
shortcuts.render_to_response(
'score_form.html', context_vars,
context_instance=context.RequestContext(request))
This would all work fine if the form to enter the score itself was just displayed on the page, but because it is an AJAX popup, it doesn't work properly. If I just do a simple form submission (via HTML submit button), it works fine if the data is valid. But if the data isn't valid, instead of displaying the form with errors in the popup, it just loads only the text that would've been displayed in the popup - the form with errors - in the main browser window rather than in the popup.
Conversely, if I submit the form via my loadForm() JS method above, it works perfectly fine if the form is invalid (and displays the invalid form in the popup box), but doesn't work if the form is valid (because the main index page ends up getting displayed in my popup's innerHTML).
I can't seem to figure out how to get the code to work in both scenarios. So, how can I have my cake and eat it to? :)
This is kind of a strange issue, so if I didn't explain it well enough, let me know and I'll try to clarify. Thanks in advance.
I got it to work. The basic trick was, if the form submission was successful, instead of returning a redirect I returned a basic response object with a redirect status code and the URL to redirect to. Then I modified my displayForm() to look for that and redirect if it was found.
Here's the modified code from the Score() function:
if form.is_valid():
form.save()
messages.success(request, 'Score saved!')
redirect = shortcuts.redirect('index')
return http.HttpResponse(content=redirect['Location'],
status=redirect.status_code)
And the modified displayForm():
var displayForm = function(e) {
var responseText = e.target.getResponseText();
if (e.target.getStatus() == 302) {
// If this was a redirect form submission, the response text will be the URL
// to redirect to.
window.location.href = responseText;
} else {
// Regular form submission. Show the response text.
goog.dom.getElement('popup-box').innerHTML = responseText;
}
};

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.

codeigniter: Return form validator results as string

I'm new to codeigniter so sorry for the simple question.
I want to run formvalidator for my ajax process. How can I return the valdiation errors as JSON? Is there a better way to do this?
Thanks
you haven't really stated what you are doing. i am going to assume that you have a form that you want to save data in, using ajax, so that you don't have any of those pesky save/submit buttons. also, i am guessing that you have some sort of .change() handler that sends the form element to the ajax handler as a post variable as a name/value pair.
the problem you will run into, is that when you run the form validator on your data it will always fail. because the form validator needs all of the fields for that form, and you will only send one piece of data at a time.
normally in the code igniter example code you check to see if the 'run' method passess or not. in your case it doesn't really matter because it will always fail, so don't bother checking. here is a snippet of some example code
$this->form_validation->run('form'); // it is likely that the form won't validate, but thats ok.
$validation_error=form_error($field_name);
if($validation_error){
$feedback = 'Field <strong>NOT</strong> saved.';
}else{
// no errors, we can save.
$this->my_model->set_field($id,$field_name,$field_value);
$validation_error=' '; // this is set so if the field was initially not validated, and it is later, the validation message goes away.
$validation_element = '#'.$field_name;
$feedback = 'Field saved.';
}
....
echo json_encode(array('feedback'=>$feedback,'validation_element'=>'#'.$field_name,'validation_error'=>$validation_error));
break;
in my snippet, a json object is returned to the ajax post. in the jquery ajax post,the success handler has this snippet of code.
try{
var json = $.parseJSON(data);
if(typeof(json.container)==='string'){
var container=json.container;
}
if(typeof(json.html)==='string'){
var con = $(container);
$(con).html(json.html);
}
if(typeof(json.feedback)==='string'){
display_feedback(json.feedback);}
if(typeof(json.validation_element) ==='string'){
// assumes that if a validation_element object is returned, it has a paired validation_error element.
$(json.validation_element).closest('.col_b').nextAll('.validation_error').first().html(json.validation_error);
}
}
catch(err){
display_feedback(err);
}
in my form, i have a three column format, where:
<div class='col_a'>label</div>
<div class='col_b' >input, id = field_name </div>
<div class='col_c validation_error'>validation text</div>
hopefully that makes some sense to you.

Resources