JQuery selectmenu won't initialize after ajax call - jquery-ui

I am using filamentgroup JQuery selectmenu widget. The widget is initialized in page's head section. When the page is loaded for the first time Jquery loads widget successfully but after ajax call (form submit using POST) selectmenu widget stops working (not initializing). I had same problem using input text fields for submitting form on enter key press but then I used delegate method to attach an event handler to selected elements. And it worked. So my question is: how can I reinitialize selectmenu after AJAX call. Maybe I can use same delegate method for initialization. I googled but didn't found any JQuery events that initializes widgets. Here is the code snippet
<head>
<script type="text/javascript">
$(document).ready(function()
{
$('select').selectmenu
({
width: 70,
style: 'dropdown',
menuWidth: 100,
maxHeight: 400,
change: function()
{
$(this).parents('form').submit();
}
});
$('body').delegate('.submit', 'keydown', function(e)
{
if (e.keyCode == 13)
{
$(this).parents('form').submit();
return false;
}
});
$('#regFormID').submit(function()
{
$.ajax(
{
type: 'POST',
url: 'index.php',
data: $(this).serialize(),
error: function(xml, status, error)
{
$('#dataFilterID').html('<p><strong>Error Code:</strong> '+status+'</p><p><strong>Explanation:</strong> '+error+'</p>');
},
success: function(data, textStatus, jqXHR)
{
$('#dataTableID').html($(data).find('#dataFilterID').html());
}
});
return false;
}
});
</script>
</head>
<body>
<div id="#dataFilterID">
<form id="regFormID" class="reg-form" name="regForm" method="POST" action="">
<select class="select" id="Filter-dbPage-count" name="Filter-dbPage-count">
<option selected="selected" value="30">30</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="150">150</option>
<option value="200">200</option>
</select>
<input type="text" value="" class="submit " id="Filter-dbField-1" name="Filter-dbField-1">
<input type="text" value="" class="submit " id="Filter-dbField-2" name="Filter-dbField-2">
<input type="text" value="" class="submit " id="Filter-dbField-3" name="Filter-dbField-3">
</form>
</div>
</body>

rebind in the success callback
success: function(data, textStatus, jqXHR)
{
$('#dataTableID').html($(data).find('#dataFilterID').html());
$('select').selectmenu
({
width: 70,
style: 'dropdown',
menuWidth: 100,
maxHeight: 400,
change: function()
{
$("select").parents('form').submit();
}
});
}

Related

Select2 custom data return from API

I am working with select2 to display the data return from the API. However, the data didn't manage to load out.Am I doing something wrong? Any ideas how to fix this?
HTML:
<select class="js-example-basic-single form-control select2 select2-hidden-accessible" id="user" name="user_id" autocomplete="off" required="required">
<option value="">Please select</option>
</select>
script:
var url = "{{env('API_URL')}}";
var username = null;
$(".select2").select2({
placeholder: "Please select",
width: null,
ajax: {
dataType: "jsonp",
method: "GET",
data: function (term) {
username = term.term;
return {"username": username};
},
url: url+"user/search/username?",
results: function (data) {
return {
results: data.result.users
};
},
},
formatResult: function (option) {
return "<option value='" + option.id + "'>" + option.username + "</option>";
},
formatSelection: function (option) {
return option.id;
}
});
result return from API:
result : [{"users":["[object] (App\\User: {\"username\":\"Kaki\",\"id\":123456})","[object] (App\\User: {\"username\":\"(Alan)\",\"id\":123457})","[object] (App\\User: {\"username\":\"Alex\",\"id\":123458})","[object] (App\\User: {\"username\":\"Sky\",\"id\":1234569})","[object] (App\\User: {\"username\":\"Kvin\",\"id\":123460})"]}] []
One thing is your JSON return from API who is not well formatted.
[{
"users":[
"[object] (App\\User: {\"username\":\"Kaki\",\"id\":123456})",
"[object] (App\\User: {\"username\":\"(Alan)\",\"id\":123457})",
...
]
}]
should be
[{
"users":[
{"username":"Kaki","id":123456}),
{"username":"(Alan)","id":123457}),
...
]
}]
I don't know what is Select2 version you use, but > 4 is advice.
Use functions templateResult and templateSelection is better, later you can return HTML for nicer rendering.
You can use this snipplet demo.
$(".select2").select2({
placeholder: "Please select",
width: null,
ajax: {
dataType: "json",
method: "GET",
url: function (params) {
// return 'url+"user/search/username?' + params.term;
// Fake url to make demo working, use upper line
return 'http://ip.jsontest.com/';
},
processResults: function (data) {
// Use this function to convert api result to Select2 result
// return {"results":data.users};
// Build fake answer for demo
return {"results":[{"username":"Kaki","id":123456},{"username":"(Alan)","id":123457}]};
},
},
templateResult: function (dataRow) {
if (dataRow.loading) return dataRow.text;
return dataRow.username;
},
templateSelection: function (dataRow) {
return dataRow.username;
}
});
.select2 {
width:50%
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/select2/4.0.1/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/select2/4.0.1/js/select2.full.js"></script>
<select class="form-control select2" id="user_id" name="user_id" autocomplete="off" required="required">
<option value="">Please select</option>
</select>
$(".select2").select2({
placeholder: "Please select",
width: null,
ajax: {
dataType: "json",
method: "GET",
url: function (params) {
// return 'url+"user/search/username?' + params.term;
// Fake url to make demo working, use upper line
return 'http://ip.jsontest.com/';
},
processResults: function (data) {
// Use this function to convert api result to Select2 result
// return {"results":data.users};
// Build fake answer for demo
return {"results":[{"username":"Kaki","id":123456},{"username":"(Alan)","id":123457}]};
},
},
templateResult: function (dataRow) {
if (dataRow.loading) return dataRow.text;
return dataRow.username;
},
templateSelection: function (dataRow) {
return dataRow.username;
}
});
.select2 {
width:50%
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/select2/4.0.1/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/select2/4.0.1/js/select2.full.js"></script>
<select class="form-control select2" id="user_id" name="user_id" autocomplete="off" required="required">
<option value="">Please select</option>
</select>

How do I target a div when programmatically submitting and MVC Ajax form?

I'm using the MVC4 Ajax helper functions on a form and I'd like to submit the form from script.
The problem is when I call the submit function, it does not load into the proper div. Any thoughts?
#using (Ajax.BeginForm("NewGame", "Home", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "targetDiv" }, new { id = "newGameForm" }))
{
<input type="hidden" name="client_seed" id="client_seed" />
<input type="submit" value="New Game" id="NewGameButton" />
<a class=button onclick="$('#newGameForm').submit();">New Game</a>
}
Clicking the standard submit button load the results of the call into the targetDiv. Clicking on the anchor replaces the current div.
The key is to prevent default browser behavior via .preventDefault() or to return false at the end of the event handlers.
This is how I'd do it:
<div id="targetDiv"></div>
#using(Html.BeginForm("NewGame", "Home", FormMethod.Post,
new { id = "newGameForm" }))
{
<input type="hidden" name="client_seed" id="client_seed" />
<input type="submit" value="New Game" id="NewGameButton" />
}
<script type="text/javascript">
$(document).ready(function () {
$("#newGameForm").on("submit", function(e) {
e.preventDefault();
$.ajax({
url: $(this).attr("action"),
data: $(this).serialize(),
type: $(this).attr("method") // "POST"
})
.done(function(result) {
$("#targetDiv").html(result);
})
.fail(function((jqXHR, textStatus, errorThrown) {
// handle error
});
});
});
</script>
If you insist on using an anchor <a>...
New Game
<script type="text/javascript">
$(document).ready(function() {
$("#submit-link").on("click", function(e) {
e.preventDefault();
$("#newGameForm").submit();
});
$("#newGameForm").on("submit", function(e) {
e.preventDefault();
$.ajax({
...
});
});
</script>
Edit There is also an AjaxHelper.ActionLink method. If you're already using the AjaxHelper in other parts of your code you might want to stick with that.
Pseudo Code.
<a class=button onclick="PostAjax();">New Game</a>
function PostAjax(){
$.ajax({
url:"Home/NewGame",
data:$('#newGameForm').serialize(),
DataType:"HTML", // assuming your post method returns HTML
success:function(data){
$("#targetDiv").html(data);
},
error:function(err){
alert(err);
}
})
}

jQueryUI Autocomplete won't close on select

I'm pretty new to jQuery and UI, and I'm having two issue with the autocomplete, and I suspect they're related. When I select an item in the list, the value, not the label, is displayed in the input. Second, the autocomplete will not close. When I step through my code, the select function gets called, and I see my label, not the value, displayed in the input, as I want. Unfortunately, the close function gets called (twice), and the ui.item.value replaces the label in the input and the autocomplete doesn't close.
My autocomplete code, along with the input HTML, is below. If it matters, the autocomplete is nested in a jQueryUI dialog.
HTML:
<input id="id_projectid" type="text" class="projEntryControl ui-autocomplete-input ui-corner-all" name="projectid" autocomplete="off"></input>
AutoComplete:
$('#id_projectid').autocomplete({
source: function(request, response) {
$.ajax({
url: "/chargeback/projList/" + $('#id_departmentid').val(),
dataType:"json",
data: {
project_startsWith: request.term
},
success: function(data) {
response( $.map( data.results, function( item ) {
return {
label: item.projectName,
value: item.id
}
}));
}
});
},
minLength: 3,
select: function(event, ui) {
$('#id_projectid').val(ui.item.label);
},
open: function() {
$( '#id_projectid' ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
EDIT: Adding more code as requested.
Here's the javascript that sets up the dialog, and connects the buttons to open the dialog
function setupProjectEntryDialog() {
$( "#addPEForm" ).dialog({
autoOpen: false,
height: 490,
width: 376,
modal: true,
buttons: {
"Save": function() {
var bValid = true;
allFields.removeClass( "ui-state-error" );
bValid = bValid && checkRegexp( hrsWorked, /^(?!\d{3})(?![2-9]\d)(?!1[1-9])(10|[1-9]{1})(.\d{0,2})?$/, "Please enter a valid number of hours worked." );
if ( bValid ) {
//save the changes to the database
var dataArray = $("#peUpdateForm").serializeArray();
var ed = new Object();
ed.name = "entryDateId";
ed.value = $("#entryDateId").text();
dataArray.push(ed);
if ($("#projEntryId").val() != "") {
var pe = new Object();
pe.name = "projEntryId";
pe.value = $("#projEntryId").val();
dataArray.push(pe);
}
$.post('/chargeback/savepe/', dataArray, function(data){
alert(data.msg);
//reload the project entries and total hours worked
showProjectEntries($('.entryDate.selected'));
getTotalHoursForEntryDate($('.entryDate.selected'));
}, "json");
//close the window
$( this ).dialog( "close" );
$('#id_projectid').autocomplete("destroy");
}
},
Cancel: function() {
$( this ).dialog( "close" );
$('#id_projectid').autocomplete("destroy");
}
},
close: function() {
allFields.val( "" ).removeClass( "ui-state-error" );
}
});
//connect the add new button
$("#addNewPEButton").click(function() {
$( "#addPEForm" ).dialog( "open" );
});
//hook up the add new project entry form submittal
$("#addNewPE").submit(function() {
addProjectEntry($(this));
return false;
});
//connect the delete Project Entry button
$('#deletePEButton').click(function() {
deleteProjectEntry($('.peRow.selected'));
return false;
});
//connect the row click method to the function
$('.peRow').click(function() {
peRowWasClicked($(this));
});
$('.peRow').dblclick(function() {
peRowWasDoubleClicked($(this));
})
}
Here's the javascript that loads the Dialog using a Django form and template to generate the HTML.
function addProjectEntry(anED) {
//ensure all peRows are not selected and disable the delete project entry button
$('.peRow').removeClass('selected');
$('#deletePEButton').attr('disabled', true);
//disable newFavoriteFromPEButton
$('#newFavoriteFromPEButton').attr('disabled', true);
//get the id of the selected entry date and strip the ed_ from it
$selectedED = $(".entryDate.selected");
var edId = $selectedED[0].id.split("_");
$("#addPEForm").load("/chargeback/cb_timeentry/newPE/" + edId[1], function() {
//connect the variables to the newly loaded html
connectDialogVariables();
//connect the project filtering to the department change
/*$("#id_departmentid").change(function() {
getProjectsForDepartment();
});*/
//connect the project and program number autocompletes to the controls
$('#id_projectid').autocomplete({
source: function(request, response) {
$.ajax({
url: "/chargeback/projList/" + $('#id_departmentid').val(),
dataType:"json",
data: {
project_startsWith: request.term
},
success: function(data) {
response( $.map( data.results, function( item ) {
return {
label: item.projectName,
value: item.id
}
}));
}
});
},
minLength: 3,
select: function(event, ui) {
$('#id_projectid').val(ui.item.label);
$(this).close();
return false;
},
open: function() {
$( '#id_projectid' ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
});
}
This is the HTML after the ajax call completes, and the above javascript completes. The autocomplete begins the search when typing in the correct text input, and is positioned correctly, but isn't part of the form.
<div class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable ui-resizable ui-dialog-buttons" style="outline: 0px none; z-index: 1002; position: absolute; height: auto; width: 376px; top: 66px; left: 297.5px; display: block;" tabindex="-1" role="dialog" aria-labelledby="ui-id-9">
<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix">
<span id="ui-id-9" class="ui-dialog-title">Project Entry Update</span>
<a href="#" class="ui-dialog-titlebar-close ui-corner-all" role="button">
<span class="ui-icon ui-icon-closethick">close</span>
</a>
</div>
<div id="addPEForm" class="ui-dialog-content ui-widget-content" style="width: auto; min-height: 0px; height: 367px;" scrolltop="0" scrollleft="0"><form action="" id="peUpdateForm" method="post">
<div style="display:none"><input type="hidden" value="BTrLZBVfA2ltExq3OUU5015BVxPKO9lL" name="csrfmiddlewaretoken"></div>
<p><label for="id_departmentid">Department:</label>
<select name="departmentid" class="projEntryControl" id="id_departmentid">
<option selected="selected" value="">Choose a Department</option>
<option value="1">ABND</option>
<option value="2">ATT</option>
<option value="3">AVI</option>
<option value="4">CCS</option>
<option value="5">PBW</option>
</select></p>
<p>
<label for="id_projectid">Project:</label>
<input type="text" name="projectid" class="projEntryControl ui-autocomplete-input" id="id_projectid" autocomplete="off">
<span role="status" aria-live="polite" class="ui-helper-hidden-accessible"></span>
</p>
<p>
<label for="id_progNumId">Program Number:</label>
<input type="text" name="progNumId" class="projEntryControl" id="id_progNumId">
</p>
<p>
<label for="id_hoursWorked">Hours Worked:</label>
<input type="text" id="id_hoursWorked" maxlength="5" class="projEntryControl" value="0.0" name="hoursWorked">
</p>
<p>
<label for="id_notes">Notes:</label>
<textarea name="notes" cols="40" rows="10" id="id_notes"></textarea
</p>
<p style="display:none;" id="entryDateId">1</p>
<p style="display:none;" id="projEntryId"></p>
</form>
</div>
<div class="ui-resizable-handle ui-resizable-n" style="z-index: 1000;"></div>
<div class="ui-resizable-handle ui-resizable-e" style="z-index: 1000;"></div>
<div class="ui-resizable-handle ui-resizable-s" style="z-index: 1000;"></div>
<div class="ui-resizable-handle ui-resizable-w" style="z-index: 1000;"></div>
<div class="ui-resizable-handle ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se ui-icon-grip-diagonal-se" style="z-index: 1000;"></div>
<div class="ui-resizable-handle ui-resizable-sw" style="z-index: 1000;">
</div><div class="ui-resizable-handle ui-resizable-ne" style="z-index: 1000;"></div>
<div class="ui-resizable-handle ui-resizable-nw" style="z-index: 1000;"></div>
<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
<div class="ui-dialog-buttonset">
<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button" aria-disabled="false">
<span class="ui-button-text">Save</span>
</button>
<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button" aria-disabled="false">
<span class="ui-button-text">Cancel</span>
</button>
</div>
</div>
</div>
<div class="ui-widget-overlay" style="width: 979px; height: 567px; z-index: 1001;"></div>
<ul class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all" id="ui-id-11" tabindex="0" style="z-index: 1003; display: none;">
</ul>

Issue when submitting form data via JQuery UI Dialog to the server

I have an asp.net mvc app, using JQuery UI dialog. I'm trying to submit form data to the controler action method. I do hit the action method but my object has no data. Do you know why?
From Filter.cshtml
$("#selectUnits").dialog({
autoOpen: false,
title: 'Select Units',
width: 400,
modal: true,
minHeight: 200,
buttons: {
"Cancel": function () {
$(this).dialog("close");
},
"Submit": function () {
$.post('/Data/SetUnitNumbers', $("#frmSelectedUnits").submit(), function (data) {
alert('This worked');
});
}
} // END OF BUTTONS
}); //END OF DIALOG
From Controler...Action Method:
public void SetUnitNumbers(object data)
{
int a = 5;
}
From SelectUnits.cshtml where form 'frmSelectedUnits' lives. Essentially it is a bunch of checkboxes values that I'm trying to send back to the server:
<body>
<form id="frmSelectedUnits" action="/" >
<div id="unitNumberCheckboxes" style=" ">
<div>
#Html.CheckBox("SelectAllUnitNumbers", false)<label for="SelectAllUnitNumbers"><b>Select/Unselect All Units</b></label>
</div>
<div id="unitCheckboxes">
#foreach (var item in Model)
{
<div style="float:left">
#Html.CheckBox("UnitNumbers", false)<label for="UnitNumbers">#item.unit_number.ToString().PadLeft(3, '0') </label>
</div>
}
</div>
</div>
</form>
</body>
jQuery .post is:
$.post(url, data, success-callback-function);
where data is A map or string that is sent to the server with the request.
Calling $("#frmSelectedUnits").submit() probably won't work.
Try:
$.post('/Data/SetUnitNumbers', $("#frmSelectedUnits").serialize(), function (data) {
alert('This worked');
});
jQuery docs on .serialize()

JqueryUI Dialog. Unable to trigger from html form

Works fine with a text link to fire dialog - but lasts for about .5 second if triggered from an html form submit button. Sounds crazy! Yep, just cannot get it to work. Help!
$(document).ready(function() {
$('#rating-0').click(function() { $('#dialog').dialog('open'); }); $('#dialog').dialog({ autoOpen: false, height: 280, modal: true, resizable: false, buttons: { Continue: function() {
$(this).dialog('close'); // Submit Rating
}, 'Change Rating': function() {
$(this).dialog('close'); // Update Rating
} }
});
});
<form action="https://www.etc" id="rating-0">
<input type="hidden" name="cmd" value="_s-xclick" />
<input name="submit" type="image" src="https://www.paypal.com/en_GB/i/btn/btn_cart_LG.gif" />
</form>
<div id="dialog" title="Are you sure?">
<p>You've assigned the current celebrity a rating of 0…</p> <p>Perhaps you are just judging them on the terrible last movie…</p>
</div>
Add return false; to your submit or click handler to prevent the browser from submitting the form and reloading the page.
EDIT:
$(document).ready(function() {
$('#rating-0').submit(function() {
$('#dialog').dialog('open');
return false;
});
...
});

Resources