I have a little issue and I don't overcome to solve it. I have a list of Django objects generated in my views.py file and I would like to display these variables in my Javascript part.
I get the list in my Javascript code, but each variable are 'undefined'.
In my views.py file, I have :
context['results2'] = SubMethod.objects.values_list('name', flat=True).all()
with this model :
class SubMethod(EdqmTable):
name = models.CharField(verbose_name=_('name'), max_length=80, unique=True)
def __str__(self):
return self.name
Then, in my HTML/JS part :
function get_sub_method_options(keep_cur) {
var sel_option = $('select#id_method-group').find("option:selected");
var sel_val = sel_option.val();
if (!sel_val) {
$("select#id_method-sub_method").empty();
var all_sub_methods = "{{ results2 }}";
console.log(all_sub_methods.name);
for (var i = 0; i < all_sub_methods.length; i++) {
$("select#id_method-sub_method").append('<option value="' + all_sub_methods[i].id + '">' + all_sub_methods[i].name + '</option>'); //here add list of all submethods
}
return;
}
data = {
'test_method': $('select#id_method-test_method').find("option:selected").val(),
'group': sel_val
};
$.ajax({
method: "GET",
url: '{% url 'ajax_method_submethod' %}',
data: data
}).done(function (result) {
reset_select('id_method-sub_method');
for (var i = 0; i < result['results'].length; i++) {
if (keep_cur > 0 & keep_cur == result['results'][i].id)
$("select#id_method-sub_method").append('<option value="' + result['results'][i].id + '" selected>' + result['results'][i].text + '</option>');
else
$("select#id_method-sub_method").append('<option value="' + result['results'][i].id + '">' + result['results'][i].text + '</option>');
}
;
});
}
As you can see, I pick up my context variable result2 in this part :
if (!sel_val) {
$("select#id_method-sub_method").empty();
var all_sub_methods = "{{ results2 }}";
console.log(all_sub_methods.name);
for (var i = 0; i < all_sub_methods.length; i++) {
$("select#id_method-sub_method").append('<option value="' + all_sub_methods[i].id + '">' + all_sub_methods[i].name + '</option>'); //here add list of all submethods
}
return;
}
In my terminal I get :
<QuerySet ['50% cell culture infective dose (CCID50)', 'Acetic acid in synthetic peptides', 'Acid value', 'Adenylate cyclase', ...]>
But in my Javascript part, it displays this :
Do you have any idea why ?
EDIT :
In my django code, count() displays 450
In my JS code : length display 684
In my database : I have 450 elements
You need to convert your queryset to a list first. JS does not read querysets.
context['results2'] = list(SubMethod.objects.values_list('name', flat=True).all())
and you may want to skip wrapping results2 in quotes on the JS side and ass safe` to prevent escaping characters:
var all_sub_methods = {{ results2|safe }};
Related
I want to get value of dropdownlist and show textbox but my code dont working
This is my code:
Controller:
public function socaucuachuong($id)
{
$units = CauHoi::groupBy('chuong')->select('chuong', CauHoi::raw('count(id) as Total'))->where('idmonthi','=', $id)->get()->toArray();
return view('DeThi::dethi',compact('units'));
}
View: dethi.blade.php
$('select').select();
function get_units() {
var id = $('#id_select').val();
var list = $('#dschuong');
list.empty();
var url = "{{ route('dthi.socaucuachuong') }}"+'/'+id;
var success = function (result) {
if (result.length <= 0) {
var item = '<div class="input-field"><input type="text" disabled value="Môn này hiện chưa có câu hỏi nào"></div>';
list.append(item);
} else {
for (i = 0; i < result.length; i++) {
var item = '<div class="input-field"><label for="unit-' + result[i].chuong+ '">Nhập số câu hỏi chương ' + result[i].chuong+ ' (có ' + result[i].Total + ' câu) <span class="failed">(*)</span></label><input type="number" max="' + result[i].Total + '" class="unit_input" onchange="set_sum(' + result[i].Total + ')" name="unit-' + result[i].chuong+ '" id="unit-' + result[i].chuong+ '" required></div>';
list.append(item);
}
}
};
$.get(url, success);
}
Route:
Route::get('dethi/socau', 'App\Modules\DeThi\Controllers\DeThiController#socaucuachuong')->name('dethi.socaucuachuong');
Route::resource('dethi', DeThiController::class);
And my error when I select dropdownlist:
How can I fix this?
You are missing a route parameter for the ID you're passing along.
https://laravel.com/docs/8.x/routing#required-parameters
Basically, your route needs to be updated to
Route::get('dethi/socau/{id}', 'App\Modules\DeThi\Controllers\DeThiController#socaucuachuong')->name('dethi.socaucuachuong');
Route
Route::get('dethi/socau/{id}', 'App\Modules\DeThi\Controllers\DeThiController#socaucuachuong')->name('dethi.socaucuachuong');
Javascript (blade)
var url = '{{ "dthi.socaucuachuong", ":id") }}';
url = url.replace(':id', id);
I apologize up front for the possible lack of clarity for this question, but I'm new to Angular.js and my knowledge of it is still slightly hazy. I have done the Angular.js tutorial and googled for answers, but I haven't found any.
I have multiple select/option html elements, not inside a form element, and I'm populating them using AJAX. Each form field is populated by values from a different SharePoint list. I'm wondering if there is a way to implement this using Angular.js?
I would like to consider building this using Angular because I like some of it features such as data-binding, routing, and organizing code by components. But I can't quite grasp how I could implement it in this situation while coding using the DRY principle.
Currently, I have a single AJAX.js file and I have a Javascript file that contains an array of the different endpoints I need to connect to along with specific query parameters. When my page loads, I loop through the arrays and for each element, I call the GET method and pass it the end-point details.
The code then goes on to find the corresponding select element on the page and appends the option element returned by the ajax call.
I'm new to Angular, but from what I understand, I could create a custom component for each select element. I would place the component on the page and all the select and options that are associated with that component would appear there. The examples I've seen demonstrated, associate the ajax call with the code for the component. I'm thinking that I could use a service and have each component dependent on that service and the component would pass it's specific query details to the service's ajax call.
My current code - Program flow: main -> data retrieval -> object creation | main -> form build.
Called from index.html - creates the multiple query strings that are passed to ajax calls - ajax calls are once for each query string - the very last function in the file is a call to another function to build the form elements.
var snbApp = window.snbApp || {};
snbApp.main = (function () {
var main = {};
main.loadCount = 0;
main.init = function () {
function buildSelectOptions(){
//***
//Build select options from multiple SharePoint lists
//***
var listsArray = snbApp.splistarray.getArrayOfListsForObjects();
for(var i = 0; i < listsArray.length; i++){
var listItem = listsArray[i];
var qryStrng = listItem.list +
"?$select=" + listItem.codeDigits + "," + listItem.codeDescription + "," + listItem.ItemStatus + "&$orderby=" + listItem.codeDescription + "&$filter="+listItem.ItemStatus+" eq true" + "&$inlinecount=allpages"
var listDetails = {
listName: listItem.list,
listObj: listItem,
url: "http://myEnv/_vti_bin/listdata.svc/" + listItem.list +
"?$select=" + listItem.codeDigits + "," + listItem.codeDescription + "," + listItem.ItemStatus + "&$orderby=" + listItem.codeDescription + "&$filter="+listItem.ItemStatus+" eq true" + "&$inlinecount=allpages"
};
var clientContext = new SP.ClientContext.get_current();
clientContext.executeQueryAsync(snbApp.dataretriever.letsBuild(listDetails), _onQueryFailed);
}
//***
//Build select option from other API endpoint
//***
var listDetails = {
listName:"SNB_SecondaryActivityCodes",
url: "http://myEnv/requests/odata/v1/Sites?$filter=(IsMajor eq true or IsMinor eq true) and IsActive eq true and IsPending eq false and CodePc ne null and IsSpecialPurpose eq false&$orderby=CodePc"
};
snbApp.dataretriever.letsBuild(listDetails);
}
buildSelectOptions();
//***
//Add delay to populate fields to ensure all data retrieved from AJAX calls
//***
var myObj = setTimeout(delayFieldPopulate,5000);
function delayFieldPopulate(){
var optObj = snbApp.optionsobj.getAllOptions();
var osType = $("input[name=os_platform]:checked").val();
snbApp.formmanager.buildForm(osType, optObj);
}
};
function _onQueryFailed(sender, args) {
alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
return main
})();
AJAX calls here - called from main/previous file:
var snbApp = window.snbApp || {};
snbApp.dataretriever = (function () {
var listsArray = snbApp.splistarray.getArrayOfListsForObjects();
function getListData(listItem) {
var eventType = event.type;
var baseURL = listItem.url;
$.ajax({
url: baseURL,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
}
})
.done(function(results){
snbApp.objectbuilderutility.buildObjectFields(results, listItem);
})
.fail(function(xhr, status, errorThrown){
//console.log("Error:" + errorThrown + ": " + myListName);
});
}
function _onQueryFailed(sender, args) {
alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
return{
letsBuild:function(item) {
getListData(item);
}
};
})();
Builds a item name object - called from recursive AJAX calls / previous file
var snbApp = window.snbApp || {};
snbApp.objectbuilderutility = (function () {
function formatItemCode(itemCode, eventType){
if(eventType !== 'change'){ //for load event
var pattern = /^CE/;
var result = pattern.test(itemCode);
if(result){
return itemCode.slice(2);
}else{
return itemCode.slice(0,3);
}
}else{ //for change event
var pattern = /^CE/;
var result = pattern.test(itemCode);
if(result){
return itemCode.slice(2);
}else{
return itemCode.slice(3);
}
}
}
return{
buildObjectFields: function(returnedObj, listItem){ //results:returnedObj, prevItem:listItem
//***
//For SharePoint list data
//***
if (listItem.listName !== "SNB_SecondaryActivityCodes") {
var theList = listItem.listName;
var firstQueryParam = listItem.listObj.codeDigits;
var secondQueryParam = listItem.listObj.codeDescription;
var returnedItems = returnedObj.d.results;
var bigStringOptions = "";
//regex to search for SecondaryFunctionCodes in list names
var pattern = /SecondaryFunctionCodes/;
var isSecFunction = pattern.test(theList);
if(isSecFunction){
bigStringOptions = "<option value='0' selected>Not Applicable</option>";
}else{
bigStringOptions = "<option value='0' disabled selected>Select Option</option>";
}
$.each(returnedItems, function (index, item) {
var first = "";
var second = "";
for (var key in item) {
if (item.hasOwnProperty(key)) {
if (key != "__metadata") {
if (key == firstQueryParam) {
first = item[key];
}
if (key == secondQueryParam) {
second = item[key];
}
}
}
}
bigStringOptions += "<option value=" + first + " data-code=" + first + ">" + second + "</option>";
});
var str = theList.toLowerCase();
snbApp.optionsobj.updateFunctionOrActivity(theList.toLowerCase(), bigStringOptions);
//***
//For other API
//***
} else {
var theList = listItem.listName;
var bigStringOptions = "<option value='0' disabled selected>Select Option</option>";
var returnedItems = returnedObj.value;
for(var i = 0; i < returnedItems.length; i++){
var item = returnedItems[i];
//***
//change event type means the user selected a field
//***
if(listItem.eventType === "change"){
var siteCodeChange = item.SiteCodePc;
if (typeof siteCodeChange === "string" & siteCodeChange != "null") {
siteCodeChange = siteCodeChange < 6 ? siteCodeChange : siteCodeChange.slice(3);
}
bigStringOptions += "<option value='" + item.Id + "' data-code='" + siteCodeChange + "' data-isDivSite='" + item.IsDivisionSite + "' data-isDistSite='" + item.IsDistrictSite + "' data-divID='" + item.DivisionSiteId + "' data-distID='" + item.DistrictSiteId + "'>(" + siteCodeChange + ") " + item.Name + "</option>";
snbApp.formmanager.buildSelectSiteLocations(bigStringOptions);
//***
//load event which means this happens when the page is loaded
//***
}else{
var siteCodeLoad = item.SiteCodePc;
if (typeof siteCodeLoad === "string" & siteCodeLoad != "null") {
var siteCodeLoad = siteCodeLoad.length < 4 ? siteCodeLoad : siteCodeLoad.slice(0, 3);
}
bigStringOptions += "<option value='" + item.Id + "' data-code='" + siteCodeLoad + "' data-isDivSite='" + item.IsDivisionSite + "' data-isDistSite='" + item.IsDistrictSite + "' data-divID='" + item.DivisionSiteId + "' data-distID='" + item.DistrictSiteId + "'>(" + siteCodeLoad + ") " + item.Name + "</option>";
snbApp.optionsobj.updateFunctionOrActivity(theList.toLowerCase(), bigStringOptions);
}
}
}
}
};
})();
Form management - called from previous file, gets all select elements on page and appends items from the object in previous file to each select element.
var snbApp = window.snbApp || {};
//Direct interface to the form on the page
snbApp.formmanager = (function(){
var form = {};
form.content_holder = document.getElementById("content_holder");
form.sec_act_codes = document.getElementById("snb_secondary_activity_codes");
form.prim_func_codes = document.getElementById("snb_primary_function_codes");
form.sec_func_codes = document.getElementById("snb_secondary_function_codes");
form.sec_func_nums = document.getElementById("snb_secondary_function_numbers");
form.host_options = document.getElementById("snb_host_options");
form.site_locs_div = document.getElementById("site_locations_div");
form.site_locs = document.getElementById("snb_site_locations");
form.dc_or_off_prem_div = document.getElementById("dc_or_off_premise_div");
form.dc_off_prem_codes = document.getElementById("snb_dc_offpremise_codes");
var snb_secondary_activity_codes = "";
var snb_primary_function_codes = "";
var snb_secondary_function_codes = "";
var snb_secondary_function_numbers = "";
var snb_host_options = "";
var snb_site_locations = "";
var snb_dc_op = "";
//builds the server location hosting options selection
function buildLocationTypeSelector() {
var locationOptionsString = "<option value='0' disabled selected>Select Option</option>";
for (var i = 0; i < locationOptions.length; i++) {
var location = locationOptions[i];
locationOptionsString += "<option value=" + location.hostLocale + " data-code=" + location.code + ">" + location.hostLocale + "</option>";
}
$("#snb_host_options").append(locationOptionsString);
}
function buildSiteLocations(bigString){
if(bigString === undefined){
var siteLocs = document.getElementById("snb_site_locations");
var newOption = document.createElement("option");
newOption.setAttribute("value", 0);
newOption.setAttribute("disabled","disabled");
newOption.setAttribute("checked","checked");
var newText = document.createTextNode("Select Option");
newOption.appendChild(newText);
siteLocs.appendChild(newOption);
} else{
var siteLocs = document.getElementById("snb_site_locations");
siteLocs.innerHTML = bigString;
}
}
return {
form:form,
buildSelectSiteLocations: function(bigString){
buildSiteLocations(bigString);
},
buildForm: function (osType, optObj) {
buildLocationTypeSelector();
buildSecondaryFunctionNumberSelector();
buildSiteLocations();
if(osType === 'windows'){
$("#snb_secondary_activity_codes").append(optObj.windows.secondary_activity);
$("#snb_primary_function_codes").append(optObj.windows.primary_function);
$("#snb_secondary_function_codes").append(optObj.windows.secondary_function);
$("#snb_site_locations").append(optObj.windows.site_location);
$("#snb_dc_offpremise_codes").append(optObj.windows.dc_offpremise);
}else{
$("#snb_secondary_activity_codes").append(optObj.unix.secondary_activity);
$("#snb_primary_function_codes").append(optObj.unix.primary_function);
$("#snb_secondary_function_codes").append(optObj.unix.secondary_function);
$("#snb_site_locations").append(optObj.unix.site_location);
$("#snb_dc_offpremise_codes").append(optObj.unix.dc_offpremise);
}
}
};
})();
Thanks in advance.
This is my response from AJAX call
{"screen":[{"screen_name":"SCR1","screen_id":"1"},{"screen_name":"SCR2","screen_id":"2"},{"screen_name":"SCR3","screen_id":"3"},{"screen_name":"SCR4","screen_id":"4"},{"screen_name":"SCR5","screen_id":"5"},{"screen_name":"BIGSCR","screen_id":"6"}]}
success: function(response) {
var jsondata = JSON.stringify(response);
console.log(jsondata);
var html = '';
for (var i = 0; i < jsondata.screen.length; i++) {
var screenName = jsondata.screen[i].screen_name;
var screenId = jsondata.screen[i].screen_id;
html += '<option value="' + screenName + '">' + screenId + '</option>';
}
$('#SCname').append(html);
}
But I keep on getting
Uncaught TypeError: Cannot read property 'length' of undefined at for loop
Try this: It Works. As smooth as silk: (See comment for explanation)
<select id="SCname"></select>
<script>
$.ajax({
dataType: 'json',
//This JSON datatype returns a json encoded response
url:"api/test.php",
//This is the URL From where you fetch the JSON Data
success: function(response){
//Since the response array object has a single array element "screen", we make it myArray
myArray = response["screen"];
console.log(myArray);
//We get six Objects in myArray.
//Thsese are Arrays of your six screens . Now Using Loops
var html = '';
for (var i = 0; i < myArray.length; i++) {
// Each element is inside DOuble Array like: myArray[0]["screen_name"]
var screenName = myArray[i]["screen_name"];
var screenId = myArray[i]["screen_id"];
html += '<option value="' + screenName + '">' + screenId + '</option>';
}
$('#SCname').append(html);
//Check your console ouput
console.log(html);
}
});
</script>
JSON.stringify(object) returns a string. You want a JSON.parse(string) – which returns an object. Alternatively, if your response is already an object, then you don't have to parse it at all:
success: function(jsonData) {
var html = '';
for (var i = 0; i < jsonData.screen.length; i++) {
var screenName = jsonData.screen[i].screen_name;
var screenId = jsonData.screen[i].screen_id;
html += '<option value="' + screenName + '">' + screenId + '</option>';
}
$('#SCname').append(html);
You don't want to stringifybut to parse. Correct it must be:
var jsondata = JSON.parse(response);
But keep in mind that jQuery possibly is already parsing the JSON for you.
Let suppose i have a json file
and i can read this file in my script like this
$(document).ready(function () {
$.ajax({
type: "GET",
url: "Package.html",
dataType: "json",
success: function (data) {
var t = '';
for (var i = 0; i < data.yearData.length; i++) {
var mainStoryTitle = data.yearData[i].players;
for (var j = 0; j < mainStoryTitle.length; j++) {
var storyTitle = mainStoryTitle[j].name;
var topStoryContent = mainStoryTitle[j].description;
var storyImage = mainStoryTitle[j].image;
t = t + '<div class="content">';
t = t + '<article class="topcontent">';
t = t + '<header class="top" id="top1"><h2>' + storyTitle + '</h2></header>';
t = t + '<header class="bottom">';
t = t + '<h6><img src="' + storyImage + '" height=150 width=200>' + '</h6></header>';
t = t + '<content class="hide" id="content_' + j + '"><p>' + topStoryContent + '</p></content>';
t = t + '</article>';
t = t + '</div>';
}
}
$(".content").html(t);
},
error: function (e, ts, et) { alert(ts) }
})
});
and then i put this script in my html file.
So when i run this, it works properly but the problem is when i click on view source then inside it shows the path of json instead of exact data.
Hope you got the problem and please revert me asap.thanx
Instead of using alert, use console.log(ts) this will post the JSON file into your console. From there you can easily look around and see the JSON file by clicking the down arrow.
console.log(data); shows as:
> Object {Data: Array[2], ResponseMessage: "", Success: true}
console.log(JSON.stringify(data)); shows as:
{"Data":[{"ControllerID":2,"Description":"Aeon Power Monitor","DevType":1,"ID":1,"Name":"Power Monitor"},{"ControllerID":2,"Description":"Aeon Power Switch","DevType":2,"ID":2,"Name":"Switch"}],"ResponseMessage":"","Success":true}
I have values that come from a dynamically created table from it's selected rows. inside each selected row i want all the td.innerText values that belong to be sent to a C# page, but i don't know how to. I was using JSON but I dont know if i used it properly.
function selectedRows()
{
var selectedItems = $('#ScannedLabelTable').find(':checkbox:checked').parents('tr');
var serial, kanbanNumber, customer, description, quantity;
$.each(selectedItems, function (i, item) {
var td = $(this).children('td');
for (var i = 0; i < td.length; ++i)
{
serial = td[1].innerText;
kanbanNumber = td[2].innerText;
customer = td[3].innerText;
description = td[4].innerText;
quantity = td[5].innerText;
}
console.log(serial + ' ' + kanbanNumber + ' ' + customer + ' ' + description + ' ' + quantity);
});
$.ajax({
url: SEND_TO_TEXTFILE_PAGE
, data: "labelSerial=" + serial + "&kanbanNumber=" + kanbanNumber + "&customer="
+ customer + "&description=" + description + "&quantity=" + quantity
, dataType: 'json'
, success: function (status) {
if (status.Error) {
alert(status.Error);
}
}
, error: Hesto.Ajax.ErrorHandler
});
}
EDIT: sorry I must have read this too quickly. This should do it. create an array and add the data object to it in the loop.
If you just create a json object using key value pairs you can send that object to your c# controller.
function selectedRows() {
var selectedItems = $('#ScannedLabelTable').find(':checkbox:checked').parents('tr');
var serial, kanbanNumber, customer, description, quantity;
var dataArray = new Array();
$.each(selectedItems, function (i, item) {
var td = $(this).children('td');
for (var i = 0; i < td.length; ++i)
{
var InfoObject = {
serial: td[1].innerText;
kanbanNumber: td[2].innerText;
customer: td[3].innerText;
description: td[4].innerText;
quantity: td[5].innerText;
};
dataArray.push(InfoObject);
}
});
$.ajax({
url: SEND_TO_TEXTFILE_PAGE
, data: dataArray
, dataType: 'json'
, success: function (status) {
if (status.Error) {
alert(status.Error);
}
}
, error: Hesto.Ajax.ErrorHandler
});
}