drop down using ajax and css - javascript

I make a list and make it hyperlink using #Ajax.ActinLink so that on click nested list can be opened using Partial View. When I click on the first list option partial view is displayed but when I click on the second list option, partial view is not opened Here is my code:
<ul id="menu">
<h3>Categories</h3>
#foreach (company company in #Model)
{
<li>
#Ajax.ActionLink(company.COMPANY_NAME, "All", new AjaxOptions()
{
HttpMethod = "GET",
UpdateTargetId = "yr",
InsertionMode = InsertionMode.Replace
})
<ul class="sub-menu">
<li id="yr"></li>
</ul>
</li>
}
</ul>
here 2016 and 2017 comes from the partial view but it does not display when i click on the BMW

I see that you're using C# razor syntax, I'm going to infer you're using some form of ASP.NET and creating an application in that manner. They're much better ways to make this call than using AJAX. AJAX is outdated and isn't the best implementation to use when you're working with C# razor syntax. I would make the HTTP GET request call to your controller using JS or angularJS. Take a look at this example of loading comments in a web page using an HTTP GET request below.
<script type="text/javascript">
// Http GET Request to load the comments at each page refresh.
var app = angular.module('myArticleViewer', []);
app.controller('myArticleController', function ($scope, $http, $timeout) {
try {
$http({
method: "GET",
url: "/Documentation/Comments/#Model.ArticlesViewModelID"
}).then(function mySucces(response) {
$scope.data = response.data;
});
} catch (e) {
alert("Error: Bad Request");
}
});
</script>
You're going to make the HTTP GET request to a controller action, in the corresponding controller responsible for the page. Then you're going to return a list of hyperlinked URLs as the value for the controller action you're making the HTTP GET request to. Then, using angularJS and ngDirectives, you're going to write HTML code for a dropdown box and iterate through the data returned from the angularJS HTTP GET request call. This will provide you with the result you seek.

Related

C# & AJAX- Update view with new model

I have a .NET web app that simply works in this way: Page A where I send an input (barcode scan result) and then it goes to Page B to load a table created by many queries and inserted results in a view model.
What I want to do is that when I go to scan another barcode while I am in Page B, it has to do the same operation that it does with Page A: Page B with new results. It means that through AJAX I send a parameter to the controller, it makes his queries and operations and then it has to return a View with the new View Model and reload the page. Problem it is that it doesn't reload the page with new View Model, but it stays with the old data.
I also tried putting the table in a partial view and try to make it reload after every input in Page B, but it doesn't load all the javascript code in the page which is the most important thing I need to keep (editing table values etc..). Javascript code is contained in Page B, not in partial view ".cshtml".
AJAX CODE: I send an ID to the controller, and it returns an HTML which I put on the ID of a div containing the partial view of the table.
$.ajax
({
type: 'POST',
url: '#Url.Action("QueryBollaTestP", "Bolla")',
data: JSON.stringify({ 'NumBolla': evt.state.code }),
contentType: 'application/json; charset=UTF-8',
dataType: "html",
success: function (data)
{
$(".tesst").html(data);
},
})
Controller:
[HttpPost]
public ActionResult QueryBollaTestP(string NumBolla){
......... all operations and queries..... going to pickingViewModel for the table
return PartialView("_BollaTable", pickingViewModel);
}
Is there anything for that? Doesn't matter if it is with the use of partial view or not, important is it will update the model of the page with the correct data and then it loads the javascript code.
Is the only variable the bar code (NumBolla?)? What is the purpose of Page A?
I would think you only need a single View.
public async Task<ActionResult> PageA(int NumBolla){
..do stuff create model
return View(model)
}
to load a new bar code scan via js: window.location.href = "../PageA/" + NumBolla;

Adding Angular to an existing CodeIgniter project

