jQuery element reloader

#1

I have looked around for an already existing script for this, but couldn’t find one, so i decided to make my own.

The point of this is to make it easy to reload an element, whether its a form or a link.

To use the script, you add a class to the link/form called “js_container-reloader”.
What the script does is it simply gets the content of the action url or href, creates a wrapper around the element you are reloading, takes the ajax response and puts it in to the wrapper, then removes the wrapper.

Its working as it should at the moment, but i wonder if there is a better way of doing this.

//Form element reloader
$(document).on("submit", ".js_container-reloader", function(e){
	e.preventDefault();

	//Call the reloader function
	elementReloader(e.currentTarget, "POST");
});


//Link element reloader
$(document).on("click", ".js_container-reloader", function(e){
	e.preventDefault();

	//Call the reloader function
	elementReloader(e.currentTarget, "GET");
});


/* 	Element reloader function
*	Takes an element and the type of request this is */
function elementReloader(element, type){

	//Set variables
	var element = $(element),
		eleAction = element.attr('action'),
		eleHref = element.attr('href'),
		reloadContainer,
		ajUrl,
		ajType,
		data;


	//Wrap the element in a reloader div and save the div to a variable
	element.wrap("<div class='dv_dis-i js_reload-container'></div>");
	reloadContainer = element.closest('.js_reload-container');


	//If the request should be done by POST
	if(eleAction){
		ajType = "POST";
		ajUrl = eleAction;
		data = element.serialize();


	//If the request should be done by GET
	}else{
		ajType = "GET";
		ajUrl = eleHref;
	}


	//Run the ajax script
	$.ajax({
		type: ajType,
		url: ajUrl,
		data: data,
		success: function(result){

			//Add the result to the wrapper
			reloadContainer.html(result);


			//Remvoe the wrapper
			reloadContainer.find(".js_container-reloader").unwrap();
		},
		error: function(xhr) {

			/*	Reload the alerts container
			*	An alert is saved to the session if there was an error
			*	with any script that was loaded.
			*	This function reloads the container which shows the session alert. */
			reloadAlertContainer();
		},
	});
}

I don’t assume my code is expert level as i am not an expert, but the goal is to make it as easy and dynamic as possible for future implementations.
I tried looking in to combining the code, especially the first 2 functions for the event listeners, together in to one function, but couldn’t find a way that seemed like a proper solution.

Just to clarify about the form posting - i do the form validation and checking in php, in the actual file that is being loaded, and not in JavaScript/jQuery. This script is just for reloading elements.

#2

Maybe this is useful for others, so ill post my edited code, i ran in to problems with the previous one, and got suggestions to update it, so this is the current script i have:

//Form element reloader
$(document).on("submit", ".js_container-reloader", function(e){
	e.preventDefault();

	//Call the reloader function
	elementReloader(e.currentTarget);
});


//Link element reloader
$(document).on("click", ".js_container-reloader", function(e){
	e.preventDefault();

	//Call the reloader function
	elementReloader(e.currentTarget);
});


/* 	Element reloader function
*	Takes an element and the type of request this is */
function elementReloader(element){

	//Set variables
	var element = $(element),
		requestUrl,
		requestType,
		data,
		reloadContainer;


	//Wrap the element in a reloader div and save the div to a variable
	element.wrap("<div class='dv_dis-i js_reload-container'></div>");
	reloadContainer = element.closest('.js_reload-container');


	//If the element is a form
	if(element.is("form")){

		//Save the forms action
		requestUrl = element.attr('action');

		//Save the request type
		requestType = element.attr('method');

		//Save the forms data
		data = element.serialize();


	//If the request should be done by GET
	}else{

		//Get the forms action
		requestUrl = element.attr('href');

		//Save the request type
		requestType = "GET";
	}


	//Run the ajax script
	$.ajax({
		type: requestType,
		url: requestUrl,
		data: data,
		success: function(result){

			//If the result returned false, reload the alert container
			if(!result){
				reloadAlertContainer();

			//If its not false then load the container with the result
			}else{

				//Add the result to the wrapper
				reloadContainer.html(result);

				//Remvoe the wrapper
				reloadContainer.find(".js_container-reloader").unwrap();
			}
		},
		error: function(xhr) {

			/*	Reload the alerts container
			*	An alert is saved to the session if there was an error
			*	with any script that was loaded.
			*	This function reloads the container which shows the session alert. */
			reloadAlertContainer();
		},
	});
}

Any thoughts?
Its working as it should, but i’m sure there are ways to improve it.

#3

Hi @admin532, I was a bit confused by the title TBH… just to clarify, with reloading an element you mean loading the linked resource and render it into the document? In that case you don’t need the wrapper; you might just use the replaceWith() method, like

var loadContent = function (element) {
  var $element = $(element)

  $.ajax({
    method: element.method || 'GET',
    dataType: 'html',
    url: element.action || element.href,
    data: element instanceof HTMLFormElement ? $element.serialize() : null,
    success: function (response) {
      $element.replaceWith(response)
    },
    error: console.error
  })
}

// Usage for links:
$('a.load-content').click(function (event) {
  event.preventDefault()
  loadContent(this)
})

// Or for forms:
$('form.load-content').submit(function (event) {
  event.preventDefault()
  loadContent(this)
})

Keep in mind though that this will render the entire response, including the head, scripts, styles etc.; so you might want to parse the response first and only render the document body (or any desired section).

#4

Hey! I can see now how the title can be confusing actually, but yes what you said is exactly what i meant by it.

And i didn’t know jQuery had that functionality, i haven’t worked too much with jQuery so i’m guessing i’m lacking the basic knowledge of a lot of its functions, so thanks for that!

The point of this script is to basically load a url in to an element (or switch it). For example, if i have a like button, the button will send to the url /like/save, and that will render the button again just with the correct amount of likes next to it, and a different icon. In this case i would just switch the elements.

#5

I see… a more common approach though would be to just respond with the number of likes (usually as JSON, e.g. { "success": true, "likes": 42 }), and modify the button text accordingly on the client side; this way you don’t have to worry about sanitising the markup etc.

#6

with this approach, how would you update the html of it?

Say the html of the button is this:

<div>thumbs-up-icon</div><div>number_of_likes</div>

How would go about updating that, or even more complicated html code like forms, if i have a button that when you click on it, is replaced by an html form, would you not load the actual html form file in that case?