I need some help in order to replace some html inside a div with some other html which I get from the server when making the Ajax call.
To make this clear for you guys, I have the following code:
Code:
<div class="travel-container" id="travel-container">
<div class="travel-content">
#using (Html.BeginForm(new { id = "sbw_travel_form" }))
{
<div class="row">
<div class="routes small-12 large-6 column">
#Html.Label("Departure Route:", new { #class = "label-travel" })
#Html.DropDownListFor(m => m.DepartureRoute, routesSelectList, new { #class = "dropdown", #id = "Outbound-route" })
#Html.Label("Return Route:", new { #class = "label-travel" })
#Html.DropDownListFor(m => m.ReturnRoute, routesConverslySelectList, new { #class = "dropdown", #id = "Return-route" })
</div>
<div class="dates small-12 large-3 column">
#Html.Label("Departure Date:", new { #class = "label-travel" })
#Html.TextBoxFor(m => m.DepartureDate, new { Value = Model.DepartureDate.ToShortDateString(), #class = "textbox datepicker ll-skin-melon", #id = "departureDate" })
#Html.Label("Return Date:", new { #class = "label-travel" })
#Html.TextBoxFor(m => m.ReturnDate, new { Value = Model.ReturnDate.ToShortDateString(), #class = "textbox datepicker ll-skin-melon", #id = "returnDate" })
</div>
<div class="small-12 medium-6 large-3 columns"></div>
</div>
}
</div>
</div>
Here you see that I have put everything inside a class container called travel-container.
What I'm trying to do is to replace the div with the "routes" class with some same div tag when I get new html from the server. The problem is that I need to keep the rest of the html inside the container.
The ajax call code:
$.ajax({
type: 'POST',
url: "#Url.Action("FindReturnRoutes", "Travel")",
dataType: "html",
data: postData,
beforeSend: function () {
$(".travel-content").append(res.loader);
setTimeout(delay);
},
success: function (data) {
setTimeout(function () {
$(".travel-content").find(res.loader).remove();
$('.travel-container').html($(data).find(".travel-content"));
datepickerLoad();
Initializer();
}, delay);
}
});
Right now I'm using the find method to find the travel-content div and replace all the content within that div. Have tried putting .routes after and alone but none seem to work. Is find the right solution to use here?
All I want is to replace the routes div with the new one I get from the ajax call, but still keep the rest of the html without replaceing it all.
Following code snippet may be helpful for you.
$('.travel-container .routes').prepend($(data).find('.routes').html());
Can you try this please:
$('.travel-container .travelcontent').html(data);
Related
I have added fields to my form dynamically using a for-loop, which works fine. However, the fields i'm adding are supposed to be DatePickers and they require javascript as well. I've tried giving them a unique ID from the integer that the loops iterates through, but it does not seem to find them?
This is the view:
#model ProjectName.Models.ViewModels.GuestCreatorViewModel
#using Res = ProjectName.Resources.Resources
#for (int i = 1; i <= Model.NumOfGuests; i++)
{
<div class="row">
<div class="form-group">
#Html.Label(Res.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label(Res.Period, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.DateRange, new { id = "dateRangePicker" + i, htmlAttributes = new { #class = "form-control" }, #readonly = true })
#Html.ValidationMessageFor(model => model.DateRange, "", new { #class = "text-danger" })
</div>
</div>
</div>
<script type="text/javascript">
$('input[name="dateRangePicker'+#i'"]').daterangepicker();
$('#dateRangePicker'+ #i'').daterangepicker({
"showWeekNumbers": true
}, function (start, end, label) {
console.log('New date range selected: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD') + ' (predefined range: ' + label + ')');
});
</script>
}
If I remove the "+ #i" in the javascript and "+ i" in the html.helper it works for the first row, but all rows/fields after does not work (I guess because the script is outside their scope). If I keep them, none of the fields work with the script.
Am I doing something wrong when dynamically naming them or something?
The DateRangePicker is taken from here, but I've also tried other datepickers where the same issue occurs.
First: This syntax is incorrect:
#Html.TextBoxFor(model => model.DateRange, new { id = "dateRangePicker" + i, htmlAttributes = new { #class = "form-control" }, #readonly = true })
It will render this useless attribute: htmlAttributes It should be:
#Html.TextBoxFor(model => model.DateRange, new { id = "dateRangePicker" + i, #class= "form-control", #readonly = true })
I guess it is a typo.
Second:
What you should do is generate all your HTML in the for loop, and use a single script tag after that to initialize the daterangepicker controls at once. You can get all inputs with a class instead of using their ids.
#{
int numOfGuests = 2;
}
#for (int i = 1; i <= numOfGuests; i++)
{
<div class="row">
<div class="form-group">
<div class="col-md-10">
#Html.TextBoxFor(model => model.DateRange, new { id = "dateRangePicker" + i, #class = "form-control custom-date-picker" , #readonly = true })
</div>
</div>
</div>
}
<script type="text/javascript">
$('input.custom-date-picker').daterangepicker({
"showWeekNumbers": true
}, function (start, end, label) {
console.log('New date range selected: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD') + ' (predefined range: ' + label + ')');
});
</script>
Explanation:
Upon creating the datepickers I add to each one a custom css class:
custom-date-picker
After the for loop renders the HTML I create a
script tag and get all inputs with the selector
.custom-date-picker and create daterangepicker controls out of
them
P.S. I used a simplified version of your code for the sake of explanation.
I would not use the ID to assign the datepicker but a css class (even a not defined one, just for this purpose).
So you code could be something like this:
#class = "control-label col-md-2 ToBeDatePickered"
So you could try and use this simple selector:
$(".ToBeDatePickered").daterangepicker();
// ... and so on...
And the JS code should be outside the for statement, maybe in a document.ready function like this:
<script type="text/javascript">
$(document).ready(funtion() {
$(".ToBeDatePickered").daterangepicker();
// ... and so on...
});
</script>
Hope this helps
I am trying to append a number of dropdowns on Button click.These dropdowns should have proper indexing in its 'name' attribute.
This is the dropdown:-
<div id="dropdownDiv" style="display:none">
<div class="form-group">
#Html.LabelFor(model => model.PropertyInvestors, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.PropertyInvestors, (IEnumerable<SelectListItem>)#ViewBag.Investors, "Select Investor", htmlAttributes: new { #id = "dropdown",#name= "[#].PropertyInvestors", #class = "form-control",#onChange="dropdownChange()" })
#Html.ValidationMessageFor(model => model.PropertyInvestors, "", new { #class = "text-danger" })
</div>
</div>
</div>
This is the JS code that I am trying in order to clone the dropdown and replace its name attribute with desired indexing.
$('#addDropdown').click(function () {
var index = (new Date()).getTime();
var clone1 = $('#dropdownDiv').clone();
clone1.html($(clone1).html().replace(/\[#\]/g, '[' + index + ']'));
$('#field1').append(clone1.html());
});
Problem:- The dropdowns are being appended as they are clicked but their name attributes are same for all of the dropdowns produced due to which I cant postback the data to the controller.
While this problem can be solved by using dummy code and manipulating the Index no. by using JS, a good method would be to use Html.BeginCollectionItem() by creating a partial view for the dropdown and later making an ajax call to append the partial view to the main view. Refer to the answer HERE
You can replace ID and Name as follows:
$('#addDropdown').click(function () {
var index = (new Date()).getTime();
var clone1 = $('#dropdownDiv').clone();
$(clone1).find('select').attr("id", index);
$(clone1).find('select').attr("name", "PropertyInvestor[" + index +"]");
$('#field1').append(clone1.html());
});
JSFiddler: https://jsfiddle.net/qj24yybe/6/
I'm pretty new to html, razor, and MVC so I apologize if this is a easy fix, but I've worked on this issue for a while with no resolution. I would like a controller action to be triggered that re-populates a partial view every time a drop down list changes. I've tried implementing this with the 'onchange' html attribute as well as by setting an id for the drop down and having a jquery function trigger it. But I can't get any of the three functions below to fire. Here's my code..
#model AislesOnlineDataControl.Models.PickupPointsListModel
#{
ViewBag.Title = "PickupPointsList";
}
<script>
function Select() {
#Html.Action("PickupPartial", "PickUpPoint", new { mod = Model.points[Model.selectedID] });
};
$("#PupDropDown").on('change', function () {
#Html.Action("PickupPartial", "PickUpPoint", new { mod = Model.points[Model.selectedID] });
});
$(function() {
$('#PupDropDown').change(function () {
Model.selectedID = Convert.ToInt32(selectPoint.SelectedValue);
//window.location.reload();
#Html.Action("PickupPartial", "PickUpPoint", new { mod = Model.points[Model.selectedID] });
});
});
</script>
<h2>Manage Pick-Up Points</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#{SelectList selectPoint = new SelectList(Model.selectedPoint, "Value", "Text");}
<div class="form-inline">
<div class="row">
#Html.DropDownListFor(model => model.selectedID, selectPoint, null, new { #id="PupDropDown", #onchange = "Select()" })
#Html.ActionLink("New", "CreatePickup", "PickUpPoint", null, new { #class = "btn btn-default pull-right" })
</div>
</div>
<div>
#Html.Partial("~/Views/PickUpPoint/PickupPartial.cshtml", Model.points[Model.selectedID])
</div>
</div>
}
#Html.Action(..) returns the ActionResultfrom your partial view, which eventually turns out to be a block of html code. So you cant put your html code in your JavaScript block.
What you need is the JavaScript code to have a ajax call to the action and render action Result.
Here is example of making simple ajax call in asp.Net MVC
https://stackoverflow.com/a/16186212/2802809
I can't seem to get the output that my previous answer is getting for TinyMCE.
I am using MVC and my HTML razor-view looks like below.
The TextAreaFor is my TinyMCE. When looking at the HTML in the browser I don't see an area for #tinymce-textarea? So I am not sure how to bind my script to it.
All I am trying to do is output the tinymce text area to a div below it.
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript">
tinymce.init({
selector: "#tinymce-textarea",
setup: function (editor) {
editor.on('change', function (e) {
var newVal = tinymce.get('tinymce-textarea').getContent();
$('.text-mirror').html(newVal);
});
}
});
</script>
#using (Html.BeginForm("Create", "Post", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<br />
<div class="editor-label">
#Html.TextAreaFor(model => model.Description)
</div>
<div class="editor-field">
#Html.ValidationMessageFor(model => model.Description)
</div>
<br />
<div class="text-mirror">
</div>
According to documentation selector option 'enables you to specify a CSS selector expression that will be used to find textareas you want to convert.'
In your html you don't have any textarea with id tinymce-textarea. All you need is add this id to your textartea html attributes
...
#Html.TextAreaFor(model => model.Description, new {Id = "tinymce-textarea"})
Or you can use id that is standard generated by MVC textarea helper which in your case is Description:
...
tinymce.init({
selector: "#Description",
setup: function (editor) {
editor.on('change', function (e) {
var newVal = tinymce.get('Description').getContent();
$('.text-mirror').html(newVal);
});
}
});
I've implemented Cascading Drop Down Lists on the Create View page of my MVC Asp.NET Application.
Unfortunately, I am having issues with selecting a value that is located in the JavaScript Array. I need to bind the selected value for the use of one of my controllers.
Right now my List populates, but I have no way to select it. Is there a way to move the counties[i] array from my JavaScript to the #Html.DropDownListFor() helper?
Thanks!
JavaScript:
<script src="#Url.Content("~/Scripts/jquery-1.10.2.min.js")"
type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$("#county").prop("disabled", true);
$("#StateLongName").change(function() {
if ($("#StateItems").val() != "Please select") {
var options = {};
options.url = "/County/GetCounties";
options.type = "POST";
options.data = JSON.stringify({ state: $("#StateLongName").val() });
options.dataType = "json";
options.contentType = "application/json";
options.success = function(counties) {
$("#county").empty();
for (var i = 0; i < counties.length; i++) {
$("#county").append("<option>" + counties[i] + "</option>");
}
$("#county").prop("disabled", false);
};
options.error = function() { alert("Error retrieving counties!"); };
$.ajax(options);
} else {
$("#county").empty();
$("#county").prop("disabled", true);
}
});
});
</script>
Controller:
//GET Counties for Cascading Dropdown List
public JsonResult GetCounties(string state)
{
var counties = db.countycigtaxes.Join(db.statecigtaxes,
cc => cc.stateid,
sc => sc.stateid,
(cc, sc) => new
{
cc,
sc
}).Where(co => co.sc.statefullname == state)
.Select(co => co.cc.countyfullname).ToList();
return Json(counties);
}
View Page:
<div class="form-group">
#Html.LabelFor(model => model.StateLongName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.StateLongName, Model.StateItems, "Please select")
#Html.ValidationMessageFor(model => model.StateLongName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CountyLongName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#*#Html.DropDownListFor(m => m.CountyLongName, )*#
<select id="county"></select>
#Html.ValidationMessageFor(model => model.CountyLongName)
</div>
</div>
I assume you mean the the selected value of the property CountyLongName is not posting back when you submit the form. You have commented out this line
#Html.DropDownListFor(m => m.CountyLongName, )
and used
<select id="county"></select>
If you want the manual version (I do not recommend this), then you need to add a name attribute that matches the property name so it can be bound by the ModelBinder
<select name="CountyLongName" id="county"></select>
But it is better to use the helper and pass it an empty SelectList
Html.DropDownListFor(m => m.CountyLongName, Model.CountryNames)
where Model.CountryNames is a property in you view model that is initialised to an empty SelectList
Note also options.type = "POST"; should be "GET" and the whole AJAX could be simplified to
$.get('#Url.Action("GetCounties","Country")', { state: $('#StateLongName').val() }, function(countries) {...
and theToList() is not required in the JsonResult method
This should set the option selected for you.
$("#county option[value='" + counties[index] + "']").attr("selected", "selected");