Adapt page display along with jQuery result - html

I have a Django project which executes a task and then renders a page in which I want to display different things following the state of the task.
To show an example of what I want, I have these three div, with each one being displayed for a particular task state :
<div id="SUCCESS">
<!-- What I want to display when the execution of my task succeeded -->
</div>
<div id="FAILURE">
<!-- What I want to display when the execution of my task failed -->
</div>
<div id="EXECUTING">
<!-- What I want to display when my task is still executing -->
</div>
I finally found a way of doing that by adding a style="display:none" on the div for the success and failure state, and updates the display of the divs when the state of task changes.
For example, at first, only the div with id="EXECUTING" will be displayed, and then when the task state changes to 'failed', the div with id="EXECUTING" will have its display attribute changed to display:none and the div with id="FAILURE" will be changed to display:""
The code for doing this is the following :
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
let task_id = '{{ task_id }}'
updateState(task_id)
function updateState(task_id) {
$.ajax({
url: "{% url 'scripts:task_status' task_id %}",
type: 'GET'
})
.done(response => {
if(response.state == "FAILURE" || response.state == "SUCCESS"){
document.getElementById("EXECUTING").style.display = "none"
document.getElementById(response.state).style.display = ""
return
}
else{
// rerun every 100 milliseconds
setTimeout(function() {
updateState(response.task_id)
}, 100)
}
})
}
})
</script>
And the view from where the task_status is taken is this one :
def task_status(request, task_id):
task = AsyncResult(task_id)
response = {
'task_id': task_id,
'state': task.state,
'info': str(task.info),
}
return JsonResponse(response, status=200)
What I want to know is, is there another way to change what's displayed on the page without using this trick of modifying the display attribute of my divs ?
That's my first time using jQuery and js so there's probably something I'm not understanding well, which is why I'm asking this.
Thanks for your help

Related

How do I call a button once without going into an infinite loop (Angular)?

Maybe the title is not very clear but here is what I have.
I have a scenario where I have a button in HTML, I call the service when the button is clicked and I want HTML B to know when the button from HTML A is clicked.
A.html
<button (click)="passData(a,b,c)">
B.html
<div *ngIf="fromA()" >
{{ showResult() }}
</div>
A.component.ts
passData(a: string, b:string, c:string) {
this.Xservice.getData.subscribe(data => res = data);
}
B.compoent.ts
fromA() {
this.xService.subscribe( data => res = data ); // This is observable
if (res !== undefined ) {
console.log("true returned");
return true;
}
}
So from this above I have checked the console and it is flooded with logs "true returned" and I was wondering how do I just to call this once when button from A.html is pressed?
You don't need to use *ngIf. You can just have
fromA():string {
if // Whatever logic you do
return "block";
else return "none";
}
Now I'm assuming what you mean is you want HTML B to only show when fromA() is clicked. So you can do this:
<div [display] = "fromA()">
{{ showResults() }}
</div>
Basically, you just set the property display to whatever result fromA() has. If the button is not clicked (returning none), then the HTML is not displayed (display=none). If it is clicked (returning inline), then the HTML is displayed (display=inline).
Of course, you could use any other display properties besides inline to show the HTML.

how to pass the data from parent page to child using reactjs?

I would want to know when we open a html page ,if it is possible to pass the details from parent to child page using reactjs.I opted to open in a html page rather than modal pop up because of heavy data to be displayed in the page.
Below is my code :
I would want the value in variable "message" to be passed to the html page i would be opening. this message can be lengthy one having more than 3000 characters.
var App = React.createClass({
openModal: function () {
var message = "hello xyz";
window.open('../Scripts/Custom/Details.html', '', 'toolbar=no,status=0,width=548,height=325,menubar=no,location=no,resizable=yes');
},
render: function () {
return (
<div>
<button onClick={this.openModal} >Open Modal</button>
</div>
);
}
}
);
ReactDOM.render(<App/>, document.getElementById('container'))

How to prevent Ajax redirects to another page in Asp.net Mvc 5

