I want to grab data other than id or text when an element is selected. The data is retrieved from some source when user puts in some values. All the data fetching and populating works properly. Previously just to get it working, I have just concatenated the "custom" value with some delimiter into the id then later parsed it out, but for the specs of what I want to do, I can't do that anymore. This is basically the code I have so far:
JS:
function convertResult(result) {
return {
id: result.p0,
text: result.p1,
custom: result.p2
};
}
searchBox.select2({
width: '100%',
minimumInputLength: 3,
placeholder: 'Search',
ajax: {
url: {someUrl},
delay: 350,
dataType: 'json',
data: function data(params) {
return { q: params.term }
},
processResults: function processResults(data) {
return { results: $.map(data.results, convertResult); }
}
}
});
searchBox.on("change", function (e) {
var selVal = $(this).val(); //this gets me the id
var selText = $(this).text(); //this gets me the text
// grab the "custom" property from the selected element
}
(cs)HTML:
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label> Dropdown </label>
<div class="col-sm-10">
<select data-url='#Url.Action("get")' class="form-control ">
<option value="" selected="selected"> </option>
</select>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"> Readonly Textfield</label>
<div class="col-sm-10">
<input type="text" class="form-control custom" style="width: 100%;" readonly="readonly">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">
Submit
</button>
</div>
</div>
</div>
So what I want to do is once an element is selected from the select2 dropdown, populate the readonly textfield with the value saved in custom. When I look at the developer window for my browser I can't seem to find the value on the page. But when debugging, I can see the Json Object with custom value. I have considered scanning through the JSON to find the information I need, but I want to avoid that if possible. How do I go about extracting this information otherwise?
Related
I am doing a project in django which is a car rental/sale web app, the search query works, but when i am trying to submit my form in ajax it seems like it never reaches into ajax.
<div class="container">
<div class="card-header bg-info text-white">
<h4>
<i class="fas fa-car"></i> Search Car </h4>
</div>
<form method="get" id="search-form">
<div class="input-field">
<label for="from">Number:</label>
<input type="number" class="form-control" id="from-place" placeholder="Any" name="number" />
</div>
<section>
<label for="class">Car Type:</label>
<select class="cs-select cs-skin-border input-half">
<option value="" disabled selected>Any</option>
<option value="1">Sedan</option>
<option value="2">Saloon</option>
</select>
</section>
<section>
<label for="class">Price:</label>
<div class="wide">
<select class="cs-select cs-select-half cs-skin-border input-half" name="price">
<option value="" disabled selected>any</option>
<option value="1000">1.000</option>
<option value="2000">2.000</option>
<option value="3000">3.000</option>
</div>
</section>
<div class="col-xxs-12 col-xs-12 text-center">
<input type="hidden" name="search_filter" value="true">
<input type="submit" id="search-apa" value="Search">
</div>
</form>
</div>
and this ajax code:
$(document).ready(function() {
$('#search-form').on('submit', function(e) {
e.preventDefault();
var searchText = $('#search-form').val();
$.ajax({
url: '/cars/search_car/?search_filter=' + searchText,
type: 'GET',
success: function(resp) {
var newHtml = resp.data.map(d => {
return `<div class="cars">
<a href="/cars/${d.id}">
<h4>${d.type}</h4>
<p>${d.price}</p>
</a>
</div>`
});
$('.cars-index').html(newHtml.join(''));
$('.search-form').val( '');
},
error: function(xhr, ststus, error) {
console.log(error);
}
})
});
});
I am trying to get the values from the form into ajax, but when i click search it says undefined. I printed searchText and i does not print anything, it seems like it never reaches the ajax, is something wrong with my form or my i am not calling properly in ajax?
The error that shows is
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
search_car.js:25 Internal Server Error
The $('#search-form') doesn't have any value, because it's a form. You need the <input />'s value. If you need to send the whole form's data, you need to use:
data: $('#search-form').serialize(),
In your AJAX call, please change this way:
$(document).ready(function() {
$('#search-form').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: '/cars/search_car/?search_filter=' + searchText,
type: 'GET',
data: $('#search-form').serialize(),
success: function(resp) {
var newHtml = resp.data.map(d => {
return `<div class="cars">
<a href="/cars/${d.id}">
<h4>${d.type}</h4>
<p>${d.price}</p>
</a>
</div>`
});
$('.cars-index').html(newHtml.join(''));
$('.search-form').val( '');
},
error: function(xhr, ststus, error) {
console.log(error);
}
})
});
});
And make sure you have name attribute for everything and it gets matched in the backend too.
I think what's wrong with the code is this var searchText = $('#search-form').val();
You should get the value of each field by their own selector, you can not just get all the values from form with the form selector. Try console logging the searchText and see if it actually has any value
You are accessing form value with. Val() function. Which is incorrect As form contains multiple child elements it won't return you a value. If you have to access search text then it must be an input control like $('#from-place').val().
The line
var searchText = $('#search-form').val();
asigns searchText an empty string value. What you want is:
let formString = $("#search-form").serialize();
I have a form where the user can input multiple addresses, city, street+nbr and country.
For this field to be repeated I use the jquery repeater library. For the city field I want to use a selectize input field.
I am trying to repeat those 4 fields when clicking on the button, it copies everything correctly but the selectize field does not contain inputs (i guess this is because they have the same id?) but I don't know how to instantiate another selectize instance on that object.
This is my code:
HTML:
<div class="row">
<div class="form-group col-12 mb-2 address-repeater">
<div data-repeater-list="stcity">
<div class="input-group mb-1" data-repeater-item>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="companystreet"><?=lang("flow_company_street")?></label>
<input type="text" id="companystreet" class="form-control" placeholder="<?=lang("flow_company_streetname")?>" name="companystreet" required data-validation-required-message="<?=lang("flow_company_street_validation")?>">
<div class="help-block font-small-3"></div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="companystreetnumber"><?=lang("flow_company_nbr")?></label>
<input type="text" id="companystreetnumber" class="form-control" placeholder="<?=lang("flow_company_streetnbr")?>" name="companystreetnumber" required data-validation-required-message="<?=lang("flow_company_nbr_validation")?>">
<div class="help-block font-small-3"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="companycity"><?=lang("flow_company_city_or_commune")?></label>
<select id="companycity" class="companycity-select" name="companycity" autocomplete="new-password" required data-validation-required-message="<?=lang("flow_company_city_or_commune_validation")?>">
<option value="" selected><?=lang("flow_company_select_city_or_commune")?></option>
<?php
foreach ($citiesbe as $city) {
//Values are prefilled from javascript
$key = strtolower($city->name_nl) . "," . $city->zip_code;
echo "<option value=\"$key\"> $city->name_nl ($city->zip_code)</option>";
}
?>
</select>
<div class="help-block font-small-3"></div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="companycountry"><?=lang("flow_company_country")?></label>
<select id="companycountry" class="companycountry-select" name="companycountry" autocomplete="new-password" disabled>
<option value="BE" selected><?=lang("flow_company_country_belgium")?></option>
</select>
</div>
</div>
</div>
</div>
</div>
<button type="button" data-repeater-create class="btn btn-primary">
<i class="ft-plus"></i> Add new address
</button>
</div>
Javascript:
// Custom Show / Hide Configurations
$('.address-repeater').repeater({
show: function () {
$(this).slideDown();
},
hide: function(remove) {
$(this).slideUp(remove);
}
});
Since the button is not the selectize element, I don't know how to assign it to the newly created element.
Funny, I ran into a similar problem, but couldn't find a solution, so I had to work it out myself. Here's an explanation to the solution I applied to get selectize and jquery.repeater to work nicely.
First, checking through the browser console, you'll find out that selectize removes all the select options except the empty option, and uses it to populate it's own dropdown which is generated via javascript. This becomes a problem for jquery.repeater because it only repeats or creates a duplicate based on the initial page load, and not after. So, what gets repeated is the only select option left in the select element, which in this case (unfortunately) is the empty select option. Here's a pen explaining this, feel free to toggle the category targeting selectize in the select element to see for yourself.
So, here are the steps I took to get it to work nicely:
On repeating of the form (show() of the repeater instance), you'll need to delete the duplicated element completely from the DOM.
Create another select element(s) in the DOM with the preferred (or same) attributes/options.
Instantiate selectize on the newly created select element(s).
I'll suggest you add a class to the .form-group wrapper housing the .companycity-select select element. This will help to append a new select element at the exact place only, since there are other .form-group in the code. Check my solution below:
// Assuming your have the select element wrapper as <div class="form-group select-wrapper">
$('.address-repeater').reapeter({
show: function() {
$(this).slideDown();
// Remove the created element
$(this).find('.companycity-select').remove();
// Repeater rewrites your name attributes to avoid collisions within the same form,
// so we need to follow this same rule
// Get the length of the currently repeated items, to be used as the index for new elements
var count = $('div[data-repeater-item]').length;
// Create the new select element. The select name is based on the new name by repeater
var new_select_option = '<option value="" selected>Select city or community</option>';
var new_select_element = '<select id="companycity" class="companycity-select" name="stcity['+count+'][companycity]" autocomplete="new-password" required>'+new_select_option+'</select>';
// Append newly created element to DOM. Remember the new class added to the form-group?
$(this).find('.form-group.select-wrapper').append(new_select_element);
// Create a new instance of selectize on the new select element
$(this).find('.companycity-select').selectize({
// Populate your select options data via ajax,
// see docs: https://selectize.dev/docs.html
valueField: '',
labelField: '',
searchField: [],
options: []
});
}
});
I think a more appropriate title is my private JavaScript Hell.
First off I am new to JavaScript. Never used it before this attempt.
Three or four weeks back when I first encountered this error I posted on ASP.Net forums and the good folks helped me out there. However after a full week of one hour a day concentrating on this issue I am no further advanced than I was three weeks ago even with their help. The issue seems to be either I am transcribing something incorrectly and I am blind (this wouldn't surprise me) or the error is specific to some aspect within my machine.
First the set up. I have a controller for jobs where I am wanting to cascade a drop down box content based on a preceeding selection. The two drop downs involved are Site and Waterbodys. The relevant part of the controller is:
public class JobsController : Controller
{
private readonly EVAContext _context;
public JobsController(EVAContext context)
{
_context = context;
}
// GET: Jobs/Create
public IActionResult Create()
{
ViewData["SiteID"] = new SelectList(_context.Sites, "SiteID", "SiteName");
ViewData["WaterBodyID"] = new SelectList(_context.WaterBodys, "WaterBodyID", "WBName");
ViewData["DepartmentID"] = new SelectList(_context.Departments, "DepartmentID", "iDepartment");
return View();
}
public IActionResult GetWaterBody(int siteID)
{
var waterBody = new List<WaterBody>();
waterBody = getWaterBodyFromDataBaseBySiteID(siteID);
return Json(waterBody);
}
public List<WaterBody> getWaterBodyFromDataBaseBySiteID(int siteID)
{
return _context.WaterBodys.ToList();
}
Within the associated view I have :
#model EVA.Models.Job
#{
ViewData["Title"] = "Add Job";
}
<h2>Add Job</h2>
<form asp-action="Create">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrderNumber" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="OrderNumber" class="form-control" />
<span asp-validation-for="OrderNumber" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="SiteID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="SiteID" class="form-control" asp-items="ViewBag.SiteID" id="site-target">
<option>---Select Site First---</option>
</select>
</div>
</div>
<div class="form-group">
<label asp-for="WaterBodyID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="WaterBodyID" class="form-control" asp-items="ViewBag.WaterBodyID" id="wb-target">
<option>---Select Site First---</option>
</select>
</div>
</div>
<div class="form-group">
<label asp-for="DepartmentID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="DepartmentID" class="form-control" asp-items="ViewBag.DepartmentID">
<option>---Select Department---</option>
</select>
</div>
</div>
<div class="form-group">
<label asp-for="JobNumber" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="JobNumber" class="form-control" value="1234" />
<span asp-validation-for="JobNumber" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="JobDescription" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="JobDescription" class="form-control" />
<span asp-validation-for="JobDescription" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script>
$(document).ready(function () {
$("#site-target").on("change", function () {
$list = $("#wb-target");
$.ajax({
url: "Jobs/GetWaterBody",//Core0309 is my controller name
type: "GET",
data: { id: $("#site-target").val() }, //id of the site which is used to extract waterbodies
traditional: true,
success: function (result) {
$list.empty();
$.each(result, function (i, item) {
$list.append('<option value="' + item["WaterBodyID"] + '"> ' + item["WBName"] + ' </option>'); //Must be lowercase ,if not ,you will get value 'Undefined'
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(textStatus);
},
//error: function () {
// alert("Danger!! Will Robertson Danger!!!!!!!!!!!");
// }
});
});
});
</script>
<!--<script src="~/js/WaterBody.js"></script>-->
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
I previously had Waterbody.js which was also returning the same 404 based error.
What is frustrating and has led me here is on the ASP.Net forum the people there have copied my code to their own machine and it is running without error I am told. Although they are using a different set of drop downs.
I am seriously feeling like I am bashing my head against the wall. I have tried every suggestion, spent hours looking at examples on line and making minor changes to try and find the culprit but nothing works.
I am left with these questions:
1: Is my JobController code correct? Have I inadvertently introduced a stuff up there?
2: Is the script correct? I added alerts at one stage and I keep getting the idea the error is in the url but don't know that.
3: Is there some reference or dependency I may be missing on my machine specifically?
4: Some other question I haven't considered as I am still too new to this?
Help please. I am at the point where I must get this working to be able to move on with the balance of the project. Thanks in advance. I honestly hope this is a silly thing I done.
Bit of an update...
I added some alerts and they are indicating the error is occurring on $.ajax line.
alert("Inside")
$list = $("#wb-target");
alert("aferlist")
$.ajax({
Afterlist is firing but the next alert "Ajax" doesn't fire.
I need your help. I am trying to realize a live search. So whenever I switch from one TextBox to another, a form should be submitted, to update the URL and to pass the data to the controller. It works perfectly fine when I click the submit button but it does not work the way I want.
Here is my code:
Controller:
public ActionResult Index(string number, string caption)
{
//Fetch data from the database
return View();
}
View:
$(document).ready(function () {
$('#number').change(function () {
$('#filter').submit();
});
});
#using (Html.BeginForm("Index", "Home", FormMethod.Get, new { id = "filter" }))
{
<div class="row">
<div class="col-sm-2 checkbox">
Number:
</div>
<div class="col-sm-3">
#Html.TextBox("Number", "", new { #class = "form-control", type = "text", id = "number" })
</div>
</div>
<div class="row">
<div class="col-sm-2 checkbox">
Caption:
</div>
<div class="col-sm-3">
#Html.TextBox("Caption", "", new { #class = "form-control", type = "text", id = "caption" })
</div>
</div>
<div class="row">
<div class="col-sm-2 col-sm-offset-2">
<button type="submit" id="submit" class=" btn btn-block btn-primary">Search</button>
</div>
</div>
}
Output HTML:
<script>
$(document).ready(function () {
$('#number').change(function () {
$('#filter').submit();
});
});
</script>
<form action="/" id="filter" method="get"> <div class="row">
<div class="col-sm-2 checkbox">
Number:
</div>
<div class="col-sm-3">
<input class="form-control" id="number" name="Number" type="text" value="">
</div>
</div>
<div class="row">
<div class="col-sm-2 checkbox">
Caption:
</div>
<div class="col-sm-3">
<input class="form-control" id="caption" name="Caption" type="text" value="">
</div>
</div>
<div class="row">
<div class="col-sm-2 col-sm-offset-2">
<button type="submit" id="submit" class=" btn btn-block btn-primary">Search</button>
</div>
</div>
Browser Console:
Uncaught TypeError: elem[type] is not a function
at Object.trigger (http://localhost:49782/Scripts/jquery-1.8.2.js:2991:18)
at HTMLFormElement.<anonymous> (http://localhost:49782/Scripts/jquery-1.8.2.js:3618:17)
at Function.each (http://localhost:49782/Scripts/jquery-1.8.2.js:625:20)
at init.each (http://localhost:49782/Scripts/jquery-1.8.2.js:255:17)
at init.trigger (http://localhost:49782/Scripts/jquery-1.8.2.js:3617:15)
at init.jQuery.fn.(anonymous function) [as submit] (http://localhost:49782/Scripts/jquery-1.8.2.js:3671:9)
at HTMLInputElement.<anonymous> (http://localhost:49782/:63:26)
at HTMLInputElement.dispatch (http://localhost:49782/Scripts/jquery-1.8.2.js:3077:9)
at HTMLInputElement.eventHandle (http://localhost:49782/Scripts/jquery-1.8.2.js:2695:28)
Your JavaScript code is looking for the tag with ID #number. Because browsers mostly read the source code from the top to the bottom, the code will be evaluated well before the #number <input> is even declared. This means that jQuery will not find it and will therefore not attach the event. If you move the script after the HTML, or wrap it into document.ready, it will work as expected:
$(document).ready( function() {
$('#number').change(function () {
$('#filter').submit();
});
} );
//or simpler equivalent
$( function () { ... } );
This however will still not work as you want, because each time the input changes, the whole page will be posted back to the server, so user will have to wait for the entire page to reload after he tries to switch focus from one input to another. This is not very convenient and you would probably be better off changing the logic to use AJAX calls and dynamically update the search results. Although it is not a requirement, it is a nice to have and user-friendly approach :-) .
Update - solution to submit error
I have just found the solution for the error you get trying to submit. Your submit button's id is submit. This is not "wrong" per se, but it causes a problem trying to submit with jQuery. You see, because the button is inside your form, when jQuery returns the #filter form, when you try to use submit() on it, JavaScript finds your submit button in scope and thinks that you want to "call it" - hence you get the error, because you you cannot "call" an element. This might also happen if you use submit as the name of a button.
The best and easiest solution for you will be to change the id to something else:
<button type="submit" id="submitButton" class=" btn btn-block btn-primary">Search</button>
In modern browsers use the input event. This event will fire when the user is typing into a text field, pasting, undoing, basically anytime the value changed from one value to another.
$('#number').on('input', function() {
$('#filter').submit();
});
It's working fine for me I hope it also working for u
C# Code:
[HttpPost]
public ActionResult Index(string firstname)
{
return Json("Done");
}
Razor Code
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
var abc = document.getElementById('Number');
abc.onchange = (function () {
document.forms[0].submit();
});
});
</script>
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id= "filter" }))
{
<div class="row">
<div class="col-sm-2 checkbox">
Number:
</div>
<div class="col-sm-3">
#Html.TextBox("Number", "", new { #class = "form-control", type = "text", id = "Number" })
</div>
</div>
<div class="row">
<div class="col-sm-2 checkbox">
Caption:
</div>
<div class="col-sm-3">
#Html.TextBox("Caption", "", new { #class = "form-control", type = "text", id = "caption" })
</div>
</div>
<div class="row">
<div class="col-sm-2 col-sm-offset-2">
<button type="submit" id="submit1" class=" btn btn-block btn-primary">Search</button>
</div>
</div>
}
Do Not use submit as id or name of button it override the meaning of Java Script submit Method
AngularJS client application.
I have a form with two text inputs and a drop down listbox. Only one of the two text inputs is enabled, the selected item in the listbox determines which input is enabled.
The two text inputs are associated with fields in the model. However, when a text input is disabled, I would like the value to be cleared, not visible in a disabled state. When the input is enabled again, the model value should be displayed.
What is the best way to achieve this with AngularJS?
Angular Expression can be used with ngDisabled directive.
Use ternary operator to check if selected value is equal to name of the input field and based on that set ngDisabled.
If the expression is truthy, then the disabled attribute will be set on the element.
Something like this in your html template.
ngDisabled = "($scope.input_model_variable_name != $scope.select_model_variable_name)?true:false"
One way to go about it would be
Call a function on ng-change on select.
-- copy all the values to restore later
-- blank all the text fields except for the field you want to edit
Have a function for ng-disable
-- disable the not selected text box
-- enable the rest
var app = angular.module('testApp', []);
app.controller('MainCtrl', function ($scope) {
var modelCopy = {
inputTextField1: "",
inputTextField2: ""
};
$scope.data = {
inputTextField1: "",
inputTextField2: "",
selectedInputField: ""
};
$scope.inputFieldChanged = function () {
angular.forEach(modelCopy, function (value, key) {
modelCopy[key] = $scope.data[key];
if (this.selectedInputField === key) {
this[key] = value;
} else {
this[key] = "";
}
}, $scope.data);
};
$scope.toggleDisability = function (fieldToEnable) {
if ($scope.data.selectedInputField === fieldToEnable) {
return false;
} else {
return true;
}
};
});
HTML
<div ng-controller="MainCtrl">
<div class="container">
<form novalidate="novalidate" class="form-horizontal">
<div class="form-group">
<label for="selectInputFieldToEdit" class="control-label col-sm-2">Select Input Field to Edit</label>
<div class="col-sm-6">
<select class="form-control" ng-change="inputFieldChanged()" id="selectInputFieldToEdit" ng-model="data.selectedInputField">
<option value="inputTextField1">Field 1</option>
<option value="inputTextField2">Field 2</option>
</select>
</div>
</div>
<div class="form-group">
<label for="inputTextField1" class="control-label col-sm-2">Input Text Field 1</label>
<div class="col-sm-6">
<input id="inputTextField1" type="text" ng-model="data.inputTextField1" name="inputTextField1" class="form-control" ng-disabled="toggleDisability('inputTextField1')" />
</div>
</div>
<div class="form-group">
<label for="inputTextField2" class="control-label col-sm-2">Input Text Field 2</label>
<div class="col-sm-6">
<input id="inputTextField2" type="text" ng-model="data.inputTextField2" name="inputTextField2" class="form-control" ng-disabled="toggleDisability('inputTextField2')" />
</div>
</div>
</form>
</div>
</div>
Here is a jsFiddle https://jsfiddle.net/hheymu/jpydjuhp/