Add a new method to a jQuery UI widget - jquery-ui

The jQuery UI docs give an example of extending an existing UI widget method, like this:
$.widget("ui.dialog", $.ui.dialog,
{
open: function()
{
console.log("open");
return this._super();
}
});
That works for me using UI 1.12.1, I see the expected log entry when a dialog is opened.
However, using the same technique to recreate the removed .url() method of jQuery UI Tabs does not, throws the error "Uncaught TypeError: $(...).url is not a function". This is my code:
$.widget("ui.tabs", $.ui.tabs,
{
url: function (index, url)
{
console.log("url");
$(this.data("uiTabs").anchors[index]).attr("href", url);
return this;
}
});
What's the difference here, besides the fact that the url() method is being created rather than extended? Is it possible to do what I'm attempting?

It is possible however I am unsure of that line after the log, i.e. the .data() method seems invalid here?
Perhaps you meant this:
$.widget("ui.tabs", $.ui.tabs, {
url: function(index, url) {
$(this.anchors[index]).attr("href", url);
}
});

Related

angularjs $compile is not working on production

I am using angularJS in my MVC application and loading a partial using ajax call in angularJS. I am using $compile to compile the html. Everything is working fine on local but it is not working on production. Unexpected error is showing. Below is the code I am using.
Angular Controller:
app.controller("mproductController", ["$scope", "mproductService", "$compile", function ($scope, mproductService, $compile) {
$scope.ShowProdUnitPop = function (val) {
mproductService.ShowProdUnitPop(val).success(function (result) {
debugger;
var snippet = angular.element(result);
$compile(snippet)($scope);
$("#dvAddProd").html(snippet);
$("#dvPopup").modal('show');
});
}
}
Angular Service:
app.service("mproductService", ["$http", function ($http) {
this.ShowProdUnitPop = function () {
var request = $http({
method: "post",
url: "/Home/GetActiveCat"
});
return request;
}}
MVC Controller:
[HttpPost]
public ActionResult AddProduct(int id)
{
ViewBag.ProductCategory = Utility.GetProd(id);
return PartialView("_AddProduct",new Product());
}
Error is throwing on this line:
var snippet = angular.element(result);
$compile(snippet)($scope);
$("#dvAddProd").html(snippet);
$("#dvPopup").modal('show');
It is working on local but not on production. Please help.
Seems like you are using bundling and minification enabled on production server. That is breaking you controller code while you are utilizing that controller and its necessary to have inline array annotation of DI while minifying JS files.
Most possible answer would be you are using $compile by injecting it to controller and using it, That's fine. It seems like you had not followed inline array dependency injection inside your controller.
Also you need to attach compile element to your dvAddProd element, rather than updating html, appending html to DOM will never make angular angular binding on that element. Looks like this code shouldn't be working on any of the environment if it has angular bindings on it.
Controller
app.controller('someCtrl', ['$scope', '$http', '$compile',
function($scope, $http, $compile) {
//you should have controller in this way that would fix your issue
//note I'm using inline array notation of DI
$scope.ShowProdUnitPop = function(val) {
mproductService.ShowProdUnitPop(val).success(function(result) {
debugger;
var snippet = angular.element(result);
var compiledSnippet = $compile(snippet)($scope);
$("#dvAddProd").append(compiledSnippet); //should attach compile element
});
}
}
]);
Visit this link for more Information

ajax request php class function

i have content listed in a div and i have a dropdown with various options to order and filter that content.
I'm using ajax to filter/order that content and is working but i use other php page with the content i want on the div that has the content, like this
function order(str){
$.post("order_products.php",
{
q: str,
},
function(data, status){
document.getElementById("txtHint").innerHTML = data;
});
}
What i wanted was to instead of putting the code (data) to change in another page just for that, i could put that code inside a class php function that i have.
<?php
class products{
function list(){
blablabla
}
That way i would "save space" and organize everything, considering that i have many other things to order/filter but i don't know to to make the ajax request to that function, or if it's possible without having a page in between and then get the response from the function and put it on the div.
You can do this using Laravel by setting up a route to a function that will do the ordering. Please note I've made a lot of assumptions in the following answer as I can't see all your code and have made it quite general, please adjust the code to your project or provide more details of your code if you don't understand the answer fully.
routes.php
Route::post('products/order', [
'as' => 'products.order',
'uses' => 'ProductsController#orderProducts'
]);
Your view (assuming you're using blade)
$txtHint = $('#txtHint'); // grab the reference to txtHint dropdown
$.post( '{{ route("products.order") }}', // hit our route
{
q: str,
},
function(data, status){
$txtHint.empty(); // clear the dropdown
// loop through the data and assign each element to the dropdown
$.each(data, function(value, key) {
$txtHint.append($("<option></option>")
.attr("value", value)
.text(key));
});
});
ProductsController.php
public function orderProducts()
{
$orderBy = \Input::get('q');
return \Products::lists('name', 'id')->orderBy($orderBy);
}
For outside of a framework just change the url to your php file and add in a data attribute for the method you require to be fired from the file.
$.post( 'products.php', // hit our route
{
action: 'order',
q: str,
},
...
Then in products.php you'd do something like this
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'order' : order();break;
case 'otherFunction' : otherFunction();break;
}
}
function order()
{
// order logic here
// get $_POST['q']
// do your ordering
// return data as json
}
See here for similar question: using jquery $.ajax to call a PHP function

Select2 use a dynamic Ajax URL on call

I use the Select2 plugin (v 3.5.2) with Ajax to dynamically load elements in the list.
I have an issue as between the initialization of the Select2 (where a url property is set in the ajax helper) and the time the ajax call is made, this url might need to be changed.
So I have something like this :
$box.select2({
containerCssClass: "form-control"
minimumInputLength: 0,
allowClear: true,
ajax: {
url: someUrl,
dataType: 'json',
quietMillis: 100,
...
}
I can't figure out how, when, where to change the ajax.url value before it launches.
The help of Select2 says:
Select2 uses jQuery's $.ajax function to execute the remote call by default. An alternative transport function can be specified in the ajax settings, or an entirely custom implementation can be built by providing a custom query function instead of using the ajax helper.
But I can't find any example on how to do it.
Thanks in advance for any help. Much appreciated.
I can't figure out how, when, where to change the ajax.url value before it launches.
The ajax.url option can be specified as a static string or a method returning one in both Select2 3.5.x and 4.0.0.
$("select").select2({
ajax: {
url: function () {
return UrlHelper.RemoteAPI();
}
}
});
This is useful for changing the base URL, for example when the URL is determined at runtime or is automatically generated in a different method. If you need to change the query parameters, such as the one used for sending the search term, you need to override the ajax.data option.
$("select").select2({
ajax: {
data: function (args) {
// args is the search term in 3.5.x
// args is an object containing the query parameters in 4.0.0
// args.term is the search term in 4.0.0
return {
search: args.term || args;
};
}
}
});
The data here will be appended as query parameters by default, and will be sent as the request body if the method type is changed from GET (the default) to anything else.
Select2 uses jQuery's $.ajax function to execute the remote call by default. An alternative transport function can be specified in the ajax settings, or an entirely custom implementation can be built by providing a custom query function instead of using the ajax helper.
But I can't find any example on how to do it.
Select2 does allow for a different AJAX transport to be used by changing the ajax.transport option.
In 3.5.2, this must be a $.ajax-compatible method, so it must be able to take an object containing the success and failure callbacks.
$("select").select2({
ajax: {
transport: function (args) {
// args.success is a callback
// args.failure is a callback
// should return an object which has an `abort` method.
return $.ajax(args);
}
}
});
In 4.0.0, this must be a method which takes a params object (the same one passed to ajax.data), a success callback, and a failure callback.
$("select").select2({
ajax: {
transport: function (params, success, failure) {
var $request = $.ajax(params);
$request.then(success);
$request.fail(failure);
return $request;
}
}
});
Very Simple Javascript code to handle the same, can be used in Suitescript(Netsuite) also.
// prepare your dynamic URL inside this method and return
function getURL() {
return url + params;
}
// While binding the select2 with the dropdown set url to call a anonymous function which internally calls another function.
jQuery("select.itemDropDown").select2({
placeholder: "Select an item",
width: "200px",
minimumInputLength: 3,
ajax: {
url: function() {
return getURL()
},
dataType: 'json'
}
});

Callback after .swap() not working - ASP.NET SPA w/sammy.js

I am building a Single Page Application using ASP.NET and sammy.js, where all views except for the Home/Index view are rendered as partial views so that sammy can swap out the content of the main body with the partial view that is returned.
I am using the example given here, and everything loads fine as expected.
Similar to the above example, in my Home/Index page I have reference to a script called routing.js, which wraps the sammy function call in order to parse the MVC route:
var Routing = function (appRoot, contentSelector, defaultRoute) {
function getUrlFromHash(hash) {
var url = hash.replace('#/', '');
if (url === appRoot)
url = defaultRoute;
return url;
}
return {
init: function () {
Sammy(contentSelector, function () {
this.get(/\#\/(.*)/, function (context) {
var url = getUrlFromHash(context.path);
context.load(url).swap();
});
}).run('#/');
}
};
}
I need to call a callback function after the content swap has fully completed in order to implement further jQuery functionality on the newly rendered content. My dilemma is that no matter what option I try from the sammy.js docs, nothing seems to run the callback after the content has been swapped.
I have tried all of the following (all "valid" ways of passing a callback according to the sammy.js docs):
content.load(url).swap(pageLoadScripts(url));
content.load(url).swap().onComplete(pageLoadScripts(url));
content.load(url).swap().then(pageLoadScripts(url));
content.load(url).swap().next(pageLoadScripts(url));
content.load(url,pageLoadScripts(url)).swap();
and even
content.load(url).swap();
pageLoadScripts(url);
In every case the pageLoadScripts function fires off prior to the content being swapped. Any ideas or suggestions on what to do differently?
This is a bit of a hack, but it works.
Inside the Sammy initialization function, I added the following override to the swap function just before the override to the get function:
this.swap = function (content, callback) {
var context = this;
context.$element().html(content);
pageLoadScripts(hashedUrl);
};
FWIW, I still have not been able to get callback to be anything other than 'undefined', even in this override function.
Managed to get this working:
// override for callback after page load
this.swap = function(content, callback) {
this.$element().html(content);
if (callback) {
callback();
}
};
// users
this.get('/#/users', function(context) {
context.load('/users').swap(function() { replaceBindings(viewModel.users); });
});
I managed to get the callback param to NOT be 'undefined' by wrapping it in another function.

Dotnetnuke partial rendering make my jQueryUI widget stop working

I want to use tab widget of jQueryUI in dotnetnuke 5.6.3
I registered jQueryUI in my module and it works fine but when I use partial Rendering in my page it fails to load.
Here is my code:
$(document).ready(function () {
rastaAdmin();
});
function rastaAdmin() {
var tabdiv = $('#tabul');
var tabvar = tabdiv.tabs();
}
this site have a method to solve my problem but it doesn't work in my script.
After reading the above site I changed my code to:
$(document).ready(function () {
rastaAdmin();
});
function pageLoad(sender, args) {
rastaAdmin();
}
function rastaAdmin() {
var tabdiv = $('#tabul');
var tabvar = tabdiv.tabs();
}
This Doesn't work for me.
What Can I do?
Thank You
I've had issues using the pageLoad function as well (though I don't remember now where it ended up breaking down). However, something like the other method should work fine (see the new jQuery UI setup in the core modules in DNN 6):
$(document).ready(function () {
setupDnnSiteSettings();
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function () {
setupDnnSiteSettings();
});
});
The one caveat here is that this registers the setup code to happen after returning from any UpdatePanel-initiated request, not just your specific UpdatePanel. Calling tabs again on the same element shouldn't cause any issue, but you'll want to figure out a way to differentiate if you're doing something that should only be called once.
Thank you bdukes
After your help, I changed my code to:
$(document).ready(function () {
Sys.Application.add_load(function (s, e) { rastaAdmin(); });
rastaAdmin();
});
function rastaAdmin() {
var tabdiv = $('#tabul');
var tabvar = tabdiv.tabs();
}
And It Works Like a charm for me! Thank You mate.

Resources