I have two forms in a single page.One of them is for adding comment, the other one is the main blog content as follows.
My aim is to have blog page with adding comment functionality.When user adds a comment , I want to post the comment another controller using ajax.When providing this functionality,I want user stay at the same page and update comments partial view at the page.However I couldn't achieve this with the codes below.
Main Blog Content
#model WforViolation.Models.Violation
#{
ViewBag.Title = "Details";
}
<h1>#Model.Title</h1>
<p class="lead">
Posted by #Model.CreatorUser.UserName
</p>
<hr>
<!-- Date/Time -->
<p><span class="glyphicon glyphicon-time"></span> Posted on #Model.CreationDateTime <span class="glyphicon glyphicon-flag"></span> #Model.Severity Severity <span class="glyphicon glyphicon-comment"> </span> #Model.Comments.Count Comments </p>
<p><span class="glyphicon glyphicon-eye-open"> People Viewed</span></p>
<hr>
<!-- Preview Image -->
<img class="img-responsive" src="#Model.Picture.FirstOrDefault().MediumPath" alt="">
<hr>
<!-- Post Content -->
<p class="lead">#Model.Title</p>
<p>#Model.Description</p>
<hr>
<!-- Blog Comments -->
<!-- Comments Form -->
#Html.Partial("_AddComment", new WforViolation.Models.CommentViewModel() { ViolationId=Model.Id,Content=""})
<hr>
<!-- Posted Comments -->
<!-- Comment -->
#Html.Partial("_Comments",Model)
Add Comment View
#model WforViolation.Models.CommentViewModel
<div class="well">
<h4>Leave a Comment:</h4>
#using (Ajax.BeginForm("AddComment", "Comment", null, new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "SuccessMessage",
OnFailure = "FailMessage"
//UpdateTargetId = "resultTarget"
}, new { id = "MyNewNameId", role = "form" })) // set new Id name for Form
{
#Html.AntiForgeryToken()
<div class="form-group">
#Html.TextAreaFor(model => model.Content, new { #rows = 3 })
</div>
<button type="submit" class="btn btn-primary">Submit</button>
#Html.HiddenFor(model=>model.ViolationId)
}
</div>
<script>
//\\\\\\\ JS retrun message SucccessPost or FailPost
function SuccessMessage() {
alert("Succcess Post");
}
function FailMessage() {
alert("Fail Post");
}
</script>
My Comment Controller
[HttpPost]
public ActionResult AddComment(CommentViewModel commentViewModel)
{
Comment comment = new Comment();
var userID = User.Identity.GetUserId();
if (!string.IsNullOrEmpty(userID))
{
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var currentUser = manager.FindById(User.Identity.GetUserId());
comment.ApplicationUser=currentUser;
}
var violationId = commentViewModel.ViolationId;
Violation violationCommentedOn = context.Violations.Where(x => x.Id == violationId).FirstOrDefault();
comment.Violation = violationCommentedOn;
context.Comments.Add(comment);
context.SaveChanges();
var result = Json(
new
{
Success = true,//success
StatusMessage = "Object created successfully"
});
return result;
}
When I added a comment it redirects me to another page called localhost/Comment/AddComment its content is just the Json.
Is it ever possible to just retrieve JsonResult and stay at the same page ?
Or I cant post a form data using ajax and not redirecting to another page?
I know there are similar questions but I couldn't find the exact answer.
Any help is appreciated.
You are using Form in your Add Comment view and that form calls AddComment in your controller that returns a json data. Forms do cause a redirect to the method they call and because your controller is returning json, the browser simply displays it on a new page.
You may either return a view from your AddComment method in the controller. This view could be the comment view. This way the control will redirect back to the same view with new data. This is a sample code, in practice, this code should be pretty much the same as you may have it in ShowAddCommentView method of the controller.
CommentViewModel commentVM;
/// populate commentVM from DB or comment store
/// remove return result;
return View("AddCommentView", commentVM); /// your add comment view name
Or instead of using Form to send data to the controller, use a simple ajax call without using AjaxForm. When a user clicks on the button, you can call Ajax in javascript. I have a jquery example. parameter1, parameter2 are the same as properties of your CommentViewModel. Of course, you can also use json data parameter in this call instead passing parameters like in this following sample.
$.ajax({
url: '/Comment/AddComment?parameter1='+ pvalue1 + '&parameter2=' + pvalue2,
async: false,
cache: false,
type: 'POST',
success: function (msg) {
/// this msg object is actually the json object your controller is returning.
}
});
This call will not cause the page to redirect. When json is returned, you may write code in javascript to do something with that data, perhaps display it back on the add comment page.
It is possible to make this ajax call from asp.net directly without using a separate javascript. But I can't seem to remember it exactly right now.

Express framework: How to capture a value on clicking an image and use that value to fetch database details into another html page