I am using CodeIgniter on a daily basis as a frontend and backend development framework and I'am using dynamic frontend stuff like reacting forms and Ajax very rarely. But I need to say: I love it because it's most user-friendly and that's the key of good frontend development.
With forms for example I'm going with to good old way by posting to e new file, validating and pushing it to the database or wherever.
I'll like the way of validating it and giving feedback while the user is typing and this is where I came to angular.
First and foremost I like Angular for reacting forms. For the beginning I'll use it with forms only.
How can I combine CodeIgniter's folder structure with angular's folder structure so that I can use first and foremost CI but angular for the form handling.
Angular usually serves the content from AJAX calls, so you should use CodeIgniter as the webservice API framework.
Let's think you're going to implement a simple list:
First, create your Angular project using sample data (by hardcoding values, for example). When you have your product list working.
HTML
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.items = [
"One",
"Two",
"Three",
"Four"
];
});
angular.bootstrap(document, ['myApp']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MainCtrl">
<ul>
<li ng-repeat="item in items">
{{item}}
</li>
</ul>
</div>
For now, elements are hardcoded. But we need this elements to be dynamic, with CodeIgniter served data.
For that, create a folder named 'api' at the 'www' folder of your server. Then upload all the CodeIgniter source files. If you have done it correctly, you should see the 'Welcome' controller when you access 'http://yourdomain.com/api'.
For this, I recommend to use this CodeIgniter plugin that allows you to easily create a Webservice API Rest. The main objective is to serve a json object when the Angular asks for data. Then Angular will do the rest.
A brief example:
<?php
header("Content-type: application/json");
class List extends CI_Controller
{
function __construct()
{
// Here you can load stuff like models or libraries if you need
$this->load->model("list_model"); // For example
}
/**
* This method receives a parameter so it can
* filter what list wants the client to get
*/
public function list1($list_number)
{
$list = $this->list_model->getList($list_number);
// If list not exists
if ( empty($list) ) {
$this->output->set_status_header(404);
echo json_encode(
"success" => false,
);
return;
} else { // If has returned a list
// CodeIgniter returns an HTTP 200 OK by default
echo json_encode(
"success" => true,
"list" => $list,
);
return;
}
}
}
Now we can take the info by AJAX. The same code above but changed to get the remote data:
var app = angular.module('myApp', []);
app.controller('MainCtrl', ['$scope', '$http', function($scope, $http) {
// Replace link bellow by the API url
// For this example it would be:
// http://yourdomain.com/api/list/list1/1
$http.get("https://codepen.io/anon/pen/VExQdK.js").
success(function(res) {
console.log(res);
if ( res.success == true ) {
$scope.items = res.items;
} else {
$scope.items = [];
}
});
}]);
angular.bootstrap(document, ['myApp']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MainCtrl">
<ul>
<li ng-repeat="item in items">
{{item.name}}
</li>
</ul>
</div>
This way you can get a completely functional CodeIgniter API working with Angular. I like to organize methods in different controllers so code is structured to be "readable".
To modify or delete data on the server, you can use $http.post and send parameters to tell CodeIgniter which kind of operation has to do. Remember to use session data to protect the ajax calls of modifying/deleting information (for example if a user tries to update other user's info).
This is not a definitive way, but it's mine. I hope it helped you.

Thymeleaf page refresh followup - Now with AJAX

As a followup to my earlier question about using Thymeleaf and preventing page refresh:
http://forum.thymeleaf.org/Preventing-page-refresh-Thymeleaf-amp-Spring-MVC-td4029155.html
Basically I had a working Spring MVC app that uses Thymeleaf to save form data. When the user saves the data the page would refresh (since I wanted to leave them on the page for more edits) and I wanted to eliminate the page refresh.
I have coded up some Javascript to use JQuery Ajax to post the data to my Spring MVC Controller. The trick seemed to be to not use a submit button, just a regular button and bind a JS function to it for sending the data to the server.
It all seems to work perfectly, but I want to make sure I understand what is happening. In particular I'm wondering if Thymeleaf is now redundant. I don't think it is because when I initially load the page Thymeleaf is still bound to the data bean. From using the debugger on the server side in the controller it looks like the post request calls the mapped method and passes in the data to the model.
I would appreciate your comments on whether or not this is the correct way to accomplish this.
Finally, how do I handle an error, say for example the repository fails to persist the data for any reason?
Thanks very much.
Here are the important parts of the form:
<FORM id="adminDataForm" action="#" th:action="#{/admin_ajax}" th:object="${adminFormAjax}" method="post">
<input type="button" value="Save Changes" id="post" onClick="sendData()" />
Here is the Javascript:
function sendData()
{
$.ajax(
{
type: "POST",
data: $("#adminDataForm").serialize(),
cache: false,
url: "/admin_ajax",
success: function(data)
{
alert("Your changes have been saved");
},
error: function()
{
alert("Error - Data not saved");
}
});
}
Here is the controller:
#SessionAttributes("adminFormAjax")
#Controller
public class TestController
{
final static protected long INDEX_RA = 2L;
#Autowired
private AdminDataRepository rep;
#RequestMapping(value="/admin_ajax", method=RequestMethod.GET)
public String adminFormAjax(Model model)
{
AdminData ad = rep.findById(INDEX_RA);
// If there is no configuration record, create one and assign the primary key
if(ad == null)
{
ad = new AdminData();
ad.setId(INDEX_RA);
}
model.addAttribute("adminFormAjax", ad);
return "adminFormAjax";
}
#RequestMapping(value="/admin_ajax", method=RequestMethod.POST)
public #ResponseBody AdminData adminSubmit(#ModelAttribute("adminFormAjax") AdminData ad, Model model)
{
rep.save(ad);
model.addAttribute("adminFormAjax", ad);
return ad;
}
}
So breakdown of answer.
Thymeleaf not redundant, it will still render the HTML page prior to sending to client. Ajax just does the further processing for you on client side.
You can use submit button as well, you just need to ensure your form is properly structured and you have javascript listening for your submit button click e.g.
$("#submitbutton").on('click', function (){//do stuff});
You handle any and all exceptions/issues within your Ajax controller as you would with standard controller. You need to separate issue handling at different levels. e.g. respository level issues should be managed at rep level, controller/pojo should be at controller level (or pojo if you using one for processing). You should also be capturing any exceptions through a global medium (e.g. ControllerAdvice).
Any issues/errors you pick up you should be communicating back via your return call in adminSubmit, and managing the relevant client response in ajax.

How to submit form and update element on the page without refresh, in Rails 4

I'm having a lot of trouble trying to do something that I imagine would be fairly simple.
I have a list of items, let's say, todos. At the bottom of that list I have a text field where I add new items to that list. I want to make it so that the new items are added to the bottom of that list dynamically, without a full page refresh, like in a chat window.
I made the submit form remote: true and it successfully submits without reloading the page, but I can't get the new item to appear at the bottom of the list at the same time. I have to refresh the page to see the changes.
I tried a few different approaches I found on SO (there's no shortage of similar questions here) and the web, and even a gem called Sync, but each of them had errors and problems of their own and I couldn't get any to work properly. Each of them could be its own SO question. So instead I ask: Is there a "recipe" that is sure to successfully implement this in Rails 4?
let's say, now you have a user form to submit,
<%=form_for #user,remote: true%><%end%>
And you also have a controller,
UsersController
In your controller, you have a function,
def create
#something
end
which is for the form.
the only thing you need is to modify the function like
def create
#something
respond_to do |format|
format.js
format.html
end
end
then in your view side, under directory of view/users/ , create a create.js file, in the file, you can do the js action, like get the new record, and append the new record to the users list.
reference:
http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#form-for
There are various ways to do what you are asking. My approach would be:
Create an AJAX call to the controller that passes the parameters of the form
Inside the controller, you save/update things and then return a JSON object
On the success callback of the AJAX function, you append a list item/table row, using the object values
The code could be something like this:
model.js
$(function() {
$("#submit_button").on("click", function(event) {
event.preventDefault();
$.ajax({
type: "POST",
url: "your_controller_url",
data: "your_form_data"
success: function(result) {
// Append the result to a table or list, $("list").append(result)
},
});
});
});
controller.rb
def your_action
# Do your stuff
# return JSON to the ajax call
end
Well, this is just a skeleton. I prefer doing things this way. (Because i hate the js.erb approach)
Here is rails 5, hope it will help someone ( it still works on rails 4 ):
Try this ajax example:
In 'routes.rb':
# set the route that ajax can find the path to what controller in backend
get '/admin/some_great_flow', to: 'great_control#great_flow'
In 'great_control_controller.rb' controller:
# this function in controller will response for ajax's call
def great_flow
# We can find some user or getting some data, model here.
# 'params[:id]' is passed by ajax that we can use it to find something we want.
#user = User.find(params[:id])
# print whole data on terminal to check it correct.
puts YAML::dump(#user.id)
# transform what you want to json and pass it back.
render json: {staff_info: #user }
end
In 'app/views/great_control/index.html.erb' view:
<div>
<label>Staffs</label>
<%=select_tag(:staff, options_from_collection_for_select(#staffs, :id, :name), id:"staff_id", required: true)%>
</div>
<script>
//every time if option change it will call ajax once to get the backend data.
$("#staff_id").change(function(event) {
let staff_id = $("#staff_id").val()
$.ajax({
// If you want to find url can try this 'localhost:prot/rails/info/routes'
url: '/admin/some_great_flow',
type: 'GET',
dataType: 'script',
data: { id: staff_id },
// we get the controller pass here
success: function(result) {
var result = JSON.parse(result);
console.log(result['staff_info']);
// use the data from backend for your great javascript.
},
});
});
</script>
I write it for myself.
You can see the changes using javascript.
For eg lets consider a controller Mycontroller with action index and you are submitting form on index.
Then create a file in views my_controller/index.js.erb
To reflect changes use javascript in this template.
Definately remote sends the ajax call, so to see the changes you need some manipulation using javascript.
Thanks

Django : provide dynamically generated data as attachment on button press

Problem Overview:
I am creating a Django-based client with the intent of returning data from a web service. The goal of this project is to return data to the user from the web service based on the values selected by the user in a form. Upon the form submit, a query string is generated, sent to the web service and the page data is returned as a string. Currently, that data is displayed to the user in the browser. I want to provide the functionality that would allow the user to click a button and download the data.
Question:
How could I return the data to the user when they click a button in their browser for download? How do I make different options of the same data available (i.e. application/json, or text/csv)?
Current (not-working) Implementation:
I am attempting, and failing, to do the following:
views.py
Returning a render_to_response object of my template. To the template I pass the form, and the data in it's various forms.
def view(request):
#Do stuff, get data as string
#Get data into needed formats (see utils.py)
jsonData = jsonToJsonFile(dataString, fileName)
return render_to_response('template.html', {'someForm' : aForm,
'regularData' : stringData,
'jsonData' : jsonData...})
utils.py
Contains functions to take the data as a string and return response objects. This part I am unsure if I am doing correctly. I call these functions in the view to get jsonData (and csvData) into their proper formats from the original data string.
def jsonToJsonFile(dataString, fileName):
#Get the data as json
theData = json.dumps(dataString)
#Prepare to return a json file
response = HttpResponse(theData, mimetype = 'application/json')
response['Content-Disposition'] = 'attachment; filename=' + str(fileName) + '.json'
#return the response
return response
template.html
I am currently passing the responses into the template. This is where I am really lost, and have not yet begun to find a good solution. I expect I will need to use javascript to return the variables (jsonData and csvData) to the user when the button is clicked. I have attempted the use of the onclick action of the anchor class, and then using javascript to return the django variable of the response - but this really isn't working.
<li class = 'button'>
<a href = "#dataButtons" onclick = "javaScript:alert('test');">
TEST
</a>
</li>
<li class = 'button'>
<a href = "#dataButtons" onclick = "javaScript: var a = '{{ jsonData }}'; return a;">
JSON
</a>
</li>
I put the test part in there to, well, test whether or no the alert would work. It does. However, when I click the button for the json data, nothing happens.
Am I approaching this completely wrong? Or is there something small that I am missing?
Solution:
After looking at the problem a little further and talking to a colleague about it, it seems as though my problem lies in trying to pass the response object to the javascript. For those interested, I solved the problem with a little careful re-routing of the data.
views.py
In my views.py I added a couple lines of code in my main view that would set variables of two extra views (one for csv one for json) to the response objects holding the data. These two extra views would then be called when their respective buttons were pressed, returning the httpresponse and prompting the user for download.
#MAIN VIEW FUNCTION
def view(request):
#Do stuff, get data as string
#Get data into needed formats
jsonData = jsonToJsonFile(dataString, fileName)
#Set values to external view ****NEW PART****
returnJSON.jsonData = jsonData
#Render main template
return render_to_response('mainTemplate.html', {'someForm' : aForm,
'regularData' : dataString})
#SECONDARY VIEW TO RETURN JSON DATA TO USER ****NEW PART****
def returnJSON(request):
#Simply return the response
return returnJSON.jsonData
template.html
Then, when the button is pressed by the user, the anchor is linked via the url to the secondary django view that will present the download option to the user.
<li class = 'button'>
<a href = "{% url client.views.returnJSON %}">
JSON
</a>
</li>
urls.py
Lastly, I just pointed my url patterns to the view.
urlpatterns = patterns('',
(r'^somesite/$', views.view),
(r'^somesite/json$', views.returnJSON),
)
So far, this method has worked great for me! If anyone has any other suggestions, or a better method, I would certainly be open to hear it.
I think you need to change your javascript to make it start a file download - see this question & answer:
starting file download with JavaScript

Categories