I have the following ejs file and I want to capture the NAME field value inorder to fetch the respective details from database and display onto another page. I know how to do this using form tag, but I am unsure how to capture in this case. Any help would be appreciated. Thanks.
search.ejs file:
<a href="/menu/<%= tablelist[i].NAME %>">
<img alt="<%= tablelist[i].NAME %>" class="restaurant-card-cover" src="<%= tablelist[i].IMAGELINK %>" style="height: 115px;">
<div class="restaurant-card-content-text">
<div id="catererName" class="restaurant-card-name heading-color" variable="<%= tablelist[i].NAME %>"><%= tablelist[i].NAME %></div>
<div class="card-description"><%= tablelist[i].DESC2 %></div></a>
In app.js file, I added the following:
app.get('/menu/:name', routes.menu(ibmdb,connString));
And, I have another folder "routes" and I am mentioning all my SQL queries in index.js file. Here it is:
exports.menu = function(ibmdb,connString) {
return function(req, res) {
var name = req.param.name;
ibmdb.open(connString, function(err, conn) {
if (err ) {
res.send("error occurred " + err.message);
}
else {
conn.query("SELECT ITEM_NAME, PRICE FROM HOMEBASEDAPP.MENU WHERE CATERER_NAME='"+name+"';", function(err, tables, moreResultSets) {
if ( !err ) {
res.render('menu', {"tablelist" : tables, name: name});
} else {
res.send("error occurred " + err.message);
}
/*
Close the connection to the database
param 1: The callback function to execute on completion of close function.
*/
conn.close(function(){
console.log("Connection Closed");
});
});
}
} );
}
}
I tried to print the "name" in menu.ejs file but its not getting the value.
This is done on the frontend.
One way to do that would be to add a data tag, say on the same div where you want to capture the click. I will take this div from you, but you can adapt:
<div class="restaurant-card-name heading-color"><%= table[i].NAME %></div>
Now, add a data tag, something we can put data in:
<div class="restaurant-card-name heading-color" data-restaurant="<%= table[i].NAME %>">
<%= table[i].NAME %>
</div>
Now, your div will render the name as a data attribute.
Then you have some click handler. Assuming jQuery here, you can grab a click on such divs. This bit javascript loaded when the dom is ready should do it:
$('.restaurant-card-name').click(function(evt) {
evt.preventDefault();
var name = this.data('restaurant');
$.ajax({
url: '/where/you/want/to/fetch/stuff/from',
method: 'POST',
// other stuff here, like displaying the data or image in a modal or similar.
})
});
Alternatively, if you want to just navigate to another page, as you say, there are a few steps.
First one is to prepare the url instead of the data attribute:
<a href="/my-restaurant-handler-route/<%= table[i].NAME %>">
<div class="restaurant-card-name heading-color">
<%= table[i].NAME %>
</div>
</a>
Now, your href value will be, for example, /my-restaurant-handler-route/mcdonalds
The second step is to prepare a route on the server. Since you're using ejs and you've tagged Node, I'll assume you're using express.
You need to prepare a route handler like this:
app.get('/my-restaurant-handler-route/:name', function(req, res) {
// param is on the request, whatever you named it after the `:` in app.get.
var name = req.param.name;
// now do the db dance
database.getData({restaurantName: name}).then(function(data) {
// you have the data, put it on the response or render it:
res.render('restaurant-handler.ejs', {data: data});
});
});
That is one way to do it. There are others, but you'll have to specify your situation a bit more for more details.

two submit buttons in one form executing two different servlets

i have a form having two submit buttons.
one for creating a user and other for logging in an existing user.
how can i fire two different servlets from these two buttons keeping them in one single form??
like if create button is clicked then create.java is executed
and if login button is fired then login.java is executed
If you want to go with JavaScript, this is an example using jQuery ajax:
$(document).ready(function() {
$('#id_of_your_button').click(function() {
// do some stuff here, e.g.
var str = $("#your_html_form").serialize();
$.ajax({
type: "POST",
url: "url_to_your_file",
data: str,
success: function(msg) {
//...
}
});
}
// prevent the default action, e.g., following a link
return false;
});
});
EDIT:
if you want to do it without JavaScript, you can do it like <input type="button" value="register">
Otherwise, if you want the form submitted right away, you could only take two forms, or use JavaScript (also in other ways, as you could e.g. change the action-url with JavaScript depending on which button the user clicks, etc)...
... but there is only one "Submit" button allowed per HTML-form.
Check this tutorial about the onclick event for HTML buttons: Here
Example:
<script type="text/javascript">
function copyText()
{
document.getElementById("field2").value=document.getElementById("field1").value;
}
</script>
<button onclick="copyText()">Copy Text</button>
Source